1 #include <config.h>
2 #include "test-utils.h"
3
4 typedef struct
5 {
6 DBusLoop *loop;
7 DBusConnection *connection;
8
9 } CData;
10
11 static dbus_bool_t
connection_watch_callback(DBusWatch * watch,unsigned int condition,void * data)12 connection_watch_callback (DBusWatch *watch,
13 unsigned int condition,
14 void *data)
15 {
16 return dbus_watch_handle (watch, condition);
17 }
18
19 static dbus_bool_t
add_watch(DBusWatch * watch,void * data)20 add_watch (DBusWatch *watch,
21 void *data)
22 {
23 CData *cd = data;
24
25 return _dbus_loop_add_watch (cd->loop,
26 watch,
27 connection_watch_callback,
28 cd, NULL);
29 }
30
31 static void
remove_watch(DBusWatch * watch,void * data)32 remove_watch (DBusWatch *watch,
33 void *data)
34 {
35 CData *cd = data;
36
37 _dbus_loop_remove_watch (cd->loop,
38 watch, connection_watch_callback, cd);
39 }
40
41 static void
connection_timeout_callback(DBusTimeout * timeout,void * data)42 connection_timeout_callback (DBusTimeout *timeout,
43 void *data)
44 {
45 /* Can return FALSE on OOM but we just let it fire again later */
46 dbus_timeout_handle (timeout);
47 }
48
49 static dbus_bool_t
add_timeout(DBusTimeout * timeout,void * data)50 add_timeout (DBusTimeout *timeout,
51 void *data)
52 {
53 CData *cd = data;
54
55 return _dbus_loop_add_timeout (cd->loop,
56 timeout, connection_timeout_callback, cd, NULL);
57 }
58
59 static void
remove_timeout(DBusTimeout * timeout,void * data)60 remove_timeout (DBusTimeout *timeout,
61 void *data)
62 {
63 CData *cd = data;
64
65 _dbus_loop_remove_timeout (cd->loop,
66 timeout, connection_timeout_callback, cd);
67 }
68
69 static void
dispatch_status_function(DBusConnection * connection,DBusDispatchStatus new_status,void * data)70 dispatch_status_function (DBusConnection *connection,
71 DBusDispatchStatus new_status,
72 void *data)
73 {
74 DBusLoop *loop = data;
75
76 if (new_status != DBUS_DISPATCH_COMPLETE)
77 {
78 while (!_dbus_loop_queue_dispatch (loop, connection))
79 _dbus_wait_for_memory ();
80 }
81 }
82
83 static void
cdata_free(void * data)84 cdata_free (void *data)
85 {
86 CData *cd = data;
87
88 dbus_connection_unref (cd->connection);
89 _dbus_loop_unref (cd->loop);
90
91 dbus_free (cd);
92 }
93
94 static CData*
cdata_new(DBusLoop * loop,DBusConnection * connection)95 cdata_new (DBusLoop *loop,
96 DBusConnection *connection)
97 {
98 CData *cd;
99
100 cd = dbus_new0 (CData, 1);
101 if (cd == NULL)
102 return NULL;
103
104 cd->loop = loop;
105 cd->connection = connection;
106
107 dbus_connection_ref (cd->connection);
108 _dbus_loop_ref (cd->loop);
109
110 return cd;
111 }
112
113 dbus_bool_t
test_connection_setup(DBusLoop * loop,DBusConnection * connection)114 test_connection_setup (DBusLoop *loop,
115 DBusConnection *connection)
116 {
117 CData *cd;
118
119 cd = NULL;
120
121 dbus_connection_set_dispatch_status_function (connection, dispatch_status_function,
122 loop, NULL);
123
124 cd = cdata_new (loop, connection);
125 if (cd == NULL)
126 goto nomem;
127
128 /* Because dbus-mainloop.c checks dbus_timeout_get_enabled(),
129 * dbus_watch_get_enabled() directly, we don't have to provide
130 * "toggled" callbacks.
131 */
132
133 if (!dbus_connection_set_watch_functions (connection,
134 add_watch,
135 remove_watch,
136 NULL,
137 cd, cdata_free))
138 goto nomem;
139
140
141 cd = cdata_new (loop, connection);
142 if (cd == NULL)
143 goto nomem;
144
145 if (!dbus_connection_set_timeout_functions (connection,
146 add_timeout,
147 remove_timeout,
148 NULL,
149 cd, cdata_free))
150 goto nomem;
151
152 if (dbus_connection_get_dispatch_status (connection) != DBUS_DISPATCH_COMPLETE)
153 {
154 if (!_dbus_loop_queue_dispatch (loop, connection))
155 goto nomem;
156 }
157
158 return TRUE;
159
160 nomem:
161 if (cd)
162 cdata_free (cd);
163
164 dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
165 dbus_connection_set_watch_functions (connection, NULL, NULL, NULL, NULL, NULL);
166 dbus_connection_set_timeout_functions (connection, NULL, NULL, NULL, NULL, NULL);
167
168 return FALSE;
169 }
170
171 void
test_connection_shutdown(DBusLoop * loop,DBusConnection * connection)172 test_connection_shutdown (DBusLoop *loop,
173 DBusConnection *connection)
174 {
175 if (!dbus_connection_set_watch_functions (connection,
176 NULL,
177 NULL,
178 NULL,
179 NULL, NULL))
180 _dbus_assert_not_reached ("setting watch functions to NULL failed");
181
182 if (!dbus_connection_set_timeout_functions (connection,
183 NULL,
184 NULL,
185 NULL,
186 NULL, NULL))
187 _dbus_assert_not_reached ("setting timeout functions to NULL failed");
188
189 dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
190 }
191
192 typedef struct
193 {
194 DBusLoop *loop;
195 DBusServer *server;
196 } ServerData;
197
198 static void
serverdata_free(void * data)199 serverdata_free (void *data)
200 {
201 ServerData *sd = data;
202
203 dbus_server_unref (sd->server);
204 _dbus_loop_unref (sd->loop);
205
206 dbus_free (sd);
207 }
208
209 static ServerData*
serverdata_new(DBusLoop * loop,DBusServer * server)210 serverdata_new (DBusLoop *loop,
211 DBusServer *server)
212 {
213 ServerData *sd;
214
215 sd = dbus_new0 (ServerData, 1);
216 if (sd == NULL)
217 return NULL;
218
219 sd->loop = loop;
220 sd->server = server;
221
222 dbus_server_ref (sd->server);
223 _dbus_loop_ref (sd->loop);
224
225 return sd;
226 }
227
228 static dbus_bool_t
server_watch_callback(DBusWatch * watch,unsigned int condition,void * data)229 server_watch_callback (DBusWatch *watch,
230 unsigned int condition,
231 void *data)
232 {
233 /* FIXME this can be done in dbus-mainloop.c
234 * if the code in activation.c for the babysitter
235 * watch handler is fixed.
236 */
237
238 return dbus_watch_handle (watch, condition);
239 }
240
241 static dbus_bool_t
add_server_watch(DBusWatch * watch,void * data)242 add_server_watch (DBusWatch *watch,
243 void *data)
244 {
245 ServerData *context = data;
246
247 return _dbus_loop_add_watch (context->loop,
248 watch, server_watch_callback, context,
249 NULL);
250 }
251
252 static void
remove_server_watch(DBusWatch * watch,void * data)253 remove_server_watch (DBusWatch *watch,
254 void *data)
255 {
256 ServerData *context = data;
257
258 _dbus_loop_remove_watch (context->loop,
259 watch, server_watch_callback, context);
260 }
261
262 static void
server_timeout_callback(DBusTimeout * timeout,void * data)263 server_timeout_callback (DBusTimeout *timeout,
264 void *data)
265 {
266 /* can return FALSE on OOM but we just let it fire again later */
267 dbus_timeout_handle (timeout);
268 }
269
270 static dbus_bool_t
add_server_timeout(DBusTimeout * timeout,void * data)271 add_server_timeout (DBusTimeout *timeout,
272 void *data)
273 {
274 ServerData *context = data;
275
276 return _dbus_loop_add_timeout (context->loop,
277 timeout, server_timeout_callback, context, NULL);
278 }
279
280 static void
remove_server_timeout(DBusTimeout * timeout,void * data)281 remove_server_timeout (DBusTimeout *timeout,
282 void *data)
283 {
284 ServerData *context = data;
285
286 _dbus_loop_remove_timeout (context->loop,
287 timeout, server_timeout_callback, context);
288 }
289
290 dbus_bool_t
test_server_setup(DBusLoop * loop,DBusServer * server)291 test_server_setup (DBusLoop *loop,
292 DBusServer *server)
293 {
294 ServerData *sd;
295
296 sd = serverdata_new (loop, server);
297 if (sd == NULL)
298 goto nomem;
299
300 if (!dbus_server_set_watch_functions (server,
301 add_server_watch,
302 remove_server_watch,
303 NULL,
304 sd,
305 serverdata_free))
306 {
307 return FALSE;
308 }
309
310 if (!dbus_server_set_timeout_functions (server,
311 add_server_timeout,
312 remove_server_timeout,
313 NULL,
314 sd, serverdata_free))
315 {
316 return FALSE;
317 }
318 return TRUE;
319
320 nomem:
321 if (sd)
322 serverdata_free (sd);
323
324 test_server_shutdown (loop, server);
325
326 return FALSE;
327 }
328
329 void
test_server_shutdown(DBusLoop * loop,DBusServer * server)330 test_server_shutdown (DBusLoop *loop,
331 DBusServer *server)
332 {
333 if (!dbus_server_set_watch_functions (server,
334 NULL, NULL, NULL,
335 NULL,
336 NULL))
337 _dbus_assert_not_reached ("setting watch functions to NULL failed");
338
339 if (!dbus_server_set_timeout_functions (server,
340 NULL, NULL, NULL,
341 NULL,
342 NULL))
343 _dbus_assert_not_reached ("setting timeout functions to NULL failed");
344 }
345