1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24: #include <config.h>
25:
26: #ifdef DBUS_BUILD_TESTS
27: #include "test.h"
28: #include <dbus/dbus-internals.h>
29: #include <dbus/dbus-list.h>
30:
31:
32:
33:
34:
35: static DBusList *clients = NULL;
36: static DBusLoop *client_loop = NULL;
37:
38: static dbus_bool_t
39: client_watch_callback (DBusWatch *watch,
40: unsigned int condition,
41: void *data)
42: {
43:
44:
45:
46:
47:
48: return dbus_watch_handle (watch, condition);
49: }
50:
51: static dbus_bool_t
52: add_client_watch (DBusWatch *watch,
53: void *data)
54: {
55: DBusConnection *connection = data;
56:
57: return _dbus_loop_add_watch (client_loop,
58: watch, client_watch_callback, connection,
59: NULL);
60: }
61:
62: static void
63: remove_client_watch (DBusWatch *watch,
64: void *data)
65: {
66: DBusConnection *connection = data;
67:
68: _dbus_loop_remove_watch (client_loop,
69: watch, client_watch_callback, connection);
70: }
71:
72: static void
73: client_timeout_callback (DBusTimeout *timeout,
74: void *data)
75: {
76: DBusConnection *connection = data;
77:
78: dbus_connection_ref (connection);
79:
80:
81: dbus_timeout_handle (timeout);
82:
83: dbus_connection_unref (connection);
84: }
85:
86: static dbus_bool_t
87: add_client_timeout (DBusTimeout *timeout,
88: void *data)
89: {
90: DBusConnection *connection = data;
91:
92: return _dbus_loop_add_timeout (client_loop, timeout, client_timeout_callback, connection, NULL);
93: }
94:
95: static void
96: remove_client_timeout (DBusTimeout *timeout,
97: void *data)
98: {
99: DBusConnection *connection = data;
100:
101: _dbus_loop_remove_timeout (client_loop, timeout, client_timeout_callback, connection);
102: }
103:
104: static DBusHandlerResult
105: client_disconnect_filter (DBusConnection *connection,
106: DBusMessage *message,
107: void *user_data)
108: {
109: if (!dbus_message_is_signal (message,
110: DBUS_INTERFACE_LOCAL,
111: "Disconnected"))
112: return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
113:
114: _dbus_verbose ("Removing client %p in disconnect handler\n",
115: connection);
116:
117: _dbus_list_remove (&clients, connection);
118:
119: dbus_connection_unref (connection);
120:
121: if (clients == NULL)
122: {
123: _dbus_loop_unref (client_loop);
124: client_loop = NULL;
125: }
126:
127: return DBUS_HANDLER_RESULT_HANDLED;
128: }
129:
130: dbus_bool_t
131: bus_setup_debug_client (DBusConnection *connection)
132: {
133: dbus_bool_t retval;
134:
135: if (!dbus_connection_add_filter (connection,
136: client_disconnect_filter,
137: NULL, NULL))
138: return FALSE;
139:
140: retval = FALSE;
141:
142: if (client_loop == NULL)
143: {
144: client_loop = _dbus_loop_new ();
145: if (client_loop == NULL)
146: goto out;
147: }
148:
149: if (!dbus_connection_set_watch_functions (connection,
150: add_client_watch,
151: remove_client_watch,
152: NULL,
153: connection,
154: NULL))
155: goto out;
156:
157: if (!dbus_connection_set_timeout_functions (connection,
158: add_client_timeout,
159: remove_client_timeout,
160: NULL,
161: connection, NULL))
162: goto out;
163:
164: if (!_dbus_list_append (&clients, connection))
165: goto out;
166:
167: retval = TRUE;
168:
169: out:
170: if (!retval)
171: {
172: dbus_connection_remove_filter (connection,
173: client_disconnect_filter,
174: NULL);
175:
176: dbus_connection_set_watch_functions (connection,
177: NULL, NULL, NULL, NULL, NULL);
178: dbus_connection_set_timeout_functions (connection,
179: NULL, NULL, NULL, NULL, NULL);
180:
181: _dbus_list_remove_last (&clients, connection);
182:
183: if (clients == NULL)
184: {
185: _dbus_loop_unref (client_loop);
186: client_loop = NULL;
187: }
188: }
189:
190: return retval;
191: }
192:
193: void
194: bus_test_clients_foreach (BusConnectionForeachFunction function,
195: void *data)
196: {
197: DBusList *link;
198:
199: link = _dbus_list_get_first_link (&clients);
200: while (link != NULL)
201: {
202: DBusConnection *connection = link->data;
203: DBusList *next = _dbus_list_get_next_link (&clients, link);
204:
205: if (!(* function) (connection, data))
206: break;
207:
208: link = next;
209: }
210: }
211:
212: dbus_bool_t
213: bus_test_client_listed (DBusConnection *connection)
214: {
215: DBusList *link;
216:
217: link = _dbus_list_get_first_link (&clients);
218: while (link != NULL)
219: {
220: DBusConnection *c = link->data;
221: DBusList *next = _dbus_list_get_next_link (&clients, link);
222:
223: if (c == connection)
224: return TRUE;
225:
226: link = next;
227: }
228:
229: return FALSE;
230: }
231:
232: void
233: bus_test_run_clients_loop (dbus_bool_t block_once)
234: {
235: if (client_loop == NULL)
236: return;
237:
238: _dbus_verbose ("---> Dispatching on \"client side\"\n");
239:
240:
241:
242:
243: _dbus_loop_dispatch (client_loop);
244:
245:
246: if (block_once)
247: {
248: _dbus_verbose ("---> blocking on \"client side\"\n");
249: _dbus_loop_iterate (client_loop, TRUE);
250: }
251:
252:
253: while (_dbus_loop_iterate (client_loop, FALSE))
254: ;
255:
256: _dbus_verbose ("---> Done dispatching on \"client side\"\n");
257: }
258:
259: void
260: bus_test_run_bus_loop (BusContext *context,
261: dbus_bool_t block_once)
262: {
263: _dbus_verbose ("---> Dispatching on \"server side\"\n");
264:
265:
266:
267:
268: _dbus_loop_dispatch (bus_context_get_loop (context));
269:
270:
271: if (block_once)
272: {
273: _dbus_verbose ("---> blocking on \"server side\"\n");
274: _dbus_loop_iterate (bus_context_get_loop (context), TRUE);
275: }
276:
277:
278: while (_dbus_loop_iterate (bus_context_get_loop (context), FALSE))
279: ;
280:
281: _dbus_verbose ("---> Done dispatching on \"server side\"\n");
282: }
283:
284: void
285: bus_test_run_everything (BusContext *context)
286: {
287: while (_dbus_loop_iterate (bus_context_get_loop (context), FALSE) ||
288: (client_loop == NULL || _dbus_loop_iterate (client_loop, FALSE)))
289: ;
290: }
291:
292: BusContext*
293: bus_context_new_test (const DBusString *test_data_dir,
294: const char *filename)
295: {
296: DBusError error;
297: DBusString config_file;
298: DBusString relative;
299: BusContext *context;
300:
301: if (!_dbus_string_init (&config_file))
302: {
303: _dbus_warn ("No memory\n");
304: return NULL;
305: }
306:
307: if (!_dbus_string_copy (test_data_dir, 0,
308: &config_file, 0))
309: {
310: _dbus_warn ("No memory\n");
311: _dbus_string_free (&config_file);
312: return NULL;
313: }
314:
315: _dbus_string_init_const (&relative, filename);
316:
317: if (!_dbus_concat_dir_and_file (&config_file, &relative))
318: {
319: _dbus_warn ("No memory\n");
320: _dbus_string_free (&config_file);
321: return NULL;
322: }
323:
324: dbus_error_init (&error);
325: context = bus_context_new (&config_file, FALSE, -1, -1, &error);
326: if (context == NULL)
327: {
328: _DBUS_ASSERT_ERROR_IS_SET (&error);
329:
330: _dbus_warn ("Failed to create debug bus context from configuration file %s: %s\n",
331: filename, error.message);
332:
333: dbus_error_free (&error);
334:
335: _dbus_string_free (&config_file);
336:
337: return NULL;
338: }
339:
340: _dbus_string_free (&config_file);
341:
342: return context;
343: }
344:
345: #endif