2003-04-17 Havoc Pennington <hp@redhat.com>

* dbus/dbus-mainloop.c (_dbus_loop_iterate): fix logic so that if
	there was an OOM watch we skipped, we always return TRUE so we
	iterate again to have a look at it again. Fixes test suite hang.
	Code rearrangement also lets us lose some memset and only iterate
	over callbacks once.

	* bus/driver.c (bus_driver_handle_message): sense of test for
	reply was backward
This commit is contained in:
Havoc Pennington 2003-04-17 20:25:33 +00:00
parent dac0a1f893
commit 4219b08bfa
5 changed files with 104 additions and 99 deletions

View file

@ -1,3 +1,14 @@
2003-04-17 Havoc Pennington <hp@redhat.com>
* dbus/dbus-mainloop.c (_dbus_loop_iterate): fix logic so that if
there was an OOM watch we skipped, we always return TRUE so we
iterate again to have a look at it again. Fixes test suite hang.
Code rearrangement also lets us lose some memset and only iterate
over callbacks once.
* bus/driver.c (bus_driver_handle_message): sense of test for
reply was backward
2003-04-16 Havoc Pennington <hp@pobox.com>
* doc/dbus-specification.sgml: make spec say serials are unsigned

View file

@ -1922,7 +1922,7 @@ bus_dispatch_test (const DBusString *test_data_dir)
_dbus_assert_not_reached ("initial connection setup failed");
}
check1_try_iterations (context, "create_and_hello_sha1",
check1_try_iterations (context, "create_and_hello",
check_hello_connection);
check2_try_iterations (context, foo, "nonexistent_service_activation",
@ -1978,7 +1978,7 @@ bus_dispatch_sha1_test (const DBusString *test_data_dir)
_dbus_assert_not_reached ("initial connection setup failed");
}
check1_try_iterations (context, "create_and_hello",
check1_try_iterations (context, "create_and_hello_sha1",
check_hello_connection);
kill_client_connection_unchecked (foo);

View file

@ -620,7 +620,7 @@ bus_driver_handle_message (DBusConnection *connection,
return FALSE;
}
if (dbus_message_get_reply_serial (message) != 0)
if (dbus_message_get_reply_serial (message) == 0)
{
_dbus_verbose ("Client sent a reply to the bus driver, ignoring it\n");
return TRUE;

View file

@ -489,13 +489,13 @@ dbus_bool_t
_dbus_loop_iterate (DBusLoop *loop,
dbus_bool_t block)
{
#define N_STATIC_DESCRIPTORS 64
#define N_STACK_DESCRIPTORS 64
dbus_bool_t retval;
DBusPollFD *fds;
DBusPollFD static_fds[N_STATIC_DESCRIPTORS];
DBusPollFD stack_fds[N_STACK_DESCRIPTORS];
int n_fds;
WatchCallback **watches_for_fds;
WatchCallback *static_watches_for_fds[N_STATIC_DESCRIPTORS];
WatchCallback *stack_watches_for_fds[N_STACK_DESCRIPTORS];
int i;
DBusList *link;
int n_ready;
@ -504,8 +504,8 @@ _dbus_loop_iterate (DBusLoop *loop,
dbus_bool_t oom_watch_pending;
int orig_depth;
retval = FALSE;
retval = FALSE;
fds = NULL;
watches_for_fds = NULL;
n_fds = 0;
@ -520,7 +520,30 @@ _dbus_loop_iterate (DBusLoop *loop,
if (loop->callbacks == NULL)
goto next_iteration;
/* count enabled watches */
if (loop->watch_count > N_STACK_DESCRIPTORS)
{
fds = dbus_new0 (DBusPollFD, loop->watch_count);
while (fds == NULL)
{
_dbus_wait_for_memory ();
fds = dbus_new0 (DBusPollFD, loop->watch_count);
}
watches_for_fds = dbus_new (WatchCallback*, loop->watch_count);
while (watches_for_fds == NULL)
{
_dbus_wait_for_memory ();
watches_for_fds = dbus_new (WatchCallback*, loop->watch_count);
}
}
else
{
fds = stack_fds;
watches_for_fds = stack_watches_for_fds;
}
/* fill our array of fds and watches */
n_fds = 0;
link = _dbus_list_get_first_link (&loop->callbacks);
while (link != NULL)
@ -529,95 +552,60 @@ _dbus_loop_iterate (DBusLoop *loop,
Callback *cb = link->data;
if (cb->type == CALLBACK_WATCH)
{
unsigned int flags;
WatchCallback *wcb = WATCH_CALLBACK (cb);
if (!wcb->last_iteration_oom &&
dbus_watch_get_enabled (wcb->watch))
++n_fds;
if (wcb->last_iteration_oom)
{
/* we skip this one this time, but reenable it next time,
* and have a timeout on this iteration
*/
wcb->last_iteration_oom = FALSE;
oom_watch_pending = TRUE;
retval = TRUE; /* return TRUE here to keep the loop going,
* since we don't know the watch is inactive
*/
#if MAINLOOP_SPEW
_dbus_verbose (" skipping watch on fd %d as it was out of memory last time\n",
dbus_watch_get_fd (wcb->watch));
#endif
}
else if (dbus_watch_get_enabled (wcb->watch))
{
watches_for_fds[n_fds] = wcb;
callback_ref (cb);
flags = dbus_watch_get_flags (wcb->watch);
fds[n_fds].fd = dbus_watch_get_fd (wcb->watch);
fds[n_fds].revents = 0;
fds[n_fds].events = 0;
if (flags & DBUS_WATCH_READABLE)
fds[n_fds].events |= _DBUS_POLLIN;
if (flags & DBUS_WATCH_WRITABLE)
fds[n_fds].events |= _DBUS_POLLOUT;
n_fds += 1;
#if MAINLOOP_SPEW
_dbus_verbose (" polling watch on fd %d\n", fds[n_fds].fd);
#endif
}
else
{
#if MAINLOOP_SPEW
_dbus_verbose (" skipping disabled watch on fd %d\n",
dbus_watch_get_fd (wcb->watch));
#endif
}
}
link = next;
}
/* fill our array of fds and watches */
if (n_fds > 0)
{
if (n_fds > N_STATIC_DESCRIPTORS)
{
fds = dbus_new0 (DBusPollFD, n_fds);
while (fds == NULL)
{
_dbus_wait_for_memory ();
fds = dbus_new0 (DBusPollFD, n_fds);
}
watches_for_fds = dbus_new (WatchCallback*, n_fds);
while (watches_for_fds == NULL)
{
_dbus_wait_for_memory ();
watches_for_fds = dbus_new (WatchCallback*, n_fds);
}
}
else
{
memset (static_fds, '\0', sizeof (static_fds[0]) * n_fds);
memset (static_watches_for_fds, '\0', sizeof (static_watches_for_fds[0]) * n_fds);
fds = static_fds;
watches_for_fds = static_watches_for_fds;
}
i = 0;
link = _dbus_list_get_first_link (&loop->callbacks);
while (link != NULL)
{
DBusList *next = _dbus_list_get_next_link (&loop->callbacks, link);
Callback *cb = link->data;
if (cb->type == CALLBACK_WATCH)
{
unsigned int flags;
WatchCallback *wcb = WATCH_CALLBACK (cb);
if (wcb->last_iteration_oom)
{
/* we skip this one this time, but reenable it next time,
* and have a timeout on this iteration
*/
wcb->last_iteration_oom = FALSE;
oom_watch_pending = TRUE;
retval = TRUE; /* return TRUE here to keep the loop going,
* since we don't know the watch is inactive
*/
_dbus_verbose (" skipping watch on fd %d as it was out of memory last time\n",
dbus_watch_get_fd (wcb->watch));
}
else if (dbus_watch_get_enabled (wcb->watch))
{
watches_for_fds[i] = wcb;
callback_ref (cb);
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;
++i;
}
}
link = next;
}
_dbus_assert (i == n_fds);
}
timeout = -1;
if (loop->timeout_count > 0)
{
@ -784,7 +772,7 @@ _dbus_loop_iterate (DBusLoop *loop,
}
next_iteration:
if (fds && fds != static_fds)
if (fds && fds != stack_fds)
dbus_free (fds);
if (watches_for_fds)
{
@ -795,13 +783,13 @@ _dbus_loop_iterate (DBusLoop *loop,
++i;
}
if (watches_for_fds != static_watches_for_fds)
if (watches_for_fds != stack_watches_for_fds)
dbus_free (watches_for_fds);
}
if (_dbus_loop_dispatch (loop))
retval = TRUE;
#if MAINLOOP_SPEW
_dbus_verbose ("Returning %d\n", retval);
#endif

View file

@ -725,14 +725,17 @@ unix_handle_watch (DBusTransport *transport,
if (watch == unix_transport->read_watch &&
(flags & DBUS_WATCH_READABLE))
{
#if 0
#if 1
_dbus_verbose ("handling read watch\n");
#endif
if (!do_authentication (transport, TRUE, FALSE))
return FALSE;
if (!do_reading (transport))
return FALSE;
{
_dbus_verbose ("no memory to read\n");
return FALSE;
}
}
else if (watch == unix_transport->write_watch &&
(flags & DBUS_WATCH_WRITABLE))
@ -745,7 +748,10 @@ unix_handle_watch (DBusTransport *transport,
return FALSE;
if (!do_writing (transport))
return FALSE;
{
_dbus_verbose ("no memory to write\n");
return FALSE;
}
}
#ifdef DBUS_ENABLE_VERBOSE_MODE
else