summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-10-07 09:48:09 +0200
committerThomas Haller <thaller@redhat.com>2019-10-15 20:33:24 +0200
commitbb31c612b8f53b60181738f724fa6d8213f0de5d (patch)
tree335ee9b629a435698fede7c2bd608a85265abb78
parent4f7a912934f64794e94885f31698ce8d14aabedd (diff)
downloadNetworkManager-th/libnm-no-dbus-codegen-1.tar.gz
libnm: implement nm_client_add_connection*() by using GDBusConnection directlyth/libnm-no-dbus-codegen-1
-rw-r--r--libnm/nm-client.c286
-rw-r--r--libnm/nm-remote-settings.c187
-rw-r--r--libnm/nm-remote-settings.h28
3 files changed, 244 insertions, 257 deletions
diff --git a/libnm/nm-client.c b/libnm/nm-client.c
index 2dd8b3aadd..5189d67a53 100644
--- a/libnm/nm-client.c
+++ b/libnm/nm-client.c
@@ -1785,55 +1785,160 @@ nm_client_get_connection_by_uuid (NMClient *client, const char *uuid)
return nm_remote_settings_get_connection_by_uuid (NM_CLIENT_GET_PRIVATE (client)->settings, uuid);
}
-typedef struct {
- NMRemoteConnection *connection;
- GVariant *results;
-} AddConnection2CbData;
+static void
+_add_connection_cb (GObject *source,
+ GAsyncResult *result,
+ gboolean with_extra_arg,
+ gpointer user_data)
+{
+ NMClient *self;
+ gs_unref_variant GVariant *ret = NULL;
+ gs_unref_object GTask *task = user_data;
+ gs_unref_variant GVariant *v_result = NULL;
+ const char *v_path;
+ GError *error = NULL;
+
+ ret = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error);
+ if (!ret) {
+ g_dbus_error_strip_remote_error (error);
+ g_task_return_error (task, error);
+ return;
+ }
+
+ if (with_extra_arg) {
+ g_variant_get (ret,
+ "(&o@a{sv})",
+ &v_path,
+ &v_result);
+ } else {
+ g_variant_get (ret,
+ "(&o)",
+ &v_path);
+ }
+
+ self = g_task_get_source_object (task);
+
+ nm_remote_settings_wait_for_connection (NM_CLIENT_GET_PRIVATE (self)->settings,
+ v_path,
+ g_steal_pointer (&v_result),
+ g_steal_pointer (&task));
+}
static void
-add_connection2_cb_data_destroy (gpointer user_data)
+_add_connection_cb_without_extra_result (GObject *object, GAsyncResult *result, gpointer user_data)
{
- AddConnection2CbData *data = user_data;
+ _add_connection_cb (object, result, FALSE, user_data);
+}
- g_object_unref (data->connection);
- nm_g_variant_unref (data->results);
- nm_g_slice_free (data);
+static void
+_add_connection_cb_with_extra_result (GObject *object, GAsyncResult *result, gpointer user_data)
+{
+ _add_connection_cb (object, result, TRUE, user_data);
}
static void
-add_connection2_cb (NMRemoteSettings *self,
- NMRemoteConnection *connection,
- GVariant *results,
- GError *error,
- gpointer user_data)
+_add_connection_call (NMClient *self,
+ gpointer source_tag,
+ gboolean ignore_out_result,
+ GVariant *settings,
+ NMSettingsAddConnection2Flags flags,
+ GVariant *args,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- gs_unref_object GSimpleAsyncResult *simple = user_data;
-
- if (error) {
- g_simple_async_result_take_error (simple,
- g_error_new_literal (error->domain,
- error->code,
- error->message));
- } else if (g_simple_async_result_get_source_tag (simple) == nm_client_add_connection_async) {
- g_simple_async_result_set_op_res_gpointer (simple,
- g_object_ref (connection),
- g_object_unref);
+ g_return_if_fail (NM_IS_CLIENT (self));
+ g_return_if_fail (!settings || g_variant_is_of_type (settings, G_VARIANT_TYPE ("a{sa{sv}}")));
+ g_return_if_fail (!args || g_variant_is_of_type (args, G_VARIANT_TYPE ("a{sv}")));
+
+ if (!settings)
+ settings = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0);
+
+ /* Although AddConnection2() being capable to handle also AddConnection() and
+ * AddConnectionUnsaved() variants, we prefer to use the old D-Bus methods when
+ * they are sufficient. The reason is that libnm should avoid hard dependencies
+ * on 1.20 API whenever possible. */
+ if ( ignore_out_result
+ && flags == NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK) {
+ _nm_object_dbus_call (self,
+ source_tag,
+ cancellable,
+ callback,
+ user_data,
+ NM_DBUS_PATH_SETTINGS,
+ NM_DBUS_INTERFACE_SETTINGS,
+ "AddConnection",
+ g_variant_new ("(@a{sa{sv}})", settings),
+ G_VARIANT_TYPE ("(o)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+ _add_connection_cb_without_extra_result);
+ } else if ( ignore_out_result
+ && flags == NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY) {
+ _nm_object_dbus_call (self,
+ source_tag,
+ cancellable,
+ callback,
+ user_data,
+ NM_DBUS_PATH_SETTINGS,
+ NM_DBUS_INTERFACE_SETTINGS,
+ "AddConnectionUnsaved",
+ g_variant_new ("(@a{sa{sv}})", settings),
+ G_VARIANT_TYPE ("(o)"),
+ G_DBUS_CALL_FLAGS_NONE,
+ NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+ _add_connection_cb_without_extra_result);
} else {
- AddConnection2CbData *data;
-
- nm_assert (g_simple_async_result_get_source_tag (simple) == nm_client_add_connection2);
-
- data = g_slice_new (AddConnection2CbData);
- *data = (AddConnection2CbData) {
- .connection = g_object_ref (connection),
- .results = nm_g_variant_ref (results),
- };
- g_simple_async_result_set_op_res_gpointer (simple,
- data,
- add_connection2_cb_data_destroy);
+ _nm_object_dbus_call (self,
+ source_tag,
+ cancellable,
+ callback,
+ user_data,
+ NM_DBUS_PATH_SETTINGS,
+ NM_DBUS_INTERFACE_SETTINGS,
+ "AddConnection2",
+ g_variant_new ("(@a{sa{sv}}u@a{sv})",
+ settings,
+ (guint32) flags,
+ args
+ ?: g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0)),
+ G_VARIANT_TYPE ("(oa{sv})"),
+ G_DBUS_CALL_FLAGS_NONE,
+ NM_DBUS_DEFAULT_TIMEOUT_MSEC,
+ _add_connection_cb_with_extra_result);
}
+}
- g_simple_async_result_complete (simple);
+static NMRemoteConnection *
+_add_connection_call_finish (NMClient *client,
+ GAsyncResult *result,
+ gpointer source_tag,
+ GVariant **out_result,
+ GError **error)
+{
+ nm_auto_free_add_connection_result_data NMAddConnectionResultData *result_data = NULL;
+
+ g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (nm_g_task_is_valid (result, client, source_tag), NULL);
+
+ result_data = g_task_propagate_pointer (G_TASK (result), error);
+ if (!result_data) {
+ NM_SET_OUT (out_result, NULL);
+ return NULL;
+ }
+
+ nm_assert (NM_IS_REMOTE_CONNECTION (result_data->connection));
+
+ NM_SET_OUT (out_result, g_steal_pointer (&result_data->extra_results));
+ return g_steal_pointer (&result_data->connection);
+}
+
+void
+nm_add_connection_result_data_free (NMAddConnectionResultData *result_data)
+{
+ nm_g_object_unref (result_data->connection);
+ nm_g_variant_unref (result_data->extra_results);
+ nm_g_slice_free (result_data);
}
/**
@@ -1869,32 +1974,19 @@ nm_client_add_connection_async (NMClient *client,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *simple;
- GError *error = NULL;
-
- g_return_if_fail (NM_IS_CLIENT (client));
g_return_if_fail (NM_IS_CONNECTION (connection));
- if (!_nm_client_check_nm_running (client, &error)) {
- g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error);
- return;
- }
-
- simple = g_simple_async_result_new (G_OBJECT (client), callback, user_data,
- nm_client_add_connection_async);
- if (cancellable)
- g_simple_async_result_set_check_cancellable (simple, cancellable);
-
- nm_remote_settings_add_connection2 (NM_CLIENT_GET_PRIVATE (client)->settings,
- nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL),
- save_to_disk
- ? NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK
- : NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY,
- NULL,
- TRUE,
- cancellable,
- add_connection2_cb,
- simple);
+ _add_connection_call (client,
+ nm_client_add_connection_async,
+ TRUE,
+ nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL),
+ save_to_disk
+ ? NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK
+ : NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY,
+ NULL,
+ cancellable,
+ callback,
+ user_data);
}
/**
@@ -1913,15 +2005,11 @@ nm_client_add_connection_finish (NMClient *client,
GAsyncResult *result,
GError **error)
{
- GSimpleAsyncResult *simple;
-
- g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
- g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (client), nm_client_add_connection_async), NULL);
-
- simple = G_SIMPLE_ASYNC_RESULT (result);
- if (g_simple_async_result_propagate_error (simple, error))
- return NULL;
- return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
+ return _add_connection_call_finish (client,
+ result,
+ nm_client_add_connection_async,
+ NULL,
+ error);
}
/**
@@ -1956,33 +2044,15 @@ nm_client_add_connection2 (NMClient *client,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GSimpleAsyncResult *simple;
- GError *error = NULL;
-
- g_return_if_fail (NM_IS_CLIENT (client));
- g_return_if_fail (g_variant_is_of_type (settings, G_VARIANT_TYPE ("a{sa{sv}}")));
- g_return_if_fail (!args || g_variant_is_of_type (args, G_VARIANT_TYPE ("a{sv}")));
-
- if (!_nm_client_check_nm_running (client, &error)) {
- g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error);
- return;
- }
-
- simple = g_simple_async_result_new (G_OBJECT (client),
- callback,
- user_data,
- nm_client_add_connection2);
- if (cancellable)
- g_simple_async_result_set_check_cancellable (simple, cancellable);
-
- nm_remote_settings_add_connection2 (NM_CLIENT_GET_PRIVATE (client)->settings,
- settings,
- flags,
- args,
- ignore_out_result,
- cancellable,
- add_connection2_cb,
- simple);
+ _add_connection_call (client,
+ nm_client_add_connection2,
+ ignore_out_result,
+ settings,
+ flags,
+ args,
+ cancellable,
+ callback,
+ user_data);
}
/**
@@ -2006,21 +2076,11 @@ nm_client_add_connection2_finish (NMClient *client,
GVariant **out_result,
GError **error)
{
- GSimpleAsyncResult *simple;
- AddConnection2CbData *data;
-
- g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
- g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (client), nm_client_add_connection2), NULL);
-
- simple = G_SIMPLE_ASYNC_RESULT (result);
- if (g_simple_async_result_propagate_error (simple, error)) {
- NM_SET_OUT (out_result, NULL);
- return NULL;
- }
-
- data = g_simple_async_result_get_op_res_gpointer (simple);
- NM_SET_OUT (out_result, g_variant_ref (data->results));
- return g_object_ref (data->connection);
+ return _add_connection_call_finish (client,
+ result,
+ nm_client_add_connection2,
+ out_result,
+ error);
}
/**
diff --git a/libnm/nm-remote-settings.c b/libnm/nm-remote-settings.c
index d07a1a551a..0a95ce3050 100644
--- a/libnm/nm-remote-settings.c
+++ b/libnm/nm-remote-settings.c
@@ -59,24 +59,20 @@ static guint signals[LAST_SIGNAL] = { 0 };
typedef struct {
CList add_lst;
NMRemoteSettings *self;
- NMRemoteSettingAddConnection2Callback callback;
- gpointer user_data;
- GCancellable *cancellable;
- char *path;
- GVariant *results;
+ GTask *task;
+ char *connection_path;
+ GVariant *extra_results;
gulong cancellable_id;
- NMSettingsAddConnection2Flags flags;
- bool ignore_out_result:1;
} AddConnectionInfo;
static AddConnectionInfo *
-_add_connection_info_find (NMRemoteSettings *self, const char *path)
+_add_connection_info_find (NMRemoteSettings *self, const char *connection_path)
{
NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
AddConnectionInfo *info;
c_list_for_each_entry (info, &priv->add_lst_head, add_lst) {
- if (nm_streq0 (info->path, path))
+ if (nm_streq (info->connection_path, connection_path))
return info;
}
return NULL;
@@ -91,38 +87,31 @@ _add_connection_info_complete (AddConnectionInfo *info,
c_list_unlink_stale (&info->add_lst);
- nm_clear_g_signal_handler (info->cancellable, &info->cancellable_id);
+ nm_clear_g_signal_handler (g_task_get_cancellable (info->task), &info->cancellable_id);
- if ( info->cancellable
- && !nm_utils_error_is_cancelled (error_take, FALSE)) {
- GError *error2 = NULL;
+ if (error_take)
+ g_task_return_error (info->task, error_take);
+ else {
+ NMAddConnectionResultData *result_info;
- if (g_cancellable_set_error_if_cancelled (info->cancellable, &error2)) {
- g_clear_error (&error_take);
- error_take = error2;
- connection = NULL;
- }
+ result_info = g_slice_new (NMAddConnectionResultData);
+ *result_info = (NMAddConnectionResultData) {
+ .connection = g_object_ref (connection),
+ .extra_results = g_steal_pointer (&info->extra_results),
+ };
+ g_task_return_pointer (info->task, result_info, (GDestroyNotify) nm_add_connection_result_data_free);
}
- info->callback (info->self,
- connection,
- connection ? info->results : NULL,
- error_take,
- info->user_data);
-
- g_clear_error (&error_take);
-
+ g_object_unref (info->task);
g_object_unref (info->self);
- nm_g_object_unref (info->cancellable);
- nm_clear_g_free (&info->path);
- nm_g_variant_unref (info->results);
-
+ g_free (info->connection_path);
+ nm_g_variant_unref (info->extra_results);
nm_g_slice_free (info);
}
static void
-_add_connection_info_cancelled (GCancellable *cancellable,
- AddConnectionInfo *info)
+_wait_for_connection_cancelled_cb (GCancellable *cancellable,
+ AddConnectionInfo *info)
{
_add_connection_info_complete (info,
NULL,
@@ -246,8 +235,12 @@ connection_added (NMRemoteSettings *self,
else
g_signal_stop_emission (self, signals[CONNECTION_ADDED], 0);
+ /* FIXME: this doesn't look right. Why does it not care about whether the
+ * connection is visible? Anyway, this will be reworked. */
path = nm_connection_get_path (NM_CONNECTION (remote));
- info = _add_connection_info_find (self, path);
+ info = path
+ ? _add_connection_info_find (self, path)
+ : NULL;
if (info)
_add_connection_info_complete (info, remote, NULL);
}
@@ -278,51 +271,42 @@ nm_remote_settings_get_connections (NMRemoteSettings *settings)
return NM_REMOTE_SETTINGS_GET_PRIVATE (settings)->visible_connections;
}
-static void
-add_connection_done (GObject *proxy, GAsyncResult *result, gpointer user_data)
+void
+nm_remote_settings_wait_for_connection (NMRemoteSettings *self,
+ const char *connection_path,
+ GVariant *extra_results_take,
+ GTask *task_take)
{
- AddConnectionInfo *info = user_data;
- GError *error = NULL;
-
- if ( info->ignore_out_result
- && info->flags == NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK) {
- nmdbus_settings_call_add_connection_finish (NMDBUS_SETTINGS (proxy),
- &info->path,
- result,
- &error);
- } else if ( info->ignore_out_result
- && info->flags == NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY) {
- nmdbus_settings_call_add_connection_unsaved_finish (NMDBUS_SETTINGS (proxy),
- &info->path,
- result,
- &error);
- } else {
- nmdbus_settings_call_add_connection2_finish (NMDBUS_SETTINGS (proxy),
- &info->path,
- &info->results,
- result,
- &error);
- if (info->ignore_out_result) {
- /* despite we have the result, the caller didn't ask for it.
- * Through it away, so we consistently don't return a result. */
- nm_clear_pointer (&info->results, g_variant_unref);
- }
- }
+ NMRemoteSettingsPrivate *priv;
+ gs_unref_object GTask *task = task_take;
+ gs_unref_variant GVariant *extra_results = extra_results_take;
+ GCancellable *cancellable;
+ AddConnectionInfo *info;
- if (error) {
- g_dbus_error_strip_remote_error (error);
- _add_connection_info_complete (info, NULL, error);
- return;
- }
+ priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
+
+ /* FIXME: there is no timeout for how long we wait. But this entire
+ * code will be reworked, also that we have a suitable GMainContext
+ * where we can schedule the timeout (we shouldn't use g_main_context_default()). */
+
+ info = g_slice_new (AddConnectionInfo);
+ *info = (AddConnectionInfo) {
+ .self = g_object_ref (self),
+ .connection_path = g_strdup (connection_path),
+ .task = g_steal_pointer (&task),
+ .extra_results = g_steal_pointer (&extra_results),
+ };
+ c_list_link_tail (&priv->add_lst_head, &info->add_lst);
+ cancellable = g_task_get_cancellable (info->task);
/* On success, we still have to wait until the connection is fully
* initialized before calling the callback.
*/
- if (info->cancellable) {
+ if (cancellable) {
gulong id;
- id = g_cancellable_connect (info->cancellable,
- G_CALLBACK (_add_connection_info_cancelled),
+ id = g_cancellable_connect (cancellable,
+ G_CALLBACK (_wait_for_connection_cancelled_cb),
info,
NULL);
if (id == 0) {
@@ -331,67 +315,10 @@ add_connection_done (GObject *proxy, GAsyncResult *result, gpointer user_data)
} else
info->cancellable_id = id;
}
-}
-
-void
-nm_remote_settings_add_connection2 (NMRemoteSettings *self,
- GVariant *settings,
- NMSettingsAddConnection2Flags flags,
- GVariant *args,
- gboolean ignore_out_result,
- GCancellable *cancellable,
- NMRemoteSettingAddConnection2Callback callback,
- gpointer user_data)
-{
- NMRemoteSettingsPrivate *priv;
- AddConnectionInfo *info;
- nm_assert (NM_IS_REMOTE_SETTINGS (self));
- nm_assert (g_variant_is_of_type (settings, G_VARIANT_TYPE ("a{sa{sv}}")));
- nm_assert (!args || g_variant_is_of_type (args, G_VARIANT_TYPE ("a{sv}")));
- nm_assert (callback);
-
- priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
-
- info = g_slice_new (AddConnectionInfo);
- *info = (AddConnectionInfo) {
- .self = g_object_ref (self),
- .cancellable = nm_g_object_ref (cancellable),
- .flags = flags,
- .ignore_out_result = ignore_out_result,
- .callback = callback,
- .user_data = user_data,
- };
- c_list_link_tail (&priv->add_lst_head, &info->add_lst);
-
- /* Although AddConnection2() being capable to handle also AddConnection() and
- * AddConnectionUnsaved() variants, we prefer to use the old D-Bus methods when
- * they are sufficient. The reason is that libnm should avoid hard dependencies
- * on 1.20 API whenever possible. */
- if ( ignore_out_result
- && flags == NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK) {
- nmdbus_settings_call_add_connection (priv->proxy,
- settings,
- cancellable,
- add_connection_done,
- info);
- } else if ( ignore_out_result
- && flags == NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY) {
- nmdbus_settings_call_add_connection_unsaved (priv->proxy,
- settings,
- cancellable,
- add_connection_done,
- info);
- } else {
- nmdbus_settings_call_add_connection2 (priv->proxy,
- settings,
- flags,
- args
- ?: g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0),
- cancellable,
- add_connection_done,
- info);
- }
+ /* FIXME: OK, we just assume the the connection is here, and that we are bound
+ * to get the suitable signal when the connection is fully initalized (or failed).
+ * Obviously, that needs reworking. */
}
/*****************************************************************************/
diff --git a/libnm/nm-remote-settings.h b/libnm/nm-remote-settings.h
index 5dc5d01bb8..2ebc39d659 100644
--- a/libnm/nm-remote-settings.h
+++ b/libnm/nm-remote-settings.h
@@ -60,19 +60,19 @@ NMRemoteConnection *nm_remote_settings_get_connection_by_path (NMRemoteSettings
NMRemoteConnection *nm_remote_settings_get_connection_by_uuid (NMRemoteSettings *settings,
const char *uuid);
-typedef void (*NMRemoteSettingAddConnection2Callback) (NMRemoteSettings *self,
- NMRemoteConnection *connection,
- GVariant *results,
- GError *error,
- gpointer user_data);
-
-void nm_remote_settings_add_connection2 (NMRemoteSettings *self,
- GVariant *settings,
- NMSettingsAddConnection2Flags flags,
- GVariant *args,
- gboolean ignore_out_result,
- GCancellable *cancellable,
- NMRemoteSettingAddConnection2Callback callback,
- gpointer user_data);
+typedef struct {
+ NMRemoteConnection *connection;
+ GVariant *extra_results;
+} NMAddConnectionResultData;
+
+void nm_add_connection_result_data_free (NMAddConnectionResultData *result_data);
+
+NM_AUTO_DEFINE_FCN0 (NMAddConnectionResultData *, _nm_auto_free_add_connection_result_data, nm_add_connection_result_data_free)
+#define nm_auto_free_add_connection_result_data nm_auto (_nm_auto_free_add_connection_result_data)
+
+void nm_remote_settings_wait_for_connection (NMRemoteSettings *settings,
+ const char *connection_path,
+ GVariant *extra_results_take,
+ GTask *task_take);
#endif /* __NM_REMOTE_SETTINGS_H__ */