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