1#include <config.h>
2#include "test-utils.h"
3
4typedef struct
5{
6  DBusLoop *loop;
7  DBusConnection *connection;
8
9} CData;
10
11static dbus_bool_t
12connection_watch_callback (DBusWatch     *watch,
13                           unsigned int   condition,
14                           void          *data)
15{
16  return dbus_watch_handle (watch, condition);
17}
18
19static dbus_bool_t
20add_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
31static void
32remove_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
41static void
42connection_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
49static dbus_bool_t
50add_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
59static void
60remove_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
69static void
70dispatch_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
83static void
84cdata_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
94static CData*
95cdata_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
113dbus_bool_t
114test_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
171void
172test_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
192typedef struct
193{
194  DBusLoop *loop;
195  DBusServer *server;
196} ServerData;
197
198static void
199serverdata_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
209static ServerData*
210serverdata_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
228static dbus_bool_t
229server_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
241static dbus_bool_t
242add_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
252static void
253remove_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
262static void
263server_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
270static dbus_bool_t
271add_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
280static void
281remove_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
290dbus_bool_t
291test_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
329void
330test_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