From ed0e0cf4f678d9e3b13570d217d7960b5ffebdac Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Fri, 11 Apr 2008 13:11:38 +0000 Subject: We can't use *_run_* API from dbus signal cb or method implementation. To avoid problems move the code to a g_idle cb. svn path=/trunk/; revision=922 --- libempathy/empathy-chandler.c | 66 ++++++++++++++++++----- libempathy/empathy-contact-manager.c | 7 ++- libempathy/empathy-filter.c | 77 ++++++++++++++++++++------ libempathy/empathy-tp-contact-factory.c | 7 ++- libempathy/empathy-utils.c | 96 +++++++++++++++++++++++++++++++++ libempathy/empathy-utils.h | 4 ++ 6 files changed, 218 insertions(+), 39 deletions(-) (limited to 'libempathy') diff --git a/libempathy/empathy-chandler.c b/libempathy/empathy-chandler.c index a294febf4..2fdb37294 100644 --- a/libempathy/empathy-chandler.c +++ b/libempathy/empathy-chandler.c @@ -44,17 +44,20 @@ G_DEFINE_TYPE_WITH_CODE (EmpathyChandler, empathy_chandler, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (EMP_TYPE_SVC_CHANDLER, chandler_iface_init)); -static void -my_handle_channel (EmpSvcChandler *self, - const gchar *bus_name, - const gchar *connection, - const gchar *channel_type, - const gchar *channel, - guint handle_type, - guint handle, - DBusGMethodInvocation *context) +typedef struct { + EmpathyChandler *chandler; + gchar *bus_name; + gchar *connection; + gchar *channel_type; + gchar *channel; + guint handle_type; + guint handle; +} IdleData; + +static gboolean +handle_channel_idle_cb (gpointer data) { - EmpathyChandler *chandler = EMPATHY_CHANDLER (self); + IdleData *idle_data = data; TpChannel *chan; TpConnection *conn; static TpDBusDaemon *daemon = NULL; @@ -63,17 +66,52 @@ my_handle_channel (EmpSvcChandler *self, daemon = tp_dbus_daemon_new (tp_get_bus ()); } - conn = tp_connection_new (daemon, bus_name, connection, NULL); - chan = tp_channel_new (conn, channel, channel_type, handle_type, handle, NULL); + conn = tp_connection_new (daemon, idle_data->bus_name, + idle_data->connection, NULL); + chan = tp_channel_new (conn, idle_data->channel, idle_data->channel_type, + idle_data->handle_type, idle_data->handle, NULL); tp_channel_run_until_ready (chan, NULL, NULL); empathy_debug (DEBUG_DOMAIN, "New channel to be handled: " "type=%s handle=%d", - channel_type, handle); - g_signal_emit (chandler, signals[NEW_CHANNEL], 0, chan); + idle_data->channel_type, idle_data->handle); + g_signal_emit (idle_data->chandler, signals[NEW_CHANNEL], 0, chan); g_object_unref (chan); g_object_unref (conn); + g_free (idle_data->bus_name); + g_free (idle_data->connection); + g_free (idle_data->channel_type); + g_free (idle_data->channel); + g_slice_free (IdleData, idle_data); + + return FALSE; +} + +static void +my_handle_channel (EmpSvcChandler *self, + const gchar *bus_name, + const gchar *connection, + const gchar *channel_type, + const gchar *channel, + guint handle_type, + guint handle, + DBusGMethodInvocation *context) +{ + EmpathyChandler *chandler = EMPATHY_CHANDLER (self); + IdleData *data; + + data = g_slice_new (IdleData); + data->chandler = chandler; + data->bus_name = g_strdup (bus_name); + data->connection = g_strdup (connection); + data->channel_type = g_strdup (channel_type); + data->channel = g_strdup (channel); + data->handle_type = handle_type; + data->handle = handle; + g_idle_add_full (G_PRIORITY_HIGH, + handle_channel_idle_cb, + data, NULL); emp_svc_chandler_return_from_handle_channel (context); } diff --git a/libempathy/empathy-contact-manager.c b/libempathy/empathy-contact-manager.c index 1ef3b683a..a151dbd26 100644 --- a/libempathy/empathy-contact-manager.c +++ b/libempathy/empathy-contact-manager.c @@ -225,10 +225,9 @@ empathy_contact_manager_init (EmpathyContactManager *manager) priv->mc = empathy_mission_control_new (); - dbus_g_proxy_connect_signal (DBUS_G_PROXY (priv->mc), - "AccountStatusChanged", - G_CALLBACK (contact_manager_status_changed_cb), - manager, NULL); + empathy_connect_to_account_status_changed (priv->mc, + G_CALLBACK (contact_manager_status_changed_cb), + manager, NULL); /* Get ContactList for existing connections */ accounts = mission_control_get_online_connections (priv->mc, NULL); diff --git a/libempathy/empathy-filter.c b/libempathy/empathy-filter.c index a5d0757d5..08f9ee6c7 100644 --- a/libempathy/empathy-filter.c +++ b/libempathy/empathy-filter.c @@ -53,19 +53,22 @@ G_DEFINE_TYPE_WITH_CODE (EmpathyFilter, empathy_filter, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (EMP_TYPE_SVC_FILTER, filter_iface_init)); -static void -my_filter_channel (EmpSvcFilter *self, - const gchar *bus_name, - const gchar *connection, - const gchar *channel_type, - const gchar *channel, - guint handle_type, - guint handle, - guint id, - DBusGMethodInvocation *context) +typedef struct { + EmpathyFilter *filter; + gchar *bus_name; + gchar *connection; + gchar *channel_type; + gchar *channel; + guint handle_type; + guint handle; + guint id; +} IdleData; + +static gboolean +filter_channel_idle_cb (gpointer data) { - EmpathyFilter *filter = EMPATHY_FILTER (self); - EmpathyFilterPriv *priv = GET_PRIV (filter); + IdleData *idle_data = data; + EmpathyFilterPriv *priv = GET_PRIV (idle_data->filter); TpChannel *chan; TpConnection *conn; static TpDBusDaemon *daemon = NULL; @@ -74,19 +77,58 @@ my_filter_channel (EmpSvcFilter *self, daemon = tp_dbus_daemon_new (tp_get_bus ()); } - conn = tp_connection_new (daemon, bus_name, connection, NULL); - chan = tp_channel_new (conn, channel, channel_type, handle_type, handle, NULL); + conn = tp_connection_new (daemon, idle_data->bus_name, + idle_data->connection, NULL); + tp_connection_run_until_ready (conn, FALSE, NULL, NULL); + chan = tp_channel_new (conn, idle_data->channel, idle_data->channel_type, + idle_data->handle_type, idle_data->handle, NULL); tp_channel_run_until_ready (chan, NULL, NULL); - g_hash_table_insert (priv->table, chan, GUINT_TO_POINTER (id)); + g_hash_table_insert (priv->table, chan, GUINT_TO_POINTER (idle_data->id)); empathy_debug (DEBUG_DOMAIN, "New channel to be filtred: " "type=%s handle=%d id=%d", - channel_type, handle, id); + idle_data->channel_type, idle_data->handle, + idle_data->id); - g_signal_emit (filter, signals[NEW_CHANNEL], 0, chan); + g_signal_emit (idle_data->filter, signals[NEW_CHANNEL], 0, chan); g_object_unref (conn); + g_free (idle_data->bus_name); + g_free (idle_data->connection); + g_free (idle_data->channel_type); + g_free (idle_data->channel); + g_slice_free (IdleData, idle_data); + + return FALSE; +} + +static void +my_filter_channel (EmpSvcFilter *self, + const gchar *bus_name, + const gchar *connection, + const gchar *channel_type, + const gchar *channel, + guint handle_type, + guint handle, + guint id, + DBusGMethodInvocation *context) +{ + EmpathyFilter *filter = EMPATHY_FILTER (self); + IdleData *data; + + data = g_slice_new (IdleData); + data->filter = filter; + data->bus_name = g_strdup (bus_name); + data->connection = g_strdup (connection); + data->channel_type = g_strdup (channel_type); + data->channel = g_strdup (channel); + data->handle_type = handle_type; + data->handle = handle; + data->id = id; + g_idle_add_full (G_PRIORITY_HIGH, + filter_channel_idle_cb, + data, NULL); emp_svc_filter_return_from_filter_channel (context); } @@ -181,6 +223,7 @@ empathy_filter_new (const gchar *bus_name, G_OBJECT (filter)); mc = empathy_mission_control_new (); + mission_control_register_filter (mc, bus_name, object_path, diff --git a/libempathy/empathy-tp-contact-factory.c b/libempathy/empathy-tp-contact-factory.c index 91a4a83a7..678e53b36 100644 --- a/libempathy/empathy-tp-contact-factory.c +++ b/libempathy/empathy-tp-contact-factory.c @@ -1277,10 +1277,9 @@ empathy_tp_contact_factory_init (EmpathyTpContactFactory *tp_factory) EmpathyTpContactFactoryPriv *priv = GET_PRIV (tp_factory); priv->mc = empathy_mission_control_new (); - dbus_g_proxy_connect_signal (DBUS_G_PROXY (priv->mc), - "AccountStatusChanged", - G_CALLBACK (tp_contact_factory_status_changed_cb), - tp_factory, NULL); + empathy_connect_to_account_status_changed (priv->mc, + G_CALLBACK (tp_contact_factory_status_changed_cb), + tp_factory, NULL); } EmpathyTpContactFactory * diff --git a/libempathy/empathy-utils.c b/libempathy/empathy-utils.c index b4058cd38..46fb97027 100644 --- a/libempathy/empathy-utils.c +++ b/libempathy/empathy-utils.c @@ -633,3 +633,99 @@ empathy_channel_get_account (TpChannel *channel) return account; } + +typedef void (*AccountStatusChangedFunc) (MissionControl *mc, + TpConnectionStatus status, + McPresence presence, + TpConnectionStatusReason reason, + const gchar *unique_name, + gpointer *user_data); + +typedef struct { + AccountStatusChangedFunc handler; + gpointer user_data; + GClosureNotify free_func; +} AccountStatusChangedData; + +typedef struct { + MissionControl *mc; + TpConnectionStatus status; + McPresence presence; + TpConnectionStatusReason reason; + gchar *unique_name; + AccountStatusChangedData *data; +} InvocationData; + +static void +account_status_changed_data_free (gpointer ptr, + GClosure *closure) +{ + AccountStatusChangedData *data = ptr; + + if (data->free_func) { + data->free_func (data->user_data, closure); + } + g_slice_free (AccountStatusChangedData, data); +} + +static gboolean +account_status_changed_invoke_callback (gpointer data) +{ + InvocationData *invocation_data = data; + + invocation_data->data->handler (invocation_data->mc, + invocation_data->status, + invocation_data->presence, + invocation_data->reason, + invocation_data->unique_name, + invocation_data->data->user_data); + + g_free (invocation_data->unique_name); + g_slice_free (InvocationData, invocation_data); + + return FALSE; +} + +static void +account_status_changed_cb (MissionControl *mc, + TpConnectionStatus status, + McPresence presence, + TpConnectionStatusReason reason, + const gchar *unique_name, + AccountStatusChangedData *data) +{ + InvocationData *invocation_data; + + invocation_data = g_slice_new (InvocationData); + invocation_data->mc = mc; + invocation_data->status = status; + invocation_data->presence = presence; + invocation_data->reason = reason; + invocation_data->unique_name = g_strdup (unique_name); + invocation_data->data = data; + g_idle_add_full (G_PRIORITY_HIGH, + account_status_changed_invoke_callback, + invocation_data, NULL); +} + +void +empathy_connect_to_account_status_changed (MissionControl *mc, + GCallback handler, + gpointer user_data, + GClosureNotify free_func) +{ + AccountStatusChangedData *data; + + g_return_if_fail (IS_MISSIONCONTROL (mc)); + g_return_if_fail (handler != NULL); + + data = g_slice_new (AccountStatusChangedData); + + data->handler = (AccountStatusChangedFunc) handler; + data->user_data = user_data; + data->free_func = free_func; + dbus_g_proxy_connect_signal (DBUS_G_PROXY (mc), "AccountStatusChanged", + G_CALLBACK (account_status_changed_cb), + data, account_status_changed_data_free); +} + diff --git a/libempathy/empathy-utils.h b/libempathy/empathy-utils.h index f717b845a..2b14374fb 100644 --- a/libempathy/empathy-utils.h +++ b/libempathy/empathy-utils.h @@ -102,6 +102,10 @@ void empathy_run_until_ready_full (gpointer object, gpointer user_data, GMainLoop **loop); McAccount * empathy_channel_get_account (TpChannel *channel); +void empathy_connect_to_account_status_changed (MissionControl *mc, + GCallback handler, + gpointer user_data, + GClosureNotify free_func); G_END_DECLS -- cgit v1.2.3