diff options
author | Thomas Haller <thaller@redhat.com> | 2019-10-07 09:48:09 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2019-10-15 20:33:24 +0200 |
commit | bb31c612b8f53b60181738f724fa6d8213f0de5d (patch) | |
tree | 335ee9b629a435698fede7c2bd608a85265abb78 | |
parent | 4f7a912934f64794e94885f31698ce8d14aabedd (diff) | |
download | NetworkManager-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.c | 286 | ||||
-rw-r--r-- | libnm/nm-remote-settings.c | 187 | ||||
-rw-r--r-- | libnm/nm-remote-settings.h | 28 |
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__ */ |