dbus/dbus dbus-connection-internal.h, 1.18, 1.19 dbus-connection.c,
1.84, 1.85 dbus-connection.h, 1.33, 1.34 dbus-internals.c,
1.37, 1.38 dbus-keyring.c, 1.25, 1.26 dbus-mainloop.c, 1.16,
1.17 dbus-message.c, 1.140, 1.141 dbus-server-unix.c, 1.23,
1.24 dbus-string.c, 1.53, 1.54 dbus-string.h, 1.29,
1.30 dbus-sysdeps.c, 1.82, 1.83 dbus-transport-protected.h,
1.14, 1.15 dbus-transport-unix.c, 1.42, 1.43 dbus-transport.c,
1.41, 1.42 dbus-transport.h, 1.18, 1.19 dbus-watch.c, 1.17, 1.18
Havoc Pennington
hp at freedesktop.org
Thu Nov 25 17:53:15 PST 2004
Update of /cvs/dbus/dbus/dbus
In directory gabe:/tmp/cvs-serv21187/dbus
Modified Files:
dbus-connection-internal.h dbus-connection.c dbus-connection.h
dbus-internals.c dbus-keyring.c dbus-mainloop.c dbus-message.c
dbus-server-unix.c dbus-string.c dbus-string.h dbus-sysdeps.c
dbus-transport-protected.h dbus-transport-unix.c
dbus-transport.c dbus-transport.h dbus-watch.c
Log Message:
2004-11-25 Havoc Pennington <hp at redhat.com>
The primary change here is to always write() once before adding
the write watch, which gives us about a 10% performance increase.
* dbus/dbus-transport-unix.c: a number of modifications to cope
with removing messages_pending
(check_write_watch): properly handle
DBUS_AUTH_STATE_WAITING_FOR_MEMORY; adapt to removal of
messages_pending stuff
(check_read_watch): properly handle WAITING_FOR_MEMORY and
AUTHENTICATED cases
(unix_handle_watch): after writing, see if the write watch can be
removed
(unix_do_iteration): assert that write_watch/read_watch are
non-NULL rather than testing that they aren't, since they
aren't allowed to be NULL. check_write_watch() at the end so
we add the watch if we did not finish writing (e.g. got EAGAIN)
* dbus/dbus-transport-protected.h: remove messages_pending call,
since it resulted in too much inefficient watch adding/removing;
instead we now require that the transport user does an iteration
after queueing outgoing messages, and after trying the first
write() we add a write watch if we got EAGAIN or exceeded our
max bytes to write per iteration setting
* dbus/dbus-string.c (_dbus_string_validate_signature): add this
function
* dbus/dbus-server-unix.c (unix_finalize): the socket name was
freed and then accessed, valgrind flagged this bug, fix it
* dbus/dbus-message.c: fix several bugs where HEADER_FIELD_LAST was taken
as the last valid field plus 1, where really it is equal to the
last valid field. Corrects some message corruption issues.
* dbus/dbus-mainloop.c: verbosity changes
* dbus/dbus-keyring.c (_dbus_keyring_new_homedir): handle OOM
instead of aborting in one of the test codepaths
* dbus/dbus-internals.c (_dbus_verbose_real): fix a bug that
caused not printing the pid ever again if a verbose was missing
the newline at the end
(_dbus_header_field_to_string): add HEADER_FIELD_SIGNATURE
* dbus/dbus-connection.c: verbosity changes;
(dbus_connection_has_messages_to_send): new function
(_dbus_connection_message_sent): no longer call transport->messages_pending
(_dbus_connection_send_preallocated_unlocked): do one iteration to
try to write() immediately, so we can avoid the write watch. This
is the core purpose of this patchset
(_dbus_connection_get_dispatch_status_unlocked): if disconnected,
dump the outgoing message queue, so nobody will get confused
trying to send them or thinking stuff is pending to be sent
* bus/test.c: verbosity changes
* bus/driver.c: verbosity/assertion changes
* bus/dispatch.c: a bunch of little tweaks to get it working again
because this patchset changes when/where you need to block.
Index: dbus-connection-internal.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-connection-internal.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- dbus-connection-internal.h 9 Sep 2004 10:20:17 -0000 1.18
+++ dbus-connection-internal.h 26 Nov 2004 01:53:13 -0000 1.19
@@ -52,7 +52,7 @@
DBusMessage *message);
void _dbus_connection_queue_received_message_link (DBusConnection *connection,
DBusList *link);
-dbus_bool_t _dbus_connection_have_messages_to_send (DBusConnection *connection);
+dbus_bool_t _dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection);
DBusMessage* _dbus_connection_get_message_to_send (DBusConnection *connection);
void _dbus_connection_message_sent (DBusConnection *connection,
DBusMessage *message);
Index: dbus-connection.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-connection.c,v
retrieving revision 1.84
retrieving revision 1.85
diff -u -d -r1.84 -r1.85
--- dbus-connection.c 10 Aug 2004 03:06:59 -0000 1.84
+++ dbus-connection.c 26 Nov 2004 01:53:13 -0000 1.85
@@ -1,7 +1,7 @@
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-connection.c DBusConnection object
*
- * Copyright (C) 2002, 2003 Red Hat Inc.
+ * Copyright (C) 2002, 2003, 2004 Red Hat Inc.
*
* Licensed under the Academic Free License version 2.1
*
@@ -54,6 +54,12 @@
#define CONNECTION_UNLOCK(connection) dbus_mutex_unlock ((connection)->mutex)
#endif
+#define DISPATCH_STATUS_NAME(s) \
+ ((s) == DBUS_DISPATCH_COMPLETE ? "complete" : \
+ (s) == DBUS_DISPATCH_DATA_REMAINS ? "data remains" : \
+ (s) == DBUS_DISPATCH_NEED_MEMORY ? "need memory" : \
+ "???")
+
/**
* @defgroup DBusConnection DBusConnection
* @ingroup DBus
@@ -350,12 +356,15 @@
_dbus_connection_wakeup_mainloop (connection);
- _dbus_verbose ("Message %p (%d %s '%s') added to incoming queue %p, %d incoming\n",
+ _dbus_verbose ("Message %p (%d %s %s '%s') added to incoming queue %p, %d incoming\n",
message,
dbus_message_get_type (message),
dbus_message_get_interface (message) ?
dbus_message_get_interface (message) :
"no interface",
+ dbus_message_get_member (message) ?
+ dbus_message_get_member (message) :
+ "no member",
dbus_message_get_signature (message),
connection,
connection->n_incoming);
@@ -388,17 +397,38 @@
/**
* Checks whether there are messages in the outgoing message queue.
+ * Called with connection lock held.
*
* @param connection the connection.
* @returns #TRUE if the outgoing queue is non-empty.
*/
dbus_bool_t
-_dbus_connection_have_messages_to_send (DBusConnection *connection)
+_dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection)
{
return connection->outgoing_messages != NULL;
}
/**
+ * Checks whether there are messages in the outgoing message queue.
+ *
+ * @param connection the connection.
+ * @returns #TRUE if the outgoing queue is non-empty.
+ */
+dbus_bool_t
+dbus_connection_has_messages_to_send (DBusConnection *connection)
+{
+ dbus_bool_t v;
+
+ _dbus_return_val_if_fail (connection != NULL, FALSE);
+
+ CONNECTION_LOCK (connection);
+ v = _dbus_connection_has_messages_to_send_unlocked (connection);
+ CONNECTION_UNLOCK (connection);
+
+ return v;
+}
+
+/**
* Gets the next outgoing message. The message remains in the
* queue, and the caller does not own a reference to it.
*
@@ -424,8 +454,11 @@
DBusMessage *message)
{
DBusList *link;
-
- _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport));
+
+ /* This can be called before we even complete authentication, since
+ * it's called on disconnect to clean up the outgoing queue.
+ * It's also called as we successfully send each message.
+ */
link = _dbus_list_get_last_link (&connection->outgoing_messages);
_dbus_assert (link != NULL);
@@ -438,12 +471,15 @@
connection->n_outgoing -= 1;
- _dbus_verbose ("Message %p (%d %s '%s') removed from outgoing queue %p, %d left to send\n",
+ _dbus_verbose ("Message %p (%d %s %s '%s') removed from outgoing queue %p, %d left to send\n",
message,
dbus_message_get_type (message),
dbus_message_get_interface (message) ?
dbus_message_get_interface (message) :
"no interface",
+ dbus_message_get_member (message) ?
+ dbus_message_get_member (message) :
+ "no member",
dbus_message_get_signature (message),
connection, connection->n_outgoing);
@@ -453,10 +489,6 @@
_dbus_list_prepend_link (&connection->link_cache, link);
dbus_message_unref (message);
-
- if (connection->n_outgoing == 0)
- _dbus_transport_messages_pending (connection->transport,
- connection->n_outgoing);
}
/**
@@ -501,6 +533,7 @@
* Toggles a watch and notifies app via connection's
* DBusWatchToggledFunction if available. It's an error to call this
* function on a watch that was not previously added.
+ * Connection lock should be held when calling this.
*
* @param connection the connection.
* @param watch the watch to toggle.
@@ -511,6 +544,8 @@
DBusWatch *watch,
dbus_bool_t enabled)
{
+ _dbus_assert (watch != NULL);
+
if (connection->watches) /* null during finalize */
_dbus_watch_list_toggle_watch (connection->watches,
watch, enabled);
@@ -777,6 +812,8 @@
* wasn't specified, then it's impossible to block, even if
* you specify DBUS_ITERATION_BLOCK; in that case the function
* returns immediately.
+ *
+ * Called with connection lock held.
*
* @param connection the connection.
* @param flags iteration flags.
@@ -1001,11 +1038,11 @@
#ifdef DBUS_HAVE_ATOMIC_INT
last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
-#else
+#else
_dbus_assert (connection->refcount.value > 0);
connection->refcount.value -= 1;
- last_unref = (connection->refcount.value == 0);
+ last_unref = (connection->refcount.value == 0);
#if 0
printf ("unref_unlocked() connection %p count = %d\n", connection, connection->refcount.value);
#endif
@@ -1311,6 +1348,8 @@
DBusDispatchStatus status;
_dbus_return_if_fail (connection != NULL);
+
+ _dbus_verbose ("Disconnecting %p\n", connection);
CONNECTION_LOCK (connection);
_dbus_transport_disconnect (connection->transport);
@@ -1504,6 +1543,7 @@
dbus_uint32_t *client_serial)
{
dbus_uint32_t serial;
+ const char *sig;
preallocated->queue_link->data = message;
_dbus_list_prepend_link (&connection->outgoing_messages,
@@ -1519,13 +1559,27 @@
connection->n_outgoing += 1;
- _dbus_verbose ("Message %p (%d %s '%s') added to outgoing queue %p, %d pending to send\n",
+ sig = dbus_message_get_signature (message);
+#ifndef DBUS_DISABLE_ASSERT
+ {
+ DBusString foo;
+ _dbus_verbose (" validating signature '%s'\n", sig);
+ _dbus_string_init_const (&foo, sig);
+ _dbus_assert (_dbus_string_validate_signature (&foo, 0,
+ _dbus_string_get_length (&foo)));
+ }
+#endif
+
+ _dbus_verbose ("Message %p (%d %s %s '%s') added to outgoing queue %p, %d pending to send\n",
message,
dbus_message_get_type (message),
dbus_message_get_interface (message) ?
dbus_message_get_interface (message) :
"no interface",
- dbus_message_get_signature (message),
+ dbus_message_get_member (message) ?
+ dbus_message_get_member (message) :
+ "no member",
+ sig,
connection,
connection->n_outgoing);
@@ -1544,11 +1598,16 @@
_dbus_message_lock (message);
- if (connection->n_outgoing == 1)
- _dbus_transport_messages_pending (connection->transport,
- connection->n_outgoing);
+ /* Now we need to run an iteration to hopefully just write the messages
+ * out immediately, and otherwise get them queued up
+ */
+ _dbus_connection_do_iteration (connection,
+ DBUS_ITERATION_DO_WRITING,
+ -1);
- _dbus_connection_wakeup_mainloop (connection);
+ /* If stuff is still queued up, be sure we wake up the main loop */
+ if (connection->n_outgoing > 0)
+ _dbus_connection_wakeup_mainloop (connection);
}
/**
@@ -2195,12 +2254,15 @@
link = _dbus_list_pop_first_link (&connection->incoming_messages);
connection->n_incoming -= 1;
- _dbus_verbose ("Message %p (%d %s '%s') removed from incoming queue %p, %d incoming\n",
+ _dbus_verbose ("Message %p (%d %s %s '%s') removed from incoming queue %p, %d incoming\n",
link->data,
dbus_message_get_type (link->data),
dbus_message_get_interface (link->data) ?
dbus_message_get_interface (link->data) :
"no interface",
+ dbus_message_get_member (link->data) ?
+ dbus_message_get_member (link->data) :
+ "no member",
dbus_message_get_signature (link->data),
connection, connection->n_incoming);
@@ -2246,12 +2308,15 @@
message_link);
connection->n_incoming += 1;
- _dbus_verbose ("Message %p (%d %s '%s') put back into queue %p, %d incoming\n",
+ _dbus_verbose ("Message %p (%d %s %s '%s') put back into queue %p, %d incoming\n",
message_link->data,
dbus_message_get_type (message_link->data),
dbus_message_get_interface (message_link->data) ?
dbus_message_get_interface (message_link->data) :
"no interface",
+ dbus_message_get_member (message_link->data) ?
+ dbus_message_get_member (message_link->data) :
+ "no member",
dbus_message_get_signature (message_link->data),
connection, connection->n_incoming);
}
@@ -2347,19 +2412,46 @@
else
{
DBusDispatchStatus status;
+ dbus_bool_t is_connected;
status = _dbus_transport_get_dispatch_status (connection->transport);
+ is_connected = _dbus_transport_get_is_connected (connection->transport);
- if (status == DBUS_DISPATCH_COMPLETE &&
- connection->disconnect_message_link &&
- !_dbus_transport_get_is_connected (connection->transport))
+ _dbus_verbose ("dispatch status = %s is_connected = %d\n",
+ DISPATCH_STATUS_NAME (status), is_connected);
+
+ if (!is_connected)
{
- /* We haven't sent the disconnect message already,
- * and all real messages have been queued up.
+ if (status == DBUS_DISPATCH_COMPLETE &&
+ connection->disconnect_message_link)
+ {
+ _dbus_verbose ("Sending disconnect message from %s\n",
+ _DBUS_FUNCTION_NAME);
+
+ /* We haven't sent the disconnect message already,
+ * and all real messages have been queued up.
+ */
+ _dbus_connection_queue_synthesized_message_link (connection,
+ connection->disconnect_message_link);
+ connection->disconnect_message_link = NULL;
+ }
+
+ /* Dump the outgoing queue, we aren't going to be able to
+ * send it now, and we'd like accessors like
+ * dbus_connection_get_outgoing_size() to be accurate.
*/
- _dbus_connection_queue_synthesized_message_link (connection,
- connection->disconnect_message_link);
- connection->disconnect_message_link = NULL;
+ if (connection->n_outgoing > 0)
+ {
+ DBusList *link;
+
+ _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
+ connection->n_outgoing);
+
+ while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
+ {
+ _dbus_connection_message_sent (connection, link->data);
+ }
+ }
}
if (status != DBUS_DISPATCH_COMPLETE)
@@ -2397,10 +2489,7 @@
{
_dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
connection, new_status,
- new_status == DBUS_DISPATCH_COMPLETE ? "complete" :
- new_status == DBUS_DISPATCH_DATA_REMAINS ? "data remains" :
- new_status == DBUS_DISPATCH_NEED_MEMORY ? "need memory" :
- "???");
+ DISPATCH_STATUS_NAME (new_status));
(* function) (connection, new_status, data);
}
@@ -2470,6 +2559,8 @@
_dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
+ _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
+
CONNECTION_LOCK (connection);
status = _dbus_connection_get_dispatch_status_unlocked (connection);
if (status != DBUS_DISPATCH_DATA_REMAINS)
@@ -2497,6 +2588,8 @@
{
/* another thread dispatched our stuff */
+ _dbus_verbose ("another thread dispatched message\n");
+
_dbus_connection_release_dispatch (connection);
status = _dbus_connection_get_dispatch_status_unlocked (connection);
@@ -2509,6 +2602,17 @@
}
message = message_link->data;
+
+ _dbus_verbose (" dispatching message %p (%d %s %s '%s')\n",
+ message,
+ dbus_message_get_type (message),
+ dbus_message_get_interface (message) ?
+ dbus_message_get_interface (message) :
+ "no interface",
+ dbus_message_get_member (message) ?
+ dbus_message_get_member (message) :
+ "no member",
+ dbus_message_get_signature (message));
result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -2563,7 +2667,10 @@
CONNECTION_LOCK (connection);
if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
- goto out;
+ {
+ _dbus_verbose ("No memory in %s\n", _DBUS_FUNCTION_NAME);
+ goto out;
+ }
/* Did a reply we were waiting on get filtered? */
if (pending && result == DBUS_HANDLER_RESULT_HANDLED)
@@ -2583,7 +2690,10 @@
}
if (result == DBUS_HANDLER_RESULT_HANDLED)
- goto out;
+ {
+ _dbus_verbose ("filter handled message in dispatch\n");
+ goto out;
+ }
if (pending)
{
@@ -2592,18 +2702,22 @@
pending = NULL;
CONNECTION_LOCK (connection);
+ _dbus_verbose ("pending call completed in dispatch\n");
goto out;
}
/* We're still protected from dispatch() reentrancy here
* since we acquired the dispatcher
*/
- _dbus_verbose (" running object path dispatch on message %p (%d %s '%s')\n",
+ _dbus_verbose (" running object path dispatch on message %p (%d %s %s '%s')\n",
message,
dbus_message_get_type (message),
dbus_message_get_interface (message) ?
dbus_message_get_interface (message) :
"no interface",
+ dbus_message_get_member (message) ?
+ dbus_message_get_member (message) :
+ "no member",
dbus_message_get_signature (message));
result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
@@ -2612,7 +2726,10 @@
CONNECTION_LOCK (connection);
if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
- goto out;
+ {
+ _dbus_verbose ("object tree handled message in dispatch\n");
+ goto out;
+ }
if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
{
@@ -2626,6 +2743,7 @@
if (!_dbus_string_init (&str))
{
result = DBUS_HANDLER_RESULT_NEED_MEMORY;
+ _dbus_verbose ("no memory for error string in dispatch\n");
goto out;
}
@@ -2636,6 +2754,7 @@
{
_dbus_string_free (&str);
result = DBUS_HANDLER_RESULT_NEED_MEMORY;
+ _dbus_verbose ("no memory for error string in dispatch\n");
goto out;
}
@@ -2647,6 +2766,7 @@
if (reply == NULL)
{
result = DBUS_HANDLER_RESULT_NEED_MEMORY;
+ _dbus_verbose ("no memory for error reply in dispatch\n");
goto out;
}
@@ -2656,6 +2776,7 @@
{
dbus_message_unref (reply);
result = DBUS_HANDLER_RESULT_NEED_MEMORY;
+ _dbus_verbose ("no memory for error send in dispatch\n");
goto out;
}
@@ -2667,11 +2788,14 @@
result = DBUS_HANDLER_RESULT_HANDLED;
}
- _dbus_verbose (" done dispatching %p (%d %s '%s') on connection %p\n", message,
+ _dbus_verbose (" done dispatching %p (%d %s %s '%s') on connection %p\n", message,
dbus_message_get_type (message),
dbus_message_get_interface (message) ?
dbus_message_get_interface (message) :
"no interface",
+ dbus_message_get_member (message) ?
+ dbus_message_get_member (message) :
+ "no member",
dbus_message_get_signature (message),
connection);
@@ -2689,7 +2813,7 @@
}
else
{
- _dbus_verbose ("Done with message in %s\n", _DBUS_FUNCTION_NAME);
+ _dbus_verbose (" ... done dispatching in %s\n", _DBUS_FUNCTION_NAME);
if (connection->exit_on_disconnect &&
dbus_message_is_signal (message,
Index: dbus-connection.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-connection.h,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -d -r1.33 -r1.34
--- dbus-connection.h 9 Sep 2004 10:20:17 -0000 1.33
+++ dbus-connection.h 26 Nov 2004 01:53:13 -0000 1.34
@@ -105,6 +105,7 @@
DBusMessage* dbus_connection_pop_message (DBusConnection *connection);
DBusDispatchStatus dbus_connection_get_dispatch_status (DBusConnection *connection);
DBusDispatchStatus dbus_connection_dispatch (DBusConnection *connection);
+dbus_bool_t dbus_connection_has_messages_to_send (DBusConnection *connection);
dbus_bool_t dbus_connection_send (DBusConnection *connection,
DBusMessage *message,
dbus_uint32_t *client_serial);
Index: dbus-internals.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-internals.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -d -r1.37 -r1.38
--- dbus-internals.c 10 Aug 2004 03:06:59 -0000 1.37
+++ dbus-internals.c 26 Nov 2004 01:53:13 -0000 1.38
@@ -191,6 +191,7 @@
va_list args;
static dbus_bool_t verbose = TRUE;
static dbus_bool_t need_pid = TRUE;
+ int len;
/* things are written a bit oddly here so that
* in the non-verbose case we just have the one
@@ -207,18 +208,16 @@
return;
}
+ /* Print out pid before the line */
if (need_pid)
- {
- int len;
-
- fprintf (stderr, "%lu: ", _dbus_getpid ());
+ fprintf (stderr, "%lu: ", _dbus_getpid ());
- len = strlen (format);
- if (format[len-1] == '\n')
- need_pid = TRUE;
- else
- need_pid = FALSE;
- }
+ /* Only print pid again if the next line is a new line */
+ len = strlen (format);
+ if (format[len-1] == '\n')
+ need_pid = TRUE;
+ else
+ need_pid = FALSE;
va_start (args, format);
vfprintf (stderr, format, args);
@@ -418,6 +417,8 @@
return "destination";
case DBUS_HEADER_FIELD_SENDER:
return "sender";
+ case DBUS_HEADER_FIELD_SIGNATURE:
+ return "signature";
default:
return "unknown";
}
Index: dbus-keyring.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-keyring.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- dbus-keyring.c 10 Aug 2004 21:32:25 -0000 1.25
+++ dbus-keyring.c 26 Nov 2004 01:53:13 -0000 1.26
@@ -759,7 +759,7 @@
{
_dbus_string_set_length (&homedir, 0);
if (!_dbus_string_append (&homedir, override))
- _dbus_assert_not_reached ("no memory");
+ goto failed;
_dbus_verbose ("Using fake homedir for testing: %s\n",
_dbus_string_get_const_data (&homedir));
Index: dbus-mainloop.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-mainloop.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- dbus-mainloop.c 10 Aug 2004 03:06:59 -0000 1.16
+++ dbus-mainloop.c 26 Nov 2004 01:53:13 -0000 1.17
@@ -1,7 +1,7 @@
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-mainloop.c Main loop utility
*
- * Copyright (C) 2003 Red Hat, Inc.
+ * Copyright (C) 2003, 2004 Red Hat, Inc.
*
* Licensed under the Academic Free License version 2.1
*
@@ -30,6 +30,27 @@
#define MAINLOOP_SPEW 0
+#ifdef MAINLOOP_SPEW
+#ifdef DBUS_ENABLE_VERBOSE_MODE
+static const char*
+watch_flags_to_string (int flags)
+{
+ const char *watch_type;
+
+ if ((flags & DBUS_WATCH_READABLE) &&
+ (flags & DBUS_WATCH_WRITABLE))
+ watch_type = "readwrite";
+ else if (flags & DBUS_WATCH_READABLE)
+ watch_type = "read";
+ else if (flags & DBUS_WATCH_WRITABLE)
+ watch_type = "write";
+ else
+ watch_type = "not read or write";
+ return watch_type;
+}
+#endif /* DBUS_ENABLE_VERBOSE_MODE */
+#endif /* MAINLOOP_SPEW */
+
struct DBusLoop
{
int refcount;
@@ -597,7 +618,8 @@
fds[n_fds].events |= _DBUS_POLLOUT;
#if MAINLOOP_SPEW
- _dbus_verbose (" polling watch on fd %d\n", fds[n_fds].fd);
+ _dbus_verbose (" polling watch on fd %d %s\n",
+ fds[n_fds].fd, watch_flags_to_string (flags));
#endif
n_fds += 1;
@@ -605,8 +627,9 @@
else
{
#if MAINLOOP_SPEW
- _dbus_verbose (" skipping disabled watch on fd %d\n",
- dbus_watch_get_fd (wcb->watch));
+ _dbus_verbose (" skipping disabled watch on fd %d %s\n",
+ dbus_watch_get_fd (wcb->watch),
+ watch_flags_to_string (dbus_watch_get_flags (wcb->watch)));
#endif
}
}
Index: dbus-message.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-message.c,v
retrieving revision 1.140
retrieving revision 1.141
diff -u -d -r1.140 -r1.141
--- dbus-message.c 13 Nov 2004 07:07:46 -0000 1.140
+++ dbus-message.c 26 Nov 2004 01:53:13 -0000 1.141
@@ -525,8 +525,10 @@
int value_end;
int pos;
+#if 0
_dbus_verbose ("%s: name_offset=%d, append to %p\n",
_DBUS_FUNCTION_NAME, name_offset, append_copy_to);
+#endif
pos = name_offset;
@@ -547,9 +549,12 @@
array_type = _dbus_string_get_byte (str, pos);
}
- _dbus_verbose ("%s: name %d, type '%c' %d at %d len %d, array type '%c' %d\n",
+#if 0
+ _dbus_verbose ("%s: name %s, type '%c' %d at %d len %d, array type '%c' %d\n",
_DBUS_FUNCTION_NAME,
- name, type, type, type_pos, type_len, array_type, array_type);
+ _dbus_header_field_to_string (name),
+ type, type, type_pos, type_len, array_type, array_type);
+#endif
#ifndef DBUS_DISABLE_ASSERT
if (!_dbus_type_is_valid (array_type))
@@ -631,7 +636,7 @@
{
int i;
i = 0;
- while (i < DBUS_HEADER_FIELD_LAST)
+ while (i <= DBUS_HEADER_FIELD_LAST)
{
if (message->header_fields[i].name_offset >= 0)
_dbus_assert (_dbus_string_get_byte (&message->header,
@@ -656,7 +661,7 @@
int next_offset;
int field_name;
dbus_bool_t retval;
- HeaderField new_header_fields[DBUS_HEADER_FIELD_LAST];
+ HeaderField new_header_fields[DBUS_HEADER_FIELD_LAST+1];
_dbus_assert (name_offset_to_delete < _dbus_string_get_length (&message->header));
verify_header_fields (message);
@@ -703,7 +708,11 @@
&field_name, NULL, NULL, NULL))
_dbus_assert_not_reached ("shouldn't have failed to alloc memory to skip the deleted field");
- if (field_name < DBUS_HEADER_FIELD_LAST)
+ _dbus_verbose (" Skipping %s field which will be deleted; next_offset = %d\n",
+ _dbus_header_field_to_string (field_name), next_offset);
+
+ /* This field no longer exists */
+ if (field_name <= DBUS_HEADER_FIELD_LAST)
{
new_header_fields[field_name].name_offset = -1;
new_header_fields[field_name].value_offset = -1;
@@ -728,10 +737,16 @@
goto out_1;
}
- if (field_name < DBUS_HEADER_FIELD_LAST)
+ if (field_name <= DBUS_HEADER_FIELD_LAST)
{
new_header_fields[field_name].name_offset = copy_name_offset - new_fields_front_padding + name_offset_to_delete;
new_header_fields[field_name].value_offset = copy_value_offset - new_fields_front_padding + name_offset_to_delete;
+
+ _dbus_verbose (" Re-adding %s field at name_offset = %d value_offset = %d; next_offset = %d\n",
+ _dbus_header_field_to_string (field_name),
+ new_header_fields[field_name].name_offset,
+ new_header_fields[field_name].value_offset,
+ next_offset);
}
}
@@ -801,6 +816,9 @@
int offset = message->header_fields[field].value_offset;
_dbus_assert (!message->locked);
+
+ _dbus_verbose ("set_int_field() field %d value '%d'\n",
+ field, value);
if (offset < 0)
{
@@ -826,6 +844,9 @@
int offset = message->header_fields[field].value_offset;
_dbus_assert (!message->locked);
+
+ _dbus_verbose ("set_uint_field() field %d value '%u'\n",
+ field, value);
if (offset < 0)
{
@@ -860,8 +881,8 @@
*/
prealloc = value_len + MAX_BYTES_OVERHEAD_TO_APPEND_A_STRING;
- _dbus_verbose ("set_string_field() field %d prealloc %d\n",
- field, prealloc);
+ _dbus_verbose ("set_string_field() field %d prealloc %d value '%s'\n",
+ field, prealloc, value);
if (!delete_field (message, field, prealloc))
return FALSE;
@@ -5118,8 +5139,6 @@
&field_data, pos, type))
return FALSE;
-#if 0
- /* FIXME */
if (!_dbus_string_validate_signature (&field_data, 0,
_dbus_string_get_length (&field_data)))
{
@@ -5127,7 +5146,6 @@
_dbus_string_get_const_data (&field_data));
return FALSE;
}
-#endif
break;
default:
@@ -7317,6 +7335,77 @@
dbus_free (t);
dbus_message_unref (message);
+
+ /* This ServiceAcquired message used to trigger a bug in
+ * setting header fields, adding to regression test.
+ */
+ message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_DBUS,
+ DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS,
+ "ServiceAcquired");
+
+ if (message == NULL)
+ _dbus_assert_not_reached ("out of memory");
+
+ _dbus_verbose ("Bytes after creation\n");
+ _dbus_verbose_bytes_of_string (&message->header, 0,
+ _dbus_string_get_length (&message->header));
+
+ if (!dbus_message_set_destination (message, ":1.0") ||
+ !dbus_message_append_args (message,
+ DBUS_TYPE_STRING, ":1.0",
+ DBUS_TYPE_INVALID))
+ _dbus_assert_not_reached ("out of memory");
+
+ _dbus_verbose ("Bytes after set_destination() and append_args()\n");
+ _dbus_verbose_bytes_of_string (&message->header, 0,
+ _dbus_string_get_length (&message->header));
+
+ if (!dbus_message_set_sender (message, "org.freedesktop.DBus"))
+ _dbus_assert_not_reached ("out of memory");
+
+ _dbus_verbose ("Bytes after set_sender()\n");
+ _dbus_verbose_bytes_of_string (&message->header, 0,
+ _dbus_string_get_length (&message->header));
+
+ /* When the bug happened the above set_destination() would
+ * corrupt the signature
+ */
+ if (!dbus_message_has_signature (message, "s"))
+ {
+ _dbus_warn ("Signature should be 's' but is '%s'\n",
+ dbus_message_get_signature (message));
+ _dbus_assert_not_reached ("signal has wrong signature");
+ }
+
+ /* have to set destination again to reproduce the bug */
+ if (!dbus_message_set_destination (message, ":1.0"))
+ _dbus_assert_not_reached ("out of memory");
+
+ _dbus_verbose ("Bytes after set_destination()\n");
+ _dbus_verbose_bytes_of_string (&message->header, 0,
+ _dbus_string_get_length (&message->header));
+
+ /* When the bug happened the above set_destination() would
+ * corrupt the signature
+ */
+ if (!dbus_message_has_signature (message, "s"))
+ {
+ _dbus_warn ("Signature should be 's' but is '%s'\n",
+ dbus_message_get_signature (message));
+ _dbus_assert_not_reached ("signal has wrong signature");
+ }
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING,
+ &t, DBUS_TYPE_INVALID))
+
+ {
+ _dbus_warn ("Failed to get expected string arg for signal: %s\n", error.message);
+ exit (1);
+ }
+ dbus_free (t);
+
+ dbus_message_unref (message);
/* Now load every message in test_data_dir if we have one */
if (test_data_dir == NULL)
Index: dbus-server-unix.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-server-unix.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- dbus-server-unix.c 10 Aug 2004 03:07:00 -0000 1.23
+++ dbus-server-unix.c 26 Nov 2004 01:53:13 -0000 1.24
@@ -58,11 +58,10 @@
unix_finalize (DBusServer *server)
{
DBusServerUnix *unix_server = (DBusServerUnix*) server;
-
- dbus_free (unix_server->socket_name);
_dbus_server_finalize_base (server);
-
+
+ dbus_free (unix_server->socket_name);
dbus_free (server);
}
Index: dbus-string.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-string.c,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -d -r1.53 -r1.54
--- dbus-string.c 22 Nov 2004 19:20:29 -0000 1.53
+++ dbus-string.c 26 Nov 2004 01:53:13 -0000 1.54
@@ -1,7 +1,7 @@
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-string.c String utility class (internal to D-BUS implementation)
*
- * Copyright (C) 2002, 2003 Red Hat, Inc.
+ * Copyright (C) 2002, 2003, 2004 Red Hat, Inc.
*
* Licensed under the Academic Free License version 2.1
*
@@ -2362,7 +2362,7 @@
* string, returns #FALSE.
*
* @todo this is inconsistent with most of DBusString in that
- * it allows a start,len range that isn't in the string.
+ * it allows a start,len range that extends past the string end.
*
* @param str the string
* @param start first byte index to check
@@ -2406,7 +2406,7 @@
* boundaries, returns #FALSE.
*
* @todo this is inconsistent with most of DBusString in that
- * it allows a start,len range that isn't in the string.
+ * it allows a start,len range that extends past the string end.
*
* @param str the string
* @param start first byte index to check
@@ -2504,7 +2504,7 @@
* #FALSE.
*
* @todo this is inconsistent with most of DBusString in that
- * it allows a start,len range that isn't in the string.
+ * it allows a start,len range that extends past the string end.
*
* @param str the string
* @param start first byte index to check
@@ -2545,7 +2545,7 @@
* to be done separately for now.
*
* @todo this is inconsistent with most of DBusString in that
- * it allows a start,len range that isn't in the string.
+ * it allows a start,len range that extends past the string end.
*
* @todo change spec to disallow more things, such as spaces in the
* path name
@@ -2631,7 +2631,7 @@
* ASCII subset, see the specification.
*
* @todo this is inconsistent with most of DBusString in that
- * it allows a start,len range that isn't in the string.
+ * it allows a start,len range that extends past the string end.
*
* @param str the string
* @param start first byte index to check
@@ -2708,7 +2708,7 @@
* see the specification.
*
* @todo this is inconsistent with most of DBusString in that
- * it allows a start,len range that isn't in the string.
+ * it allows a start,len range that extends past the string end.
*
* @param str the string
* @param start first byte index to check
@@ -2770,7 +2770,7 @@
* see the specification.
*
* @todo this is inconsistent with most of DBusString in that
- * it allows a start,len range that isn't in the string.
+ * it allows a start,len range that extends past the string end.
*
* @param str the string
* @param start first byte index to check
@@ -2841,7 +2841,7 @@
* see the specification.
*
* @todo this is inconsistent with most of DBusString in that
- * it allows a start,len range that isn't in the string.
+ * it allows a start,len range that extends past the string end.
*
* @param str the string
* @param start first byte index to check
@@ -2862,6 +2862,64 @@
}
/**
+ * Checks that the given range of the string is a valid message type
+ * signature in the D-BUS protocol.
+ *
+ * @todo this is inconsistent with most of DBusString in that
+ * it allows a start,len range that extends past the string end.
+ *
+ * @param str the string
+ * @param start first byte index to check
+ * @param len number of bytes to check
+ * @returns #TRUE if the byte range exists and is a valid signature
+ */
+dbus_bool_t
+_dbus_string_validate_signature (const DBusString *str,
+ int start,
+ int len)
+{
+ const unsigned char *s;
+ const unsigned char *end;
+ DBUS_CONST_STRING_PREAMBLE (str);
+ _dbus_assert (start >= 0);
+ _dbus_assert (start <= real->len);
+ _dbus_assert (len >= 0);
+
+ if (len > real->len - start)
+ return FALSE;
+
+ s = real->str + start;
+ end = s + len;
+ while (s != end)
+ {
+ switch (*s)
+ {
+ case DBUS_TYPE_NIL:
+ case DBUS_TYPE_BYTE:
+ case DBUS_TYPE_BOOLEAN:
+ case DBUS_TYPE_INT32:
+ case DBUS_TYPE_UINT32:
+ case DBUS_TYPE_INT64:
+ case DBUS_TYPE_UINT64:
+ case DBUS_TYPE_DOUBLE:
+ case DBUS_TYPE_STRING:
+ case DBUS_TYPE_CUSTOM:
+ case DBUS_TYPE_ARRAY:
+ case DBUS_TYPE_DICT:
+ case DBUS_TYPE_OBJECT_PATH:
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ ++s;
+ }
+
+ return TRUE;
+}
+
+/**
* Clears all allocated bytes in the string to zero.
*
* @param str the string
@@ -3227,6 +3285,21 @@
" ",
"foo bar"
};
+
+ const char *valid_signatures[] = {
+ "",
+ "sss",
+ "i",
+ "b"
+ };
+
+ const char *invalid_signatures[] = {
+ " ",
+ "not a valid signature",
+ "123",
+ ".",
+ "("
+ };
i = 0;
while (i < _DBUS_N_ELEMENTS (lens))
@@ -3811,6 +3884,37 @@
++i;
}
+ /* Signature validation */
+ i = 0;
+ while (i < (int) _DBUS_N_ELEMENTS (valid_signatures))
+ {
+ _dbus_string_init_const (&str, valid_signatures[i]);
+
+ if (!_dbus_string_validate_signature (&str, 0,
+ _dbus_string_get_length (&str)))
+ {
+ _dbus_warn ("Signature \"%s\" should have been valid\n", valid_signatures[i]);
+ _dbus_assert_not_reached ("invalid signature");
+ }
+
+ ++i;
+ }
+
+ i = 0;
+ while (i < (int) _DBUS_N_ELEMENTS (invalid_signatures))
+ {
+ _dbus_string_init_const (&str, invalid_signatures[i]);
+
+ if (_dbus_string_validate_signature (&str, 0,
+ _dbus_string_get_length (&str)))
+ {
+ _dbus_warn ("Signature \"%s\" should have been invalid\n", invalid_signatures[i]);
+ _dbus_assert_not_reached ("valid signature");
+ }
+
+ ++i;
+ }
+
/* Validate claimed length longer than real length */
_dbus_string_init_const (&str, "abc.efg");
if (_dbus_string_validate_service (&str, 0, 8))
@@ -3824,6 +3928,10 @@
if (_dbus_string_validate_member (&str, 0, 4))
_dbus_assert_not_reached ("validated too-long string");
+ _dbus_string_init_const (&str, "sss");
+ if (_dbus_string_validate_signature (&str, 0, 4))
+ _dbus_assert_not_reached ("validated too-long signature");
+
/* Validate string exceeding max name length */
if (!_dbus_string_init (&str))
_dbus_assert_not_reached ("no memory");
Index: dbus-string.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-string.h,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- dbus-string.h 13 Nov 2004 07:07:46 -0000 1.29
+++ dbus-string.h 26 Nov 2004 01:53:13 -0000 1.30
@@ -253,6 +253,9 @@
dbus_bool_t _dbus_string_validate_service (const DBusString *str,
int start,
int len);
+dbus_bool_t _dbus_string_validate_signature (const DBusString *str,
+ int start,
+ int len);
void _dbus_string_zero (DBusString *str);
Index: dbus-sysdeps.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-sysdeps.c,v
retrieving revision 1.82
retrieving revision 1.83
diff -u -d -r1.82 -r1.83
--- dbus-sysdeps.c 29 Oct 2004 19:59:14 -0000 1.82
+++ dbus-sysdeps.c 26 Nov 2004 01:53:13 -0000 1.83
@@ -3019,6 +3019,9 @@
*fd1 = fds[0];
*fd2 = fds[1];
+
+ _dbus_verbose ("full-duplex pipe %d <-> %d\n",
+ *fd1, *fd2);
return TRUE;
#else
Index: dbus-transport-protected.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-transport-protected.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- dbus-transport-protected.h 9 Sep 2004 10:20:17 -0000 1.14
+++ dbus-transport-protected.h 26 Nov 2004 01:53:13 -0000 1.15
@@ -1,7 +1,7 @@
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-transport-protected.h Used by subclasses of DBusTransport object (internal to D-BUS implementation)
*
- * Copyright (C) 2002 Red Hat Inc.
+ * Copyright (C) 2002, 2004 Red Hat Inc.
*
* Licensed under the Academic Free License version 2.1
*
@@ -56,12 +56,6 @@
dbus_bool_t (* connection_set) (DBusTransport *transport);
/**< Called when transport->connection has been filled in */
- void (* messages_pending) (DBusTransport *transport,
- int queue_length);
- /**< Called when the outgoing message queue goes from empty
- * to non-empty or vice versa.
- */
-
void (* do_iteration) (DBusTransport *transport,
unsigned int flags,
int timeout_milliseconds);
@@ -111,7 +105,6 @@
unsigned int disconnected : 1; /**< #TRUE if we are disconnected. */
unsigned int authenticated : 1; /**< Cache of auth state; use _dbus_transport_get_is_authenticated() to query value */
- unsigned int messages_need_sending : 1; /**< #TRUE if we need to write messages out */
unsigned int send_credentials_pending : 1; /**< #TRUE if we need to send credentials */
unsigned int receive_credentials_pending : 1; /**< #TRUE if we need to receive credentials */
unsigned int is_server : 1; /**< #TRUE if on the server side */
Index: dbus-transport-unix.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-transport-unix.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -d -r1.42 -r1.43
--- dbus-transport-unix.c 7 Nov 2004 17:06:34 -0000 1.42
+++ dbus-transport-unix.c 26 Nov 2004 01:53:13 -0000 1.43
@@ -1,7 +1,7 @@
/* -*- mode: C; c-file-style: "gnu" -*- */
/* dbus-transport-unix.c UNIX socket subclasses of DBusTransport
*
- * Copyright (C) 2002, 2003 Red Hat Inc.
+ * Copyright (C) 2002, 2003, 2004 Red Hat Inc.
*
* Licensed under the Academic Free License version 2.1
*
@@ -114,7 +114,7 @@
check_write_watch (DBusTransport *transport)
{
DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
- dbus_bool_t need_write_watch;
+ dbus_bool_t needed;
if (transport->connection == NULL)
return;
@@ -128,14 +128,37 @@
_dbus_transport_ref (transport);
if (_dbus_transport_get_is_authenticated (transport))
- need_write_watch = transport->messages_need_sending;
+ needed = _dbus_connection_has_messages_to_send_unlocked (transport->connection);
else
- need_write_watch = transport->send_credentials_pending ||
- _dbus_auth_do_work (transport->auth) == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND;
+ {
+ if (transport->send_credentials_pending)
+ needed = TRUE;
+ else
+ {
+ DBusAuthState auth_state;
+
+ auth_state = _dbus_auth_do_work (transport->auth);
+
+ /* If we need memory we install the write watch just in case,
+ * if there's no need for it, it will get de-installed
+ * next time we try reading.
+ */
+ if (auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND ||
+ auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY)
+ needed = TRUE;
+ else
+ needed = FALSE;
+ }
+ }
+
+ _dbus_verbose ("check_write_watch(): needed = %d on connection %p watch %p fd = %d outgoing messages exist %d\n",
+ needed, transport->connection, unix_transport->write_watch,
+ unix_transport->fd,
+ _dbus_connection_has_messages_to_send_unlocked (transport->connection));
_dbus_connection_toggle_watch (transport->connection,
unix_transport->write_watch,
- need_write_watch);
+ needed);
_dbus_transport_unref (transport);
}
@@ -146,6 +169,9 @@
DBusTransportUnix *unix_transport = (DBusTransportUnix*) transport;
dbus_bool_t need_read_watch;
+ _dbus_verbose ("%s: fd = %d\n",
+ _DBUS_FUNCTION_NAME, unix_transport->fd);
+
if (transport->connection == NULL)
return;
@@ -161,9 +187,35 @@
need_read_watch =
_dbus_counter_get_value (transport->live_messages_size) < transport->max_live_messages_size;
else
- need_read_watch = transport->receive_credentials_pending ||
- _dbus_auth_do_work (transport->auth) == DBUS_AUTH_STATE_WAITING_FOR_INPUT;
+ {
+ if (transport->receive_credentials_pending)
+ need_read_watch = TRUE;
+ else
+ {
+ /* The reason to disable need_read_watch when not WAITING_FOR_INPUT
+ * is to avoid spinning on the file descriptor when we're waiting
+ * to write or for some other part of the auth process
+ */
+ DBusAuthState auth_state;
+
+ auth_state = _dbus_auth_do_work (transport->auth);
+
+ /* If we need memory we install the read watch just in case,
+ * if there's no need for it, it will get de-installed
+ * next time we try reading. If we're authenticated we
+ * install it since we normally have it installed while
+ * authenticated.
+ */
+ if (auth_state == DBUS_AUTH_STATE_WAITING_FOR_INPUT ||
+ auth_state == DBUS_AUTH_STATE_WAITING_FOR_MEMORY ||
+ auth_state == DBUS_AUTH_STATE_AUTHENTICATED)
+ need_read_watch = TRUE;
+ else
+ need_read_watch = FALSE;
+ }
+ }
+ _dbus_verbose (" setting read watch enabled = %d\n", need_read_watch);
_dbus_connection_toggle_watch (transport->connection,
unix_transport->read_watch,
need_read_watch);
@@ -326,12 +378,24 @@
{
dbus_bool_t oom;
dbus_bool_t orig_auth_state;
-
- _dbus_transport_ref (transport);
oom = FALSE;
orig_auth_state = _dbus_transport_get_is_authenticated (transport);
+
+ /* This is essential to avoid the check_write_watch() at the end,
+ * we don't want to add a write watch in do_iteration before
+ * we try writing and get EAGAIN
+ */
+ if (orig_auth_state)
+ {
+ if (auth_completed)
+ *auth_completed = FALSE;
+ return TRUE;
+ }
+
+ _dbus_transport_ref (transport);
+
while (!_dbus_transport_get_is_authenticated (transport) &&
_dbus_transport_get_is_connected (transport))
{
@@ -418,16 +482,17 @@
return TRUE;
}
-#if 0
- _dbus_verbose ("do_writing(), have_messages = %d\n",
- _dbus_connection_have_messages_to_send (transport->connection));
+#if 1
+ _dbus_verbose ("do_writing(), have_messages = %d, fd = %d\n",
+ _dbus_connection_has_messages_to_send_unlocked (transport->connection),
+ unix_transport->fd);
#endif
oom = FALSE;
total = 0;
while (!transport->disconnected &&
- _dbus_connection_have_messages_to_send (transport->connection))
+ _dbus_connection_has_messages_to_send_unlocked (transport->connection))
{
int bytes_written;
DBusMessage *message;
@@ -442,12 +507,6 @@
total, unix_transport->max_bytes_written_per_iteration);
goto out;
}
-
- if (!dbus_watch_get_enabled (unix_transport->write_watch))
- {
- _dbus_verbose ("write watch disabled, not writing more stuff\n");
- goto out;
- }
message = _dbus_connection_get_message_to_send (transport->connection);
_dbus_assert (message != NULL);
@@ -580,6 +639,9 @@
int total;
dbus_bool_t oom;
+ _dbus_verbose ("%s: fd = %d\n", _DBUS_FUNCTION_NAME,
+ unix_transport->fd);
+
/* No messages without authentication! */
if (!_dbus_transport_get_is_authenticated (transport))
return TRUE;
@@ -722,6 +784,7 @@
_dbus_assert (watch == unix_transport->read_watch ||
watch == unix_transport->write_watch);
+ _dbus_assert (watch != NULL);
/* Disconnect in case of an error. In case of hangup do not
* disconnect the transport because data can still be in the buffer
@@ -741,8 +804,9 @@
(flags & DBUS_WATCH_READABLE))
{
dbus_bool_t auth_finished;
-#if 0
- _dbus_verbose ("handling read watch (%x)\n", flags);
+#if 1
+ _dbus_verbose ("handling read watch %p flags = %x\n",
+ watch, flags);
#endif
if (!do_authentication (transport, TRUE, FALSE, &auth_finished))
return FALSE;
@@ -761,13 +825,17 @@
return FALSE;
}
}
+ else
+ {
+ _dbus_verbose ("Not reading anything since we just completed the authentication\n");
+ }
}
else if (watch == unix_transport->write_watch &&
(flags & DBUS_WATCH_WRITABLE))
{
-#if 0
- _dbus_verbose ("handling write watch, messages_need_sending = %d\n",
- transport->messages_need_sending);
+#if 1
+ _dbus_verbose ("handling write watch, have_outgoing_messages = %d\n",
+ _dbus_connection_has_messages_to_send_unlocked (transport->connection));
#endif
if (!do_authentication (transport, FALSE, TRUE, NULL))
return FALSE;
@@ -777,6 +845,9 @@
_dbus_verbose ("no memory to write\n");
return FALSE;
}
+
+ /* See if we still need the write watch */
+ check_write_watch (transport);
}
#ifdef DBUS_ENABLE_VERBOSE_MODE
else
@@ -838,13 +909,6 @@
return TRUE;
}
-static void
-unix_messages_pending (DBusTransport *transport,
- int messages_pending)
-{
- check_write_watch (transport);
-}
-
/**
* @todo We need to have a way to wake up the select sleep if
* a new iteration request comes in with a flag (read/write) that
@@ -862,20 +926,18 @@
int poll_res;
int poll_timeout;
- _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p\n",
+ _dbus_verbose (" iteration flags = %s%s timeout = %d read_watch = %p write_watch = %p fd = %d\n",
flags & DBUS_ITERATION_DO_READING ? "read" : "",
flags & DBUS_ITERATION_DO_WRITING ? "write" : "",
timeout_milliseconds,
unix_transport->read_watch,
- unix_transport->write_watch);
+ unix_transport->write_watch,
+ unix_transport->fd);
/* the passed in DO_READING/DO_WRITING flags indicate whether to
* read/write messages, but regardless of those we may need to block
* for reading/writing to do auth. But if we do reading for auth,
* we don't want to read any messages yet if not given DO_READING.
- *
- * Also, if read_watch == NULL or write_watch == NULL, we don't
- * want to read/write so don't.
*/
poll_fd.fd = unix_transport->fd;
@@ -883,12 +945,12 @@
if (_dbus_transport_get_is_authenticated (transport))
{
- if (unix_transport->read_watch &&
- (flags & DBUS_ITERATION_DO_READING))
+ _dbus_assert (unix_transport->read_watch);
+ if (flags & DBUS_ITERATION_DO_READING)
poll_fd.events |= _DBUS_POLLIN;
-
- if (unix_transport->write_watch &&
- (flags & DBUS_ITERATION_DO_WRITING))
+
+ _dbus_assert (unix_transport->write_watch);
+ if (flags & DBUS_ITERATION_DO_WRITING)
poll_fd.events |= _DBUS_POLLOUT;
}
else
@@ -904,7 +966,7 @@
if (transport->send_credentials_pending ||
auth_state == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND)
poll_fd.events |= _DBUS_POLLOUT;
- }
+ }
if (poll_fd.events)
{
@@ -947,7 +1009,7 @@
/* See comment in unix_handle_watch. */
if (authentication_completed)
- return;
+ goto out;
if (need_read && (flags & DBUS_ITERATION_DO_READING))
do_reading (transport);
@@ -961,6 +1023,22 @@
_dbus_strerror (errno));
}
}
+
+
+ out:
+ /* We need to install the write watch only if we did not
+ * successfully write everything. Note we need to be careful that we
+ * don't call check_write_watch *before* do_writing, since it's
+ * inefficient to add the write watch, and we can avoid it most of
+ * the time since we can write immediately.
+ *
+ * However, we MUST always call check_write_watch(); DBusConnection code
+ * relies on the fact that running an iteration will notice that
+ * messages are pending.
+ */
+ check_write_watch (transport);
+
+ _dbus_verbose (" ... leaving do_iteration()\n");
}
static void
@@ -987,7 +1065,6 @@
unix_handle_watch,
unix_disconnect,
unix_connection_set,
- unix_messages_pending,
unix_do_iteration,
unix_live_messages_changed,
unix_get_unix_fd
Index: dbus-transport.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-transport.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- dbus-transport.c 10 Aug 2004 03:07:00 -0000 1.41
+++ dbus-transport.c 26 Nov 2004 01:53:13 -0000 1.42
@@ -141,7 +141,6 @@
transport->auth = auth;
transport->live_messages_size = counter;
transport->authenticated = FALSE;
- transport->messages_need_sending = FALSE;
transport->disconnected = FALSE;
transport->send_credentials_pending = !server;
transport->receive_credentials_pending = server;
@@ -611,32 +610,6 @@
}
/**
- * Notifies the transport when the outgoing message queue goes from
- * empty to non-empty or vice versa. Typically causes the transport to
- * add or remove its DBUS_WATCH_WRITABLE watch.
- *
- * @param transport the transport.
- * @param queue_length the length of the outgoing message queue.
- *
- */
-void
-_dbus_transport_messages_pending (DBusTransport *transport,
- int queue_length)
-{
- _dbus_assert (transport->vtable->messages_pending != NULL);
-
- if (transport->disconnected)
- return;
-
- transport->messages_need_sending = queue_length > 0;
-
- _dbus_transport_ref (transport);
- (* transport->vtable->messages_pending) (transport,
- queue_length);
- _dbus_transport_unref (transport);
-}
-
-/**
* Get the UNIX file descriptor, if any.
*
* @param transport the transport
Index: dbus-transport.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-transport.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- dbus-transport.h 9 Sep 2004 10:20:17 -0000 1.18
+++ dbus-transport.h 26 Nov 2004 01:53:13 -0000 1.19
@@ -44,8 +44,6 @@
unsigned int condition);
dbus_bool_t _dbus_transport_set_connection (DBusTransport *transport,
DBusConnection *connection);
-void _dbus_transport_messages_pending (DBusTransport *transport,
- int queue_length);
void _dbus_transport_do_iteration (DBusTransport *transport,
unsigned int flags,
int timeout_milliseconds);
Index: dbus-watch.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-watch.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- dbus-watch.c 10 Aug 2004 03:07:00 -0000 1.17
+++ dbus-watch.c 26 Nov 2004 01:53:13 -0000 1.18
@@ -268,8 +268,27 @@
DBusList *next = _dbus_list_get_next_link (&watch_list->watches,
link);
- _dbus_verbose ("Adding a watch on fd %d using newly-set add watch function\n",
- dbus_watch_get_fd (link->data));
+#ifdef DBUS_ENABLE_VERBOSE_MODE
+ {
+ const char *watch_type;
+ int flags;
+
+ flags = dbus_watch_get_flags (link->data);
+ if ((flags & DBUS_WATCH_READABLE) &&
+ (flags & DBUS_WATCH_WRITABLE))
+ watch_type = "readwrite";
+ else if (flags & DBUS_WATCH_READABLE)
+ watch_type = "read";
+ else if (flags & DBUS_WATCH_WRITABLE)
+ watch_type = "write";
+ else
+ watch_type = "not read or write";
+
+ _dbus_verbose ("Adding a %s watch on fd %d using newly-set add watch function\n",
+ watch_type,
+ dbus_watch_get_fd (link->data));
+ }
+#endif /* DBUS_ENABLE_VERBOSE_MODE */
if (!(* add_function) (link->data, data))
{
@@ -402,8 +421,8 @@
if (watch_list->watch_toggled_function != NULL)
{
- _dbus_verbose ("Toggling watch on fd %d to %d\n",
- dbus_watch_get_fd (watch), watch->enabled);
+ _dbus_verbose ("Toggling watch %p on fd %d to %d\n",
+ watch, dbus_watch_get_fd (watch), watch->enabled);
(* watch_list->watch_toggled_function) (watch,
watch_list->watch_data);
More information about the dbus-commit
mailing list