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