summaryrefslogtreecommitdiffstats
path: root/abs
diff options
context:
space:
mode:
Diffstat (limited to 'abs')
-rw-r--r--abs/core/dbus-core/PKGBUILD33
-rw-r--r--abs/core/dbus-core/bug17754.patch392
-rw-r--r--abs/core/dbus-core/git-fixes.patch289
3 files changed, 699 insertions, 15 deletions
diff --git a/abs/core/dbus-core/PKGBUILD b/abs/core/dbus-core/PKGBUILD
index b57829f..78ac2f8 100644
--- a/abs/core/dbus-core/PKGBUILD
+++ b/abs/core/dbus-core/PKGBUILD
@@ -1,9 +1,9 @@
-# $Id: PKGBUILD 73272 2010-03-24 11:36:47Z jgc $
+# $Id: PKGBUILD 90541 2010-09-13 10:46:30Z jgc $
# Maintainer: Jan de Groot <jgc@archlinux.org>
# Contributor: Link Dupont <link@subpop.net>
#
pkgname=dbus-core
-pkgver=1.2.24
+pkgver=1.4.0
pkgrel=1
pkgdesc="Freedesktop.org message bus system"
url="http://www.freedesktop.org/Software/dbus"
@@ -15,7 +15,7 @@ options=(!libtool)
install=dbus.install
source=(http://dbus.freedesktop.org/releases/dbus/dbus-${pkgver}.tar.gz
dbus)
-md5sums=('565346cecd9cfecf1463540c6086cc2c'
+md5sums=('f59618b18d2fb2bd1fce9e1c5a2a3282'
'08f93dd19cffd1b45ab05c1fd4efb560')
build() {
@@ -25,29 +25,32 @@ build() {
--with-system-pid-file=/var/run/dbus.pid \
--enable-inotify --disable-dnotify \
--disable-verbose-mode --disable-static \
- --disable-tests --disable-asserts --without-x || return 1
+ --disable-tests --disable-asserts --without-x
make || return 1
- make DESTDIR="${pkgdir}" install || return 1
+}
+package() {
+ cd "${srcdir}/dbus-${pkgver}"
+ make DESTDIR="${pkgdir}" install
rm -f "${pkgdir}/usr/bin/dbus-launch"
rm -f "${pkgdir}/usr/share/man/man1/dbus-launch.1"
- chown 81:81 "${pkgdir}/var/run/dbus" || return 1
+ chown 81:81 "${pkgdir}/var/run/dbus"
- install -m755 -d "${pkgdir}/etc/rc.d" || return 1
- install -m755 "${srcdir}/dbus" "${pkgdir}/etc/rc.d/" || return 1
+ install -m755 -d "${pkgdir}/etc/rc.d"
+ install -m755 "${srcdir}/dbus" "${pkgdir}/etc/rc.d/"
#Fix configuration file
- sed -i -e 's|<user>81</user>|<user>dbus</user>|' "${pkgdir}/etc/dbus-1/system.conf" || return 1
+ sed -i -e 's|<user>81</user>|<user>dbus</user>|' "${pkgdir}/etc/dbus-1/system.conf"
#install .keep files so pacman doesn't delete empty dirs
- touch "${pkgdir}/usr/share/dbus-1/services/.keep" || return 1
- touch "${pkgdir}/usr/share/dbus-1/system-services/.keep" || return 1
- touch "${pkgdir}/etc/dbus-1/session.d/.keep" || return 1
- touch "${pkgdir}/etc/dbus-1/system.d/.keep" || return 1
+ touch "${pkgdir}/usr/share/dbus-1/services/.keep"
+ touch "${pkgdir}/usr/share/dbus-1/system-services/.keep"
+ touch "${pkgdir}/etc/dbus-1/session.d/.keep"
+ touch "${pkgdir}/etc/dbus-1/system.d/.keep"
- rmdir "${pkgdir}/usr/lib/dbus-1.0/dbus-1" || return 1
+ rmdir "${pkgdir}/usr/lib/dbus-1.0/dbus-1"
install -d -m755 "${pkgdir}/usr/share/licenses/dbus-core"
- install -m644 COPYING "${pkgdir}/usr/share/licenses/dbus-core/" || return 1
+ install -m644 COPYING "${pkgdir}/usr/share/licenses/dbus-core/"
}
diff --git a/abs/core/dbus-core/bug17754.patch b/abs/core/dbus-core/bug17754.patch
new file mode 100644
index 0000000..7f677ac
--- /dev/null
+++ b/abs/core/dbus-core/bug17754.patch
@@ -0,0 +1,392 @@
+diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
+index b3cfa3d..e6d261f 100644
+--- a/dbus/dbus-connection.c
++++ b/dbus/dbus-connection.c
+@@ -73,6 +73,14 @@
+ _dbus_mutex_unlock ((connection)->mutex); \
+ } while (0)
+
++#define SLOTS_LOCK(connection) do { \
++ _dbus_mutex_lock ((connection)->slot_mutex); \
++ } while (0)
++
++#define SLOTS_UNLOCK(connection) do { \
++ _dbus_mutex_unlock ((connection)->slot_mutex); \
++ } while (0)
++
+ #define DISPATCH_STATUS_NAME(s) \
+ ((s) == DBUS_DISPATCH_COMPLETE ? "complete" : \
+ (s) == DBUS_DISPATCH_DATA_REMAINS ? "data remains" : \
+@@ -257,6 +265,7 @@ struct DBusConnection
+
+ DBusList *filter_list; /**< List of filters. */
+
++ DBusMutex *slot_mutex; /**< Lock on slot_list so overall connection lock need not be taken */
+ DBusDataSlotList slot_list; /**< Data stored by allocated integer ID */
+
+ DBusHashTable *pending_replies; /**< Hash of message serials to #DBusPendingCall. */
+@@ -649,39 +658,42 @@ protected_change_watch (DBusConnection *connection,
+ DBusWatchToggleFunction toggle_function,
+ dbus_bool_t enabled)
+ {
+- DBusWatchList *watches;
+ dbus_bool_t retval;
+-
++
+ HAVE_LOCK_CHECK (connection);
+
+- /* This isn't really safe or reasonable; a better pattern is the "do everything, then
+- * drop lock and call out" one; but it has to be propagated up through all callers
++ /* The original purpose of protected_change_watch() was to hold a
++ * ref on the connection while dropping the connection lock, then
++ * calling out to the app. This was a broken hack that did not
++ * work, since the connection was in a hosed state (no WatchList
++ * field) while calling out.
++ *
++ * So for now we'll just keep the lock while calling out. This means
++ * apps are not allowed to call DBusConnection methods inside a
++ * watch function or they will deadlock.
++ *
++ * The "real fix" is to use the _and_unlock() pattern found
++ * elsewhere in the code, to defer calling out to the app until
++ * we're about to drop locks and return flow of control to the app
++ * anyway.
++ *
++ * See http://lists.freedesktop.org/archives/dbus/2007-July/thread.html#8144
+ */
+-
+- watches = connection->watches;
+- if (watches)
+- {
+- connection->watches = NULL;
+- _dbus_connection_ref_unlocked (connection);
+- CONNECTION_UNLOCK (connection);
+
++ if (connection->watches)
++ {
+ if (add_function)
+- retval = (* add_function) (watches, watch);
++ retval = (* add_function) (connection->watches, watch);
+ else if (remove_function)
+ {
+ retval = TRUE;
+- (* remove_function) (watches, watch);
++ (* remove_function) (connection->watches, watch);
+ }
+ else
+ {
+ retval = TRUE;
+- (* toggle_function) (watches, watch, enabled);
++ (* toggle_function) (connection->watches, watch, enabled);
+ }
+-
+- CONNECTION_LOCK (connection);
+- connection->watches = watches;
+- _dbus_connection_unref_unlocked (connection);
+-
+ return retval;
+ }
+ else
+@@ -770,39 +782,42 @@ protected_change_timeout (DBusConnection *connection,
+ DBusTimeoutToggleFunction toggle_function,
+ dbus_bool_t enabled)
+ {
+- DBusTimeoutList *timeouts;
+ dbus_bool_t retval;
+-
++
+ HAVE_LOCK_CHECK (connection);
+
+- /* This isn't really safe or reasonable; a better pattern is the "do everything, then
+- * drop lock and call out" one; but it has to be propagated up through all callers
++ /* The original purpose of protected_change_timeout() was to hold a
++ * ref on the connection while dropping the connection lock, then
++ * calling out to the app. This was a broken hack that did not
++ * work, since the connection was in a hosed state (no TimeoutList
++ * field) while calling out.
++ *
++ * So for now we'll just keep the lock while calling out. This means
++ * apps are not allowed to call DBusConnection methods inside a
++ * timeout function or they will deadlock.
++ *
++ * The "real fix" is to use the _and_unlock() pattern found
++ * elsewhere in the code, to defer calling out to the app until
++ * we're about to drop locks and return flow of control to the app
++ * anyway.
++ *
++ * See http://lists.freedesktop.org/archives/dbus/2007-July/thread.html#8144
+ */
+-
+- timeouts = connection->timeouts;
+- if (timeouts)
+- {
+- connection->timeouts = NULL;
+- _dbus_connection_ref_unlocked (connection);
+- CONNECTION_UNLOCK (connection);
+
++ if (connection->timeouts)
++ {
+ if (add_function)
+- retval = (* add_function) (timeouts, timeout);
++ retval = (* add_function) (connection->timeouts, timeout);
+ else if (remove_function)
+ {
+ retval = TRUE;
+- (* remove_function) (timeouts, timeout);
++ (* remove_function) (connection->timeouts, timeout);
+ }
+ else
+ {
+ retval = TRUE;
+- (* toggle_function) (timeouts, timeout, enabled);
++ (* toggle_function) (connection->timeouts, timeout, enabled);
+ }
+-
+- CONNECTION_LOCK (connection);
+- connection->timeouts = timeouts;
+- _dbus_connection_unref_unlocked (connection);
+-
+ return retval;
+ }
+ else
+@@ -1263,6 +1278,10 @@ _dbus_connection_new_for_transport (DBusTransport *transport)
+ if (connection->io_path_cond == NULL)
+ goto error;
+
++ _dbus_mutex_new_at_location (&connection->slot_mutex);
++ if (connection->slot_mutex == NULL)
++ goto error;
++
+ disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL,
+ DBUS_INTERFACE_LOCAL,
+ "Disconnected");
+@@ -1339,6 +1358,7 @@ _dbus_connection_new_for_transport (DBusTransport *transport)
+ _dbus_mutex_free_at_location (&connection->mutex);
+ _dbus_mutex_free_at_location (&connection->io_path_mutex);
+ _dbus_mutex_free_at_location (&connection->dispatch_mutex);
++ _dbus_mutex_free_at_location (&connection->slot_mutex);
+ dbus_free (connection);
+ }
+ if (pending_replies)
+@@ -2612,9 +2632,14 @@ dbus_connection_ref (DBusConnection *connection)
+
+ /* The connection lock is better than the global
+ * lock in the atomic increment fallback
++ *
++ * (FIXME but for now we always use the atomic version,
++ * to avoid taking the connection lock, due to
++ * the mess with set_timeout_functions()/set_watch_functions()
++ * calling out to the app without dropping locks)
+ */
+
+-#ifdef DBUS_HAVE_ATOMIC_INT
++#if 1
+ _dbus_atomic_inc (&connection->refcount);
+ #else
+ CONNECTION_LOCK (connection);
+@@ -2726,6 +2751,8 @@ _dbus_connection_last_unref (DBusConnection *connection)
+ _dbus_mutex_free_at_location (&connection->io_path_mutex);
+ _dbus_mutex_free_at_location (&connection->dispatch_mutex);
+
++ _dbus_mutex_free_at_location (&connection->slot_mutex);
++
+ _dbus_mutex_free_at_location (&connection->mutex);
+
+ dbus_free (connection);
+@@ -2760,9 +2787,14 @@ dbus_connection_unref (DBusConnection *connection)
+
+ /* The connection lock is better than the global
+ * lock in the atomic increment fallback
++ *
++ * (FIXME but for now we always use the atomic version,
++ * to avoid taking the connection lock, due to
++ * the mess with set_timeout_functions()/set_watch_functions()
++ * calling out to the app without dropping locks)
+ */
+
+-#ifdef DBUS_HAVE_ATOMIC_INT
++#if 1
+ last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
+ #else
+ CONNECTION_LOCK (connection);
+@@ -4708,9 +4740,11 @@ dbus_connection_dispatch (DBusConnection *connection)
+ * should be that dbus_connection_set_watch_functions() has no effect,
+ * but the add_function and remove_function may have been called.
+ *
+- * @todo We need to drop the lock when we call the
+- * add/remove/toggled functions which can be a side effect
+- * of setting the watch functions.
++ * @note The thread lock on DBusConnection is held while
++ * watch functions are invoked, so inside these functions you
++ * may not invoke any methods on DBusConnection or it will deadlock.
++ * See the comments in the code or http://lists.freedesktop.org/archives/dbus/2007-July/tread.html#8144
++ * if you encounter this issue and want to attempt writing a patch.
+ *
+ * @param connection the connection.
+ * @param add_function function to begin monitoring a new descriptor.
+@@ -4729,43 +4763,18 @@ dbus_connection_set_watch_functions (DBusConnection *connection,
+ DBusFreeFunction free_data_function)
+ {
+ dbus_bool_t retval;
+- DBusWatchList *watches;
+
+ _dbus_return_val_if_fail (connection != NULL, FALSE);
+
+ CONNECTION_LOCK (connection);
+
+-#ifndef DBUS_DISABLE_CHECKS
+- if (connection->watches == NULL)
+- {
+- _dbus_warn_check_failed ("Re-entrant call to %s is not allowed\n",
+- _DBUS_FUNCTION_NAME);
+- return FALSE;
+- }
+-#endif
+-
+- /* ref connection for slightly better reentrancy */
+- _dbus_connection_ref_unlocked (connection);
+-
+- /* This can call back into user code, and we need to drop the
+- * connection lock when it does. This is kind of a lame
+- * way to do it.
+- */
+- watches = connection->watches;
+- connection->watches = NULL;
+- CONNECTION_UNLOCK (connection);
+-
+- retval = _dbus_watch_list_set_functions (watches,
++ retval = _dbus_watch_list_set_functions (connection->watches,
+ add_function, remove_function,
+ toggled_function,
+ data, free_data_function);
+- CONNECTION_LOCK (connection);
+- connection->watches = watches;
+-
++
+ CONNECTION_UNLOCK (connection);
+- /* drop our paranoid refcount */
+- dbus_connection_unref (connection);
+-
++
+ return retval;
+ }
+
+@@ -4794,6 +4803,12 @@ dbus_connection_set_watch_functions (DBusConnection *connection,
+ * given remove_function. The timer interval may change whenever the
+ * timeout is added, removed, or toggled.
+ *
++ * @note The thread lock on DBusConnection is held while
++ * timeout functions are invoked, so inside these functions you
++ * may not invoke any methods on DBusConnection or it will deadlock.
++ * See the comments in the code or http://lists.freedesktop.org/archives/dbus/2007-July/thread.html#8144
++ * if you encounter this issue and want to attempt writing a patch.
++ *
+ * @param connection the connection.
+ * @param add_function function to add a timeout.
+ * @param remove_function function to remove a timeout.
+@@ -4811,38 +4826,17 @@ dbus_connection_set_timeout_functions (DBusConnection *connection,
+ DBusFreeFunction free_data_function)
+ {
+ dbus_bool_t retval;
+- DBusTimeoutList *timeouts;
+
+ _dbus_return_val_if_fail (connection != NULL, FALSE);
+
+ CONNECTION_LOCK (connection);
+
+-#ifndef DBUS_DISABLE_CHECKS
+- if (connection->timeouts == NULL)
+- {
+- _dbus_warn_check_failed ("Re-entrant call to %s is not allowed\n",
+- _DBUS_FUNCTION_NAME);
+- return FALSE;
+- }
+-#endif
+-
+- /* ref connection for slightly better reentrancy */
+- _dbus_connection_ref_unlocked (connection);
+-
+- timeouts = connection->timeouts;
+- connection->timeouts = NULL;
+- CONNECTION_UNLOCK (connection);
+-
+- retval = _dbus_timeout_list_set_functions (timeouts,
++ retval = _dbus_timeout_list_set_functions (connection->timeouts,
+ add_function, remove_function,
+ toggled_function,
+ data, free_data_function);
+- CONNECTION_LOCK (connection);
+- connection->timeouts = timeouts;
+-
++
+ CONNECTION_UNLOCK (connection);
+- /* drop our paranoid refcount */
+- dbus_connection_unref (connection);
+
+ return retval;
+ }
+@@ -5805,6 +5799,15 @@ dbus_connection_free_data_slot (dbus_int32_t *slot_p)
+ * the connection is finalized. The slot number
+ * must have been allocated with dbus_connection_allocate_data_slot().
+ *
++ * @note This function does not take the
++ * main thread lock on DBusConnection, which allows it to be
++ * used from inside watch and timeout functions. (See the
++ * note in docs for dbus_connection_set_watch_functions().)
++ * A side effect of this is that you need to know there's
++ * a reference held on the connection while invoking
++ * dbus_connection_set_data(), or the connection could be
++ * finalized during dbus_connection_set_data().
++ *
+ * @param connection the connection
+ * @param slot the slot number
+ * @param data the data to store
+@@ -5824,14 +5827,14 @@ dbus_connection_set_data (DBusConnection *connection,
+ _dbus_return_val_if_fail (connection != NULL, FALSE);
+ _dbus_return_val_if_fail (slot >= 0, FALSE);
+
+- CONNECTION_LOCK (connection);
++ SLOTS_LOCK (connection);
+
+ retval = _dbus_data_slot_list_set (&slot_allocator,
+ &connection->slot_list,
+ slot, data, free_data_func,
+ &old_free_func, &old_data);
+
+- CONNECTION_UNLOCK (connection);
++ SLOTS_UNLOCK (connection);
+
+ if (retval)
+ {
+@@ -5847,6 +5850,15 @@ dbus_connection_set_data (DBusConnection *connection,
+ * Retrieves data previously set with dbus_connection_set_data().
+ * The slot must still be allocated (must not have been freed).
+ *
++ * @note This function does not take the
++ * main thread lock on DBusConnection, which allows it to be
++ * used from inside watch and timeout functions. (See the
++ * note in docs for dbus_connection_set_watch_functions().)
++ * A side effect of this is that you need to know there's
++ * a reference held on the connection while invoking
++ * dbus_connection_get_data(), or the connection could be
++ * finalized during dbus_connection_get_data().
++ *
+ * @param connection the connection
+ * @param slot the slot to get data from
+ * @returns the data, or #NULL if not found
+@@ -5859,13 +5871,13 @@ dbus_connection_get_data (DBusConnection *connection,
+
+ _dbus_return_val_if_fail (connection != NULL, NULL);
+
+- CONNECTION_LOCK (connection);
++ SLOTS_LOCK (connection);
+
+ res = _dbus_data_slot_list_get (&slot_allocator,
+ &connection->slot_list,
+ slot);
+
+- CONNECTION_UNLOCK (connection);
++ SLOTS_UNLOCK (connection);
+
+ return res;
+ }
diff --git a/abs/core/dbus-core/git-fixes.patch b/abs/core/dbus-core/git-fixes.patch
new file mode 100644
index 0000000..b1b11fa
--- /dev/null
+++ b/abs/core/dbus-core/git-fixes.patch
@@ -0,0 +1,289 @@
+diff --git a/bus/config-parser-trivial.c b/bus/config-parser-trivial.c
+index fd016a8..8a1f504 100644
+--- a/bus/config-parser-trivial.c
++++ b/bus/config-parser-trivial.c
+@@ -131,6 +131,25 @@ bus_config_parser_unref (BusConfigParser *parser)
+ }
+
+ dbus_bool_t
++bus_config_parser_check_doctype (BusConfigParser *parser,
++ const char *doctype,
++ DBusError *error)
++{
++ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
++
++ if (strcmp (doctype, "busconfig") != 0)
++ {
++ dbus_set_error (error,
++ DBUS_ERROR_FAILED,
++ "Configuration file has the wrong document type %s",
++ doctype);
++ return FALSE;
++ }
++ else
++ return TRUE;
++}
++
++dbus_bool_t
+ bus_config_parser_start_element (BusConfigParser *parser,
+ const char *element_name,
+ const char **attribute_names,
+diff --git a/bus/config-parser-trivial.h b/bus/config-parser-trivial.h
+index ce542bf..6733b1f 100644
+--- a/bus/config-parser-trivial.h
++++ b/bus/config-parser-trivial.h
+@@ -41,6 +41,9 @@ BusConfigParser* bus_config_parser_new (const DBusString *basedir,
+
+ BusConfigParser* bus_config_parser_ref (BusConfigParser *parser);
+ void bus_config_parser_unref (BusConfigParser *parser);
++dbus_bool_t bus_config_parser_check_doctype (BusConfigParser *parser,
++ const char *doctype,
++ DBusError *error);
+ dbus_bool_t bus_config_parser_start_element (BusConfigParser *parser,
+ const char *element_name,
+ const char **attribute_names,
+diff --git a/bus/dir-watch-kqueue.c b/bus/dir-watch-kqueue.c
+index 4a01b74..4e436eb 100644
+--- a/bus/dir-watch-kqueue.c
++++ b/bus/dir-watch-kqueue.c
+@@ -169,7 +169,7 @@ bus_set_watched_dirs (BusContext *context, DBusList **directories)
+ */
+ for (i = 0; new_dirs[i]; i++)
+ {
+- for (j = 0; i < num_fds; j++)
++ for (j = 0; j < num_fds; j++)
+ {
+ if (dirs[j] && strcmp (new_dirs[i], dirs[j]) == 0)
+ {
+diff --git a/bus/messagebus.in b/bus/messagebus.in
+index 1f1004b..3e2ee07 100755
+--- a/bus/messagebus.in
++++ b/bus/messagebus.in
+@@ -68,7 +68,7 @@ case "$1" in
+ stop
+ ;;
+ status)
+- status $processname
++ status $servicename
+ RETVAL=$?
+ ;;
+ restart)
+diff --git a/bus/rc.messagebus.in b/bus/rc.messagebus.in
+index b147503..c52ca77 100644
+--- a/bus/rc.messagebus.in
++++ b/bus/rc.messagebus.in
+@@ -61,7 +61,7 @@ case "$1" in
+ stop
+ ;;
+ status)
+- status $processname
++ status $servicename
+ RETVAL=$?
+ ;;
+ restart)
+diff --git a/dbus/dbus-connection-internal.h b/dbus/dbus-connection-internal.h
+index 721b5d7..cdf3f59 100644
+--- a/dbus/dbus-connection-internal.h
++++ b/dbus/dbus-connection-internal.h
+@@ -75,6 +75,7 @@ void _dbus_connection_toggle_timeout_unlocked (DBusConnection
+ dbus_bool_t enabled);
+ DBusConnection* _dbus_connection_new_for_transport (DBusTransport *transport);
+ void _dbus_connection_do_iteration_unlocked (DBusConnection *connection,
++ DBusPendingCall *pending,
+ unsigned int flags,
+ int timeout_milliseconds);
+ void _dbus_connection_close_possibly_shared (DBusConnection *connection);
+diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
+index 9526d3c..b3cfa3d 100644
+--- a/dbus/dbus-connection.c
++++ b/dbus/dbus-connection.c
+@@ -320,6 +320,8 @@ static void _dbus_connection_release_dispatch (DB
+ static DBusDispatchStatus _dbus_connection_flush_unlocked (DBusConnection *connection);
+ static void _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection);
+ static dbus_bool_t _dbus_connection_get_is_connected_unlocked (DBusConnection *connection);
++static dbus_bool_t _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection,
++ dbus_uint32_t client_serial);
+
+ static DBusMessageFilter *
+ _dbus_message_filter_ref (DBusMessageFilter *filter)
+@@ -1137,14 +1139,22 @@ _dbus_connection_release_io_path (DBusConnection *connection)
+ * you specify DBUS_ITERATION_BLOCK; in that case the function
+ * returns immediately.
+ *
++ * If pending is not NULL then a check is made if the pending call
++ * is completed after the io path has been required. If the call
++ * has been completed nothing is done. This must be done since
++ * the _dbus_connection_acquire_io_path releases the connection
++ * lock for a while.
++ *
+ * Called with connection lock held.
+ *
+ * @param connection the connection.
++ * @param pending the pending call that should be checked or NULL
+ * @param flags iteration flags.
+ * @param timeout_milliseconds maximum blocking time, or -1 for no limit.
+ */
+ void
+ _dbus_connection_do_iteration_unlocked (DBusConnection *connection,
++ DBusPendingCall *pending,
+ unsigned int flags,
+ int timeout_milliseconds)
+ {
+@@ -1160,8 +1170,22 @@ _dbus_connection_do_iteration_unlocked (DBusConnection *connection,
+ {
+ HAVE_LOCK_CHECK (connection);
+
+- _dbus_transport_do_iteration (connection->transport,
+- flags, timeout_milliseconds);
++ if ( (pending != NULL) && _dbus_pending_call_get_completed_unlocked(pending))
++ {
++ _dbus_verbose ("pending call completed while acquiring I/O path");
++ }
++ else if ( (pending != NULL) &&
++ _dbus_connection_peek_for_reply_unlocked (connection,
++ _dbus_pending_call_get_reply_serial_unlocked (pending)))
++ {
++ _dbus_verbose ("pending call completed while acquiring I/O path (reply found in queue)");
++ }
++ else
++ {
++ _dbus_transport_do_iteration (connection->transport,
++ flags, timeout_milliseconds);
++ }
++
+ _dbus_connection_release_io_path (connection);
+ }
+
+@@ -1989,6 +2013,7 @@ _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *con
+ * out immediately, and otherwise get them queued up
+ */
+ _dbus_connection_do_iteration_unlocked (connection,
++ NULL,
+ DBUS_ITERATION_DO_WRITING,
+ -1);
+
+@@ -2157,6 +2182,32 @@ generate_local_error_message (dbus_uint32_t serial,
+ return message;
+ }
+
++/*
++ * Peek the incoming queue to see if we got reply for a specific serial
++ */
++static dbus_bool_t
++_dbus_connection_peek_for_reply_unlocked (DBusConnection *connection,
++ dbus_uint32_t client_serial)
++{
++ DBusList *link;
++ HAVE_LOCK_CHECK (connection);
++
++ link = _dbus_list_get_first_link (&connection->incoming_messages);
++
++ while (link != NULL)
++ {
++ DBusMessage *reply = link->data;
++
++ if (dbus_message_get_reply_serial (reply) == client_serial)
++ {
++ _dbus_verbose ("%s reply to %d found in queue\n", _DBUS_FUNCTION_NAME, client_serial);
++ return TRUE;
++ }
++ link = _dbus_list_get_next_link (&connection->incoming_messages, link);
++ }
++
++ return FALSE;
++}
+
+ /* This is slightly strange since we can pop a message here without
+ * the dispatch lock.
+@@ -2333,6 +2384,7 @@ _dbus_connection_block_pending_call (DBusPendingCall *pending)
+ /* Now we wait... */
+ /* always block at least once as we know we don't have the reply yet */
+ _dbus_connection_do_iteration_unlocked (connection,
++ pending,
+ DBUS_ITERATION_DO_READING |
+ DBUS_ITERATION_BLOCK,
+ timeout_milliseconds);
+@@ -2399,6 +2451,7 @@ _dbus_connection_block_pending_call (DBusPendingCall *pending)
+ {
+ /* block again, we don't have the reply buffered yet. */
+ _dbus_connection_do_iteration_unlocked (connection,
++ pending,
+ DBUS_ITERATION_DO_READING |
+ DBUS_ITERATION_BLOCK,
+ timeout_milliseconds - elapsed_milliseconds);
+@@ -2426,6 +2479,7 @@ _dbus_connection_block_pending_call (DBusPendingCall *pending)
+ {
+ /* block again, we don't have the reply buffered yet. */
+ _dbus_connection_do_iteration_unlocked (connection,
++ NULL,
+ DBUS_ITERATION_DO_READING |
+ DBUS_ITERATION_BLOCK,
+ timeout_milliseconds - elapsed_milliseconds);
+@@ -3403,6 +3457,7 @@ _dbus_connection_flush_unlocked (DBusConnection *connection)
+ _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME);
+ HAVE_LOCK_CHECK (connection);
+ _dbus_connection_do_iteration_unlocked (connection,
++ NULL,
+ DBUS_ITERATION_DO_READING |
+ DBUS_ITERATION_DO_WRITING |
+ DBUS_ITERATION_BLOCK,
+@@ -3489,6 +3544,7 @@ _dbus_connection_read_write_dispatch (DBusConnection *connection,
+ {
+ _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME);
+ _dbus_connection_do_iteration_unlocked (connection,
++ NULL,
+ DBUS_ITERATION_DO_READING |
+ DBUS_ITERATION_DO_WRITING |
+ DBUS_ITERATION_BLOCK,
+diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
+index ce3475a..b58d09a 100644
+--- a/dbus/dbus-sysdeps-unix.c
++++ b/dbus/dbus-sysdeps-unix.c
+@@ -623,6 +623,7 @@ _dbus_listen_unix_socket (const char *path,
+ int listen_fd;
+ struct sockaddr_un addr;
+ size_t path_len;
++ unsigned int reuseaddr;
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
+@@ -696,7 +697,15 @@ _dbus_listen_unix_socket (const char *path,
+
+ strncpy (addr.sun_path, path, path_len);
+ }
+-
++
++ reuseaddr = 1;
++ if (setsockopt (listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
++ {
++ dbus_set_error (error, _dbus_error_from_errno (errno),
++ "Failed to set socket option\"%s\": %s",
++ path, _dbus_strerror (errno));
++ }
++
+ if (bind (listen_fd, (struct sockaddr*) &addr, _DBUS_STRUCT_OFFSET (struct sockaddr_un, sun_path) + path_len) < 0)
+ {
+ dbus_set_error (error, _dbus_error_from_errno (errno),
+@@ -870,6 +879,7 @@ _dbus_listen_tcp_socket (const char *host,
+ int nlisten_fd = 0, *listen_fd = NULL, res, i;
+ struct addrinfo hints;
+ struct addrinfo *ai, *tmp;
++ unsigned int reuseaddr;
+
+ *fds_p = NULL;
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+@@ -915,6 +925,14 @@ _dbus_listen_tcp_socket (const char *host,
+ }
+ _DBUS_ASSERT_ERROR_IS_CLEAR(error);
+
++ reuseaddr = 1;
++ if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr))==-1)
++ {
++ dbus_set_error (error, _dbus_error_from_errno (errno),
++ "Failed to set socket option \"%s:%s\": %s",
++ host ? host : "*", port, _dbus_strerror (errno));
++ }
++
+ if (bind (fd, (struct sockaddr*) tmp->ai_addr, tmp->ai_addrlen) < 0)
+ {
+ _dbus_close(fd, NULL);