From a8366e2a6a3f013d527bbba912eee0e59f08224b Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Tue, 18 Nov 2014 10:12:56 +0100 Subject: [WIP] attempt to fix refcount leak of UpDaemon Debug in GDB with: break up-main.c:260 # just after daemon = up_daemon_new () p &daemon->parent.ref_count break *(guint *)ADDR_PRINTED_ABOVE commands bt c end c Refcount of daemon was over 100 at the end... --- src/linux/up-backend.c | 36 ++++++++++++++++++++++++++++++------ src/up-backend.h | 1 + src/up-daemon.c | 9 +++++++++ src/up-daemon.h | 1 + src/up-device-list.c | 15 +++++++++++++++ src/up-device-list.h | 1 + src/up-device.c | 15 +++++++++++++-- src/up-device.h | 1 + src/up-main.c | 1 + 9 files changed, 72 insertions(+), 8 deletions(-) diff --git a/src/linux/up-backend.c b/src/linux/up-backend.c index f45ce29..71e7ef8 100644 --- a/src/linux/up-backend.c +++ b/src/linux/up-backend.c @@ -340,6 +340,36 @@ up_backend_coldplug (UpBackend *backend, UpDaemon *daemon) return TRUE; } +/** + * up_backend_unplug: + * + * Initiates destruction of %UpBackend, undoing the effects of + * up_backend_coldplug. + */ +void +up_backend_unplug (UpBackend *backend) +{ + GList *keys, *item; + GUdevDevice *native; + + if (backend->priv->gudev_client != NULL && backend->priv->device_list != NULL) { + keys = up_device_list_get_keys (backend->priv->device_list); + for (item = keys; item != NULL; item = item->next) { + native = g_udev_client_query_by_sysfs_path (backend->priv->gudev_client, item->data); + if (native != NULL) + up_backend_device_remove (backend, native); + } + g_list_free (keys); + } + + if (backend->priv->gudev_client != NULL) + g_object_unref (backend->priv->gudev_client); + if (backend->priv->device_list != NULL) + g_object_unref (backend->priv->device_list); + if (backend->priv->daemon != NULL) + g_object_unref (backend->priv->daemon); +} + static gboolean check_action_result (GVariant *result) { @@ -495,12 +525,6 @@ up_backend_finalize (GObject *object) backend = UP_BACKEND (object); g_object_unref (backend->priv->config); - if (backend->priv->daemon != NULL) - g_object_unref (backend->priv->daemon); - if (backend->priv->device_list != NULL) - g_object_unref (backend->priv->device_list); - if (backend->priv->gudev_client != NULL) - g_object_unref (backend->priv->gudev_client); g_clear_object (&backend->priv->logind_proxy); g_object_unref (backend->priv->managed_devices); diff --git a/src/up-backend.h b/src/up-backend.h index 7b3145c..213c0e1 100644 --- a/src/up-backend.h +++ b/src/up-backend.h @@ -69,6 +69,7 @@ void up_backend_test (gpointer user_data); gboolean up_backend_coldplug (UpBackend *backend, UpDaemon *daemon); +void up_backend_unplug (UpBackend *backend); void up_backend_take_action (UpBackend *backend); const char *up_backend_get_critical_action (UpBackend *backend); diff --git a/src/up-daemon.c b/src/up-daemon.c index d6420fc..b16438e 100644 --- a/src/up-daemon.c +++ b/src/up-daemon.c @@ -546,6 +546,15 @@ out: return ret; } +/** + * up_daemon_shutdown: + **/ +void +up_daemon_shutdown (UpDaemon *daemon) +{ + up_backend_unplug (daemon->priv->backend); +} + /** * up_daemon_get_device_list: **/ diff --git a/src/up-daemon.h b/src/up-daemon.h index 3392ad0..87857b3 100644 --- a/src/up-daemon.h +++ b/src/up-daemon.h @@ -72,6 +72,7 @@ guint up_daemon_get_number_devices_of_type (UpDaemon *daemon, UpDeviceKind type); UpDeviceList *up_daemon_get_device_list (UpDaemon *daemon); gboolean up_daemon_startup (UpDaemon *daemon); +void up_daemon_shutdown (UpDaemon *daemon); void up_daemon_set_lid_is_closed (UpDaemon *daemon, gboolean lid_is_closed); void up_daemon_set_lid_is_present (UpDaemon *daemon, diff --git a/src/up-device-list.c b/src/up-device-list.c index da5555b..6b28dc4 100644 --- a/src/up-device-list.c +++ b/src/up-device-list.c @@ -143,6 +143,21 @@ up_device_list_get_array (UpDeviceList *list) return g_ptr_array_ref (list->priv->array); } +/** + * up_device_list_get_get_keys: + * + * Get a list of registered native paths to a device, useful if you want to + * free all devices. + * + * Return value: a list of keys, free with g_list_free(). + **/ +GList * +up_device_list_get_keys (UpDeviceList *list) +{ + g_return_val_if_fail (UP_IS_DEVICE_LIST (list), NULL); + return g_hash_table_get_keys (list->priv->map_native_path_to_device); +} + /** * up_device_list_class_init: * @klass: The UpDeviceListClass diff --git a/src/up-device-list.h b/src/up-device-list.h index 709c893..d29bb9b 100644 --- a/src/up-device-list.h +++ b/src/up-device-list.h @@ -62,6 +62,7 @@ gboolean up_device_list_insert (UpDeviceList *list, gboolean up_device_list_remove (UpDeviceList *list, GObject *device); GPtrArray *up_device_list_get_array (UpDeviceList *list); +GList *up_device_list_get_keys (UpDeviceList *list); G_END_DECLS diff --git a/src/up-device.c b/src/up-device.c index 685be80..40c4c6b 100644 --- a/src/up-device.c +++ b/src/up-device.c @@ -721,6 +721,19 @@ bail: return ret; } +/** + * up_device_unplug: + * + * Initiates destruction of %UpDevice, undoing the effects of + * up_device_coldplug. + */ +void +up_device_unplug (UpDevice *device) +{ + if (device->priv->daemon != NULL) + g_object_unref (device->priv->daemon); +} + /** * up_device_register_display_device: **/ @@ -1042,8 +1055,6 @@ up_device_finalize (GObject *object) g_return_if_fail (device->priv != NULL); if (device->priv->native != NULL) g_object_unref (device->priv->native); - if (device->priv->daemon != NULL) - g_object_unref (device->priv->daemon); if (device->priv->props_idle_id != 0) g_source_remove (device->priv->props_idle_id); g_object_unref (device->priv->history); diff --git a/src/up-device.h b/src/up-device.h index 53415e7..a2d0b7e 100644 --- a/src/up-device.h +++ b/src/up-device.h @@ -75,6 +75,7 @@ UpDevice *up_device_new (void); gboolean up_device_coldplug (UpDevice *device, UpDaemon *daemon, GObject *native); +void up_device_unplug (UpDevice *device); gboolean up_device_register_display_device (UpDevice *device, UpDaemon *daemon); UpDaemon *up_device_get_daemon (UpDevice *device); diff --git a/src/up-main.c b/src/up-main.c index c27cfb4..cb835b7 100644 --- a/src/up-main.c +++ b/src/up-main.c @@ -278,6 +278,7 @@ main (gint argc, gchar **argv) /* wait for input or timeout */ g_main_loop_run (loop); + up_daemon_shutdown (daemon); retval = 0; out: if (kbd_backlight != NULL) -- cgit v1.2.1