summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2008-08-10 11:56:25 +0200
committerMarcel Holtmann <marcel@holtmann.org>2008-08-10 11:56:25 +0200
commit746e33bd6337b3abb7e2823f3b6afc83bf29b549 (patch)
tree2dd221831102be7654bb2e7397ac7096c36f6bbc
parentc3cdbfae11de2fbc126528955d4330794c590424 (diff)
downloadconnman-746e33bd6337b3abb7e2823f3b6afc83bf29b549.tar.gz
connman-746e33bd6337b3abb7e2823f3b6afc83bf29b549.tar.bz2
connman-746e33bd6337b3abb7e2823f3b6afc83bf29b549.zip
Add function to unregister all children of an element
-rw-r--r--include/element.h1
-rw-r--r--src/element.c36
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;