diff options
| author | Michael Biebl <biebl@debian.org> | 2020-10-05 22:27:18 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2020-10-05 22:27:18 +0200 |
| commit | aafc1dbe4712c86189bbc1d4d54ad8cb4c69be7e (patch) | |
| tree | a2a9bb4d007339a0b1304540388230ccedac32bd /shared/nm-test-utils-impl.c | |
| parent | e7b44ef4c80907346ec7492a09c45277459924fc (diff) | |
New upstream version 1.27.90 upstream/1.27.90
Diffstat (limited to 'shared/nm-test-utils-impl.c')
| -rw-r--r-- | shared/nm-test-utils-impl.c | 971 |
1 files changed, 487 insertions, 484 deletions
diff --git a/shared/nm-test-utils-impl.c b/shared/nm-test-utils-impl.c index ce7cc8d1..7b71484e 100644 --- a/shared/nm-test-utils-impl.c +++ b/shared/nm-test-utils-impl.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Copyright (C) 2010 - 2015 Red Hat, Inc. */ @@ -12,626 +12,629 @@ #include "nm-test-libnm-utils.h" -#define NMTSTC_NM_SERVICE NM_BUILD_SRCDIR"/tools/test-networkmanager-service.py" +#define NMTSTC_NM_SERVICE NM_BUILD_SRCDIR "/tools/test-networkmanager-service.py" /*****************************************************************************/ static gboolean -name_exists (GDBusConnection *c, const char *name) +name_exists(GDBusConnection *c, const char *name) { - GVariant *reply; - gboolean exists = FALSE; - - reply = g_dbus_connection_call_sync (c, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS, - "GetNameOwner", - g_variant_new ("(s)", name), - NULL, - G_DBUS_CALL_FLAGS_NO_AUTO_START, - -1, - NULL, - NULL); - if (reply != NULL) { - exists = TRUE; - g_variant_unref (reply); - } - - return exists; + GVariant *reply; + gboolean exists = FALSE; + + reply = g_dbus_connection_call_sync(c, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "GetNameOwner", + g_variant_new("(s)", name), + NULL, + G_DBUS_CALL_FLAGS_NO_AUTO_START, + -1, + NULL, + NULL); + if (reply != NULL) { + exists = TRUE; + g_variant_unref(reply); + } + + return exists; } typedef struct { - GMainLoop *mainloop; - GDBusConnection *bus; - int exit_code; - bool exited:1; - bool name_found:1; + GMainLoop * mainloop; + GDBusConnection *bus; + int exit_code; + bool exited : 1; + bool name_found : 1; } ServiceInitWaitData; static gboolean -_service_init_wait_probe_name (gpointer user_data) +_service_init_wait_probe_name(gpointer user_data) { - ServiceInitWaitData *data = user_data; + ServiceInitWaitData *data = user_data; - if (!name_exists (data->bus, "org.freedesktop.NetworkManager")) - return G_SOURCE_CONTINUE; + if (!name_exists(data->bus, "org.freedesktop.NetworkManager")) + return G_SOURCE_CONTINUE; - data->name_found = TRUE; - g_main_loop_quit (data->mainloop); - return G_SOURCE_REMOVE; + data->name_found = TRUE; + g_main_loop_quit(data->mainloop); + return G_SOURCE_REMOVE; } static void -_service_init_wait_child_wait (GPid pid, - int status, - gpointer user_data) +_service_init_wait_child_wait(GPid pid, int status, gpointer user_data) { - ServiceInitWaitData *data = user_data; + ServiceInitWaitData *data = user_data; - data->exited = TRUE; - data->exit_code = status; - g_main_loop_quit (data->mainloop); + data->exited = TRUE; + data->exit_code = status; + g_main_loop_quit(data->mainloop); } NMTstcServiceInfo * -nmtstc_service_available (NMTstcServiceInfo *info) +nmtstc_service_available(NMTstcServiceInfo *info) { - gs_free char *m = NULL; + gs_free char *m = NULL; - if (info) - return info; + if (info) + return info; - /* This happens, when test-networkmanager-service.py exits with 77 status - * code. */ - m = g_strdup_printf ("missing dependency for running NetworkManager stub service %s", NMTSTC_NM_SERVICE); - g_test_skip (m); - return NULL; + /* This happens, when test-networkmanager-service.py exits with 77 status + * code. */ + m = g_strdup_printf("missing dependency for running NetworkManager stub service %s", + NMTSTC_NM_SERVICE); + g_test_skip(m); + return NULL; } NMTstcServiceInfo * -nmtstc_service_init (void) +nmtstc_service_init(void) { - NMTstcServiceInfo *info; - const char *args[] = { TEST_NM_PYTHON, NMTSTC_NM_SERVICE, NULL }; - GError *error = NULL; - - info = g_malloc0 (sizeof (*info)); - - info->bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); - g_assert_no_error (error); - - /* Spawn the test service. info->keepalive_fd will be a pipe to the service's - * stdin; if it closes, the service will exit immediately. We use this to - * make sure the service exits if the test program crashes. - */ - g_spawn_async_with_pipes (NULL, (char **) args, NULL, - G_SPAWN_SEARCH_PATH - | G_SPAWN_DO_NOT_REAP_CHILD, - NULL, NULL, - &info->pid, &info->keepalive_fd, NULL, NULL, &error); - g_assert_no_error (error); - - { - nm_auto_unref_gsource GSource *timeout_source = NULL; - nm_auto_unref_gsource GSource *child_source = NULL; - GMainContext *context = g_main_context_new (); - ServiceInitWaitData data = { - .bus = info->bus, - .mainloop = g_main_loop_new (context, FALSE), - }; - gboolean had_timeout; - - timeout_source = g_timeout_source_new (50); - g_source_set_callback (timeout_source, _service_init_wait_probe_name, &data, NULL); - g_source_attach (timeout_source, context); - - child_source = g_child_watch_source_new (info->pid); - g_source_set_callback (child_source, G_SOURCE_FUNC (_service_init_wait_child_wait), &data, NULL); - g_source_attach (child_source, context); - - had_timeout = !nmtst_main_loop_run (data.mainloop, 30000); - - g_source_destroy (timeout_source); - g_source_destroy (child_source); - g_main_loop_unref (data.mainloop); - g_main_context_unref (context); - - if (had_timeout) - g_error ("test service %s did not start in time", NMTSTC_NM_SERVICE); - if (!data.name_found) { - g_assert (data.exited); - info->pid = NM_PID_T_INVAL; - nmtstc_service_cleanup (info); - - if ( WIFEXITED (data.exit_code) - && WEXITSTATUS (data.exit_code) == 77) { - /* If the stub service exited with status 77 it means that it decided - * that it cannot conduct the tests and the test should be (gracefully) - * skip. The likely reason for that, is that libnm is not available - * via pygobject. */ - return NULL; - } - g_error ("test service %s exited with error code %d", NMTSTC_NM_SERVICE, data.exit_code); - } - } - - /* Grab a proxy to our fake NM service to trigger tests */ - info->proxy = g_dbus_proxy_new_sync (info->bus, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | - G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - NULL, - NM_DBUS_SERVICE, - NM_DBUS_PATH, - "org.freedesktop.NetworkManager.LibnmGlibTest", - NULL, &error); - g_assert_no_error (error); - - return info; + NMTstcServiceInfo *info; + const char * args[] = {TEST_NM_PYTHON, NMTSTC_NM_SERVICE, NULL}; + GError * error = NULL; + + info = g_malloc0(sizeof(*info)); + + info->bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error(error); + + /* Spawn the test service. info->keepalive_fd will be a pipe to the service's + * stdin; if it closes, the service will exit immediately. We use this to + * make sure the service exits if the test program crashes. + */ + g_spawn_async_with_pipes(NULL, + (char **) args, + NULL, + G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, + NULL, + NULL, + &info->pid, + &info->keepalive_fd, + NULL, + NULL, + &error); + g_assert_no_error(error); + + { + nm_auto_unref_gsource GSource *timeout_source = NULL; + nm_auto_unref_gsource GSource *child_source = NULL; + GMainContext * context = g_main_context_new(); + ServiceInitWaitData data = { + .bus = info->bus, + .mainloop = g_main_loop_new(context, FALSE), + }; + gboolean had_timeout; + + timeout_source = g_timeout_source_new(50); + g_source_set_callback(timeout_source, _service_init_wait_probe_name, &data, NULL); + g_source_attach(timeout_source, context); + + child_source = g_child_watch_source_new(info->pid); + g_source_set_callback(child_source, + G_SOURCE_FUNC(_service_init_wait_child_wait), + &data, + NULL); + g_source_attach(child_source, context); + + had_timeout = !nmtst_main_loop_run(data.mainloop, 30000); + + g_source_destroy(timeout_source); + g_source_destroy(child_source); + g_main_loop_unref(data.mainloop); + g_main_context_unref(context); + + if (had_timeout) + g_error("test service %s did not start in time", NMTSTC_NM_SERVICE); + if (!data.name_found) { + g_assert(data.exited); + info->pid = NM_PID_T_INVAL; + nmtstc_service_cleanup(info); + + if (WIFEXITED(data.exit_code) && WEXITSTATUS(data.exit_code) == 77) { + /* If the stub service exited with status 77 it means that it decided + * that it cannot conduct the tests and the test should be (gracefully) + * skip. The likely reason for that, is that libnm is not available + * via pygobject. */ + return NULL; + } + g_error("test service %s exited with error code %d", NMTSTC_NM_SERVICE, data.exit_code); + } + } + + /* Grab a proxy to our fake NM service to trigger tests */ + info->proxy = g_dbus_proxy_new_sync(info->bus, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES + | G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS + | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + NM_DBUS_SERVICE, + NM_DBUS_PATH, + "org.freedesktop.NetworkManager.LibnmGlibTest", + NULL, + &error); + g_assert_no_error(error); + + return info; } void -nmtstc_service_cleanup (NMTstcServiceInfo *info) +nmtstc_service_cleanup(NMTstcServiceInfo *info) { - int ret; - gint64 t; - int status; + int ret; + gint64 t; + int status; - if (!info) - return; + if (!info) + return; - nm_close (nm_steal_fd (&info->keepalive_fd)); + nm_close(nm_steal_fd(&info->keepalive_fd)); - g_clear_object (&info->proxy); + g_clear_object(&info->proxy); - if (info->pid != NM_PID_T_INVAL) { - kill (info->pid, SIGTERM); + if (info->pid != NM_PID_T_INVAL) { + kill(info->pid, SIGTERM); - t = g_get_monotonic_time (); + t = g_get_monotonic_time(); again_wait: - ret = waitpid (info->pid, &status, WNOHANG); - if (ret == 0) { - if (t + 2000000 < g_get_monotonic_time ()) { - kill (info->pid, SIGKILL); - g_error ("child process %lld did not exit within timeout", (long long) info->pid); - } - g_usleep (G_USEC_PER_SEC / 50); - goto again_wait; - } - if (ret == -1 && errno == EINTR) - goto again_wait; - - g_assert (ret == info->pid); - } - - g_assert (!name_exists (info->bus, "org.freedesktop.NetworkManager")); - - g_clear_object (&info->bus); - - memset (info, 0, sizeof (*info)); - g_free (info); + ret = waitpid(info->pid, &status, WNOHANG); + if (ret == 0) { + if (t + 2000000 < g_get_monotonic_time()) { + kill(info->pid, SIGKILL); + g_error("child process %lld did not exit within timeout", (long long) info->pid); + } + g_usleep(G_USEC_PER_SEC / 50); + goto again_wait; + } + if (ret == -1 && errno == EINTR) + goto again_wait; + + g_assert(ret == info->pid); + } + + g_assert(!name_exists(info->bus, "org.freedesktop.NetworkManager")); + + g_clear_object(&info->bus); + + memset(info, 0, sizeof(*info)); + g_free(info); } typedef struct { - GMainLoop *loop; - const char *ifname; - const char *path; - NMDevice *device; + GMainLoop * loop; + const char *ifname; + const char *path; + NMDevice * device; } AddDeviceInfo; static void -device_added_cb (NMClient *client, - NMDevice *device, - gpointer user_data) +device_added_cb(NMClient *client, NMDevice *device, gpointer user_data) { - AddDeviceInfo *info = user_data; + AddDeviceInfo *info = user_data; - g_assert (info); - g_assert (!info->device); + g_assert(info); + g_assert(!info->device); - g_assert (NM_IS_DEVICE (device)); - g_assert_cmpstr (nm_object_get_path (NM_OBJECT (device)), ==, info->path); - g_assert_cmpstr (nm_device_get_iface (device), ==, info->ifname); + g_assert(NM_IS_DEVICE(device)); + g_assert_cmpstr(nm_object_get_path(NM_OBJECT(device)), ==, info->path); + g_assert_cmpstr(nm_device_get_iface(device), ==, info->ifname); - info->device = g_object_ref (device); - g_main_loop_quit (info->loop); + info->device = g_object_ref(device); + g_main_loop_quit(info->loop); } static GVariant * -call_add_wired_device (GDBusProxy *proxy, const char *ifname, const char *hwaddr, - const char **subchannels, GError **error) +call_add_wired_device(GDBusProxy * proxy, + const char * ifname, + const char * hwaddr, + const char **subchannels, + GError ** error) { - const char *empty[] = { NULL }; - - if (!hwaddr) - hwaddr = "/"; - if (!subchannels) - subchannels = empty; - - return g_dbus_proxy_call_sync (proxy, - "AddWiredDevice", - g_variant_new ("(ss^as)", ifname, hwaddr, subchannels), - G_DBUS_CALL_FLAGS_NO_AUTO_START, - 3000, - NULL, - error); + const char *empty[] = {NULL}; + + if (!hwaddr) + hwaddr = "/"; + if (!subchannels) + subchannels = empty; + + return g_dbus_proxy_call_sync(proxy, + "AddWiredDevice", + g_variant_new("(ss^as)", ifname, hwaddr, subchannels), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + error); } static GVariant * -call_add_device (GDBusProxy *proxy, const char *method, const char *ifname, GError **error) +call_add_device(GDBusProxy *proxy, const char *method, const char *ifname, GError **error) { - return g_dbus_proxy_call_sync (proxy, - method, - g_variant_new ("(s)", ifname), - G_DBUS_CALL_FLAGS_NO_AUTO_START, - 3000, - NULL, - error); + return g_dbus_proxy_call_sync(proxy, + method, + g_variant_new("(s)", ifname), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + error); } static NMDevice * -add_device_common (NMTstcServiceInfo *sinfo, - NMClient *client, - const char *method, - const char *ifname, - const char *hwaddr, - const char **subchannels) +add_device_common(NMTstcServiceInfo *sinfo, + NMClient * client, + const char * method, + const char * ifname, + const char * hwaddr, + const char ** subchannels) { - nm_auto_unref_gmainloop GMainLoop *loop = NULL; - gs_unref_variant GVariant *ret = NULL; - gs_free_error GError *error = NULL; - AddDeviceInfo info; + nm_auto_unref_gmainloop GMainLoop *loop = NULL; + gs_unref_variant GVariant *ret = NULL; + gs_free_error GError *error = NULL; + AddDeviceInfo info; - g_assert (sinfo); - g_assert (NM_IS_CLIENT (client)); + g_assert(sinfo); + g_assert(NM_IS_CLIENT(client)); - if (nm_streq0 (method, "AddWiredDevice")) - ret = call_add_wired_device (sinfo->proxy, ifname, hwaddr, subchannels, &error); - else - ret = call_add_device (sinfo->proxy, method, ifname, &error); + if (nm_streq0(method, "AddWiredDevice")) + ret = call_add_wired_device(sinfo->proxy, ifname, hwaddr, subchannels, &error); + else + ret = call_add_device(sinfo->proxy, method, ifname, &error); - nmtst_assert_success (ret, error); - g_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)"); + nmtst_assert_success(ret, error); + g_assert_cmpstr(g_variant_get_type_string(ret), ==, "(o)"); - /* Wait for NMClient to find the device */ + /* Wait for NMClient to find the device */ - loop = g_main_loop_new (nm_client_get_main_context (client), FALSE); + loop = g_main_loop_new(nm_client_get_main_context(client), FALSE); - info = (AddDeviceInfo) { - .ifname = ifname, - .loop = loop, - }; - g_variant_get (ret, "(&o)", &info.path); + info = (AddDeviceInfo){ + .ifname = ifname, + .loop = loop, + }; + g_variant_get(ret, "(&o)", &info.path); - g_signal_connect (client, - NM_CLIENT_DEVICE_ADDED, - G_CALLBACK (device_added_cb), - &info); + g_signal_connect(client, NM_CLIENT_DEVICE_ADDED, G_CALLBACK(device_added_cb), &info); - if (!nmtst_main_loop_run (loop, 5000)) - g_assert_not_reached (); + if (!nmtst_main_loop_run(loop, 5000)) + g_assert_not_reached(); - g_signal_handlers_disconnect_by_func (client, device_added_cb, &info); + g_signal_handlers_disconnect_by_func(client, device_added_cb, &info); - g_assert (NM_IS_DEVICE (info.device)); + g_assert(NM_IS_DEVICE(info.device)); - g_assert (info.device == nm_client_get_device_by_path (client, nm_object_get_path (NM_OBJECT (info.device)))); - g_object_unref (info.device); - return info.device; + g_assert(info.device + == nm_client_get_device_by_path(client, nm_object_get_path(NM_OBJECT(info.device)))); + g_object_unref(info.device); + return info.device; } NMDevice * -nmtstc_service_add_device (NMTstcServiceInfo *sinfo, NMClient *client, - const char *method, const char *ifname) +nmtstc_service_add_device(NMTstcServiceInfo *sinfo, + NMClient * client, + const char * method, + const char * ifname) { - return add_device_common (sinfo, client, method, ifname, NULL, NULL); + return add_device_common(sinfo, client, method, ifname, NULL, NULL); } NMDevice * -nmtstc_service_add_wired_device (NMTstcServiceInfo *sinfo, NMClient *client, - const char *ifname, const char *hwaddr, - const char **subchannels) +nmtstc_service_add_wired_device(NMTstcServiceInfo *sinfo, + NMClient * client, + const char * ifname, + const char * hwaddr, + const char ** subchannels) { - return add_device_common (sinfo, client, "AddWiredDevice", ifname, hwaddr, subchannels); + return add_device_common(sinfo, client, "AddWiredDevice", ifname, hwaddr, subchannels); } void -nmtstc_service_add_connection (NMTstcServiceInfo *sinfo, - NMConnection *connection, - gboolean verify_connection, - char **out_path) +nmtstc_service_add_connection(NMTstcServiceInfo *sinfo, + NMConnection * connection, + gboolean verify_connection, + char ** out_path) { - nmtstc_service_add_connection_variant (sinfo, - nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL), - verify_connection, - out_path); + nmtstc_service_add_connection_variant( + sinfo, + nm_connection_to_dbus(connection, NM_CONNECTION_SERIALIZE_ALL), + verify_connection, + out_path); } void -nmtstc_service_add_connection_variant (NMTstcServiceInfo *sinfo, - GVariant *connection, - gboolean verify_connection, - char **out_path) +nmtstc_service_add_connection_variant(NMTstcServiceInfo *sinfo, + GVariant * connection, + gboolean verify_connection, + char ** out_path) { - GVariant *result; - GError *error = NULL; - - g_assert (sinfo); - g_assert (G_IS_DBUS_PROXY (sinfo->proxy)); - g_assert (g_variant_is_of_type (connection, G_VARIANT_TYPE ("a{sa{sv}}"))); - - result = g_dbus_proxy_call_sync (sinfo->proxy, - "AddConnection", - g_variant_new ("(vb)", connection, verify_connection), - G_DBUS_CALL_FLAGS_NO_AUTO_START, - 3000, - NULL, - &error); - g_assert_no_error (error); - g_assert (g_variant_is_of_type (result, G_VARIANT_TYPE ("(o)"))); - if (out_path) - g_variant_get (result, "(o)", out_path); - g_variant_unref (result); + GVariant *result; + GError * error = NULL; + + g_assert(sinfo); + g_assert(G_IS_DBUS_PROXY(sinfo->proxy)); + g_assert(g_variant_is_of_type(connection, G_VARIANT_TYPE("a{sa{sv}}"))); + + result = g_dbus_proxy_call_sync(sinfo->proxy, + "AddConnection", + g_variant_new("(vb)", connection, verify_connection), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + g_assert_no_error(error); + g_assert(g_variant_is_of_type(result, G_VARIANT_TYPE("(o)"))); + if (out_path) + g_variant_get(result, "(o)", out_path); + g_variant_unref(result); } void -nmtstc_service_update_connection (NMTstcServiceInfo *sinfo, - const char *path, - NMConnection *connection, - gboolean verify_connection) +nmtstc_service_update_connection(NMTstcServiceInfo *sinfo, + const char * path, + NMConnection * connection, + gboolean verify_connection) { - if (!path) - path = nm_connection_get_path (connection); - g_assert (path); - - nmtstc_service_update_connection_variant (sinfo, - path, - nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL), - verify_connection); + if (!path) + path = nm_connection_get_path(connection); + g_assert(path); + + nmtstc_service_update_connection_variant( + sinfo, + path, + nm_connection_to_dbus(connection, NM_CONNECTION_SERIALIZE_ALL), + verify_connection); } void -nmtstc_service_update_connection_variant (NMTstcServiceInfo *sinfo, - const char *path, - GVariant *connection, - gboolean verify_connection) +nmtstc_service_update_connection_variant(NMTstcServiceInfo *sinfo, + const char * path, + GVariant * connection, + gboolean verify_connection) { - GVariant *result; - GError *error = NULL; - - g_assert (sinfo); - g_assert (G_IS_DBUS_PROXY (sinfo->proxy)); - g_assert (g_variant_is_of_type (connection, G_VARIANT_TYPE ("a{sa{sv}}"))); - g_assert (path && path[0] == '/'); - - result = g_dbus_proxy_call_sync (sinfo->proxy, - "UpdateConnection", - g_variant_new ("(ovb)", path, connection, verify_connection), - G_DBUS_CALL_FLAGS_NO_AUTO_START, - 3000, - NULL, - &error); - g_assert_no_error (error); - g_assert (g_variant_is_of_type (result, G_VARIANT_TYPE ("()"))); - g_variant_unref (result); + GVariant *result; + GError * error = NULL; + + g_assert(sinfo); + g_assert(G_IS_DBUS_PROXY(sinfo->proxy)); + g_assert(g_variant_is_of_type(connection, G_VARIANT_TYPE("a{sa{sv}}"))); + g_assert(path && path[0] == '/'); + + result = g_dbus_proxy_call_sync(sinfo->proxy, + "UpdateConnection", + g_variant_new("(ovb)", path, connection, verify_connection), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + g_assert_no_error(error); + g_assert(g_variant_is_of_type(result, G_VARIANT_TYPE("()"))); + g_variant_unref(result); } /*****************************************************************************/ typedef struct { - GType gtype; - GMainLoop *loop; - GObject *obj; - bool call_nm_client_new_async:1; + GType gtype; + GMainLoop *loop; + GObject * obj; + bool call_nm_client_new_async : 1; } NMTstcObjNewData; static void -_context_object_new_do_cb (GObject *source_object, - GAsyncResult *res, - gpointer user_data) +_context_object_new_do_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) { - NMTstcObjNewData *d = user_data; - gs_free_error GError *error = NULL; + NMTstcObjNewData *d = user_data; + gs_free_error GError *error = NULL; - g_assert (!d->obj); + g_assert(!d->obj); - if (d->call_nm_client_new_async) { - d->obj = G_OBJECT (nm_client_new_finish (res, - nmtst_get_rand_bool () ? &error : NULL)); - } else { - d->obj = g_async_initable_new_finish (G_ASYNC_INITABLE (source_object), - res, - nmtst_get_rand_bool () ? &error : NULL); - } + if (d->call_nm_client_new_async) { + d->obj = G_OBJECT(nm_client_new_finish(res, nmtst_get_rand_bool() ? &error : NULL)); + } else { + d->obj = g_async_initable_new_finish(G_ASYNC_INITABLE(source_object), + res, + nmtst_get_rand_bool() ? &error : NULL); + } - nmtst_assert_success (G_IS_OBJECT (d->obj), error); - g_assert (G_OBJECT_TYPE (d->obj) == d->gtype); + nmtst_assert_success(G_IS_OBJECT(d->obj), error); + g_assert(G_OBJECT_TYPE(d->obj) == d->gtype); - g_main_loop_quit (d->loop); + g_main_loop_quit(d->loop); } static GObject * -_context_object_new_do (GType gtype, - gboolean sync, - const char *first_property_name, - va_list var_args) +_context_object_new_do(GType gtype, + gboolean sync, + const char *first_property_name, + va_list var_args) { - gs_free_error GError *error = NULL; - GObject *obj; - - /* Create a GObject instance synchronously, and arbitrarily use either - * the sync or async constructor. - * - * Note that the sync and async construct differ in one important aspect: - * the async constructor iterates the current g_main_context_get_thread_default(), - * while the sync constructor does not! Aside from that, both should behave - * pretty much the same way. */ - - if (sync) { - nm_auto_destroy_and_unref_gsource GSource *source = NULL; - - if (nmtst_get_rand_bool ()) { - /* the current main context must not be iterated! */ - source = g_idle_source_new (); - g_source_set_callback (source, nmtst_g_source_assert_not_called, NULL, NULL); - g_source_attach (source, g_main_context_get_thread_default ()); - } - - if ( gtype != NM_TYPE_CLIENT - || first_property_name - || nmtst_get_rand_bool ()) { - gboolean success; - - if ( first_property_name - || nmtst_get_rand_bool ()) - obj = g_object_new_valist (gtype, first_property_name, var_args); - else - obj = g_object_new (gtype, NULL); - - success = g_initable_init (G_INITABLE (obj), - NULL, - nmtst_get_rand_bool () ? &error : NULL); - nmtst_assert_success (success, error); - } else { - obj = G_OBJECT (nm_client_new (NULL, - nmtst_get_rand_bool () ? &error : NULL)); - } - } else { - nm_auto_unref_gmainloop GMainLoop *loop = NULL; - NMTstcObjNewData d = { - .gtype = gtype, - .loop = NULL, - }; - gs_unref_object GObject *obj2 = NULL; - - loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE); - d.loop = loop; - - if ( gtype != NM_TYPE_CLIENT - || first_property_name - || nmtst_get_rand_bool ()) { - if ( first_property_name - || nmtst_get_rand_bool ()) - obj2 = g_object_new_valist (gtype, first_property_name, var_args); - else - obj2 = g_object_new (gtype, NULL); - - g_async_initable_init_async (G_ASYNC_INITABLE (obj2), - G_PRIORITY_DEFAULT, - NULL, - _context_object_new_do_cb, - &d); - } else { - d.call_nm_client_new_async = TRUE; - nm_client_new_async (NULL, - _context_object_new_do_cb, - &d); - } - g_main_loop_run (loop); - obj = d.obj; - g_assert (!obj2 || obj == obj2); - } - - nmtst_assert_success (G_IS_OBJECT (obj), error); - g_assert (G_OBJECT_TYPE (obj) == gtype); - return obj; + gs_free_error GError *error = NULL; + GObject * obj; + + /* Create a GObject instance synchronously, and arbitrarily use either + * the sync or async constructor. + * + * Note that the sync and async construct differ in one important aspect: + * the async constructor iterates the current g_main_context_get_thread_default(), + * while the sync constructor does not! Aside from that, both should behave + * pretty much the same way. */ + + if (sync) { + nm_auto_destroy_and_unref_gsource GSource *source = NULL; + + if (nmtst_get_rand_bool()) { + /* the current main context must not be iterated! */ + source = g_idle_source_new(); + g_source_set_callback(source, nmtst_g_source_assert_not_called, NULL, NULL); + g_source_attach(source, g_main_context_get_thread_default()); + } + + if (gtype != NM_TYPE_CLIENT || first_property_name || nmtst_get_rand_bool()) { + gboolean success; + + if (first_property_name || nmtst_get_rand_bool()) + obj = g_object_new_valist(gtype, first_property_name, var_args); + else + obj = g_object_new(gtype, NULL); + + success = g_initable_init(G_INITABLE(obj), NULL, nmtst_get_rand_bool() ? &error : NULL); + nmtst_assert_success(success, error); + } else { + obj = G_OBJECT(nm_client_new(NULL, nmtst_get_rand_bool() ? &error : NULL)); + } + } else { + nm_auto_unref_gmainloop GMainLoop *loop = NULL; + NMTstcObjNewData d = { + .gtype = gtype, + .loop = NULL, + }; + gs_unref_object GObject *obj2 = NULL; + + loop = g_main_loop_new(g_main_context_get_thread_default(), FALSE); + d.loop = loop; + + if (gtype != NM_TYPE_CLIENT || first_property_name || nmtst_get_rand_bool()) { + if (first_property_name || nmtst_get_rand_bool()) + obj2 = g_object_new_valist(gtype, first_property_name, var_args); + else + obj2 = g_object_new(gtype, NULL); + + g_async_initable_init_async(G_ASYNC_INITABLE(obj2), + G_PRIORITY_DEFAULT, + NULL, + _context_object_new_do_cb, + &d); + } else { + d.call_nm_client_new_async = TRUE; + nm_client_new_async(NULL, _context_object_new_do_cb, &d); + } + g_main_loop_run(loop); + obj = d.obj; + g_assert(!obj2 || obj == obj2); + } + + nmtst_assert_success(G_IS_OBJECT(obj), error); + g_assert(G_OBJECT_TYPE(obj) == gtype); + return obj; } typedef struct { - GType gtype; - const char *first_property_name; - va_list var_args; - GMainLoop *loop; - GObject *obj; - bool sync; + GType gtype; + const char *first_property_name; + va_list var_args; + GMainLoop * loop; + GObject * obj; + bool sync; } NewSyncInsideDispatchedData; static gboolean -_context_object_new_inside_loop_do (gpointer user_data) +_context_object_new_inside_loop_do(gpointer user_data) { - NewSyncInsideDispatchedData *d = user_data; + NewSyncInsideDispatchedData *d = user_data; - g_assert (d->loop); - g_assert (!d->obj); + g_assert(d->loop); + g_assert(!d->obj); - d->obj = nmtstc_context_object_new_valist (d->gtype, d->sync, d->first_property_name, d->var_args); - g_main_loop_quit (d->loop); - return G_SOURCE_CONTINUE; + d->obj = + nmtstc_context_object_new_valist(d->gtype, d->sync, d->first_property_name, d->var_args); + g_main_loop_quit(d->loop); + return G_SOURCE_CONTINUE; } static GObject * -_context_object_new_inside_loop (GType gtype, - gboolean sync, - const char *first_property_name, - va_list var_args) +_context_object_new_inside_loop(GType gtype, + gboolean sync, + const char *first_property_name, + va_list var_args) { - GMainContext *context = g_main_context_get_thread_default (); - nm_auto_unref_gmainloop GMainLoop *loop = g_main_loop_new (context, FALSE); - NewSyncInsideDispatchedData d = { - .gtype = gtype, - .first_property_name = first_property_name, - .sync = sync, - .loop = loop, - }; - nm_auto_destroy_and_unref_gsource GSource *source = NULL; + GMainContext * context = g_main_context_get_thread_default(); + nm_auto_unref_gmainloop GMainLoop *loop = g_main_loop_new(context, FALSE); + NewSyncInsideDispatchedData d = { + .gtype = gtype, + .first_property_name = first_property_name, + .sync = sync, + .loop = loop, + }; + nm_auto_destroy_and_unref_gsource GSource *source = NULL; - va_copy (d.var_args, var_args); + va_copy(d.var_args, var_args); - source = g_idle_source_new (); - g_source_set_callback (source, _context_object_new_inside_loop_do, &d, NULL); - g_source_attach (source, context); + source = g_idle_source_new(); + g_source_set_callback(source, _context_object_new_inside_loop_do, &d, NULL); + g_source_attach(source, context); - g_main_loop_run (loop); + g_main_loop_run(loop); - va_end (d.var_args); + va_end(d.var_args); - g_assert (G_IS_OBJECT (d.obj)); - g_assert (G_OBJECT_TYPE (d.obj) == gtype); - return d.obj; + g_assert(G_IS_OBJECT(d.obj)); + g_assert(G_OBJECT_TYPE(d.obj) == gtype); + return d.obj; } gpointer -nmtstc_context_object_new_valist (GType gtype, - gboolean allow_iterate_main_context, - const char *first_property_name, - va_list var_args) +nmtstc_context_object_new_valist(GType gtype, + gboolean allow_iterate_main_context, + const char *first_property_name, + va_list var_args) { - gboolean inside_loop; - gboolean sync; - - if (!allow_iterate_main_context) { - sync = TRUE; - inside_loop = FALSE; - } else { - /* The caller allows to iterate the main context. That that point, - * we can both use the synchronous and the asynchronous initialization, - * both should yield the same result. Choose one randomly. */ - sync = nmtst_get_rand_bool (); - inside_loop = ((nmtst_get_rand_uint32 () % 3) == 0); - } - - if (inside_loop) { - /* Create the obj on an idle handler of the current context. - * In practice, it should make no difference, which this check - * tries to prove. */ - return _context_object_new_inside_loop (gtype, sync, first_property_name, var_args); - } - - return _context_object_new_do (gtype, sync, first_property_name, var_args); + gboolean inside_loop; + gboolean sync; + + if (!allow_iterate_main_context) { + sync = TRUE; + inside_loop = FALSE; + } else { + /* The caller allows to iterate the main context. On that point, + * we can both use the synchronous and the asynchronous initialization, + * both should yield the same result. Choose one randomly. */ + sync = nmtst_get_rand_bool(); + inside_loop = ((nmtst_get_rand_uint32() % 3) == 0); + } + + if (inside_loop) { + /* Create the obj on an idle handler of the current context. + * In practice, it should make no difference, which this check + * tries to prove. */ + return _context_object_new_inside_loop(gtype, sync, first_property_name, var_args); + } + + return _context_object_new_do(gtype, sync, first_property_name, var_args); } gpointer -nmtstc_context_object_new (GType gtype, - gboolean allow_iterate_main_context, - const char *first_property_name, - ...) +nmtstc_context_object_new(GType gtype, + gboolean allow_iterate_main_context, + const char *first_property_name, + ...) { - GObject *obj; - va_list var_args; - - va_start (var_args, first_property_name); - obj = nmtstc_context_object_new_valist (gtype, allow_iterate_main_context, first_property_name, var_args); - va_end (var_args); - return obj; + GObject *obj; + va_list var_args; + + va_start(var_args, first_property_name); + obj = nmtstc_context_object_new_valist(gtype, + allow_iterate_main_context, + first_property_name, + var_args); + va_end(var_args); + return obj; } |