/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
/* dbus-connection.c DBusConnection object
 *
 * Copyright (C) 2002-2006  Red Hat Inc.
 *
 * Licensed under the Academic Free License version 2.1
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include <config.h>
#include "dbus-shared.h"
#include "dbus-connection.h"
#include "dbus-list.h"
#include "dbus-timeout.h"
#include "dbus-transport.h"
#include "dbus-watch.h"
#include "dbus-connection-internal.h"
#include "dbus-pending-call-internal.h"
#include "dbus-list.h"
#include "dbus-hash.h"
#include "dbus-message-internal.h"
#include "dbus-message-private.h"
#include "dbus-threads.h"
#include "dbus-protocol.h"
#include "dbus-dataslot.h"
#include "dbus-string.h"
#include "dbus-pending-call.h"
#include "dbus-object-tree.h"
#include "dbus-threads-internal.h"
#include "dbus-bus.h"
#include "dbus-marshal-basic.h"

#ifdef DBUS_DISABLE_CHECKS
#define TOOK_LOCK_CHECK(connection)
#define RELEASING_LOCK_CHECK(connection)
#define HAVE_LOCK_CHECK(connection)
#else
#define TOOK_LOCK_CHECK(connection) do {                \
    _dbus_assert (!(connection)->have_connection_lock); \
    (connection)->have_connection_lock = TRUE;          \
  } while (0)
#define RELEASING_LOCK_CHECK(connection) do {            \
    _dbus_assert ((connection)->have_connection_lock);   \
    (connection)->have_connection_lock = FALSE;          \
  } while (0)
#define HAVE_LOCK_CHECK(connection)        _dbus_assert ((connection)->have_connection_lock)
/* A "DO_NOT_HAVE_LOCK_CHECK" is impossible since we need the lock to check the flag */
#endif

#define TRACE_LOCKS 1

#define CONNECTION_LOCK(connection)   do {                                      \
    if (TRACE_LOCKS) { _dbus_verbose ("LOCK\n"); }   \
    _dbus_mutex_lock ((connection)->mutex);                                      \
    TOOK_LOCK_CHECK (connection);                                               \
  } while (0)

#define CONNECTION_UNLOCK(connection) do {                                              \
    if (TRACE_LOCKS) { _dbus_verbose ("UNLOCK\n");  }        \
    RELEASING_LOCK_CHECK (connection);                                                  \
    _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" : \
                      (s) == DBUS_DISPATCH_NEED_MEMORY ? "need memory" :   \
                      "???")

/**
 * @defgroup DBusConnection DBusConnection
 * @ingroup  DBus
 * @brief Connection to another application
 *
 * A DBusConnection represents a connection to another
 * application. Messages can be sent and received via this connection.
 * The other application may be a message bus; for convenience, the
 * function dbus_bus_get() is provided to automatically open a
 * connection to the well-known message buses.
 * 
 * In brief a DBusConnection is a message queue associated with some
 * message transport mechanism such as a socket.  The connection
 * maintains a queue of incoming messages and a queue of outgoing
 * messages.
 *
 * Several functions use the following terms:
 * <ul>
 * <li><b>read</b> means to fill the incoming message queue by reading from the socket</li>
 * <li><b>write</b> means to drain the outgoing queue by writing to the socket</li>
 * <li><b>dispatch</b> means to drain the incoming queue by invoking application-provided message handlers</li>
 * </ul>
 *
 * The function dbus_connection_read_write_dispatch() for example does all
 * three of these things, offering a simple alternative to a main loop.
 *
 * In an application with a main loop, the read/write/dispatch
 * operations are usually separate.
 *
 * The connection provides #DBusWatch and #DBusTimeout objects to
 * the main loop. These are used to know when reading, writing, or
 * dispatching should be performed.
 * 
 * Incoming messages are processed
 * by calling dbus_connection_dispatch(). dbus_connection_dispatch()
 * runs any handlers registered for the topmost message in the message
 * queue, then discards the message, then returns.
 * 
 * dbus_connection_get_dispatch_status() indicates whether
 * messages are currently in the queue that need dispatching.
 * dbus_connection_set_dispatch_status_function() allows
 * you to set a function to be used to monitor the dispatch status.
 * 
 * If you're using GLib or Qt add-on libraries for D-Bus, there are
 * special convenience APIs in those libraries that hide
 * all the details of dispatch and watch/timeout monitoring.
 * For example, dbus_connection_setup_with_g_main().
 *
 * If you aren't using these add-on libraries, but want to process
 * messages asynchronously, you must manually call
 * dbus_connection_set_dispatch_status_function(),
 * dbus_connection_set_watch_functions(),
 * dbus_connection_set_timeout_functions() providing appropriate
 * functions to integrate the connection with your application's main
 * loop. This can be tricky to get right; main loops are not simple.
 *
 * If you don't need to be asynchronous, you can ignore #DBusWatch,
 * #DBusTimeout, and dbus_connection_dispatch().  Instead,
 * dbus_connection_read_write_dispatch() can be used.
 *
 * Or, in <em>very</em> simple applications,
 * dbus_connection_pop_message() may be all you need, allowing you to
 * avoid setting up any handler functions (see
 * dbus_connection_add_filter(),
 * dbus_connection_register_object_path() for more on handlers).
 * 
 * When you use dbus_connection_send() or one of its variants to send
 * a message, the message is added to the outgoing queue.  It's
 * actually written to the network later; either in
 * dbus_watch_handle() invoked by your main loop, or in
 * dbus_connection_flush() which blocks until it can write out the
 * entire outgoing queue. The GLib/Qt add-on libraries again
 * handle the details here for you by setting up watch functions.
 *
 * When a connection is disconnected, you are guaranteed to get a
 * signal "Disconnected" from the interface
 * #DBUS_INTERFACE_LOCAL, path
 * #DBUS_PATH_LOCAL.
 *
 * You may not drop the last reference to a #DBusConnection
 * until that connection has been disconnected.
 *
 * You may dispatch the unprocessed incoming message queue even if the
 * connection is disconnected. However, "Disconnected" will always be
 * the last message in the queue (obviously no messages are received
 * after disconnection).
 *
 * After calling dbus_threads_init(), #DBusConnection has thread
 * locks and drops them when invoking user callbacks, so in general is
 * transparently threadsafe. However, #DBusMessage does NOT have
 * thread locks; you must not send the same message to multiple
 * #DBusConnection if those connections will be used from different threads,
 * for example.
 *
 * Also, if you dispatch or pop messages from multiple threads, it
 * may work in the sense that it won't crash, but it's tough to imagine
 * sane results; it will be completely unpredictable which messages
 * go to which threads.
 *
 * It's recommended to dispatch from a single thread.
 *
 * The most useful function to call from multiple threads at once
 * is dbus_connection_send_with_reply_and_block(). That is,
 * multiple threads can make method calls at the same time.
 *
 * If you aren't using threads, you can use a main loop and
 * dbus_pending_call_set_notify() to achieve a similar result.
 */

/**
 * @defgroup DBusConnectionInternals DBusConnection implementation details
 * @ingroup  DBusInternals
 * @brief Implementation details of DBusConnection
 *
 * @{
 */

/**
 * Internal struct representing a message filter function 
 */
typedef struct DBusMessageFilter DBusMessageFilter;

/**
 * Internal struct representing a message filter function 
 */
struct DBusMessageFilter
{
  DBusAtomic refcount; /**< Reference count */
  DBusHandleMessageFunction function; /**< Function to call to filter */
  void *user_data; /**< User data for the function */
  DBusFreeFunction free_user_data_function; /**< Function to free the user data */
};


/**
 * Internals of DBusPreallocatedSend
 */
struct DBusPreallocatedSend
{
  DBusConnection *connection; /**< Connection we'd send the message to */
  DBusList *queue_link;       /**< Preallocated link in the queue */
  DBusList *counter_link;     /**< Preallocated link in the resource counter */
};

#if HAVE_DECL_MSG_NOSIGNAL
static dbus_bool_t _dbus_modify_sigpipe = FALSE;
#else
static dbus_bool_t _dbus_modify_sigpipe = TRUE;
#endif

/**
 * Implementation details of DBusConnection. All fields are private.
 */
struct DBusConnection
{
  DBusAtomic refcount; /**< Reference count. */

  DBusMutex *mutex; /**< Lock on the entire DBusConnection */

  DBusMutex *dispatch_mutex;     /**< Protects dispatch_acquired */
  DBusCondVar *dispatch_cond;    /**< Notify when dispatch_acquired is available */
  DBusMutex *io_path_mutex;      /**< Protects io_path_acquired */
  DBusCondVar *io_path_cond;     /**< Notify when io_path_acquired is available */
  
  DBusList *outgoing_messages; /**< Queue of messages we need to send, send the end of the list first. */
  DBusList *incoming_messages; /**< Queue of messages we have received, end of the list received most recently. */

  DBusMessage *message_borrowed; /**< Filled in if the first incoming message has been borrowed;
                                  *   dispatch_acquired will be set by the borrower
                                  */
  
  int n_outgoing;              /**< Length of outgoing queue. */
  int n_incoming;              /**< Length of incoming queue. */

  DBusCounter *outgoing_counter; /**< Counts size of outgoing messages. */
  
  DBusTransport *transport;    /**< Object that sends/receives messages over network. */
  DBusWatchList *watches;      /**< Stores active watches. */
  DBusTimeoutList *timeouts;   /**< Stores active timeouts. */
  
  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. */  
  
  dbus_uint32_t client_serial;       /**< Client serial. Increments each time a message is sent  */
  DBusList *disconnect_message_link; /**< Preallocated list node for queueing the disconnection message */

  DBusWakeupMainFunction wakeup_main_function; /**< Function to wake up the mainloop  */
  void *wakeup_main_data; /**< Application data for wakeup_main_function */
  DBusFreeFunction free_wakeup_main_data; /**< free wakeup_main_data */

  DBusDispatchStatusFunction dispatch_status_function; /**< Function on dispatch status changes  */
  void *dispatch_status_data; /**< Application data for dispatch_status_function */
  DBusFreeFunction free_dispatch_status_data; /**< free dispatch_status_data */

  DBusDispatchStatus last_dispatch_status; /**< The last dispatch status we reported to the application. */

  DBusList *link_cache; /**< A cache of linked list links to prevent contention
                         *   for the global linked list mempool lock
                         */
  DBusObjectTree *objects; /**< Object path handlers registered with this connection */

  char *server_guid; /**< GUID of server if we are in shared_connections, #NULL if server GUID is unknown or connection is private */

  /* These two MUST be bools and not bitfields, because they are protected by a separate lock
   * from connection->mutex and all bitfields in a word have to be read/written together.
   * So you can't have a different lock for different bitfields in the same word.
   */
  dbus_bool_t dispatch_acquired; /**< Someone has dispatch path (can drain incoming queue) */
  dbus_bool_t io_path_acquired;  /**< Someone has transport io path (can use the transport to read/write messages) */
  
  unsigned int shareable : 1; /**< #TRUE if libdbus owns a reference to the connection and can return it from dbus_connection_open() more than once */
  
  unsigned int exit_on_disconnect : 1; /**< If #TRUE, exit after handling disconnect signal */

  unsigned int route_peer_messages : 1; /**< If #TRUE, if org.freedesktop.DBus.Peer messages have a bus name, don't handle them automatically */

  unsigned int disconnected_message_arrived : 1;   /**< We popped or are dispatching the disconnected message.
                                                    * if the disconnect_message_link is NULL then we queued it, but
                                                    * this flag is whether it got to the head of the queue.
                                                    */
  unsigned int disconnected_message_processed : 1; /**< We did our default handling of the disconnected message,
                                                    * such as closing the connection.
                                                    */
  
#ifndef DBUS_DISABLE_CHECKS
  unsigned int have_connection_lock : 1; /**< Used to check locking */
#endif
  
#ifndef DBUS_DISABLE_CHECKS
  int generation; /**< _dbus_current_generation that should correspond to this connection */
#endif 
};

static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked      (DBusConnection     *connection);
static void               _dbus_connection_update_dispatch_status_and_unlock (DBusConnection     *connection,
                                                                              DBusDispatchStatus  new_status);
static void               _dbus_connection_last_unref                        (DBusConnection     *connection);
static void               _dbus_connection_acquire_dispatch                  (DBusConnection     *connection);
static void               _dbus_connection_release_dispatch                  (DBusConnection     *connection);
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)
{
  _dbus_assert (filter->refcount.value > 0);
  _dbus_atomic_inc (&filter->refcount);

  return filter;
}

static void
_dbus_message_filter_unref (DBusMessageFilter *filter)
{
  _dbus_assert (filter->refcount.value > 0);

  if (_dbus_atomic_dec (&filter->refcount) == 1)
    {
      if (filter->free_user_data_function)
        (* filter->free_user_data_function) (filter->user_data);
      
      dbus_free (filter);
    }
}

/**
 * Acquires the connection lock.
 *
 * @param connection the connection.
 */
void
_dbus_connection_lock (DBusConnection *connection)
{
  CONNECTION_LOCK (connection);
}

/**
 * Releases the connection lock.
 *
 * @param connection the connection.
 */
void
_dbus_connection_unlock (DBusConnection *connection)
{
  CONNECTION_UNLOCK (connection);
}

/**
 * Wakes up the main loop if it is sleeping
 * Needed if we're e.g. queueing outgoing messages
 * on a thread while the mainloop sleeps.
 *
 * @param connection the connection.
 */
static void
_dbus_connection_wakeup_mainloop (DBusConnection *connection)
{
  if (connection->wakeup_main_function)
    (*connection->wakeup_main_function) (connection->wakeup_main_data);
}

#ifdef DBUS_BUILD_TESTS
/* For now this function isn't used */
/**
 * Adds a message to the incoming message queue, returning #FALSE
 * if there's insufficient memory to queue the message.
 * Does not take over refcount of the message.
 *
 * @param connection the connection.
 * @param message the message to queue.
 * @returns #TRUE on success.
 */
dbus_bool_t
_dbus_connection_queue_received_message (DBusConnection *connection,
                                         DBusMessage    *message)
{
  DBusList *link;

  link = _dbus_list_alloc_link (message);
  if (link == NULL)
    return FALSE;

  dbus_message_ref (message);
  _dbus_connection_queue_received_message_link (connection, link);

  return TRUE;
}

/**
 * Gets the locks so we can examine them
 *
 * @param connection the connection.
 * @param mutex_loc return for the location of the main mutex pointer
 * @param dispatch_mutex_loc return location of the dispatch mutex pointer
 * @param io_path_mutex_loc return location of the io_path mutex pointer
 * @param dispatch_cond_loc return location of the dispatch conditional 
 *        variable pointer
 * @param io_path_cond_loc return location of the io_path conditional 
 *        variable pointer
 */ 
void 
_dbus_connection_test_get_locks (DBusConnection *connection,
                                 DBusMutex     **mutex_loc,
                                 DBusMutex     **dispatch_mutex_loc,
                                 DBusMutex     **io_path_mutex_loc,
                                 DBusCondVar   **dispatch_cond_loc,
                                 DBusCondVar   **io_path_cond_loc)
{
  *mutex_loc = connection->mutex;
  *dispatch_mutex_loc = connection->dispatch_mutex;
  *io_path_mutex_loc = connection->io_path_mutex; 
  *dispatch_cond_loc = connection->dispatch_cond;
  *io_path_cond_loc = connection->io_path_cond;
}
#endif

/**
 * Adds a message-containing list link to the incoming message queue,
 * taking ownership of the link and the message's current refcount.
 * Cannot fail due to lack of memory.
 *
 * @param connection the connection.
 * @param link the message link to queue.
 */
void
_dbus_connection_queue_received_message_link (DBusConnection  *connection,
                                              DBusList        *link)
{
  DBusPendingCall *pending;
  dbus_uint32_t reply_serial;
  DBusMessage *message;
  
  _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport));
  
  _dbus_list_append_link (&connection->incoming_messages,
                          link);
  message = link->data;

  /* If this is a reply we're waiting on, remove timeout for it */
  reply_serial = dbus_message_get_reply_serial (message);
  if (reply_serial != 0)
    {
      pending = _dbus_hash_table_lookup_int (connection->pending_replies,
                                             reply_serial);
      if (pending != NULL)
	{
	  if (_dbus_pending_call_is_timeout_added_unlocked (pending))
            _dbus_connection_remove_timeout_unlocked (connection,
                                                      _dbus_pending_call_get_timeout_unlocked (pending));

	  _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
	}
    }
  
  

  connection->n_incoming += 1;

  _dbus_connection_wakeup_mainloop (connection);
  
  _dbus_verbose ("Message %p (%s %s %s %s '%s' reply to %u) added to incoming queue %p, %d incoming\n",
                 message,
                 dbus_message_type_to_string (dbus_message_get_type (message)),
                 dbus_message_get_path (message) ?
                 dbus_message_get_path (message) :
                 "no path",
                 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),
                 dbus_message_get_reply_serial (message),
                 connection,
                 connection->n_incoming);}

/**
 * Adds a link + message to the incoming message queue.
 * Can't fail. Takes ownership of both link and message.
 *
 * @param connection the connection.
 * @param link the list node and message to queue.
 *
 */
void
_dbus_connection_queue_synthesized_message_link (DBusConnection *connection,
						 DBusList *link)
{
  HAVE_LOCK_CHECK (connection);
  
  _dbus_list_append_link (&connection->incoming_messages, link);

  connection->n_incoming += 1;

  _dbus_connection_wakeup_mainloop (connection);
  
  _dbus_verbose ("Synthesized message %p added to incoming queue %p, %d incoming\n",
                 link->data, connection, connection->n_incoming);
}


/**
 * 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_has_messages_to_send_unlocked (DBusConnection *connection)
{
  HAVE_LOCK_CHECK (connection);
  return connection->outgoing_messages != NULL;
}

/**
 * Checks whether there are messages in the outgoing message queue.
 * Use dbus_connection_flush() to block until all outgoing
 * messages have been written to the underlying transport
 * (such as a socket).
 * 
 * @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.
 *
 * @param connection the connection.
 * @returns the message to be sent.
 */ 
DBusMessage*
_dbus_connection_get_message_to_send (DBusConnection *connection)
{
  HAVE_LOCK_CHECK (connection);
  
  return _dbus_list_get_last (&connection->outgoing_messages);
}

/**
 * Notifies the connection that a message has been sent, so the
 * message can be removed from the outgoing queue.
 * Called with the connection lock held.
 *
 * @param connection the connection.
 * @param message the message that was sent.
 */
void
_dbus_connection_message_sent (DBusConnection *connection,
                               DBusMessage    *message)
{
  DBusList *link;

  HAVE_LOCK_CHECK (connection);
  
  /* 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);
  _dbus_assert (link->data == message);

  /* Save this link in the link cache */
  _dbus_list_unlink (&connection->outgoing_messages,
                     link);
  _dbus_list_prepend_link (&connection->link_cache, link);
  
  connection->n_outgoing -= 1;

  _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from outgoing queue %p, %d left to send\n",
                 message,
                 dbus_message_type_to_string (dbus_message_get_type (message)),
                 dbus_message_get_path (message) ?
                 dbus_message_get_path (message) :
                 "no path",
                 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);

  /* Save this link in the link cache also */
  _dbus_message_remove_counter (message, connection->outgoing_counter,
                                &link);
  _dbus_list_prepend_link (&connection->link_cache, link);
  
  dbus_message_unref (message);
}

/** Function to be called in protected_change_watch() with refcount held */
typedef dbus_bool_t (* DBusWatchAddFunction)     (DBusWatchList *list,
                                                  DBusWatch     *watch);
/** Function to be called in protected_change_watch() with refcount held */
typedef void        (* DBusWatchRemoveFunction)  (DBusWatchList *list,
                                                  DBusWatch     *watch);
/** Function to be called in protected_change_watch() with refcount held */
typedef void        (* DBusWatchToggleFunction)  (DBusWatchList *list,
                                                  DBusWatch     *watch,
                                                  dbus_bool_t    enabled);

static dbus_bool_t
protected_change_watch (DBusConnection         *connection,
                        DBusWatch              *watch,
                        DBusWatchAddFunction    add_function,
                        DBusWatchRemoveFunction remove_function,
                        DBusWatchToggleFunction toggle_function,
                        dbus_bool_t             enabled)
{
  dbus_bool_t retval;

  HAVE_LOCK_CHECK (connection);

  /* 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
   */

  if (connection->watches)
    {
      if (add_function)
        retval = (* add_function) (connection->watches, watch);
      else if (remove_function)
        {
          retval = TRUE;
          (* remove_function) (connection->watches, watch);
        }
      else
        {
          retval = TRUE;
          (* toggle_function) (connection->watches, watch, enabled);
        }
      return retval;
    }
  else
    return FALSE;
}
     

/**
 * Adds a watch using the connection's DBusAddWatchFunction if
 * available. Otherwise records the watch to be added when said
 * function is available. Also re-adds the watch if the
 * DBusAddWatchFunction changes. May fail due to lack of memory.
 * Connection lock should be held when calling this.
 *
 * @param connection the connection.
 * @param watch the watch to add.
 * @returns #TRUE on success.
 */
dbus_bool_t
_dbus_connection_add_watch_unlocked (DBusConnection *connection,
                                     DBusWatch      *watch)
{
  return protected_change_watch (connection, watch,
                                 _dbus_watch_list_add_watch,
                                 NULL, NULL, FALSE);
}

/**
 * Removes a watch using the connection's DBusRemoveWatchFunction
 * 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 remove.
 */
void
_dbus_connection_remove_watch_unlocked (DBusConnection *connection,
                                        DBusWatch      *watch)
{
  protected_change_watch (connection, watch,
                          NULL,
                          _dbus_watch_list_remove_watch,
                          NULL, FALSE);
}

/**
 * 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.
 * @param enabled whether to enable or disable
 */
void
_dbus_connection_toggle_watch_unlocked (DBusConnection *connection,
                                        DBusWatch      *watch,
                                        dbus_bool_t     enabled)
{
  _dbus_assert (watch != NULL);

  protected_change_watch (connection, watch,
                          NULL, NULL,
                          _dbus_watch_list_toggle_watch,
                          enabled);
}

/** Function to be called in protected_change_timeout() with refcount held */
typedef dbus_bool_t (* DBusTimeoutAddFunction)    (DBusTimeoutList *list,
                                                   DBusTimeout     *timeout);
/** Function to be called in protected_change_timeout() with refcount held */
typedef void        (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list,
                                                   DBusTimeout     *timeout);
/** Function to be called in protected_change_timeout() with refcount held */
typedef void        (* DBusTimeoutToggleFunction) (DBusTimeoutList *list,
                                                   DBusTimeout     *timeout,
                                                   dbus_bool_t      enabled);

static dbus_bool_t
protected_change_timeout (DBusConnection           *connection,
                          DBusTimeout              *timeout,
                          DBusTimeoutAddFunction    add_function,
                          DBusTimeoutRemoveFunction remove_function,
                          DBusTimeoutToggleFunction toggle_function,
                          dbus_bool_t               enabled)
{
  dbus_bool_t retval;

  HAVE_LOCK_CHECK (connection);

  /* 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
   */

  if (connection->timeouts)
    {
      if (add_function)
        retval = (* add_function) (connection->timeouts, timeout);
      else if (remove_function)
        {
          retval = TRUE;
          (* remove_function) (connection->timeouts, timeout);
        }
      else
        {
          retval = TRUE;
          (* toggle_function) (connection->timeouts, timeout, enabled);
        }
      return retval;
    }
  else
    return FALSE;
}

/**
 * Adds a timeout using the connection's DBusAddTimeoutFunction if
 * available. Otherwise records the timeout to be added when said
 * function is available. Also re-adds the timeout if the
 * DBusAddTimeoutFunction changes. May fail due to lack of memory.
 * The timeout will fire repeatedly until removed.
 * Connection lock should be held when calling this.
 *
 * @param connection the connection.
 * @param timeout the timeout to add.
 * @returns #TRUE on success.
 */
dbus_bool_t
_dbus_connection_add_timeout_unlocked (DBusConnection *connection,
                                       DBusTimeout    *timeout)
{
  return protected_change_timeout (connection, timeout,
                                   _dbus_timeout_list_add_timeout,
                                   NULL, NULL, FALSE);
}

/**
 * Removes a timeout using the connection's DBusRemoveTimeoutFunction
 * if available. It's an error to call this function on a timeout
 * that was not previously added.
 * Connection lock should be held when calling this.
 *
 * @param connection the connection.
 * @param timeout the timeout to remove.
 */
void
_dbus_connection_remove_timeout_unlocked (DBusConnection *connection,
                                          DBusTimeout    *timeout)
{
  protected_change_timeout (connection, timeout,
                            NULL,
                            _dbus_timeout_list_remove_timeout,
                            NULL, FALSE);
}

/**
 * Toggles a timeout and notifies app via connection's
 * DBusTimeoutToggledFunction if available. It's an error to call this
 * function on a timeout that was not previously added.
 * Connection lock should be held when calling this.
 *
 * @param connection the connection.
 * @param timeout the timeout to toggle.
 * @param enabled whether to enable or disable
 */
void
_dbus_connection_toggle_timeout_unlocked (DBusConnection   *connection,
                                          DBusTimeout      *timeout,
                                          dbus_bool_t       enabled)
{
  protected_change_timeout (connection, timeout,
                            NULL, NULL,
                            _dbus_timeout_list_toggle_timeout,
                            enabled);
}

static dbus_bool_t
_dbus_connection_attach_pending_call_unlocked (DBusConnection  *connection,
                                               DBusPendingCall *pending)
{
  dbus_uint32_t reply_serial;
  DBusTimeout *timeout;

  HAVE_LOCK_CHECK (connection);

  reply_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);

  _dbus_assert (reply_serial != 0);

  timeout = _dbus_pending_call_get_timeout_unlocked (pending);

  if (timeout)
    {
      if (!_dbus_connection_add_timeout_unlocked (connection, timeout))
        return FALSE;
      
      if (!_dbus_hash_table_insert_int (connection->pending_replies,
                                        reply_serial,
                                        pending))
        {
          _dbus_connection_remove_timeout_unlocked (connection, timeout);

          _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
          HAVE_LOCK_CHECK (connection);
          return FALSE;
        }
      
      _dbus_pending_call_set_timeout_added_unlocked (pending, TRUE);
    }
  else
    {
      if (!_dbus_hash_table_insert_int (connection->pending_replies,
                                        reply_serial,
                                        pending))
        {
          HAVE_LOCK_CHECK (connection);
          return FALSE;
        }
    }

  _dbus_pending_call_ref_unlocked (pending);

  HAVE_LOCK_CHECK (connection);
  
  return TRUE;
}

static void
free_pending_call_on_hash_removal (void *data)
{
  DBusPendingCall *pending;
  DBusConnection  *connection;
  
  if (data == NULL)
    return;

  pending = data;

  connection = _dbus_pending_call_get_connection_unlocked (pending);

  HAVE_LOCK_CHECK (connection);
  
  if (_dbus_pending_call_is_timeout_added_unlocked (pending))
    {
      _dbus_connection_remove_timeout_unlocked (connection,
                                                _dbus_pending_call_get_timeout_unlocked (pending));
      
      _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
    }

  /* FIXME 1.0? this is sort of dangerous and undesirable to drop the lock 
   * here, but the pending call finalizer could in principle call out to 
   * application code so we pretty much have to... some larger code reorg 
   * might be needed.
   */
  _dbus_connection_ref_unlocked (connection);
  _dbus_pending_call_unref_and_unlock (pending);
  CONNECTION_LOCK (connection);
  _dbus_connection_unref_unlocked (connection);
}

static void
_dbus_connection_detach_pending_call_unlocked (DBusConnection  *connection,
                                               DBusPendingCall *pending)
{
  /* This ends up unlocking to call the pending call finalizer, which is unexpected to
   * say the least.
   */
  _dbus_hash_table_remove_int (connection->pending_replies,
                               _dbus_pending_call_get_reply_serial_unlocked (pending));
}

static void
_dbus_connection_detach_pending_call_and_unlock (DBusConnection  *connection,
                                                 DBusPendingCall *pending)
{
  /* The idea here is to avoid finalizing the pending call
   * with the lock held, since there's a destroy notifier
   * in pending call that goes out to application code.
   *
   * There's an extra unlock inside the hash table
   * "free pending call" function FIXME...
   */
  _dbus_pending_call_ref_unlocked (pending);
  _dbus_hash_table_remove_int (connection->pending_replies,
                               _dbus_pending_call_get_reply_serial_unlocked (pending));

  if (_dbus_pending_call_is_timeout_added_unlocked (pending))
      _dbus_connection_remove_timeout_unlocked (connection,
              _dbus_pending_call_get_timeout_unlocked (pending));

  _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);

  _dbus_pending_call_unref_and_unlock (pending);
}

/**
 * Removes a pending call from the connection, such that
 * the pending reply will be ignored. May drop the last
 * reference to the pending call.
 *
 * @param connection the connection
 * @param pending the pending call
 */
void
_dbus_connection_remove_pending_call (DBusConnection  *connection,
                                      DBusPendingCall *pending)
{
  CONNECTION_LOCK (connection);
  _dbus_connection_detach_pending_call_and_unlock (connection, pending);
}

/**
 * Acquire the transporter I/O path. This must be done before
 * doing any I/O in the transporter. May sleep and drop the
 * IO path mutex while waiting for the I/O path.
 *
 * @param connection the connection.
 * @param timeout_milliseconds maximum blocking time, or -1 for no limit.
 * @returns TRUE if the I/O path was acquired.
 */
static dbus_bool_t
_dbus_connection_acquire_io_path (DBusConnection *connection,
				  int             timeout_milliseconds)
{
  dbus_bool_t we_acquired;
  
  HAVE_LOCK_CHECK (connection);

  /* We don't want the connection to vanish */
  _dbus_connection_ref_unlocked (connection);

  /* We will only touch io_path_acquired which is protected by our mutex */
  CONNECTION_UNLOCK (connection);
  
  _dbus_verbose ("locking io_path_mutex\n");
  _dbus_mutex_lock (connection->io_path_mutex);

  _dbus_verbose ("start connection->io_path_acquired = %d timeout = %d\n",
                 connection->io_path_acquired, timeout_milliseconds);

  we_acquired = FALSE;
  
  if (connection->io_path_acquired)
    {
      if (timeout_milliseconds != -1)
        {
          _dbus_verbose ("waiting %d for IO path to be acquirable\n",
                         timeout_milliseconds);

          if (!_dbus_condvar_wait_timeout (connection->io_path_cond,
                                           connection->io_path_mutex,
                                           timeout_milliseconds))
            {
              /* We timed out before anyone signaled. */
              /* (writing the loop to handle the !timedout case by
               * waiting longer if needed is a pain since dbus
               * wraps pthread_cond_timedwait to take a relative
               * time instead of absolute, something kind of stupid
               * on our part. for now it doesn't matter, we will just
               * end up back here eventually.)
               */
            }
        }
      else
        {
          while (connection->io_path_acquired)
            {
              _dbus_verbose ("waiting for IO path to be acquirable\n");
              _dbus_condvar_wait (connection->io_path_cond, 
                                  connection->io_path_mutex);
            }
        }
    }
  
  if (!connection->io_path_acquired)
    {
      we_acquired = TRUE;
      connection->io_path_acquired = TRUE;
    }
  
  _dbus_verbose ("end connection->io_path_acquired = %d we_acquired = %d\n",
                 connection->io_path_acquired, we_acquired);

  _dbus_verbose ("unlocking io_path_mutex\n");
  _dbus_mutex_unlock (connection->io_path_mutex);

  CONNECTION_LOCK (connection);
  
  HAVE_LOCK_CHECK (connection);

  _dbus_connection_unref_unlocked (connection);
  
  return we_acquired;
}

/**
 * Release the I/O path when you're done with it. Only call
 * after you've acquired the I/O. Wakes up at most one thread
 * currently waiting to acquire the I/O path.
 *
 * @param connection the connection.
 */
static void
_dbus_connection_release_io_path (DBusConnection *connection)
{
  HAVE_LOCK_CHECK (connection);
  
  _dbus_verbose ("locking io_path_mutex\n");
  _dbus_mutex_lock (connection->io_path_mutex);
  
  _dbus_assert (connection->io_path_acquired);

  _dbus_verbose ("start connection->io_path_acquired = %d\n",
                 connection->io_path_acquired);
  
  connection->io_path_acquired = FALSE;
  _dbus_condvar_wake_one (connection->io_path_cond);

  _dbus_verbose ("unlocking io_path_mutex\n");
  _dbus_mutex_unlock (connection->io_path_mutex);
}

/**
 * Queues incoming messages and sends outgoing messages for this
 * connection, optionally blocking in the process. Each call to
 * _dbus_connection_do_iteration_unlocked() will call select() or poll() one
 * time and then read or write data if possible.
 *
 * The purpose of this function is to be able to flush outgoing
 * messages or queue up incoming messages without returning
 * control to the application and causing reentrancy weirdness.
 *
 * The flags parameter allows you to specify whether to
 * read incoming messages, write outgoing messages, or both,
 * and whether to block if no immediate action is possible.
 *
 * The timeout_milliseconds parameter does nothing unless the
 * iteration is blocking.
 *
 * If there are no outgoing messages and DBUS_ITERATION_DO_READING
 * wasn't specified, then it's impossible to block, even if
 * 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)
{
  _dbus_verbose ("start\n");
  
  HAVE_LOCK_CHECK (connection);
  
  if (connection->n_outgoing == 0)
    flags &= ~DBUS_ITERATION_DO_WRITING;

  if (_dbus_connection_acquire_io_path (connection,
					(flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0))
    {
      HAVE_LOCK_CHECK (connection);
      
      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);
    }

  HAVE_LOCK_CHECK (connection);

  _dbus_verbose ("end\n");
}

/**
 * Creates a new connection for the given transport.  A transport
 * represents a message stream that uses some concrete mechanism, such
 * as UNIX domain sockets. May return #NULL if insufficient
 * memory exists to create the connection.
 *
 * @param transport the transport.
 * @returns the new connection, or #NULL on failure.
 */
DBusConnection*
_dbus_connection_new_for_transport (DBusTransport *transport)
{
  DBusConnection *connection;
  DBusWatchList *watch_list;
  DBusTimeoutList *timeout_list;
  DBusHashTable *pending_replies;
  DBusList *disconnect_link;
  DBusMessage *disconnect_message;
  DBusCounter *outgoing_counter;
  DBusObjectTree *objects;
  
  watch_list = NULL;
  connection = NULL;
  pending_replies = NULL;
  timeout_list = NULL;
  disconnect_link = NULL;
  disconnect_message = NULL;
  outgoing_counter = NULL;
  objects = NULL;
  
  watch_list = _dbus_watch_list_new ();
  if (watch_list == NULL)
    goto error;

  timeout_list = _dbus_timeout_list_new ();
  if (timeout_list == NULL)
    goto error;  

  pending_replies =
    _dbus_hash_table_new (DBUS_HASH_INT,
			  NULL,
                          (DBusFreeFunction)free_pending_call_on_hash_removal);
  if (pending_replies == NULL)
    goto error;
  
  connection = dbus_new0 (DBusConnection, 1);
  if (connection == NULL)
    goto error;

  _dbus_mutex_new_at_location (&connection->mutex);
  if (connection->mutex == NULL)
    goto error;

  _dbus_mutex_new_at_location (&connection->io_path_mutex);
  if (connection->io_path_mutex == NULL)
    goto error;

  _dbus_mutex_new_at_location (&connection->dispatch_mutex);
  if (connection->dispatch_mutex == NULL)
    goto error;
  
  _dbus_condvar_new_at_location (&connection->dispatch_cond);
  if (connection->dispatch_cond == NULL)
    goto error;
  
  _dbus_condvar_new_at_location (&connection->io_path_cond);
  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");
  
  if (disconnect_message == NULL)
    goto error;

  disconnect_link = _dbus_list_alloc_link (disconnect_message);
  if (disconnect_link == NULL)
    goto error;

  outgoing_counter = _dbus_counter_new ();
  if (outgoing_counter == NULL)
    goto error;

  objects = _dbus_object_tree_new (connection);
  if (objects == NULL)
    goto error;
  
  if (_dbus_modify_sigpipe)
    _dbus_disable_sigpipe ();
  
  connection->refcount.value = 1;
  connection->transport = transport;
  connection->watches = watch_list;
  connection->timeouts = timeout_list;
  connection->pending_replies = pending_replies;
  connection->outgoing_counter = outgoing_counter;
  connection->filter_list = NULL;
  connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE; /* so we're notified first time there's data */
  connection->objects = objects;
  connection->exit_on_disconnect = FALSE;
  connection->shareable = FALSE;
  connection->route_peer_messages = FALSE;
  connection->disconnected_message_arrived = FALSE;
  connection->disconnected_message_processed = FALSE;
  
#ifndef DBUS_DISABLE_CHECKS
  connection->generation = _dbus_current_generation;
#endif
  
  _dbus_data_slot_list_init (&connection->slot_list);

  connection->client_serial = 1;

  connection->disconnect_message_link = disconnect_link;

  CONNECTION_LOCK (connection);
  
  if (!_dbus_transport_set_connection (transport, connection))
    {
      CONNECTION_UNLOCK (connection);

      goto error;
    }

  _dbus_transport_ref (transport);

  CONNECTION_UNLOCK (connection);
  
  return connection;
  
 error:
  if (disconnect_message != NULL)
    dbus_message_unref (disconnect_message);
  
  if (disconnect_link != NULL)
    _dbus_list_free_link (disconnect_link);
  
  if (connection != NULL)
    {
      _dbus_condvar_free_at_location (&connection->io_path_cond);
      _dbus_condvar_free_at_location (&connection->dispatch_cond);
      _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)
    _dbus_hash_table_unref (pending_replies);
  
  if (watch_list)
    _dbus_watch_list_free (watch_list);

  if (timeout_list)
    _dbus_timeout_list_free (timeout_list);

  if (outgoing_counter)
    _dbus_counter_unref (outgoing_counter);

  if (objects)
    _dbus_object_tree_unref (objects);
  
  return NULL;
}

/**
 * Increments the reference count of a DBusConnection.
 * Requires that the caller already holds the connection lock.
 *
 * @param connection the connection.
 * @returns the connection.
 */
DBusConnection *
_dbus_connection_ref_unlocked (DBusConnection *connection)
{  
  _dbus_assert (connection != NULL);
  _dbus_assert (connection->generation == _dbus_current_generation);

  HAVE_LOCK_CHECK (connection);
  
#ifdef DBUS_HAVE_ATOMIC_INT
  _dbus_atomic_inc (&connection->refcount);
#else
  _dbus_assert (connection->refcount.value > 0);
  connection->refcount.value += 1;
#endif

  return connection;
}

/**
 * Decrements the reference count of a DBusConnection.
 * Requires that the caller already holds the connection lock.
 *
 * @param connection the connection.
 */
void
_dbus_connection_unref_unlocked (DBusConnection *connection)
{
  dbus_bool_t last_unref;

  HAVE_LOCK_CHECK (connection);
  
  _dbus_assert (connection != NULL);

  /* The connection lock is better than the global
   * lock in the atomic increment fallback
   */
  
#ifdef DBUS_HAVE_ATOMIC_INT
  last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
#else
  _dbus_assert (connection->refcount.value > 0);

  connection->refcount.value -= 1;
  last_unref = (connection->refcount.value == 0);  
#if 0
  printf ("unref_unlocked() connection %p count = %d\n", connection, connection->refcount.value);
#endif
#endif
  
  if (last_unref)
    _dbus_connection_last_unref (connection);
}

static dbus_uint32_t
_dbus_connection_get_next_client_serial (DBusConnection *connection)
{
  dbus_uint32_t serial;

  serial = connection->client_serial++;

  if (connection->client_serial == 0)
    connection->client_serial = 1;

  return serial;
}

/**
 * A callback for use with dbus_watch_new() to create a DBusWatch.
 * 
 * @todo This is basically a hack - we could delete _dbus_transport_handle_watch()
 * and the virtual handle_watch in DBusTransport if we got rid of it.
 * The reason this is some work is threading, see the _dbus_connection_handle_watch()
 * implementation.
 *
 * @param watch the watch.
 * @param condition the current condition of the file descriptors being watched.
 * @param data must be a pointer to a #DBusConnection
 * @returns #FALSE if the IO condition may not have been fully handled due to lack of memory
 */
dbus_bool_t
_dbus_connection_handle_watch (DBusWatch                   *watch,
                               unsigned int                 condition,
                               void                        *data)
{
  DBusConnection *connection;
  dbus_bool_t retval;
  DBusDispatchStatus status;

  connection = data;

  _dbus_verbose ("start\n");
  
  CONNECTION_LOCK (connection);

  if (!_dbus_connection_acquire_io_path (connection, 1))
    {
      /* another thread is handling the message */
      CONNECTION_UNLOCK (connection);
      return TRUE;
    }

  HAVE_LOCK_CHECK (connection);
  retval = _dbus_transport_handle_watch (connection->transport,
                                         watch, condition);

  _dbus_connection_release_io_path (connection);

  HAVE_LOCK_CHECK (connection);

  _dbus_verbose ("middle\n");
  
  status = _dbus_connection_get_dispatch_status_unlocked (connection);

  /* this calls out to user code */
  _dbus_connection_update_dispatch_status_and_unlock (connection, status);

  _dbus_verbose ("end\n");
  
  return retval;
}

_DBUS_DEFINE_GLOBAL_LOCK (shared_connections);
static DBusHashTable *shared_connections = NULL;
static DBusList *shared_connections_no_guid = NULL;

static void
close_connection_on_shutdown (DBusConnection *connection)
{
  DBusMessage *message;

  dbus_connection_ref (connection);
  _dbus_connection_close_possibly_shared (connection);

  /* Churn through to the Disconnected message */
  while ((message = dbus_connection_pop_message (connection)))
    {
      dbus_message_unref (message);
    }
  dbus_connection_unref (connection);
}

static void
shared_connections_shutdown (void *data)
{
  int n_entries;
  
  _DBUS_LOCK (shared_connections);
  
  /* This is a little bit unpleasant... better ideas? */
  while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0)
    {
      DBusConnection *connection;
      DBusHashIter iter;
      
      _dbus_hash_iter_init (shared_connections, &iter);
      _dbus_hash_iter_next (&iter);
       
      connection = _dbus_hash_iter_get_value (&iter);

      _DBUS_UNLOCK (shared_connections);
      close_connection_on_shutdown (connection);
      _DBUS_LOCK (shared_connections);

      /* The connection should now be dead and not in our hash ... */
      _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) < n_entries);
    }

  _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) == 0);
  
  _dbus_hash_table_unref (shared_connections);
  shared_connections = NULL;

  if (shared_connections_no_guid != NULL)
    {
      DBusConnection *connection;
      connection = _dbus_list_pop_first (&shared_connections_no_guid);
      while (connection != NULL)
        {
          _DBUS_UNLOCK (shared_connections);
          close_connection_on_shutdown (connection);
          _DBUS_LOCK (shared_connections);
          connection = _dbus_list_pop_first (&shared_connections_no_guid);
        }
    }

  shared_connections_no_guid = NULL;
  
  _DBUS_UNLOCK (shared_connections);
}

static dbus_bool_t
connection_lookup_shared (DBusAddressEntry  *entry,
                          DBusConnection   **result)
{
  _dbus_verbose ("checking for existing connection\n");
  
  *result = NULL;
  
  _DBUS_LOCK (shared_connections);

  if (shared_connections == NULL)
    {
      _dbus_verbose ("creating shared_connections hash table\n");
      
      shared_connections = _dbus_hash_table_new (DBUS_HASH_STRING,
                                                 dbus_free,
                                                 NULL);
      if (shared_connections == NULL)
        {
          _DBUS_UNLOCK (shared_connections);
          return FALSE;
        }

      if (!_dbus_register_shutdown_func (shared_connections_shutdown, NULL))
        {
          _dbus_hash_table_unref (shared_connections);
          shared_connections = NULL;
          _DBUS_UNLOCK (shared_connections);
          return FALSE;
        }

      _dbus_verbose ("  successfully created shared_connections\n");
      
      _DBUS_UNLOCK (shared_connections);
      return TRUE; /* no point looking up in the hash we just made */
    }
  else
    {
      const char *guid;

      guid = dbus_address_entry_get_value (entry, "guid");
      
      if (guid != NULL)
        {
          DBusConnection *connection;
          
          connection = _dbus_hash_table_lookup_string (shared_connections,
                                                       guid);

          if (connection)
            {
              /* The DBusConnection can't be finalized without taking
               * the shared_connections lock to remove it from the
               * hash.  So it's safe to ref the connection here.
               * However, it may be disconnected if the Disconnected
               * message hasn't been processed yet, in which case we
               * want to pretend it isn't in the hash and avoid
               * returning it.
               *
               * The idea is to avoid ever returning a disconnected connection
               * from dbus_connection_open(). We could just synchronously
               * drop our shared ref to the connection on connection disconnect,
               * and then assert here that the connection is connected, but
               * that causes reentrancy headaches.
               */
              CONNECTION_LOCK (connection);
              if (_dbus_connection_get_is_connected_unlocked (connection))
                {
                  _dbus_connection_ref_unlocked (connection);
                  *result = connection;
                  _dbus_verbose ("looked up existing connection to server guid %s\n",
                                 guid);
                }
              else
                {
                  _dbus_verbose ("looked up existing connection to server guid %s but it was disconnected so ignoring it\n",
                                 guid);
                }
              CONNECTION_UNLOCK (connection);
            }
        }
      
      _DBUS_UNLOCK (shared_connections);
      return TRUE;
    }
}

static dbus_bool_t
connection_record_shared_unlocked (DBusConnection *connection,
                                   const char     *guid)
{
  char *guid_key;
  char *guid_in_connection;

  HAVE_LOCK_CHECK (connection);
  _dbus_assert (connection->server_guid == NULL);
  _dbus_assert (connection->shareable);

  /* get a hard ref on this connection, even if
   * we won't in fact store it in the hash, we still
   * need to hold a ref on it until it's disconnected.
   */
  _dbus_connection_ref_unlocked (connection);

  if (guid == NULL)
    {
      _DBUS_LOCK (shared_connections);

      if (!_dbus_list_prepend (&shared_connections_no_guid, connection))
        {
          _DBUS_UNLOCK (shared_connections);
          return FALSE;
        }

      _DBUS_UNLOCK (shared_connections);
      return TRUE; /* don't store in the hash */
    }
  
  /* A separate copy of the key is required in the hash table, because
   * we don't have a lock on the connection when we are doing a hash
   * lookup.
   */
  
  guid_key = _dbus_strdup (guid);
  if (guid_key == NULL)
    return FALSE;

  guid_in_connection = _dbus_strdup (guid);
  if (guid_in_connection == NULL)
    {
      dbus_free (guid_key);
      return FALSE;
    }
  
  _DBUS_LOCK (shared_connections);
  _dbus_assert (shared_connections != NULL);
  
  if (!_dbus_hash_table_insert_string (shared_connections,
                                       guid_key, connection))
    {
      dbus_free (guid_key);
      dbus_free (guid_in_connection);
      _DBUS_UNLOCK (shared_connections);
      return FALSE;
    }

  connection->server_guid = guid_in_connection;

  _dbus_verbose ("stored connection to %s to be shared\n",
                 connection->server_guid);
  
  _DBUS_UNLOCK (shared_connections);

  _dbus_assert (connection->server_guid != NULL);
  
  return TRUE;
}

static void
connection_forget_shared_unlocked (DBusConnection *connection)
{
  HAVE_LOCK_CHECK (connection);

  if (!connection->shareable)
    return;
  
  _DBUS_LOCK (shared_connections);
      
  if (connection->server_guid != NULL)
    {
      _dbus_verbose ("dropping connection to %s out of the shared table\n",
                     connection->server_guid);
      
      if (!_dbus_hash_table_remove_string (shared_connections,
                                           connection->server_guid))
        _dbus_assert_not_reached ("connection was not in the shared table");
      
      dbus_free (connection->server_guid);
      connection->server_guid = NULL;
    }
  else
    {
      _dbus_list_remove (&shared_connections_no_guid, connection);
    }

  _DBUS_UNLOCK (shared_connections);
  
  /* remove our reference held on all shareable connections */
  _dbus_connection_unref_unlocked (connection);
}

static DBusConnection*
connection_try_from_address_entry (DBusAddressEntry *entry,
                                   DBusError        *error)
{
  DBusTransport *transport;
  DBusConnection *connection;

  transport = _dbus_transport_open (entry, error);

  if (transport == NULL)
    {
      _DBUS_ASSERT_ERROR_IS_SET (error);
      return NULL;
    }

  connection = _dbus_connection_new_for_transport (transport);

  _dbus_transport_unref (transport);
  
  if (connection == NULL)
    {
      _DBUS_SET_OOM (error);
      return NULL;
    }

#ifndef DBUS_DISABLE_CHECKS
  _dbus_assert (!connection->have_connection_lock);
#endif
  return connection;
}

/*
 * If the shared parameter is true, then any existing connection will
 * be used (and if a new connection is created, it will be available
 * for use by others). If the shared parameter is false, a new
 * connection will always be created, and the new connection will
 * never be returned to other callers.
 *
 * @param address the address
 * @param shared whether the connection is shared or private
 * @param error error return
 * @returns the connection or #NULL on error
 */
static DBusConnection*
_dbus_connection_open_internal (const char     *address,
                                dbus_bool_t     shared,
                                DBusError      *error)
{
  DBusConnection *connection;
  DBusAddressEntry **entries;
  DBusError tmp_error = DBUS_ERROR_INIT;
  DBusError first_error = DBUS_ERROR_INIT;
  int len, i;

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);

  _dbus_verbose ("opening %s connection to: %s\n",
                 shared ? "shared" : "private", address);
  
  if (!dbus_parse_address (address, &entries, &len, error))
    return NULL;

  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
  
  connection = NULL;

  for (i = 0; i < len; i++)
    {
      if (shared)
        {
          if (!connection_lookup_shared (entries[i], &connection))
            _DBUS_SET_OOM (&tmp_error);
        }

      if (connection == NULL)
        {
          connection = connection_try_from_address_entry (entries[i],
                                                          &tmp_error);

          if (connection != NULL && shared)
            {
              const char *guid;
                  
              connection->shareable = TRUE;
                  
              /* guid may be NULL */
              guid = dbus_address_entry_get_value (entries[i], "guid");
                  
              CONNECTION_LOCK (connection);
          
              if (!connection_record_shared_unlocked (connection, guid))
                {
                  _DBUS_SET_OOM (&tmp_error);
                  _dbus_connection_close_possibly_shared_and_unlock (connection);
                  dbus_connection_unref (connection);
                  connection = NULL;
                }
              else
                CONNECTION_UNLOCK (connection);
            }
        }
      
      if (connection)
        break;

      _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
      
      if (i == 0)
        dbus_move_error (&tmp_error, &first_error);
      else
        dbus_error_free (&tmp_error);
    }
  
  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
  _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
  
  if (connection == NULL)
    {
      _DBUS_ASSERT_ERROR_IS_SET (&first_error);
      dbus_move_error (&first_error, error);
    }
  else
    dbus_error_free (&first_error);
  
  dbus_address_entries_free (entries);
  return connection;
}

/**
 * Closes a shared OR private connection, while dbus_connection_close() can
 * only be used on private connections. Should only be called by the
 * dbus code that owns the connection - an owner must be known,
 * the open/close state is like malloc/free, not like ref/unref.
 * 
 * @param connection the connection
 */
void
_dbus_connection_close_possibly_shared (DBusConnection *connection)
{
  _dbus_assert (connection != NULL);
  _dbus_assert (connection->generation == _dbus_current_generation);

  CONNECTION_LOCK (connection);
  _dbus_connection_close_possibly_shared_and_unlock (connection);
}

static DBusPreallocatedSend*
_dbus_connection_preallocate_send_unlocked (DBusConnection *connection)
{
  DBusPreallocatedSend *preallocated;

  HAVE_LOCK_CHECK (connection);
  
  _dbus_assert (connection != NULL);
  
  preallocated = dbus_new (DBusPreallocatedSend, 1);
  if (preallocated == NULL)
    return NULL;

  if (connection->link_cache != NULL)
    {
      preallocated->queue_link =
        _dbus_list_pop_first_link (&connection->link_cache);
      preallocated->queue_link->data = NULL;
    }
  else
    {
      preallocated->queue_link = _dbus_list_alloc_link (NULL);
      if (preallocated->queue_link == NULL)
        goto failed_0;
    }
  
  if (connection->link_cache != NULL)
    {
      preallocated->counter_link =
        _dbus_list_pop_first_link (&connection->link_cache);
      preallocated->counter_link->data = connection->outgoing_counter;
    }
  else
    {
      preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter);
      if (preallocated->counter_link == NULL)
        goto failed_1;
    }

  _dbus_counter_ref (preallocated->counter_link->data);

  preallocated->connection = connection;
  
  return preallocated;
  
 failed_1:
  _dbus_list_free_link (preallocated->queue_link);
 failed_0:
  dbus_free (preallocated);
  
  return NULL;
}

/* Called with lock held, does not update dispatch status */
static void
_dbus_connection_send_preallocated_unlocked_no_update (DBusConnection       *connection,
                                                       DBusPreallocatedSend *preallocated,
                                                       DBusMessage          *message,
                                                       dbus_uint32_t        *client_serial)
{
  dbus_uint32_t serial;

  preallocated->queue_link->data = message;
  _dbus_list_prepend_link (&connection->outgoing_messages,
                           preallocated->queue_link);

  _dbus_message_add_counter_link (message,
                                  preallocated->counter_link);

  dbus_free (preallocated);
  preallocated = NULL;
  
  dbus_message_ref (message);
  
  connection->n_outgoing += 1;

  _dbus_verbose ("Message %p (%s %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
                 message,
                 dbus_message_type_to_string (dbus_message_get_type (message)),
                 dbus_message_get_path (message) ?
                 dbus_message_get_path (message) :
                 "no path",
                 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),
                 dbus_message_get_destination (message) ?
                 dbus_message_get_destination (message) :
                 "null",
                 connection,
                 connection->n_outgoing);

  if (dbus_message_get_serial (message) == 0)
    {
      serial = _dbus_connection_get_next_client_serial (connection);
      dbus_message_set_serial (message, serial);
      if (client_serial)
        *client_serial = serial;
    }
  else
    {
      if (client_serial)
        *client_serial = dbus_message_get_serial (message);
    }

  _dbus_verbose ("Message %p serial is %u\n",
                 message, dbus_message_get_serial (message));
  
  dbus_message_lock (message);

  /* 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_unlocked (connection,
                                          NULL,
                                          DBUS_ITERATION_DO_WRITING,
                                          -1);

  /* If stuff is still queued up, be sure we wake up the main loop */
  if (connection->n_outgoing > 0)
    _dbus_connection_wakeup_mainloop (connection);
}

static void
_dbus_connection_send_preallocated_and_unlock (DBusConnection       *connection,
					       DBusPreallocatedSend *preallocated,
					       DBusMessage          *message,
					       dbus_uint32_t        *client_serial)
{
  DBusDispatchStatus status;

  HAVE_LOCK_CHECK (connection);
  
  _dbus_connection_send_preallocated_unlocked_no_update (connection,
                                                         preallocated,
                                                         message, client_serial);

  _dbus_verbose ("middle\n");
  status = _dbus_connection_get_dispatch_status_unlocked (connection);

  /* this calls out to user code */
  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
}

/**
 * Like dbus_connection_send(), but assumes the connection
 * is already locked on function entry, and unlocks before returning.
 *
 * @param connection the connection
 * @param message the message to send
 * @param client_serial return location for client serial of sent message
 * @returns #FALSE on out-of-memory
 */
dbus_bool_t
_dbus_connection_send_and_unlock (DBusConnection *connection,
				  DBusMessage    *message,
				  dbus_uint32_t  *client_serial)
{
  DBusPreallocatedSend *preallocated;

  _dbus_assert (connection != NULL);
  _dbus_assert (message != NULL);
  
  preallocated = _dbus_connection_preallocate_send_unlocked (connection);
  if (preallocated == NULL)
    {
      CONNECTION_UNLOCK (connection);
      return FALSE;
    }

  _dbus_connection_send_preallocated_and_unlock (connection,
						 preallocated,
						 message,
						 client_serial);
  return TRUE;
}

/**
 * Used internally to handle the semantics of dbus_server_set_new_connection_function().
 * If the new connection function does not ref the connection, we want to close it.
 *
 * A bit of a hack, probably the new connection function should have returned a value
 * for whether to close, or should have had to close the connection itself if it
 * didn't want it.
 *
 * But, this works OK as long as the new connection function doesn't do anything
 * crazy like keep the connection around without ref'ing it.
 *
 * We have to lock the connection across refcount check and close in case
 * the new connection function spawns a thread that closes and unrefs.
 * In that case, if the app thread
 * closes and unrefs first, we'll harmlessly close again; if the app thread
 * still has the ref, we'll close and then the app will close harmlessly.
 * If the app unrefs without closing, the app is broken since if the
 * app refs from the new connection function it is supposed to also close.
 *
 * If we didn't atomically check the refcount and close with the lock held
 * though, we could screw this up.
 * 
 * @param connection the connection
 */
void
_dbus_connection_close_if_only_one_ref (DBusConnection *connection)
{
  CONNECTION_LOCK (connection);
  
  _dbus_assert (connection->refcount.value > 0);

  if (connection->refcount.value == 1)
    _dbus_connection_close_possibly_shared_and_unlock (connection);
  else
    CONNECTION_UNLOCK (connection);
}


/**
 * When a function that blocks has been called with a timeout, and we
 * run out of memory, the time to wait for memory is based on the
 * timeout. If the caller was willing to block a long time we wait a
 * relatively long time for memory, if they were only willing to block
 * briefly then we retry for memory at a rapid rate.
 *
 * @timeout_milliseconds the timeout requested for blocking
 */
static void
_dbus_memory_pause_based_on_timeout (int timeout_milliseconds)
{
  if (timeout_milliseconds == -1)
    _dbus_sleep_milliseconds (1000);
  else if (timeout_milliseconds < 100)
    ; /* just busy loop */
  else if (timeout_milliseconds <= 1000)
    _dbus_sleep_milliseconds (timeout_milliseconds / 3);
  else
    _dbus_sleep_milliseconds (1000);
}

static DBusMessage *
generate_local_error_message (dbus_uint32_t serial, 
                              char *error_name, 
                              char *error_msg)
{
  DBusMessage *message;
  message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
  if (!message)
    goto out;

  if (!dbus_message_set_error_name (message, error_name))
    {
      dbus_message_unref (message);
      message = NULL;
      goto out; 
    }

  dbus_message_set_no_reply (message, TRUE); 

  if (!dbus_message_set_reply_serial (message,
                                      serial))
    {
      dbus_message_unref (message);
      message = NULL;
      goto out;
    }

  if (error_msg != NULL)
    {
      DBusMessageIter iter;

      dbus_message_iter_init_append (message, &iter);
      if (!dbus_message_iter_append_basic (&iter,
                                           DBUS_TYPE_STRING,
                                           &error_msg))
        {
          dbus_message_unref (message);
          message = NULL;
	  goto out;
        }
    }

 out:
  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.
 */
static DBusMessage*
check_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_list_remove_link (&connection->incoming_messages, link);
	  connection->n_incoming  -= 1;
	  return reply;
	}
      link = _dbus_list_get_next_link (&connection->incoming_messages, link);
    }

  return NULL;
}

static void
connection_timeout_and_complete_all_pending_calls_unlocked (DBusConnection *connection)
{
   /* We can't iterate over the hash in the normal way since we'll be
    * dropping the lock for each item. So we restart the
    * iter each time as we drain the hash table.
    */
   
   while (_dbus_hash_table_get_n_entries (connection->pending_replies) > 0)
    {
      DBusPendingCall *pending;
      DBusHashIter iter;
      
      _dbus_hash_iter_init (connection->pending_replies, &iter);
      _dbus_hash_iter_next (&iter);
       
      pending = _dbus_hash_iter_get_value (&iter);
      _dbus_pending_call_ref_unlocked (pending);
       
      _dbus_pending_call_queue_timeout_error_unlocked (pending, 
                                                       connection);

      if (_dbus_pending_call_is_timeout_added_unlocked (pending))
          _dbus_connection_remove_timeout_unlocked (connection,
                                                    _dbus_pending_call_get_timeout_unlocked (pending));
      _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);       
      _dbus_hash_iter_remove_entry (&iter);

      _dbus_pending_call_unref_and_unlock (pending);
      CONNECTION_LOCK (connection);
    }
  HAVE_LOCK_CHECK (connection);
}

static void
complete_pending_call_and_unlock (DBusConnection  *connection,
                                  DBusPendingCall *pending,
                                  DBusMessage     *message)
{
  _dbus_pending_call_set_reply_unlocked (pending, message);
  _dbus_pending_call_ref_unlocked (pending); /* in case there's no app with a ref held */
  _dbus_connection_detach_pending_call_and_unlock (connection, pending);
 
  /* Must be called unlocked since it invokes app callback */
  _dbus_pending_call_complete (pending);
  dbus_pending_call_unref (pending);
}

static dbus_bool_t
check_for_reply_and_update_dispatch_unlocked (DBusConnection  *connection,
                                              DBusPendingCall *pending)
{
  DBusMessage *reply;
  DBusDispatchStatus status;

  reply = check_for_reply_unlocked (connection, 
                                    _dbus_pending_call_get_reply_serial_unlocked (pending));
  if (reply != NULL)
    {
      _dbus_verbose ("checked for reply\n");

      _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");

      complete_pending_call_and_unlock (connection, pending, reply);
      dbus_message_unref (reply);

      CONNECTION_LOCK (connection);
      status = _dbus_connection_get_dispatch_status_unlocked (connection);
      _dbus_connection_update_dispatch_status_and_unlock (connection, status);
      dbus_pending_call_unref (pending);

      return TRUE;
    }

  return FALSE;
}

/**
 * Blocks until a pending call times out or gets a reply.
 *
 * Does not re-enter the main loop or run filter/path-registered
 * callbacks. The reply to the message will not be seen by
 * filter callbacks.
 *
 * Returns immediately if pending call already got a reply.
 * 
 * @todo could use performance improvements (it keeps scanning
 * the whole message queue for example)
 *
 * @param pending the pending call we block for a reply on
 */
void
_dbus_connection_block_pending_call (DBusPendingCall *pending)
{
  long start_tv_sec, start_tv_usec;
  long tv_sec, tv_usec;
  DBusDispatchStatus status;
  DBusConnection *connection;
  dbus_uint32_t client_serial;
  DBusTimeout *timeout;
  int timeout_milliseconds, elapsed_milliseconds;

  _dbus_assert (pending != NULL);

  if (dbus_pending_call_get_completed (pending))
    return;

  dbus_pending_call_ref (pending); /* necessary because the call could be canceled */

  connection = _dbus_pending_call_get_connection_and_lock (pending);
  
  /* Flush message queue - note, can affect dispatch status */
  _dbus_connection_flush_unlocked (connection);

  client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);

  /* note that timeout_milliseconds is limited to a smallish value
   * in _dbus_pending_call_new() so overflows aren't possible
   * below
   */
  timeout = _dbus_pending_call_get_timeout_unlocked (pending);
  _dbus_get_current_time (&start_tv_sec, &start_tv_usec);
  if (timeout)
    {
      timeout_milliseconds = dbus_timeout_get_interval (timeout);

      _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec\n",
                     timeout_milliseconds,
                     client_serial,
                     start_tv_sec, start_tv_usec);
    }
  else
    {
      timeout_milliseconds = -1;

      _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block for reply serial %u\n", client_serial);
    }

  /* check to see if we already got the data off the socket */
  /* from another blocked pending call */
  if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
    return;

  /* 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);

 recheck_status:

  _dbus_verbose ("top of recheck\n");
  
  HAVE_LOCK_CHECK (connection);
  
  /* queue messages and get status */

  status = _dbus_connection_get_dispatch_status_unlocked (connection);

  /* the get_completed() is in case a dispatch() while we were blocking
   * got the reply instead of us.
   */
  if (_dbus_pending_call_get_completed_unlocked (pending))
    {
      _dbus_verbose ("Pending call completed by dispatch\n");
      _dbus_connection_update_dispatch_status_and_unlock (connection, status);
      dbus_pending_call_unref (pending);
      return;
    }
  
  if (status == DBUS_DISPATCH_DATA_REMAINS)
    {
      if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
        return;
    }
  
  _dbus_get_current_time (&tv_sec, &tv_usec);
  elapsed_milliseconds = (tv_sec - start_tv_sec) * 1000 +
	  (tv_usec - start_tv_usec) / 1000;
  
  if (!_dbus_connection_get_is_connected_unlocked (connection))
    {
      DBusMessage *error_msg;

      error_msg = generate_local_error_message (client_serial,
                                                DBUS_ERROR_DISCONNECTED, 
                                                "Connection was disconnected before a reply was received"); 

      /* on OOM error_msg is set to NULL */
      complete_pending_call_and_unlock (connection, pending, error_msg);
      dbus_pending_call_unref (pending);
      return;
    }
  else if (connection->disconnect_message_link == NULL)
    _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
  else if (timeout == NULL)
    {
       if (status == DBUS_DISPATCH_NEED_MEMORY)
        {
          /* Try sleeping a bit, as we aren't sure we need to block for reading,
           * we may already have a reply in the buffer and just can't process
           * it.
           */
          _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");

          _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
        }
      else
        {          
          /* 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);
        }

      goto recheck_status;
    }
  else if (tv_sec < start_tv_sec)
    _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
  else if (elapsed_milliseconds < timeout_milliseconds)
    {
      _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds - elapsed_milliseconds);
      
      if (status == DBUS_DISPATCH_NEED_MEMORY)
        {
          /* Try sleeping a bit, as we aren't sure we need to block for reading,
           * we may already have a reply in the buffer and just can't process
           * it.
           */
          _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");

          _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
        }
      else
        {          
          /* 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);
        }

      goto recheck_status;
    }

  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %d milliseconds and got no reply\n",
                 elapsed_milliseconds);

  _dbus_assert (!_dbus_pending_call_get_completed_unlocked (pending));
  
  /* unlock and call user code */
  complete_pending_call_and_unlock (connection, pending, NULL);

  /* update user code on dispatch status */
  CONNECTION_LOCK (connection);
  status = _dbus_connection_get_dispatch_status_unlocked (connection);
  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
  dbus_pending_call_unref (pending);
}

/** @} */

/**
 * @addtogroup DBusConnection
 *
 * @{
 */

/**
 * Gets a connection to a remote address. If a connection to the given
 * address already exists, returns the existing connection with its
 * reference count incremented.  Otherwise, returns a new connection
 * and saves the new connection for possible re-use if a future call
 * to dbus_connection_open() asks to connect to the same server.
 *
 * Use dbus_connection_open_private() to get a dedicated connection
 * not shared with other callers of dbus_connection_open().
 *
 * If the open fails, the function returns #NULL, and provides a
 * reason for the failure in the error parameter. Pass #NULL for the
 * error parameter if you aren't interested in the reason for
 * failure.
 *
 * Because this connection is shared, no user of the connection
 * may call dbus_connection_close(). However, when you are done with the
 * connection you should call dbus_connection_unref().
 *
 * @note Prefer dbus_connection_open() to dbus_connection_open_private()
 * unless you have good reason; connections are expensive enough
 * that it's wasteful to create lots of connections to the same
 * server.
 * 
 * @param address the address.
 * @param error address where an error can be returned.
 * @returns new connection, or #NULL on failure.
 */
DBusConnection*
dbus_connection_open (const char     *address,
                      DBusError      *error)
{
  DBusConnection *connection;

  _dbus_return_val_if_fail (address != NULL, NULL);
  _dbus_return_val_if_error_is_set (error, NULL);

  connection = _dbus_connection_open_internal (address,
                                               TRUE,
                                               error);

  return connection;
}

/**
 * Opens a new, dedicated connection to a remote address. Unlike
 * dbus_connection_open(), always creates a new connection.
 * This connection will not be saved or recycled by libdbus.
 *
 * If the open fails, the function returns #NULL, and provides a
 * reason for the failure in the error parameter. Pass #NULL for the
 * error parameter if you aren't interested in the reason for
 * failure.
 *
 * When you are done with this connection, you must
 * dbus_connection_close() to disconnect it,
 * and dbus_connection_unref() to free the connection object.
 * 
 * (The dbus_connection_close() can be skipped if the
 * connection is already known to be disconnected, for example
 * if you are inside a handler for the Disconnected signal.)
 *
 * @note Prefer dbus_connection_open() to dbus_connection_open_private()
 * unless you have good reason; connections are expensive enough
 * that it's wasteful to create lots of connections to the same
 * server.
 *
 * @param address the address.
 * @param error address where an error can be returned.
 * @returns new connection, or #NULL on failure.
 */
DBusConnection*
dbus_connection_open_private (const char     *address,
                              DBusError      *error)
{
  DBusConnection *connection;

  _dbus_return_val_if_fail (address != NULL, NULL);
  _dbus_return_val_if_error_is_set (error, NULL);

  connection = _dbus_connection_open_internal (address,
                                               FALSE,
                                               error);

  return connection;
}

/**
 * Increments the reference count of a DBusConnection.
 *
 * @param connection the connection.
 * @returns the connection.
 */
DBusConnection *
dbus_connection_ref (DBusConnection *connection)
{
  _dbus_return_val_if_fail (connection != NULL, NULL);
  _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
  
  /* 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)
   */
  
#if 1
  _dbus_atomic_inc (&connection->refcount);
#else
  CONNECTION_LOCK (connection);
  _dbus_assert (connection->refcount.value > 0);

  connection->refcount.value += 1;
  CONNECTION_UNLOCK (connection);
#endif

  return connection;
}

static void
free_outgoing_message (void *element,
                       void *data)
{
  DBusMessage *message = element;
  DBusConnection *connection = data;

  _dbus_message_remove_counter (message,
                                connection->outgoing_counter,
                                NULL);
  dbus_message_unref (message);
}

/* This is run without the mutex held, but after the last reference
 * to the connection has been dropped we should have no thread-related
 * problems
 */
static void
_dbus_connection_last_unref (DBusConnection *connection)
{
  DBusList *link;

  _dbus_verbose ("Finalizing connection %p\n", connection);
  
  _dbus_assert (connection->refcount.value == 0);
  
  /* You have to disconnect the connection before unref:ing it. Otherwise
   * you won't get the disconnected message.
   */
  _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
  _dbus_assert (connection->server_guid == NULL);
  
  /* ---- We're going to call various application callbacks here, hope it doesn't break anything... */
  _dbus_object_tree_free_all_unlocked (connection->objects);
  
  dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
  dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
  dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
  
  _dbus_watch_list_free (connection->watches);
  connection->watches = NULL;
  
  _dbus_timeout_list_free (connection->timeouts);
  connection->timeouts = NULL;

  _dbus_data_slot_list_free (&connection->slot_list);
  
  link = _dbus_list_get_first_link (&connection->filter_list);
  while (link != NULL)
    {
      DBusMessageFilter *filter = link->data;
      DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);

      filter->function = NULL;
      _dbus_message_filter_unref (filter); /* calls app callback */
      link->data = NULL;
      
      link = next;
    }
  _dbus_list_clear (&connection->filter_list);
  
  /* ---- Done with stuff that invokes application callbacks */

  _dbus_object_tree_unref (connection->objects);  

  _dbus_hash_table_unref (connection->pending_replies);
  connection->pending_replies = NULL;
  
  _dbus_list_clear (&connection->filter_list);
  
  _dbus_list_foreach (&connection->outgoing_messages,
                      free_outgoing_message,
		      connection);
  _dbus_list_clear (&connection->outgoing_messages);
  
  _dbus_list_foreach (&connection->incoming_messages,
		      (DBusForeachFunction) dbus_message_unref,
		      NULL);
  _dbus_list_clear (&connection->incoming_messages);

  _dbus_counter_unref (connection->outgoing_counter);

  _dbus_transport_unref (connection->transport);

  if (connection->disconnect_message_link)
    {
      DBusMessage *message = connection->disconnect_message_link->data;
      dbus_message_unref (message);
      _dbus_list_free_link (connection->disconnect_message_link);
    }

  _dbus_list_clear (&connection->link_cache);
  
  _dbus_condvar_free_at_location (&connection->dispatch_cond);
  _dbus_condvar_free_at_location (&connection->io_path_cond);

  _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);
}

/**
 * Decrements the reference count of a DBusConnection, and finalizes
 * it if the count reaches zero.
 *
 * Note: it is a bug to drop the last reference to a connection that
 * is still connected.
 *
 * For shared connections, libdbus will own a reference
 * as long as the connection is connected, so you can know that either
 * you don't have the last reference, or it's OK to drop the last reference.
 * Most connections are shared. dbus_connection_open() and dbus_bus_get()
 * return shared connections.
 *
 * For private connections, the creator of the connection must arrange for
 * dbus_connection_close() to be called prior to dropping the last reference.
 * Private connections come from dbus_connection_open_private() or dbus_bus_get_private().
 *
 * @param connection the connection.
 */
void
dbus_connection_unref (DBusConnection *connection)
{
  dbus_bool_t last_unref;

  _dbus_return_if_fail (connection != NULL);
  _dbus_return_if_fail (connection->generation == _dbus_current_generation);
  
  /* 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)
   */
  
#if 1
  last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
#else
  CONNECTION_LOCK (connection);
  
  _dbus_assert (connection->refcount.value > 0);

  connection->refcount.value -= 1;
  last_unref = (connection->refcount.value == 0);

#if 0
  printf ("unref() connection %p count = %d\n", connection, connection->refcount.value);
#endif
  
  CONNECTION_UNLOCK (connection);
#endif
  
  if (last_unref)
    {
#ifndef DBUS_DISABLE_CHECKS
      if (_dbus_transport_get_is_connected (connection->transport))
        {
          _dbus_warn_check_failed ("The last reference on a connection was dropped without closing the connection. This is a bug in an application. See dbus_connection_unref() documentation for details.\n%s",
                                   connection->shareable ?
                                   "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" : 
                                    "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n");
          return;
        }
#endif
      _dbus_connection_last_unref (connection);
    }
}

/*
 * Note that the transport can disconnect itself (other end drops us)
 * and in that case this function never runs. So this function must
 * not do anything more than disconnect the transport and update the
 * dispatch status.
 * 
 * If the transport self-disconnects, then we assume someone will
 * dispatch the connection to cause the dispatch status update.
 */
static void
_dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection)
{
  DBusDispatchStatus status;

  HAVE_LOCK_CHECK (connection);
  
  _dbus_verbose ("Disconnecting %p\n", connection);

  /* We need to ref because update_dispatch_status_and_unlock will unref
   * the connection if it was shared and libdbus was the only remaining
   * refcount holder.
   */
  _dbus_connection_ref_unlocked (connection);
  
  _dbus_transport_disconnect (connection->transport);

  /* This has the side effect of queuing the disconnect message link
   * (unless we don't have enough memory, possibly, so don't assert it).
   * After the disconnect message link is queued, dbus_bus_get/dbus_connection_open
   * should never again return the newly-disconnected connection.
   *
   * However, we only unref the shared connection and exit_on_disconnect when
   * the disconnect message reaches the head of the message queue,
   * NOT when it's first queued.
   */
  status = _dbus_connection_get_dispatch_status_unlocked (connection);

  /* This calls out to user code */
  _dbus_connection_update_dispatch_status_and_unlock (connection, status);

  /* Could also call out to user code */
  dbus_connection_unref (connection);
}

/**
 * Closes a private connection, so no further data can be sent or received.
 * This disconnects the transport (such as a socket) underlying the
 * connection.
 *
 * Attempts to send messages after closing a connection are safe, but will result in
 * error replies generated locally in libdbus.
 * 
 * This function does not affect the connection's reference count.  It's
 * safe to close a connection more than once; all calls after the
 * first do nothing. It's impossible to "reopen" a connection, a
 * new connection must be created. This function may result in a call
 * to the DBusDispatchStatusFunction set with
 * dbus_connection_set_dispatch_status_function(), as the disconnect
 * message it generates needs to be dispatched.
 *
 * If a connection is dropped by the remote application, it will
 * close itself. 
 * 
 * You must close a connection prior to releasing the last reference to
 * the connection. If you dbus_connection_unref() for the last time
 * without closing the connection, the results are undefined; it
 * is a bug in your program and libdbus will try to print a warning.
 *
 * You may not close a shared connection. Connections created with
 * dbus_connection_open() or dbus_bus_get() are shared.
 * These connections are owned by libdbus, and applications should
 * only unref them, never close them. Applications can know it is
 * safe to unref these connections because libdbus will be holding a
 * reference as long as the connection is open. Thus, either the
 * connection is closed and it is OK to drop the last reference,
 * or the connection is open and the app knows it does not have the
 * last reference.
 *
 * Connections created with dbus_connection_open_private() or
 * dbus_bus_get_private() are not kept track of or referenced by
 * libdbus. The creator of these connections is responsible for
 * calling dbus_connection_close() prior to releasing the last
 * reference, if the connection is not already disconnected.
 *
 * @param connection the private (unshared) connection to close
 */
void
dbus_connection_close (DBusConnection *connection)
{
  _dbus_return_if_fail (connection != NULL);
  _dbus_return_if_fail (connection->generation == _dbus_current_generation);

  CONNECTION_LOCK (connection);

#ifndef DBUS_DISABLE_CHECKS
  if (connection->shareable)
    {
      CONNECTION_UNLOCK (connection);

      _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n");
      return;
    }
#endif
  
  _dbus_connection_close_possibly_shared_and_unlock (connection);
}

static dbus_bool_t
_dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
{
  HAVE_LOCK_CHECK (connection);
  return _dbus_transport_get_is_connected (connection->transport);
}

/**
 * Gets whether the connection is currently open.  A connection may
 * become disconnected when the remote application closes its end, or
 * exits; a connection may also be disconnected with
 * dbus_connection_close().
 * 
 * There are not separate states for "closed" and "disconnected," the two
 * terms are synonymous. This function should really be called
 * get_is_open() but for historical reasons is not.
 *
 * @param connection the connection.
 * @returns #TRUE if the connection is still alive.
 */
dbus_bool_t
dbus_connection_get_is_connected (DBusConnection *connection)
{
  dbus_bool_t res;

  _dbus_return_val_if_fail (connection != NULL, FALSE);
  
  CONNECTION_LOCK (connection);
  res = _dbus_connection_get_is_connected_unlocked (connection);
  CONNECTION_UNLOCK (connection);
  
  return res;
}

/**
 * Gets whether the connection was authenticated. (Note that
 * if the connection was authenticated then disconnected,
 * this function still returns #TRUE)
 *
 * @param connection the connection
 * @returns #TRUE if the connection was ever authenticated
 */
dbus_bool_t
dbus_connection_get_is_authenticated (DBusConnection *connection)
{
  dbus_bool_t res;

  _dbus_return_val_if_fail (connection != NULL, FALSE);
  
  CONNECTION_LOCK (connection);
  res = _dbus_transport_get_is_authenticated (connection->transport);
  CONNECTION_UNLOCK (connection);
  
  return res;
}

/**
 * Gets whether the connection is not authenticated as a specific
 * user.  If the connection is not authenticated, this function
 * returns #TRUE, and if it is authenticated but as an anonymous user,
 * it returns #TRUE.  If it is authenticated as a specific user, then
 * this returns #FALSE. (Note that if the connection was authenticated
 * as anonymous then disconnected, this function still returns #TRUE.)
 *
 * If the connection is not anonymous, you can use
 * dbus_connection_get_unix_user() and
 * dbus_connection_get_windows_user() to see who it's authorized as.
 *
 * If you want to prevent non-anonymous authorization, use
 * dbus_server_set_auth_mechanisms() to remove the mechanisms that
 * allow proving user identity (i.e. only allow the ANONYMOUS
 * mechanism).
 * 
 * @param connection the connection
 * @returns #TRUE if not authenticated or authenticated as anonymous 
 */
dbus_bool_t
dbus_connection_get_is_anonymous (DBusConnection *connection)
{
  dbus_bool_t res;

  _dbus_return_val_if_fail (connection != NULL, FALSE);
  
  CONNECTION_LOCK (connection);
  res = _dbus_transport_get_is_anonymous (connection->transport);
  CONNECTION_UNLOCK (connection);
  
  return res;
}

/**
 * Gets the ID of the server address we are authenticated to, if this
 * connection is on the client side. If the connection is on the
 * server side, this will always return #NULL - use dbus_server_get_id()
 * to get the ID of your own server, if you are the server side.
 * 
 * If a client-side connection is not authenticated yet, the ID may be
 * available if it was included in the server address, but may not be
 * available. The only way to be sure the server ID is available
 * is to wait for authentication to complete.
 *
 * In general, each mode of connecting to a given server will have
 * its own ID. So for example, if the session bus daemon is listening
 * on UNIX domain sockets and on TCP, then each of those modalities
 * will have its own server ID.
 *
 * If you want an ID that identifies an entire session bus, look at
 * dbus_bus_get_id() instead (which is just a convenience wrapper
 * around the org.freedesktop.DBus.GetId method invoked on the bus).
 *
 * You can also get a machine ID; see dbus_get_local_machine_id() to
 * get the machine you are on.  There isn't a convenience wrapper, but
 * you can invoke org.freedesktop.DBus.Peer.GetMachineId on any peer
 * to get the machine ID on the other end.
 * 
 * The D-Bus specification describes the server ID and other IDs in a
 * bit more detail.
 *
 * @param connection the connection
 * @returns the server ID or #NULL if no memory or the connection is server-side
 */
char*
dbus_connection_get_server_id (DBusConnection *connection)
{
  char *id;

  _dbus_return_val_if_fail (connection != NULL, NULL);

  CONNECTION_LOCK (connection);
  id = _dbus_strdup (_dbus_transport_get_server_id (connection->transport));
  CONNECTION_UNLOCK (connection);

  return id;
}

/**
 * Tests whether a certain type can be send via the connection. This
 * will always return TRUE for all types, with the exception of
 * DBUS_TYPE_UNIX_FD. The function will return TRUE for
 * DBUS_TYPE_UNIX_FD only on systems that know Unix file descriptors
 * and can send them via the chosen transport and when the remote side
 * supports this.
 *
 * This function can be used to do runtime checking for types that
 * might be unknown to the specific D-Bus client implementation
 * version, i.e. it will return FALSE for all types this
 * implementation does not know, including invalid or reserved types.
 *
 * @param connection the connection
 * @param type the type to check
 * @returns TRUE if the type may be send via the connection
 */
dbus_bool_t
dbus_connection_can_send_type(DBusConnection *connection,
                                  int type)
{
  _dbus_return_val_if_fail (connection != NULL, FALSE);

  if (!_dbus_type_is_valid(type))
    return FALSE;

  if (type != DBUS_TYPE_UNIX_FD)
    return TRUE;

#ifdef HAVE_UNIX_FD_PASSING
  {
    dbus_bool_t b;

    CONNECTION_LOCK(connection);
    b = _dbus_transport_can_pass_unix_fd(connection->transport);
    CONNECTION_UNLOCK(connection);

    return b;
  }
#endif

  return FALSE;
}

/**
 * Set whether _exit() should be called when the connection receives a
 * disconnect signal. The call to _exit() comes after any handlers for
 * the disconnect signal run; handlers can cancel the exit by calling
 * this function.
 *
 * By default, exit_on_disconnect is #FALSE; but for message bus
 * connections returned from dbus_bus_get() it will be toggled on
 * by default.
 *
 * @param connection the connection
 * @param exit_on_disconnect #TRUE if _exit() should be called after a disconnect signal
 */
void
dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
                                        dbus_bool_t     exit_on_disconnect)
{
  _dbus_return_if_fail (connection != NULL);

  CONNECTION_LOCK (connection);
  connection->exit_on_disconnect = exit_on_disconnect != FALSE;
  CONNECTION_UNLOCK (connection);
}

/**
 * Preallocates resources needed to send a message, allowing the message 
 * to be sent without the possibility of memory allocation failure.
 * Allows apps to create a future guarantee that they can send
 * a message regardless of memory shortages.
 *
 * @param connection the connection we're preallocating for.
 * @returns the preallocated resources, or #NULL
 */
DBusPreallocatedSend*
dbus_connection_preallocate_send (DBusConnection *connection)
{
  DBusPreallocatedSend *preallocated;

  _dbus_return_val_if_fail (connection != NULL, NULL);

  CONNECTION_LOCK (connection);
  
  preallocated =
    _dbus_connection_preallocate_send_unlocked (connection);

  CONNECTION_UNLOCK (connection);

  return preallocated;
}

/**
 * Frees preallocated message-sending resources from
 * dbus_connection_preallocate_send(). Should only
 * be called if the preallocated resources are not used
 * to send a message.
 *
 * @param connection the connection
 * @param preallocated the resources
 */
void
dbus_connection_free_preallocated_send (DBusConnection       *connection,
                                        DBusPreallocatedSend *preallocated)
{
  _dbus_return_if_fail (connection != NULL);
  _dbus_return_if_fail (preallocated != NULL);  
  _dbus_return_if_fail (connection == preallocated->connection);

  _dbus_list_free_link (preallocated->queue_link);
  _dbus_counter_unref (preallocated->counter_link->data);
  _dbus_list_free_link (preallocated->counter_link);
  dbus_free (preallocated);
}

/**
 * Sends a message using preallocated resources. This function cannot fail.
 * It works identically to dbus_connection_send() in other respects.
 * Preallocated resources comes from dbus_connection_preallocate_send().
 * This function "consumes" the preallocated resources, they need not
 * be freed separately.
 *
 * @param connection the connection
 * @param preallocated the preallocated resources
 * @param message the message to send
 * @param client_serial return location for client serial assigned to the message
 */
void
dbus_connection_send_preallocated (DBusConnection       *connection,
                                   DBusPreallocatedSend *preallocated,
                                   DBusMessage          *message,
                                   dbus_uint32_t        *client_serial)
{
  _dbus_return_if_fail (connection != NULL);
  _dbus_return_if_fail (preallocated != NULL);
  _dbus_return_if_fail (message != NULL);
  _dbus_return_if_fail (preallocated->connection == connection);
  _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
                        dbus_message_get_member (message) != NULL);
  _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
                        (dbus_message_get_interface (message) != NULL &&
                         dbus_message_get_member (message) != NULL));

  CONNECTION_LOCK (connection);

#ifdef HAVE_UNIX_FD_PASSING

  if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
      message->n_unix_fds > 0)
    {
      /* Refuse to send fds on a connection that cannot handle
         them. Unfortunately we cannot return a proper error here, so
         the best we can is just return. */
      CONNECTION_UNLOCK (connection);
      return;
    }

#endif

  _dbus_connection_send_preallocated_and_unlock (connection,
						 preallocated,
						 message, client_serial);
}

static dbus_bool_t
_dbus_connection_send_unlocked_no_update (DBusConnection *connection,
                                          DBusMessage    *message,
                                          dbus_uint32_t  *client_serial)
{
  DBusPreallocatedSend *preallocated;

  _dbus_assert (connection != NULL);
  _dbus_assert (message != NULL);
  
  preallocated = _dbus_connection_preallocate_send_unlocked (connection);
  if (preallocated == NULL)
    return FALSE;

  _dbus_connection_send_preallocated_unlocked_no_update (connection,
                                                         preallocated,
                                                         message,
                                                         client_serial);
  return TRUE;
}

/**
 * Adds a message to the outgoing message queue. Does not block to
 * write the message to the network; that happens asynchronously. To
 * force the message to be written, call dbus_connection_flush() however
 * it is not necessary to call dbus_connection_flush() by hand; the 
 * message will be sent the next time the main loop is run. 
 * dbus_connection_flush() should only be used, for example, if
 * the application was expected to exit before running the main loop.
 *
 * Because this only queues the message, the only reason it can
 * fail is lack of memory. Even if the connection is disconnected,
 * no error will be returned. If the function fails due to lack of memory, 
 * it returns #FALSE. The function will never fail for other reasons; even 
 * if the connection is disconnected, you can queue an outgoing message,
 * though obviously it won't be sent.
 *
 * The message serial is used by the remote application to send a
 * reply; see dbus_message_get_serial() or the D-Bus specification.
 *
 * dbus_message_unref() can be called as soon as this method returns
 * as the message queue will hold its own ref until the message is sent.
 * 
 * @param connection the connection.
 * @param message the message to write.
 * @param serial return location for message serial, or #NULL if you don't care
 * @returns #TRUE on success.
 */
dbus_bool_t
dbus_connection_send (DBusConnection *connection,
                      DBusMessage    *message,
                      dbus_uint32_t  *serial)
{
  _dbus_return_val_if_fail (connection != NULL, FALSE);
  _dbus_return_val_if_fail (message != NULL, FALSE);

  CONNECTION_LOCK (connection);

#ifdef HAVE_UNIX_FD_PASSING

  if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
      message->n_unix_fds > 0)
    {
      /* Refuse to send fds on a connection that cannot handle
         them. Unfortunately we cannot return a proper error here, so
         the best we can is just return. */
      CONNECTION_UNLOCK (connection);
      return FALSE;
    }

#endif

  return _dbus_connection_send_and_unlock (connection,
					   message,
					   serial);
}

static dbus_bool_t
reply_handler_timeout (void *data)
{
  DBusConnection *connection;
  DBusDispatchStatus status;
  DBusPendingCall *pending = data;

  connection = _dbus_pending_call_get_connection_and_lock (pending);

  _dbus_pending_call_queue_timeout_error_unlocked (pending, 
                                                   connection);
  _dbus_connection_remove_timeout_unlocked (connection,
				            _dbus_pending_call_get_timeout_unlocked (pending));
  _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);

  _dbus_verbose ("middle\n");
  status = _dbus_connection_get_dispatch_status_unlocked (connection);

  /* Unlocks, and calls out to user code */
  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
  
  return TRUE;
}

/**
 * Queues a message to send, as with dbus_connection_send(),
 * but also returns a #DBusPendingCall used to receive a reply to the
 * message. If no reply is received in the given timeout_milliseconds,
 * this function expires the pending reply and generates a synthetic
 * error reply (generated in-process, not by the remote application)
 * indicating that a timeout occurred.
 *
 * A #DBusPendingCall will see a reply message before any filters or
 * registered object path handlers. See dbus_connection_dispatch() for
 * details on when handlers are run.
 *
 * A #DBusPendingCall will always see exactly one reply message,
 * unless it's cancelled with dbus_pending_call_cancel().
 * 
 * If #NULL is passed for the pending_return, the #DBusPendingCall
 * will still be generated internally, and used to track
 * the message reply timeout. This means a timeout error will
 * occur if no reply arrives, unlike with dbus_connection_send().
 *
 * If -1 is passed for the timeout, a sane default timeout is used. -1
 * is typically the best value for the timeout for this reason, unless
 * you want a very short or very long timeout.  If INT_MAX is passed for
 * the timeout, no timeout will be set and the call will block forever.
 *
 * @warning if the connection is disconnected or you try to send Unix
 * file descriptors on a connection that does not support them, the
 * #DBusPendingCall will be set to #NULL, so be careful with this.
 *
 * @param connection the connection
 * @param message the message to send
 * @param pending_return return location for a #DBusPendingCall
 * object, or #NULL if connection is disconnected or when you try to
 * send Unix file descriptors on a connection that does not support
 * them.
 * @param timeout_milliseconds timeout in milliseconds, -1 for default or INT_MAX for no timeout
 * @returns #FALSE if no memory, #TRUE otherwise.
 *
 */
dbus_bool_t
dbus_connection_send_with_reply (DBusConnection     *connection,
                                 DBusMessage        *message,
                                 DBusPendingCall   **pending_return,
                                 int                 timeout_milliseconds)
{
  DBusPendingCall *pending;
  dbus_int32_t serial = -1;
  DBusDispatchStatus status;

  _dbus_return_val_if_fail (connection != NULL, FALSE);
  _dbus_return_val_if_fail (message != NULL, FALSE);
  _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);

  if (pending_return)
    *pending_return = NULL;

  CONNECTION_LOCK (connection);

#ifdef HAVE_UNIX_FD_PASSING

  if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
      message->n_unix_fds > 0)
    {
      /* Refuse to send fds on a connection that cannot handle
         them. Unfortunately we cannot return a proper error here, so
         the best we can do is return TRUE but leave *pending_return
         as NULL. */
      CONNECTION_UNLOCK (connection);
      return TRUE;
    }

#endif

   if (!_dbus_connection_get_is_connected_unlocked (connection))
    {
      CONNECTION_UNLOCK (connection);

      return TRUE;
    }

  pending = _dbus_pending_call_new_unlocked (connection,
                                             timeout_milliseconds,
                                             reply_handler_timeout);

  if (pending == NULL)
    {
      CONNECTION_UNLOCK (connection);
      return FALSE;
    }

  /* Assign a serial to the message */
  serial = dbus_message_get_serial (message);
  if (serial == 0)
    {
      serial = _dbus_connection_get_next_client_serial (connection);
      dbus_message_set_serial (message, serial);
    }

  if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
    goto error;
    
  /* Insert the serial in the pending replies hash;
   * hash takes a refcount on DBusPendingCall.
   * Also, add the timeout.
   */
  if (!_dbus_connection_attach_pending_call_unlocked (connection,
						      pending))
    goto error;
 
  if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
    {
      _dbus_connection_detach_pending_call_and_unlock (connection,
						       pending);
      goto error_unlocked;
    }

  if (pending_return)
    *pending_return = pending; /* hand off refcount */
  else
    {
      _dbus_connection_detach_pending_call_unlocked (connection, pending);
      /* we still have a ref to the pending call in this case, we unref
       * after unlocking, below
       */
    }

  status = _dbus_connection_get_dispatch_status_unlocked (connection);

  /* this calls out to user code */
  _dbus_connection_update_dispatch_status_and_unlock (connection, status);

  if (pending_return == NULL)
    dbus_pending_call_unref (pending);
  
  return TRUE;

 error:
  CONNECTION_UNLOCK (connection);
 error_unlocked:
  dbus_pending_call_unref (pending);
  return FALSE;
}

/**
 * Sends a message and blocks a certain time period while waiting for
 * a reply.  This function does not reenter the main loop,
 * i.e. messages other than the reply are queued up but not
 * processed. This function is used to invoke method calls on a
 * remote object.
 * 
 * If a normal reply is received, it is returned, and removed from the
 * incoming message queue. If it is not received, #NULL is returned
 * and the error is set to #DBUS_ERROR_NO_REPLY.  If an error reply is
 * received, it is converted to a #DBusError and returned as an error,
 * then the reply message is deleted and #NULL is returned. If
 * something else goes wrong, result is set to whatever is
 * appropriate, such as #DBUS_ERROR_NO_MEMORY or
 * #DBUS_ERROR_DISCONNECTED.
 *
 * @warning While this function blocks the calling thread will not be
 * processing the incoming message queue. This means you can end up
 * deadlocked if the application you're talking to needs you to reply
 * to a method. To solve this, either avoid the situation, block in a
 * separate thread from the main connection-dispatching thread, or use
 * dbus_pending_call_set_notify() to avoid blocking.
 *
 * @param connection the connection
 * @param message the message to send
 * @param timeout_milliseconds timeout in milliseconds, -1 for default or INT_MAX for no timeout.
 * @param error return location for error message
 * @returns the message that is the reply or #NULL with an error code if the
 * function fails.
 */
DBusMessage*
dbus_connection_send_with_reply_and_block (DBusConnection     *connection,
                                           DBusMessage        *message,
                                           int                 timeout_milliseconds,
                                           DBusError          *error)
{
  DBusMessage *reply;
  DBusPendingCall *pending;

  _dbus_return_val_if_fail (connection != NULL, NULL);
  _dbus_return_val_if_fail (message != NULL, NULL);
  _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL);
  _dbus_return_val_if_error_is_set (error, NULL);

#ifdef HAVE_UNIX_FD_PASSING

  CONNECTION_LOCK (connection);
  if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
      message->n_unix_fds > 0)
    {
      CONNECTION_UNLOCK (connection);
      dbus_set_error(error, DBUS_ERROR_FAILED, "Cannot send file descriptors on this connection.");
      return NULL;
    }
  CONNECTION_UNLOCK (connection);

#endif

  if (!dbus_connection_send_with_reply (connection, message,
                                        &pending, timeout_milliseconds))
    {
      _DBUS_SET_OOM (error);
      return NULL;
    }

  if (pending == NULL)
    {
      dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Connection is closed");
      return NULL;
    }
  
  dbus_pending_call_block (pending);

  reply = dbus_pending_call_steal_reply (pending);
  dbus_pending_call_unref (pending);

  /* call_complete_and_unlock() called from pending_call_block() should
   * always fill this in.
   */
  _dbus_assert (reply != NULL);
  
   if (dbus_set_error_from_message (error, reply))
    {
      dbus_message_unref (reply);
      return NULL;
    }
  else
    return reply;
}

/**
 * Blocks until the outgoing message queue is empty.
 * Assumes connection lock already held.
 *
 * If you call this, you MUST call update_dispatch_status afterword...
 * 
 * @param connection the connection.
 */
static DBusDispatchStatus
_dbus_connection_flush_unlocked (DBusConnection *connection)
{
  /* We have to specify DBUS_ITERATION_DO_READING here because
   * otherwise we could have two apps deadlock if they are both doing
   * a flush(), and the kernel buffers fill up. This could change the
   * dispatch status.
   */
  DBusDispatchStatus status;

  HAVE_LOCK_CHECK (connection);
  
  while (connection->n_outgoing > 0 &&
         _dbus_connection_get_is_connected_unlocked (connection))
    {
      _dbus_verbose ("doing iteration in\n");
      HAVE_LOCK_CHECK (connection);
      _dbus_connection_do_iteration_unlocked (connection,
                                              NULL,
                                              DBUS_ITERATION_DO_READING |
                                              DBUS_ITERATION_DO_WRITING |
                                              DBUS_ITERATION_BLOCK,
                                              -1);
    }

  HAVE_LOCK_CHECK (connection);
  _dbus_verbose ("middle\n");
  status = _dbus_connection_get_dispatch_status_unlocked (connection);

  HAVE_LOCK_CHECK (connection);
  return status;
}

/**
 * Blocks until the outgoing message queue is empty.
 *
 * @param connection the connection.
 */
void
dbus_connection_flush (DBusConnection *connection)
{
  /* We have to specify DBUS_ITERATION_DO_READING here because
   * otherwise we could have two apps deadlock if they are both doing
   * a flush(), and the kernel buffers fill up. This could change the
   * dispatch status.
   */
  DBusDispatchStatus status;

  _dbus_return_if_fail (connection != NULL);
  
  CONNECTION_LOCK (connection);

  status = _dbus_connection_flush_unlocked (connection);
  
  HAVE_LOCK_CHECK (connection);
  /* Unlocks and calls out to user code */
  _dbus_connection_update_dispatch_status_and_unlock (connection, status);

  _dbus_verbose ("end\n");
}

/**
 * This function implements dbus_connection_read_write_dispatch() and
 * dbus_connection_read_write() (they pass a different value for the
 * dispatch parameter).
 * 
 * @param connection the connection
 * @param timeout_milliseconds max time to block or -1 for infinite
 * @param dispatch dispatch new messages or leave them on the incoming queue
 * @returns #TRUE if the disconnect message has not been processed
 */
static dbus_bool_t
_dbus_connection_read_write_dispatch (DBusConnection *connection,
                                     int             timeout_milliseconds, 
                                     dbus_bool_t     dispatch)
{
  DBusDispatchStatus dstatus;
  dbus_bool_t progress_possible;

  /* Need to grab a ref here in case we're a private connection and
   * the user drops the last ref in a handler we call; see bug 
   * https://bugs.freedesktop.org/show_bug.cgi?id=15635
   */
  dbus_connection_ref (connection);
  dstatus = dbus_connection_get_dispatch_status (connection);

  if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
    {
      _dbus_verbose ("doing dispatch\n");
      dbus_connection_dispatch (connection);
      CONNECTION_LOCK (connection);
    }
  else if (dstatus == DBUS_DISPATCH_NEED_MEMORY)
    {
      _dbus_verbose ("pausing for memory\n");
      _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
      CONNECTION_LOCK (connection);
    }
  else
    {
      CONNECTION_LOCK (connection);
      if (_dbus_connection_get_is_connected_unlocked (connection))
        {
          _dbus_verbose ("doing iteration\n");
          _dbus_connection_do_iteration_unlocked (connection,
                                                  NULL,
                                                  DBUS_ITERATION_DO_READING |
                                                  DBUS_ITERATION_DO_WRITING |
                                                  DBUS_ITERATION_BLOCK,
                                                  timeout_milliseconds);
        }
    }
  
  HAVE_LOCK_CHECK (connection);
  /* If we can dispatch, we can make progress until the Disconnected message
   * has been processed; if we can only read/write, we can make progress
   * as long as the transport is open.
   */
  if (dispatch)
    progress_possible = connection->n_incoming != 0 ||
      connection->disconnect_message_link != NULL;
  else
    progress_possible = _dbus_connection_get_is_connected_unlocked (connection);

  CONNECTION_UNLOCK (connection);

  dbus_connection_unref (connection);

  return progress_possible; /* TRUE if we can make more progress */
}


/**
 * This function is intended for use with applications that don't want
 * to write a main loop and deal with #DBusWatch and #DBusTimeout. An
 * example usage would be:
 * 
 * @code
 *   while (dbus_connection_read_write_dispatch (connection, -1))
 *     ; // empty loop body
 * @endcode
 * 
 * In this usage you would normally have set up a filter function to look
 * at each message as it is dispatched. The loop terminates when the last
 * message from the connection (the disconnected signal) is processed.
 * 
 * If there are messages to dispatch, this function will
 * dbus_connection_dispatch() once, and return. If there are no
 * messages to dispatch, this function will block until it can read or
 * write, then read or write, then return.
 *
 * The way to think of this function is that it either makes some sort
 * of progress, or it blocks. Note that, while it is blocked on I/O, it
 * cannot be interrupted (even by other threads), which makes this function
 * unsuitable for applications that do more than just react to received
 * messages.
 *
 * The return value indicates whether the disconnect message has been
 * processed, NOT whether the connection is connected. This is
 * important because even after disconnecting, you want to process any
 * messages you received prior to the disconnect.
 *
 * @param connection the connection
 * @param timeout_milliseconds max time to block or -1 for infinite
 * @returns #TRUE if the disconnect message has not been processed
 */
dbus_bool_t
dbus_connection_read_write_dispatch (DBusConnection *connection,
                                     int             timeout_milliseconds)
{
  _dbus_return_val_if_fail (connection != NULL, FALSE);
  _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
   return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE);
}

/** 
 * This function is intended for use with applications that don't want to
 * write a main loop and deal with #DBusWatch and #DBusTimeout. See also
 * dbus_connection_read_write_dispatch().
 * 
 * As long as the connection is open, this function will block until it can
 * read or write, then read or write, then return #TRUE.
 *
 * If the connection is closed, the function returns #FALSE.
 *
 * The return value indicates whether reading or writing is still
 * possible, i.e. whether the connection is connected.
 *
 * Note that even after disconnection, messages may remain in the
 * incoming queue that need to be
 * processed. dbus_connection_read_write_dispatch() dispatches
 * incoming messages for you; with dbus_connection_read_write() you
 * have to arrange to drain the incoming queue yourself.
 * 
 * @param connection the connection 
 * @param timeout_milliseconds max time to block or -1 for infinite 
 * @returns #TRUE if still connected
 */
dbus_bool_t 
dbus_connection_read_write (DBusConnection *connection, 
                            int             timeout_milliseconds) 
{ 
  _dbus_return_val_if_fail (connection != NULL, FALSE);
  _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
   return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE);
}

/* We need to call this anytime we pop the head of the queue, and then
 * update_dispatch_status_and_unlock needs to be called afterward
 * which will "process" the disconnected message and set
 * disconnected_message_processed.
 */
static void
check_disconnected_message_arrived_unlocked (DBusConnection *connection,
                                             DBusMessage    *head_of_queue)
{
  HAVE_LOCK_CHECK (connection);

  /* checking that the link is NULL is an optimization to avoid the is_signal call */
  if (connection->disconnect_message_link == NULL &&
      dbus_message_is_signal (head_of_queue,
                              DBUS_INTERFACE_LOCAL,
                              "Disconnected"))
    {
      connection->disconnected_message_arrived = TRUE;
    }
}

/**
 * Returns the first-received message from the incoming message queue,
 * leaving it in the queue. If the queue is empty, returns #NULL.
 * 
 * The caller does not own a reference to the returned message, and
 * must either return it using dbus_connection_return_message() or
 * keep it after calling dbus_connection_steal_borrowed_message(). No
 * one can get at the message while its borrowed, so return it as
 * quickly as possible and don't keep a reference to it after
 * returning it. If you need to keep the message, make a copy of it.
 *
 * dbus_connection_dispatch() will block if called while a borrowed
 * message is outstanding; only one piece of code can be playing with
 * the incoming queue at a time. This function will block if called
 * during a dbus_connection_dispatch().
 *
 * @param connection the connection.
 * @returns next message in the incoming queue.
 */
DBusMessage*
dbus_connection_borrow_message (DBusConnection *connection)
{
  DBusDispatchStatus status;
  DBusMessage *message;

  _dbus_return_val_if_fail (connection != NULL, NULL);

  _dbus_verbose ("start\n");
  
  /* this is called for the side effect that it queues
   * up any messages from the transport
   */
  status = dbus_connection_get_dispatch_status (connection);
  if (status != DBUS_DISPATCH_DATA_REMAINS)
    return NULL;
  
  CONNECTION_LOCK (connection);

  _dbus_connection_acquire_dispatch (connection);

  /* While a message is outstanding, the dispatch lock is held */
  _dbus_assert (connection->message_borrowed == NULL);

  connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
  
  message = connection->message_borrowed;

  check_disconnected_message_arrived_unlocked (connection, message);
  
  /* Note that we KEEP the dispatch lock until the message is returned */
  if (message == NULL)
    _dbus_connection_release_dispatch (connection);

  CONNECTION_UNLOCK (connection);

  /* We don't update dispatch status until it's returned or stolen */
  
  return message;
}

/**
 * Used to return a message after peeking at it using
 * dbus_connection_borrow_message(). Only called if
 * message from dbus_connection_borrow_message() was non-#NULL.
 *
 * @param connection the connection
 * @param message the message from dbus_connection_borrow_message()
 */
void
dbus_connection_return_message (DBusConnection *connection,
				DBusMessage    *message)
{
  DBusDispatchStatus status;
  
  _dbus_return_if_fail (connection != NULL);
  _dbus_return_if_fail (message != NULL);
  _dbus_return_if_fail (message == connection->message_borrowed);
  _dbus_return_if_fail (connection->dispatch_acquired);
  
  CONNECTION_LOCK (connection);
  
  _dbus_assert (message == connection->message_borrowed);
  
  connection->message_borrowed = NULL;

  _dbus_connection_release_dispatch (connection); 

  status = _dbus_connection_get_dispatch_status_unlocked (connection);
  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
}

/**
 * Used to keep a message after peeking at it using
 * dbus_connection_borrow_message(). Before using this function, see
 * the caveats/warnings in the documentation for
 * dbus_connection_pop_message().
 *
 * @param connection the connection
 * @param message the message from dbus_connection_borrow_message()
 */
void
dbus_connection_steal_borrowed_message (DBusConnection *connection,
					DBusMessage    *message)
{
  DBusMessage *pop_message;
  DBusDispatchStatus status;

  _dbus_return_if_fail (connection != NULL);
  _dbus_return_if_fail (message != NULL);
  _dbus_return_if_fail (message == connection->message_borrowed);
  _dbus_return_if_fail (connection->dispatch_acquired);
  
  CONNECTION_LOCK (connection);
 
  _dbus_assert (message == connection->message_borrowed);

  pop_message = _dbus_list_pop_first (&connection->incoming_messages);
  _dbus_assert (message == pop_message);
  
  connection->n_incoming -= 1;
 
  _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
		 message, connection->n_incoming);
 
  connection->message_borrowed = NULL;

  _dbus_connection_release_dispatch (connection);

  status = _dbus_connection_get_dispatch_status_unlocked (connection);
  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
}

/* See dbus_connection_pop_message, but requires the caller to own
 * the lock before calling. May drop the lock while running.
 */
static DBusList*
_dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
{
  HAVE_LOCK_CHECK (connection);
  
  _dbus_assert (connection->message_borrowed == NULL);
  
  if (connection->n_incoming > 0)
    {
      DBusList *link;

      link = _dbus_list_pop_first_link (&connection->incoming_messages);
      connection->n_incoming -= 1;

      _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from incoming queue %p, %d incoming\n",
                     link->data,
                     dbus_message_type_to_string (dbus_message_get_type (link->data)),
                     dbus_message_get_path (link->data) ?
                     dbus_message_get_path (link->data) :
                     "no path",
                     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);

      check_disconnected_message_arrived_unlocked (connection, link->data);
      
      return link;
    }
  else
    return NULL;
}

/* See dbus_connection_pop_message, but requires the caller to own
 * the lock before calling. May drop the lock while running.
 */
static DBusMessage*
_dbus_connection_pop_message_unlocked (DBusConnection *connection)
{
  DBusList *link;

  HAVE_LOCK_CHECK (connection);
  
  link = _dbus_connection_pop_message_link_unlocked (connection);

  if (link != NULL)
    {
      DBusMessage *message;
      
      message = link->data;
      
      _dbus_list_free_link (link);
      
      return message;
    }
  else
    return NULL;
}

static void
_dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
                                                DBusList       *message_link)
{
  HAVE_LOCK_CHECK (connection);
  
  _dbus_assert (message_link != NULL);
  /* You can't borrow a message while a link is outstanding */
  _dbus_assert (connection->message_borrowed == NULL);
  /* We had to have the dispatch lock across the pop/putback */
  _dbus_assert (connection->dispatch_acquired);

  _dbus_list_prepend_link (&connection->incoming_messages,
                           message_link);
  connection->n_incoming += 1;

  _dbus_verbose ("Message %p (%s %s %s '%s') put back into queue %p, %d incoming\n",
                 message_link->data,
                 dbus_message_type_to_string (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);
}

/**
 * Returns the first-received message from the incoming message queue,
 * removing it from the queue. The caller owns a reference to the
 * returned message. If the queue is empty, returns #NULL.
 *
 * This function bypasses any message handlers that are registered,
 * and so using it is usually wrong. Instead, let the main loop invoke
 * dbus_connection_dispatch(). Popping messages manually is only
 * useful in very simple programs that don't share a #DBusConnection
 * with any libraries or other modules.
 *
 * There is a lock that covers all ways of accessing the incoming message
 * queue, so dbus_connection_dispatch(), dbus_connection_pop_message(),
 * dbus_connection_borrow_message(), etc. will all block while one of the others
 * in the group is running.
 * 
 * @param connection the connection.
 * @returns next message in the incoming queue.
 */
DBusMessage*
dbus_connection_pop_message (DBusConnection *connection)
{
  DBusMessage *message;
  DBusDispatchStatus status;

  _dbus_verbose ("start\n");
  
  /* this is called for the side effect that it queues
   * up any messages from the transport
   */
  status = dbus_connection_get_dispatch_status (connection);
  if (status != DBUS_DISPATCH_DATA_REMAINS)
    return NULL;
  
  CONNECTION_LOCK (connection);
  _dbus_connection_acquire_dispatch (connection);
  HAVE_LOCK_CHECK (connection);
  
  message = _dbus_connection_pop_message_unlocked (connection);

  _dbus_verbose ("Returning popped message %p\n", message);    

  _dbus_connection_release_dispatch (connection);

  status = _dbus_connection_get_dispatch_status_unlocked (connection);
  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
  
  return message;
}

/**
 * Acquire the dispatcher. This is a separate lock so the main
 * connection lock can be dropped to call out to application dispatch
 * handlers.
 *
 * @param connection the connection.
 */
static void
_dbus_connection_acquire_dispatch (DBusConnection *connection)
{
  HAVE_LOCK_CHECK (connection);

  _dbus_connection_ref_unlocked (connection);
  CONNECTION_UNLOCK (connection);
  
  _dbus_verbose ("locking dispatch_mutex\n");
  _dbus_mutex_lock (connection->dispatch_mutex);

  while (connection->dispatch_acquired)
    {
      _dbus_verbose ("waiting for dispatch to be acquirable\n");
      _dbus_condvar_wait (connection->dispatch_cond, 
                          connection->dispatch_mutex);
    }
  
  _dbus_assert (!connection->dispatch_acquired);

  connection->dispatch_acquired = TRUE;

  _dbus_verbose ("unlocking dispatch_mutex\n");
  _dbus_mutex_unlock (connection->dispatch_mutex);
  
  CONNECTION_LOCK (connection);
  _dbus_connection_unref_unlocked (connection);
}

/**
 * Release the dispatcher when you're done with it. Only call
 * after you've acquired the dispatcher. Wakes up at most one
 * thread currently waiting to acquire the dispatcher.
 *
 * @param connection the connection.
 */
static void
_dbus_connection_release_dispatch (DBusConnection *connection)
{
  HAVE_LOCK_CHECK (connection);
  
  _dbus_verbose ("locking dispatch_mutex\n");
  _dbus_mutex_lock (connection->dispatch_mutex);
  
  _dbus_assert (connection->dispatch_acquired);

  connection->dispatch_acquired = FALSE;
  _dbus_condvar_wake_one (connection->dispatch_cond);

  _dbus_verbose ("unlocking dispatch_mutex\n");
  _dbus_mutex_unlock (connection->dispatch_mutex);
}

static void
_dbus_connection_failed_pop (DBusConnection *connection,
			     DBusList       *message_link)
{
  _dbus_list_prepend_link (&connection->incoming_messages,
			   message_link);
  connection->n_incoming += 1;
}

/* Note this may be called multiple times since we don't track whether we already did it */
static void
notify_disconnected_unlocked (DBusConnection *connection)
{
  HAVE_LOCK_CHECK (connection);

  /* Set the weakref in dbus-bus.c to NULL, so nobody will get a disconnected
   * connection from dbus_bus_get(). We make the same guarantee for
   * dbus_connection_open() but in a different way since we don't want to
   * unref right here; we instead check for connectedness before returning
   * the connection from the hash.
   */
  _dbus_bus_notify_shared_connection_disconnected_unlocked (connection);

  /* 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.
   */
  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);
        }
    } 
}

/* Note this may be called multiple times since we don't track whether we already did it */
static DBusDispatchStatus
notify_disconnected_and_dispatch_complete_unlocked (DBusConnection *connection)
{
  HAVE_LOCK_CHECK (connection);
  
  if (connection->disconnect_message_link != NULL)
    {
      _dbus_verbose ("Sending disconnect message\n");
      
      /* If we have pending calls, queue their timeouts - we want the Disconnected
       * to be the last message, after these timeouts.
       */
      connection_timeout_and_complete_all_pending_calls_unlocked (connection);
      
      /* 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;

      return DBUS_DISPATCH_DATA_REMAINS;
    }

  return DBUS_DISPATCH_COMPLETE;
}

static DBusDispatchStatus
_dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
{
  HAVE_LOCK_CHECK (connection);
  
  if (connection->n_incoming > 0)
    return DBUS_DISPATCH_DATA_REMAINS;
  else if (!_dbus_transport_queue_messages (connection->transport))
    return DBUS_DISPATCH_NEED_MEMORY;
  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);

      _dbus_verbose ("dispatch status = %s is_connected = %d\n",
                     DISPATCH_STATUS_NAME (status), is_connected);
      
      if (!is_connected)
        {
          /* It's possible this would be better done by having an explicit
           * notification from _dbus_transport_disconnect() that would
           * synchronously do this, instead of waiting for the next dispatch
           * status check. However, probably not good to change until it causes
           * a problem.
           */
          notify_disconnected_unlocked (connection);

          /* I'm not sure this is needed; the idea is that we want to
           * queue the Disconnected only after we've read all the
           * messages, but if we're disconnected maybe we are guaranteed
           * to have read them all ?
           */
          if (status == DBUS_DISPATCH_COMPLETE)
            status = notify_disconnected_and_dispatch_complete_unlocked (connection);
        }
      
      if (status != DBUS_DISPATCH_COMPLETE)
        return status;
      else if (connection->n_incoming > 0)
        return DBUS_DISPATCH_DATA_REMAINS;
      else
        return DBUS_DISPATCH_COMPLETE;
    }
}

static void
_dbus_connection_update_dispatch_status_and_unlock (DBusConnection    *connection,
                                                    DBusDispatchStatus new_status)
{
  dbus_bool_t changed;
  DBusDispatchStatusFunction function;
  void *data;

  HAVE_LOCK_CHECK (connection);

  _dbus_connection_ref_unlocked (connection);

  changed = new_status != connection->last_dispatch_status;

  connection->last_dispatch_status = new_status;

  function = connection->dispatch_status_function;
  data = connection->dispatch_status_data;

  if (connection->disconnected_message_arrived &&
      !connection->disconnected_message_processed)
    {
      connection->disconnected_message_processed = TRUE;
      
      /* this does an unref, but we have a ref
       * so we should not run the finalizer here
       * inside the lock.
       */
      connection_forget_shared_unlocked (connection);

      if (connection->exit_on_disconnect)
        {
          CONNECTION_UNLOCK (connection);            
          
          _dbus_verbose ("Exiting on Disconnected signal\n");
          _dbus_exit (1);
          _dbus_assert_not_reached ("Call to exit() returned");
        }
    }
  
  /* We drop the lock */
  CONNECTION_UNLOCK (connection);
  
  if (changed && function)
    {
      _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
                     connection, new_status,
                     DISPATCH_STATUS_NAME (new_status));
      (* function) (connection, new_status, data);      
    }
  
  dbus_connection_unref (connection);
}

/**
 * Gets the current state of the incoming message queue.
 * #DBUS_DISPATCH_DATA_REMAINS indicates that the message queue
 * may contain messages. #DBUS_DISPATCH_COMPLETE indicates that the
 * incoming queue is empty. #DBUS_DISPATCH_NEED_MEMORY indicates that
 * there could be data, but we can't know for sure without more
 * memory.
 *
 * To process the incoming message queue, use dbus_connection_dispatch()
 * or (in rare cases) dbus_connection_pop_message().
 *
 * Note, #DBUS_DISPATCH_DATA_REMAINS really means that either we
 * have messages in the queue, or we have raw bytes buffered up
 * that need to be parsed. When these bytes are parsed, they
 * may not add up to an entire message. Thus, it's possible
 * to see a status of #DBUS_DISPATCH_DATA_REMAINS but not
 * have a message yet.
 *
 * In particular this happens on initial connection, because all sorts
 * of authentication protocol stuff has to be parsed before the
 * first message arrives.
 * 
 * @param connection the connection.
 * @returns current dispatch status
 */
DBusDispatchStatus
dbus_connection_get_dispatch_status (DBusConnection *connection)
{
  DBusDispatchStatus status;

  _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);

  _dbus_verbose ("start\n");
  
  CONNECTION_LOCK (connection);

  status = _dbus_connection_get_dispatch_status_unlocked (connection);
  
  CONNECTION_UNLOCK (connection);

  return status;
}

/**
 * Filter funtion for handling the Peer standard interface.
 */
static DBusHandlerResult
_dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
                                                 DBusMessage    *message)
{
  if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
    {
      /* This means we're letting the bus route this message */
      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    }
  else if (dbus_message_is_method_call (message,
                                        DBUS_INTERFACE_PEER,
                                        "Ping"))
    {
      DBusMessage *ret;
      dbus_bool_t sent;
      
      ret = dbus_message_new_method_return (message);
      if (ret == NULL)
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
     
      sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);

      dbus_message_unref (ret);

      if (!sent)
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
      
      return DBUS_HANDLER_RESULT_HANDLED;
    }
  else if (dbus_message_is_method_call (message,
                                        DBUS_INTERFACE_PEER,
                                        "GetMachineId"))
    {
      DBusMessage *ret;
      dbus_bool_t sent;
      DBusString uuid;
      
      ret = dbus_message_new_method_return (message);
      if (ret == NULL)
        return DBUS_HANDLER_RESULT_NEED_MEMORY;

      sent = FALSE;
      _dbus_string_init (&uuid);
      if (_dbus_get_local_machine_uuid_encoded (&uuid))
        {
          const char *v_STRING = _dbus_string_get_const_data (&uuid);
          if (dbus_message_append_args (ret,
                                        DBUS_TYPE_STRING, &v_STRING,
                                        DBUS_TYPE_INVALID))
            {
              sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
            }
        }
      _dbus_string_free (&uuid);
      
      dbus_message_unref (ret);

      if (!sent)
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
      
      return DBUS_HANDLER_RESULT_HANDLED;
    }
  else if (dbus_message_has_interface (message, DBUS_INTERFACE_PEER))
    {
      /* We need to bounce anything else with this interface, otherwise apps
       * could start extending the interface and when we added extensions
       * here to DBusConnection we'd break those apps.
       */
      
      DBusMessage *ret;
      dbus_bool_t sent;
      
      ret = dbus_message_new_error (message,
                                    DBUS_ERROR_UNKNOWN_METHOD,
                                    "Unknown method invoked on org.freedesktop.DBus.Peer interface");
      if (ret == NULL)
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
      
      sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
      
      dbus_message_unref (ret);
      
      if (!sent)
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
      
      return DBUS_HANDLER_RESULT_HANDLED;
    }
  else
    {
      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
    }
}

/**
* Processes all builtin filter functions
*
* If the spec specifies a standard interface
* they should be processed from this method
**/
static DBusHandlerResult
_dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection,
                                                           DBusMessage    *message)
{
  /* We just run one filter for now but have the option to run more
     if the spec calls for it in the future */

  return _dbus_connection_peer_filter_unlocked_no_update (connection, message);
}

/**
 * Processes any incoming data.
 *
 * If there's incoming raw data that has not yet been parsed, it is
 * parsed, which may or may not result in adding messages to the
 * incoming queue.
 *
 * The incoming data buffer is filled when the connection reads from
 * its underlying transport (such as a socket).  Reading usually
 * happens in dbus_watch_handle() or dbus_connection_read_write().
 * 
 * If there are complete messages in the incoming queue,
 * dbus_connection_dispatch() removes one message from the queue and
 * processes it. Processing has three steps.
 *
 * First, any method replies are passed to #DBusPendingCall or
 * dbus_connection_send_with_reply_and_block() in order to
 * complete the pending method call.
 * 
 * Second, any filters registered with dbus_connection_add_filter()
 * are run. If any filter returns #DBUS_HANDLER_RESULT_HANDLED
 * then processing stops after that filter.
 *
 * Third, if the message is a method call it is forwarded to
 * any registered object path handlers added with
 * dbus_connection_register_object_path() or
 * dbus_connection_register_fallback().
 *
 * A single call to dbus_connection_dispatch() will process at most
 * one message; it will not clear the entire message queue.
 *
 * Be careful about calling dbus_connection_dispatch() from inside a
 * message handler, i.e. calling dbus_connection_dispatch()
 * recursively.  If threads have been initialized with a recursive
 * mutex function, then this will not deadlock; however, it can
 * certainly confuse your application.
 * 
 * @todo some FIXME in here about handling DBUS_HANDLER_RESULT_NEED_MEMORY
 * 
 * @param connection the connection
 * @returns dispatch status, see dbus_connection_get_dispatch_status()
 */
DBusDispatchStatus
dbus_connection_dispatch (DBusConnection *connection)
{
  DBusMessage *message;
  DBusList *link, *filter_list_copy, *message_link;
  DBusHandlerResult result;
  DBusPendingCall *pending;
  dbus_int32_t reply_serial;
  DBusDispatchStatus status;

  _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);

  _dbus_verbose ("\n");
  
  CONNECTION_LOCK (connection);
  status = _dbus_connection_get_dispatch_status_unlocked (connection);
  if (status != DBUS_DISPATCH_DATA_REMAINS)
    {
      /* unlocks and calls out to user code */
      _dbus_connection_update_dispatch_status_and_unlock (connection, status);
      return status;
    }
  
  /* We need to ref the connection since the callback could potentially
   * drop the last ref to it
   */
  _dbus_connection_ref_unlocked (connection);

  _dbus_connection_acquire_dispatch (connection);
  HAVE_LOCK_CHECK (connection);

  message_link = _dbus_connection_pop_message_link_unlocked (connection);
  if (message_link == NULL)
    {
      /* another thread dispatched our stuff */

      _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
      
      _dbus_connection_release_dispatch (connection);

      status = _dbus_connection_get_dispatch_status_unlocked (connection);

      _dbus_connection_update_dispatch_status_and_unlock (connection, status);
      
      dbus_connection_unref (connection);
      
      return status;
    }

  message = message_link->data;

  _dbus_verbose (" dispatching message %p (%s %s %s '%s')\n",
                 message,
                 dbus_message_type_to_string (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;
  
  /* Pending call handling must be first, because if you do
   * dbus_connection_send_with_reply_and_block() or
   * dbus_pending_call_block() then no handlers/filters will be run on
   * the reply. We want consistent semantics in the case where we
   * dbus_connection_dispatch() the reply.
   */
  
  reply_serial = dbus_message_get_reply_serial (message);
  pending = _dbus_hash_table_lookup_int (connection->pending_replies,
                                         reply_serial);
  if (pending)
    {
      _dbus_verbose ("Dispatching a pending reply\n");
      complete_pending_call_and_unlock (connection, pending, message);
      pending = NULL; /* it's probably unref'd */
      
      CONNECTION_LOCK (connection);
      _dbus_verbose ("pending call completed in dispatch\n");
      result = DBUS_HANDLER_RESULT_HANDLED;
      goto out;
    }

  result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message);
  if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
    goto out;
 
  if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
    {
      _dbus_connection_release_dispatch (connection);
      HAVE_LOCK_CHECK (connection);
      
      _dbus_connection_failed_pop (connection, message_link);

      /* unlocks and calls user code */
      _dbus_connection_update_dispatch_status_and_unlock (connection,
                                                          DBUS_DISPATCH_NEED_MEMORY);
      dbus_connection_unref (connection);
      
      return DBUS_DISPATCH_NEED_MEMORY;
    }
  
  _dbus_list_foreach (&filter_list_copy,
		      (DBusForeachFunction)_dbus_message_filter_ref,
		      NULL);

  /* We're still protected from dispatch() reentrancy here
   * since we acquired the dispatcher
   */
  CONNECTION_UNLOCK (connection);
  
  link = _dbus_list_get_first_link (&filter_list_copy);
  while (link != NULL)
    {
      DBusMessageFilter *filter = link->data;
      DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);

      if (filter->function == NULL)
        {
          _dbus_verbose ("  filter was removed in a callback function\n");
          link = next;
          continue;
        }

      _dbus_verbose ("  running filter on message %p\n", message);
      result = (* filter->function) (connection, message, filter->user_data);

      if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
	break;

      link = next;
    }

  _dbus_list_foreach (&filter_list_copy,
		      (DBusForeachFunction)_dbus_message_filter_unref,
		      NULL);
  _dbus_list_clear (&filter_list_copy);
  
  CONNECTION_LOCK (connection);

  if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
    {
      _dbus_verbose ("No memory\n");
      goto out;
    }
  else if (result == DBUS_HANDLER_RESULT_HANDLED)
    {
      _dbus_verbose ("filter handled message 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 (%s %s %s '%s')\n",
                 message,
                 dbus_message_type_to_string (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));

  HAVE_LOCK_CHECK (connection);
  result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
                                                  message);
  
  CONNECTION_LOCK (connection);

  if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
    {
      _dbus_verbose ("object tree handled message in dispatch\n");
      goto out;
    }

  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
    {
      DBusMessage *reply;
      DBusString str;
      DBusPreallocatedSend *preallocated;

      _dbus_verbose ("  sending error %s\n",
                     DBUS_ERROR_UNKNOWN_METHOD);
      
      if (!_dbus_string_init (&str))
        {
          result = DBUS_HANDLER_RESULT_NEED_MEMORY;
          _dbus_verbose ("no memory for error string in dispatch\n");
          goto out;
        }
              
      if (!_dbus_string_append_printf (&str,
                                       "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
                                       dbus_message_get_member (message),
                                       dbus_message_get_signature (message),
                                       dbus_message_get_interface (message)))
        {
          _dbus_string_free (&str);
          result = DBUS_HANDLER_RESULT_NEED_MEMORY;
          _dbus_verbose ("no memory for error string in dispatch\n");
          goto out;
        }
      
      reply = dbus_message_new_error (message,
                                      DBUS_ERROR_UNKNOWN_METHOD,
                                      _dbus_string_get_const_data (&str));
      _dbus_string_free (&str);

      if (reply == NULL)
        {
          result = DBUS_HANDLER_RESULT_NEED_MEMORY;
          _dbus_verbose ("no memory for error reply in dispatch\n");
          goto out;
        }
      
      preallocated = _dbus_connection_preallocate_send_unlocked (connection);

      if (preallocated == NULL)
        {
          dbus_message_unref (reply);
          result = DBUS_HANDLER_RESULT_NEED_MEMORY;
          _dbus_verbose ("no memory for error send in dispatch\n");
          goto out;
        }

      _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
                                                             reply, NULL);

      dbus_message_unref (reply);
      
      result = DBUS_HANDLER_RESULT_HANDLED;
    }
  
  _dbus_verbose ("  done dispatching %p (%s %s %s '%s') on connection %p\n", message,
                 dbus_message_type_to_string (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);
  
 out:
  if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
    {
      _dbus_verbose ("out of memory\n");
      
      /* Put message back, and we'll start over.
       * Yes this means handlers must be idempotent if they
       * don't return HANDLED; c'est la vie.
       */
      _dbus_connection_putback_message_link_unlocked (connection,
                                                      message_link);
    }
  else
    {
      _dbus_verbose (" ... done dispatching\n");
      
      _dbus_list_free_link (message_link);
      dbus_message_unref (message); /* don't want the message to count in max message limits
                                     * in computing dispatch status below
                                     */
    }
  
  _dbus_connection_release_dispatch (connection);
  HAVE_LOCK_CHECK (connection);

  _dbus_verbose ("before final status update\n");
  status = _dbus_connection_get_dispatch_status_unlocked (connection);

  /* unlocks and calls user code */
  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
  
  dbus_connection_unref (connection);
  
  return status;
}

/**
 * Sets the watch functions for the connection. These functions are
 * responsible for making the application's main loop aware of file
 * descriptors that need to be monitored for events, using select() or
 * poll(). When using Qt, typically the DBusAddWatchFunction would
 * create a QSocketNotifier. When using GLib, the DBusAddWatchFunction
 * could call g_io_add_watch(), or could be used as part of a more
 * elaborate GSource. Note that when a watch is added, it may
 * not be enabled.
 *
 * The DBusWatchToggledFunction notifies the application that the
 * watch has been enabled or disabled. Call dbus_watch_get_enabled()
 * to check this. A disabled watch should have no effect, and enabled
 * watch should be added to the main loop. This feature is used
 * instead of simply adding/removing the watch because
 * enabling/disabling can be done without memory allocation.  The
 * toggled function may be NULL if a main loop re-queries
 * dbus_watch_get_enabled() every time anyway.
 * 
 * The DBusWatch can be queried for the file descriptor to watch using
 * dbus_watch_get_unix_fd() or dbus_watch_get_socket(), and for the
 * events to watch for using dbus_watch_get_flags(). The flags
 * returned by dbus_watch_get_flags() will only contain
 * DBUS_WATCH_READABLE and DBUS_WATCH_WRITABLE, never
 * DBUS_WATCH_HANGUP or DBUS_WATCH_ERROR; all watches implicitly
 * include a watch for hangups, errors, and other exceptional
 * conditions.
 *
 * Once a file descriptor becomes readable or writable, or an exception
 * occurs, dbus_watch_handle() should be called to
 * notify the connection of the file descriptor's condition.
 *
 * dbus_watch_handle() cannot be called during the
 * DBusAddWatchFunction, as the connection will not be ready to handle
 * that watch yet.
 * 
 * It is not allowed to reference a DBusWatch after it has been passed
 * to remove_function.
 *
 * If #FALSE is returned due to lack of memory, the failure may be due
 * to a #FALSE return from the new add_function. If so, the
 * add_function may have been called successfully one or more times,
 * but the remove_function will also have been called to remove any
 * successful adds. i.e. if #FALSE is returned the net result
 * should be that dbus_connection_set_watch_functions() has no effect,
 * but the add_function and remove_function may have been called.
 *
 * @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.
 * @param remove_function function to stop monitoring a descriptor.
 * @param toggled_function function to notify of enable/disable
 * @param data data to pass to add_function and remove_function.
 * @param free_data_function function to be called to free the data.
 * @returns #FALSE on failure (no memory)
 */
dbus_bool_t
dbus_connection_set_watch_functions (DBusConnection              *connection,
                                     DBusAddWatchFunction         add_function,
                                     DBusRemoveWatchFunction      remove_function,
                                     DBusWatchToggledFunction     toggled_function,
                                     void                        *data,
                                     DBusFreeFunction             free_data_function)
{
  dbus_bool_t retval;

  _dbus_return_val_if_fail (connection != NULL, FALSE);
  
  CONNECTION_LOCK (connection);

  retval = _dbus_watch_list_set_functions (connection->watches,
                                           add_function, remove_function,
                                           toggled_function,
                                           data, free_data_function);

  CONNECTION_UNLOCK (connection);

  return retval;
}

/**
 * Sets the timeout functions for the connection. These functions are
 * responsible for making the application's main loop aware of timeouts.
 * When using Qt, typically the DBusAddTimeoutFunction would create a
 * QTimer. When using GLib, the DBusAddTimeoutFunction would call
 * g_timeout_add.
 * 
 * The DBusTimeoutToggledFunction notifies the application that the
 * timeout has been enabled or disabled. Call
 * dbus_timeout_get_enabled() to check this. A disabled timeout should
 * have no effect, and enabled timeout should be added to the main
 * loop. This feature is used instead of simply adding/removing the
 * timeout because enabling/disabling can be done without memory
 * allocation. With Qt, QTimer::start() and QTimer::stop() can be used
 * to enable and disable. The toggled function may be NULL if a main
 * loop re-queries dbus_timeout_get_enabled() every time anyway.
 * Whenever a timeout is toggled, its interval may change.
 *
 * The DBusTimeout can be queried for the timer interval using
 * dbus_timeout_get_interval(). dbus_timeout_handle() should be called
 * repeatedly, each time the interval elapses, starting after it has
 * elapsed once. The timeout stops firing when it is removed with the
 * 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.
 * @param toggled_function function to notify of enable/disable
 * @param data data to pass to add_function and remove_function.
 * @param free_data_function function to be called to free the data.
 * @returns #FALSE on failure (no memory)
 */
dbus_bool_t
dbus_connection_set_timeout_functions   (DBusConnection            *connection,
					 DBusAddTimeoutFunction     add_function,
					 DBusRemoveTimeoutFunction  remove_function,
                                         DBusTimeoutToggledFunction toggled_function,
					 void                      *data,
					 DBusFreeFunction           free_data_function)
{
  dbus_bool_t retval;

  _dbus_return_val_if_fail (connection != NULL, FALSE);
  
  CONNECTION_LOCK (connection);

  retval = _dbus_timeout_list_set_functions (connection->timeouts,
                                             add_function, remove_function,
                                             toggled_function,
                                             data, free_data_function);

  CONNECTION_UNLOCK (connection);

  return retval;
}

/**
 * Sets the mainloop wakeup function for the connection. This function
 * is responsible for waking up the main loop (if its sleeping in
 * another thread) when some some change has happened to the
 * connection that the mainloop needs to reconsider (e.g. a message
 * has been queued for writing).  When using Qt, this typically
 * results in a call to QEventLoop::wakeUp().  When using GLib, it
 * would call g_main_context_wakeup().
 *
 * @param connection the connection.
 * @param wakeup_main_function function to wake up the mainloop
 * @param data data to pass wakeup_main_function
 * @param free_data_function function to be called to free the data.
 */
void
dbus_connection_set_wakeup_main_function (DBusConnection            *connection,
					  DBusWakeupMainFunction     wakeup_main_function,
					  void                      *data,
					  DBusFreeFunction           free_data_function)
{
  void *old_data;
  DBusFreeFunction old_free_data;

  _dbus_return_if_fail (connection != NULL);
  
  CONNECTION_LOCK (connection);
  old_data = connection->wakeup_main_data;
  old_free_data = connection->free_wakeup_main_data;

  connection->wakeup_main_function = wakeup_main_function;
  connection->wakeup_main_data = data;
  connection->free_wakeup_main_data = free_data_function;
  
  CONNECTION_UNLOCK (connection);

  /* Callback outside the lock */
  if (old_free_data)
    (*old_free_data) (old_data);
}

/**
 * Set a function to be invoked when the dispatch status changes.
 * If the dispatch status is #DBUS_DISPATCH_DATA_REMAINS, then
 * dbus_connection_dispatch() needs to be called to process incoming
 * messages. However, dbus_connection_dispatch() MUST NOT BE CALLED
 * from inside the DBusDispatchStatusFunction. Indeed, almost
 * any reentrancy in this function is a bad idea. Instead,
 * the DBusDispatchStatusFunction should simply save an indication
 * that messages should be dispatched later, when the main loop
 * is re-entered.
 *
 * If you don't set a dispatch status function, you have to be sure to
 * dispatch on every iteration of your main loop, especially if
 * dbus_watch_handle() or dbus_timeout_handle() were called.
 *
 * @param connection the connection
 * @param function function to call on dispatch status changes
 * @param data data for function
 * @param free_data_function free the function data
 */
void
dbus_connection_set_dispatch_status_function (DBusConnection             *connection,
                                              DBusDispatchStatusFunction  function,
                                              void                       *data,
                                              DBusFreeFunction            free_data_function)
{
  void *old_data;
  DBusFreeFunction old_free_data;

  _dbus_return_if_fail (connection != NULL);
  
  CONNECTION_LOCK (connection);
  old_data = connection->dispatch_status_data;
  old_free_data = connection->free_dispatch_status_data;

  connection->dispatch_status_function = function;
  connection->dispatch_status_data = data;
  connection->free_dispatch_status_data = free_data_function;
  
  CONNECTION_UNLOCK (connection);

  /* Callback outside the lock */
  if (old_free_data)
    (*old_free_data) (old_data);
}

/**
 * Get the UNIX file descriptor of the connection, if any.  This can
 * be used for SELinux access control checks with getpeercon() for
 * example. DO NOT read or write to the file descriptor, or try to
 * select() on it; use DBusWatch for main loop integration. Not all
 * connections will have a file descriptor. So for adding descriptors
 * to the main loop, use dbus_watch_get_unix_fd() and so forth.
 *
 * If the connection is socket-based, you can also use
 * dbus_connection_get_socket(), which will work on Windows too.
 * This function always fails on Windows.
 *
 * Right now the returned descriptor is always a socket, but
 * that is not guaranteed.
 * 
 * @param connection the connection
 * @param fd return location for the file descriptor.
 * @returns #TRUE if fd is successfully obtained.
 */
dbus_bool_t
dbus_connection_get_unix_fd (DBusConnection *connection,
                             int            *fd)
{
  _dbus_return_val_if_fail (connection != NULL, FALSE);
  _dbus_return_val_if_fail (connection->transport != NULL, FALSE);

#ifdef DBUS_WIN
  /* FIXME do this on a lower level */
  return FALSE;
#endif
  
  return dbus_connection_get_socket(connection, fd);
}

/**
 * Gets the underlying Windows or UNIX socket file descriptor
 * of the connection, if any. DO NOT read or write to the file descriptor, or try to
 * select() on it; use DBusWatch for main loop integration. Not all
 * connections will have a socket. So for adding descriptors
 * to the main loop, use dbus_watch_get_socket() and so forth.
 *
 * If the connection is not socket-based, this function will return FALSE,
 * even if the connection does have a file descriptor of some kind.
 * i.e. this function always returns specifically a socket file descriptor.
 * 
 * @param connection the connection
 * @param fd return location for the file descriptor.
 * @returns #TRUE if fd is successfully obtained.
 */
dbus_bool_t
dbus_connection_get_socket(DBusConnection              *connection,
                           int                         *fd)
{
  dbus_bool_t retval;

  _dbus_return_val_if_fail (connection != NULL, FALSE);
  _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
  
  CONNECTION_LOCK (connection);
  
  retval = _dbus_transport_get_socket_fd (connection->transport,
                                          fd);

  CONNECTION_UNLOCK (connection);

  return retval;
}


/**
 * Gets the UNIX user ID of the connection if known.  Returns #TRUE if
 * the uid is filled in.  Always returns #FALSE on non-UNIX platforms
 * for now, though in theory someone could hook Windows to NIS or
 * something.  Always returns #FALSE prior to authenticating the
 * connection.
 *
 * The UID is only read by servers from clients; clients can't usually
 * get the UID of servers, because servers do not authenticate to
 * clients.  The returned UID is the UID the connection authenticated
 * as.
 *
 * The message bus is a server and the apps connecting to the bus
 * are clients.
 *
 * You can ask the bus to tell you the UID of another connection though
 * if you like; this is done with dbus_bus_get_unix_user().
 *
 * @param connection the connection
 * @param uid return location for the user ID
 * @returns #TRUE if uid is filled in with a valid user ID
 */
dbus_bool_t
dbus_connection_get_unix_user (DBusConnection *connection,
                               unsigned long  *uid)
{
  dbus_bool_t result;

  _dbus_return_val_if_fail (connection != NULL, FALSE);
  _dbus_return_val_if_fail (uid != NULL, FALSE);
  
  CONNECTION_LOCK (connection);

  if (!_dbus_transport_get_is_authenticated (connection->transport))
    result = FALSE;
  else
    result = _dbus_transport_get_unix_user (connection->transport,
                                            uid);

#ifdef DBUS_WIN
  _dbus_assert (!result);
#endif
  
  CONNECTION_UNLOCK (connection);

  return result;
}

/**
 * Gets the process ID of the connection if any.
 * Returns #TRUE if the pid is filled in.
 * Always returns #FALSE prior to authenticating the
 * connection.
 *
 * @param connection the connection
 * @param pid return location for the process ID
 * @returns #TRUE if uid is filled in with a valid process ID
 */
dbus_bool_t
dbus_connection_get_unix_process_id (DBusConnection *connection,
				     unsigned long  *pid)
{
  dbus_bool_t result;

  _dbus_return_val_if_fail (connection != NULL, FALSE);
  _dbus_return_val_if_fail (pid != NULL, FALSE);
  
  CONNECTION_LOCK (connection);

  if (!_dbus_transport_get_is_authenticated (connection->transport))
    result = FALSE;
  else
    result = _dbus_transport_get_unix_process_id (connection->transport,
						  pid);

  CONNECTION_UNLOCK (connection);

  return result;
}

/**
 * Gets the ADT audit data of the connection if any.
 * Returns #TRUE if the structure pointer is returned.
 * Always returns #FALSE prior to authenticating the
 * connection.
 *
 * @param connection the connection
 * @param data return location for audit data 
 * @returns #TRUE if audit data is filled in with a valid ucred pointer
 */
dbus_bool_t
dbus_connection_get_adt_audit_session_data (DBusConnection *connection,
					    void          **data,
					    dbus_int32_t   *data_size)
{
  dbus_bool_t result;

  _dbus_return_val_if_fail (connection != NULL, FALSE);
  _dbus_return_val_if_fail (data != NULL, FALSE);
  _dbus_return_val_if_fail (data_size != NULL, FALSE);
  
  CONNECTION_LOCK (connection);

  if (!_dbus_transport_get_is_authenticated (connection->transport))
    result = FALSE;
  else
    result = _dbus_transport_get_adt_audit_session_data (connection->transport,
					    	         data,
			  			         data_size);
  CONNECTION_UNLOCK (connection);

  return result;
}

/**
 * Sets a predicate function used to determine whether a given user ID
 * is allowed to connect. When an incoming connection has
 * authenticated with a particular user ID, this function is called;
 * if it returns #TRUE, the connection is allowed to proceed,
 * otherwise the connection is disconnected.
 *
 * If the function is set to #NULL (as it is by default), then
 * only the same UID as the server process will be allowed to
 * connect. Also, root is always allowed to connect.
 *
 * On Windows, the function will be set and its free_data_function will
 * be invoked when the connection is freed or a new function is set.
 * However, the function will never be called, because there are
 * no UNIX user ids to pass to it, or at least none of the existing
 * auth protocols would allow authenticating as a UNIX user on Windows.
 * 
 * @param connection the connection
 * @param function the predicate
 * @param data data to pass to the predicate
 * @param free_data_function function to free the data
 */
void
dbus_connection_set_unix_user_function (DBusConnection             *connection,
                                        DBusAllowUnixUserFunction   function,
                                        void                       *data,
                                        DBusFreeFunction            free_data_function)
{
  void *old_data = NULL;
  DBusFreeFunction old_free_function = NULL;

  _dbus_return_if_fail (connection != NULL);
  
  CONNECTION_LOCK (connection);
  _dbus_transport_set_unix_user_function (connection->transport,
                                          function, data, free_data_function,
                                          &old_data, &old_free_function);
  CONNECTION_UNLOCK (connection);

  if (old_free_function != NULL)
    (* old_free_function) (old_data);
}

/**
 * Gets the Windows user SID of the connection if known.  Returns
 * #TRUE if the ID is filled in.  Always returns #FALSE on non-Windows
 * platforms for now, though in theory someone could hook UNIX to
 * Active Directory or something.  Always returns #FALSE prior to
 * authenticating the connection.
 *
 * The user is only read by servers from clients; clients can't usually
 * get the user of servers, because servers do not authenticate to
 * clients. The returned user is the user the connection authenticated
 * as.
 *
 * The message bus is a server and the apps connecting to the bus
 * are clients.
 *
 * The returned user string has to be freed with dbus_free().
 *
 * The return value indicates whether the user SID is available;
 * if it's available but we don't have the memory to copy it,
 * then the return value is #TRUE and #NULL is given as the SID.
 * 
 * @todo We would like to be able to say "You can ask the bus to tell
 * you the user of another connection though if you like; this is done
 * with dbus_bus_get_windows_user()." But this has to be implemented
 * in bus/driver.c and dbus/dbus-bus.c, and is pointless anyway
 * since on Windows we only use the session bus for now.
 *
 * @param connection the connection
 * @param windows_sid_p return location for an allocated copy of the user ID, or #NULL if no memory
 * @returns #TRUE if user is available (returned value may be #NULL anyway if no memory)
 */
dbus_bool_t
dbus_connection_get_windows_user (DBusConnection             *connection,
                                  char                      **windows_sid_p)
{
  dbus_bool_t result;

  _dbus_return_val_if_fail (connection != NULL, FALSE);
  _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
  
  CONNECTION_LOCK (connection);

  if (!_dbus_transport_get_is_authenticated (connection->transport))
    result = FALSE;
  else
    result = _dbus_transport_get_windows_user (connection->transport,
                                               windows_sid_p);

#ifdef DBUS_UNIX
  _dbus_assert (!result);
#endif
  
  CONNECTION_UNLOCK (connection);

  return result;
}

/**
 * Sets a predicate function used to determine whether a given user ID
 * is allowed to connect. When an incoming connection has
 * authenticated with a particular user ID, this function is called;
 * if it returns #TRUE, the connection is allowed to proceed,
 * otherwise the connection is disconnected.
 *
 * If the function is set to #NULL (as it is by default), then
 * only the same user owning the server process will be allowed to
 * connect.
 *
 * On UNIX, the function will be set and its free_data_function will
 * be invoked when the connection is freed or a new function is set.
 * However, the function will never be called, because there is no
 * way right now to authenticate as a Windows user on UNIX.
 * 
 * @param connection the connection
 * @param function the predicate
 * @param data data to pass to the predicate
 * @param free_data_function function to free the data
 */
void
dbus_connection_set_windows_user_function (DBusConnection              *connection,
                                           DBusAllowWindowsUserFunction function,
                                           void                        *data,
                                           DBusFreeFunction             free_data_function)
{
  void *old_data = NULL;
  DBusFreeFunction old_free_function = NULL;

  _dbus_return_if_fail (connection != NULL);
  
  CONNECTION_LOCK (connection);
  _dbus_transport_set_windows_user_function (connection->transport,
                                             function, data, free_data_function,
                                             &old_data, &old_free_function);
  CONNECTION_UNLOCK (connection);

  if (old_free_function != NULL)
    (* old_free_function) (old_data);
}

/**
 * This function must be called on the server side of a connection when the
 * connection is first seen in the #DBusNewConnectionFunction. If set to
 * #TRUE (the default is #FALSE), then the connection can proceed even if
 * the client does not authenticate as some user identity, i.e. clients
 * can connect anonymously.
 * 
 * This setting interacts with the available authorization mechanisms
 * (see dbus_server_set_auth_mechanisms()). Namely, an auth mechanism
 * such as ANONYMOUS that supports anonymous auth must be included in
 * the list of available mechanisms for anonymous login to work.
 *
 * This setting also changes the default rule for connections
 * authorized as a user; normally, if a connection authorizes as
 * a user identity, it is permitted if the user identity is
 * root or the user identity matches the user identity of the server
 * process. If anonymous connections are allowed, however,
 * then any user identity is allowed.
 *
 * You can override the rules for connections authorized as a
 * user identity with dbus_connection_set_unix_user_function()
 * and dbus_connection_set_windows_user_function().
 * 
 * @param connection the connection
 * @param value whether to allow authentication as an anonymous user
 */
void
dbus_connection_set_allow_anonymous (DBusConnection             *connection,
                                     dbus_bool_t                 value)
{
  _dbus_return_if_fail (connection != NULL);
  
  CONNECTION_LOCK (connection);
  _dbus_transport_set_allow_anonymous (connection->transport, value);
  CONNECTION_UNLOCK (connection);
}

/**
 *
 * Normally #DBusConnection automatically handles all messages to the
 * org.freedesktop.DBus.Peer interface. However, the message bus wants
 * to be able to route methods on that interface through the bus and
 * to other applications. If routing peer messages is enabled, then
 * messages with the org.freedesktop.DBus.Peer interface that also
 * have a bus destination name set will not be automatically
 * handled by the #DBusConnection and instead will be dispatched
 * normally to the application.
 *
 * If a normal application sets this flag, it can break things badly.
 * So don't set this unless you are the message bus.
 *
 * @param connection the connection
 * @param value #TRUE to pass through org.freedesktop.DBus.Peer messages with a bus name set
 */
void
dbus_connection_set_route_peer_messages (DBusConnection             *connection,
                                         dbus_bool_t                 value)
{
  _dbus_return_if_fail (connection != NULL);
  
  CONNECTION_LOCK (connection);
  connection->route_peer_messages = TRUE;
  CONNECTION_UNLOCK (connection);
}

/**
 * Adds a message filter. Filters are handlers that are run on all
 * incoming messages, prior to the objects registered with
 * dbus_connection_register_object_path().  Filters are run in the
 * order that they were added.  The same handler can be added as a
 * filter more than once, in which case it will be run more than once.
 * Filters added during a filter callback won't be run on the message
 * being processed.
 *
 * @todo we don't run filters on messages while blocking without
 * entering the main loop, since filters are run as part of
 * dbus_connection_dispatch(). This is probably a feature, as filters
 * could create arbitrary reentrancy. But kind of sucks if you're
 * trying to filter METHOD_RETURN for some reason.
 *
 * @param connection the connection
 * @param function function to handle messages
 * @param user_data user data to pass to the function
 * @param free_data_function function to use for freeing user data
 * @returns #TRUE on success, #FALSE if not enough memory.
 */
dbus_bool_t
dbus_connection_add_filter (DBusConnection            *connection,
                            DBusHandleMessageFunction  function,
                            void                      *user_data,
                            DBusFreeFunction           free_data_function)
{
  DBusMessageFilter *filter;
  
  _dbus_return_val_if_fail (connection != NULL, FALSE);
  _dbus_return_val_if_fail (function != NULL, FALSE);

  filter = dbus_new0 (DBusMessageFilter, 1);
  if (filter == NULL)
    return FALSE;

  filter->refcount.value = 1;
  
  CONNECTION_LOCK (connection);

  if (!_dbus_list_append (&connection->filter_list,
                          filter))
    {
      _dbus_message_filter_unref (filter);
      CONNECTION_UNLOCK (connection);
      return FALSE;
    }

  /* Fill in filter after all memory allocated,
   * so we don't run the free_user_data_function
   * if the add_filter() fails
   */
  
  filter->function = function;
  filter->user_data = user_data;
  filter->free_user_data_function = free_data_function;
        
  CONNECTION_UNLOCK (connection);
  return TRUE;
}

/**
 * Removes a previously-added message filter. It is a programming
 * error to call this function for a handler that has not been added
 * as a filter. If the given handler was added more than once, only
 * one instance of it will be removed (the most recently-added
 * instance).
 *
 * @param connection the connection
 * @param function the handler to remove
 * @param user_data user data for the handler to remove
 *
 */
void
dbus_connection_remove_filter (DBusConnection            *connection,
                               DBusHandleMessageFunction  function,
                               void                      *user_data)
{
  DBusList *link;
  DBusMessageFilter *filter;
  
  _dbus_return_if_fail (connection != NULL);
  _dbus_return_if_fail (function != NULL);
  
  CONNECTION_LOCK (connection);

  filter = NULL;
  
  link = _dbus_list_get_last_link (&connection->filter_list);
  while (link != NULL)
    {
      filter = link->data;

      if (filter->function == function &&
          filter->user_data == user_data)
        {
          _dbus_list_remove_link (&connection->filter_list, link);
          filter->function = NULL;
          
          break;
        }
        
      link = _dbus_list_get_prev_link (&connection->filter_list, link);
      filter = NULL;
    }
  
  CONNECTION_UNLOCK (connection);

#ifndef DBUS_DISABLE_CHECKS
  if (filter == NULL)
    {
      _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
                               function, user_data);
      return;
    }
#endif
  
  /* Call application code */
  if (filter->free_user_data_function)
    (* filter->free_user_data_function) (filter->user_data);

  filter->free_user_data_function = NULL;
  filter->user_data = NULL;
  
  _dbus_message_filter_unref (filter);
}

/**
 * Registers a handler for a given path in the object hierarchy.
 * The given vtable handles messages sent to exactly the given path.
 *
 * @param connection the connection
 * @param path a '/' delimited string of path elements
 * @param vtable the virtual table
 * @param user_data data to pass to functions in the vtable
 * @param error address where an error can be returned
 * @returns #FALSE if an error (#DBUS_ERROR_NO_MEMORY or
 *    #DBUS_ERROR_ADDRESS_IN_USE) is reported
 */
dbus_bool_t
dbus_connection_try_register_object_path (DBusConnection              *connection,
                                          const char                  *path,
                                          const DBusObjectPathVTable  *vtable,
                                          void                        *user_data,
                                          DBusError                   *error)
{
  char **decomposed_path;
  dbus_bool_t retval;
  
  _dbus_return_val_if_fail (connection != NULL, FALSE);
  _dbus_return_val_if_fail (path != NULL, FALSE);
  _dbus_return_val_if_fail (path[0] == '/', FALSE);
  _dbus_return_val_if_fail (vtable != NULL, FALSE);

  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
    return FALSE;

  CONNECTION_LOCK (connection);

  retval = _dbus_object_tree_register (connection->objects,
                                       FALSE,
                                       (const char **) decomposed_path, vtable,
                                       user_data, error);

  CONNECTION_UNLOCK (connection);

  dbus_free_string_array (decomposed_path);

  return retval;
}

/**
 * Registers a handler for a given path in the object hierarchy.
 * The given vtable handles messages sent to exactly the given path.
 *
 * It is a bug to call this function for object paths which already
 * have a handler. Use dbus_connection_try_register_object_path() if this
 * might be the case.
 *
 * @param connection the connection
 * @param path a '/' delimited string of path elements
 * @param vtable the virtual table
 * @param user_data data to pass to functions in the vtable
 * @returns #FALSE if not enough memory
 */
dbus_bool_t
dbus_connection_register_object_path (DBusConnection              *connection,
                                      const char                  *path,
                                      const DBusObjectPathVTable  *vtable,
                                      void                        *user_data)
{
  char **decomposed_path;
  dbus_bool_t retval;
  DBusError error = DBUS_ERROR_INIT;

  _dbus_return_val_if_fail (connection != NULL, FALSE);
  _dbus_return_val_if_fail (path != NULL, FALSE);
  _dbus_return_val_if_fail (path[0] == '/', FALSE);
  _dbus_return_val_if_fail (vtable != NULL, FALSE);

  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
    return FALSE;

  CONNECTION_LOCK (connection);

  retval = _dbus_object_tree_register (connection->objects,
                                       FALSE,
                                       (const char **) decomposed_path, vtable,
                                       user_data, &error);

  CONNECTION_UNLOCK (connection);

  dbus_free_string_array (decomposed_path);

  if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE))
    {
      _dbus_warn ("%s\n", error.message);
      dbus_error_free (&error);
      return FALSE;
    }

  return retval;
}

/**
 * Registers a fallback handler for a given subsection of the object
 * hierarchy.  The given vtable handles messages at or below the given
 * path. You can use this to establish a default message handling
 * policy for a whole "subdirectory."
 *
 * @param connection the connection
 * @param path a '/' delimited string of path elements
 * @param vtable the virtual table
 * @param user_data data to pass to functions in the vtable
 * @param error address where an error can be returned
 * @returns #FALSE if an error (#DBUS_ERROR_NO_MEMORY or
 *    #DBUS_ERROR_ADDRESS_IN_USE) is reported
 */
dbus_bool_t
dbus_connection_try_register_fallback (DBusConnection              *connection,
                                       const char                  *path,
                                       const DBusObjectPathVTable  *vtable,
                                       void                        *user_data,
                                       DBusError                   *error)
{
  char **decomposed_path;
  dbus_bool_t retval;

  _dbus_return_val_if_fail (connection != NULL, FALSE);
  _dbus_return_val_if_fail (path != NULL, FALSE);
  _dbus_return_val_if_fail (path[0] == '/', FALSE);
  _dbus_return_val_if_fail (vtable != NULL, FALSE);

  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
    return FALSE;

  CONNECTION_LOCK (connection);

  retval = _dbus_object_tree_register (connection->objects,
                                       TRUE,
                                       (const char **) decomposed_path, vtable,
                                       user_data, error);

  CONNECTION_UNLOCK (connection);

  dbus_free_string_array (decomposed_path);

  return retval;
}

/**
 * Registers a fallback handler for a given subsection of the object
 * hierarchy.  The given vtable handles messages at or below the given
 * path. You can use this to establish a default message handling
 * policy for a whole "subdirectory."
 *
 * It is a bug to call this function for object paths which already
 * have a handler. Use dbus_connection_try_register_fallback() if this
 * might be the case.
 *
 * @param connection the connection
 * @param path a '/' delimited string of path elements
 * @param vtable the virtual table
 * @param user_data data to pass to functions in the vtable
 * @returns #FALSE if not enough memory
 */
dbus_bool_t
dbus_connection_register_fallback (DBusConnection              *connection,
                                   const char                  *path,
                                   const DBusObjectPathVTable  *vtable,
                                   void                        *user_data)
{
  char **decomposed_path;
  dbus_bool_t retval;
  DBusError error = DBUS_ERROR_INIT;

  _dbus_return_val_if_fail (connection != NULL, FALSE);
  _dbus_return_val_if_fail (path != NULL, FALSE);
  _dbus_return_val_if_fail (path[0] == '/', FALSE);
  _dbus_return_val_if_fail (vtable != NULL, FALSE);

  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
    return FALSE;

  CONNECTION_LOCK (connection);

  retval = _dbus_object_tree_register (connection->objects,
                                       TRUE,
				       (const char **) decomposed_path, vtable,
                                       user_data, &error);

  CONNECTION_UNLOCK (connection);

  dbus_free_string_array (decomposed_path);

  if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE))
    {
      _dbus_warn ("%s\n", error.message);
      dbus_error_free (&error);
      return FALSE;
    }

  return retval;
}

/**
 * Unregisters the handler registered with exactly the given path.
 * It's a bug to call this function for a path that isn't registered.
 * Can unregister both fallback paths and object paths.
 *
 * @param connection the connection
 * @param path a '/' delimited string of path elements
 * @returns #FALSE if not enough memory
 */
dbus_bool_t
dbus_connection_unregister_object_path (DBusConnection              *connection,
                                        const char                  *path)
{
  char **decomposed_path;

  _dbus_return_val_if_fail (connection != NULL, FALSE);
  _dbus_return_val_if_fail (path != NULL, FALSE);
  _dbus_return_val_if_fail (path[0] == '/', FALSE);

  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
      return FALSE;

  CONNECTION_LOCK (connection);

  _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);

  dbus_free_string_array (decomposed_path);

  return TRUE;
}

/**
 * Gets the user data passed to dbus_connection_register_object_path()
 * or dbus_connection_register_fallback(). If nothing was registered
 * at this path, the data is filled in with #NULL.
 *
 * @param connection the connection
 * @param path the path you registered with
 * @param data_p location to store the user data, or #NULL
 * @returns #FALSE if not enough memory
 */
dbus_bool_t
dbus_connection_get_object_path_data (DBusConnection *connection,
                                      const char     *path,
                                      void          **data_p)
{
  char **decomposed_path;

  _dbus_return_val_if_fail (connection != NULL, FALSE);
  _dbus_return_val_if_fail (path != NULL, FALSE);
  _dbus_return_val_if_fail (data_p != NULL, FALSE);

  *data_p = NULL;
  
  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
    return FALSE;
  
  CONNECTION_LOCK (connection);

  *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path);

  CONNECTION_UNLOCK (connection);

  dbus_free_string_array (decomposed_path);

  return TRUE;
}

/**
 * Lists the registered fallback handlers and object path handlers at
 * the given parent_path. The returned array should be freed with
 * dbus_free_string_array().
 *
 * @param connection the connection
 * @param parent_path the path to list the child handlers of
 * @param child_entries returns #NULL-terminated array of children
 * @returns #FALSE if no memory to allocate the child entries
 */
dbus_bool_t
dbus_connection_list_registered (DBusConnection              *connection,
                                 const char                  *parent_path,
                                 char                      ***child_entries)
{
  char **decomposed_path;
  dbus_bool_t retval;
  _dbus_return_val_if_fail (connection != NULL, FALSE);
  _dbus_return_val_if_fail (parent_path != NULL, FALSE);
  _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
  _dbus_return_val_if_fail (child_entries != NULL, FALSE);

  if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
    return FALSE;

  CONNECTION_LOCK (connection);

  retval = _dbus_object_tree_list_registered_and_unlock (connection->objects,
							 (const char **) decomposed_path,
							 child_entries);
  dbus_free_string_array (decomposed_path);

  return retval;
}

static DBusDataSlotAllocator slot_allocator;
_DBUS_DEFINE_GLOBAL_LOCK (connection_slots);

/**
 * Allocates an integer ID to be used for storing application-specific
 * data on any DBusConnection. The allocated ID may then be used
 * with dbus_connection_set_data() and dbus_connection_get_data().
 * The passed-in slot must be initialized to -1, and is filled in
 * with the slot ID. If the passed-in slot is not -1, it's assumed
 * to be already allocated, and its refcount is incremented.
 * 
 * The allocated slot is global, i.e. all DBusConnection objects will
 * have a slot with the given integer ID reserved.
 *
 * @param slot_p address of a global variable storing the slot
 * @returns #FALSE on failure (no memory)
 */
dbus_bool_t
dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
{
  return _dbus_data_slot_allocator_alloc (&slot_allocator,
                                          &_DBUS_LOCK_NAME (connection_slots),
                                          slot_p);
}

/**
 * Deallocates a global ID for connection data slots.
 * dbus_connection_get_data() and dbus_connection_set_data() may no
 * longer be used with this slot.  Existing data stored on existing
 * DBusConnection objects will be freed when the connection is
 * finalized, but may not be retrieved (and may only be replaced if
 * someone else reallocates the slot).  When the refcount on the
 * passed-in slot reaches 0, it is set to -1.
 *
 * @param slot_p address storing the slot to deallocate
 */
void
dbus_connection_free_data_slot (dbus_int32_t *slot_p)
{
  _dbus_return_if_fail (*slot_p >= 0);
  
  _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
}

/**
 * Stores a pointer on a DBusConnection, along
 * with an optional function to be used for freeing
 * the data when the data is set again, or when
 * 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
 * @param free_data_func finalizer function for the data
 * @returns #TRUE if there was enough memory to store the data
 */
dbus_bool_t
dbus_connection_set_data (DBusConnection   *connection,
                          dbus_int32_t      slot,
                          void             *data,
                          DBusFreeFunction  free_data_func)
{
  DBusFreeFunction old_free_func;
  void *old_data;
  dbus_bool_t retval;

  _dbus_return_val_if_fail (connection != NULL, FALSE);
  _dbus_return_val_if_fail (slot >= 0, FALSE);
  
  SLOTS_LOCK (connection);

  retval = _dbus_data_slot_list_set (&slot_allocator,
                                     &connection->slot_list,
                                     slot, data, free_data_func,
                                     &old_free_func, &old_data);
  
  SLOTS_UNLOCK (connection);

  if (retval)
    {
      /* Do the actual free outside the connection lock */
      if (old_free_func)
        (* old_free_func) (old_data);
    }

  return retval;
}

/**
 * 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
 */
void*
dbus_connection_get_data (DBusConnection   *connection,
                          dbus_int32_t      slot)
{
  void *res;

  _dbus_return_val_if_fail (connection != NULL, NULL);
  
  SLOTS_LOCK (connection);

  res = _dbus_data_slot_list_get (&slot_allocator,
                                  &connection->slot_list,
                                  slot);
  
  SLOTS_UNLOCK (connection);

  return res;
}

/**
 * This function sets a global flag for whether dbus_connection_new()
 * will set SIGPIPE behavior to SIG_IGN.
 *
 * @param will_modify_sigpipe #TRUE to allow sigpipe to be set to SIG_IGN
 */
void
dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
{  
  _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
}

/**
 * Specifies the maximum size message this connection is allowed to
 * receive. Larger messages will result in disconnecting the
 * connection.
 * 
 * @param connection a #DBusConnection
 * @param size maximum message size the connection can receive, in bytes
 */
void
dbus_connection_set_max_message_size (DBusConnection *connection,
                                      long            size)
{
  _dbus_return_if_fail (connection != NULL);
  
  CONNECTION_LOCK (connection);
  _dbus_transport_set_max_message_size (connection->transport,
                                        size);
  CONNECTION_UNLOCK (connection);
}

/**
 * Gets the value set by dbus_connection_set_max_message_size().
 *
 * @param connection the connection
 * @returns the max size of a single message
 */
long
dbus_connection_get_max_message_size (DBusConnection *connection)
{
  long res;

  _dbus_return_val_if_fail (connection != NULL, 0);
  
  CONNECTION_LOCK (connection);
  res = _dbus_transport_get_max_message_size (connection->transport);
  CONNECTION_UNLOCK (connection);
  return res;
}

/**
 * Specifies the maximum number of unix fds a message on this
 * connection is allowed to receive. Messages with more unix fds will
 * result in disconnecting the connection.
 *
 * @param connection a #DBusConnection
 * @param size maximum message unix fds the connection can receive
 */
void
dbus_connection_set_max_message_unix_fds (DBusConnection *connection,
                                          long            n)
{
  _dbus_return_if_fail (connection != NULL);

  CONNECTION_LOCK (connection);
  _dbus_transport_set_max_message_unix_fds (connection->transport,
                                            n);
  CONNECTION_UNLOCK (connection);
}

/**
 * Gets the value set by dbus_connection_set_max_message_unix_fds().
 *
 * @param connection the connection
 * @returns the max numer of unix fds of a single message
 */
long
dbus_connection_get_max_message_unix_fds (DBusConnection *connection)
{
  long res;

  _dbus_return_val_if_fail (connection != NULL, 0);

  CONNECTION_LOCK (connection);
  res = _dbus_transport_get_max_message_unix_fds (connection->transport);
  CONNECTION_UNLOCK (connection);
  return res;
}

/**
 * Sets the maximum total number of bytes that can be used for all messages
 * received on this connection. Messages count toward the maximum until
 * they are finalized. When the maximum is reached, the connection will
 * not read more data until some messages are finalized.
 *
 * The semantics of the maximum are: if outstanding messages are
 * already above the maximum, additional messages will not be read.
 * The semantics are not: if the next message would cause us to exceed
 * the maximum, we don't read it. The reason is that we don't know the
 * size of a message until after we read it.
 *
 * Thus, the max live messages size can actually be exceeded
 * by up to the maximum size of a single message.
 * 
 * Also, if we read say 1024 bytes off the wire in a single read(),
 * and that contains a half-dozen small messages, we may exceed the
 * size max by that amount. But this should be inconsequential.
 *
 * This does imply that we can't call read() with a buffer larger
 * than we're willing to exceed this limit by.
 *
 * @param connection the connection
 * @param size the maximum size in bytes of all outstanding messages
 */
void
dbus_connection_set_max_received_size (DBusConnection *connection,
                                       long            size)
{
  _dbus_return_if_fail (connection != NULL);
  
  CONNECTION_LOCK (connection);
  _dbus_transport_set_max_received_size (connection->transport,
                                         size);
  CONNECTION_UNLOCK (connection);
}

/**
 * Gets the value set by dbus_connection_set_max_received_size().
 *
 * @param connection the connection
 * @returns the max size of all live messages
 */
long
dbus_connection_get_max_received_size (DBusConnection *connection)
{
  long res;

  _dbus_return_val_if_fail (connection != NULL, 0);
  
  CONNECTION_LOCK (connection);
  res = _dbus_transport_get_max_received_size (connection->transport);
  CONNECTION_UNLOCK (connection);
  return res;
}

/**
 * Sets the maximum total number of unix fds that can be used for all messages
 * received on this connection. Messages count toward the maximum until
 * they are finalized. When the maximum is reached, the connection will
 * not read more data until some messages are finalized.
 *
 * The semantics are analogous to those of dbus_connection_set_max_received_size().
 *
 * @param connection the connection
 * @param size the maximum size in bytes of all outstanding messages
 */
void
dbus_connection_set_max_received_unix_fds (DBusConnection *connection,
                                           long            n)
{
  _dbus_return_if_fail (connection != NULL);

  CONNECTION_LOCK (connection);
  _dbus_transport_set_max_received_unix_fds (connection->transport,
                                             n);
  CONNECTION_UNLOCK (connection);
}

/**
 * Gets the value set by dbus_connection_set_max_received_unix_fds().
 *
 * @param connection the connection
 * @returns the max unix fds of all live messages
 */
long
dbus_connection_get_max_received_unix_fds (DBusConnection *connection)
{
  long res;

  _dbus_return_val_if_fail (connection != NULL, 0);

  CONNECTION_LOCK (connection);
  res = _dbus_transport_get_max_received_unix_fds (connection->transport);
  CONNECTION_UNLOCK (connection);
  return res;
}

/**
 * Gets the approximate size in bytes of all messages in the outgoing
 * message queue. The size is approximate in that you shouldn't use
 * it to decide how many bytes to read off the network or anything
 * of that nature, as optimizations may choose to tell small white lies
 * to avoid performance overhead.
 *
 * @param connection the connection
 * @returns the number of bytes that have been queued up but not sent
 */
long
dbus_connection_get_outgoing_size (DBusConnection *connection)
{
  long res;

  _dbus_return_val_if_fail (connection != NULL, 0);

  CONNECTION_LOCK (connection);
  res = _dbus_counter_get_size_value (connection->outgoing_counter);
  CONNECTION_UNLOCK (connection);
  return res;
}

/**
 * Gets the approximate number of uni fds of all messages in the
 * outgoing message queue.
 *
 * @param connection the connection
 * @returns the number of unix fds that have been queued up but not sent
 */
long
dbus_connection_get_outgoing_unix_fds (DBusConnection *connection)
{
  long res;

  _dbus_return_val_if_fail (connection != NULL, 0);

  CONNECTION_LOCK (connection);
  res = _dbus_counter_get_unix_fd_value (connection->outgoing_counter);
  CONNECTION_UNLOCK (connection);
  return res;
}

/** @} */
