gio/tests/socket-common.c: add a missing #ifdef G_OS_UNIX
[platform/upstream/glib.git] / gio / tests / gdbus-tests.c
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
23 #include <gio/gio.h>
24 #include <unistd.h>
25
26 #include "gdbus-tests.h"
27
28 /* ---------------------------------------------------------------------------------------------------- */
29
30 typedef struct
31 {
32   GMainLoop *loop;
33   gboolean   timed_out;
34 } PropertyNotifyData;
35
36 static void
37 on_property_notify (GObject    *object,
38                     GParamSpec *pspec,
39                     gpointer    user_data)
40 {
41   PropertyNotifyData *data = user_data;
42   g_main_loop_quit (data->loop);
43 }
44
45 static gboolean
46 on_property_notify_timeout (gpointer user_data)
47 {
48   PropertyNotifyData *data = user_data;
49   data->timed_out = TRUE;
50   g_main_loop_quit (data->loop);
51   return TRUE;
52 }
53
54 gboolean
55 _g_assert_property_notify_run (gpointer     object,
56                                const gchar *property_name)
57 {
58   gchar *s;
59   gulong handler_id;
60   guint timeout_id;
61   PropertyNotifyData data;
62
63   data.loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
64   data.timed_out = FALSE;
65   s = g_strdup_printf ("notify::%s", property_name);
66   handler_id = g_signal_connect (object,
67                                  s,
68                                  G_CALLBACK (on_property_notify),
69                                  &data);
70   g_free (s);
71   timeout_id = g_timeout_add (30 * 1000,
72                               on_property_notify_timeout,
73                               &data);
74   g_main_loop_run (data.loop);
75   g_signal_handler_disconnect (object, handler_id);
76   g_source_remove (timeout_id);
77   g_main_loop_unref (data.loop);
78
79   return data.timed_out;
80 }
81
82 /* ---------------------------------------------------------------------------------------------------- */
83
84 typedef struct
85 {
86   GMainLoop *loop;
87   gboolean   timed_out;
88 } SignalReceivedData;
89
90 static void
91 on_signal_received (gpointer user_data)
92 {
93   SignalReceivedData *data = user_data;
94   g_main_loop_quit (data->loop);
95 }
96
97 static gboolean
98 on_signal_received_timeout (gpointer user_data)
99 {
100   SignalReceivedData *data = user_data;
101   data->timed_out = TRUE;
102   g_main_loop_quit (data->loop);
103   return TRUE;
104 }
105
106 gboolean
107 _g_assert_signal_received_run (gpointer     object,
108                                const gchar *signal_name)
109 {
110   gulong handler_id;
111   guint timeout_id;
112   SignalReceivedData data;
113
114   data.loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
115   data.timed_out = FALSE;
116   handler_id = g_signal_connect_swapped (object,
117                                          signal_name,
118                                          G_CALLBACK (on_signal_received),
119                                          &data);
120   timeout_id = g_timeout_add (30 * 1000,
121                               on_signal_received_timeout,
122                               &data);
123   g_main_loop_run (data.loop);
124   g_signal_handler_disconnect (object, handler_id);
125   g_source_remove (timeout_id);
126   g_main_loop_unref (data.loop);
127
128   return data.timed_out;
129 }
130
131 /* ---------------------------------------------------------------------------------------------------- */
132
133 GDBusConnection *
134 _g_bus_get_priv (GBusType            bus_type,
135                  GCancellable       *cancellable,
136                  GError            **error)
137 {
138   gchar *address;
139   GDBusConnection *ret;
140
141   ret = NULL;
142
143   address = g_dbus_address_get_for_bus_sync (bus_type, cancellable, error);
144   if (address == NULL)
145     goto out;
146
147   ret = g_dbus_connection_new_for_address_sync (address,
148                                                 G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
149                                                 G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
150                                                 NULL, /* GDBusAuthObserver */
151                                                 cancellable,
152                                                 error);
153   g_free (address);
154
155  out:
156   return ret;
157 }
158
159 /* ---------------------------------------------------------------------------------------------------- */
160
161 #if 1
162 /* toggle refs are not easy to use (maybe not even safe) when multiple
163  * threads are involved so implement this by busy-waiting for now
164  */
165 gboolean
166 _g_object_wait_for_single_ref_do (gpointer object)
167 {
168   guint num_ms_elapsed;
169   gboolean timed_out;
170
171   timed_out = FALSE;
172   num_ms_elapsed = 0;
173
174   while (TRUE)
175     {
176       if (G_OBJECT (object)->ref_count == 1)
177         goto out;
178
179       if (num_ms_elapsed > 30000)
180         {
181           timed_out = TRUE;
182           goto out;
183         }
184
185       usleep (10 * 1000);
186       num_ms_elapsed += 10;
187     }
188
189  out:
190   return timed_out;
191 }
192
193 #else
194
195 typedef struct
196 {
197   GMainLoop *loop;
198   gboolean   timed_out;
199 } WaitSingleRefData;
200
201 static gboolean
202 on_wait_single_ref_timeout (gpointer user_data)
203 {
204   WaitSingleRefData *data = user_data;
205   data->timed_out = TRUE;
206   g_main_loop_quit (data->loop);
207   return TRUE;
208 }
209
210 static void
211 on_wait_for_single_ref_toggled (gpointer   user_data,
212                                 GObject   *object,
213                                 gboolean   is_last_ref)
214 {
215   WaitSingleRefData *data = user_data;
216   g_main_loop_quit (data->loop);
217 }
218
219 gboolean
220 _g_object_wait_for_single_ref_do (gpointer object)
221 {
222   WaitSingleRefData data;
223   guint timeout_id;
224
225   data.timed_out = FALSE;
226
227   if (G_OBJECT (object)->ref_count == 1)
228     goto out;
229
230   data.loop = g_main_loop_new (NULL, FALSE);
231   timeout_id = g_timeout_add (30 * 1000,
232                               on_wait_single_ref_timeout,
233                               &data);
234
235   g_object_add_toggle_ref (G_OBJECT (object),
236                            on_wait_for_single_ref_toggled,
237                            &data);
238   /* the reference could have been removed between us checking the
239    * ref_count and the toggle ref being added
240    */
241   if (G_OBJECT (object)->ref_count == 2)
242     goto single_ref_already;
243
244   g_object_unref (object);
245   g_main_loop_run (data.loop);
246   g_object_ref (object);
247
248 single_ref_already:
249   g_object_remove_toggle_ref (object,
250                               on_wait_for_single_ref_toggled,
251                               &data);
252
253   g_source_remove (timeout_id);
254   g_main_loop_unref (data.loop);
255
256  out:
257   if (data.timed_out)
258     {
259       g_printerr ("b ref_count is %d\n", G_OBJECT (object)->ref_count);
260     }
261   return data.timed_out;
262 }
263 #endif
264
265 /* ---------------------------------------------------------------------------------------------------- */