aboutsummaryrefslogtreecommitdiffstats
path: root/libempathy/empathy-dispatcher.c
diff options
context:
space:
mode:
Diffstat (limited to 'libempathy/empathy-dispatcher.c')
-rw-r--r--libempathy/empathy-dispatcher.c37
1 files changed, 35 insertions, 2 deletions
diff --git a/libempathy/empathy-dispatcher.c b/libempathy/empathy-dispatcher.c
index e8f7b8c7e..a8e0b1844 100644
--- a/libempathy/empathy-dispatcher.c
+++ b/libempathy/empathy-dispatcher.c
@@ -57,6 +57,9 @@ typedef struct
GHashTable *accounts;
gpointer token;
GSList *tubes;
+
+ /* channels which the dispatcher is listening "invalidated" */
+ GList *channels;
} EmpathyDispatcherPriv;
G_DEFINE_TYPE (EmpathyDispatcher, empathy_dispatcher, G_TYPE_OBJECT);
@@ -142,7 +145,7 @@ new_dispatcher_request_data (EmpathyDispatcher *dispatcher,
{
DispatcherRequestData *result = g_slice_new0 (DispatcherRequestData);
- result->dispatcher = dispatcher;
+ result->dispatcher = g_object_ref (dispatcher);
result->connection = connection;
result->channel_type = g_strdup (channel_type);
@@ -164,6 +167,9 @@ free_dispatcher_request_data (DispatcherRequestData *r)
{
g_free (r->channel_type);
+ if (r->dispatcher != NULL)
+ g_object_unref (r->dispatcher);
+
if (r->contact != NULL)
g_object_unref (r->contact);
@@ -306,6 +312,8 @@ dispatcher_channel_invalidated_cb (TpProxy *proxy,
g_hash_table_remove (cd->dispatched_channels, object_path);
g_hash_table_remove (cd->dispatching_channels, object_path);
+ priv->channels = g_list_remove (priv->channels, proxy);
+
operation = g_hash_table_lookup (cd->outstanding_channels, object_path);
if (operation != NULL)
{
@@ -387,6 +395,7 @@ dispatch_operation_ready_cb (EmpathyDispatchOperation *operation,
g_object_unref (G_OBJECT (connection));
g_object_ref (operation);
+ g_object_ref (dispatcher);
dispatch_operation_flush_requests (dispatcher, operation, NULL, cd);
status = empathy_dispatch_operation_get_status (operation);
@@ -409,6 +418,7 @@ dispatch_operation_ready_cb (EmpathyDispatchOperation *operation,
g_signal_emit (dispatcher, signals[DISPATCH], 0, operation);
}
+ g_object_unref (dispatcher);
}
static void
@@ -549,6 +559,8 @@ dispatcher_connection_new_channel (EmpathyDispatcher *dispatcher,
G_CALLBACK (dispatcher_channel_invalidated_cb),
dispatcher);
+ priv->channels = g_list_append (priv->channels, channel);
+
if (handle_type == TP_CONN_HANDLE_TYPE_CONTACT)
{
EmpathyContactFactory *factory = empathy_contact_factory_dup_singleton ();
@@ -755,7 +767,6 @@ dispatcher_connection_ready_cb (TpConnection *connection,
g_signal_connect (connection, "invalidated",
G_CALLBACK (dispatcher_connection_invalidated_cb), dispatcher);
-
if (tp_proxy_has_interface_by_id (TP_PROXY (connection),
TP_IFACE_QUARK_CONNECTION_INTERFACE_REQUESTS))
{
@@ -866,10 +877,28 @@ static void
dispatcher_finalize (GObject *object)
{
EmpathyDispatcherPriv *priv = GET_PRIV (object);
+ GList *l;
+ GHashTableIter iter;
+ gpointer connection;
g_signal_handlers_disconnect_by_func (priv->account_manager,
dispatcher_account_connection_cb, object);
+ for (l = priv->channels; l; l = l->next)
+ {
+ g_signal_handlers_disconnect_by_func (l->data,
+ dispatcher_channel_invalidated_cb, object);
+ }
+
+ g_list_free (priv->channels);
+
+ g_hash_table_iter_init (&iter, priv->connections);
+ while (g_hash_table_iter_next (&iter, &connection, NULL))
+ {
+ g_signal_handlers_disconnect_by_func (connection,
+ dispatcher_connection_invalidated_cb, object);
+ }
+
g_object_unref (priv->account_manager);
g_object_unref (priv->mc);
@@ -941,6 +970,8 @@ empathy_dispatcher_init (EmpathyDispatcher *dispatcher)
priv->connections = g_hash_table_new_full (g_direct_hash, g_direct_equal,
g_object_unref, (GDestroyNotify) free_connection_data);
+ priv->channels = NULL;
+
accounts = mc_accounts_list_by_enabled (TRUE);
for (l = accounts; l; l = l->next)
@@ -1034,6 +1065,8 @@ dispatcher_connection_new_requested_channel (EmpathyDispatcher *dispatcher,
G_CALLBACK (dispatcher_channel_invalidated_cb),
request_data->dispatcher);
+ priv->channels = g_list_append (priv->channels, channel);
+
operation = empathy_dispatch_operation_new (request_data->connection,
channel, request_data->contact, FALSE);
g_object_unref (channel);