Move the configuration part of __connman_session_create() into
session_create_cb(). With this change the policy plugin is able
to do async work to retrieve a configuration.
---
 src/session.c | 190 ++++++++++++++++++++++++++++++++--------------------------
 1 file changed, 106 insertions(+), 84 deletions(-)

diff --git a/src/session.c b/src/session.c
index b1f11de..a5fa801 100644
--- a/src/session.c
+++ b/src/session.c
@@ -882,6 +882,9 @@ static gint sort_services(gconstpointer a, gconstpointer b, 
gpointer user_data)
 
 static void free_session(struct connman_session *session)
 {
+       if (session == NULL)
+               return;
+
        destroy_policy_config(session);
        connman_session_free_bearers(session->info->config.allowed_bearers);
        g_free(session->owner);
@@ -1585,6 +1588,8 @@ static const GDBusMethodTable session_methods[] = {
 };
 
 struct user_config {
+       DBusMessage *pending;
+
        enum connman_session_type type;
        connman_bool_t type_valid;
 
@@ -1596,9 +1601,94 @@ static void session_create_cb(struct connman_session 
*session,
                                struct connman_session_config *config,
                                void *user_data)
 {
+       DBusMessage *reply;
+       struct user_config *user_config = user_data;
+       struct session_info *info, *info_last;
+       int err = 0;
+
        DBG("session %p config %p", session, config);
 
+       if (config == NULL) {
+               err = -ENOMEM;
+               goto out;
+       }
+
        session->policy_config = config;
+
+       info = session->info;
+       info_last = session->info_last;
+
+       if (session->policy_config->ecall == TRUE)
+               ecall_session = session;
+
+       info->state = CONNMAN_SESSION_STATE_DISCONNECTED;
+       if (user_config->type_valid == FALSE)
+               user_config->type = CONNMAN_SESSION_TYPE_ANY;
+       info->config.type = apply_policy_on_type(
+                               session->policy_config->type,
+                               user_config->type);
+       info->config.priority = session->policy_config->priority;
+       info->config.roaming_policy = session->policy_config->roaming_policy;
+       info->entry = NULL;
+
+       if (user_config->allowed_bearers_valid == FALSE) {
+               user_config->allowed_bearers =
+                       connman_session_allowed_bearers_any();
+               if (user_config->allowed_bearers == NULL) {
+                       err = -ENOMEM;
+                       goto out;
+               }
+       }
+
+       err = apply_policy_on_bearers(
+                       session->policy_config->allowed_bearers,
+                       config->allowed_bearers,
+                       &info->config.allowed_bearers);
+       if (err < 0)
+               goto out;
+
+       g_hash_table_replace(session_hash, session->session_path, session);
+
+       DBG("add %s", session->session_path);
+
+       if (g_dbus_register_interface(connection, session->session_path,
+                                       CONNMAN_SESSION_INTERFACE,
+                                       session_methods, NULL,
+                                       NULL, session, NULL) == FALSE) {
+               connman_error("Failed to register %s", session->session_path);
+               g_hash_table_remove(session_hash, session->session_path);
+               err = -EINVAL;
+               goto out;
+       }
+
+       reply = g_dbus_create_reply(user_config->pending,
+                               DBUS_TYPE_OBJECT_PATH, &session->session_path,
+                               DBUS_TYPE_INVALID);
+       g_dbus_send_message(connection, reply);
+
+       populate_service_list(session);
+
+       info_last->state = info->state;
+       info_last->config.priority = info->config.priority;
+       info_last->config.roaming_policy = info->config.roaming_policy;
+       info_last->entry = info->entry;
+       info_last->config.allowed_bearers = info->config.allowed_bearers;
+
+       session->append_all = TRUE;
+
+       session_changed(session, CONNMAN_SESSION_TRIGGER_SETTING);
+
+out:
+       if (err < 0) {
+               __connman_error_failed(user_config->pending, err);
+               free_session(session);
+       }
+
+       dbus_message_unref(user_config->pending);
+
+       if (user_config != NULL)
+               connman_session_free_bearers(user_config->allowed_bearers);
+       g_free(user_config);
 }
 
 int __connman_session_create(DBusMessage *msg)
@@ -1607,7 +1697,6 @@ int __connman_session_create(DBusMessage *msg)
        char *session_path = NULL;
        DBusMessageIter iter, array;
        struct connman_session *session = NULL;
-       struct session_info *info, *info_last;
        struct user_config *config = NULL;
        int err;
 
@@ -1630,6 +1719,7 @@ int __connman_session_create(DBusMessage *msg)
                goto err;
        }
 
+       config->pending = dbus_message_ref(msg);
        config->type = CONNMAN_SESSION_TYPE_ANY;
 
        dbus_message_iter_init(msg, &iter);
@@ -1655,7 +1745,8 @@ int __connman_session_create(DBusMessage *msg)
 
                                config->allowed_bearers_valid = TRUE;
                        } else {
-                               return -EINVAL;
+                               err = -EINVAL;
+                               goto err;
                        }
                        break;
                case DBUS_TYPE_STRING:
@@ -1664,7 +1755,8 @@ int __connman_session_create(DBusMessage *msg)
                                config->type = string2type(val);
                                config->type_valid = TRUE;
                        } else {
-                               return -EINVAL;
+                               err = -EINVAL;
+                               goto err;
                        }
                }
                dbus_message_iter_next(&array);
@@ -1686,6 +1778,7 @@ int __connman_session_create(DBusMessage *msg)
 
        session = g_hash_table_lookup(session_hash, session_path);
        if (session != NULL) {
+               g_free(session_path);
                session = NULL;
                err = -EEXIST;
                goto err;
@@ -1693,10 +1786,13 @@ int __connman_session_create(DBusMessage *msg)
 
        session = g_try_new0(struct connman_session, 1);
        if (session == NULL) {
+               g_free(session_path);
                err = -ENOMEM;
                goto err;
        }
 
+       session->session_path = session_path;
+
        session->info = g_try_new0(struct session_info, 1);
        if (session->info == NULL) {
                err = -ENOMEM;
@@ -1709,11 +1805,7 @@ int __connman_session_create(DBusMessage *msg)
                goto err;
        }
 
-       info = session->info;
-       info_last = session->info_last;
-
        session->owner = g_strdup(owner);
-       session->session_path = session_path;
        session->notify_path = g_strdup(notify_path);
        session->notify_watch =
                g_dbus_add_disconnect_watch(connection, session->owner,
@@ -1722,92 +1814,22 @@ int __connman_session_create(DBusMessage *msg)
        err = assign_policy_plugin(session);
        if (err < 0)
                goto err;
-       err = create_policy_config(session, session_create_cb, NULL);
-       if (err < 0)
-               goto err;
-
-       if (session->policy_config->ecall == TRUE)
-               ecall_session = session;
-
-       info->state = CONNMAN_SESSION_STATE_DISCONNECTED;
-       if (config->type_valid == FALSE)
-               config->type = CONNMAN_SESSION_TYPE_ANY;
-       info->config.type = apply_policy_on_type(
-                               session->policy_config->type,
-                               config->type);
-       info->config.priority = session->policy_config->priority;
-       info->config.roaming_policy = session->policy_config->roaming_policy;
-       info->entry = NULL;
-
-       if (config->allowed_bearers_valid == FALSE) {
-               config->allowed_bearers = connman_session_allowed_bearers_any();
-               if (config->allowed_bearers == NULL) {
-                       err = -ENOMEM;
-                       goto err;
-               }
-       }
-
-       err = apply_policy_on_bearers(
-                       session->policy_config->allowed_bearers,
-                       config->allowed_bearers,
-                       &info->config.allowed_bearers);
+       err = create_policy_config(session, session_create_cb, config);
        if (err < 0)
                goto err;
 
-       connman_session_free_bearers(config->allowed_bearers);
-       g_free(config);
-
-       g_hash_table_replace(session_hash, session->session_path, session);
-
-       DBG("add %s", session->session_path);
-
-       if (g_dbus_register_interface(connection, session->session_path,
-                                       CONNMAN_SESSION_INTERFACE,
-                                       session_methods, NULL,
-                                       NULL, session, NULL) == FALSE) {
-               connman_error("Failed to register %s", session->session_path);
-               g_hash_table_remove(session_hash, session->session_path);
-               session = NULL;
-
-               err = -EINVAL;
-               goto err;
-       }
-
-       g_dbus_send_reply(connection, msg,
-                               DBUS_TYPE_OBJECT_PATH, &session->session_path,
-                               DBUS_TYPE_INVALID);
-
-
-       populate_service_list(session);
-
-       info_last->state = info->state;
-       info_last->config.priority = info->config.priority;
-       info_last->config.roaming_policy = info->config.roaming_policy;
-       info_last->entry = info->entry;
-       info_last->config.allowed_bearers = info->config.allowed_bearers;
-
-       session->append_all = TRUE;
-
-       session_changed(session, CONNMAN_SESSION_TRIGGER_SETTING);
-
-       return 0;
+       return -EINPROGRESS;
 
 err:
        connman_error("Failed to create session");
 
-       if (session != NULL) {
-               if (session->info_last != NULL)
-                       g_free(session->info_last);
-               if (session->info != NULL)
-                       g_free(session->info);
-               g_free(session);
-       }
-
-       g_free(session_path);
+       free_session(session);
 
-       if (config != NULL)
+       if (config != NULL) {
+               dbus_message_unref(config->pending);
                connman_session_free_bearers(config->allowed_bearers);
-       g_free(config);
+               g_free(config);
+       }
 
        return err;
 }
-- 
1.7.11.4

_______________________________________________
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman

Reply via email to