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

Reply via email to