| /* GLib testing framework examples and tests |
| * |
| * Copyright (C) 2008-2010 Red Hat, Inc. |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General |
| * Public License along with this library; if not, see <http://www.gnu.org/licenses/>. |
| * |
| * Author: David Zeuthen <davidz@redhat.com> |
| */ |
| |
| #include <gio/gio.h> |
| #ifndef _MSC_VER |
| #include <unistd.h> |
| #endif |
| |
| #include "gdbus-tests.h" |
| |
| /* ---------------------------------------------------------------------------------------------------- */ |
| |
| typedef struct |
| { |
| GMainLoop *loop; |
| gboolean timed_out; |
| } PropertyNotifyData; |
| |
| static void |
| on_property_notify (GObject *object, |
| GParamSpec *pspec, |
| gpointer user_data) |
| { |
| PropertyNotifyData *data = user_data; |
| g_main_loop_quit (data->loop); |
| } |
| |
| static gboolean |
| on_property_notify_timeout (gpointer user_data) |
| { |
| PropertyNotifyData *data = user_data; |
| data->timed_out = TRUE; |
| g_main_loop_quit (data->loop); |
| return G_SOURCE_CONTINUE; |
| } |
| |
| gboolean |
| _g_assert_property_notify_run (gpointer object, |
| const gchar *property_name) |
| { |
| gchar *s; |
| gulong handler_id; |
| guint timeout_id; |
| PropertyNotifyData data; |
| |
| data.loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE); |
| data.timed_out = FALSE; |
| s = g_strdup_printf ("notify::%s", property_name); |
| handler_id = g_signal_connect (object, |
| s, |
| G_CALLBACK (on_property_notify), |
| &data); |
| g_free (s); |
| timeout_id = g_timeout_add_seconds (30, |
| on_property_notify_timeout, |
| &data); |
| g_main_loop_run (data.loop); |
| g_signal_handler_disconnect (object, handler_id); |
| g_source_remove (timeout_id); |
| g_main_loop_unref (data.loop); |
| |
| return data.timed_out; |
| } |
| |
| static gboolean |
| _give_up (gpointer data) |
| { |
| g_error ("%s", (const gchar *) data); |
| g_return_val_if_reached (G_SOURCE_CONTINUE); |
| } |
| |
| typedef struct |
| { |
| GMainContext *context; |
| gboolean name_appeared; |
| gboolean unwatch_complete; |
| } WatchData; |
| |
| static void |
| name_appeared_cb (GDBusConnection *connection, |
| const gchar *name, |
| const gchar *name_owner, |
| gpointer user_data) |
| { |
| WatchData *data = user_data; |
| |
| g_assert (name_owner != NULL); |
| data->name_appeared = TRUE; |
| g_main_context_wakeup (data->context); |
| } |
| |
| static void |
| watch_free_cb (gpointer user_data) |
| { |
| WatchData *data = user_data; |
| |
| data->unwatch_complete = TRUE; |
| g_main_context_wakeup (data->context); |
| } |
| |
| void |
| ensure_gdbus_testserver_up (GDBusConnection *connection, |
| GMainContext *context) |
| { |
| GSource *timeout_source = NULL; |
| guint watch_id; |
| WatchData data = { context, FALSE, FALSE }; |
| |
| g_main_context_push_thread_default (context); |
| |
| watch_id = g_bus_watch_name_on_connection (connection, |
| "com.example.TestService", |
| G_BUS_NAME_WATCHER_FLAGS_NONE, |
| name_appeared_cb, |
| NULL, |
| &data, |
| watch_free_cb); |
| |
| timeout_source = g_timeout_source_new_seconds (60); |
| g_source_set_callback (timeout_source, _give_up, |
| "waited more than ~ 60s for gdbus-testserver to take its bus name", |
| NULL); |
| g_source_attach (timeout_source, context); |
| |
| while (!data.name_appeared) |
| g_main_context_iteration (context, TRUE); |
| |
| g_bus_unwatch_name (watch_id); |
| watch_id = 0; |
| |
| while (!data.unwatch_complete) |
| g_main_context_iteration (context, TRUE); |
| |
| g_source_destroy (timeout_source); |
| g_source_unref (timeout_source); |
| |
| g_main_context_pop_thread_default (context); |
| } |
| |
| /* ---------------------------------------------------------------------------------------------------- */ |
| |
| typedef struct |
| { |
| GMainLoop *loop; |
| gboolean timed_out; |
| } SignalReceivedData; |
| |
| static void |
| on_signal_received (gpointer user_data) |
| { |
| SignalReceivedData *data = user_data; |
| g_main_loop_quit (data->loop); |
| } |
| |
| static gboolean |
| on_signal_received_timeout (gpointer user_data) |
| { |
| SignalReceivedData *data = user_data; |
| data->timed_out = TRUE; |
| g_main_loop_quit (data->loop); |
| return G_SOURCE_CONTINUE; |
| } |
| |
| gboolean |
| _g_assert_signal_received_run (gpointer object, |
| const gchar *signal_name) |
| { |
| gulong handler_id; |
| guint timeout_id; |
| SignalReceivedData data; |
| |
| data.loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE); |
| data.timed_out = FALSE; |
| handler_id = g_signal_connect_swapped (object, |
| signal_name, |
| G_CALLBACK (on_signal_received), |
| &data); |
| timeout_id = g_timeout_add_seconds (30, |
| on_signal_received_timeout, |
| &data); |
| g_main_loop_run (data.loop); |
| g_signal_handler_disconnect (object, handler_id); |
| g_source_remove (timeout_id); |
| g_main_loop_unref (data.loop); |
| |
| return data.timed_out; |
| } |
| |
| /* ---------------------------------------------------------------------------------------------------- */ |
| |
| GDBusConnection * |
| _g_bus_get_priv (GBusType bus_type, |
| GCancellable *cancellable, |
| GError **error) |
| { |
| gchar *address; |
| GDBusConnection *ret; |
| |
| ret = NULL; |
| |
| address = g_dbus_address_get_for_bus_sync (bus_type, cancellable, error); |
| if (address == NULL) |
| goto out; |
| |
| ret = g_dbus_connection_new_for_address_sync (address, |
| G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | |
| G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION, |
| NULL, /* GDBusAuthObserver */ |
| cancellable, |
| error); |
| g_free (address); |
| |
| out: |
| return ret; |
| } |
| |
| /* ---------------------------------------------------------------------------------------------------- */ |