From: Lee, Chun-Yi <[email protected]>

There have a race condition issue in connman between wifi driver object with
element->driver reference.
On some machine, the wifi driver object doesn't generate before we try to
register a element. It causes element->driver is NULL, and will not do
driver->remove when remove element.

Signed-off-by: Lee, Chun-Yi <[email protected]>
---
 src/connman.h |    1 +
 src/device.c  |    2 ++
 src/element.c |   43 ++++++++++++++++++++++++++-----------------
 3 files changed, 29 insertions(+), 17 deletions(-)

diff --git a/src/connman.h b/src/connman.h
index 3a546fe..a467c64 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -169,6 +169,7 @@ void __connman_element_foreach(struct connman_element 
*element,
 void __connman_element_list(struct connman_element *element,
                                        enum connman_element_type type,
                                                        DBusMessageIter *iter);
+void __connman_element_probe_element(struct connman_element *element);
 
 struct connman_service *__connman_element_get_service(struct connman_element 
*element);
 struct connman_device *__connman_element_get_device(struct connman_element 
*element);
diff --git a/src/device.c b/src/device.c
index 373eb5f..8e9b67b 100644
--- a/src/device.c
+++ b/src/device.c
@@ -587,6 +587,8 @@ static void probe_driver(struct connman_element *element, 
gpointer user_data)
        element->device->driver = driver;
 
        setup_device(element->device);
+
+       __connman_element_probe_element(element);
 }
 
 static void remove_device(struct connman_device *device)
diff --git a/src/element.c b/src/element.c
index 74383cc..41860c3 100644
--- a/src/element.c
+++ b/src/element.c
@@ -479,6 +479,31 @@ static gboolean probe_driver(GNode *node, gpointer data)
        return FALSE;
 }
 
+void __connman_element_probe_element(struct connman_element *element)
+{
+        GSList *list;
+
+        DBG("element %p name %s", element, element->name);
+
+        for (list = driver_list; list; list = list->next) {
+                struct connman_driver *driver = list->data;
+
+                if (match_driver(element, driver) == FALSE)
+                        continue;
+
+                DBG("driver %p name %s", driver, driver->name);
+
+               if (__connman_device_has_driver(element->device) == TRUE) {
+                       if (element->driver == NULL)
+                               element->driver = driver;
+                       break;
+               } else if (driver->probe(element) == 0) {
+                       element->driver = driver;
+                       break;
+               }
+       }
+}
+
 void __connman_driver_rescan(struct connman_driver *driver)
 {
        DBG("driver %p name %s", driver, driver->name);
@@ -1007,23 +1032,7 @@ const void *connman_element_get_blob(struct 
connman_element *element,
 
 static void probe_element(struct connman_element *element)
 {
-       GSList *list;
-
-       DBG("element %p name %s", element, element->name);
-
-       for (list = driver_list; list; list = list->next) {
-               struct connman_driver *driver = list->data;
-
-               if (match_driver(element, driver) == FALSE)
-                       continue;
-
-               DBG("driver %p name %s", driver, driver->name);
-
-               if (driver->probe(element) == 0) {
-                       element->driver = driver;
-                       break;
-               }
-       }
+       __connman_element_probe_element(element);
 }
 
 static void register_element(gpointer data, gpointer user_data)
-- 
1.6.0.2

_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman

Reply via email to