diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2008-08-10 11:56:25 +0200 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2008-08-10 11:56:25 +0200 |
commit | 746e33bd6337b3abb7e2823f3b6afc83bf29b549 (patch) | |
tree | 2dd221831102be7654bb2e7397ac7096c36f6bbc | |
parent | c3cdbfae11de2fbc126528955d4330794c590424 (diff) | |
download | connman-746e33bd6337b3abb7e2823f3b6afc83bf29b549.tar.gz connman-746e33bd6337b3abb7e2823f3b6afc83bf29b549.tar.bz2 connman-746e33bd6337b3abb7e2823f3b6afc83bf29b549.zip |
Add function to unregister all children of an element
-rw-r--r-- | include/element.h | 1 | ||||
-rw-r--r-- | src/element.c | 36 |
2 files changed, 37 insertions, 0 deletions
diff --git a/include/element.h b/include/element.h index fb4f70fc..c0702acc 100644 --- a/include/element.h +++ b/include/element.h @@ -119,6 +119,7 @@ extern int connman_element_get_value(struct connman_element *element, extern int connman_element_register(struct connman_element *element, struct connman_element *parent); extern void connman_element_unregister(struct connman_element *element); +extern void connman_element_unregister_children(struct connman_element *element); extern void connman_element_update(struct connman_element *element); static inline void *connman_element_get_data(struct connman_element *element) diff --git a/src/element.c b/src/element.c index 5e1bea55..790d6154 100644 --- a/src/element.c +++ b/src/element.c @@ -39,6 +39,7 @@ static GSList *driver_list = NULL; static GThreadPool *thread_register = NULL; static GThreadPool *thread_unregister = NULL; +static GThreadPool *thread_unregister_children = NULL; static gchar *device_filter = NULL; @@ -647,6 +648,14 @@ void connman_element_unregister(struct connman_element *element) g_thread_pool_push(thread_unregister, element, NULL); } +void connman_element_unregister_children(struct connman_element *element) +{ + DBG("element %p name %s", element, element->name); + + if (thread_unregister_children != NULL) + g_thread_pool_push(thread_unregister_children, element, NULL); +} + void connman_element_update(struct connman_element *element) { DBG("element %p name %s", element, element->name); @@ -734,9 +743,13 @@ static void register_element(gpointer data, gpointer user_data) static gboolean remove_element(GNode *node, gpointer user_data) { struct connman_element *element = node->data; + struct connman_element *root = user_data; DBG("element %p name %s", element, element->name); + if (element == root) + return FALSE; + if (element->driver) { if (element->driver->remove) element->driver->remove(element); @@ -782,6 +795,24 @@ static void unregister_element(gpointer data, gpointer user_data) g_static_rw_lock_writer_unlock(&element_lock); } +static void unregister_children(gpointer data, gpointer user_data) +{ + struct connman_element *element = data; + GNode *node; + + DBG("element %p name %s", element, element->name); + + g_static_rw_lock_writer_lock(&element_lock); + + node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element); + + if (node != NULL) + g_node_traverse(node, G_POST_ORDER, + G_TRAVERSE_ALL, -1, remove_element, element); + + g_static_rw_lock_writer_unlock(&element_lock); +} + int __connman_element_init(DBusConnection *conn, const char *device) { struct connman_element *element; @@ -810,6 +841,8 @@ int __connman_element_init(DBusConnection *conn, const char *device) NULL, 1, FALSE, NULL); thread_unregister = g_thread_pool_new(unregister_element, NULL, 1, FALSE, NULL); + thread_unregister_children = g_thread_pool_new(unregister_children, + NULL, 1, FALSE, NULL); return 0; } @@ -864,6 +897,9 @@ void __connman_element_cleanup(void) g_thread_pool_free(thread_unregister, FALSE, TRUE); thread_unregister = NULL; + g_thread_pool_free(thread_unregister_children, FALSE, TRUE); + thread_unregister_children = NULL; + g_static_rw_lock_writer_lock(&element_lock); g_node_destroy(element_root); element_root = NULL; |