From: Daniel Wagner <[email protected]>
We should only return from the __connman_session_set_mode() when
all pending action (__connman_service_disconnect_all()) have been
processed. It is not possible to 'know' from the client when
the system is idle.
---
src/connman.h | 4 ++--
src/manager.c | 9 ++++++---
src/service.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++---
src/session.c | 10 ++++++----
4 files changed, 61 insertions(+), 12 deletions(-)
diff --git a/src/connman.h b/src/connman.h
index 1dc6e51..f698a3a 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -509,7 +509,7 @@ int __connman_service_request_login(struct connman_service
*service);
int __connman_service_lookup(const char *pattern, const char **path);
int __connman_service_connect(struct connman_service *service);
int __connman_service_disconnect(struct connman_service *service);
-int __connman_service_disconnect_all(void);
+int __connman_service_disconnect_all(DBusMessage *msg);
int __connman_service_create_and_connect(DBusMessage *msg);
int __connman_service_provision(DBusMessage *msg);
void __connman_service_auto_connect(void);
@@ -632,7 +632,7 @@ int __connman_rtnl_request_update(void);
int __connman_rtnl_send(const void *buf, size_t len);
connman_bool_t __connman_session_mode();
-void __connman_session_set_mode(connman_bool_t enable);
+int __connman_session_set_mode(DBusMessage *msg, connman_bool_t enable);
int __connman_session_create(DBusMessage *msg);
int __connman_session_destroy(DBusMessage *msg);
diff --git a/src/manager.c b/src/manager.c
index 722d621..f8a4072 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -97,7 +97,7 @@ static DBusMessage *set_property(DBusConnection *conn,
{
DBusMessageIter iter, value;
const char *name;
- int type;
+ int type, err;
DBG("conn %p", conn);
@@ -135,7 +135,9 @@ static DBusMessage *set_property(DBusConnection *conn,
dbus_message_iter_get_basic(&value, &sessionmode);
- __connman_session_set_mode(sessionmode);
+ err = __connman_session_set_mode(msg, sessionmode);
+ if (err < 0)
+ return __connman_error_failed(msg, -err);
} else
return __connman_error_invalid_property(msg);
@@ -630,7 +632,8 @@ static DBusMessage *release_private_network(DBusConnection
*conn,
static GDBusMethodTable manager_methods[] = {
{ "GetProperties", "", "a{sv}", get_properties },
- { "SetProperty", "sv", "", set_property },
+ { "SetProperty", "sv", "", set_property,
+ G_DBUS_METHOD_FLAG_ASYNC },
{ "GetState", "", "s", get_state },
{ "RemoveProvider", "o", "", remove_provider },
{ "RequestScan", "s", "", request_scan },
diff --git a/src/service.c b/src/service.c
index 2249863..7cd0294 100644
--- a/src/service.c
+++ b/src/service.c
@@ -38,6 +38,8 @@ static DBusConnection *connection = NULL;
static GSequence *service_list = NULL;
static GHashTable *service_hash = NULL;
static GSList *counter_list = NULL;
+static DBusMessage *session_mode_msg;
+static unsigned int session_mode_pending = 0;
struct connman_stats {
connman_bool_t valid;
@@ -2670,6 +2672,22 @@ static void reply_pending(struct connman_service
*service, int error)
}
}
+static void session_mode_notify(void)
+{
+ DBusMessage *reply;
+
+ DBG("");
+
+ if (session_mode_msg == NULL)
+ return;
+
+ reply = g_dbus_create_reply(session_mode_msg, DBUS_TYPE_INVALID);
+ g_dbus_send_message(connection, reply);
+
+ dbus_message_unref(session_mode_msg);
+ session_mode_msg = NULL;
+}
+
static gboolean connect_timeout(gpointer user_data)
{
struct connman_service *service = user_data;
@@ -2699,6 +2717,13 @@ static gboolean connect_timeout(gpointer user_data)
} else
autoconnect = TRUE;
+ if (session_mode_pending > 0) {
+ session_mode_pending--;
+
+ if (session_mode_pending == 0)
+ session_mode_notify();
+ }
+
__connman_service_ipconfig_indicate_state(service,
CONNMAN_SERVICE_STATE_FAILURE,
CONNMAN_IPCONFIG_TYPE_IPV4);
@@ -3578,6 +3603,13 @@ static int __connman_service_indicate_state(struct
connman_service *service)
dns_changed(service);
domain_changed(service);
+ if (session_mode_pending > 0) {
+ session_mode_pending--;
+
+ if (session_mode_pending == 0)
+ session_mode_notify();
+ }
+
__connman_notifier_disconnect(service->type);
}
@@ -4028,12 +4060,16 @@ int __connman_service_disconnect(struct connman_service
*service)
return err;
}
-int __connman_service_disconnect_all(void)
+int __connman_service_disconnect_all(DBusMessage *msg)
{
GSequenceIter *iter;
+ int err;
DBG("");
+ if (session_mode_msg != NULL)
+ return -EINPROGRESS;
+
iter = g_sequence_get_begin_iter(service_list);
while (g_sequence_iter_is_end(iter) == FALSE) {
@@ -4043,13 +4079,21 @@ int __connman_service_disconnect_all(void)
set_reconnect_state(service, FALSE);
- __connman_service_disconnect(service);
+ err = __connman_service_disconnect(service);
+ if (err == -EINPROGRESS)
+ session_mode_pending++;
iter = g_sequence_iter_next(iter);
}
- return 0;
+ if (session_mode_pending != 0)
+ return 0;
+
+ DBG("session_mode_pending %d", session_mode_pending);
+ session_mode_msg = dbus_message_ref(msg);
+ session_mode_notify();
+ return 0;
}
/**
diff --git a/src/session.c b/src/session.c
index fb12d3c..f12f0fd 100644
--- a/src/session.c
+++ b/src/session.c
@@ -1484,17 +1484,19 @@ connman_bool_t __connman_session_mode()
return sessionmode;
}
-void __connman_session_set_mode(connman_bool_t enable)
+int __connman_session_set_mode(DBusMessage *msg, connman_bool_t enable)
{
DBG("enable %d", enable);
if (sessionmode == enable)
- return;
+ return 0;
sessionmode = enable;
- if (sessionmode == TRUE)
- __connman_service_disconnect_all();
+ if (sessionmode == FALSE)
+ return 0;
+
+ return __connman_service_disconnect_all(msg);
}
static void service_add(struct connman_service *service)
--
1.7.6
_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman