4 #define DBUS_COMPILATION /* cheat and use DBusList */
5 #include <dbus/dbus-list.h>
6 #undef DBUS_COMPILATION
11 /* Cheesy main loop used in test programs. Any real app would use the
12 * GLib or Qt or other non-sucky main loops.
16 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
18 static int watch_list_serial = 0;
19 static DBusList *watches = NULL;
20 static dbus_bool_t exited = FALSE;
21 static DBusList *connections = NULL;
36 free_watch_data (void *data)
40 if (wd->type == WATCH_CONNECTION)
41 dbus_connection_unref (wd->data);
42 else if (wd->type == WATCH_SERVER)
43 dbus_server_unref (wd->data);
49 add_connection_watch (DBusWatch *watch,
50 DBusConnection *connection)
54 if (!_dbus_list_append (&watches, watch))
57 wd = dbus_new0 (WatchData, 1);
60 _dbus_list_remove_last (&watches, watch);
63 wd->type = WATCH_CONNECTION;
64 wd->data = connection;
66 dbus_connection_ref (connection);
68 dbus_watch_set_data (watch, wd, free_watch_data);
70 watch_list_serial += 1;
73 printf ("Added connection %swatch for fd %d\n",
74 dbus_watch_get_flags (watch) & DBUS_WATCH_WRITABLE ? "write " : "",
75 dbus_watch_get_fd (watch));
82 remove_connection_watch (DBusWatch *watch,
83 DBusConnection *connection)
85 if (!_dbus_list_remove (&watches, watch))
86 _dbus_assert_not_reached ("removed nonexistent watch");
88 dbus_watch_set_data (watch, NULL, NULL);
90 watch_list_serial += 1;
93 printf ("Removed connection watch for fd %d\n",
94 dbus_watch_get_fd (watch));
99 add_server_watch (DBusWatch *watch,
104 if (!_dbus_list_append (&watches, watch))
107 wd = dbus_new0 (WatchData, 1);
110 _dbus_list_remove_last (&watches, watch);
114 wd->type = WATCH_SERVER;
117 dbus_server_ref (server);
119 dbus_watch_set_data (watch, wd, free_watch_data);
121 watch_list_serial += 1;
124 printf ("Added server %swatch for fd %d\n",
125 dbus_watch_get_flags (watch) & DBUS_WATCH_WRITABLE ? "write " : "",
126 dbus_watch_get_fd (watch));
133 remove_server_watch (DBusWatch *watch,
136 if (!_dbus_list_remove (&watches, watch))
137 _dbus_assert_not_reached ("removed nonexistent server watch");
139 dbus_watch_set_data (watch, NULL, NULL);
141 watch_list_serial += 1;
144 printf ("Removed server watch for fd %d\n",
145 dbus_watch_get_fd (watch));
149 static int count = 0;
152 disconnect (DBusConnection *connection)
154 fprintf (stderr, "Disconnected\n");
156 _dbus_list_remove (&connections, connection);
157 dbus_connection_unref (connection);
163 check_messages (void)
167 link = _dbus_list_get_first_link (&connections);
170 DBusList *next = _dbus_list_get_next_link (&connections, link);
171 DBusConnection *connection = link->data;
172 DBusMessage *message;
175 while ((message = dbus_connection_pop_message (connection)))
179 name = dbus_message_get_name (message);
180 if (name && strcmp (name, DBUS_MESSAGE_LOCAL_DISCONNECT) == 0)
182 disconnect (connection);
186 fprintf (stderr, "Received message %d, sending reply\n", count);
188 reply = dbus_message_new ("org.freedesktop.DBus.Test", "org.freedesktop.DBus.Test");
189 if (!dbus_connection_send (connection,
192 fprintf (stderr, "No memory to send reply\n");
193 dbus_message_unref (reply);
195 dbus_message_unref (message);
200 printf ("Saw %d messages, exiting\n", count);
213 /* Of course with any real app you'd use GMainLoop or
214 * QSocketNotifier and not have to see all this crap.
216 while (!exited && watches != NULL)
223 int initial_watch_serial;
231 FD_ZERO (&write_set);
236 link = _dbus_list_get_first_link (&watches);
239 DBusList *next = _dbus_list_get_next_link (&watches, link);
244 if (dbus_watch_get_enabled (watch))
249 fd = dbus_watch_get_fd (watch);
250 flags = dbus_watch_get_flags (watch);
252 max_fd = MAX (max_fd, fd);
254 if (flags & DBUS_WATCH_READABLE)
255 FD_SET (fd, &read_set);
257 if (flags & DBUS_WATCH_WRITABLE)
258 FD_SET (fd, &write_set);
260 FD_SET (fd, &err_set);
266 select (max_fd + 1, &read_set, &write_set, &err_set, NULL);
268 initial_watch_serial = watch_list_serial;
269 link = _dbus_list_get_first_link (&watches);
272 DBusList *next = _dbus_list_get_next_link (&watches, link);
275 if (initial_watch_serial != watch_list_serial)
277 /* Watches were added/removed,
278 * hosing our list; break out of here
280 /* A more elegant solution might be to ref
281 * all watches, then check which have fd >= 0
282 * as we iterate over them, since removed
283 * watches have their fd invalidated.
285 printf ("Aborting watch iteration due to serial increment\n");
291 if (dbus_watch_get_enabled (watch))
295 unsigned int condition;
298 fd = dbus_watch_get_fd (watch);
299 flags = dbus_watch_get_flags (watch);
303 if ((flags & DBUS_WATCH_READABLE) &&
304 FD_ISSET (fd, &read_set))
305 condition |= DBUS_WATCH_READABLE;
307 if ((flags & DBUS_WATCH_WRITABLE) &&
308 FD_ISSET (fd, &write_set))
309 condition |= DBUS_WATCH_WRITABLE;
311 if (FD_ISSET (fd, &err_set))
312 condition |= DBUS_WATCH_ERROR;
318 wd = dbus_watch_get_data (watch);
320 if (wd->type == WATCH_CONNECTION)
322 DBusConnection *connection = wd->data;
324 dbus_connection_handle_watch (connection,
328 else if (wd->type == WATCH_SERVER)
330 DBusServer *server = wd->data;
332 dbus_server_handle_watch (server,
352 setup_connection (DBusConnection *connection)
354 if (!dbus_connection_set_watch_functions (connection,
355 (DBusAddWatchFunction) add_connection_watch,
356 (DBusRemoveWatchFunction) remove_connection_watch,
360 _dbus_assert_not_reached ("not enough memory");
362 dbus_connection_ref (connection);
363 _dbus_list_append (&connections, connection);
367 setup_server (DBusServer *server)
369 if (!dbus_server_set_watch_functions (server,
370 (DBusAddWatchFunction) add_server_watch,
371 (DBusRemoveWatchFunction) remove_server_watch,
375 _dbus_assert_not_reached ("not enough memory");