dbus-connection.c 214 KB
Newer Older
1
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 3
/* dbus-connection.c DBusConnection object
 *
4
 * Copyright (C) 2002-2006  Red Hat Inc.
5
 *
6
 * Licensed under the Academic Free License version 2.1
7 8 9 10 11 12 13 14 15 16 17 18 19
 * 
 * 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
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21 22 23
 *
 */

24
#include <config.h>
25
#include "dbus-shared.h"
26 27
#include "dbus-connection.h"
#include "dbus-list.h"
28
#include "dbus-timeout.h"
29 30 31
#include "dbus-transport.h"
#include "dbus-watch.h"
#include "dbus-connection-internal.h"
32
#include "dbus-pending-call-internal.h"
33
#include "dbus-list.h"
34
#include "dbus-hash.h"
35
#include "dbus-message-internal.h"
36
#include "dbus-message-private.h"
37
#include "dbus-threads.h"
38
#include "dbus-protocol.h"
39
#include "dbus-dataslot.h"
40
#include "dbus-string.h"
41
#include "dbus-signature.h"
42
#include "dbus-pending-call.h"
43
#include "dbus-object-tree.h"
44
#include "dbus-threads-internal.h"
45
#include "dbus-bus.h"
46
#include "dbus-marshal-basic.h"
47

48 49 50 51 52 53 54 55
#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;          \
56
  } while (0)
57 58 59
#define RELEASING_LOCK_CHECK(connection) do {            \
    _dbus_assert ((connection)->have_connection_lock);   \
    (connection)->have_connection_lock = FALSE;          \
60
  } while (0)
61 62
#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 */
63 64
#endif

65 66 67
#define TRACE_LOCKS 1

#define CONNECTION_LOCK(connection)   do {                                      \
68
    if (TRACE_LOCKS) { _dbus_verbose ("LOCK\n"); }   \
69
    _dbus_rmutex_lock ((connection)->mutex);                                    \
70 71 72
    TOOK_LOCK_CHECK (connection);                                               \
  } while (0)

73
#define CONNECTION_UNLOCK(connection) _dbus_connection_unlock (connection)
74

75
#define SLOTS_LOCK(connection) do {                     \
76
    _dbus_rmutex_lock ((connection)->slot_mutex);       \
77 78 79
  } while (0)

#define SLOTS_UNLOCK(connection) do {                   \
80
    _dbus_rmutex_unlock ((connection)->slot_mutex);     \
81 82
  } while (0)

83 84 85 86 87 88
#define DISPATCH_STATUS_NAME(s)                                            \
                     ((s) == DBUS_DISPATCH_COMPLETE ? "complete" :         \
                      (s) == DBUS_DISPATCH_DATA_REMAINS ? "data remains" : \
                      (s) == DBUS_DISPATCH_NEED_MEMORY ? "need memory" :   \
                      "???")

89 90 91 92 93 94 95
/**
 * @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.
96 97 98 99
 * 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.
 * 
100
 * In brief a DBusConnection is a message queue associated with some
101 102 103 104
 * message transport mechanism such as a socket.  The connection
 * maintains a queue of incoming messages and a queue of outgoing
 * messages.
 *
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
 * 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.
126
 * 
127 128 129 130
 * 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.
131
 * 
John Palmieri's avatar
John Palmieri committed
132
 * If you're using GLib or Qt add-on libraries for D-Bus, there are
133
 * special convenience APIs in those libraries that hide
134 135 136
 * all the details of dispatch and watch/timeout monitoring.
 * For example, dbus_connection_setup_with_g_main().
 *
137 138 139
 * 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(),
140 141 142
 * dbus_connection_set_watch_functions(),
 * dbus_connection_set_timeout_functions() providing appropriate
 * functions to integrate the connection with your application's main
143
 * loop. This can be tricky to get right; main loops are not simple.
144
 *
145 146 147 148 149
 * 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,
Havoc Pennington's avatar
Havoc Pennington committed
150
 * dbus_connection_pop_message() may be all you need, allowing you to
151 152 153 154
 * avoid setting up any handler functions (see
 * dbus_connection_add_filter(),
 * dbus_connection_register_object_path() for more on handlers).
 * 
155 156 157 158 159 160 161 162 163
 * 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
164
 * signal "Disconnected" from the interface
165 166
 * #DBUS_INTERFACE_LOCAL, path
 * #DBUS_PATH_LOCAL.
167 168 169 170 171
 *
 * 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
172 173 174
 * connection is disconnected. However, "Disconnected" will always be
 * the last message in the queue (obviously no messages are received
 * after disconnection).
175
 *
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
 * 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.
196 197 198 199 200 201 202 203 204 205
 */

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

206 207 208 209 210 211
static void
_dbus_connection_trace_ref (DBusConnection *connection,
    int old_refcount,
    int new_refcount,
    const char *why)
{
212
#ifdef DBUS_ENABLE_VERBOSE_MODE
213 214 215 216 217
  static int enabled = -1;

  _dbus_trace_ref ("DBusConnection", connection, old_refcount, new_refcount,
      why, "DBUS_CONNECTION_TRACE", &enabled);
#endif
218
}
219

220 221 222
/**
 * Internal struct representing a message filter function 
 */
223 224
typedef struct DBusMessageFilter DBusMessageFilter;

225 226 227
/**
 * Internal struct representing a message filter function 
 */
228 229
struct DBusMessageFilter
{
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
  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 */
245 246
};

247
#if HAVE_DECL_MSG_NOSIGNAL
248 249
static dbus_bool_t _dbus_modify_sigpipe = FALSE;
#else
250
static dbus_bool_t _dbus_modify_sigpipe = TRUE;
251
#endif
252

253 254 255 256 257
/**
 * Implementation details of DBusConnection. All fields are private.
 */
struct DBusConnection
{
258
  DBusAtomic refcount; /**< Reference count. */
259

260
  DBusRMutex *mutex; /**< Lock on the entire DBusConnection */
261

262
  DBusCMutex *dispatch_mutex;     /**< Protects dispatch_acquired */
263
  DBusCondVar *dispatch_cond;    /**< Notify when dispatch_acquired is available */
264
  DBusCMutex *io_path_mutex;      /**< Protects io_path_acquired */
265
  DBusCondVar *io_path_cond;     /**< Notify when io_path_acquired is available */
266
  
267 268
  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. */
269
  DBusList *expired_messages;  /**< Messages that will be released when we next unlock. */
270

271 272 273
  DBusMessage *message_borrowed; /**< Filled in if the first incoming message has been borrowed;
                                  *   dispatch_acquired will be set by the borrower
                                  */
274
  
275 276
  int n_outgoing;              /**< Length of outgoing queue. */
  int n_incoming;              /**< Length of incoming queue. */
277 278

  DBusCounter *outgoing_counter; /**< Counts size of outgoing messages. */
279 280 281
  
  DBusTransport *transport;    /**< Object that sends/receives messages over network. */
  DBusWatchList *watches;      /**< Stores active watches. */
282
  DBusTimeoutList *timeouts;   /**< Stores active timeouts. */
283
  
284
  DBusList *filter_list;        /**< List of filters. */
285

286
  DBusRMutex *slot_mutex;        /**< Lock on slot_list so overall connection lock need not be taken */
287
  DBusDataSlotList slot_list;   /**< Data stored by allocated integer ID */
288

289
  DBusHashTable *pending_replies;  /**< Hash of message serials to #DBusPendingCall. */  
290
  
291
  dbus_uint32_t client_serial;       /**< Client serial. Increments each time a message is sent  */
292
  DBusList *disconnect_message_link; /**< Preallocated list node for queueing the disconnection message */
293 294 295 296

  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 */
297 298 299 300 301

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

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

304
  DBusObjectTree *objects; /**< Object path handlers registered with this connection */
305 306 307

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

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

  unsigned int route_peer_messages : 1; /**< If #TRUE, if org.freedesktop.DBus.Peer messages have a bus name, don't handle them automatically */
320 321 322 323 324 325 326 327

  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.
                                                    */
328 329 330 331
  
#ifndef DBUS_DISABLE_CHECKS
  unsigned int have_connection_lock : 1; /**< Used to check locking */
#endif
332

333
#if defined(DBUS_ENABLE_CHECKS) || defined(DBUS_ENABLE_ASSERT)
334 335
  int generation; /**< _dbus_current_generation that should correspond to this connection */
#endif 
336 337
};

338 339 340
static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked      (DBusConnection     *connection);
static void               _dbus_connection_update_dispatch_status_and_unlock (DBusConnection     *connection,
                                                                              DBusDispatchStatus  new_status);
341
static void               _dbus_connection_last_unref                        (DBusConnection     *connection);
342 343
static void               _dbus_connection_acquire_dispatch                  (DBusConnection     *connection);
static void               _dbus_connection_release_dispatch                  (DBusConnection     *connection);
344
static DBusDispatchStatus _dbus_connection_flush_unlocked                    (DBusConnection     *connection);
345 346
static void               _dbus_connection_close_possibly_shared_and_unlock  (DBusConnection     *connection);
static dbus_bool_t        _dbus_connection_get_is_connected_unlocked         (DBusConnection     *connection);
347 348
static dbus_bool_t        _dbus_connection_peek_for_reply_unlocked           (DBusConnection     *connection,
                                                                              dbus_uint32_t       client_serial);
349

350
static DBusMessageFilter *
351 352
_dbus_message_filter_ref (DBusMessageFilter *filter)
{
353
#ifdef DBUS_DISABLE_ASSERT
354
  _dbus_atomic_inc (&filter->refcount);
355 356 357 358 359 360
#else
  dbus_int32_t old_value;

  old_value = _dbus_atomic_inc (&filter->refcount);
  _dbus_assert (old_value > 0);
#endif
361 362

  return filter;
363 364 365 366 367
}

static void
_dbus_message_filter_unref (DBusMessageFilter *filter)
{
368 369 370 371
  dbus_int32_t old_value;

  old_value = _dbus_atomic_dec (&filter->refcount);
  _dbus_assert (old_value > 0);
372

373
  if (old_value == 1)
374 375 376 377 378 379 380
    {
      if (filter->free_user_data_function)
        (* filter->free_user_data_function) (filter->user_data);
      
      dbus_free (filter);
    }
}
381

382 383 384 385 386 387 388 389
/**
 * Acquires the connection lock.
 *
 * @param connection the connection.
 */
void
_dbus_connection_lock (DBusConnection *connection)
{
390
  CONNECTION_LOCK (connection);
391 392 393 394 395 396 397 398 399 400
}

/**
 * Releases the connection lock.
 *
 * @param connection the connection.
 */
void
_dbus_connection_unlock (DBusConnection *connection)
{
401 402 403
  DBusList *expired_messages;
  DBusList *iter;

404 405 406 407 408
  if (TRACE_LOCKS)
    {
      _dbus_verbose ("UNLOCK\n");
    }

409 410 411 412 413
  /* If we had messages that expired (fell off the incoming or outgoing
   * queues) while we were locked, actually release them now */
  expired_messages = connection->expired_messages;
  connection->expired_messages = NULL;

414
  RELEASING_LOCK_CHECK (connection);
415
  _dbus_rmutex_unlock (connection->mutex);
416

417
  for (iter = _dbus_list_pop_first_link (&expired_messages);
418
      iter != NULL;
419
      iter = _dbus_list_pop_first_link (&expired_messages))
420 421 422 423
    {
      DBusMessage *message = iter->data;

      dbus_message_unref (message);
424
      _dbus_list_free_link (iter);
425
    }
426
}
427

428 429 430 431 432 433 434 435 436 437 438 439 440
/**
 * 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);
}
441

442
#ifdef DBUS_ENABLE_EMBEDDED_TESTS
443 444 445 446 447 448 449 450 451 452 453 454 455
/**
 * 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 
456
_dbus_connection_test_get_locks (DBusConnection *connection,
457 458 459 460 461
                                 DBusMutex     **mutex_loc,
                                 DBusMutex     **dispatch_mutex_loc,
                                 DBusMutex     **io_path_mutex_loc,
                                 DBusCondVar   **dispatch_cond_loc,
                                 DBusCondVar   **io_path_cond_loc)
462
{
463 464 465
  *mutex_loc = (DBusMutex *) connection->mutex;
  *dispatch_mutex_loc = (DBusMutex *) connection->dispatch_mutex;
  *io_path_mutex_loc = (DBusMutex *) connection->io_path_mutex;
466 467
  *dispatch_cond_loc = connection->dispatch_cond;
  *io_path_cond_loc = connection->io_path_cond;
468
}
469
#endif
470 471 472 473 474 475 476 477 478 479 480 481

/**
 * 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)
482
{
483
  DBusPendingCall *pending;
484
  dbus_uint32_t reply_serial;
485
  DBusMessage *message;
486 487 488

  _dbus_assert (_dbus_transport_peek_is_authenticated (connection->transport));

489 490 491
  _dbus_list_append_link (&connection->incoming_messages,
                          link);
  message = link->data;
492

493
  /* If this is a reply we're waiting on, remove timeout for it */
494
  reply_serial = dbus_message_get_reply_serial (message);
495
  if (reply_serial != 0)
496
    {
497 498 499
      pending = _dbus_hash_table_lookup_int (connection->pending_replies,
                                             reply_serial);
      if (pending != NULL)
500
	{
501
	  if (_dbus_pending_call_is_timeout_added_unlocked (pending))
502
            _dbus_connection_remove_timeout_unlocked (connection,
503
                                                      _dbus_pending_call_get_timeout_unlocked (pending));
504

505
	  _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
506 507
	}
    }
508
  
509 510
  

511 512
  connection->n_incoming += 1;

513
  _dbus_connection_wakeup_mainloop (connection);
514
  
515
  _dbus_verbose ("Message %p (%s %s %s %s '%s' reply to %u) added to incoming queue %p, %d incoming\n",
516
                 message,
517
                 dbus_message_type_to_string (dbus_message_get_type (message)),
518 519 520
                 dbus_message_get_path (message) ?
                 dbus_message_get_path (message) :
                 "no path",
521 522 523
                 dbus_message_get_interface (message) ?
                 dbus_message_get_interface (message) :
                 "no interface",
524 525 526
                 dbus_message_get_member (message) ?
                 dbus_message_get_member (message) :
                 "no member",
527
                 dbus_message_get_signature (message),
528
                 dbus_message_get_reply_serial (message),
529
                 connection,
530 531 532 533 534
                 connection->n_incoming);

  _dbus_message_trace_ref (message, -1, -1,
      "_dbus_conection_queue_received_message_link");
}
535

536 537 538 539 540 541 542 543
/**
 * 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.
 *
 */
544
void
545 546 547
_dbus_connection_queue_synthesized_message_link (DBusConnection *connection,
						 DBusList *link)
{
548 549
  HAVE_LOCK_CHECK (connection);
  
550 551 552 553
  _dbus_list_append_link (&connection->incoming_messages, link);

  connection->n_incoming += 1;

554
  _dbus_connection_wakeup_mainloop (connection);
555 556 557 558

  _dbus_message_trace_ref (link->data, -1, -1,
      "_dbus_connection_queue_synthesized_message_link");

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


564 565
/**
 * Checks whether there are messages in the outgoing message queue.
566
 * Called with connection lock held.
567 568 569 570 571
 *
 * @param connection the connection.
 * @returns #TRUE if the outgoing queue is non-empty.
 */
dbus_bool_t
572
_dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection)
573
{
574
  HAVE_LOCK_CHECK (connection);
575 576 577
  return connection->outgoing_messages != NULL;
}

578 579
/**
 * Checks whether there are messages in the outgoing message queue.
580 581 582 583
 * Use dbus_connection_flush() to block until all outgoing
 * messages have been written to the underlying transport
 * (such as a socket).
 * 
584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600
 * @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;
}

601
/**
602
 * Gets the next outgoing message. The message remains in the
603 604 605 606 607 608 609 610
 * 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)
{
611 612
  HAVE_LOCK_CHECK (connection);
  
613 614 615 616 617 618
  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.
619
 * Called with the connection lock held.
620 621 622 623 624
 *
 * @param connection the connection.
 * @param message the message that was sent.
 */
void
625 626
_dbus_connection_message_sent_unlocked (DBusConnection *connection,
                                        DBusMessage    *message)
627
{
628
  DBusList *link;
629

630 631
  HAVE_LOCK_CHECK (connection);
  
632 633 634 635
  /* 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.
   */
636
  
637 638 639 640 641 642
  link = _dbus_list_get_last_link (&connection->outgoing_messages);
  _dbus_assert (link != NULL);
  _dbus_assert (link->data == message);

  _dbus_list_unlink (&connection->outgoing_messages,
                     link);
643 644
  _dbus_list_prepend_link (&connection->expired_messages, link);

645
  connection->n_outgoing -= 1;
646

647
  _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from outgoing queue %p, %d left to send\n",
648
                 message,
649
                 dbus_message_type_to_string (dbus_message_get_type (message)),
650 651 652
                 dbus_message_get_path (message) ?
                 dbus_message_get_path (message) :
                 "no path",
653 654 655
                 dbus_message_get_interface (message) ?
                 dbus_message_get_interface (message) :
                 "no interface",
656 657 658
                 dbus_message_get_member (message) ?
                 dbus_message_get_member (message) :
                 "no member",
659
                 dbus_message_get_signature (message),
660 661
                 connection, connection->n_outgoing);

662 663
  /* It's OK that in principle we call the notify function, because for the
   * outgoing limit, there isn't one */
664
  _dbus_message_remove_counter (message, connection->outgoing_counter);
665 666

  /* The message will actually be unreffed when we unlock */
667 668
}

669
/** Function to be called in protected_change_watch() with refcount held */
670 671
typedef dbus_bool_t (* DBusWatchAddFunction)     (DBusWatchList *list,
                                                  DBusWatch     *watch);
672
/** Function to be called in protected_change_watch() with refcount held */
673 674
typedef void        (* DBusWatchRemoveFunction)  (DBusWatchList *list,
                                                  DBusWatch     *watch);
675
/** Function to be called in protected_change_watch() with refcount held */
676 677 678 679 680 681 682 683 684 685 686 687 688
typedef void        (* DBusWatchToggleFunction)  (DBusWatchList *list,
                                                  DBusWatch     *watch,
                                                  dbus_bool_t    enabled);

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

690 691
  HAVE_LOCK_CHECK (connection);

692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707
  /* The original purpose of protected_change_watch() was to hold a
   * ref on the connection while dropping the connection lock, then
   * calling out to the app.  This was a broken hack that did not
   * work, since the connection was in a hosed state (no WatchList
   * field) while calling out.
   *
   * So for now we'll just keep the lock while calling out. This means
   * apps are not allowed to call DBusConnection methods inside a
   * watch function or they will deadlock.
   *
   * The "real fix" is to use the _and_unlock() pattern found
   * elsewhere in the code, to defer calling out to the app until
   * we're about to drop locks and return flow of control to the app
   * anyway.
   *
   * See http://lists.freedesktop.org/archives/dbus/2007-July/thread.html#8144
708 709
   */

710 711
  if (connection->watches)
    {
712
      if (add_function)
713
        retval = (* add_function) (connection->watches, watch);
714 715 716
      else if (remove_function)
        {
          retval = TRUE;
717
          (* remove_function) (connection->watches, watch);
718 719 720 721
        }
      else
        {
          retval = TRUE;
722
          (* toggle_function) (connection->watches, watch, enabled);
723 724 725 726 727 728 729 730
        }
      return retval;
    }
  else
    return FALSE;
}
     

731 732 733 734 735
/**
 * 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.
736
 * Connection lock should be held when calling this.
737 738 739 740 741 742
 *
 * @param connection the connection.
 * @param watch the watch to add.
 * @returns #TRUE on success.
 */
dbus_bool_t
743 744
_dbus_connection_add_watch_unlocked (DBusConnection *connection,
                                     DBusWatch      *watch)
745
{
746 747 748
  return protected_change_watch (connection, watch,
                                 _dbus_watch_list_add_watch,
                                 NULL, NULL, FALSE);
749 750 751 752 753 754
}

/**
 * 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.
755
 * Connection lock should be held when calling this.
756 757 758 759 760
 *
 * @param connection the connection.
 * @param watch the watch to remove.
 */
void
761 762
_dbus_connection_remove_watch_unlocked (DBusConnection *connection,
                                        DBusWatch      *watch)
763
{
764 765 766 767
  protected_change_watch (connection, watch,
                          NULL,
                          _dbus_watch_list_remove_watch,
                          NULL, FALSE);
768 769
}

770 771 772 773
/**
 * 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.
774
 * Connection lock should be held when calling this.
775 776
 *
 * @param connection the connection.
777
 * @param watch the watch to toggle.
778 779 780
 * @param enabled whether to enable or disable
 */
void
781 782 783
_dbus_connection_toggle_watch_unlocked (DBusConnection *connection,
                                        DBusWatch      *watch,
                                        dbus_bool_t     enabled)
784
{
785
  _dbus_assert (watch != NULL);
786 787 788 789 790 791 792

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

793
/** Function to be called in protected_change_timeout() with refcount held */
794 795
typedef dbus_bool_t (* DBusTimeoutAddFunction)    (DBusTimeoutList *list,
                                                   DBusTimeout     *timeout);
796
/** Function to be called in protected_change_timeout() with refcount held */
797 798
typedef void        (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list,
                                                   DBusTimeout     *timeout);
799
/** Function to be called in protected_change_timeout() with refcount held */
800 801 802 803 804 805 806 807 808 809 810 811 812
typedef void        (* DBusTimeoutToggleFunction) (DBusTimeoutList *list,
                                                   DBusTimeout     *timeout,
                                                   dbus_bool_t      enabled);

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

814 815
  HAVE_LOCK_CHECK (connection);

816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831
  /* The original purpose of protected_change_timeout() was to hold a
   * ref on the connection while dropping the connection lock, then
   * calling out to the app.  This was a broken hack that did not
   * work, since the connection was in a hosed state (no TimeoutList
   * field) while calling out.
   *
   * So for now we'll just keep the lock while calling out. This means
   * apps are not allowed to call DBusConnection methods inside a
   * timeout function or they will deadlock.
   *
   * The "real fix" is to use the _and_unlock() pattern found
   * elsewhere in the code, to defer calling out to the app until
   * we're about to drop locks and return flow of control to the app
   * anyway.
   *
   * See http://lists.freedesktop.org/archives/dbus/2007-July/thread.html#8144
832 833
   */

834 835
  if (connection->timeouts)
    {
836
      if (add_function)
837
        retval = (* add_function) (connection->timeouts, timeout);
838 839 840
      else if (remove_function)
        {
          retval = TRUE;
841
          (* remove_function) (connection->timeouts, timeout);
842 843 844 845
        }
      else
        {
          retval = TRUE;
846
          (* toggle_function) (connection->timeouts, timeout, enabled);
847 848 849 850
        }
      return retval;
    }
  else
851
    return FALSE;
852 853
}

854 855 856 857 858
/**
 * 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.
859
 * The timeout will fire repeatedly until removed.
860
 * Connection lock should be held when calling this.
861 862 863 864 865
 *
 * @param connection the connection.
 * @param timeout the timeout to add.
 * @returns #TRUE on success.
 */
866
dbus_bool_t
867 868
_dbus_connection_add_timeout_unlocked (DBusConnection *connection,
                                       DBusTimeout    *timeout)
869
{
870 871 872
  return protected_change_timeout (connection, timeout,
                                   _dbus_timeout_list_add_timeout,
                                   NULL, NULL, FALSE);
873 874
}

875 876 877 878
/**
 * 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.
879
 * Connection lock should be held when calling this.
880 881 882 883
 *
 * @param connection the connection.
 * @param timeout the timeout to remove.
 */
884
void
885 886
_dbus_connection_remove_timeout_unlocked (DBusConnection *connection,
                                          DBusTimeout    *timeout)
887
{
888 889 890 891
  protected_change_timeout (connection, timeout,
                            NULL,
                            _dbus_timeout_list_remove_timeout,
                            NULL, FALSE);
892 893
}

894 895 896 897
/**
 * 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.
898
 * Connection lock should be held when calling this.
899 900 901 902 903 904
 *
 * @param connection the connection.
 * @param timeout the timeout to toggle.
 * @param enabled whether to enable or disable
 */
void
905 906 907
_dbus_connection_toggle_timeout_unlocked (DBusConnection   *connection,
                                          DBusTimeout      *timeout,
                                          dbus_bool_t       enabled)
908
{
909 910 911 912
  protected_change_timeout (connection, timeout,
                            NULL, NULL,
                            _dbus_timeout_list_toggle_timeout,
                            enabled);
913
}
914

915 916 917 918
static dbus_bool_t
_dbus_connection_attach_pending_call_unlocked (DBusConnection  *connection,
                                               DBusPendingCall *pending)
{
919 920 921
  dbus_uint32_t reply_serial;
  DBusTimeout *timeout;

922
  HAVE_LOCK_CHECK (connection);
923

924
  reply_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
925 926 927

  _dbus_assert (reply_serial != 0);

928
  timeout = _dbus_pending_call_get_timeout_unlocked (pending);
929

930
  if (timeout)
931
    {
932 933 934 935 936 937 938 939
      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);
940

941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956
          _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
          HAVE_LOCK_CHECK (connection);
          return FALSE;
        }
      
      _dbus_pending_call_set_timeout_added_unlocked (pending, TRUE);
    }
  else
    {
      if (!_dbus_hash_table_insert_int (connection->pending_replies,
                                        reply_serial,
                                        pending))
        {
          HAVE_LOCK_CHECK (connection);
          return FALSE;
        }
957 958
    }

959
  _dbus_pending_call_ref_unlocked (pending);
960 961

  HAVE_LOCK_CHECK (connection);
962 963 964 965 966 967 968 969
  
  return TRUE;
}

static void
free_pending_call_on_hash_removal (void *data)
{
  DBusPendingCall *pending;
970 971
  DBusConnection  *connection;
  
972 973 974 975 976
  if (data == NULL)
    return;

  pending = data;

977
  connection = _dbus_pending_call_get_connection_unlocked (pending);
978

979 980 981
  HAVE_LOCK_CHECK (connection);
  
  if (_dbus_pending_call_is_timeout_added_unlocked (pending))
982
    {
983 984
      _dbus_connection_remove_timeout_unlocked (connection,
                                                _dbus_pending_call_get_timeout_unlocked (pending));
985
      
986
      _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
987
    }
988

989 990 991 992
  /* 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.
993 994 995 996 997
   */
  _dbus_connection_ref_unlocked (connection);
  _dbus_pending_call_unref_and_unlock (pending);
  CONNECTION_LOCK (connection);
  _dbus_connection_unref_unlocked (connection);
998 999
}

1000 1001 1002 1003
static void
_dbus_connection_detach_pending_call_unlocked (DBusConnection  *connection,
                                               DBusPendingCall *pending)
{
1004 1005 1006
  /* This ends up unlocking to call the pending call finalizer, which is unexpected to
   * say the least.
   */
1007
  _dbus_hash_table_remove_int (connection->pending_replies,
1008
                               _dbus_pending_call_get_reply_serial_unlocked (pending));
1009 1010
}

1011 1012 1013 1014 1015 1016 1017
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.
1018 1019 1020
   *
   * There's an extra unlock inside the hash table
   * "free pending call" function FIXME...
1021
   */
1022
  _dbus_pending_call_ref_unlocked (pending);
1023
  _dbus_hash_table_remove_int (connection->pending_replies,
1024
                               _dbus_pending_call_get_reply_serial_unlocked (pending));
1025 1026 1027 1028 1029 1030 1031

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

1032
  _dbus_pending_call_unref_and_unlock (pending);
1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049
}

/**
 * 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);
}
1050 1051 1052 1053

/**
 * Acquire the transporter I/O path. This must be done before
 * doing any I/O in the transporter. May sleep and drop the
1054
 * IO path mutex while waiting for the I/O path.
1055 1056 1057 1058 1059 1060 1061
 *
 * @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,
1062
				  int             timeout_milliseconds)
1063
{
1064 1065 1066 1067 1068 1069 1070 1071 1072 1073
  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);
  
1074
  _dbus_verbose ("locking io_path_mutex\n");
1075
  _dbus_cmutex_lock (connection->io_path_mutex);
1076

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

  we_acquired = FALSE;
1081
  
1082 1083
  if (connection->io_path_acquired)
    {
1084 1085
      if (timeout_milliseconds != -1)
        {
1086 1087
          _dbus_verbose ("waiting %d for IO path to be acquirable\n",
                         timeout_milliseconds);
1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101

          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.)
               */
            }
1102
        }
1103
      else
1104 1105 1106
        {
          while (connection->io_path_acquired)
            {
1107
              _dbus_verbose ("waiting for IO path to be acquirable\n");
1108 1109
              _dbus_condvar_wait (connection->io_path_cond, 
                                  connection->io_path_mutex);
1110 1111
            }
        }
1112 1113
    }
  
1114
  if (!connection->io_path_acquired)
1115
    {
1116
      we_acquired = TRUE;
1117 1118
      connection->io_path_acquired = TRUE;
    }
1119
  
1120 1121
  _dbus_verbose ("end connection->io_path_acquired = %d we_acquired = %d\n",
                 connection->io_path_acquired, we_acquired);
1122

1123
  _dbus_verbose ("unlocking io_path_mutex\n");
1124
  _dbus_cmutex_unlock (connection->io_path_mutex);
1125

1126
  CONNECTION_LOCK (connection);
1127
  
1128 1129 1130 1131 1132
  HAVE_LOCK_CHECK (connection);

  _dbus_connection_unref_unlocked (connection);
  
  return we_acquired;
1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144
}

/**
 * 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)
{
1145 1146
  HAVE_LOCK_CHECK (connection);
  
1147
  _dbus_verbose ("locking io_path_mutex\n");
1148
  _dbus_cmutex_lock (connection->io_path_mutex);
1149
  
1150 1151
  _dbus_assert (connection->io_path_acquired);

1152 1153
  _dbus_verbose ("start connection->io_path_acquired = %d\n",
                 connection->io_path_acquired);
1154
  
1155
  connection->io_path_acquired = FALSE;
1156
  _dbus_condvar_wake_one (connection->io_path_cond);
1157

1158
  _dbus_verbose ("unlocking io_path_mutex\n");
1159
  _dbus_cmutex_unlock (connection->io_path_mutex);
1160
}
1161

1162 1163 1164
/**
 * Queues incoming messages and sends outgoing messages for this
 * connection, optionally blocking in the process. Each call to
1165
 * _dbus_connection_do_iteration_unlocked() will call select() or poll() one
1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182
 * 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.
1183
 *
1184 1185 1186 1187 1188 1189
 * 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.
 *
1190
 * Called with connection lock held.
1191 1192
 * 
 * @param connection the connection.
1193
 * @param pending the pending call that should be checked or NULL
1194 1195 1196 1197
 * @param flags iteration flags.
 * @param timeout_milliseconds maximum blocking time, or -1 for no limit.
 */
void
1198
_dbus_connection_do_iteration_unlocked (DBusConnection *connection,
1199
                                        DBusPendingCall *pending,
1200 1201
                                        unsigned int    flags,
                                        int             timeout_milliseconds)
1202
{
1203
  _dbus_verbose ("start\n");