From f468907fb09e8198c4cce7e8f2ddeae8b5476b9e Mon Sep 17 00:00:00 2001 From: Havoc Pennington Date: Fri, 14 Mar 2003 05:17:19 +0000 Subject: 2003-03-14 Havoc Pennington * bus/loop.c (bus_loop_iterate): add this so we can "run loop until no work remains" in test code. (the large diff here is just code movement, no actual changes) * dbus/dbus-server-debug.c (DEFAULT_INTERVAL): change interval to 1, no point waiting around for test code. (_dbus_server_debug_accept_transport): unref the timeout after adding it (right?) * dbus/dbus-transport-debug.c (DEFAULT_INTERVAL): ditto --- ChangeLog | 13 ++ bus/loop.c | 390 +++++++++++++++++++++++--------------------- bus/loop.h | 1 + dbus/dbus-connection.c | 4 +- dbus/dbus-server-debug.c | 4 +- dbus/dbus-server.c | 2 +- dbus/dbus-transport-debug.c | 2 +- 7 files changed, 228 insertions(+), 188 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5784a264..296d3342 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2003-03-14 Havoc Pennington + + * bus/loop.c (bus_loop_iterate): add this so we can "run loop + until no work remains" in test code. (the large diff here + is just code movement, no actual changes) + + * dbus/dbus-server-debug.c (DEFAULT_INTERVAL): change interval to + 1, no point waiting around for test code. + (_dbus_server_debug_accept_transport): unref the timeout + after adding it (right?) + + * dbus/dbus-transport-debug.c (DEFAULT_INTERVAL): ditto + 2003-03-13 Havoc Pennington * dbus/dbus-timeout.c (_dbus_timeout_list_set_functions): handle diff --git a/bus/loop.c b/bus/loop.c index b114d262..72bf99e4 100644 --- a/bus/loop.c +++ b/bus/loop.c @@ -262,247 +262,269 @@ bus_loop_remove_timeout (DBusTimeout *timeout, timeout, function, data); } -void -bus_loop_run (void) +/* Returns TRUE if we dispatch any callbacks, which is just used in + * test code as a debug hack + */ + +dbus_bool_t +bus_loop_iterate (dbus_bool_t block) { - while (!exited) - { - DBusPollFD *fds; - int n_fds; - WatchCallback **watches_for_fds; - int i; - DBusList *link; - int n_ready; - int initial_serial; - long timeout; + dbus_bool_t retval; + DBusPollFD *fds; + int n_fds; + WatchCallback **watches_for_fds; + int i; + DBusList *link; + int n_ready; + int initial_serial; + long timeout; + + retval = FALSE; - fds = NULL; - watches_for_fds = NULL; + fds = NULL; + watches_for_fds = NULL; - if (callbacks == NULL) - { - bus_loop_quit (); - goto next_iteration; - } + if (callbacks == NULL) + { + bus_loop_quit (); + goto next_iteration; + } - n_fds = watch_count; + n_fds = watch_count; - if (n_fds > 0) + if (n_fds > 0) + { + fds = dbus_new0 (DBusPollFD, n_fds); + while (fds == NULL) { + bus_wait_for_memory (); fds = dbus_new0 (DBusPollFD, n_fds); - while (fds == NULL) - { - bus_wait_for_memory (); - fds = dbus_new0 (DBusPollFD, n_fds); - } + } + watches_for_fds = dbus_new (WatchCallback*, n_fds); + while (watches_for_fds == NULL) + { + bus_wait_for_memory (); watches_for_fds = dbus_new (WatchCallback*, n_fds); - while (watches_for_fds == NULL) - { - bus_wait_for_memory (); - watches_for_fds = dbus_new (WatchCallback*, n_fds); - } + } - i = 0; - link = _dbus_list_get_first_link (&callbacks); - while (link != NULL) + i = 0; + link = _dbus_list_get_first_link (&callbacks); + while (link != NULL) + { + DBusList *next = _dbus_list_get_next_link (&callbacks, link); + Callback *cb = link->data; + if (cb->type == CALLBACK_WATCH) { - DBusList *next = _dbus_list_get_next_link (&callbacks, link); - Callback *cb = link->data; - if (cb->type == CALLBACK_WATCH) - { - unsigned int flags; - WatchCallback *wcb = WATCH_CALLBACK (cb); + unsigned int flags; + WatchCallback *wcb = WATCH_CALLBACK (cb); - watches_for_fds[i] = wcb; + watches_for_fds[i] = wcb; - flags = dbus_watch_get_flags (wcb->watch); + flags = dbus_watch_get_flags (wcb->watch); - fds[i].fd = dbus_watch_get_fd (wcb->watch); - if (flags & DBUS_WATCH_READABLE) - fds[i].events |= _DBUS_POLLIN; - if (flags & DBUS_WATCH_WRITABLE) - fds[i].events |= _DBUS_POLLOUT; + fds[i].fd = dbus_watch_get_fd (wcb->watch); + if (flags & DBUS_WATCH_READABLE) + fds[i].events |= _DBUS_POLLIN; + if (flags & DBUS_WATCH_WRITABLE) + fds[i].events |= _DBUS_POLLOUT; - ++i; - } - - link = next; + ++i; } - - _dbus_assert (i == n_fds); + + link = next; } - timeout = -1; - if (timeout_count > 0) - { - unsigned long tv_sec; - unsigned long tv_usec; + _dbus_assert (i == n_fds); + } + + timeout = -1; + if (timeout_count > 0) + { + unsigned long tv_sec; + unsigned long tv_usec; - _dbus_get_current_time (&tv_sec, &tv_usec); + _dbus_get_current_time (&tv_sec, &tv_usec); - link = _dbus_list_get_first_link (&callbacks); - while (link != NULL) + link = _dbus_list_get_first_link (&callbacks); + while (link != NULL) + { + DBusList *next = _dbus_list_get_next_link (&callbacks, link); + Callback *cb = link->data; + + if (cb->type == CALLBACK_TIMEOUT) { - DBusList *next = _dbus_list_get_next_link (&callbacks, link); - Callback *cb = link->data; + TimeoutCallback *tcb = TIMEOUT_CALLBACK (cb); + unsigned long interval; + unsigned long elapsed; - if (cb->type == CALLBACK_TIMEOUT) + if (tcb->last_tv_sec > tv_sec || + (tcb->last_tv_sec == tv_sec && + tcb->last_tv_usec > tv_usec)) { - TimeoutCallback *tcb = TIMEOUT_CALLBACK (cb); - unsigned long interval; - unsigned long elapsed; - - if (tcb->last_tv_sec > tv_sec || - (tcb->last_tv_sec == tv_sec && - tcb->last_tv_usec > tv_usec)) - { - /* Clock went backward, pretend timeout - * was just installed. - */ - tcb->last_tv_sec = tv_sec; - tcb->last_tv_usec = tv_usec; - _dbus_verbose ("System clock went backward\n"); - } + /* Clock went backward, pretend timeout + * was just installed. + */ + tcb->last_tv_sec = tv_sec; + tcb->last_tv_usec = tv_usec; + _dbus_verbose ("System clock went backward\n"); + } - interval = dbus_timeout_get_interval (tcb->timeout); + interval = dbus_timeout_get_interval (tcb->timeout); - elapsed = - (tv_sec - tcb->last_tv_sec) * 1000 + - (tv_usec - tcb->last_tv_usec) / 1000; + elapsed = + (tv_sec - tcb->last_tv_sec) * 1000 + + (tv_usec - tcb->last_tv_usec) / 1000; - if (interval < elapsed) - timeout = 0; - else if (timeout < 0) - timeout = interval - elapsed; - else - timeout = MIN (((unsigned long)timeout), interval - elapsed); + if (interval < elapsed) + timeout = 0; + else if (timeout < 0) + timeout = interval - elapsed; + else + timeout = MIN (((unsigned long)timeout), interval - elapsed); - _dbus_assert (timeout >= 0); + _dbus_assert (timeout >= 0); - if (timeout == 0) - break; /* it's not going to get shorter... */ - } - - link = next; + if (timeout == 0) + break; /* it's not going to get shorter... */ } + + link = next; } + } + + if (!block) + timeout = 0; - n_ready = _dbus_poll (fds, n_fds, timeout); + n_ready = _dbus_poll (fds, n_fds, timeout); - initial_serial = callback_list_serial; + initial_serial = callback_list_serial; - if (timeout_count > 0) - { - unsigned long tv_sec; - unsigned long tv_usec; + if (timeout_count > 0) + { + unsigned long tv_sec; + unsigned long tv_usec; - _dbus_get_current_time (&tv_sec, &tv_usec); + _dbus_get_current_time (&tv_sec, &tv_usec); - /* It'd be nice to avoid this O(n) thingy here */ - link = _dbus_list_get_first_link (&callbacks); - while (link != NULL) - { - DBusList *next = _dbus_list_get_next_link (&callbacks, link); - Callback *cb = link->data; + /* It'd be nice to avoid this O(n) thingy here */ + link = _dbus_list_get_first_link (&callbacks); + while (link != NULL) + { + DBusList *next = _dbus_list_get_next_link (&callbacks, link); + Callback *cb = link->data; - if (initial_serial != callback_list_serial) - goto next_iteration; + if (initial_serial != callback_list_serial) + goto next_iteration; - if (exited) - goto next_iteration; + if (exited) + goto next_iteration; - if (cb->type == CALLBACK_TIMEOUT) - { - TimeoutCallback *tcb = TIMEOUT_CALLBACK (cb); - unsigned long interval; - unsigned long elapsed; + if (cb->type == CALLBACK_TIMEOUT) + { + TimeoutCallback *tcb = TIMEOUT_CALLBACK (cb); + unsigned long interval; + unsigned long elapsed; - if (tcb->last_tv_sec > tv_sec || - (tcb->last_tv_sec == tv_sec && - tcb->last_tv_usec > tv_usec)) - { - /* Clock went backward, pretend timeout - * was just installed. - */ - tcb->last_tv_sec = tv_sec; - tcb->last_tv_usec = tv_usec; - _dbus_verbose ("System clock went backward\n"); - goto next_timeout; - } + if (tcb->last_tv_sec > tv_sec || + (tcb->last_tv_sec == tv_sec && + tcb->last_tv_usec > tv_usec)) + { + /* Clock went backward, pretend timeout + * was just installed. + */ + tcb->last_tv_sec = tv_sec; + tcb->last_tv_usec = tv_usec; + _dbus_verbose ("System clock went backward\n"); + goto next_timeout; + } - interval = dbus_timeout_get_interval (tcb->timeout); + interval = dbus_timeout_get_interval (tcb->timeout); - elapsed = - (tv_sec - tcb->last_tv_sec) * 1000 + - (tv_usec - tcb->last_tv_usec) / 1000; + elapsed = + (tv_sec - tcb->last_tv_sec) * 1000 + + (tv_usec - tcb->last_tv_usec) / 1000; - if (interval <= elapsed) - { - /* Save last callback time and fire this timeout */ - tcb->last_tv_sec = tv_sec; - tcb->last_tv_usec = tv_usec; + if (interval <= elapsed) + { + /* Save last callback time and fire this timeout */ + tcb->last_tv_sec = tv_sec; + tcb->last_tv_usec = tv_usec; - (* tcb->function) (tcb->timeout, - cb->data); - } - } + (* tcb->function) (tcb->timeout, + cb->data); - next_timeout: - link = next; + retval = TRUE; + } } + + next_timeout: + link = next; } + } - if (n_ready > 0) + if (n_ready > 0) + { + i = 0; + while (i < n_fds) { - i = 0; - while (i < n_fds) - { - /* FIXME I think this "restart if we change the watches" - * approach could result in starving watches - * toward the end of the list. - */ - if (initial_serial != callback_list_serial) - goto next_iteration; + /* FIXME I think this "restart if we change the watches" + * approach could result in starving watches + * toward the end of the list. + */ + if (initial_serial != callback_list_serial) + goto next_iteration; - if (exited) - goto next_iteration; + if (exited) + goto next_iteration; - if (fds[i].revents != 0) - { - WatchCallback *wcb; - unsigned int condition; + if (fds[i].revents != 0) + { + WatchCallback *wcb; + unsigned int condition; - wcb = watches_for_fds[i]; + wcb = watches_for_fds[i]; - condition = 0; - if (fds[i].revents & _DBUS_POLLIN) - condition |= DBUS_WATCH_READABLE; - if (fds[i].revents & _DBUS_POLLOUT) - condition |= DBUS_WATCH_WRITABLE; - if (fds[i].revents & _DBUS_POLLHUP) - condition |= DBUS_WATCH_HANGUP; - if (fds[i].revents & _DBUS_POLLERR) - condition |= DBUS_WATCH_ERROR; - - /* condition may still be 0 if we got some - * weird POLLFOO thing like POLLWRBAND - */ + condition = 0; + if (fds[i].revents & _DBUS_POLLIN) + condition |= DBUS_WATCH_READABLE; + if (fds[i].revents & _DBUS_POLLOUT) + condition |= DBUS_WATCH_WRITABLE; + if (fds[i].revents & _DBUS_POLLHUP) + condition |= DBUS_WATCH_HANGUP; + if (fds[i].revents & _DBUS_POLLERR) + condition |= DBUS_WATCH_ERROR; + + /* condition may still be 0 if we got some + * weird POLLFOO thing like POLLWRBAND + */ - if (condition != 0) - (* wcb->function) (wcb->watch, - condition, - ((Callback*)wcb)->data); + if (condition != 0) + { + (* wcb->function) (wcb->watch, + condition, + ((Callback*)wcb)->data); + retval = TRUE; } - - ++i; } + + ++i; } - - next_iteration: - dbus_free (fds); - dbus_free (watches_for_fds); } + + next_iteration: + dbus_free (fds); + dbus_free (watches_for_fds); + + return retval; +} + + +void +bus_loop_run (void) +{ + while (!exited) + bus_loop_iterate (TRUE); } void diff --git a/bus/loop.h b/bus/loop.h index cd49865c..87ebc1ee 100644 --- a/bus/loop.h +++ b/bus/loop.h @@ -48,6 +48,7 @@ void bus_loop_remove_timeout (DBusTimeout *timeout, void *data); void bus_loop_run (void); void bus_loop_quit (void); +dbus_bool_t bus_loop_iterate (dbus_bool_t block); diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c index 19fe717d..d52341a7 100644 --- a/dbus/dbus-connection.c +++ b/dbus/dbus-connection.c @@ -334,6 +334,7 @@ _dbus_connection_remove_watch (DBusConnection *connection, * available. Otherwise records the timeout to be added when said * function is available. Also re-adds the timeout if the * DBusAddTimeoutFunction changes. May fail due to lack of memory. + * The timeout will fire only one time. * * @param connection the connection. * @param timeout the timeout to add. @@ -1861,7 +1862,8 @@ dbus_connection_set_watch_functions (DBusConnection *connection, * dbus_timeout_get_interval. * * Once a timeout occurs, dbus_timeout_handle should be called to invoke - * the timeout's callback. + * the timeout's callback, and the timeout should be automatically + * removed. i.e. timeouts are one-shot. * * @param connection the connection. * @param add_function function to add a timeout. diff --git a/dbus/dbus-server-debug.c b/dbus/dbus-server-debug.c index f558e82e..5f79e81c 100644 --- a/dbus/dbus-server-debug.c +++ b/dbus/dbus-server-debug.c @@ -43,7 +43,7 @@ /** * Default timeout interval when reading or writing. */ -#define DEFAULT_INTERVAL 10 +#define DEFAULT_INTERVAL 1 /** * Opaque object representing a debug server implementation. @@ -249,6 +249,8 @@ _dbus_server_debug_accept_transport (DBusServer *server, if (!_dbus_server_add_timeout (server, timeout)) goto failed; + _dbus_timeout_unref (timeout); + return TRUE; failed: diff --git a/dbus/dbus-server.c b/dbus/dbus-server.c index 99a5a2af..cfcc0dd5 100644 --- a/dbus/dbus-server.c +++ b/dbus/dbus-server.c @@ -146,7 +146,7 @@ _dbus_server_remove_watch (DBusServer *server, /** * Adds a timeout for this server, chaining out to application-provided - * timeout handlers. + * timeout handlers. The timeout will fire only one time. * * @param server the server. * @param timeout the timeout to add. diff --git a/dbus/dbus-transport-debug.c b/dbus/dbus-transport-debug.c index e0a90644..cb4b3c2c 100644 --- a/dbus/dbus-transport-debug.c +++ b/dbus/dbus-transport-debug.c @@ -44,7 +44,7 @@ /** * Default timeout interval when reading or writing. */ -#define DEFAULT_INTERVAL 10 +#define DEFAULT_INTERVAL 1 /** * Opaque object representing a debug transport. -- cgit