mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-19 08:38:08 +02:00
146 lines
4.8 KiB
C
146 lines
4.8 KiB
C
// SPDX-License-Identifier: LGPL-2.1+
|
|
|
|
#include "nm-default.h"
|
|
|
|
#include "nm-libnm-aux.h"
|
|
|
|
/*****************************************************************************/
|
|
|
|
NMClient *
|
|
nmc_client_new_async_valist (GCancellable *cancellable,
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data,
|
|
const char *first_property_name,
|
|
va_list ap)
|
|
{
|
|
NMClient *nmc;
|
|
|
|
nmc = NM_CLIENT (g_object_new_valist (NM_TYPE_CLIENT, first_property_name, ap));
|
|
g_async_initable_init_async (G_ASYNC_INITABLE (nmc),
|
|
G_PRIORITY_DEFAULT,
|
|
cancellable,
|
|
callback,
|
|
user_data);
|
|
return nmc;
|
|
}
|
|
|
|
NMClient *
|
|
nmc_client_new_async (GCancellable *cancellable,
|
|
GAsyncReadyCallback callback,
|
|
gpointer user_data,
|
|
const char *first_property_name,
|
|
...)
|
|
{
|
|
NMClient *nmc;
|
|
va_list ap;
|
|
|
|
va_start (ap, first_property_name);
|
|
nmc = nmc_client_new_async_valist (cancellable,
|
|
callback,
|
|
user_data,
|
|
first_property_name,
|
|
ap);
|
|
va_end (ap);
|
|
return nmc;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
typedef struct {
|
|
GMainLoop *main_loop;
|
|
NMClient *nmc;
|
|
GError *error;
|
|
} ClientCreateData;
|
|
|
|
static void
|
|
_nmc_client_new_waitsync_cb (GObject *source_object,
|
|
GAsyncResult *result,
|
|
gpointer user_data)
|
|
{
|
|
ClientCreateData *data = user_data;
|
|
|
|
g_async_initable_init_finish (G_ASYNC_INITABLE (source_object),
|
|
result,
|
|
&data->error);
|
|
g_main_loop_quit (data->main_loop);
|
|
}
|
|
|
|
/**
|
|
* nmc_client_new:
|
|
* @cancellable: the cancellable to abort the creation.
|
|
* @out_nmc: (out): (transfer full): if give, transfers a reference
|
|
* to the NMClient instance. Note that this never fails to create
|
|
* the NMClient GObject, but depending on the return value,
|
|
* the instance was successfully initialized or not.
|
|
* @error: the error if creation fails.
|
|
* @first_property_name: the name of the first property
|
|
* @...: the value of the first property, followed optionally by more
|
|
* name/value pairs, followed by %NULL
|
|
*
|
|
* Returns: %TRUE, if the client was successfully initalized.
|
|
*
|
|
* This uses nm_client_new_async() to create a NMClient instance,
|
|
* but it iterates the current GMainContext until the client is
|
|
* ready. As such, it waits for the client creation to complete
|
|
* (like sync nm_client_new()) but it iterates the caller's GMainContext
|
|
* (unlike sync nm_client_new()). This is often preferable, because
|
|
* sync nm_client_new() needs to create an additional internal GMainContext
|
|
* that it can iterate instead. That has a performance overhead that
|
|
* is often unnecessary.
|
|
*/
|
|
gboolean
|
|
nmc_client_new_waitsync (GCancellable *cancellable,
|
|
NMClient **out_nmc,
|
|
GError **error,
|
|
const char *first_property_name,
|
|
...)
|
|
{
|
|
gs_unref_object NMClient *nmc = NULL;
|
|
nm_auto_unref_gmainloop GMainLoop *main_loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
|
|
ClientCreateData data = {
|
|
.main_loop = main_loop,
|
|
};
|
|
va_list ap;
|
|
|
|
#if NM_MORE_ASSERTS > 10
|
|
/* The sync initialization of NMClient is generally a bad idea, because it
|
|
* brings the overhead of an additional GMainContext. Anyway, since our own
|
|
* code no longer uses that, we hardly test those code paths. But they should
|
|
* work just the same. Randomly use instead the sync initialization in a debug
|
|
* build... */
|
|
if ((g_random_int () % 2) == 0) {
|
|
gboolean success;
|
|
|
|
va_start (ap, first_property_name);
|
|
nmc = NM_CLIENT (g_object_new_valist (NM_TYPE_CLIENT, first_property_name, ap));
|
|
va_end (ap);
|
|
|
|
/* iterate the context at least once, just so that the behavior from POV of the
|
|
* caller is roughly the same. */
|
|
g_main_context_iteration (nm_client_get_main_context (nmc), FALSE);
|
|
|
|
success = g_initable_init (G_INITABLE (nmc),
|
|
cancellable,
|
|
error);
|
|
NM_SET_OUT (out_nmc, g_steal_pointer (&nmc));
|
|
return success;
|
|
}
|
|
#endif
|
|
|
|
va_start (ap, first_property_name);
|
|
nmc = nmc_client_new_async_valist (cancellable,
|
|
_nmc_client_new_waitsync_cb,
|
|
&data,
|
|
first_property_name,
|
|
ap);
|
|
va_end (ap);
|
|
|
|
g_main_loop_run (main_loop);
|
|
|
|
NM_SET_OUT (out_nmc, g_steal_pointer (&nmc));
|
|
if (data.error) {
|
|
g_propagate_error (error, data.error);
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|