summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2002-12-27 00:44:41 +0000
committerHavoc Pennington <hp@redhat.com>2002-12-27 00:44:41 +0000
commitff5283ab92c668453fd2f28c1715a1e0e9b949f5 (patch)
tree24cf1119e1d203dd08cd4d797ac8640d35451faa /test
parentf3729626de0093762c9d00a8d02db9c96fbd5bd2 (diff)
2002-12-26 Havoc Pennington <hp@pobox.com>
* dbus/dbus-marshal.h (DBUS_COMPILER_BYTE_ORDER): #ifdef WORDS_BIGENDIAN then compiler byte order is DBUS_BIG_ENDIAN, doh * dbus/dbus-marshal.c: Add macros to do int swapping in-place and avoid swap_bytes() overhead (ignoring possible assembly stuff for now). Main point is because I wanted unpack_uint32 to implement _dbus_verbose_bytes (_dbus_verbose_bytes): new function * dbus/dbus-string.c (_dbus_string_validate_ascii): new function * dbus/dbus-message.c (_dbus_message_loader_get_is_corrupted): add mechanism to handle a corrupt message stream (_dbus_message_loader_new): fix preallocation to only prealloc, not prelengthen * dbus/dbus-string.c (_dbus_string_skip_blank): fix this function (_dbus_string_test): enhance tests for copy/move and fix the functions * dbus/dbus-transport-unix.c: Hold references in more places to avoid reentrancy problems * dbus/dbus-transport.c: ditto * dbus/dbus-connection.c (dbus_connection_dispatch_message): don't leak reference count in no-message case * test/watch.c (do_mainloop): handle adding/removing watches during iteration over the watches. Also, ref the connection/server stored on a watch, so we don't try to mangle a destroyed one. * dbus/dbus-transport-unix.c (do_authentication): perform authentication * dbus/dbus-auth.c (get_state): add a state AUTHENTICATED_WITH_UNUSED_BYTES and return it if required (_dbus_auth_get_unused_bytes): append the unused bytes to the passed in string, rather than prepend * dbus/dbus-transport.c (_dbus_transport_init_base): create the auth conversation DBusAuth * dbus/dbus-transport-unix.c (_dbus_transport_new_for_fd) (_dbus_transport_new_for_domain_socket): when creating a transport, pass in whether it's a client-side or server-side transport so we know which DBusAuth to create
Diffstat (limited to 'test')
-rw-r--r--test/watch.c81
1 files changed, 74 insertions, 7 deletions
diff --git a/test/watch.c b/test/watch.c
index 161ae3a9..3b525d37 100644
--- a/test/watch.c
+++ b/test/watch.c
@@ -15,6 +15,7 @@
#undef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+static int watch_list_serial = 0;
static DBusList *watches = NULL;
static dbus_bool_t exited = FALSE;
static DBusList *connections = NULL;
@@ -32,6 +33,19 @@ typedef struct
} WatchData;
static void
+free_watch_data (void *data)
+{
+ WatchData *wd = data;
+
+ if (wd->type == WATCH_CONNECTION)
+ dbus_connection_unref (wd->data);
+ else if (wd->type == WATCH_SERVER)
+ dbus_server_unref (wd->data);
+
+ dbus_free (wd);
+}
+
+static void
add_connection_watch (DBusWatch *watch,
DBusConnection *connection)
{
@@ -40,17 +54,36 @@ add_connection_watch (DBusWatch *watch,
wd = dbus_new0 (WatchData, 1);
wd->type = WATCH_CONNECTION;
wd->data = connection;
+
+ dbus_connection_ref (connection);
_dbus_list_append (&watches, watch);
- dbus_watch_set_data (watch, wd, dbus_free);
-}
+ dbus_watch_set_data (watch, wd, free_watch_data);
+
+ watch_list_serial += 1;
+
+#if 0
+ printf ("Added connection %swatch for fd %d\n",
+ dbus_watch_get_flags (watch) & DBUS_WATCH_WRITABLE ? "write " : "",
+ dbus_watch_get_fd (watch));
+#endif
+ }
static void
remove_connection_watch (DBusWatch *watch,
DBusConnection *connection)
{
- _dbus_list_remove (&watches, watch);
+ if (!_dbus_list_remove (&watches, watch))
+ _dbus_assert_not_reached ("removed nonexistent watch");
+
dbus_watch_set_data (watch, NULL, NULL);
+
+ watch_list_serial += 1;
+
+#if 0
+ printf ("Removed connection watch for fd %d\n",
+ dbus_watch_get_fd (watch));
+#endif
}
static void
@@ -62,18 +95,37 @@ add_server_watch (DBusWatch *watch,
wd = dbus_new0 (WatchData, 1);
wd->type = WATCH_SERVER;
wd->data = server;
+
+ dbus_server_ref (server);
_dbus_list_append (&watches, watch);
- dbus_watch_set_data (watch, wd, dbus_free);
+ dbus_watch_set_data (watch, wd, free_watch_data);
+
+ watch_list_serial += 1;
+
+#if 0
+ printf ("Added server %swatch for fd %d\n",
+ dbus_watch_get_flags (watch) & DBUS_WATCH_WRITABLE ? "write " : "",
+ dbus_watch_get_fd (watch));
+#endif
}
static void
remove_server_watch (DBusWatch *watch,
DBusServer *server)
{
- _dbus_list_remove (&watches, watch);
+ if (!_dbus_list_remove (&watches, watch))
+ _dbus_assert_not_reached ("removed nonexistent server watch");
+
dbus_watch_set_data (watch, NULL, NULL);
+
+ watch_list_serial += 1;
+
+#if 0
+ printf ("Removed server watch for fd %d\n",
+ dbus_watch_get_fd (watch));
+#endif
}
static int count = 0;
@@ -122,7 +174,6 @@ do_mainloop (void)
/* Of course with any real app you'd use GMainLoop or
* QSocketNotifier and not have to see all this crap.
*/
-
while (!exited && watches != NULL)
{
fd_set read_set;
@@ -130,7 +181,8 @@ do_mainloop (void)
fd_set err_set;
int max_fd;
DBusList *link;
-
+ int initial_watch_serial;
+
check_messages ();
FD_ZERO (&read_set);
@@ -167,6 +219,7 @@ do_mainloop (void)
select (max_fd + 1, &read_set, &write_set, &err_set, NULL);
+ initial_watch_serial = watch_list_serial;
link = _dbus_list_get_first_link (&watches);
while (link != NULL)
{
@@ -175,6 +228,20 @@ do_mainloop (void)
DBusWatch *watch;
unsigned int flags;
unsigned int condition;
+
+ if (initial_watch_serial != watch_list_serial)
+ {
+ /* Watches were added/removed,
+ * hosing our list; break out of here
+ */
+ /* A more elegant solution might be to ref
+ * all watches, then check which have fd >= 0
+ * as we iterate over them, since removed
+ * watches have their fd invalidated.
+ */
+ printf ("Aborting watch iteration due to serial increment\n");
+ break;
+ }
watch = link->data;