aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorScott Murray <scott.murray@konsulko.com>2024-10-08 16:05:11 -0400
committerJan-Simon Moeller <jsmoeller@linuxfoundation.org>2024-10-09 10:57:28 +0000
commit1afb908c72eeaee137e843aea1835859cf14a5ff (patch)
tree78a5b1c7f963aa63af1123ce28e7f6a3142780aa
parentb6fb203586130e072b1fc8312fdf2a694105669f (diff)
Rework glib main loop initializationHEADmaster
Changes: - To avoid interactions with Qt6's new and/or different use of the glib main loop, explicitly create new main context and loop instances for our processing thread to avoid any interactions. This includes making the new context the default for the thread, which impacts implicit usage in glib functions. - Refactor things a bit to have agent registration run completely asynchronously to avoid that operation blocking Qt initialization. - To expand on the above, add new checking of the agent state to the connect & disconnect calls that rely on the agent, and add a new connman_get_agent_registered API function that clients can use to check the state. - Added some more DEBUG prints for potential future use, and bumped the default log level to WARNING to make it easier to diagnose any agent registration failures. Bug-AGL: SPEC-5257 Change-Id: I290f81c99b4ffc2939ef6f503505deabbd1ebc0b Signed-off-by: Scott Murray <scott.murray@konsulko.com>
-rw-r--r--include/connman-glib.h4
-rw-r--r--src/api.c74
-rw-r--r--src/common.h3
-rw-r--r--src/connman-agent.c40
-rw-r--r--src/connman-agent.h2
5 files changed, 85 insertions, 38 deletions
diff --git a/include/connman-glib.h b/include/connman-glib.h
index 63412c0..9cb3cc8 100644
--- a/include/connman-glib.h
+++ b/include/connman-glib.h
@@ -33,7 +33,7 @@ typedef enum {
// Hook to allow users to override the default level
#ifndef CONNMAN_LOG_LEVEL_DEFAULT
-#define CONNMAN_LOG_LEVEL_DEFAULT CONNMAN_LOG_LEVEL_ERROR
+#define CONNMAN_LOG_LEVEL_DEFAULT CONNMAN_LOG_LEVEL_WARNING
#endif
typedef enum {
@@ -84,6 +84,8 @@ void connman_set_log_level(connman_log_level_t level);
gboolean connman_init(gboolean register_agent);
+gboolean connman_manager_get_agent_registered(void);
+
gboolean connman_manager_get_state(gchar **state);
gboolean connman_manager_get_online(void);
diff --git a/src/api.c b/src/api.c
index 07bbc70..d2659c0 100644
--- a/src/api.c
+++ b/src/api.c
@@ -63,6 +63,7 @@ static const char *g_connman_log_level_names[CONNMAN_LOG_LEVEL_DEBUG + 1] = {
"DEBUG"
};
+
// Wrappers to hedge possible future abstractions
static void connman_set_state(struct connman_state *ns)
{
@@ -115,6 +116,10 @@ static void callback_add(callback_list_t *callbacks, gpointer callback, gpointer
g_mutex_unlock(&callbacks->mutex);
}
+#if 0
+
+// For potential future use
+
static void callback_remove(callback_list_t *callbacks, gpointer callback)
{
callback_list_entry_t *entry = NULL;
@@ -137,6 +142,8 @@ static void callback_remove(callback_list_t *callbacks, gpointer callback)
g_mutex_unlock(&callbacks->mutex);
}
+#endif
+
static void run_manager_callbacks(callback_list_t *callbacks,
const gchar *path,
connman_manager_event_t event,
@@ -391,6 +398,8 @@ static struct connman_state *connman_dbus_init(GMainLoop *loop)
ERROR("out of memory allocating network state");
goto err_no_ns;
}
+ g_mutex_init(&ns->cw_mutex);
+ g_mutex_init(&ns->agent_state_mutex);
INFO("connecting to dbus");
@@ -495,37 +504,45 @@ static gpointer connman_handler_func(gpointer ptr)
GMainLoop *loop;
int rc;
- loop = g_main_loop_new(NULL, FALSE);
+ GMainContext *context = g_main_context_new();
+ if (!context) {
+ ERROR("Unable to create context");
+ goto err_no_context;
+ }
+ g_main_context_push_thread_default(context);
+
+ loop = g_main_loop_new(context, FALSE);
if (!loop) {
ERROR("Unable to create main loop");
goto err_no_loop;
}
- // dbus interface init
+ // D-Bbus interface init
+ DEBUG("connman_handler_func: initializing D-Bus connection");
ns = connman_dbus_init(loop);
if (!ns) {
ERROR("connman_dbus_init() failed");
goto err_no_ns;
}
+ DEBUG("connman_handler_func: D-Bus initialized");
+
+ connman_set_state(ns);
+
+ signal_init_done(id, TRUE);
- id->ns = ns;
if (id->register_agent) {
- rc = connman_register_agent(id);
+ DEBUG("connman_handler_func: registering agent");
+ rc = connman_register_agent(ns);
if (rc) {
- ERROR("network_register_agent() failed");
+ ERROR("connman_register_agent() failed");
goto err_no_agent;
}
-
- // agent registeration will signal init done
-
- } else {
- signal_init_done(id, TRUE);
}
- connman_set_state(ns);
g_main_loop_run(loop);
g_main_loop_unref(ns->loop);
+ g_free(context);
connman_unregister_agent(ns);
@@ -539,7 +556,9 @@ err_no_agent:
err_no_ns:
g_main_loop_unref(loop);
+ g_free(context);
+err_no_context:
err_no_loop:
signal_init_done(id, FALSE);
@@ -551,13 +570,9 @@ err_no_loop:
EXPORT gboolean connman_init(gboolean register_agent)
{
struct init_data init_data, *id = &init_data;
- gint64 end_time;
memset(id, 0, sizeof(*id));
id->register_agent = register_agent;
- id->init_done = FALSE;
- id->init_done_cb = signal_init_done;
- //id->rc = FALSE;
g_cond_init(&id->cond);
g_mutex_init(&id->mutex);
@@ -567,8 +582,8 @@ EXPORT gboolean connman_init(gboolean register_agent)
INFO("waiting for init done");
- /* wait maximum 10 seconds for init done */
- end_time = g_get_monotonic_time () + 10 * G_TIME_SPAN_SECOND;
+ // Wait maximum 10 seconds for init done
+ gint64 end_time = g_get_monotonic_time () + 10 * G_TIME_SPAN_SECOND;
g_mutex_lock(&id->mutex);
while (!id->init_done) {
if (!g_cond_wait_until(&id->cond, &id->mutex, end_time))
@@ -589,6 +604,17 @@ EXPORT gboolean connman_init(gboolean register_agent)
return id->rc;
}
+EXPORT gboolean connman_manager_get_agent_registered(void)
+{
+ struct connman_state *ns = connman_get_state();
+ gboolean registered = FALSE;
+
+ g_mutex_lock(&ns->agent_state_mutex);
+ registered = ns->agent_registered;
+ g_mutex_unlock(&ns->agent_state_mutex);
+ return registered;
+}
+
EXPORT gboolean connman_manager_get_state(gchar **state)
{
struct connman_state *ns = connman_get_state();
@@ -920,6 +946,13 @@ EXPORT gboolean connman_service_connect(const gchar *service,
ERROR("No service given");
return FALSE;
}
+ g_mutex_lock(&ns->agent_state_mutex);
+ if (!ns->agent_registered) {
+ ERROR("No agent registered");
+ g_mutex_unlock(&ns->agent_state_mutex);
+ return FALSE;
+ }
+ g_mutex_unlock(&ns->agent_state_mutex);
cw = call_work_create(ns, "service", service,
"connect_service", "Connect", &error);
@@ -956,6 +989,13 @@ EXPORT gboolean connman_service_disconnect(const gchar *service)
ERROR("No service given to move");
return FALSE;
}
+ g_mutex_lock(&ns->agent_state_mutex);
+ if (!ns->agent_registered) {
+ ERROR("No agent registered");
+ g_mutex_unlock(&ns->agent_state_mutex);
+ return FALSE;
+ }
+ g_mutex_unlock(&ns->agent_state_mutex);
reply = connman_call(ns, CONNMAN_AT_SERVICE, service,
"Disconnect", NULL, &error);
diff --git a/src/common.h b/src/common.h
index d05d022..1c68fe7 100644
--- a/src/common.h
+++ b/src/common.h
@@ -50,6 +50,7 @@ struct connman_state {
guint registration_id;
gchar *agent_path;
gboolean agent_registered;
+ GMutex agent_state_mutex;
};
struct init_data {
@@ -57,9 +58,7 @@ struct init_data {
GMutex mutex;
gboolean register_agent;
gboolean init_done;
- struct connman_state *ns; /* before setting afb_api_set_userdata() */
gboolean rc;
- void (*init_done_cb)(struct init_data *id, gboolean rc);
};
extern void connman_log(connman_log_level_t level, const char *func, const char *format, ...)
diff --git a/src/connman-agent.c b/src/connman-agent.c
index 46209fe..f4af300 100644
--- a/src/connman-agent.c
+++ b/src/connman-agent.c
@@ -144,12 +144,11 @@ static void on_bus_acquired(GDBusConnection *connection,
const gchar *name,
gpointer user_data)
{
- struct init_data *id = user_data;
- struct connman_state *ns = id->ns;
+ struct connman_state *ns = user_data;
GVariant *result;
GError *error = NULL;
- INFO("agent bus acquired - registering %s", ns->agent_path);
+ DEBUG("agent bus acquired - registering %s", ns->agent_path);
ns->registration_id =
g_dbus_connection_register_object(connection,
@@ -177,33 +176,28 @@ static void on_bus_acquired(GDBusConnection *connection,
ns->agent_registered = TRUE;
- INFO("agent registered at %s", ns->agent_path);
- if (id->init_done_cb)
- (*id->init_done_cb)(id, TRUE);
-
+ DEBUG("agent registered at %s", ns->agent_path);
return;
err_unable_to_register_connman:
g_dbus_connection_unregister_object(ns->conn, ns->registration_id);
ns->registration_id = 0;
err_unable_to_register_bus:
- if (id->init_done_cb)
- (*id->init_done_cb)(id, FALSE);
+ return;
}
-int connman_register_agent(struct init_data *id)
+int connman_register_agent(struct connman_state *ns)
{
- struct connman_state *ns = id->ns;
-
+ g_mutex_lock(&ns->agent_state_mutex);
ns->agent_path = g_strdup_printf("%s/agent%d", CONNMAN_PATH, getpid());
if (!ns->agent_path) {
- ERROR("can't create agent path");
+ ERROR("Cannot create agent path");
goto out_no_agent_path;
}
ns->introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL);
if (!ns->introspection_data) {
- ERROR("can't create introspection data");
+ ERROR("Cannot create introspection data");
goto out_no_introspection_data;
}
@@ -214,26 +208,38 @@ int connman_register_agent(struct init_data *id)
on_bus_acquired,
NULL,
NULL,
- id,
+ ns,
NULL);
if (!ns->agent_id) {
- ERROR("can't create agent bus instance");
+ ERROR("Cannot create agent bus instance");
goto out_no_bus_name;
}
-
+ g_mutex_unlock(&ns->agent_state_mutex);
return 0;
out_no_bus_name:
g_dbus_node_info_unref(ns->introspection_data);
+ ns->introspection_data = NULL;
out_no_introspection_data:
g_free(ns->agent_path);
+ ns->agent_path = NULL;
out_no_agent_path:
+ g_mutex_unlock(&ns->agent_state_mutex);
return -1;
}
void connman_unregister_agent(struct connman_state *ns)
{
+ g_mutex_lock(&ns->agent_state_mutex);
+ if (!ns->agent_registered) {
+ WARNING("No agent registered to unregister");
+ return;
+ }
g_bus_unown_name(ns->agent_id);
g_dbus_node_info_unref(ns->introspection_data);
+ ns->introspection_data = NULL;
g_free(ns->agent_path);
+ ns->agent_path = NULL;
+ ns->agent_registered = FALSE;
+ g_mutex_unlock(&ns->agent_state_mutex);
}
diff --git a/src/connman-agent.h b/src/connman-agent.h
index c2acc66..6ae254a 100644
--- a/src/connman-agent.h
+++ b/src/connman-agent.h
@@ -27,7 +27,7 @@
#include "common.h"
-int connman_register_agent(struct init_data *id);
+int connman_register_agent(struct connman_state *ns);
void connman_unregister_agent(struct connman_state *ns);