From cb37eaba3247a50da5ab30628dd48b1cdc2c185b Mon Sep 17 00:00:00 2001 From: Patrik Flykt Date: Tue, 24 Apr 2012 15:34:30 +0300 Subject: [PATCH] notifier: Handle Manager state when exiting online Service state can transition from online to disconnect like this: 1) old online - new disconnect/association => association 2) old association - new disconnect/disconnect => disconnect Create a separate function for leaving online mode, don't rely on the previous old_state in service_indicate_state(). Fixes BMC#25073 --- src/connman.h | 6 +++--- src/notifier.c | 16 ++++++++++------ src/service.c | 7 +++++-- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/connman.h b/src/connman.h index 317af70..97e5437 100644 --- a/src/connman.h +++ b/src/connman.h @@ -692,10 +692,10 @@ void __connman_notifier_cleanup(void); void __connman_notifier_service_add(struct connman_service *service, const char *name); void __connman_notifier_service_remove(struct connman_service *service); -void __connman_notifier_online(enum connman_service_type type); +void __connman_notifier_enter_online(enum connman_service_type type); +void __connman_notifier_leave_online(enum connman_service_type type); void __connman_notifier_connect(enum connman_service_type type); -void __connman_notifier_disconnect(enum connman_service_type type, - enum connman_service_state old_state); +void __connman_notifier_disconnect(enum connman_service_type type); void __connman_notifier_offlinemode(connman_bool_t enabled); void __connman_notifier_default_changed(struct connman_service *service); void __connman_notifier_proxy_changed(struct connman_service *service); diff --git a/src/notifier.c b/src/notifier.c index f9905be..0681aa1 100644 --- a/src/notifier.c +++ b/src/notifier.c @@ -171,7 +171,7 @@ void __connman_notifier_connect(enum connman_service_type type) technology_connected(type, TRUE); } -void __connman_notifier_online(enum connman_service_type type) +void __connman_notifier_enter_online(enum connman_service_type type) { DBG("type %d", type); @@ -179,8 +179,15 @@ void __connman_notifier_online(enum connman_service_type type) state_changed(); } -void __connman_notifier_disconnect(enum connman_service_type type, - enum connman_service_state old_state) +void __connman_notifier_leave_online(enum connman_service_type type) +{ + DBG("type %d", type); + + if (__sync_fetch_and_sub(&online[type], 1) == 1) + state_changed(); +} + +void __connman_notifier_disconnect(enum connman_service_type type) { DBG("type %d", type); @@ -205,9 +212,6 @@ void __connman_notifier_disconnect(enum connman_service_type type, break; } - if (old_state == CONNMAN_SERVICE_STATE_ONLINE) - __sync_fetch_and_sub(&online[type], 1); - if (__sync_fetch_and_sub(&connected[type], 1) != 1) return; diff --git a/src/service.c b/src/service.c index 2219a01..c710ff8 100644 --- a/src/service.c +++ b/src/service.c @@ -4530,6 +4530,9 @@ static int service_indicate_state(struct connman_service *service) __connman_service_auto_connect(); } + if (old_state == CONNMAN_SERVICE_STATE_ONLINE) + __connman_notifier_leave_online(service->type); + service->state = new_state; state_changed(service); @@ -4640,7 +4643,7 @@ static int service_indicate_state(struct connman_service *service) dns_changed(service); domain_changed(service); - __connman_notifier_disconnect(service->type, old_state); + __connman_notifier_disconnect(service->type); /* * Previous services which are connected and which states @@ -4671,7 +4674,7 @@ static int service_indicate_state(struct connman_service *service) __connman_connection_update_gateway(); if (new_state == CONNMAN_SERVICE_STATE_ONLINE) { - __connman_notifier_online(service->type); + __connman_notifier_enter_online(service->type); default_changed(); } -- 2.7.4