[arch-commits] Commit in dbus-core/trunk (PKGBUILD bug17754.patch git-fixes.patch)

Jan de Groot jgc at archlinux.org
Wed Sep 1 12:41:16 UTC 2010


    Date: Wednesday, September 1, 2010 @ 08:41:16
  Author: jgc
Revision: 89506

upgpkg: dbus-core 1.2.24-2
add patches from 1.2 branch. Backport patch from 1.3 branch that will fix FS#20604 with hopefully no side-effects

Added:
  dbus-core/trunk/bug17754.patch
  dbus-core/trunk/git-fixes.patch
Modified:
  dbus-core/trunk/PKGBUILD

-----------------+
 PKGBUILD        |   34 ++--
 bug17754.patch  |  392 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 git-fixes.patch |  289 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 701 insertions(+), 14 deletions(-)

Modified: PKGBUILD
===================================================================
--- PKGBUILD	2010-09-01 12:26:16 UTC (rev 89505)
+++ PKGBUILD	2010-09-01 12:41:16 UTC (rev 89506)
@@ -4,7 +4,7 @@
 #
 pkgname=dbus-core
 pkgver=1.2.24
-pkgrel=1
+pkgrel=2
 pkgdesc="Freedesktop.org message bus system"
 url="http://www.freedesktop.org/Software/dbus"
 arch=(i686 x86_64)
@@ -14,40 +14,46 @@
 options=(!libtool)
 install=dbus.install
 source=(http://dbus.freedesktop.org/releases/dbus/dbus-${pkgver}.tar.gz
+        bug17754.patch
+        git-fixes.patch
         dbus)
 md5sums=('565346cecd9cfecf1463540c6086cc2c'
+         'c74a42681e2726b42486dec82993c009'
+         'c4bd7c5e60b1b5df5adbe80da5839c9e'
          '08f93dd19cffd1b45ab05c1fd4efb560')
 
 build() {
   cd "${srcdir}/dbus-${pkgver}"
+  patch -Np1 -i "${srcdir}/git-fixes.patch"
+  patch -Np1 -i "${srcdir}/bug17754.patch"
   ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var \
       --libexecdir=/usr/lib/dbus-1.0 --with-dbus-user=81 \
       --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
-  make || return 1
-  make DESTDIR="${pkgdir}" install || return 1
+      --disable-tests --disable-asserts --without-x
+  make
+  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/"
 }

Added: bug17754.patch
===================================================================
--- bug17754.patch	                        (rev 0)
+++ bug17754.patch	2010-09-01 12:41:16 UTC (rev 89506)
@@ -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;
+ }

Added: git-fixes.patch
===================================================================
--- git-fixes.patch	                        (rev 0)
+++ git-fixes.patch	2010-09-01 12:41:16 UTC (rev 89506)
@@ -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);




More information about the arch-commits mailing list