aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2010-10-13 15:42:13 +0800
committerMilan Crha <mcrha@redhat.com>2010-10-13 15:42:13 +0800
commitc83faa7078cc1fd280ac573b07645e8464b2fdc4 (patch)
tree758560068839af181e5f66337a6759840f2ab56a
parentb86cb119aec6e79a9c363915c915626f4dd2959d (diff)
downloadgsoc2013-evolution-c83faa7078cc1fd280ac573b07645e8464b2fdc4.tar.gz
gsoc2013-evolution-c83faa7078cc1fd280ac573b07645e8464b2fdc4.tar.zst
gsoc2013-evolution-c83faa7078cc1fd280ac573b07645e8464b2fdc4.zip
Bug #617611 - redo_queries calls gtk+ functions in non-main thread
-rw-r--r--calendar/gui/e-cal-model.c67
1 files changed, 55 insertions, 12 deletions
diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c
index 525e4fff33..ddea112fb9 100644
--- a/calendar/gui/e-cal-model.c
+++ b/calendar/gui/e-cal-model.c
@@ -29,6 +29,7 @@
#include <string.h>
#include <glib.h>
#include <glib/gi18n.h>
+#include <libedataserver/e-flag.h>
#include <libedataserver/e-time-utils.h>
#include <libecal/e-cal-time-util.h>
#include "comp-util.h"
@@ -2323,13 +2324,53 @@ get_objects_as_list (ECalModel *model)
return l;
}
+struct cc_data
+{
+ ECalModel *model;
+ EFlag *eflag;
+};
+
+static gboolean
+cleanup_content_cb (gpointer user_data)
+{
+ ECalModel *model;
+ ECalModelPrivate *priv;
+ GSList *slist;
+ gint len;
+ struct cc_data *data = user_data;
+
+ g_return_val_if_fail (data != NULL, FALSE);
+ g_return_val_if_fail (data->model != NULL, FALSE);
+ g_return_val_if_fail (data->eflag != NULL, FALSE);
+
+ model = data->model;
+ priv = model->priv;
+
+ g_return_val_if_fail (priv != NULL, FALSE);
+
+ e_table_model_pre_change (E_TABLE_MODEL (model));
+ len = priv->objects->len;
+
+ slist = get_objects_as_list (model);
+ g_ptr_array_set_size (priv->objects, 0);
+ g_signal_emit (G_OBJECT (model), signals[COMPS_DELETED], 0, slist);
+
+ e_table_model_rows_deleted (E_TABLE_MODEL (model), 0, len);
+
+ g_slist_foreach (slist, (GFunc)g_object_unref, NULL);
+ g_slist_free (slist);
+
+ e_flag_set (data->eflag);
+
+ return FALSE;
+}
+
static void
redo_queries (ECalModel *model)
{
ECalModelPrivate *priv;
GList *l;
- GSList *slist;
- gint len;
+ struct cc_data data;
priv = model->priv;
@@ -2362,18 +2403,20 @@ redo_queries (ECalModel *model)
priv->full_sexp = g_strdup ("#f");
}
- /* clean up the current contents */
- e_table_model_pre_change (E_TABLE_MODEL (model));
- len = priv->objects->len;
-
- slist = get_objects_as_list (model);
- g_ptr_array_set_size (priv->objects, 0);
- g_signal_emit (G_OBJECT (model), signals[COMPS_DELETED], 0, slist);
+ /* clean up the current contents, which should be done
+ always from the main thread, because of gtk calls during removal */
+ data.model = model;
+ data.eflag = e_flag_new ();
- e_table_model_rows_deleted (E_TABLE_MODEL (model), 0, len);
+ if (!g_main_context_is_owner (g_main_context_default ())) {
+ /* function called from other than main thread */
+ g_timeout_add (10, cleanup_content_cb, &data);
+ e_flag_wait (data.eflag);
+ } else {
+ cleanup_content_cb (&data);
+ }
- g_slist_foreach (slist, (GFunc)g_object_unref, NULL);
- g_slist_free (slist);
+ e_flag_free (data.eflag);
/* update the query for all clients */
for (l = priv->clients; l != NULL; l = l->next) {