From: Mike Gorse Date: Mon, 15 Aug 2011 19:22:02 +0000 (-0500) Subject: Fixed some problems when shutting down and restarting the module X-Git-Tag: AT_SPI2_ATK_2_12_0~190 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fat-spi2-atk.git;a=commitdiff_plain;h=a1a316d1ef4167dbca147bc3477ed22305c83743 Fixed some problems when shutting down and restarting the module If gnome_accessibility_module_shutdown was called and followed by a call to gnome_accessibility_module_init, then things would go awry because of various resources not being freed. Fixed several of these issues, although some issues might remain. --- diff --git a/atk-adaptor/accessible-cache.c b/atk-adaptor/accessible-cache.c index ad39819..4d5cdb3 100644 --- a/atk-adaptor/accessible-cache.c +++ b/atk-adaptor/accessible-cache.c @@ -125,8 +125,8 @@ spi_cache_init (SpiCache * cache) add_subtree (cache, spi_global_app_data->root); - atk_add_global_event_listener (child_added_listener, - "Gtk:AtkObject:children-changed"); + cache->child_added_listener = atk_add_global_event_listener (child_added_listener, + "Gtk:AtkObject:children-changed"); g_signal_connect (G_OBJECT (spi_global_app_data->root), "children-changed::add", @@ -141,7 +141,15 @@ spi_cache_finalize (GObject * object) while (!g_queue_is_empty (cache->add_traversal)) g_object_unref (G_OBJECT (g_queue_pop_head (cache->add_traversal))); g_queue_free (cache->add_traversal); - g_free (cache->objects); + g_hash_table_unref (cache->objects); + + g_signal_handlers_disconnect_by_func (spi_global_register, + (GCallback) remove_object, cache); + + g_signal_handlers_disconnect_by_func (G_OBJECT (spi_global_app_data->root), + (GCallback) toplevel_added_listener, NULL); + + atk_remove_global_event_listener (cache->child_added_listener); G_OBJECT_CLASS (spi_cache_parent_class)->finalize (object); } diff --git a/atk-adaptor/accessible-cache.h b/atk-adaptor/accessible-cache.h index 1089c6f..2f5be06 100644 --- a/atk-adaptor/accessible-cache.h +++ b/atk-adaptor/accessible-cache.h @@ -44,6 +44,8 @@ struct _SpiCache GHashTable * objects; GQueue *add_traversal; gint add_pending_idle; + + guint child_added_listener; }; struct _SpiCacheClass diff --git a/atk-adaptor/accessible-leasing.c b/atk-adaptor/accessible-leasing.c index f4d0e2f..4370bff 100644 --- a/atk-adaptor/accessible-leasing.c +++ b/atk-adaptor/accessible-leasing.c @@ -72,7 +72,9 @@ spi_leasing_finalize (GObject * object) { SpiLeasing *leasing = SPI_LEASING (object); - g_free (leasing->expiry_queue); + if (leasing->expiry_func_id) + g_source_remove (leasing->expiry_func_id); + g_queue_free (leasing->expiry_queue); G_OBJECT_CLASS (spi_leasing_parent_class)->finalize (object); } diff --git a/atk-adaptor/accessible-register.c b/atk-adaptor/accessible-register.c index 83c1c6d..14f256f 100644 --- a/atk-adaptor/accessible-register.c +++ b/atk-adaptor/accessible-register.c @@ -121,11 +121,26 @@ spi_register_init (SpiRegister * reg) } static void +deregister_object (gpointer data, GObject * gobj) +{ + SpiRegister *reg = SPI_REGISTER (data); + + spi_register_deregister_object (reg, gobj, FALSE); +} + +static void +spi_register_remove_weak_ref (gpointer key, gpointer val, gpointer reg) +{ + g_object_weak_unref (val, deregister_object, reg); +} + +static void spi_register_finalize (GObject * object) { SpiRegister *reg = SPI_REGISTER (object); - g_free (reg->ref2ptr); + g_hash_table_foreach (reg->ref2ptr, spi_register_remove_weak_ref, reg); + g_hash_table_unref (reg->ref2ptr); G_OBJECT_CLASS (spi_register_parent_class)->finalize (object); } @@ -186,16 +201,8 @@ ref_to_path (guint ref) * Removes the AtkObject from the reference lookup tables, meaning * it is no longer exposed over D-Bus. */ -static void -deregister_object (gpointer data, GObject * gobj) -{ - SpiRegister *reg = SPI_REGISTER (data); - - spi_register_deregister_object (reg, gobj); -} - void -spi_register_deregister_object (SpiRegister *reg, GObject *gobj) +spi_register_deregister_object (SpiRegister *reg, GObject *gobj, gboolean unref) { guint ref; @@ -206,6 +213,8 @@ spi_register_deregister_object (SpiRegister *reg, GObject *gobj) register_signals [OBJECT_DEREGISTERED], 0, gobj); + if (unref) + g_object_weak_unref (gobj, deregister_object, reg); g_hash_table_remove (reg->ref2ptr, GINT_TO_POINTER (ref)); #ifdef SPI_ATK_DEBUG diff --git a/atk-adaptor/accessible-register.h b/atk-adaptor/accessible-register.h index edbe3c2..5a62ebb 100644 --- a/atk-adaptor/accessible-register.h +++ b/atk-adaptor/accessible-register.h @@ -73,7 +73,7 @@ gchar * spi_register_root_object_path (); void -spi_register_deregister_object (SpiRegister *reg, GObject *gobj); +spi_register_deregister_object (SpiRegister *reg, GObject *gobj, gboolean unref); /*---------------------------------------------------------------------------*/ diff --git a/atk-adaptor/adaptors/cache-adaptor.c b/atk-adaptor/adaptors/cache-adaptor.c index 3b5540c..e221920 100644 --- a/atk-adaptor/adaptors/cache-adaptor.c +++ b/atk-adaptor/adaptors/cache-adaptor.c @@ -318,15 +318,11 @@ spi_initialize_cache (DRoutePath * path) { droute_path_add_interface (path, ATSPI_DBUS_INTERFACE_CACHE, spi_org_a11y_atspi_Cache, methods, NULL); - g_signal_connect (spi_global_cache, - "object-added", - (GCallback) emit_cache_add, - NULL); - - g_signal_connect (spi_global_cache, - "object-removed", - (GCallback) emit_cache_remove, - NULL); + g_signal_connect (spi_global_cache, "object-added", + (GCallback) emit_cache_add, NULL); + + g_signal_connect (spi_global_cache, "object-removed", + (GCallback) emit_cache_remove, NULL); }; /*END------------------------------------------------------------------------*/ diff --git a/atk-adaptor/bridge.c b/atk-adaptor/bridge.c index bcae3b9..d049731 100644 --- a/atk-adaptor/bridge.c +++ b/atk-adaptor/bridge.c @@ -54,6 +54,9 @@ /*---------------------------------------------------------------------------*/ +static DBusHandlerResult +signal_filter (DBusConnection *bus, DBusMessage *message, void *user_data); + SpiBridge *spi_global_app_data = NULL; /*static Display *bridge_display = NULL;*/ @@ -301,28 +304,6 @@ deregister_application (SpiBridge * app) /*---------------------------------------------------------------------------*/ -static void -exit_func (void) -{ - if (!spi_global_app_data) - { - return; - } - - spi_atk_tidy_windows (); - spi_atk_deregister_event_listeners (); - deregister_application (spi_global_app_data); - - g_free (spi_global_app_data); - spi_global_app_data = NULL; - - /* Not currently creating an XDisplay */ -#if 0 - if (bridge_display) - XCloseDisplay (bridge_display); -#endif -} - /*---------------------------------------------------------------------------*/ static AtkPlugClass *plug_class; @@ -498,9 +479,7 @@ new_connection_cb (DBusServer *server, DBusConnection *con, void *data) droute_intercept_dbus (con); droute_context_register (spi_global_app_data->droute, con); - new_list = g_list_append (spi_global_app_data->direct_connections, con); - if (new_list) - spi_global_app_data->direct_connections = new_list; + spi_global_app_data->direct_connections = g_list_append (spi_global_app_data->direct_connections, con); } static int @@ -851,8 +830,53 @@ gnome_accessibility_module_init (void) void gnome_accessibility_module_shutdown (void) { + GList *l; + + if (!spi_global_app_data) + return; + + spi_atk_tidy_windows (); spi_atk_deregister_event_listeners (); - exit_func (); + + deregister_application (spi_global_app_data); + + if (spi_global_app_data->bus) + { + dbus_connection_remove_filter (spi_global_app_data->bus, signal_filter, NULL); + droute_context_unregister (spi_global_app_data->droute, spi_global_app_data->bus); + dbus_connection_unref (spi_global_app_data->bus); + } + + for (l = spi_global_app_data->direct_connections; l; l = l->next) + { + droute_context_unregister (spi_global_app_data->droute, l->data); + droute_unintercept_dbus (l->data); + dbus_connection_unref (l); + } + g_list_free (spi_global_app_data->direct_connections); + + for (l = clients; l; l = l->next) + g_free (l->data); + g_list_free (clients); + clients = NULL; + + g_object_unref (spi_global_cache); + g_object_unref (spi_global_leasing); + g_object_unref (spi_global_register); + + if (spi_global_app_data->main_context) + g_main_context_unref (spi_global_app_data->main_context); + + droute_free (spi_global_app_data->droute); + + g_free (spi_global_app_data); + spi_global_app_data = NULL; + + /* Not currently creating an XDisplay */ +#if 0 + if (bridge_display) + XCloseDisplay (bridge_display); +#endif } static gchar *name_match_tmpl = diff --git a/atk-adaptor/event.c b/atk-adaptor/event.c index f5a2d2d..e940e00 100644 --- a/atk-adaptor/event.c +++ b/atk-adaptor/event.c @@ -613,7 +613,8 @@ state_event_listener (GSignalInvocationHint * signal_hint, DBUS_TYPE_INT32_AS_STRING, 0, append_basic); if (!g_strcmp0 (pname, "defunct")) - spi_register_deregister_object (spi_global_register, G_OBJECT (accessible)); + spi_register_deregister_object (spi_global_register, G_OBJECT (accessible), + TRUE); return TRUE; } @@ -1194,11 +1195,14 @@ spi_atk_deregister_event_listeners (void) atk_bridge_focus_tracker_id = 0; } - for (i = 0; ids && i < ids->len; i++) + if (ids) { - atk_remove_global_event_listener (g_array_index (ids, guint, i)); + for (i = 0; i < ids->len; i++) + { + atk_remove_global_event_listener (g_array_index (ids, guint, i)); + } + g_array_free (ids, TRUE); } - g_array_free (ids, TRUE); if (atk_bridge_key_event_listener_id) { diff --git a/droute/droute.c b/droute/droute.c index 20c262f..9212e4d 100644 --- a/droute/droute.c +++ b/droute/droute.c @@ -686,6 +686,12 @@ droute_path_register (DRoutePath *path, DBusConnection *bus) } void +droute_path_unregister (DRoutePath *path, DBusConnection *bus) +{ + dbus_connection_unregister_object_path (bus, path->path); +} + +void droute_context_register (DRouteContext *cnx, DBusConnection *bus) { g_ptr_array_foreach (cnx->registered_paths, (GFunc) droute_path_register, @@ -693,9 +699,30 @@ droute_context_register (DRouteContext *cnx, DBusConnection *bus) } void +droute_context_unregister (DRouteContext *cnx, DBusConnection *bus) +{ + g_ptr_array_foreach (cnx->registered_paths, (GFunc) droute_path_unregister, + bus); +} + +void +droute_context_deregister (DRouteContext *cnx, DBusConnection *bus) +{ + g_ptr_array_foreach (cnx->registered_paths, (GFunc) droute_path_unregister, + bus); +} + +void droute_intercept_dbus (DBusConnection *bus) { dbus_connection_register_object_path (bus, DBUS_PATH_DBUS, &droute_vtable, NULL); } + +void +droute_unintercept_dbus (DBusConnection *bus) +{ + dbus_connection_unregister_object_path (bus, DBUS_PATH_DBUS); +} + /*END------------------------------------------------------------------------*/ diff --git a/droute/droute.h b/droute/droute.h index 766340e..b19dec6 100644 --- a/droute/droute.h +++ b/droute/droute.h @@ -97,8 +97,17 @@ void droute_path_register (DRoutePath *path, DBusConnection *bus); void +droute_path_unregister (DRoutePath *path, DBusConnection *bus); + +void droute_context_register (DRouteContext *cnx, DBusConnection *bus); void +droute_context_unregister (DRouteContext *cnx, DBusConnection *bus); + +void droute_intercept_dbus (DBusConnection *connection); + +void +droute_unintercept_dbus (DBusConnection *connection); #endif /* _DROUTE_H */