/gio/tests/gdbus-tests.c

https://github.com/rikaunite/gst-opera_glib · C · 265 lines · 190 code · 43 blank · 32 comment · 11 complexity · d989f33a389e3d029a107ca46f7de05e MD5 · raw file

  1. /* GLib testing framework examples and tests
  2. *
  3. * Copyright (C) 2008-2010 Red Hat, Inc.
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General
  16. * Public License along with this library; if not, write to the
  17. * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  18. * Boston, MA 02111-1307, USA.
  19. *
  20. * Author: David Zeuthen <davidz@redhat.com>
  21. */
  22. #include <gio/gio.h>
  23. #include <unistd.h>
  24. #include "gdbus-tests.h"
  25. /* ---------------------------------------------------------------------------------------------------- */
  26. typedef struct
  27. {
  28. GMainLoop *loop;
  29. gboolean timed_out;
  30. } PropertyNotifyData;
  31. static void
  32. on_property_notify (GObject *object,
  33. GParamSpec *pspec,
  34. gpointer user_data)
  35. {
  36. PropertyNotifyData *data = user_data;
  37. g_main_loop_quit (data->loop);
  38. }
  39. static gboolean
  40. on_property_notify_timeout (gpointer user_data)
  41. {
  42. PropertyNotifyData *data = user_data;
  43. data->timed_out = TRUE;
  44. g_main_loop_quit (data->loop);
  45. return TRUE;
  46. }
  47. gboolean
  48. _g_assert_property_notify_run (gpointer object,
  49. const gchar *property_name)
  50. {
  51. gchar *s;
  52. gulong handler_id;
  53. guint timeout_id;
  54. PropertyNotifyData data;
  55. data.loop = g_main_loop_new (NULL, FALSE);
  56. data.timed_out = FALSE;
  57. s = g_strdup_printf ("notify::%s", property_name);
  58. handler_id = g_signal_connect (object,
  59. s,
  60. G_CALLBACK (on_property_notify),
  61. &data);
  62. g_free (s);
  63. timeout_id = g_timeout_add (30 * 1000,
  64. on_property_notify_timeout,
  65. &data);
  66. g_main_loop_run (data.loop);
  67. g_signal_handler_disconnect (object, handler_id);
  68. g_source_remove (timeout_id);
  69. g_main_loop_unref (data.loop);
  70. return data.timed_out;
  71. }
  72. /* ---------------------------------------------------------------------------------------------------- */
  73. typedef struct
  74. {
  75. GMainLoop *loop;
  76. gboolean timed_out;
  77. } SignalReceivedData;
  78. static void
  79. on_signal_received (gpointer user_data)
  80. {
  81. SignalReceivedData *data = user_data;
  82. g_main_loop_quit (data->loop);
  83. }
  84. static gboolean
  85. on_signal_received_timeout (gpointer user_data)
  86. {
  87. SignalReceivedData *data = user_data;
  88. data->timed_out = TRUE;
  89. g_main_loop_quit (data->loop);
  90. return TRUE;
  91. }
  92. gboolean
  93. _g_assert_signal_received_run (gpointer object,
  94. const gchar *signal_name)
  95. {
  96. gulong handler_id;
  97. guint timeout_id;
  98. SignalReceivedData data;
  99. data.loop = g_main_loop_new (NULL, FALSE);
  100. data.timed_out = FALSE;
  101. handler_id = g_signal_connect_swapped (object,
  102. signal_name,
  103. G_CALLBACK (on_signal_received),
  104. &data);
  105. timeout_id = g_timeout_add (30 * 1000,
  106. on_signal_received_timeout,
  107. &data);
  108. g_main_loop_run (data.loop);
  109. g_signal_handler_disconnect (object, handler_id);
  110. g_source_remove (timeout_id);
  111. g_main_loop_unref (data.loop);
  112. return data.timed_out;
  113. }
  114. /* ---------------------------------------------------------------------------------------------------- */
  115. GDBusConnection *
  116. _g_bus_get_priv (GBusType bus_type,
  117. GCancellable *cancellable,
  118. GError **error)
  119. {
  120. gchar *address;
  121. GDBusConnection *ret;
  122. ret = NULL;
  123. address = g_dbus_address_get_for_bus_sync (bus_type, cancellable, error);
  124. if (address == NULL)
  125. goto out;
  126. ret = g_dbus_connection_new_for_address_sync (address,
  127. G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
  128. G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
  129. NULL, /* GDBusAuthObserver */
  130. cancellable,
  131. error);
  132. g_free (address);
  133. out:
  134. return ret;
  135. }
  136. /* ---------------------------------------------------------------------------------------------------- */
  137. #if 1
  138. /* toggle refs are not easy to use (maybe not even safe) when multiple
  139. * threads are involved so implement this by busy-waiting for now
  140. */
  141. gboolean
  142. _g_object_wait_for_single_ref_do (gpointer object)
  143. {
  144. guint num_ms_elapsed;
  145. gboolean timed_out;
  146. timed_out = FALSE;
  147. num_ms_elapsed = 0;
  148. while (TRUE)
  149. {
  150. if (G_OBJECT (object)->ref_count == 1)
  151. goto out;
  152. if (num_ms_elapsed > 30000)
  153. {
  154. timed_out = TRUE;
  155. goto out;
  156. }
  157. usleep (10 * 1000);
  158. num_ms_elapsed += 10;
  159. }
  160. out:
  161. return timed_out;
  162. }
  163. #else
  164. typedef struct
  165. {
  166. GMainLoop *loop;
  167. gboolean timed_out;
  168. } WaitSingleRefData;
  169. static gboolean
  170. on_wait_single_ref_timeout (gpointer user_data)
  171. {
  172. WaitSingleRefData *data = user_data;
  173. data->timed_out = TRUE;
  174. g_main_loop_quit (data->loop);
  175. return TRUE;
  176. }
  177. static void
  178. on_wait_for_single_ref_toggled (gpointer user_data,
  179. GObject *object,
  180. gboolean is_last_ref)
  181. {
  182. WaitSingleRefData *data = user_data;
  183. g_main_loop_quit (data->loop);
  184. }
  185. gboolean
  186. _g_object_wait_for_single_ref_do (gpointer object)
  187. {
  188. WaitSingleRefData data;
  189. guint timeout_id;
  190. data.timed_out = FALSE;
  191. if (G_OBJECT (object)->ref_count == 1)
  192. goto out;
  193. data.loop = g_main_loop_new (NULL, FALSE);
  194. timeout_id = g_timeout_add (30 * 1000,
  195. on_wait_single_ref_timeout,
  196. &data);
  197. g_object_add_toggle_ref (G_OBJECT (object),
  198. on_wait_for_single_ref_toggled,
  199. &data);
  200. /* the reference could have been removed between us checking the
  201. * ref_count and the toggle ref being added
  202. */
  203. if (G_OBJECT (object)->ref_count == 2)
  204. goto single_ref_already;
  205. g_object_unref (object);
  206. g_main_loop_run (data.loop);
  207. g_object_ref (object);
  208. single_ref_already:
  209. g_object_remove_toggle_ref (object,
  210. on_wait_for_single_ref_toggled,
  211. &data);
  212. g_source_remove (timeout_id);
  213. g_main_loop_unref (data.loop);
  214. out:
  215. if (data.timed_out)
  216. {
  217. g_printerr ("b ref_count is %d\n", G_OBJECT (object)->ref_count);
  218. }
  219. return data.timed_out;
  220. }
  221. #endif
  222. /* ---------------------------------------------------------------------------------------------------- */