aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClaudio Saavedra <csaavedra@igalia.com>2012-09-01 00:28:11 +0800
committerClaudio Saavedra <csaavedra@igalia.com>2012-09-01 02:34:03 +0800
commitb6a62382cb0b9029052f81151a578d8ce572c703 (patch)
tree0ad80f32988536b98ee812b48daf08d532d03b56
parent67736b8c9a8917c522e7432bda74379f768ec501 (diff)
downloadgsoc2013-epiphany-b6a62382cb0b9029052f81151a578d8ce572c703.tar.gz
gsoc2013-epiphany-b6a62382cb0b9029052f81151a578d8ce572c703.tar.zst
gsoc2013-epiphany-b6a62382cb0b9029052f81151a578d8ce572c703.zip
ephy-history-service: Do not emit signals from the history service thread
We were naively emitting a few signals from the history service thread while doing this is not thread safe. Add a few helper methods to run this in a main loop idle. https://bugzilla.gnome.org/show_bug.cgi?id=683040
-rw-r--r--lib/history/ephy-history-service.c88
1 files changed, 85 insertions, 3 deletions
diff --git a/lib/history/ephy-history-service.c b/lib/history/ephy-history-service.c
index ffe302b22..3d7a2fdbf 100644
--- a/lib/history/ephy-history-service.c
+++ b/lib/history/ephy-history-service.c
@@ -479,6 +479,35 @@ ephy_history_service_execute_job_callback (gpointer data)
return FALSE;
}
+typedef struct {
+ EphyHistoryService *service;
+ gpointer user_data;
+ GDestroyNotify destroy_func;
+} SignalEmissionContext;
+
+static void
+signal_emission_context_free (SignalEmissionContext *ctx)
+{
+ g_object_unref (ctx->service);
+ if (ctx->destroy_func && ctx->user_data)
+ ctx->destroy_func (ctx->user_data);
+ g_slice_free (SignalEmissionContext, ctx);
+}
+
+static SignalEmissionContext *
+signal_emission_context_new (EphyHistoryService *service,
+ gpointer user_data,
+ GDestroyNotify destroy_func)
+{
+ SignalEmissionContext *ctx = g_slice_new0 (SignalEmissionContext);
+
+ ctx->service = g_object_ref (service);
+ ctx->user_data = user_data;
+ ctx->destroy_func = destroy_func;
+
+ return ctx;
+}
+
static gboolean
ephy_history_service_execute_add_visit_helper (EphyHistoryService *self, EphyHistoryPageVisit *visit)
{
@@ -711,6 +740,16 @@ ephy_history_service_query_hosts (EphyHistoryService *self,
}
static gboolean
+set_url_title_signal_emit (SignalEmissionContext *ctx)
+{
+ EphyHistoryURL *url = (EphyHistoryURL *)ctx->user_data;
+
+ g_signal_emit (ctx->service, signals[URL_TITLE_CHANGED], 0, url->url, url->title);
+
+ return FALSE;
+}
+
+static gboolean
ephy_history_service_execute_set_url_title (EphyHistoryService *self,
EphyHistoryURL *url,
gpointer *result)
@@ -722,11 +761,19 @@ ephy_history_service_execute_set_url_title (EphyHistoryService *self,
g_free (title);
return FALSE;
} else {
+ SignalEmissionContext *ctx;
+
g_free (url->title);
url->title = title;
ephy_history_service_update_url_row (self, url);
ephy_history_service_schedule_commit (self);
- g_signal_emit (self, signals[URL_TITLE_CHANGED], 0, url->url, url->title);
+
+ ctx = signal_emission_context_new (self,
+ ephy_history_url_copy (url),
+ (GDestroyNotify)ephy_history_url_free);
+ g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
+ (GSourceFunc)set_url_title_signal_emit,
+ ctx, (GDestroyNotify)signal_emission_context_free);
return TRUE;
}
}
@@ -947,17 +994,34 @@ ephy_history_service_get_host_for_url (EphyHistoryService *self,
}
static gboolean
+delete_urls_signal_emit (SignalEmissionContext *ctx)
+{
+ char *url = (char *)ctx->user_data;
+
+ g_signal_emit (ctx->service, signals[URL_DELETED], 0, url);
+
+ return FALSE;
+}
+
+static gboolean
ephy_history_service_execute_delete_urls (EphyHistoryService *self,
GList *urls,
gpointer *result)
{
GList *l;
EphyHistoryURL *url;
+ SignalEmissionContext *ctx;
for (l = urls; l != NULL; l = l->next) {
url = l->data;
ephy_history_service_delete_url (self, url);
- g_signal_emit (self, signals[URL_DELETED], 0, url->url);
+
+ ctx = signal_emission_context_new (self, g_strdup (url->url),
+ (GDestroyNotify) g_free);
+ g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
+ (GSourceFunc)delete_urls_signal_emit,
+ ctx,
+ (GDestroyNotify)signal_emission_context_free);
}
ephy_history_service_delete_orphan_hosts (self);
@@ -967,14 +1031,32 @@ ephy_history_service_execute_delete_urls (EphyHistoryService *self,
}
static gboolean
+delete_host_signal_emit (SignalEmissionContext *ctx)
+{
+ char *host = (char *)ctx->user_data;
+
+ g_signal_emit (ctx->service, signals[HOST_DELETED], 0, host);
+
+ return FALSE;
+}
+
+static gboolean
ephy_history_service_execute_delete_host (EphyHistoryService *self,
EphyHistoryHost *host,
EphyHistoryJobCallback callback,
gpointer user_data)
{
+ SignalEmissionContext *ctx;
+
ephy_history_service_delete_host_row (self, host);
ephy_history_service_schedule_commit (self);
- g_signal_emit (self, signals[HOST_DELETED], 0, host->url);
+
+ ctx = signal_emission_context_new (self, g_strdup (host->url),
+ (GDestroyNotify)g_free);
+ g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
+ (GSourceFunc) delete_host_signal_emit,
+ ctx,
+ (GDestroyNotify) signal_emission_context_free);
return TRUE;
}