diff options
author | Michael Hanson <hansonorders@verizon.net> | 2010-11-12 22:48:51 (GMT) |
---|---|---|
committer | Michael Hanson <hansonorders@verizon.net> | 2010-11-12 22:48:51 (GMT) |
commit | 22477e145e888305260a02678be2623bede8ea86 (patch) | |
tree | 98e008bc9285cb2a13930723c0d30a447f582f28 | |
parent | f5afe07e0465d6c5d90bb7adeb1f0e88810eb1d5 (diff) | |
download | linhes_pkgbuild-22477e145e888305260a02678be2623bede8ea86.zip linhes_pkgbuild-22477e145e888305260a02678be2623bede8ea86.tar.gz linhes_pkgbuild-22477e145e888305260a02678be2623bede8ea86.tar.bz2 |
dbus-core: up to latest
-rw-r--r-- | abs/core/dbus-core/PKGBUILD | 33 | ||||
-rw-r--r-- | abs/core/dbus-core/bug17754.patch | 392 | ||||
-rw-r--r-- | abs/core/dbus-core/git-fixes.patch | 289 |
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); |