Commit 90994b0d authored by Peter Wu's avatar Peter Wu Committed by Richard Hughes

daemon: release resources at shutdown

This makes it easier to find real memory leaks with valgrind. After
calling the up_backend_unplug functions, you cannot restart it with
up_backend_coldplug since the lists are cleared.

Tested with Linux only (not on *BSD; dummy compiles).

https://bugs.freedesktop.org/show_bug.cgi?id=82659
parent a91d03a3
......@@ -128,6 +128,26 @@ up_backend_coldplug (UpBackend *backend, UpDaemon *daemon)
return TRUE;
}
/**
* up_backend_unplug:
* @backend: The %UpBackend class instance
*
* Forget about all learned devices, effectively undoing up_backend_coldplug.
* Resources are released without emitting signals.
*/
void
up_backend_unplug (UpBackend *backend)
{
if (backend->priv->device_list != NULL) {
g_object_unref (backend->priv->device_list);
backend->priv->device_list = NULL;
}
if (backend->priv->daemon != NULL) {
g_object_unref (backend->priv->daemon);
backend->priv->daemon = NULL;
}
}
/**
* up_backend_get_critical_action:
* @backend: The %UpBackend class instance
......
......@@ -293,6 +293,30 @@ up_backend_coldplug (UpBackend *backend, UpDaemon *daemon)
return TRUE;
}
/**
* up_backend_unplug:
* @backend: The %UpBackend class instance
*
* Forget about all learned devices, effectively undoing up_backend_coldplug.
* Resources are released without emitting signals.
*/
void
up_backend_unplug (UpBackend *backend)
{
if (backend->priv->poll_timer_id > 0) {
g_source_remove (backend->priv->poll_timer_id);
backend->priv->poll_timer_id = 0;
}
if (backend->priv->device_list != NULL) {
g_object_unref (backend->priv->device_list);
backend->priv->device_list = NULL;
}
if (backend->priv->daemon != NULL) {
g_object_unref (backend->priv->daemon);
backend->priv->daemon = NULL;
}
}
/**
* up_backend_get_critical_action:
* @backend: The %UpBackend class instance
......
......@@ -340,6 +340,33 @@ up_backend_coldplug (UpBackend *backend, UpDaemon *daemon)
return TRUE;
}
/**
* up_backend_unplug:
* @backend: The %UpBackend class instance
*
* Forget about all learned devices, effectively undoing up_backend_coldplug.
* Resources are released without emitting signals.
*/
void
up_backend_unplug (UpBackend *backend)
{
if (backend->priv->gudev_client != NULL) {
g_object_unref (backend->priv->gudev_client);
backend->priv->gudev_client = NULL;
}
if (backend->priv->device_list != NULL) {
g_object_unref (backend->priv->device_list);
backend->priv->device_list = NULL;
}
/* set in init, clear the list to remove reference to UpDaemon */
if (backend->priv->managed_devices != NULL)
up_device_list_clear (backend->priv->managed_devices, FALSE);
if (backend->priv->daemon != NULL) {
g_object_unref (backend->priv->daemon);
backend->priv->daemon = NULL;
}
}
static gboolean
check_action_result (GVariant *result)
{
......
......@@ -149,6 +149,22 @@ up_backend_coldplug (UpBackend *backend, UpDaemon *daemon)
return TRUE;
}
/**
* up_backend_unplug:
* @backend: The %UpBackend class instance
*
* Forget about all learned devices, effectively undoing up_backend_coldplug.
* Resources are released without emitting signals.
*/
void
up_backend_unplug (UpBackend *backend)
{
if (backend->priv->daemon != NULL) {
g_object_unref (backend->priv->daemon);
backend->priv->daemon = NULL;
}
}
/**
* up_backend_get_critical_action:
* @backend: The %UpBackend class instance
......
......@@ -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);
......
......@@ -546,6 +546,24 @@ out:
return ret;
}
/**
* up_daemon_shutdown:
*
* Stop the daemon, release all devices and resources.
**/
void
up_daemon_shutdown (UpDaemon *daemon)
{
/* stop accepting new devices and clear backend state */
up_backend_unplug (daemon->priv->backend);
/* forget about discovered devices and release UpDaemon reference */
up_device_list_clear (daemon->priv->power_devices, TRUE);
/* release UpDaemon reference */
up_device_unplug (daemon->priv->display_device);
}
/**
* up_daemon_get_device_list:
**/
......
......@@ -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,
......
......@@ -129,6 +129,37 @@ up_device_list_remove (UpDeviceList *list, GObject *device)
return TRUE;
}
/**
* up_device_list_remove_cb:
**/
static gboolean
up_device_list_remove_all_cb (gpointer key, gpointer value, gpointer user_data)
{
return TRUE;
}
/**
* up_device_list_clear:
* @list: This class instance
* @unref_it: %TRUE if you own a reference to the objects and want to drop it.
*
* Clear the contents of this list.
**/
void
up_device_list_clear (UpDeviceList *list, gboolean unref_it)
{
g_return_if_fail (UP_IS_DEVICE_LIST (list));
/* caller owns these objects, but wants to destroy them */
if (unref_it)
g_ptr_array_foreach (list->priv->array, (GFunc) g_object_unref, NULL);
/* remove all devices from the db */
g_hash_table_foreach_remove (list->priv->map_native_path_to_device,
up_device_list_remove_all_cb, NULL);
g_ptr_array_set_size (list->priv->array, 0);
}
/**
* up_device_list_get_array:
*
......
......@@ -61,6 +61,8 @@ gboolean up_device_list_insert (UpDeviceList *list,
GObject *device);
gboolean up_device_list_remove (UpDeviceList *list,
GObject *device);
void up_device_list_clear (UpDeviceList *list,
gboolean unref_it);
GPtrArray *up_device_list_get_array (UpDeviceList *list);
G_END_DECLS
......
......@@ -721,6 +721,22 @@ bail:
return ret;
}
/**
* up_device_unplug:
*
* Initiates destruction of %UpDevice, undoing the effects of
* up_device_coldplug.
*/
void
up_device_unplug (UpDevice *device)
{
/* break circular dependency */
if (device->priv->daemon != NULL) {
g_object_unref (device->priv->daemon);
device->priv->daemon = NULL;
}
}
/**
* up_device_register_display_device:
**/
......
......@@ -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);
......
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment