When devices are unplugged and plugged again, __connman_notifier_enable
may be called twice, this will lead the inbalance of enabled refcount,
use bool to indicate the enabled/disabled state as alok's suggest
Fixes BMC#13547
---
src/notifier.c | 24 ++++++++++--------------
1 files changed, 10 insertions(+), 14 deletions(-)
diff --git a/src/notifier.c b/src/notifier.c
index 37c23a9..a36222f 100644
--- a/src/notifier.c
+++ b/src/notifier.c
@@ -73,8 +73,8 @@ void connman_notifier_unregister(struct connman_notifier
*notifier)
#define MAX_TECHNOLOGIES 10
+static volatile connman_bool_t enabled[MAX_TECHNOLOGIES];
static volatile int registered[MAX_TECHNOLOGIES];
-static volatile int enabled[MAX_TECHNOLOGIES];
static volatile int connected[MAX_TECHNOLOGIES];
void __connman_notifier_list_registered(DBusMessageIter *iter, void *user_data)
@@ -105,7 +105,7 @@ void __connman_notifier_list_enabled(DBusMessageIter *iter,
void *user_data)
if (type == NULL)
continue;
- if (enabled[i] > 0)
+ if (enabled[i] == TRUE)
dbus_message_iter_append_basic(iter,
DBUS_TYPE_STRING, &type);
}
@@ -296,20 +296,16 @@ void __connman_notifier_enable(enum connman_service_type
type)
break;
}
- if (__sync_fetch_and_add(&enabled[type], 1) == 0)
+ if (__sync_bool_compare_and_swap(&enabled[type], FALSE, TRUE))
technology_enabled(type, TRUE);
+ else
+ DBG("notifier already enabled");
}
void __connman_notifier_disable(enum connman_service_type type)
{
DBG("type %d", type);
- __sync_synchronize();
- if (enabled[type] == 0) {
- connman_error("notifier disable underflow");
- return;
- }
-
switch (type) {
case CONNMAN_SERVICE_TYPE_UNKNOWN:
case CONNMAN_SERVICE_TYPE_SYSTEM:
@@ -325,10 +321,10 @@ void __connman_notifier_disable(enum connman_service_type
type)
break;
}
- if (__sync_fetch_and_sub(&enabled[type], 1) != 1)
- return;
-
- technology_enabled(type, FALSE);
+ if (__sync_bool_compare_and_swap(&enabled[type], TRUE, FALSE))
+ technology_enabled(type, FALSE);
+ else
+ DBG("notifier already disabled");
}
void __connman_notifier_connect(enum connman_service_type type)
@@ -605,7 +601,7 @@ connman_bool_t __connman_notifier_is_enabled(enum
connman_service_type type)
return FALSE;
__sync_synchronize();
- if (enabled[type] > 0)
+ if (enabled[type] == TRUE)
return TRUE;
return FALSE;
--
1.7.2.2
_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman