/* -*- mode: C; c-file-style: "gnu" -*- */
/* 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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-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"

#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 0

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

#define CONNECTION_UNLOCK(connection) do {                                              \
    if (TRACE_LOCKS) { _dbus_verbose ("  UNLOCK: %s\n", _DBUS_FUNCTION_NAME);  }        \
    RELEASING_LOCK_CHECK (connection);                                                  \
    _dbus_mutex_unlock ((connection)->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 */
};

static dbus_bool_t _dbus_modify_sigpipe = TRUE;

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

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

  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 dispatch_acquired : 1; /**< Someone has dispatch path (can drain incoming queue) */
  unsigned int io_path_acquired : 1;  /**< Someone has transport io path (can use the transport to read/write messages) */
  
  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_int32_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 != -1)
    {
      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 (%d %s %s %s '%s' reply to %u) added to incoming queue %p, %d incoming\n",
                 message,
                 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 (%d %s %s %s '%s') removed from outgoing queue %p, %d left to send\n",
                 message,
                 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_size_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)
{
  DBusWatchList *watches;
  dbus_bool_t retval;
  
  HAVE_LOCK_CHECK (connection);

  /* This isn't really safe or reasonable; a better pattern is the "do everything, then
   * drop lock and call out" one; but it has to be propagated up through all callers
   */
  
  watches = connection->watches;
  if (watches)
    {
      connection->watches = NULL;
      _dbus_connection_ref_unlocked (connection);
      CONNECTION_UNLOCK (connection);

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

      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)
{
  DBusTimeoutList *timeouts;
  dbus_bool_t retval;
  
  HAVE_LOCK_CHECK (connection);

  /* This isn't really safe or reasonable; a better pattern is the "do everything, then
   * drop lock and call out" one; but it has to be propagated up through all callers
   */
  
  timeouts = connection->timeouts;
  if (timeouts)
    {
      connection->timeouts = NULL;
      _dbus_connection_ref_unlocked (connection);
      CONNECTION_UNLOCK (connection);

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

      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 (!_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);

  _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));
  _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 ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME);
  _dbus_mutex_lock (connection->io_path_mutex);

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

  we_acquired = FALSE;
  
  if (connection->io_path_acquired)
    {
      if (timeout_milliseconds != -1)
        {
          _dbus_verbose ("%s waiting %d for IO path to be acquirable\n",
                         _DBUS_FUNCTION_NAME, 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 ("%s waiting for IO path to be acquirable\n", _DBUS_FUNCTION_NAME);
              _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 ("%s end connection->io_path_acquired = %d we_acquired = %d\n",
                 _DBUS_FUNCTION_NAME, connection->io_path_acquired, we_acquired);

  _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME);
  _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 ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME);
  _dbus_mutex_lock (connection->io_path_mutex);
  
  _dbus_assert (connection->io_path_acquired);

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

  _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME);
  _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 ("%s start\n", _DBUS_FUNCTION_NAME);
  
  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 ("%s end\n", _DBUS_FUNCTION_NAME);
}

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

  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_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)
{
  int 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 ("%s start\n", _DBUS_FUNCTION_NAME);
  
  CONNECTION_LOCK (connection);
  _dbus_connection_acquire_io_path (connection, -1);
  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 ("%s middle\n", _DBUS_FUNCTION_NAME);
  
  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 ("%s end\n", _DBUS_FUNCTION_NAME);
  
  return retval;
}

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

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;
      DBusMessage *message;
      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);

      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);
      
      _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;
  
  _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)
    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;
  
  if (connection->server_guid != NULL)
    {
      _dbus_verbose ("dropping connection to %s out of the shared table\n",
                     connection->server_guid);
      
      _DBUS_LOCK (shared_connections);
      
      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;
      _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;
  DBusError first_error;
  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;

  dbus_error_init (&tmp_error);
  dbus_error_init (&first_error);
  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;
  const char *sig;

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

  _dbus_message_add_size_counter_link (message,
                                       preallocated->counter_link);

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

  sig = dbus_message_get_signature (message);
  
  _dbus_verbose ("Message %p (%d %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
                 message,
                 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",
                 sig,
                 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 ("%s middle\n", _DBUS_FUNCTION_NAME);
  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);
      _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 ("%s checked for reply\n", _DBUS_FUNCTION_NAME);

      _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 end_tv_sec, end_tv_usec;
  long tv_sec, tv_usec;
  DBusDispatchStatus status;
  DBusConnection *connection;
  dbus_uint32_t client_serial;
  int timeout_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_milliseconds = dbus_timeout_get_interval (_dbus_pending_call_get_timeout_unlocked (pending));
  
  _dbus_get_current_time (&start_tv_sec, &start_tv_usec);
  end_tv_sec = start_tv_sec + timeout_milliseconds / 1000;
  end_tv_usec = start_tv_usec + (timeout_milliseconds % 1000) * 1000;
  end_tv_sec += end_tv_usec / _DBUS_USEC_PER_SECOND;
  end_tv_usec = end_tv_usec % _DBUS_USEC_PER_SECOND;

  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec to %ld sec %ld usec\n",
                 timeout_milliseconds,
                 client_serial,
                 start_tv_sec, start_tv_usec,
                 end_tv_sec, end_tv_usec);

  /* 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 ("%s top of recheck\n", _DBUS_FUNCTION_NAME);
  
  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 in %s\n", _DBUS_FUNCTION_NAME);
      _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);
  
  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 (tv_sec < start_tv_sec)
    _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
  else if (connection->disconnect_message_link == NULL)
    _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
  else if (tv_sec < end_tv_sec ||
           (tv_sec == end_tv_sec && tv_usec < end_tv_usec))
    {
      timeout_milliseconds = (end_tv_sec - tv_sec) * 1000 +
        (end_tv_usec - tv_usec) / 1000;
      _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds);
      _dbus_assert (timeout_milliseconds >= 0);
      
      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);
        }
      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);
        }

      goto recheck_status;
    }

  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %ld milliseconds and got no reply\n",
                 (tv_sec - start_tv_sec) * 1000 + (tv_usec - start_tv_usec) / 1000);

  _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
   */
  
#ifdef DBUS_HAVE_ATOMIC_INT
  _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_size_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->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
   */
  
#ifdef DBUS_HAVE_ATOMIC_INT
  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;
}

/**
 * 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);
  _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().
 * 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.
 * 
 * @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);

  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 ("%s middle\n", _DBUS_FUNCTION_NAME);
  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.  There is no way to
 * avoid a timeout entirely, other than passing INT_MAX for the
 * timeout to mean "very long timeout." libdbus clamps an INT_MAX
 * timeout down to a few hours timeout though.
 *
 * @warning if the connection is disconnected, 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
 * @param timeout_milliseconds timeout in milliseconds or -1 for default
 * @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);

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

      *pending_return = NULL;

      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 or -1 for default
 * @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);
  
  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.
 */
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 %s\n", _DBUS_FUNCTION_NAME);
      HAVE_LOCK_CHECK (connection);
      _dbus_connection_do_iteration_unlocked (connection,
                                              NULL,
                                              DBUS_ITERATION_DO_READING |
                                              DBUS_ITERATION_DO_WRITING |
                                              DBUS_ITERATION_BLOCK,
                                              -1);
    }

  HAVE_LOCK_CHECK (connection);
  _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
  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 ("%s end\n", _DBUS_FUNCTION_NAME);
}

/**
 * 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 no_progress_possible;
  
  dstatus = dbus_connection_get_dispatch_status (connection);

  if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
    {
      _dbus_verbose ("doing dispatch in %s\n", _DBUS_FUNCTION_NAME);
      dbus_connection_dispatch (connection);
      CONNECTION_LOCK (connection);
    }
  else if (dstatus == DBUS_DISPATCH_NEED_MEMORY)
    {
      _dbus_verbose ("pausing for memory in %s\n", _DBUS_FUNCTION_NAME);
      _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 in %s\n", _DBUS_FUNCTION_NAME);
          _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)
    no_progress_possible = connection->n_incoming == 0 &&
      connection->disconnect_message_link == NULL;
  else
    no_progress_possible = _dbus_connection_get_is_connected_unlocked (connection);
  CONNECTION_UNLOCK (connection);
  return !no_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 want to 
 * dispatch all the events in the incoming/outgoing queue before returning. 
 * The function just calls dbus_connection_read_write_dispatch till
 * the incoming queue is empty.
 * 
 * @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_greedy (DBusConnection *connection,
                                            int   timeout_milliseconds)
{
  dbus_bool_t ret, progress_possible;
  int pre_incoming, pre_outgoing;
  do
    {
      pre_incoming = connection->n_incoming;
      pre_outgoing = connection->n_outgoing;
      ret = dbus_connection_read_write_dispatch(connection, timeout_milliseconds);
      /* No need to take a lock here. If another 'reader' thread has read the packet,
       * dbus_connection_read_write_dispatch will just return. If a writer
       * writes a packet between the call and the check, it will get processed 
       * in the next call to the function.
       */
      if ((pre_incoming != connection->n_incoming ||
           pre_outgoing != connection->n_outgoing) &&
          (connection->n_incoming > 0 ||
           connection->n_outgoing > 0)) {
        progress_possible = TRUE;
      } else {
        progress_possible = FALSE;
      }
    } while (ret == TRUE && progress_possible);
  return ret;
}


/** 
 * 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 ("%s start\n", _DBUS_FUNCTION_NAME);
  
  /* 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 (%d %s %s %s '%s') removed from incoming queue %p, %d incoming\n",
                     link->data,
                     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 (%d %s %s '%s') put back into queue %p, %d incoming\n",
                 message_link->data,
                 dbus_message_get_type (message_link->data),
                 dbus_message_get_interface (message_link->data) ?
                 dbus_message_get_interface (message_link->data) :
                 "no interface",
                 dbus_message_get_member (message_link->data) ?
                 dbus_message_get_member (message_link->data) :
                 "no member",
                 dbus_message_get_signature (message_link->data),
                 connection, connection->n_incoming);
}

/**
 * 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 ("%s start\n", _DBUS_FUNCTION_NAME);
  
  /* 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 ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
  _dbus_mutex_lock (connection->dispatch_mutex);

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

  connection->dispatch_acquired = TRUE;

  _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
  _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 ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
  _dbus_mutex_lock (connection->dispatch_mutex);
  
  _dbus_assert (connection->dispatch_acquired);

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

  _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
  _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 from %s\n",
                     _DBUS_FUNCTION_NAME);
      
      /* 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 ("%s start\n", _DBUS_FUNCTION_NAME);
  
  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 ("%s\n", _DBUS_FUNCTION_NAME);
  
  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 (%d %s %s '%s')\n",
                 message,
                 dbus_message_get_type (message),
                 dbus_message_get_interface (message) ?
                 dbus_message_get_interface (message) :
                 "no interface",
                 dbus_message_get_member (message) ?
                 dbus_message_get_member (message) :
                 "no member",
                 dbus_message_get_signature (message));

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

      if (pending)
        dbus_pending_call_unref (pending);
      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 in %s\n", _DBUS_FUNCTION_NAME);
      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 (%d %s %s '%s')\n",
                 message,
                 dbus_message_get_type (message),
                 dbus_message_get_interface (message) ?
                 dbus_message_get_interface (message) :
                 "no interface",
                 dbus_message_get_member (message) ?
                 dbus_message_get_member (message) :
                 "no member",
                 dbus_message_get_signature (message));

  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 (%d %s %s '%s') on connection %p\n", message,
                 dbus_message_get_type (message),
                 dbus_message_get_interface (message) ?
                 dbus_message_get_interface (message) :
                 "no interface",
                 dbus_message_get_member (message) ?
                 dbus_message_get_member (message) :
                 "no member",
                 dbus_message_get_signature (message),
                 connection);
  
 out:
  if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
    {
      _dbus_verbose ("out of memory in %s\n", _DBUS_FUNCTION_NAME);
      
      /* 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 in %s\n", _DBUS_FUNCTION_NAME);
      
      _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 ("%s before final status update\n", _DBUS_FUNCTION_NAME);
  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_fd(), 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.
 *
 * @todo We need to drop the lock when we call the
 * add/remove/toggled functions which can be a side effect
 * of setting the watch functions.
 * 
 * @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;
  DBusWatchList *watches;

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

#ifndef DBUS_DISABLE_CHECKS
  if (connection->watches == NULL)
    {
      _dbus_warn_check_failed ("Re-entrant call to %s is not allowed\n",
                               _DBUS_FUNCTION_NAME);
      return FALSE;
    }
#endif
  
  /* ref connection for slightly better reentrancy */
  _dbus_connection_ref_unlocked (connection);

  /* This can call back into user code, and we need to drop the
   * connection lock when it does. This is kind of a lame
   * way to do it.
   */
  watches = connection->watches;
  connection->watches = NULL;
  CONNECTION_UNLOCK (connection);

  retval = _dbus_watch_list_set_functions (watches,
                                           add_function, remove_function,
                                           toggled_function,
                                           data, free_data_function);
  CONNECTION_LOCK (connection);
  connection->watches = watches;
  
  CONNECTION_UNLOCK (connection);
  /* drop our paranoid refcount */
  dbus_connection_unref (connection);
  
  return retval;
}

/**
 * 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.
 *
 * @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;
  DBusTimeoutList *timeouts;

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

#ifndef DBUS_DISABLE_CHECKS
  if (connection->timeouts == NULL)
    {
      _dbus_warn_check_failed ("Re-entrant call to %s is not allowed\n",
                               _DBUS_FUNCTION_NAME);
      return FALSE;
    }
#endif
  
  /* ref connection for slightly better reentrancy */
  _dbus_connection_ref_unlocked (connection);

  timeouts = connection->timeouts;
  connection->timeouts = NULL;
  CONNECTION_UNLOCK (connection);
  
  retval = _dbus_timeout_list_set_functions (timeouts,
                                             add_function, remove_function,
                                             toggled_function,
                                             data, free_data_function);
  CONNECTION_LOCK (connection);
  connection->timeouts = timeouts;
  
  CONNECTION_UNLOCK (connection);
  /* drop our paranoid refcount */
  dbus_connection_unref (connection);

  return retval;
}

/**
 * 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_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_fd() 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.
 * 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);

#ifdef DBUS_WIN
  /* FIXME this should be done at a lower level, but it's kind of hard,
   * just want to be sure we don't ship with this API returning
   * some weird internal fake uid for 1.0
   */
  return FALSE;
#endif
  
  CONNECTION_LOCK (connection);

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

  return result;
}

/**
 * Gets the process ID of the connection if any.
 * Returns #TRUE if the uid 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);

#ifdef DBUS_WIN
  /* FIXME this should be done at a lower level, but it's kind of hard,
   * just want to be sure we don't ship with this API returning
   * some weird internal fake uid for 1.0
   */
  return FALSE;
#endif
  
  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;
}

/**
 * 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.
 *
 * 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.
 * 
 * @todo add a Windows API analogous to dbus_connection_set_unix_user_function()
 * 
 * @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);    
}

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

  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."
 *
 * @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;
  
  _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);

  CONNECTION_UNLOCK (connection);

  dbus_free_string_array (decomposed_path);

  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().
 *
 * @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);
  
  CONNECTION_LOCK (connection);

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

  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).
 *
 * @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);
  
  CONNECTION_LOCK (connection);

  res = _dbus_data_slot_list_get (&slot_allocator,
                                  &connection->slot_list,
                                  slot);
  
  CONNECTION_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;
}

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

/**
 * 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_value (connection->outgoing_counter);
  CONNECTION_UNLOCK (connection);
  return res;
}

/** @} */
