2005-02-17 Colin Walters <walters@verbum.org>
[platform/upstream/dbus.git] / dbus / dbus-connection.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-connection.c DBusConnection object
3  *
4  * Copyright (C) 2002, 2003, 2004, 2005  Red Hat Inc.
5  *
6  * Licensed under the Academic Free License version 2.1
7  * 
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  * 
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  */
23
24 #include <config.h>
25 #include "dbus-shared.h"
26 #include "dbus-connection.h"
27 #include "dbus-list.h"
28 #include "dbus-timeout.h"
29 #include "dbus-transport.h"
30 #include "dbus-watch.h"
31 #include "dbus-connection-internal.h"
32 #include "dbus-list.h"
33 #include "dbus-hash.h"
34 #include "dbus-message-internal.h"
35 #include "dbus-threads.h"
36 #include "dbus-protocol.h"
37 #include "dbus-dataslot.h"
38 #include "dbus-string.h"
39 #include "dbus-pending-call.h"
40 #include "dbus-object-tree.h"
41
42 #ifdef DBUS_DISABLE_CHECKS
43 #define TOOK_LOCK_CHECK(connection)
44 #define RELEASING_LOCK_CHECK(connection)
45 #define HAVE_LOCK_CHECK(connection)
46 #else
47 #define TOOK_LOCK_CHECK(connection) do {                \
48     _dbus_assert (!(connection)->have_connection_lock); \
49     (connection)->have_connection_lock = TRUE;          \
50   } while (0)
51 #define RELEASING_LOCK_CHECK(connection) do {            \
52     _dbus_assert ((connection)->have_connection_lock);   \
53     (connection)->have_connection_lock = FALSE;          \
54   } while (0)
55 #define HAVE_LOCK_CHECK(connection)        _dbus_assert ((connection)->have_connection_lock)
56 /* A "DO_NOT_HAVE_LOCK_CHECK" is impossible since we need the lock to check the flag */
57 #endif
58
59 #define TRACE_LOCKS 1
60
61 #define CONNECTION_LOCK(connection)   do {                                      \
62     if (TRACE_LOCKS) { _dbus_verbose ("  LOCK: %s\n", _DBUS_FUNCTION_NAME); }   \
63     dbus_mutex_lock ((connection)->mutex);                                      \
64     TOOK_LOCK_CHECK (connection);                                               \
65   } while (0)
66
67 #define CONNECTION_UNLOCK(connection) do {                                              \
68     if (TRACE_LOCKS) { _dbus_verbose ("  UNLOCK: %s\n", _DBUS_FUNCTION_NAME);  }        \
69     RELEASING_LOCK_CHECK (connection);                                                  \
70     dbus_mutex_unlock ((connection)->mutex);                                            \
71   } while (0)
72
73 #define DISPATCH_STATUS_NAME(s)                                            \
74                      ((s) == DBUS_DISPATCH_COMPLETE ? "complete" :         \
75                       (s) == DBUS_DISPATCH_DATA_REMAINS ? "data remains" : \
76                       (s) == DBUS_DISPATCH_NEED_MEMORY ? "need memory" :   \
77                       "???")
78
79 /**
80  * @defgroup DBusConnection DBusConnection
81  * @ingroup  DBus
82  * @brief Connection to another application
83  *
84  * A DBusConnection represents a connection to another
85  * application. Messages can be sent and received via this connection.
86  * The other application may be a message bus; for convenience, the
87  * function dbus_bus_get() is provided to automatically open a
88  * connection to the well-known message buses.
89  * 
90  * In brief a DBusConnection is a message queue associated with some
91  * message transport mechanism such as a socket.  The connection
92  * maintains a queue of incoming messages and a queue of outgoing
93  * messages.
94  *
95  * Incoming messages are normally processed by calling
96  * dbus_connection_dispatch(). dbus_connection_dispatch() runs any
97  * handlers registered for the topmost message in the message queue,
98  * then discards the message, then returns.
99  * 
100  * dbus_connection_get_dispatch_status() indicates whether
101  * messages are currently in the queue that need dispatching.
102  * dbus_connection_set_dispatch_status_function() allows
103  * you to set a function to be used to monitor the dispatch status.
104  *
105  * If you're using GLib or Qt add-on libraries for D-BUS, there are
106  * special convenience APIs in those libraries that hide
107  * all the details of dispatch and watch/timeout monitoring.
108  * For example, dbus_connection_setup_with_g_main().
109  *
110  * If you aren't using these add-on libraries, you have to manually
111  * call dbus_connection_set_dispatch_status_function(),
112  * dbus_connection_set_watch_functions(),
113  * dbus_connection_set_timeout_functions() providing appropriate
114  * functions to integrate the connection with your application's main
115  * loop.
116  *
117  * When you use dbus_connection_send() or one of its variants to send
118  * a message, the message is added to the outgoing queue.  It's
119  * actually written to the network later; either in
120  * dbus_watch_handle() invoked by your main loop, or in
121  * dbus_connection_flush() which blocks until it can write out the
122  * entire outgoing queue. The GLib/Qt add-on libraries again
123  * handle the details here for you by setting up watch functions.
124  *
125  * When a connection is disconnected, you are guaranteed to get a
126  * signal "Disconnected" from the interface
127  * #DBUS_INTERFACE_LOCAL, path
128  * #DBUS_PATH_LOCAL.
129  *
130  * You may not drop the last reference to a #DBusConnection
131  * until that connection has been disconnected.
132  *
133  * You may dispatch the unprocessed incoming message queue even if the
134  * connection is disconnected. However, "Disconnected" will always be
135  * the last message in the queue (obviously no messages are received
136  * after disconnection).
137  *
138  * #DBusConnection has thread locks and drops them when invoking user
139  * callbacks, so in general is transparently threadsafe. However,
140  * #DBusMessage does NOT have thread locks; you must not send the same
141  * message to multiple #DBusConnection that will be used from
142  * different threads.
143  */
144
145 /**
146  * @defgroup DBusConnectionInternals DBusConnection implementation details
147  * @ingroup  DBusInternals
148  * @brief Implementation details of DBusConnection
149  *
150  * @{
151  */
152
153 /**
154  * Internal struct representing a message filter function 
155  */
156 typedef struct DBusMessageFilter DBusMessageFilter;
157
158 /**
159  * Internal struct representing a message filter function 
160  */
161 struct DBusMessageFilter
162 {
163   DBusAtomic refcount; /**< Reference count */
164   DBusHandleMessageFunction function; /**< Function to call to filter */
165   void *user_data; /**< User data for the function */
166   DBusFreeFunction free_user_data_function; /**< Function to free the user data */
167 };
168
169
170 /**
171  * Internals of DBusPreallocatedSend
172  */
173 struct DBusPreallocatedSend
174 {
175   DBusConnection *connection; /**< Connection we'd send the message to */
176   DBusList *queue_link;       /**< Preallocated link in the queue */
177   DBusList *counter_link;     /**< Preallocated link in the resource counter */
178 };
179
180 static dbus_bool_t _dbus_modify_sigpipe = TRUE;
181
182 /**
183  * Implementation details of DBusConnection. All fields are private.
184  */
185 struct DBusConnection
186 {
187   DBusAtomic refcount; /**< Reference count. */
188
189   DBusMutex *mutex; /**< Lock on the entire DBusConnection */
190
191   DBusMutex *dispatch_mutex;     /**< Protects dispatch_acquired */
192   DBusCondVar *dispatch_cond;    /**< Notify when dispatch_acquired is available */
193   DBusMutex *io_path_mutex;      /**< Protects io_path_acquired */
194   DBusCondVar *io_path_cond;     /**< Notify when io_path_acquired is available */
195   
196   DBusList *outgoing_messages; /**< Queue of messages we need to send, send the end of the list first. */
197   DBusList *incoming_messages; /**< Queue of messages we have received, end of the list received most recently. */
198
199   DBusMessage *message_borrowed; /**< Filled in if the first incoming message has been borrowed;
200                                   *   dispatch_acquired will be set by the borrower
201                                   */
202   
203   int n_outgoing;              /**< Length of outgoing queue. */
204   int n_incoming;              /**< Length of incoming queue. */
205
206   DBusCounter *outgoing_counter; /**< Counts size of outgoing messages. */
207   
208   DBusTransport *transport;    /**< Object that sends/receives messages over network. */
209   DBusWatchList *watches;      /**< Stores active watches. */
210   DBusTimeoutList *timeouts;   /**< Stores active timeouts. */
211   
212   DBusList *filter_list;        /**< List of filters. */
213
214   DBusDataSlotList slot_list;   /**< Data stored by allocated integer ID */
215
216   DBusHashTable *pending_replies;  /**< Hash of message serials to #DBusPendingCall. */  
217   
218   dbus_uint32_t client_serial;       /**< Client serial. Increments each time a message is sent  */
219   DBusList *disconnect_message_link; /**< Preallocated list node for queueing the disconnection message */
220
221   DBusWakeupMainFunction wakeup_main_function; /**< Function to wake up the mainloop  */
222   void *wakeup_main_data; /**< Application data for wakeup_main_function */
223   DBusFreeFunction free_wakeup_main_data; /**< free wakeup_main_data */
224
225   DBusDispatchStatusFunction dispatch_status_function; /**< Function on dispatch status changes  */
226   void *dispatch_status_data; /**< Application data for dispatch_status_function */
227   DBusFreeFunction free_dispatch_status_data; /**< free dispatch_status_data */
228
229   DBusDispatchStatus last_dispatch_status; /**< The last dispatch status we reported to the application. */
230
231   DBusList *link_cache; /**< A cache of linked list links to prevent contention
232                          *   for the global linked list mempool lock
233                          */
234   DBusObjectTree *objects; /**< Object path handlers registered with this connection */
235   
236   unsigned int dispatch_acquired : 1; /**< Someone has dispatch path (can drain incoming queue) */
237   unsigned int io_path_acquired : 1;  /**< Someone has transport io path (can use the transport to read/write messages) */
238   
239   unsigned int exit_on_disconnect : 1; /**< If #TRUE, exit after handling disconnect signal */
240   
241 #ifndef DBUS_DISABLE_CHECKS
242   unsigned int have_connection_lock : 1; /**< Used to check locking */
243 #endif
244   
245 #ifndef DBUS_DISABLE_CHECKS
246   int generation; /**< _dbus_current_generation that should correspond to this connection */
247 #endif 
248 };
249
250 static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked      (DBusConnection     *connection);
251 static void               _dbus_connection_update_dispatch_status_and_unlock (DBusConnection     *connection,
252                                                                               DBusDispatchStatus  new_status);
253 static void               _dbus_connection_last_unref                        (DBusConnection     *connection);
254 static void               _dbus_connection_acquire_dispatch                  (DBusConnection     *connection);
255 static void               _dbus_connection_release_dispatch                  (DBusConnection     *connection);
256
257 static DBusMessageFilter *
258 _dbus_message_filter_ref (DBusMessageFilter *filter)
259 {
260   _dbus_assert (filter->refcount.value > 0);
261   _dbus_atomic_inc (&filter->refcount);
262
263   return filter;
264 }
265
266 static void
267 _dbus_message_filter_unref (DBusMessageFilter *filter)
268 {
269   _dbus_assert (filter->refcount.value > 0);
270
271   if (_dbus_atomic_dec (&filter->refcount) == 1)
272     {
273       if (filter->free_user_data_function)
274         (* filter->free_user_data_function) (filter->user_data);
275       
276       dbus_free (filter);
277     }
278 }
279
280 /**
281  * Acquires the connection lock.
282  *
283  * @param connection the connection.
284  */
285 void
286 _dbus_connection_lock (DBusConnection *connection)
287 {
288   CONNECTION_LOCK (connection);
289 }
290
291 /**
292  * Releases the connection lock.
293  *
294  * @param connection the connection.
295  */
296 void
297 _dbus_connection_unlock (DBusConnection *connection)
298 {
299   CONNECTION_UNLOCK (connection);
300 }
301
302 /**
303  * Wakes up the main loop if it is sleeping
304  * Needed if we're e.g. queueing outgoing messages
305  * on a thread while the mainloop sleeps.
306  *
307  * @param connection the connection.
308  */
309 static void
310 _dbus_connection_wakeup_mainloop (DBusConnection *connection)
311 {
312   if (connection->wakeup_main_function)
313     (*connection->wakeup_main_function) (connection->wakeup_main_data);
314 }
315
316 #ifdef DBUS_BUILD_TESTS
317 /* For now this function isn't used */
318 /**
319  * Adds a message to the incoming message queue, returning #FALSE
320  * if there's insufficient memory to queue the message.
321  * Does not take over refcount of the message.
322  *
323  * @param connection the connection.
324  * @param message the message to queue.
325  * @returns #TRUE on success.
326  */
327 dbus_bool_t
328 _dbus_connection_queue_received_message (DBusConnection *connection,
329                                          DBusMessage    *message)
330 {
331   DBusList *link;
332
333   link = _dbus_list_alloc_link (message);
334   if (link == NULL)
335     return FALSE;
336
337   dbus_message_ref (message);
338   _dbus_connection_queue_received_message_link (connection, link);
339
340   return TRUE;
341 }
342 #endif
343
344 /**
345  * Adds a message-containing list link to the incoming message queue,
346  * taking ownership of the link and the message's current refcount.
347  * Cannot fail due to lack of memory.
348  *
349  * @param connection the connection.
350  * @param link the message link to queue.
351  */
352 void
353 _dbus_connection_queue_received_message_link (DBusConnection  *connection,
354                                               DBusList        *link)
355 {
356   DBusPendingCall *pending;
357   dbus_int32_t reply_serial;
358   DBusMessage *message;
359   
360   _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport));
361   
362   _dbus_list_append_link (&connection->incoming_messages,
363                           link);
364   message = link->data;
365
366   /* If this is a reply we're waiting on, remove timeout for it */
367   reply_serial = dbus_message_get_reply_serial (message);
368   if (reply_serial != -1)
369     {
370       pending = _dbus_hash_table_lookup_int (connection->pending_replies,
371                                              reply_serial);
372       if (pending != NULL)
373         {
374           if (pending->timeout_added)
375             _dbus_connection_remove_timeout (connection,
376                                              pending->timeout);
377
378           pending->timeout_added = FALSE;
379         }
380     }
381   
382   connection->n_incoming += 1;
383
384   _dbus_connection_wakeup_mainloop (connection);
385   
386   _dbus_verbose ("Message %p (%d %s %s %s '%s' reply to %u) added to incoming queue %p, %d incoming\n",
387                  message,
388                  dbus_message_get_type (message),
389                  dbus_message_get_path (message),
390                  dbus_message_get_interface (message) ?
391                  dbus_message_get_interface (message) :
392                  "no interface",
393                  dbus_message_get_member (message) ?
394                  dbus_message_get_member (message) :
395                  "no member",
396                  dbus_message_get_signature (message),
397                  dbus_message_get_reply_serial (message),
398                  connection,
399                  connection->n_incoming);
400 }
401
402 /**
403  * Adds a link + message to the incoming message queue.
404  * Can't fail. Takes ownership of both link and message.
405  *
406  * @param connection the connection.
407  * @param link the list node and message to queue.
408  *
409  * @todo This needs to wake up the mainloop if it is in
410  * a poll/select and this is a multithreaded app.
411  */
412 static void
413 _dbus_connection_queue_synthesized_message_link (DBusConnection *connection,
414                                                  DBusList *link)
415 {
416   HAVE_LOCK_CHECK (connection);
417   
418   _dbus_list_append_link (&connection->incoming_messages, link);
419
420   connection->n_incoming += 1;
421
422   _dbus_connection_wakeup_mainloop (connection);
423   
424   _dbus_verbose ("Synthesized message %p added to incoming queue %p, %d incoming\n",
425                  link->data, connection, connection->n_incoming);
426 }
427
428
429 /**
430  * Checks whether there are messages in the outgoing message queue.
431  * Called with connection lock held.
432  *
433  * @param connection the connection.
434  * @returns #TRUE if the outgoing queue is non-empty.
435  */
436 dbus_bool_t
437 _dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection)
438 {
439   HAVE_LOCK_CHECK (connection);
440   return connection->outgoing_messages != NULL;
441 }
442
443 /**
444  * Checks whether there are messages in the outgoing message queue.
445  *
446  * @param connection the connection.
447  * @returns #TRUE if the outgoing queue is non-empty.
448  */
449 dbus_bool_t
450 dbus_connection_has_messages_to_send (DBusConnection *connection)
451 {
452   dbus_bool_t v;
453   
454   _dbus_return_val_if_fail (connection != NULL, FALSE);
455
456   CONNECTION_LOCK (connection);
457   v = _dbus_connection_has_messages_to_send_unlocked (connection);
458   CONNECTION_UNLOCK (connection);
459
460   return v;
461 }
462
463 /**
464  * Gets the next outgoing message. The message remains in the
465  * queue, and the caller does not own a reference to it.
466  *
467  * @param connection the connection.
468  * @returns the message to be sent.
469  */ 
470 DBusMessage*
471 _dbus_connection_get_message_to_send (DBusConnection *connection)
472 {
473   HAVE_LOCK_CHECK (connection);
474   
475   return _dbus_list_get_last (&connection->outgoing_messages);
476 }
477
478 /**
479  * Notifies the connection that a message has been sent, so the
480  * message can be removed from the outgoing queue.
481  * Called with the connection lock held.
482  *
483  * @param connection the connection.
484  * @param message the message that was sent.
485  */
486 void
487 _dbus_connection_message_sent (DBusConnection *connection,
488                                DBusMessage    *message)
489 {
490   DBusList *link;
491
492   HAVE_LOCK_CHECK (connection);
493   
494   /* This can be called before we even complete authentication, since
495    * it's called on disconnect to clean up the outgoing queue.
496    * It's also called as we successfully send each message.
497    */
498   
499   link = _dbus_list_get_last_link (&connection->outgoing_messages);
500   _dbus_assert (link != NULL);
501   _dbus_assert (link->data == message);
502
503   /* Save this link in the link cache */
504   _dbus_list_unlink (&connection->outgoing_messages,
505                      link);
506   _dbus_list_prepend_link (&connection->link_cache, link);
507   
508   connection->n_outgoing -= 1;
509
510   _dbus_verbose ("Message %p (%d %s %s %s '%s') removed from outgoing queue %p, %d left to send\n",
511                  message,
512                  dbus_message_get_type (message),
513                  dbus_message_get_path (message),
514                  dbus_message_get_interface (message) ?
515                  dbus_message_get_interface (message) :
516                  "no interface",
517                  dbus_message_get_member (message) ?
518                  dbus_message_get_member (message) :
519                  "no member",
520                  dbus_message_get_signature (message),
521                  connection, connection->n_outgoing);
522
523   /* Save this link in the link cache also */
524   _dbus_message_remove_size_counter (message, connection->outgoing_counter,
525                                      &link);
526   _dbus_list_prepend_link (&connection->link_cache, link);
527   
528   dbus_message_unref (message);
529 }
530
531 typedef dbus_bool_t (* DBusWatchAddFunction)     (DBusWatchList *list,
532                                                   DBusWatch     *watch);
533 typedef void        (* DBusWatchRemoveFunction)  (DBusWatchList *list,
534                                                   DBusWatch     *watch);
535 typedef void        (* DBusWatchToggleFunction)  (DBusWatchList *list,
536                                                   DBusWatch     *watch,
537                                                   dbus_bool_t    enabled);
538
539 static dbus_bool_t
540 protected_change_watch (DBusConnection         *connection,
541                         DBusWatch              *watch,
542                         DBusWatchAddFunction    add_function,
543                         DBusWatchRemoveFunction remove_function,
544                         DBusWatchToggleFunction toggle_function,
545                         dbus_bool_t             enabled)
546 {
547   DBusWatchList *watches;
548   dbus_bool_t retval;
549   
550   HAVE_LOCK_CHECK (connection);
551
552   /* This isn't really safe or reasonable; a better pattern is the "do everything, then
553    * drop lock and call out" one; but it has to be propagated up through all callers
554    */
555   
556   watches = connection->watches;
557   if (watches)
558     {
559       connection->watches = NULL;
560       _dbus_connection_ref_unlocked (connection);
561       CONNECTION_UNLOCK (connection);
562
563       if (add_function)
564         retval = (* add_function) (watches, watch);
565       else if (remove_function)
566         {
567           retval = TRUE;
568           (* remove_function) (watches, watch);
569         }
570       else
571         {
572           retval = TRUE;
573           (* toggle_function) (watches, watch, enabled);
574         }
575       
576       CONNECTION_LOCK (connection);
577       connection->watches = watches;
578       _dbus_connection_unref_unlocked (connection);
579
580       return retval;
581     }
582   else
583     return FALSE;
584 }
585      
586
587 /**
588  * Adds a watch using the connection's DBusAddWatchFunction if
589  * available. Otherwise records the watch to be added when said
590  * function is available. Also re-adds the watch if the
591  * DBusAddWatchFunction changes. May fail due to lack of memory.
592  *
593  * @param connection the connection.
594  * @param watch the watch to add.
595  * @returns #TRUE on success.
596  */
597 dbus_bool_t
598 _dbus_connection_add_watch (DBusConnection *connection,
599                             DBusWatch      *watch)
600 {
601   return protected_change_watch (connection, watch,
602                                  _dbus_watch_list_add_watch,
603                                  NULL, NULL, FALSE);
604 }
605
606 /**
607  * Removes a watch using the connection's DBusRemoveWatchFunction
608  * if available. It's an error to call this function on a watch
609  * that was not previously added.
610  *
611  * @param connection the connection.
612  * @param watch the watch to remove.
613  */
614 void
615 _dbus_connection_remove_watch (DBusConnection *connection,
616                                DBusWatch      *watch)
617 {
618   protected_change_watch (connection, watch,
619                           NULL,
620                           _dbus_watch_list_remove_watch,
621                           NULL, FALSE);
622 }
623
624 /**
625  * Toggles a watch and notifies app via connection's
626  * DBusWatchToggledFunction if available. It's an error to call this
627  * function on a watch that was not previously added.
628  * Connection lock should be held when calling this.
629  *
630  * @param connection the connection.
631  * @param watch the watch to toggle.
632  * @param enabled whether to enable or disable
633  */
634 void
635 _dbus_connection_toggle_watch (DBusConnection *connection,
636                                DBusWatch      *watch,
637                                dbus_bool_t     enabled)
638 {
639   _dbus_assert (watch != NULL);
640
641   protected_change_watch (connection, watch,
642                           NULL, NULL,
643                           _dbus_watch_list_toggle_watch,
644                           enabled);
645 }
646
647 typedef dbus_bool_t (* DBusTimeoutAddFunction)    (DBusTimeoutList *list,
648                                                    DBusTimeout     *timeout);
649 typedef void        (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list,
650                                                    DBusTimeout     *timeout);
651 typedef void        (* DBusTimeoutToggleFunction) (DBusTimeoutList *list,
652                                                    DBusTimeout     *timeout,
653                                                    dbus_bool_t      enabled);
654
655 static dbus_bool_t
656 protected_change_timeout (DBusConnection           *connection,
657                           DBusTimeout              *timeout,
658                           DBusTimeoutAddFunction    add_function,
659                           DBusTimeoutRemoveFunction remove_function,
660                           DBusTimeoutToggleFunction toggle_function,
661                           dbus_bool_t               enabled)
662 {
663   DBusTimeoutList *timeouts;
664   dbus_bool_t retval;
665   
666   HAVE_LOCK_CHECK (connection);
667
668   /* This isn't really safe or reasonable; a better pattern is the "do everything, then
669    * drop lock and call out" one; but it has to be propagated up through all callers
670    */
671   
672   timeouts = connection->timeouts;
673   if (timeouts)
674     {
675       connection->timeouts = NULL;
676       _dbus_connection_ref_unlocked (connection);
677       CONNECTION_UNLOCK (connection);
678
679       if (add_function)
680         retval = (* add_function) (timeouts, timeout);
681       else if (remove_function)
682         {
683           retval = TRUE;
684           (* remove_function) (timeouts, timeout);
685         }
686       else
687         {
688           retval = TRUE;
689           (* toggle_function) (timeouts, timeout, enabled);
690         }
691       
692       CONNECTION_LOCK (connection);
693       connection->timeouts = timeouts;
694       _dbus_connection_unref_unlocked (connection);
695
696       return retval;
697     }
698   else
699     return FALSE;
700 }
701
702 /**
703  * Adds a timeout using the connection's DBusAddTimeoutFunction if
704  * available. Otherwise records the timeout to be added when said
705  * function is available. Also re-adds the timeout if the
706  * DBusAddTimeoutFunction changes. May fail due to lack of memory.
707  * The timeout will fire repeatedly until removed.
708  *
709  * @param connection the connection.
710  * @param timeout the timeout to add.
711  * @returns #TRUE on success.
712  */
713 dbus_bool_t
714 _dbus_connection_add_timeout (DBusConnection *connection,
715                               DBusTimeout    *timeout)
716 {
717   return protected_change_timeout (connection, timeout,
718                                    _dbus_timeout_list_add_timeout,
719                                    NULL, NULL, FALSE);
720 }
721
722 /**
723  * Removes a timeout using the connection's DBusRemoveTimeoutFunction
724  * if available. It's an error to call this function on a timeout
725  * that was not previously added.
726  *
727  * @param connection the connection.
728  * @param timeout the timeout to remove.
729  */
730 void
731 _dbus_connection_remove_timeout (DBusConnection *connection,
732                                  DBusTimeout    *timeout)
733 {
734   protected_change_timeout (connection, timeout,
735                             NULL,
736                             _dbus_timeout_list_remove_timeout,
737                             NULL, FALSE);
738 }
739
740 /**
741  * Toggles a timeout and notifies app via connection's
742  * DBusTimeoutToggledFunction if available. It's an error to call this
743  * function on a timeout that was not previously added.
744  *
745  * @param connection the connection.
746  * @param timeout the timeout to toggle.
747  * @param enabled whether to enable or disable
748  */
749 void
750 _dbus_connection_toggle_timeout (DBusConnection   *connection,
751                                  DBusTimeout      *timeout,
752                                  dbus_bool_t       enabled)
753 {
754   protected_change_timeout (connection, timeout,
755                             NULL, NULL,
756                             _dbus_timeout_list_toggle_timeout,
757                             enabled);
758 }
759
760 static dbus_bool_t
761 _dbus_connection_attach_pending_call_unlocked (DBusConnection  *connection,
762                                                DBusPendingCall *pending)
763 {
764   HAVE_LOCK_CHECK (connection);
765   
766   _dbus_assert (pending->reply_serial != 0);
767
768   if (!_dbus_connection_add_timeout (connection, pending->timeout))
769     return FALSE;
770   
771   if (!_dbus_hash_table_insert_int (connection->pending_replies,
772                                     pending->reply_serial,
773                                     pending))
774     {
775       _dbus_connection_remove_timeout (connection, pending->timeout);
776
777       HAVE_LOCK_CHECK (connection);
778       return FALSE;
779     }
780   
781   pending->timeout_added = TRUE;
782   pending->connection = connection;
783
784   dbus_pending_call_ref (pending);
785
786   HAVE_LOCK_CHECK (connection);
787   
788   return TRUE;
789 }
790
791 static void
792 free_pending_call_on_hash_removal (void *data)
793 {
794   DBusPendingCall *pending;
795   
796   if (data == NULL)
797     return;
798
799   pending = data;
800
801   if (pending->connection)
802     {
803       if (pending->timeout_added)
804         {
805           _dbus_connection_remove_timeout (pending->connection,
806                                            pending->timeout);
807           pending->timeout_added = FALSE;
808         }
809
810       pending->connection = NULL;
811       
812       dbus_pending_call_unref (pending);
813     }
814 }
815
816 static void
817 _dbus_connection_detach_pending_call_unlocked (DBusConnection  *connection,
818                                                DBusPendingCall *pending)
819 {
820   /* Can't have a destroy notifier on the pending call if we're going to do this */
821
822   dbus_pending_call_ref (pending);
823   _dbus_hash_table_remove_int (connection->pending_replies,
824                                pending->reply_serial);
825   _dbus_assert (pending->connection == NULL);
826   dbus_pending_call_unref (pending);
827 }
828
829 static void
830 _dbus_connection_detach_pending_call_and_unlock (DBusConnection  *connection,
831                                                  DBusPendingCall *pending)
832 {
833   /* The idea here is to avoid finalizing the pending call
834    * with the lock held, since there's a destroy notifier
835    * in pending call that goes out to application code.
836    */
837   dbus_pending_call_ref (pending);
838   _dbus_hash_table_remove_int (connection->pending_replies,
839                                pending->reply_serial);
840   _dbus_assert (pending->connection == NULL);
841   CONNECTION_UNLOCK (connection);
842   dbus_pending_call_unref (pending);
843 }
844
845 /**
846  * Removes a pending call from the connection, such that
847  * the pending reply will be ignored. May drop the last
848  * reference to the pending call.
849  *
850  * @param connection the connection
851  * @param pending the pending call
852  */
853 void
854 _dbus_connection_remove_pending_call (DBusConnection  *connection,
855                                       DBusPendingCall *pending)
856 {
857   CONNECTION_LOCK (connection);
858   _dbus_connection_detach_pending_call_and_unlock (connection, pending);
859 }
860
861 /**
862  * Completes a pending call with the given message,
863  * or if the message is #NULL, by timing out the pending call.
864  * 
865  * @param pending the pending call
866  * @param message the message to complete the call with, or #NULL
867  *  to time out the call
868  */
869 void
870 _dbus_pending_call_complete_and_unlock (DBusPendingCall *pending,
871                                         DBusMessage     *message)
872 {
873   if (message == NULL)
874     {
875       message = pending->timeout_link->data;
876       _dbus_list_clear (&pending->timeout_link);
877     }
878   else
879     dbus_message_ref (message);
880
881   _dbus_verbose ("  handing message %p (%s) to pending call serial %u\n",
882                  message,
883                  dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN ?
884                  "method return" :
885                  dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR ?
886                  "error" : "other type",
887                  pending->reply_serial);
888   
889   _dbus_assert (pending->reply == NULL);
890   _dbus_assert (pending->reply_serial == dbus_message_get_reply_serial (message));
891   pending->reply = message;
892   
893   dbus_pending_call_ref (pending); /* in case there's no app with a ref held */
894   _dbus_connection_detach_pending_call_and_unlock (pending->connection, pending);
895   
896   /* Must be called unlocked since it invokes app callback */
897   _dbus_pending_call_notify (pending);
898   dbus_pending_call_unref (pending);
899 }
900
901 /**
902  * Acquire the transporter I/O path. This must be done before
903  * doing any I/O in the transporter. May sleep and drop the
904  * IO path mutex while waiting for the I/O path.
905  *
906  * @param connection the connection.
907  * @param timeout_milliseconds maximum blocking time, or -1 for no limit.
908  * @returns TRUE if the I/O path was acquired.
909  */
910 static dbus_bool_t
911 _dbus_connection_acquire_io_path (DBusConnection *connection,
912                                   int timeout_milliseconds)
913 {
914   dbus_bool_t we_acquired;
915   
916   HAVE_LOCK_CHECK (connection);
917
918   /* We don't want the connection to vanish */
919   _dbus_connection_ref_unlocked (connection);
920
921   /* We will only touch io_path_acquired which is protected by our mutex */
922   CONNECTION_UNLOCK (connection);
923   
924   _dbus_verbose ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME);
925   dbus_mutex_lock (connection->io_path_mutex);
926
927   _dbus_verbose ("%s start connection->io_path_acquired = %d timeout = %d\n",
928                  _DBUS_FUNCTION_NAME, connection->io_path_acquired, timeout_milliseconds);
929
930   we_acquired = FALSE;
931   
932   if (connection->io_path_acquired)
933     {
934       if (timeout_milliseconds != -1)
935         {
936           _dbus_verbose ("%s waiting %d for IO path to be acquirable\n",
937                          _DBUS_FUNCTION_NAME, timeout_milliseconds);
938           dbus_condvar_wait_timeout (connection->io_path_cond,
939                                      connection->io_path_mutex,
940                                      timeout_milliseconds);
941         }
942       else
943         {
944           while (connection->io_path_acquired)
945             {
946               _dbus_verbose ("%s waiting for IO path to be acquirable\n", _DBUS_FUNCTION_NAME);
947               dbus_condvar_wait (connection->io_path_cond, connection->io_path_mutex);
948             }
949         }
950     }
951   
952   if (!connection->io_path_acquired)
953     {
954       we_acquired = TRUE;
955       connection->io_path_acquired = TRUE;
956     }
957   
958   _dbus_verbose ("%s end connection->io_path_acquired = %d we_acquired = %d\n",
959                  _DBUS_FUNCTION_NAME, connection->io_path_acquired, we_acquired);
960
961   _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME);
962   dbus_mutex_unlock (connection->io_path_mutex);
963
964   CONNECTION_LOCK (connection);
965   
966   HAVE_LOCK_CHECK (connection);
967
968   _dbus_connection_unref_unlocked (connection);
969   
970   return we_acquired;
971 }
972
973 /**
974  * Release the I/O path when you're done with it. Only call
975  * after you've acquired the I/O. Wakes up at most one thread
976  * currently waiting to acquire the I/O path.
977  *
978  * @param connection the connection.
979  */
980 static void
981 _dbus_connection_release_io_path (DBusConnection *connection)
982 {
983   HAVE_LOCK_CHECK (connection);
984   
985   _dbus_verbose ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME);
986   dbus_mutex_lock (connection->io_path_mutex);
987   
988   _dbus_assert (connection->io_path_acquired);
989
990   _dbus_verbose ("%s start connection->io_path_acquired = %d\n",
991                  _DBUS_FUNCTION_NAME, connection->io_path_acquired);
992   
993   connection->io_path_acquired = FALSE;
994   dbus_condvar_wake_one (connection->io_path_cond);
995
996   _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME);
997   dbus_mutex_unlock (connection->io_path_mutex);
998 }
999
1000 /**
1001  * Queues incoming messages and sends outgoing messages for this
1002  * connection, optionally blocking in the process. Each call to
1003  * _dbus_connection_do_iteration_unlocked() will call select() or poll() one
1004  * time and then read or write data if possible.
1005  *
1006  * The purpose of this function is to be able to flush outgoing
1007  * messages or queue up incoming messages without returning
1008  * control to the application and causing reentrancy weirdness.
1009  *
1010  * The flags parameter allows you to specify whether to
1011  * read incoming messages, write outgoing messages, or both,
1012  * and whether to block if no immediate action is possible.
1013  *
1014  * The timeout_milliseconds parameter does nothing unless the
1015  * iteration is blocking.
1016  *
1017  * If there are no outgoing messages and DBUS_ITERATION_DO_READING
1018  * wasn't specified, then it's impossible to block, even if
1019  * you specify DBUS_ITERATION_BLOCK; in that case the function
1020  * returns immediately.
1021  *
1022  * Called with connection lock held.
1023  * 
1024  * @param connection the connection.
1025  * @param flags iteration flags.
1026  * @param timeout_milliseconds maximum blocking time, or -1 for no limit.
1027  */
1028 void
1029 _dbus_connection_do_iteration_unlocked (DBusConnection *connection,
1030                                         unsigned int    flags,
1031                                         int             timeout_milliseconds)
1032 {
1033   _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
1034   
1035   HAVE_LOCK_CHECK (connection);
1036   
1037   if (connection->n_outgoing == 0)
1038     flags &= ~DBUS_ITERATION_DO_WRITING;
1039
1040   if (_dbus_connection_acquire_io_path (connection,
1041                                         (flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0))
1042     {
1043       HAVE_LOCK_CHECK (connection);
1044       
1045       _dbus_transport_do_iteration (connection->transport,
1046                                     flags, timeout_milliseconds);
1047       _dbus_connection_release_io_path (connection);
1048     }
1049
1050   HAVE_LOCK_CHECK (connection);
1051
1052   _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
1053 }
1054
1055 /**
1056  * Creates a new connection for the given transport.  A transport
1057  * represents a message stream that uses some concrete mechanism, such
1058  * as UNIX domain sockets. May return #NULL if insufficient
1059  * memory exists to create the connection.
1060  *
1061  * @param transport the transport.
1062  * @returns the new connection, or #NULL on failure.
1063  */
1064 DBusConnection*
1065 _dbus_connection_new_for_transport (DBusTransport *transport)
1066 {
1067   DBusConnection *connection;
1068   DBusWatchList *watch_list;
1069   DBusTimeoutList *timeout_list;
1070   DBusHashTable *pending_replies;
1071   DBusMutex *mutex;
1072   DBusMutex *io_path_mutex;
1073   DBusMutex *dispatch_mutex;
1074   DBusCondVar *message_returned_cond;
1075   DBusCondVar *dispatch_cond;
1076   DBusCondVar *io_path_cond;
1077   DBusList *disconnect_link;
1078   DBusMessage *disconnect_message;
1079   DBusCounter *outgoing_counter;
1080   DBusObjectTree *objects;
1081   
1082   watch_list = NULL;
1083   connection = NULL;
1084   pending_replies = NULL;
1085   timeout_list = NULL;
1086   mutex = NULL;
1087   io_path_mutex = NULL;
1088   dispatch_mutex = NULL;
1089   message_returned_cond = NULL;
1090   dispatch_cond = NULL;
1091   io_path_cond = NULL;
1092   disconnect_link = NULL;
1093   disconnect_message = NULL;
1094   outgoing_counter = NULL;
1095   objects = NULL;
1096   
1097   watch_list = _dbus_watch_list_new ();
1098   if (watch_list == NULL)
1099     goto error;
1100
1101   timeout_list = _dbus_timeout_list_new ();
1102   if (timeout_list == NULL)
1103     goto error;  
1104
1105   pending_replies =
1106     _dbus_hash_table_new (DBUS_HASH_INT,
1107                           NULL,
1108                           (DBusFreeFunction)free_pending_call_on_hash_removal);
1109   if (pending_replies == NULL)
1110     goto error;
1111   
1112   connection = dbus_new0 (DBusConnection, 1);
1113   if (connection == NULL)
1114     goto error;
1115
1116   mutex = dbus_mutex_new ();
1117   if (mutex == NULL)
1118     goto error;
1119
1120   io_path_mutex = dbus_mutex_new ();
1121   if (io_path_mutex == NULL)
1122     goto error;
1123
1124   dispatch_mutex = dbus_mutex_new ();
1125   if (dispatch_mutex == NULL)
1126     goto error;
1127   
1128   message_returned_cond = dbus_condvar_new ();
1129   if (message_returned_cond == NULL)
1130     goto error;
1131   
1132   dispatch_cond = dbus_condvar_new ();
1133   if (dispatch_cond == NULL)
1134     goto error;
1135   
1136   io_path_cond = dbus_condvar_new ();
1137   if (io_path_cond == NULL)
1138     goto error;
1139
1140   disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL,
1141                                                 DBUS_INTERFACE_LOCAL,
1142                                                 "Disconnected");
1143   
1144   if (disconnect_message == NULL)
1145     goto error;
1146
1147   disconnect_link = _dbus_list_alloc_link (disconnect_message);
1148   if (disconnect_link == NULL)
1149     goto error;
1150
1151   outgoing_counter = _dbus_counter_new ();
1152   if (outgoing_counter == NULL)
1153     goto error;
1154
1155   objects = _dbus_object_tree_new (connection);
1156   if (objects == NULL)
1157     goto error;
1158   
1159   if (_dbus_modify_sigpipe)
1160     _dbus_disable_sigpipe ();
1161   
1162   connection->refcount.value = 1;
1163   connection->mutex = mutex;
1164   connection->dispatch_cond = dispatch_cond;
1165   connection->dispatch_mutex = dispatch_mutex;
1166   connection->io_path_cond = io_path_cond;
1167   connection->io_path_mutex = io_path_mutex;
1168   connection->transport = transport;
1169   connection->watches = watch_list;
1170   connection->timeouts = timeout_list;
1171   connection->pending_replies = pending_replies;
1172   connection->outgoing_counter = outgoing_counter;
1173   connection->filter_list = NULL;
1174   connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE; /* so we're notified first time there's data */
1175   connection->objects = objects;
1176   connection->exit_on_disconnect = FALSE;
1177 #ifndef DBUS_DISABLE_CHECKS
1178   connection->generation = _dbus_current_generation;
1179 #endif
1180   
1181   _dbus_data_slot_list_init (&connection->slot_list);
1182
1183   connection->client_serial = 1;
1184
1185   connection->disconnect_message_link = disconnect_link;
1186
1187   CONNECTION_LOCK (connection);
1188   
1189   if (!_dbus_transport_set_connection (transport, connection))
1190     goto error;
1191
1192   _dbus_transport_ref (transport);
1193
1194   CONNECTION_UNLOCK (connection);
1195   
1196   return connection;
1197   
1198  error:
1199   if (disconnect_message != NULL)
1200     dbus_message_unref (disconnect_message);
1201   
1202   if (disconnect_link != NULL)
1203     _dbus_list_free_link (disconnect_link);
1204   
1205   if (io_path_cond != NULL)
1206     dbus_condvar_free (io_path_cond);
1207   
1208   if (dispatch_cond != NULL)
1209     dbus_condvar_free (dispatch_cond);
1210   
1211   if (message_returned_cond != NULL)
1212     dbus_condvar_free (message_returned_cond);
1213   
1214   if (mutex != NULL)
1215     dbus_mutex_free (mutex);
1216
1217   if (io_path_mutex != NULL)
1218     dbus_mutex_free (io_path_mutex);
1219
1220   if (dispatch_mutex != NULL)
1221     dbus_mutex_free (dispatch_mutex);
1222   
1223   if (connection != NULL)
1224     dbus_free (connection);
1225
1226   if (pending_replies)
1227     _dbus_hash_table_unref (pending_replies);
1228   
1229   if (watch_list)
1230     _dbus_watch_list_free (watch_list);
1231
1232   if (timeout_list)
1233     _dbus_timeout_list_free (timeout_list);
1234
1235   if (outgoing_counter)
1236     _dbus_counter_unref (outgoing_counter);
1237
1238   if (objects)
1239     _dbus_object_tree_unref (objects);
1240   
1241   return NULL;
1242 }
1243
1244 /**
1245  * Increments the reference count of a DBusConnection.
1246  * Requires that the caller already holds the connection lock.
1247  *
1248  * @param connection the connection.
1249  * @returns the connection.
1250  */
1251 DBusConnection *
1252 _dbus_connection_ref_unlocked (DBusConnection *connection)
1253 {  
1254   _dbus_assert (connection != NULL);
1255   _dbus_assert (connection->generation == _dbus_current_generation);
1256
1257   HAVE_LOCK_CHECK (connection);
1258   
1259 #ifdef DBUS_HAVE_ATOMIC_INT
1260   _dbus_atomic_inc (&connection->refcount);
1261 #else
1262   _dbus_assert (connection->refcount.value > 0);
1263   connection->refcount.value += 1;
1264 #endif
1265
1266   return connection;
1267 }
1268
1269 /**
1270  * Decrements the reference count of a DBusConnection.
1271  * Requires that the caller already holds the connection lock.
1272  *
1273  * @param connection the connection.
1274  */
1275 void
1276 _dbus_connection_unref_unlocked (DBusConnection *connection)
1277 {
1278   dbus_bool_t last_unref;
1279
1280   HAVE_LOCK_CHECK (connection);
1281   
1282   _dbus_assert (connection != NULL);
1283
1284   /* The connection lock is better than the global
1285    * lock in the atomic increment fallback
1286    */
1287   
1288 #ifdef DBUS_HAVE_ATOMIC_INT
1289   last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
1290 #else
1291   _dbus_assert (connection->refcount.value > 0);
1292
1293   connection->refcount.value -= 1;
1294   last_unref = (connection->refcount.value == 0);  
1295 #if 0
1296   printf ("unref_unlocked() connection %p count = %d\n", connection, connection->refcount.value);
1297 #endif
1298 #endif
1299   
1300   if (last_unref)
1301     _dbus_connection_last_unref (connection);
1302 }
1303
1304 static dbus_uint32_t
1305 _dbus_connection_get_next_client_serial (DBusConnection *connection)
1306 {
1307   int serial;
1308
1309   serial = connection->client_serial++;
1310
1311   if (connection->client_serial < 0)
1312     connection->client_serial = 1;
1313   
1314   return serial;
1315 }
1316
1317 /**
1318  * A callback for use with dbus_watch_new() to create a DBusWatch.
1319  * 
1320  * @todo This is basically a hack - we could delete _dbus_transport_handle_watch()
1321  * and the virtual handle_watch in DBusTransport if we got rid of it.
1322  * The reason this is some work is threading, see the _dbus_connection_handle_watch()
1323  * implementation.
1324  *
1325  * @param watch the watch.
1326  * @param condition the current condition of the file descriptors being watched.
1327  * @param data must be a pointer to a #DBusConnection
1328  * @returns #FALSE if the IO condition may not have been fully handled due to lack of memory
1329  */
1330 dbus_bool_t
1331 _dbus_connection_handle_watch (DBusWatch                   *watch,
1332                                unsigned int                 condition,
1333                                void                        *data)
1334 {
1335   DBusConnection *connection;
1336   dbus_bool_t retval;
1337   DBusDispatchStatus status;
1338
1339   connection = data;
1340
1341   _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
1342   
1343   CONNECTION_LOCK (connection);
1344   _dbus_connection_acquire_io_path (connection, -1);
1345   HAVE_LOCK_CHECK (connection);
1346   retval = _dbus_transport_handle_watch (connection->transport,
1347                                          watch, condition);
1348
1349   _dbus_connection_release_io_path (connection);
1350
1351   HAVE_LOCK_CHECK (connection);
1352
1353   _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
1354   
1355   status = _dbus_connection_get_dispatch_status_unlocked (connection);
1356
1357   /* this calls out to user code */
1358   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
1359
1360   _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
1361   
1362   return retval;
1363 }
1364
1365 /** @} */
1366
1367 /**
1368  * @addtogroup DBusConnection
1369  *
1370  * @{
1371  */
1372
1373 /**
1374  * Opens a new connection to a remote address.
1375  *
1376  * @todo specify what the address parameter is. Right now
1377  * it's just the name of a UNIX domain socket. It should be
1378  * something more complex that encodes which transport to use.
1379  *
1380  * If the open fails, the function returns #NULL, and provides
1381  * a reason for the failure in the result parameter. Pass
1382  * #NULL for the result parameter if you aren't interested
1383  * in the reason for failure.
1384  * 
1385  * @param address the address.
1386  * @param error address where an error can be returned.
1387  * @returns new connection, or #NULL on failure.
1388  */
1389 DBusConnection*
1390 dbus_connection_open (const char     *address,
1391                       DBusError      *error)
1392 {
1393   DBusConnection *connection;
1394   DBusTransport *transport;
1395
1396   _dbus_return_val_if_fail (address != NULL, NULL);
1397   _dbus_return_val_if_error_is_set (error, NULL);
1398   
1399   transport = _dbus_transport_open (address, error);
1400   if (transport == NULL)
1401     {
1402       _DBUS_ASSERT_ERROR_IS_SET (error);
1403       return NULL;
1404     }
1405   
1406   connection = _dbus_connection_new_for_transport (transport);
1407
1408   _dbus_transport_unref (transport);
1409   
1410   if (connection == NULL)
1411     {
1412       dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
1413       return NULL;
1414     }
1415
1416 #ifndef DBUS_DISABLE_CHECKS
1417   _dbus_assert (!connection->have_connection_lock);
1418 #endif
1419   return connection;
1420 }
1421
1422 /**
1423  * Increments the reference count of a DBusConnection.
1424  *
1425  * @param connection the connection.
1426  * @returns the connection.
1427  */
1428 DBusConnection *
1429 dbus_connection_ref (DBusConnection *connection)
1430 {
1431   _dbus_return_val_if_fail (connection != NULL, NULL);
1432   _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
1433   
1434   /* The connection lock is better than the global
1435    * lock in the atomic increment fallback
1436    */
1437   
1438 #ifdef DBUS_HAVE_ATOMIC_INT
1439   _dbus_atomic_inc (&connection->refcount);
1440 #else
1441   CONNECTION_LOCK (connection);
1442   _dbus_assert (connection->refcount.value > 0);
1443
1444   connection->refcount.value += 1;
1445   CONNECTION_UNLOCK (connection);
1446 #endif
1447
1448   return connection;
1449 }
1450
1451 static void
1452 free_outgoing_message (void *element,
1453                        void *data)
1454 {
1455   DBusMessage *message = element;
1456   DBusConnection *connection = data;
1457
1458   _dbus_message_remove_size_counter (message,
1459                                      connection->outgoing_counter,
1460                                      NULL);
1461   dbus_message_unref (message);
1462 }
1463
1464 /* This is run without the mutex held, but after the last reference
1465  * to the connection has been dropped we should have no thread-related
1466  * problems
1467  */
1468 static void
1469 _dbus_connection_last_unref (DBusConnection *connection)
1470 {
1471   DBusList *link;
1472
1473   _dbus_verbose ("Finalizing connection %p\n", connection);
1474   
1475   _dbus_assert (connection->refcount.value == 0);
1476   
1477   /* You have to disconnect the connection before unref:ing it. Otherwise
1478    * you won't get the disconnected message.
1479    */
1480   _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
1481
1482   /* ---- We're going to call various application callbacks here, hope it doesn't break anything... */
1483   _dbus_object_tree_free_all_unlocked (connection->objects);
1484   
1485   dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
1486   dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
1487   dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
1488   
1489   _dbus_watch_list_free (connection->watches);
1490   connection->watches = NULL;
1491   
1492   _dbus_timeout_list_free (connection->timeouts);
1493   connection->timeouts = NULL;
1494
1495   _dbus_data_slot_list_free (&connection->slot_list);
1496   
1497   link = _dbus_list_get_first_link (&connection->filter_list);
1498   while (link != NULL)
1499     {
1500       DBusMessageFilter *filter = link->data;
1501       DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
1502
1503       filter->function = NULL;
1504       _dbus_message_filter_unref (filter); /* calls app callback */
1505       link->data = NULL;
1506       
1507       link = next;
1508     }
1509   _dbus_list_clear (&connection->filter_list);
1510   
1511   /* ---- Done with stuff that invokes application callbacks */
1512
1513   _dbus_object_tree_unref (connection->objects);  
1514
1515   _dbus_hash_table_unref (connection->pending_replies);
1516   connection->pending_replies = NULL;
1517   
1518   _dbus_list_clear (&connection->filter_list);
1519   
1520   _dbus_list_foreach (&connection->outgoing_messages,
1521                       free_outgoing_message,
1522                       connection);
1523   _dbus_list_clear (&connection->outgoing_messages);
1524   
1525   _dbus_list_foreach (&connection->incoming_messages,
1526                       (DBusForeachFunction) dbus_message_unref,
1527                       NULL);
1528   _dbus_list_clear (&connection->incoming_messages);
1529
1530   _dbus_counter_unref (connection->outgoing_counter);
1531   
1532   _dbus_transport_unref (connection->transport);
1533
1534   if (connection->disconnect_message_link)
1535     {
1536       DBusMessage *message = connection->disconnect_message_link->data;
1537       dbus_message_unref (message);
1538       _dbus_list_free_link (connection->disconnect_message_link);
1539     }
1540
1541   _dbus_list_clear (&connection->link_cache);
1542   
1543   dbus_condvar_free (connection->dispatch_cond);
1544   dbus_condvar_free (connection->io_path_cond);
1545
1546   dbus_mutex_free (connection->io_path_mutex);
1547   dbus_mutex_free (connection->dispatch_mutex);
1548
1549   dbus_mutex_free (connection->mutex);
1550   
1551   dbus_free (connection);
1552 }
1553
1554 /**
1555  * Decrements the reference count of a DBusConnection, and finalizes
1556  * it if the count reaches zero.  It is a bug to drop the last reference
1557  * to a connection that has not been disconnected.
1558  *
1559  * @todo in practice it can be quite tricky to never unref a connection
1560  * that's still connected; maybe there's some way we could avoid
1561  * the requirement.
1562  *
1563  * @param connection the connection.
1564  */
1565 void
1566 dbus_connection_unref (DBusConnection *connection)
1567 {
1568   dbus_bool_t last_unref;
1569
1570   _dbus_return_if_fail (connection != NULL);
1571   _dbus_return_if_fail (connection->generation == _dbus_current_generation);
1572   
1573   /* The connection lock is better than the global
1574    * lock in the atomic increment fallback
1575    */
1576   
1577 #ifdef DBUS_HAVE_ATOMIC_INT
1578   last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
1579 #else
1580   CONNECTION_LOCK (connection);
1581   
1582   _dbus_assert (connection->refcount.value > 0);
1583
1584   connection->refcount.value -= 1;
1585   last_unref = (connection->refcount.value == 0);
1586
1587 #if 0
1588   printf ("unref() connection %p count = %d\n", connection, connection->refcount.value);
1589 #endif
1590   
1591   CONNECTION_UNLOCK (connection);
1592 #endif
1593   
1594   if (last_unref)
1595     _dbus_connection_last_unref (connection);
1596 }
1597
1598 /**
1599  * Closes the connection, so no further data can be sent or received.
1600  * Any further attempts to send data will result in errors.  This
1601  * function does not affect the connection's reference count.  It's
1602  * safe to disconnect a connection more than once; all calls after the
1603  * first do nothing. It's impossible to "reconnect" a connection, a
1604  * new connection must be created. This function may result in a call
1605  * to the DBusDispatchStatusFunction set with
1606  * dbus_connection_set_dispatch_status_function(), as the disconnect
1607  * message it generates needs to be dispatched.
1608  *
1609  * @param connection the connection.
1610  */
1611 void
1612 dbus_connection_disconnect (DBusConnection *connection)
1613 {
1614   DBusDispatchStatus status;
1615   
1616   _dbus_return_if_fail (connection != NULL);
1617   _dbus_return_if_fail (connection->generation == _dbus_current_generation);
1618
1619   _dbus_verbose ("Disconnecting %p\n", connection);
1620   
1621   CONNECTION_LOCK (connection);
1622   _dbus_transport_disconnect (connection->transport);
1623
1624   _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
1625   status = _dbus_connection_get_dispatch_status_unlocked (connection);
1626
1627   /* this calls out to user code */
1628   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
1629 }
1630
1631 static dbus_bool_t
1632 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
1633 {
1634   HAVE_LOCK_CHECK (connection);
1635   return _dbus_transport_get_is_connected (connection->transport);
1636 }
1637
1638 /**
1639  * Gets whether the connection is currently connected.  All
1640  * connections are connected when they are opened.  A connection may
1641  * become disconnected when the remote application closes its end, or
1642  * exits; a connection may also be disconnected with
1643  * dbus_connection_disconnect().
1644  *
1645  * @param connection the connection.
1646  * @returns #TRUE if the connection is still alive.
1647  */
1648 dbus_bool_t
1649 dbus_connection_get_is_connected (DBusConnection *connection)
1650 {
1651   dbus_bool_t res;
1652
1653   _dbus_return_val_if_fail (connection != NULL, FALSE);
1654   
1655   CONNECTION_LOCK (connection);
1656   res = _dbus_connection_get_is_connected_unlocked (connection);
1657   CONNECTION_UNLOCK (connection);
1658   
1659   return res;
1660 }
1661
1662 /**
1663  * Gets whether the connection was authenticated. (Note that
1664  * if the connection was authenticated then disconnected,
1665  * this function still returns #TRUE)
1666  *
1667  * @param connection the connection
1668  * @returns #TRUE if the connection was ever authenticated
1669  */
1670 dbus_bool_t
1671 dbus_connection_get_is_authenticated (DBusConnection *connection)
1672 {
1673   dbus_bool_t res;
1674
1675   _dbus_return_val_if_fail (connection != NULL, FALSE);
1676   
1677   CONNECTION_LOCK (connection);
1678   res = _dbus_transport_get_is_authenticated (connection->transport);
1679   CONNECTION_UNLOCK (connection);
1680   
1681   return res;
1682 }
1683
1684 /**
1685  * Set whether _exit() should be called when the connection receives a
1686  * disconnect signal. The call to _exit() comes after any handlers for
1687  * the disconnect signal run; handlers can cancel the exit by calling
1688  * this function.
1689  *
1690  * By default, exit_on_disconnect is #FALSE; but for message bus
1691  * connections returned from dbus_bus_get() it will be toggled on
1692  * by default.
1693  *
1694  * @param connection the connection
1695  * @param exit_on_disconnect #TRUE if _exit() should be called after a disconnect signal
1696  */
1697 void
1698 dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
1699                                         dbus_bool_t     exit_on_disconnect)
1700 {
1701   _dbus_return_if_fail (connection != NULL);
1702
1703   CONNECTION_LOCK (connection);
1704   connection->exit_on_disconnect = exit_on_disconnect != FALSE;
1705   CONNECTION_UNLOCK (connection);
1706 }
1707
1708 static DBusPreallocatedSend*
1709 _dbus_connection_preallocate_send_unlocked (DBusConnection *connection)
1710 {
1711   DBusPreallocatedSend *preallocated;
1712
1713   HAVE_LOCK_CHECK (connection);
1714   
1715   _dbus_assert (connection != NULL);
1716   
1717   preallocated = dbus_new (DBusPreallocatedSend, 1);
1718   if (preallocated == NULL)
1719     return NULL;
1720
1721   if (connection->link_cache != NULL)
1722     {
1723       preallocated->queue_link =
1724         _dbus_list_pop_first_link (&connection->link_cache);
1725       preallocated->queue_link->data = NULL;
1726     }
1727   else
1728     {
1729       preallocated->queue_link = _dbus_list_alloc_link (NULL);
1730       if (preallocated->queue_link == NULL)
1731         goto failed_0;
1732     }
1733   
1734   if (connection->link_cache != NULL)
1735     {
1736       preallocated->counter_link =
1737         _dbus_list_pop_first_link (&connection->link_cache);
1738       preallocated->counter_link->data = connection->outgoing_counter;
1739     }
1740   else
1741     {
1742       preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter);
1743       if (preallocated->counter_link == NULL)
1744         goto failed_1;
1745     }
1746
1747   _dbus_counter_ref (preallocated->counter_link->data);
1748
1749   preallocated->connection = connection;
1750   
1751   return preallocated;
1752   
1753  failed_1:
1754   _dbus_list_free_link (preallocated->queue_link);
1755  failed_0:
1756   dbus_free (preallocated);
1757   
1758   return NULL;
1759 }
1760
1761 /**
1762  * Preallocates resources needed to send a message, allowing the message 
1763  * to be sent without the possibility of memory allocation failure.
1764  * Allows apps to create a future guarantee that they can send
1765  * a message regardless of memory shortages.
1766  *
1767  * @param connection the connection we're preallocating for.
1768  * @returns the preallocated resources, or #NULL
1769  */
1770 DBusPreallocatedSend*
1771 dbus_connection_preallocate_send (DBusConnection *connection)
1772 {
1773   DBusPreallocatedSend *preallocated;
1774
1775   _dbus_return_val_if_fail (connection != NULL, NULL);
1776
1777   CONNECTION_LOCK (connection);
1778   
1779   preallocated =
1780     _dbus_connection_preallocate_send_unlocked (connection);
1781
1782   CONNECTION_UNLOCK (connection);
1783
1784   return preallocated;
1785 }
1786
1787 /**
1788  * Frees preallocated message-sending resources from
1789  * dbus_connection_preallocate_send(). Should only
1790  * be called if the preallocated resources are not used
1791  * to send a message.
1792  *
1793  * @param connection the connection
1794  * @param preallocated the resources
1795  */
1796 void
1797 dbus_connection_free_preallocated_send (DBusConnection       *connection,
1798                                         DBusPreallocatedSend *preallocated)
1799 {
1800   _dbus_return_if_fail (connection != NULL);
1801   _dbus_return_if_fail (preallocated != NULL);  
1802   _dbus_return_if_fail (connection == preallocated->connection);
1803
1804   _dbus_list_free_link (preallocated->queue_link);
1805   _dbus_counter_unref (preallocated->counter_link->data);
1806   _dbus_list_free_link (preallocated->counter_link);
1807   dbus_free (preallocated);
1808 }
1809
1810 /* Called with lock held, does not update dispatch status */
1811 static void
1812 _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection       *connection,
1813                                                        DBusPreallocatedSend *preallocated,
1814                                                        DBusMessage          *message,
1815                                                        dbus_uint32_t        *client_serial)
1816 {
1817   dbus_uint32_t serial;
1818   const char *sig;
1819
1820   preallocated->queue_link->data = message;
1821   _dbus_list_prepend_link (&connection->outgoing_messages,
1822                            preallocated->queue_link);
1823
1824   _dbus_message_add_size_counter_link (message,
1825                                        preallocated->counter_link);
1826
1827   dbus_free (preallocated);
1828   preallocated = NULL;
1829   
1830   dbus_message_ref (message);
1831   
1832   connection->n_outgoing += 1;
1833
1834   sig = dbus_message_get_signature (message);
1835   
1836   _dbus_verbose ("Message %p (%d %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
1837                  message,
1838                  dbus_message_get_type (message),
1839                  dbus_message_get_path (message),
1840                  dbus_message_get_interface (message) ?
1841                  dbus_message_get_interface (message) :
1842                  "no interface",
1843                  dbus_message_get_member (message) ?
1844                  dbus_message_get_member (message) :
1845                  "no member",
1846                  sig,
1847                  dbus_message_get_destination (message) ?
1848                  dbus_message_get_destination (message) :
1849                  "null",
1850                  connection,
1851                  connection->n_outgoing);
1852
1853   if (dbus_message_get_serial (message) == 0)
1854     {
1855       serial = _dbus_connection_get_next_client_serial (connection);
1856       _dbus_message_set_serial (message, serial);
1857       if (client_serial)
1858         *client_serial = serial;
1859     }
1860   else
1861     {
1862       if (client_serial)
1863         *client_serial = dbus_message_get_serial (message);
1864     }
1865
1866   _dbus_verbose ("Message %p serial is %u\n",
1867                  message, dbus_message_get_serial (message));
1868   
1869   _dbus_message_lock (message);
1870
1871   /* Now we need to run an iteration to hopefully just write the messages
1872    * out immediately, and otherwise get them queued up
1873    */
1874   _dbus_connection_do_iteration_unlocked (connection,
1875                                           DBUS_ITERATION_DO_WRITING,
1876                                           -1);
1877
1878   /* If stuff is still queued up, be sure we wake up the main loop */
1879   if (connection->n_outgoing > 0)
1880     _dbus_connection_wakeup_mainloop (connection);
1881 }
1882
1883 static void
1884 _dbus_connection_send_preallocated_and_unlock (DBusConnection       *connection,
1885                                                DBusPreallocatedSend *preallocated,
1886                                                DBusMessage          *message,
1887                                                dbus_uint32_t        *client_serial)
1888 {
1889   DBusDispatchStatus status;
1890
1891   HAVE_LOCK_CHECK (connection);
1892   
1893   _dbus_connection_send_preallocated_unlocked_no_update (connection,
1894                                                          preallocated,
1895                                                          message, client_serial);
1896
1897   _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
1898   status = _dbus_connection_get_dispatch_status_unlocked (connection);
1899
1900   /* this calls out to user code */
1901   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
1902 }
1903
1904 /**
1905  * Sends a message using preallocated resources. This function cannot fail.
1906  * It works identically to dbus_connection_send() in other respects.
1907  * Preallocated resources comes from dbus_connection_preallocate_send().
1908  * This function "consumes" the preallocated resources, they need not
1909  * be freed separately.
1910  *
1911  * @param connection the connection
1912  * @param preallocated the preallocated resources
1913  * @param message the message to send
1914  * @param client_serial return location for client serial assigned to the message
1915  */
1916 void
1917 dbus_connection_send_preallocated (DBusConnection       *connection,
1918                                    DBusPreallocatedSend *preallocated,
1919                                    DBusMessage          *message,
1920                                    dbus_uint32_t        *client_serial)
1921 {
1922   _dbus_return_if_fail (connection != NULL);
1923   _dbus_return_if_fail (preallocated != NULL);
1924   _dbus_return_if_fail (message != NULL);
1925   _dbus_return_if_fail (preallocated->connection == connection);
1926   _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
1927                         (dbus_message_get_interface (message) != NULL &&
1928                          dbus_message_get_member (message) != NULL));
1929   _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
1930                         (dbus_message_get_interface (message) != NULL &&
1931                          dbus_message_get_member (message) != NULL));
1932   
1933   CONNECTION_LOCK (connection);
1934   _dbus_connection_send_preallocated_and_unlock (connection,
1935                                                  preallocated,
1936                                                  message, client_serial);
1937 }
1938
1939 static dbus_bool_t
1940 _dbus_connection_send_unlocked_no_update (DBusConnection *connection,
1941                                           DBusMessage    *message,
1942                                           dbus_uint32_t  *client_serial)
1943 {
1944   DBusPreallocatedSend *preallocated;
1945
1946   _dbus_assert (connection != NULL);
1947   _dbus_assert (message != NULL);
1948   
1949   preallocated = _dbus_connection_preallocate_send_unlocked (connection);
1950   if (preallocated == NULL)
1951     return FALSE;
1952
1953   _dbus_connection_send_preallocated_unlocked_no_update (connection,
1954                                                          preallocated,
1955                                                          message,
1956                                                          client_serial);
1957   return TRUE;
1958 }
1959
1960 dbus_bool_t
1961 _dbus_connection_send_and_unlock (DBusConnection *connection,
1962                                   DBusMessage    *message,
1963                                   dbus_uint32_t  *client_serial)
1964 {
1965   DBusPreallocatedSend *preallocated;
1966
1967   _dbus_assert (connection != NULL);
1968   _dbus_assert (message != NULL);
1969   
1970   preallocated = _dbus_connection_preallocate_send_unlocked (connection);
1971   if (preallocated == NULL)
1972     {
1973       CONNECTION_UNLOCK (connection);
1974       return FALSE;
1975     }
1976
1977   _dbus_connection_send_preallocated_and_unlock (connection,
1978                                                  preallocated,
1979                                                  message,
1980                                                  client_serial);
1981   return TRUE;
1982 }
1983
1984 /**
1985  * Adds a message to the outgoing message queue. Does not block to
1986  * write the message to the network; that happens asynchronously. To
1987  * force the message to be written, call dbus_connection_flush().
1988  * Because this only queues the message, the only reason it can
1989  * fail is lack of memory. Even if the connection is disconnected,
1990  * no error will be returned.
1991  *
1992  * If the function fails due to lack of memory, it returns #FALSE.
1993  * The function will never fail for other reasons; even if the
1994  * connection is disconnected, you can queue an outgoing message,
1995  * though obviously it won't be sent.
1996  * 
1997  * @param connection the connection.
1998  * @param message the message to write.
1999  * @param client_serial return location for client serial.
2000  * @returns #TRUE on success.
2001  */
2002 dbus_bool_t
2003 dbus_connection_send (DBusConnection *connection,
2004                       DBusMessage    *message,
2005                       dbus_uint32_t  *client_serial)
2006 {
2007   _dbus_return_val_if_fail (connection != NULL, FALSE);
2008   _dbus_return_val_if_fail (message != NULL, FALSE);
2009
2010   CONNECTION_LOCK (connection);
2011
2012   return _dbus_connection_send_and_unlock (connection,
2013                                            message,
2014                                            client_serial);
2015 }
2016
2017 static dbus_bool_t
2018 reply_handler_timeout (void *data)
2019 {
2020   DBusConnection *connection;
2021   DBusDispatchStatus status;
2022   DBusPendingCall *pending = data;
2023
2024   connection = pending->connection;
2025   
2026   CONNECTION_LOCK (connection);
2027   if (pending->timeout_link)
2028     {
2029       _dbus_connection_queue_synthesized_message_link (connection,
2030                                                        pending->timeout_link);
2031       pending->timeout_link = NULL;
2032     }
2033
2034   _dbus_connection_remove_timeout (connection,
2035                                    pending->timeout);
2036   pending->timeout_added = FALSE;
2037
2038   _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
2039   status = _dbus_connection_get_dispatch_status_unlocked (connection);
2040
2041   /* Unlocks, and calls out to user code */
2042   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2043   
2044   return TRUE;
2045 }
2046
2047 /**
2048  * Queues a message to send, as with dbus_connection_send_message(),
2049  * but also returns a #DBusPendingCall used to receive a reply to the
2050  * message. If no reply is received in the given timeout_milliseconds,
2051  * this function expires the pending reply and generates a synthetic
2052  * error reply (generated in-process, not by the remote application)
2053  * indicating that a timeout occurred.
2054  *
2055  * A #DBusPendingCall will see a reply message after any filters, but
2056  * before any object instances or other handlers. A #DBusPendingCall
2057  * will always see exactly one reply message, unless it's cancelled
2058  * with dbus_pending_call_cancel().
2059  * 
2060  * If a filter filters out the reply before the handler sees it, the
2061  * reply is immediately timed out and a timeout error reply is
2062  * generated. If a filter removes the timeout error reply then the
2063  * #DBusPendingCall will get confused. Filtering the timeout error
2064  * is thus considered a bug and will print a warning.
2065  * 
2066  * If #NULL is passed for the pending_return, the #DBusPendingCall
2067  * will still be generated internally, and used to track
2068  * the message reply timeout. This means a timeout error will
2069  * occur if no reply arrives, unlike with dbus_connection_send().
2070  *
2071  * If -1 is passed for the timeout, a sane default timeout is used. -1
2072  * is typically the best value for the timeout for this reason, unless
2073  * you want a very short or very long timeout.  There is no way to
2074  * avoid a timeout entirely, other than passing INT_MAX for the
2075  * timeout to postpone it indefinitely.
2076  * 
2077  * @param connection the connection
2078  * @param message the message to send
2079  * @param pending_return return location for a #DBusPendingCall object, or #NULL
2080  * @param timeout_milliseconds timeout in milliseconds or -1 for default
2081  * @returns #TRUE if the message is successfully queued, #FALSE if no memory.
2082  *
2083  */
2084 dbus_bool_t
2085 dbus_connection_send_with_reply (DBusConnection     *connection,
2086                                  DBusMessage        *message,
2087                                  DBusPendingCall   **pending_return,
2088                                  int                 timeout_milliseconds)
2089 {
2090   DBusPendingCall *pending;
2091   DBusMessage *reply;
2092   DBusList *reply_link;
2093   dbus_int32_t serial = -1;
2094   DBusDispatchStatus status;
2095
2096   _dbus_return_val_if_fail (connection != NULL, FALSE);
2097   _dbus_return_val_if_fail (message != NULL, FALSE);
2098   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
2099
2100   if (pending_return)
2101     *pending_return = NULL;
2102   
2103   pending = _dbus_pending_call_new (connection,
2104                                     timeout_milliseconds,
2105                                     reply_handler_timeout);
2106
2107   if (pending == NULL)
2108     return FALSE;
2109
2110   CONNECTION_LOCK (connection);
2111   
2112   /* Assign a serial to the message */
2113   if (dbus_message_get_serial (message) == 0)
2114     {
2115       serial = _dbus_connection_get_next_client_serial (connection);
2116       _dbus_message_set_serial (message, serial);
2117     }
2118
2119   pending->reply_serial = serial;
2120
2121   reply = dbus_message_new_error (message, DBUS_ERROR_NO_REPLY,
2122                                   "No reply within specified time");
2123   if (reply == NULL)
2124     goto error;
2125
2126   reply_link = _dbus_list_alloc_link (reply);
2127   if (reply_link == NULL)
2128     {
2129       CONNECTION_UNLOCK (connection);
2130       dbus_message_unref (reply);
2131       goto error_unlocked;
2132     }
2133
2134   pending->timeout_link = reply_link;
2135
2136   /* Insert the serial in the pending replies hash;
2137    * hash takes a refcount on DBusPendingCall.
2138    * Also, add the timeout.
2139    */
2140   if (!_dbus_connection_attach_pending_call_unlocked (connection,
2141                                                       pending))
2142     goto error;
2143   
2144   if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
2145     {
2146       _dbus_connection_detach_pending_call_and_unlock (connection,
2147                                                        pending);
2148       goto error_unlocked;
2149     }
2150
2151   if (pending_return)
2152     *pending_return = pending;
2153   else
2154     {
2155       _dbus_connection_detach_pending_call_unlocked (connection, pending);
2156       dbus_pending_call_unref (pending);
2157     }
2158
2159   _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
2160   status = _dbus_connection_get_dispatch_status_unlocked (connection);
2161
2162   /* this calls out to user code */
2163   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2164
2165   return TRUE;
2166
2167  error:
2168   CONNECTION_UNLOCK (connection);
2169  error_unlocked:
2170   dbus_pending_call_unref (pending);
2171   return FALSE;
2172 }
2173
2174 /* This is slightly strange since we can pop a message here without
2175  * the dispatch lock.
2176  */
2177 static DBusMessage*
2178 check_for_reply_unlocked (DBusConnection *connection,
2179                           dbus_uint32_t   client_serial)
2180 {
2181   DBusList *link;
2182
2183   HAVE_LOCK_CHECK (connection);
2184   
2185   link = _dbus_list_get_first_link (&connection->incoming_messages);
2186
2187   while (link != NULL)
2188     {
2189       DBusMessage *reply = link->data;
2190
2191       if (dbus_message_get_reply_serial (reply) == client_serial)
2192         {
2193           _dbus_list_remove_link (&connection->incoming_messages, link);
2194           connection->n_incoming  -= 1;
2195           return reply;
2196         }
2197       link = _dbus_list_get_next_link (&connection->incoming_messages, link);
2198     }
2199
2200   return NULL;
2201 }
2202
2203 /**
2204  * Blocks until a pending call times out or gets a reply.
2205  *
2206  * Does not re-enter the main loop or run filter/path-registered
2207  * callbacks. The reply to the message will not be seen by
2208  * filter callbacks.
2209  *
2210  * Returns immediately if pending call already got a reply.
2211  * 
2212  * @todo could use performance improvements (it keeps scanning
2213  * the whole message queue for example)
2214  *
2215  * @param pending the pending call we block for a reply on
2216  */
2217 void
2218 _dbus_connection_block_pending_call (DBusPendingCall *pending)
2219 {
2220   long start_tv_sec, start_tv_usec;
2221   long end_tv_sec, end_tv_usec;
2222   long tv_sec, tv_usec;
2223   DBusDispatchStatus status;
2224   DBusConnection *connection;
2225   dbus_uint32_t client_serial;
2226   int timeout_milliseconds;
2227
2228   _dbus_assert (pending != NULL);
2229
2230   if (dbus_pending_call_get_completed (pending))
2231     return;
2232
2233   if (pending->connection == NULL)
2234     return; /* call already detached */
2235
2236   dbus_pending_call_ref (pending); /* necessary because the call could be canceled */
2237   
2238   connection = pending->connection;
2239   client_serial = pending->reply_serial;
2240
2241   /* note that timeout_milliseconds is limited to a smallish value
2242    * in _dbus_pending_call_new() so overflows aren't possible
2243    * below
2244    */
2245   timeout_milliseconds = dbus_timeout_get_interval (pending->timeout);
2246
2247   /* Flush message queue */
2248   dbus_connection_flush (connection);
2249
2250   CONNECTION_LOCK (connection);
2251
2252   _dbus_get_current_time (&start_tv_sec, &start_tv_usec);
2253   end_tv_sec = start_tv_sec + timeout_milliseconds / 1000;
2254   end_tv_usec = start_tv_usec + (timeout_milliseconds % 1000) * 1000;
2255   end_tv_sec += end_tv_usec / _DBUS_USEC_PER_SECOND;
2256   end_tv_usec = end_tv_usec % _DBUS_USEC_PER_SECOND;
2257
2258   _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",
2259                  timeout_milliseconds,
2260                  client_serial,
2261                  start_tv_sec, start_tv_usec,
2262                  end_tv_sec, end_tv_usec);
2263
2264   /* Now we wait... */
2265   /* always block at least once as we know we don't have the reply yet */
2266   _dbus_connection_do_iteration_unlocked (connection,
2267                                           DBUS_ITERATION_DO_READING |
2268                                           DBUS_ITERATION_BLOCK,
2269                                           timeout_milliseconds);
2270
2271  recheck_status:
2272
2273   _dbus_verbose ("%s top of recheck\n", _DBUS_FUNCTION_NAME);
2274   
2275   HAVE_LOCK_CHECK (connection);
2276   
2277   /* queue messages and get status */
2278
2279   status = _dbus_connection_get_dispatch_status_unlocked (connection);
2280
2281   /* the get_completed() is in case a dispatch() while we were blocking
2282    * got the reply instead of us.
2283    */
2284   if (dbus_pending_call_get_completed (pending))
2285     {
2286       _dbus_verbose ("Pending call completed by dispatch in %s\n", _DBUS_FUNCTION_NAME);
2287       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2288       return;
2289     }
2290   
2291   if (status == DBUS_DISPATCH_DATA_REMAINS)
2292     {
2293       DBusMessage *reply;
2294       
2295       reply = check_for_reply_unlocked (connection, client_serial);
2296       if (reply != NULL)
2297         {
2298           _dbus_verbose ("%s checked for reply\n", _DBUS_FUNCTION_NAME);
2299
2300           _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
2301           
2302           _dbus_pending_call_complete_and_unlock (pending, reply);
2303           dbus_message_unref (reply);
2304
2305           CONNECTION_LOCK (connection);
2306           status = _dbus_connection_get_dispatch_status_unlocked (connection);
2307           _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2308           
2309           return;
2310         }
2311     }
2312   
2313   _dbus_get_current_time (&tv_sec, &tv_usec);
2314   
2315   if (!_dbus_connection_get_is_connected_unlocked (connection))
2316     {
2317       /* FIXME send a "DBUS_ERROR_DISCONNECTED" instead, just to help
2318        * programmers understand what went wrong since the timeout is
2319        * confusing
2320        */
2321       
2322       _dbus_pending_call_complete_and_unlock (pending, NULL);
2323       return;
2324     }
2325   else if (tv_sec < start_tv_sec)
2326     _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
2327   else if (connection->disconnect_message_link == NULL)
2328     _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
2329   else if (tv_sec < end_tv_sec ||
2330            (tv_sec == end_tv_sec && tv_usec < end_tv_usec))
2331     {
2332       timeout_milliseconds = (end_tv_sec - tv_sec) * 1000 +
2333         (end_tv_usec - tv_usec) / 1000;
2334       _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds);
2335       _dbus_assert (timeout_milliseconds >= 0);
2336       
2337       if (status == DBUS_DISPATCH_NEED_MEMORY)
2338         {
2339           /* Try sleeping a bit, as we aren't sure we need to block for reading,
2340            * we may already have a reply in the buffer and just can't process
2341            * it.
2342            */
2343           _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
2344           
2345           if (timeout_milliseconds < 100)
2346             ; /* just busy loop */
2347           else if (timeout_milliseconds <= 1000)
2348             _dbus_sleep_milliseconds (timeout_milliseconds / 3);
2349           else
2350             _dbus_sleep_milliseconds (1000);
2351         }
2352       else
2353         {          
2354           /* block again, we don't have the reply buffered yet. */
2355           _dbus_connection_do_iteration_unlocked (connection,
2356                                                   DBUS_ITERATION_DO_READING |
2357                                                   DBUS_ITERATION_BLOCK,
2358                                                   timeout_milliseconds);
2359         }
2360
2361       goto recheck_status;
2362     }
2363
2364   _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %ld milliseconds and got no reply\n",
2365                  (tv_sec - start_tv_sec) * 1000 + (tv_usec - start_tv_usec) / 1000);
2366
2367   _dbus_assert (!dbus_pending_call_get_completed (pending));
2368   
2369   /* unlock and call user code */
2370   _dbus_pending_call_complete_and_unlock (pending, NULL);
2371
2372   /* update user code on dispatch status */
2373   CONNECTION_LOCK (connection);
2374   status = _dbus_connection_get_dispatch_status_unlocked (connection);
2375   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2376 }
2377
2378 /**
2379  * Sends a message and blocks a certain time period while waiting for
2380  * a reply.  This function does not reenter the main loop,
2381  * i.e. messages other than the reply are queued up but not
2382  * processed. This function is used to do non-reentrant "method
2383  * calls."
2384  * 
2385  * If a normal reply is received, it is returned, and removed from the
2386  * incoming message queue. If it is not received, #NULL is returned
2387  * and the error is set to #DBUS_ERROR_NO_REPLY.  If an error reply is
2388  * received, it is converted to a #DBusError and returned as an error,
2389  * then the reply message is deleted. If something else goes wrong,
2390  * result is set to whatever is appropriate, such as
2391  * #DBUS_ERROR_NO_MEMORY or #DBUS_ERROR_DISCONNECTED.
2392  *
2393  * @param connection the connection
2394  * @param message the message to send
2395  * @param timeout_milliseconds timeout in milliseconds or -1 for default
2396  * @param error return location for error message
2397  * @returns the message that is the reply or #NULL with an error code if the
2398  * function fails.
2399  */
2400 DBusMessage*
2401 dbus_connection_send_with_reply_and_block (DBusConnection     *connection,
2402                                            DBusMessage        *message,
2403                                            int                 timeout_milliseconds,
2404                                            DBusError          *error)
2405 {
2406   DBusMessage *reply;
2407   DBusPendingCall *pending;
2408   
2409   _dbus_return_val_if_fail (connection != NULL, NULL);
2410   _dbus_return_val_if_fail (message != NULL, NULL);
2411   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);  
2412   _dbus_return_val_if_error_is_set (error, NULL);
2413   
2414   if (!dbus_connection_send_with_reply (connection, message,
2415                                         &pending, timeout_milliseconds))
2416     {
2417       _DBUS_SET_OOM (error);
2418       return NULL;
2419     }
2420
2421   _dbus_assert (pending != NULL);
2422   
2423   dbus_pending_call_block (pending);
2424
2425   reply = dbus_pending_call_steal_reply (pending);
2426   dbus_pending_call_unref (pending);
2427
2428   /* call_complete_and_unlock() called from pending_call_block() should
2429    * always fill this in.
2430    */
2431   _dbus_assert (reply != NULL);
2432   
2433    if (dbus_set_error_from_message (error, reply))
2434     {
2435       dbus_message_unref (reply);
2436       return NULL;
2437     }
2438   else
2439     return reply;
2440 }
2441
2442 /**
2443  * Blocks until the outgoing message queue is empty.
2444  *
2445  * @param connection the connection.
2446  */
2447 void
2448 dbus_connection_flush (DBusConnection *connection)
2449 {
2450   /* We have to specify DBUS_ITERATION_DO_READING here because
2451    * otherwise we could have two apps deadlock if they are both doing
2452    * a flush(), and the kernel buffers fill up. This could change the
2453    * dispatch status.
2454    */
2455   DBusDispatchStatus status;
2456
2457   _dbus_return_if_fail (connection != NULL);
2458   
2459   CONNECTION_LOCK (connection);
2460   while (connection->n_outgoing > 0 &&
2461          _dbus_connection_get_is_connected_unlocked (connection))
2462     {
2463       _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME);
2464       HAVE_LOCK_CHECK (connection);
2465       _dbus_connection_do_iteration_unlocked (connection,
2466                                               DBUS_ITERATION_DO_READING |
2467                                               DBUS_ITERATION_DO_WRITING |
2468                                               DBUS_ITERATION_BLOCK,
2469                                               -1);
2470     }
2471
2472   HAVE_LOCK_CHECK (connection);
2473   _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
2474   status = _dbus_connection_get_dispatch_status_unlocked (connection);
2475
2476   HAVE_LOCK_CHECK (connection);
2477   /* Unlocks and calls out to user code */
2478   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2479
2480   _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
2481 }
2482
2483 /**
2484  * Returns the first-received message from the incoming message queue,
2485  * leaving it in the queue. If the queue is empty, returns #NULL.
2486  * 
2487  * The caller does not own a reference to the returned message, and
2488  * must either return it using dbus_connection_return_message() or
2489  * keep it after calling dbus_connection_steal_borrowed_message(). No
2490  * one can get at the message while its borrowed, so return it as
2491  * quickly as possible and don't keep a reference to it after
2492  * returning it. If you need to keep the message, make a copy of it.
2493  *
2494  * dbus_connection_dispatch() will block if called while a borrowed
2495  * message is outstanding; only one piece of code can be playing with
2496  * the incoming queue at a time. This function will block if called
2497  * during a dbus_connection_dispatch().
2498  *
2499  * @param connection the connection.
2500  * @returns next message in the incoming queue.
2501  */
2502 DBusMessage*
2503 dbus_connection_borrow_message (DBusConnection *connection)
2504 {
2505   DBusDispatchStatus status;
2506   DBusMessage *message;
2507
2508   _dbus_return_val_if_fail (connection != NULL, NULL);
2509
2510   _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
2511   
2512   /* this is called for the side effect that it queues
2513    * up any messages from the transport
2514    */
2515   status = dbus_connection_get_dispatch_status (connection);
2516   if (status != DBUS_DISPATCH_DATA_REMAINS)
2517     return NULL;
2518   
2519   CONNECTION_LOCK (connection);
2520
2521   _dbus_connection_acquire_dispatch (connection);
2522
2523   /* While a message is outstanding, the dispatch lock is held */
2524   _dbus_assert (connection->message_borrowed == NULL);
2525
2526   connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
2527   
2528   message = connection->message_borrowed;
2529
2530   /* Note that we KEEP the dispatch lock until the message is returned */
2531   if (message == NULL)
2532     _dbus_connection_release_dispatch (connection);
2533
2534   CONNECTION_UNLOCK (connection);
2535   
2536   return message;
2537 }
2538
2539 /**
2540  * Used to return a message after peeking at it using
2541  * dbus_connection_borrow_message(). Only called if
2542  * message from dbus_connection_borrow_message() was non-#NULL.
2543  *
2544  * @param connection the connection
2545  * @param message the message from dbus_connection_borrow_message()
2546  */
2547 void
2548 dbus_connection_return_message (DBusConnection *connection,
2549                                 DBusMessage    *message)
2550 {
2551   _dbus_return_if_fail (connection != NULL);
2552   _dbus_return_if_fail (message != NULL);
2553   _dbus_return_if_fail (message == connection->message_borrowed);
2554   _dbus_return_if_fail (connection->dispatch_acquired);
2555   
2556   CONNECTION_LOCK (connection);
2557   
2558   _dbus_assert (message == connection->message_borrowed);
2559   
2560   connection->message_borrowed = NULL;
2561
2562   _dbus_connection_release_dispatch (connection);
2563   
2564   CONNECTION_UNLOCK (connection);
2565 }
2566
2567 /**
2568  * Used to keep a message after peeking at it using
2569  * dbus_connection_borrow_message(). Before using this function, see
2570  * the caveats/warnings in the documentation for
2571  * dbus_connection_pop_message().
2572  *
2573  * @param connection the connection
2574  * @param message the message from dbus_connection_borrow_message()
2575  */
2576 void
2577 dbus_connection_steal_borrowed_message (DBusConnection *connection,
2578                                         DBusMessage    *message)
2579 {
2580   DBusMessage *pop_message;
2581
2582   _dbus_return_if_fail (connection != NULL);
2583   _dbus_return_if_fail (message != NULL);
2584   _dbus_return_if_fail (message == connection->message_borrowed);
2585   _dbus_return_if_fail (connection->dispatch_acquired);
2586   
2587   CONNECTION_LOCK (connection);
2588  
2589   _dbus_assert (message == connection->message_borrowed);
2590
2591   pop_message = _dbus_list_pop_first (&connection->incoming_messages);
2592   _dbus_assert (message == pop_message);
2593   
2594   connection->n_incoming -= 1;
2595  
2596   _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
2597                  message, connection->n_incoming);
2598  
2599   connection->message_borrowed = NULL;
2600
2601   _dbus_connection_release_dispatch (connection);
2602   
2603   CONNECTION_UNLOCK (connection);
2604 }
2605
2606 /* See dbus_connection_pop_message, but requires the caller to own
2607  * the lock before calling. May drop the lock while running.
2608  */
2609 static DBusList*
2610 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
2611 {
2612   HAVE_LOCK_CHECK (connection);
2613   
2614   _dbus_assert (connection->message_borrowed == NULL);
2615   
2616   if (connection->n_incoming > 0)
2617     {
2618       DBusList *link;
2619
2620       link = _dbus_list_pop_first_link (&connection->incoming_messages);
2621       connection->n_incoming -= 1;
2622
2623       _dbus_verbose ("Message %p (%d %s %s %s '%s') removed from incoming queue %p, %d incoming\n",
2624                      link->data,
2625                      dbus_message_get_type (link->data),
2626                      dbus_message_get_path (link->data), 
2627                      dbus_message_get_interface (link->data) ?
2628                      dbus_message_get_interface (link->data) :
2629                      "no interface",
2630                      dbus_message_get_member (link->data) ?
2631                      dbus_message_get_member (link->data) :
2632                      "no member",
2633                      dbus_message_get_signature (link->data),
2634                      connection, connection->n_incoming);
2635
2636       return link;
2637     }
2638   else
2639     return NULL;
2640 }
2641
2642 /* See dbus_connection_pop_message, but requires the caller to own
2643  * the lock before calling. May drop the lock while running.
2644  */
2645 static DBusMessage*
2646 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
2647 {
2648   DBusList *link;
2649
2650   HAVE_LOCK_CHECK (connection);
2651   
2652   link = _dbus_connection_pop_message_link_unlocked (connection);
2653
2654   if (link != NULL)
2655     {
2656       DBusMessage *message;
2657       
2658       message = link->data;
2659       
2660       _dbus_list_free_link (link);
2661       
2662       return message;
2663     }
2664   else
2665     return NULL;
2666 }
2667
2668 static void
2669 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
2670                                                 DBusList       *message_link)
2671 {
2672   HAVE_LOCK_CHECK (connection);
2673   
2674   _dbus_assert (message_link != NULL);
2675   /* You can't borrow a message while a link is outstanding */
2676   _dbus_assert (connection->message_borrowed == NULL);
2677   /* We had to have the dispatch lock across the pop/putback */
2678   _dbus_assert (connection->dispatch_acquired);
2679
2680   _dbus_list_prepend_link (&connection->incoming_messages,
2681                            message_link);
2682   connection->n_incoming += 1;
2683
2684   _dbus_verbose ("Message %p (%d %s %s '%s') put back into queue %p, %d incoming\n",
2685                  message_link->data,
2686                  dbus_message_get_type (message_link->data),
2687                  dbus_message_get_interface (message_link->data) ?
2688                  dbus_message_get_interface (message_link->data) :
2689                  "no interface",
2690                  dbus_message_get_member (message_link->data) ?
2691                  dbus_message_get_member (message_link->data) :
2692                  "no member",
2693                  dbus_message_get_signature (message_link->data),
2694                  connection, connection->n_incoming);
2695 }
2696
2697 /**
2698  * Returns the first-received message from the incoming message queue,
2699  * removing it from the queue. The caller owns a reference to the
2700  * returned message. If the queue is empty, returns #NULL.
2701  *
2702  * This function bypasses any message handlers that are registered,
2703  * and so using it is usually wrong. Instead, let the main loop invoke
2704  * dbus_connection_dispatch(). Popping messages manually is only
2705  * useful in very simple programs that don't share a #DBusConnection
2706  * with any libraries or other modules.
2707  *
2708  * There is a lock that covers all ways of accessing the incoming message
2709  * queue, so dbus_connection_dispatch(), dbus_connection_pop_message(),
2710  * dbus_connection_borrow_message(), etc. will all block while one of the others
2711  * in the group is running.
2712  * 
2713  * @param connection the connection.
2714  * @returns next message in the incoming queue.
2715  */
2716 DBusMessage*
2717 dbus_connection_pop_message (DBusConnection *connection)
2718 {
2719   DBusMessage *message;
2720   DBusDispatchStatus status;
2721
2722   _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
2723   
2724   /* this is called for the side effect that it queues
2725    * up any messages from the transport
2726    */
2727   status = dbus_connection_get_dispatch_status (connection);
2728   if (status != DBUS_DISPATCH_DATA_REMAINS)
2729     return NULL;
2730   
2731   CONNECTION_LOCK (connection);
2732   _dbus_connection_acquire_dispatch (connection);
2733   HAVE_LOCK_CHECK (connection);
2734   
2735   message = _dbus_connection_pop_message_unlocked (connection);
2736
2737   _dbus_verbose ("Returning popped message %p\n", message);    
2738
2739   _dbus_connection_release_dispatch (connection);
2740   CONNECTION_UNLOCK (connection);
2741   
2742   return message;
2743 }
2744
2745 /**
2746  * Acquire the dispatcher. This is a separate lock so the main
2747  * connection lock can be dropped to call out to application dispatch
2748  * handlers.
2749  *
2750  * @param connection the connection.
2751  */
2752 static void
2753 _dbus_connection_acquire_dispatch (DBusConnection *connection)
2754 {
2755   HAVE_LOCK_CHECK (connection);
2756
2757   _dbus_connection_ref_unlocked (connection);
2758   CONNECTION_UNLOCK (connection);
2759   
2760   _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
2761   dbus_mutex_lock (connection->dispatch_mutex);
2762
2763   while (connection->dispatch_acquired)
2764     {
2765       _dbus_verbose ("%s waiting for dispatch to be acquirable\n", _DBUS_FUNCTION_NAME);
2766       dbus_condvar_wait (connection->dispatch_cond, connection->dispatch_mutex);
2767     }
2768   
2769   _dbus_assert (!connection->dispatch_acquired);
2770
2771   connection->dispatch_acquired = TRUE;
2772
2773   _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
2774   dbus_mutex_unlock (connection->dispatch_mutex);
2775   
2776   CONNECTION_LOCK (connection);
2777   _dbus_connection_unref_unlocked (connection);
2778 }
2779
2780 /**
2781  * Release the dispatcher when you're done with it. Only call
2782  * after you've acquired the dispatcher. Wakes up at most one
2783  * thread currently waiting to acquire the dispatcher.
2784  *
2785  * @param connection the connection.
2786  */
2787 static void
2788 _dbus_connection_release_dispatch (DBusConnection *connection)
2789 {
2790   HAVE_LOCK_CHECK (connection);
2791   
2792   _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
2793   dbus_mutex_lock (connection->dispatch_mutex);
2794   
2795   _dbus_assert (connection->dispatch_acquired);
2796
2797   connection->dispatch_acquired = FALSE;
2798   dbus_condvar_wake_one (connection->dispatch_cond);
2799
2800   _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
2801   dbus_mutex_unlock (connection->dispatch_mutex);
2802 }
2803
2804 static void
2805 _dbus_connection_failed_pop (DBusConnection *connection,
2806                              DBusList       *message_link)
2807 {
2808   _dbus_list_prepend_link (&connection->incoming_messages,
2809                            message_link);
2810   connection->n_incoming += 1;
2811 }
2812
2813 static DBusDispatchStatus
2814 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
2815 {
2816   HAVE_LOCK_CHECK (connection);
2817   
2818   if (connection->n_incoming > 0)
2819     return DBUS_DISPATCH_DATA_REMAINS;
2820   else if (!_dbus_transport_queue_messages (connection->transport))
2821     return DBUS_DISPATCH_NEED_MEMORY;
2822   else
2823     {
2824       DBusDispatchStatus status;
2825       dbus_bool_t is_connected;
2826       
2827       status = _dbus_transport_get_dispatch_status (connection->transport);
2828       is_connected = _dbus_transport_get_is_connected (connection->transport);
2829
2830       _dbus_verbose ("dispatch status = %s is_connected = %d\n",
2831                      DISPATCH_STATUS_NAME (status), is_connected);
2832       
2833       if (!is_connected)
2834         {
2835           if (status == DBUS_DISPATCH_COMPLETE &&
2836               connection->disconnect_message_link)
2837             {
2838               _dbus_verbose ("Sending disconnect message from %s\n",
2839                              _DBUS_FUNCTION_NAME);
2840                              
2841               /* We haven't sent the disconnect message already,
2842                * and all real messages have been queued up.
2843                */
2844               _dbus_connection_queue_synthesized_message_link (connection,
2845                                                                connection->disconnect_message_link);
2846               connection->disconnect_message_link = NULL;
2847             }
2848
2849           /* Dump the outgoing queue, we aren't going to be able to
2850            * send it now, and we'd like accessors like
2851            * dbus_connection_get_outgoing_size() to be accurate.
2852            */
2853           if (connection->n_outgoing > 0)
2854             {
2855               DBusList *link;
2856               
2857               _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
2858                              connection->n_outgoing);
2859               
2860               while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
2861                 {
2862                   _dbus_connection_message_sent (connection, link->data);
2863                 }
2864             }
2865         }
2866       
2867       if (status != DBUS_DISPATCH_COMPLETE)
2868         return status;
2869       else if (connection->n_incoming > 0)
2870         return DBUS_DISPATCH_DATA_REMAINS;
2871       else
2872         return DBUS_DISPATCH_COMPLETE;
2873     }
2874 }
2875
2876 static void
2877 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection    *connection,
2878                                                     DBusDispatchStatus new_status)
2879 {
2880   dbus_bool_t changed;
2881   DBusDispatchStatusFunction function;
2882   void *data;
2883
2884   HAVE_LOCK_CHECK (connection);
2885
2886   _dbus_connection_ref_unlocked (connection);
2887
2888   changed = new_status != connection->last_dispatch_status;
2889
2890   connection->last_dispatch_status = new_status;
2891
2892   function = connection->dispatch_status_function;
2893   data = connection->dispatch_status_data;
2894
2895   /* We drop the lock */
2896   CONNECTION_UNLOCK (connection);
2897   
2898   if (changed && function)
2899     {
2900       _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
2901                      connection, new_status,
2902                      DISPATCH_STATUS_NAME (new_status));
2903       (* function) (connection, new_status, data);      
2904     }
2905   
2906   dbus_connection_unref (connection);
2907 }
2908
2909 /**
2910  * Gets the current state (what we would currently return
2911  * from dbus_connection_dispatch()) but doesn't actually
2912  * dispatch any messages.
2913  * 
2914  * @param connection the connection.
2915  * @returns current dispatch status
2916  */
2917 DBusDispatchStatus
2918 dbus_connection_get_dispatch_status (DBusConnection *connection)
2919 {
2920   DBusDispatchStatus status;
2921
2922   _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
2923
2924   _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
2925   
2926   CONNECTION_LOCK (connection);
2927
2928   status = _dbus_connection_get_dispatch_status_unlocked (connection);
2929   
2930   CONNECTION_UNLOCK (connection);
2931
2932   return status;
2933 }
2934
2935 /**
2936  * Processes data buffered while handling watches, queueing zero or
2937  * more incoming messages. Then pops the first-received message from
2938  * the current incoming message queue, runs any handlers for it, and
2939  * unrefs the message. Returns a status indicating whether messages/data
2940  * remain, more memory is needed, or all data has been processed.
2941  * 
2942  * Even if the dispatch status is #DBUS_DISPATCH_DATA_REMAINS,
2943  * does not necessarily dispatch a message, as the data may
2944  * be part of authentication or the like.
2945  *
2946  * @todo some FIXME in here about handling DBUS_HANDLER_RESULT_NEED_MEMORY
2947  *
2948  * @todo FIXME what if we call out to application code to handle a
2949  * message, holding the dispatch lock, and the application code runs
2950  * the main loop and dispatches again? Probably deadlocks at the
2951  * moment. Maybe we want a dispatch status of DBUS_DISPATCH_IN_PROGRESS,
2952  * and then the GSource etc. could handle the situation? Right now
2953  * our GSource is NO_RECURSE
2954  * 
2955  * @param connection the connection
2956  * @returns dispatch status
2957  */
2958 DBusDispatchStatus
2959 dbus_connection_dispatch (DBusConnection *connection)
2960 {
2961   DBusMessage *message;
2962   DBusList *link, *filter_list_copy, *message_link;
2963   DBusHandlerResult result;
2964   DBusPendingCall *pending;
2965   dbus_int32_t reply_serial;
2966   DBusDispatchStatus status;
2967
2968   _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
2969
2970   _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
2971   
2972   CONNECTION_LOCK (connection);
2973   status = _dbus_connection_get_dispatch_status_unlocked (connection);
2974   if (status != DBUS_DISPATCH_DATA_REMAINS)
2975     {
2976       /* unlocks and calls out to user code */
2977       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2978       return status;
2979     }
2980   
2981   /* We need to ref the connection since the callback could potentially
2982    * drop the last ref to it
2983    */
2984   _dbus_connection_ref_unlocked (connection);
2985
2986   _dbus_connection_acquire_dispatch (connection);
2987   HAVE_LOCK_CHECK (connection);
2988
2989   message_link = _dbus_connection_pop_message_link_unlocked (connection);
2990   if (message_link == NULL)
2991     {
2992       /* another thread dispatched our stuff */
2993
2994       _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
2995       
2996       _dbus_connection_release_dispatch (connection);
2997
2998       status = _dbus_connection_get_dispatch_status_unlocked (connection);
2999
3000       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3001       
3002       dbus_connection_unref (connection);
3003       
3004       return status;
3005     }
3006
3007   message = message_link->data;
3008
3009   _dbus_verbose (" dispatching message %p (%d %s %s '%s')\n",
3010                  message,
3011                  dbus_message_get_type (message),
3012                  dbus_message_get_interface (message) ?
3013                  dbus_message_get_interface (message) :
3014                  "no interface",
3015                  dbus_message_get_member (message) ?
3016                  dbus_message_get_member (message) :
3017                  "no member",
3018                  dbus_message_get_signature (message));
3019
3020   result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
3021   
3022   /* Pending call handling must be first, because if you do
3023    * dbus_connection_send_with_reply_and_block() or
3024    * dbus_pending_call_block() then no handlers/filters will be run on
3025    * the reply. We want consistent semantics in the case where we
3026    * dbus_connection_dispatch() the reply.
3027    */
3028   
3029   reply_serial = dbus_message_get_reply_serial (message);
3030   pending = _dbus_hash_table_lookup_int (connection->pending_replies,
3031                                          reply_serial);
3032   if (pending)
3033     {
3034       _dbus_verbose ("Dispatching a pending reply\n");
3035       _dbus_pending_call_complete_and_unlock (pending, message);
3036       pending = NULL; /* it's probably unref'd */
3037       
3038       CONNECTION_LOCK (connection);
3039       _dbus_verbose ("pending call completed in dispatch\n");
3040       result = DBUS_HANDLER_RESULT_HANDLED;
3041       goto out;
3042     }
3043   
3044   if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
3045     {
3046       _dbus_connection_release_dispatch (connection);
3047       HAVE_LOCK_CHECK (connection);
3048       
3049       _dbus_connection_failed_pop (connection, message_link);
3050
3051       /* unlocks and calls user code */
3052       _dbus_connection_update_dispatch_status_and_unlock (connection,
3053                                                           DBUS_DISPATCH_NEED_MEMORY);
3054
3055       if (pending)
3056         dbus_pending_call_unref (pending);
3057       dbus_connection_unref (connection);
3058       
3059       return DBUS_DISPATCH_NEED_MEMORY;
3060     }
3061   
3062   _dbus_list_foreach (&filter_list_copy,
3063                       (DBusForeachFunction)_dbus_message_filter_ref,
3064                       NULL);
3065
3066   /* We're still protected from dispatch() reentrancy here
3067    * since we acquired the dispatcher
3068    */
3069   CONNECTION_UNLOCK (connection);
3070   
3071   link = _dbus_list_get_first_link (&filter_list_copy);
3072   while (link != NULL)
3073     {
3074       DBusMessageFilter *filter = link->data;
3075       DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
3076
3077       _dbus_verbose ("  running filter on message %p\n", message);
3078       result = (* filter->function) (connection, message, filter->user_data);
3079
3080       if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
3081         break;
3082
3083       link = next;
3084     }
3085
3086   _dbus_list_foreach (&filter_list_copy,
3087                       (DBusForeachFunction)_dbus_message_filter_unref,
3088                       NULL);
3089   _dbus_list_clear (&filter_list_copy);
3090   
3091   CONNECTION_LOCK (connection);
3092
3093   if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
3094     {
3095       _dbus_verbose ("No memory in %s\n", _DBUS_FUNCTION_NAME);
3096       goto out;
3097     }
3098   else if (result == DBUS_HANDLER_RESULT_HANDLED)
3099     {
3100       _dbus_verbose ("filter handled message in dispatch\n");
3101       goto out;
3102     }
3103
3104   /* We're still protected from dispatch() reentrancy here
3105    * since we acquired the dispatcher
3106    */
3107   _dbus_verbose ("  running object path dispatch on message %p (%d %s %s '%s')\n",
3108                  message,
3109                  dbus_message_get_type (message),
3110                  dbus_message_get_interface (message) ?
3111                  dbus_message_get_interface (message) :
3112                  "no interface",
3113                  dbus_message_get_member (message) ?
3114                  dbus_message_get_member (message) :
3115                  "no member",
3116                  dbus_message_get_signature (message));
3117
3118   HAVE_LOCK_CHECK (connection);
3119   result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
3120                                                   message);
3121   
3122   CONNECTION_LOCK (connection);
3123
3124   if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
3125     {
3126       _dbus_verbose ("object tree handled message in dispatch\n");
3127       goto out;
3128     }
3129
3130   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
3131     {
3132       DBusMessage *reply;
3133       DBusString str;
3134       DBusPreallocatedSend *preallocated;
3135
3136       _dbus_verbose ("  sending error %s\n",
3137                      DBUS_ERROR_UNKNOWN_METHOD);
3138       
3139       if (!_dbus_string_init (&str))
3140         {
3141           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
3142           _dbus_verbose ("no memory for error string in dispatch\n");
3143           goto out;
3144         }
3145               
3146       if (!_dbus_string_append_printf (&str,
3147                                        "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
3148                                        dbus_message_get_member (message),
3149                                        dbus_message_get_signature (message),
3150                                        dbus_message_get_interface (message)))
3151         {
3152           _dbus_string_free (&str);
3153           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
3154           _dbus_verbose ("no memory for error string in dispatch\n");
3155           goto out;
3156         }
3157       
3158       reply = dbus_message_new_error (message,
3159                                       DBUS_ERROR_UNKNOWN_METHOD,
3160                                       _dbus_string_get_const_data (&str));
3161       _dbus_string_free (&str);
3162
3163       if (reply == NULL)
3164         {
3165           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
3166           _dbus_verbose ("no memory for error reply in dispatch\n");
3167           goto out;
3168         }
3169       
3170       preallocated = _dbus_connection_preallocate_send_unlocked (connection);
3171
3172       if (preallocated == NULL)
3173         {
3174           dbus_message_unref (reply);
3175           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
3176           _dbus_verbose ("no memory for error send in dispatch\n");
3177           goto out;
3178         }
3179
3180       _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
3181                                                              reply, NULL);
3182
3183       dbus_message_unref (reply);
3184       
3185       result = DBUS_HANDLER_RESULT_HANDLED;
3186     }
3187   
3188   _dbus_verbose ("  done dispatching %p (%d %s %s '%s') on connection %p\n", message,
3189                  dbus_message_get_type (message),
3190                  dbus_message_get_interface (message) ?
3191                  dbus_message_get_interface (message) :
3192                  "no interface",
3193                  dbus_message_get_member (message) ?
3194                  dbus_message_get_member (message) :
3195                  "no member",
3196                  dbus_message_get_signature (message),
3197                  connection);
3198   
3199  out:
3200   if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
3201     {
3202       _dbus_verbose ("out of memory in %s\n", _DBUS_FUNCTION_NAME);
3203       
3204       /* Put message back, and we'll start over.
3205        * Yes this means handlers must be idempotent if they
3206        * don't return HANDLED; c'est la vie.
3207        */
3208       _dbus_connection_putback_message_link_unlocked (connection,
3209                                                       message_link);
3210     }
3211   else
3212     {
3213       _dbus_verbose (" ... done dispatching in %s\n", _DBUS_FUNCTION_NAME);
3214       
3215       if (connection->exit_on_disconnect &&
3216           dbus_message_is_signal (message,
3217                                   DBUS_INTERFACE_LOCAL,
3218                                   "Disconnected"))
3219         {
3220           _dbus_verbose ("Exiting on Disconnected signal\n");
3221           CONNECTION_UNLOCK (connection);
3222           _dbus_exit (1);
3223           _dbus_assert_not_reached ("Call to exit() returned");
3224         }
3225       
3226       _dbus_list_free_link (message_link);
3227       dbus_message_unref (message); /* don't want the message to count in max message limits
3228                                      * in computing dispatch status below
3229                                      */
3230     }
3231   
3232   _dbus_connection_release_dispatch (connection);
3233   HAVE_LOCK_CHECK (connection);
3234
3235   _dbus_verbose ("%s before final status update\n", _DBUS_FUNCTION_NAME);
3236   status = _dbus_connection_get_dispatch_status_unlocked (connection);
3237
3238   /* unlocks and calls user code */
3239   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3240   
3241   dbus_connection_unref (connection);
3242   
3243   return status;
3244 }
3245
3246 /**
3247  * Sets the watch functions for the connection. These functions are
3248  * responsible for making the application's main loop aware of file
3249  * descriptors that need to be monitored for events, using select() or
3250  * poll(). When using Qt, typically the DBusAddWatchFunction would
3251  * create a QSocketNotifier. When using GLib, the DBusAddWatchFunction
3252  * could call g_io_add_watch(), or could be used as part of a more
3253  * elaborate GSource. Note that when a watch is added, it may
3254  * not be enabled.
3255  *
3256  * The DBusWatchToggledFunction notifies the application that the
3257  * watch has been enabled or disabled. Call dbus_watch_get_enabled()
3258  * to check this. A disabled watch should have no effect, and enabled
3259  * watch should be added to the main loop. This feature is used
3260  * instead of simply adding/removing the watch because
3261  * enabling/disabling can be done without memory allocation.  The
3262  * toggled function may be NULL if a main loop re-queries
3263  * dbus_watch_get_enabled() every time anyway.
3264  * 
3265  * The DBusWatch can be queried for the file descriptor to watch using
3266  * dbus_watch_get_fd(), and for the events to watch for using
3267  * dbus_watch_get_flags(). The flags returned by
3268  * dbus_watch_get_flags() will only contain DBUS_WATCH_READABLE and
3269  * DBUS_WATCH_WRITABLE, never DBUS_WATCH_HANGUP or DBUS_WATCH_ERROR;
3270  * all watches implicitly include a watch for hangups, errors, and
3271  * other exceptional conditions.
3272  *
3273  * Once a file descriptor becomes readable or writable, or an exception
3274  * occurs, dbus_watch_handle() should be called to
3275  * notify the connection of the file descriptor's condition.
3276  *
3277  * dbus_watch_handle() cannot be called during the
3278  * DBusAddWatchFunction, as the connection will not be ready to handle
3279  * that watch yet.
3280  * 
3281  * It is not allowed to reference a DBusWatch after it has been passed
3282  * to remove_function.
3283  *
3284  * If #FALSE is returned due to lack of memory, the failure may be due
3285  * to a #FALSE return from the new add_function. If so, the
3286  * add_function may have been called successfully one or more times,
3287  * but the remove_function will also have been called to remove any
3288  * successful adds. i.e. if #FALSE is returned the net result
3289  * should be that dbus_connection_set_watch_functions() has no effect,
3290  * but the add_function and remove_function may have been called.
3291  *
3292  * @todo We need to drop the lock when we call the
3293  * add/remove/toggled functions which can be a side effect
3294  * of setting the watch functions.
3295  * 
3296  * @param connection the connection.
3297  * @param add_function function to begin monitoring a new descriptor.
3298  * @param remove_function function to stop monitoring a descriptor.
3299  * @param toggled_function function to notify of enable/disable
3300  * @param data data to pass to add_function and remove_function.
3301  * @param free_data_function function to be called to free the data.
3302  * @returns #FALSE on failure (no memory)
3303  */
3304 dbus_bool_t
3305 dbus_connection_set_watch_functions (DBusConnection              *connection,
3306                                      DBusAddWatchFunction         add_function,
3307                                      DBusRemoveWatchFunction      remove_function,
3308                                      DBusWatchToggledFunction     toggled_function,
3309                                      void                        *data,
3310                                      DBusFreeFunction             free_data_function)
3311 {
3312   dbus_bool_t retval;
3313   DBusWatchList *watches;
3314
3315   _dbus_return_val_if_fail (connection != NULL, FALSE);
3316   
3317   CONNECTION_LOCK (connection);
3318
3319 #ifndef DBUS_DISABLE_CHECKS
3320   if (connection->watches == NULL)
3321     {
3322       _dbus_warn ("Re-entrant call to %s is not allowed\n",
3323                   _DBUS_FUNCTION_NAME);
3324       return FALSE;
3325     }
3326 #endif
3327   
3328   /* ref connection for slightly better reentrancy */
3329   _dbus_connection_ref_unlocked (connection);
3330
3331   /* This can call back into user code, and we need to drop the
3332    * connection lock when it does. This is kind of a lame
3333    * way to do it.
3334    */
3335   watches = connection->watches;
3336   connection->watches = NULL;
3337   CONNECTION_UNLOCK (connection);
3338
3339   retval = _dbus_watch_list_set_functions (watches,
3340                                            add_function, remove_function,
3341                                            toggled_function,
3342                                            data, free_data_function);
3343   CONNECTION_LOCK (connection);
3344   connection->watches = watches;
3345   
3346   CONNECTION_UNLOCK (connection);
3347   /* drop our paranoid refcount */
3348   dbus_connection_unref (connection);
3349   
3350   return retval;
3351 }
3352
3353 /**
3354  * Sets the timeout functions for the connection. These functions are
3355  * responsible for making the application's main loop aware of timeouts.
3356  * When using Qt, typically the DBusAddTimeoutFunction would create a
3357  * QTimer. When using GLib, the DBusAddTimeoutFunction would call
3358  * g_timeout_add.
3359  * 
3360  * The DBusTimeoutToggledFunction notifies the application that the
3361  * timeout has been enabled or disabled. Call
3362  * dbus_timeout_get_enabled() to check this. A disabled timeout should
3363  * have no effect, and enabled timeout should be added to the main
3364  * loop. This feature is used instead of simply adding/removing the
3365  * timeout because enabling/disabling can be done without memory
3366  * allocation. With Qt, QTimer::start() and QTimer::stop() can be used
3367  * to enable and disable. The toggled function may be NULL if a main
3368  * loop re-queries dbus_timeout_get_enabled() every time anyway.
3369  * Whenever a timeout is toggled, its interval may change.
3370  *
3371  * The DBusTimeout can be queried for the timer interval using
3372  * dbus_timeout_get_interval(). dbus_timeout_handle() should be called
3373  * repeatedly, each time the interval elapses, starting after it has
3374  * elapsed once. The timeout stops firing when it is removed with the
3375  * given remove_function.  The timer interval may change whenever the
3376  * timeout is added, removed, or toggled.
3377  *
3378  * @param connection the connection.
3379  * @param add_function function to add a timeout.
3380  * @param remove_function function to remove a timeout.
3381  * @param toggled_function function to notify of enable/disable
3382  * @param data data to pass to add_function and remove_function.
3383  * @param free_data_function function to be called to free the data.
3384  * @returns #FALSE on failure (no memory)
3385  */
3386 dbus_bool_t
3387 dbus_connection_set_timeout_functions   (DBusConnection            *connection,
3388                                          DBusAddTimeoutFunction     add_function,
3389                                          DBusRemoveTimeoutFunction  remove_function,
3390                                          DBusTimeoutToggledFunction toggled_function,
3391                                          void                      *data,
3392                                          DBusFreeFunction           free_data_function)
3393 {
3394   dbus_bool_t retval;
3395   DBusTimeoutList *timeouts;
3396
3397   _dbus_return_val_if_fail (connection != NULL, FALSE);
3398   
3399   CONNECTION_LOCK (connection);
3400
3401 #ifndef DBUS_DISABLE_CHECKS
3402   if (connection->timeouts == NULL)
3403     {
3404       _dbus_warn ("Re-entrant call to %s is not allowed\n",
3405                   _DBUS_FUNCTION_NAME);
3406       return FALSE;
3407     }
3408 #endif
3409   
3410   /* ref connection for slightly better reentrancy */
3411   _dbus_connection_ref_unlocked (connection);
3412
3413   timeouts = connection->timeouts;
3414   connection->timeouts = NULL;
3415   CONNECTION_UNLOCK (connection);
3416   
3417   retval = _dbus_timeout_list_set_functions (timeouts,
3418                                              add_function, remove_function,
3419                                              toggled_function,
3420                                              data, free_data_function);
3421   CONNECTION_LOCK (connection);
3422   connection->timeouts = timeouts;
3423   
3424   CONNECTION_UNLOCK (connection);
3425   /* drop our paranoid refcount */
3426   dbus_connection_unref (connection);
3427
3428   return retval;
3429 }
3430
3431 /**
3432  * Sets the mainloop wakeup function for the connection. Thi function is
3433  * responsible for waking up the main loop (if its sleeping) when some some
3434  * change has happened to the connection that the mainloop needs to reconsiders
3435  * (e.g. a message has been queued for writing).
3436  * When using Qt, this typically results in a call to QEventLoop::wakeUp().
3437  * When using GLib, it would call g_main_context_wakeup().
3438  *
3439  *
3440  * @param connection the connection.
3441  * @param wakeup_main_function function to wake up the mainloop
3442  * @param data data to pass wakeup_main_function
3443  * @param free_data_function function to be called to free the data.
3444  */
3445 void
3446 dbus_connection_set_wakeup_main_function (DBusConnection            *connection,
3447                                           DBusWakeupMainFunction     wakeup_main_function,
3448                                           void                      *data,
3449                                           DBusFreeFunction           free_data_function)
3450 {
3451   void *old_data;
3452   DBusFreeFunction old_free_data;
3453
3454   _dbus_return_if_fail (connection != NULL);
3455   
3456   CONNECTION_LOCK (connection);
3457   old_data = connection->wakeup_main_data;
3458   old_free_data = connection->free_wakeup_main_data;
3459
3460   connection->wakeup_main_function = wakeup_main_function;
3461   connection->wakeup_main_data = data;
3462   connection->free_wakeup_main_data = free_data_function;
3463   
3464   CONNECTION_UNLOCK (connection);
3465
3466   /* Callback outside the lock */
3467   if (old_free_data)
3468     (*old_free_data) (old_data);
3469 }
3470
3471 /**
3472  * Set a function to be invoked when the dispatch status changes.
3473  * If the dispatch status is #DBUS_DISPATCH_DATA_REMAINS, then
3474  * dbus_connection_dispatch() needs to be called to process incoming
3475  * messages. However, dbus_connection_dispatch() MUST NOT BE CALLED
3476  * from inside the DBusDispatchStatusFunction. Indeed, almost
3477  * any reentrancy in this function is a bad idea. Instead,
3478  * the DBusDispatchStatusFunction should simply save an indication
3479  * that messages should be dispatched later, when the main loop
3480  * is re-entered.
3481  *
3482  * @param connection the connection
3483  * @param function function to call on dispatch status changes
3484  * @param data data for function
3485  * @param free_data_function free the function data
3486  */
3487 void
3488 dbus_connection_set_dispatch_status_function (DBusConnection             *connection,
3489                                               DBusDispatchStatusFunction  function,
3490                                               void                       *data,
3491                                               DBusFreeFunction            free_data_function)
3492 {
3493   void *old_data;
3494   DBusFreeFunction old_free_data;
3495
3496   _dbus_return_if_fail (connection != NULL);
3497   
3498   CONNECTION_LOCK (connection);
3499   old_data = connection->dispatch_status_data;
3500   old_free_data = connection->free_dispatch_status_data;
3501
3502   connection->dispatch_status_function = function;
3503   connection->dispatch_status_data = data;
3504   connection->free_dispatch_status_data = free_data_function;
3505   
3506   CONNECTION_UNLOCK (connection);
3507
3508   /* Callback outside the lock */
3509   if (old_free_data)
3510     (*old_free_data) (old_data);
3511 }
3512
3513 /**
3514  * Get the UNIX file descriptor of the connection, if any.  This can
3515  * be used for SELinux access control checks with getpeercon() for
3516  * example. DO NOT read or write to the file descriptor, or try to
3517  * select() on it; use DBusWatch for main loop integration. Not all
3518  * connections will have a file descriptor. So for adding descriptors
3519  * to the main loop, use dbus_watch_get_fd() and so forth.
3520  *
3521  * @param connection the connection
3522  * @param fd return location for the file descriptor.
3523  * @returns #TRUE if fd is successfully obtained.
3524  */
3525 dbus_bool_t
3526 dbus_connection_get_unix_fd (DBusConnection *connection,
3527                              int            *fd)
3528 {
3529   dbus_bool_t retval;
3530
3531   _dbus_return_val_if_fail (connection != NULL, FALSE);
3532   _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
3533   
3534   CONNECTION_LOCK (connection);
3535   
3536   retval = _dbus_transport_get_unix_fd (connection->transport,
3537                                         fd);
3538
3539   CONNECTION_UNLOCK (connection);
3540
3541   return retval;
3542 }
3543
3544 /**
3545  * Gets the UNIX user ID of the connection if any.
3546  * Returns #TRUE if the uid is filled in.
3547  * Always returns #FALSE on non-UNIX platforms.
3548  * Always returns #FALSE prior to authenticating the
3549  * connection.
3550  *
3551  * @param connection the connection
3552  * @param uid return location for the user ID
3553  * @returns #TRUE if uid is filled in with a valid user ID
3554  */
3555 dbus_bool_t
3556 dbus_connection_get_unix_user (DBusConnection *connection,
3557                                unsigned long  *uid)
3558 {
3559   dbus_bool_t result;
3560
3561   _dbus_return_val_if_fail (connection != NULL, FALSE);
3562   _dbus_return_val_if_fail (uid != NULL, FALSE);
3563   
3564   CONNECTION_LOCK (connection);
3565
3566   if (!_dbus_transport_get_is_authenticated (connection->transport))
3567     result = FALSE;
3568   else
3569     result = _dbus_transport_get_unix_user (connection->transport,
3570                                             uid);
3571   CONNECTION_UNLOCK (connection);
3572
3573   return result;
3574 }
3575
3576 /**
3577  * Gets the process ID of the connection if any.
3578  * Returns #TRUE if the uid is filled in.
3579  * Always returns #FALSE prior to authenticating the
3580  * connection.
3581  *
3582  * @param connection the connection
3583  * @param pid return location for the process ID
3584  * @returns #TRUE if uid is filled in with a valid process ID
3585  */
3586 dbus_bool_t
3587 dbus_connection_get_unix_process_id (DBusConnection *connection,
3588                                      unsigned long  *pid)
3589 {
3590   dbus_bool_t result;
3591
3592   _dbus_return_val_if_fail (connection != NULL, FALSE);
3593   _dbus_return_val_if_fail (pid != NULL, FALSE);
3594   
3595   CONNECTION_LOCK (connection);
3596
3597   if (!_dbus_transport_get_is_authenticated (connection->transport))
3598     result = FALSE;
3599   else
3600     result = _dbus_transport_get_unix_process_id (connection->transport,
3601                                                   pid);
3602   CONNECTION_UNLOCK (connection);
3603
3604   return result;
3605 }
3606
3607 /**
3608  * Sets a predicate function used to determine whether a given user ID
3609  * is allowed to connect. When an incoming connection has
3610  * authenticated with a particular user ID, this function is called;
3611  * if it returns #TRUE, the connection is allowed to proceed,
3612  * otherwise the connection is disconnected.
3613  *
3614  * If the function is set to #NULL (as it is by default), then
3615  * only the same UID as the server process will be allowed to
3616  * connect.
3617  *
3618  * @param connection the connection
3619  * @param function the predicate
3620  * @param data data to pass to the predicate
3621  * @param free_data_function function to free the data
3622  */
3623 void
3624 dbus_connection_set_unix_user_function (DBusConnection             *connection,
3625                                         DBusAllowUnixUserFunction   function,
3626                                         void                       *data,
3627                                         DBusFreeFunction            free_data_function)
3628 {
3629   void *old_data = NULL;
3630   DBusFreeFunction old_free_function = NULL;
3631
3632   _dbus_return_if_fail (connection != NULL);
3633   
3634   CONNECTION_LOCK (connection);
3635   _dbus_transport_set_unix_user_function (connection->transport,
3636                                           function, data, free_data_function,
3637                                           &old_data, &old_free_function);
3638   CONNECTION_UNLOCK (connection);
3639
3640   if (old_free_function != NULL)
3641     (* old_free_function) (old_data);    
3642 }
3643
3644 /**
3645  * Adds a message filter. Filters are handlers that are run on all
3646  * incoming messages, prior to the objects registered with
3647  * dbus_connection_register_object_path().  Filters are run in the
3648  * order that they were added.  The same handler can be added as a
3649  * filter more than once, in which case it will be run more than once.
3650  * Filters added during a filter callback won't be run on the message
3651  * being processed.
3652  *
3653  * @todo we don't run filters on messages while blocking without
3654  * entering the main loop, since filters are run as part of
3655  * dbus_connection_dispatch(). This is probably a feature, as filters
3656  * could create arbitrary reentrancy. But kind of sucks if you're
3657  * trying to filter METHOD_RETURN for some reason.
3658  *
3659  * @param connection the connection
3660  * @param function function to handle messages
3661  * @param user_data user data to pass to the function
3662  * @param free_data_function function to use for freeing user data
3663  * @returns #TRUE on success, #FALSE if not enough memory.
3664  */
3665 dbus_bool_t
3666 dbus_connection_add_filter (DBusConnection            *connection,
3667                             DBusHandleMessageFunction  function,
3668                             void                      *user_data,
3669                             DBusFreeFunction           free_data_function)
3670 {
3671   DBusMessageFilter *filter;
3672   
3673   _dbus_return_val_if_fail (connection != NULL, FALSE);
3674   _dbus_return_val_if_fail (function != NULL, FALSE);
3675
3676   filter = dbus_new0 (DBusMessageFilter, 1);
3677   if (filter == NULL)
3678     return FALSE;
3679
3680   filter->refcount.value = 1;
3681   
3682   CONNECTION_LOCK (connection);
3683
3684   if (!_dbus_list_append (&connection->filter_list,
3685                           filter))
3686     {
3687       _dbus_message_filter_unref (filter);
3688       CONNECTION_UNLOCK (connection);
3689       return FALSE;
3690     }
3691
3692   /* Fill in filter after all memory allocated,
3693    * so we don't run the free_user_data_function
3694    * if the add_filter() fails
3695    */
3696   
3697   filter->function = function;
3698   filter->user_data = user_data;
3699   filter->free_user_data_function = free_data_function;
3700         
3701   CONNECTION_UNLOCK (connection);
3702   return TRUE;
3703 }
3704
3705 /**
3706  * Removes a previously-added message filter. It is a programming
3707  * error to call this function for a handler that has not been added
3708  * as a filter. If the given handler was added more than once, only
3709  * one instance of it will be removed (the most recently-added
3710  * instance).
3711  *
3712  * @param connection the connection
3713  * @param function the handler to remove
3714  * @param user_data user data for the handler to remove
3715  *
3716  */
3717 void
3718 dbus_connection_remove_filter (DBusConnection            *connection,
3719                                DBusHandleMessageFunction  function,
3720                                void                      *user_data)
3721 {
3722   DBusList *link;
3723   DBusMessageFilter *filter;
3724   
3725   _dbus_return_if_fail (connection != NULL);
3726   _dbus_return_if_fail (function != NULL);
3727   
3728   CONNECTION_LOCK (connection);
3729
3730   filter = NULL;
3731   
3732   link = _dbus_list_get_last_link (&connection->filter_list);
3733   while (link != NULL)
3734     {
3735       filter = link->data;
3736
3737       if (filter->function == function &&
3738           filter->user_data == user_data)
3739         {
3740           _dbus_list_remove_link (&connection->filter_list, link);
3741           filter->function = NULL;
3742           
3743           break;
3744         }
3745         
3746       link = _dbus_list_get_prev_link (&connection->filter_list, link);
3747     }
3748   
3749   CONNECTION_UNLOCK (connection);
3750
3751 #ifndef DBUS_DISABLE_CHECKS
3752   if (filter == NULL)
3753     {
3754       _dbus_warn ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
3755                   function, user_data);
3756       return;
3757     }
3758 #endif
3759   
3760   /* Call application code */
3761   if (filter->free_user_data_function)
3762     (* filter->free_user_data_function) (filter->user_data);
3763
3764   filter->free_user_data_function = NULL;
3765   filter->user_data = NULL;
3766   
3767   _dbus_message_filter_unref (filter);
3768 }
3769
3770 /**
3771  * Registers a handler for a given path in the object hierarchy.
3772  * The given vtable handles messages sent to exactly the given path.
3773  *
3774  *
3775  * @param connection the connection
3776  * @param path a '/' delimited string of path elements
3777  * @param vtable the virtual table
3778  * @param user_data data to pass to functions in the vtable
3779  * @returns #FALSE if not enough memory
3780  */
3781 dbus_bool_t
3782 dbus_connection_register_object_path (DBusConnection              *connection,
3783                                       const char                  *path,
3784                                       const DBusObjectPathVTable  *vtable,
3785                                       void                        *user_data)
3786 {
3787   char **decomposed_path;
3788   dbus_bool_t retval;
3789   
3790   _dbus_return_val_if_fail (connection != NULL, FALSE);
3791   _dbus_return_val_if_fail (path != NULL, FALSE);
3792   _dbus_return_val_if_fail (path[0] == '/', FALSE);
3793   _dbus_return_val_if_fail (vtable != NULL, FALSE);
3794
3795   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
3796     return FALSE;
3797
3798   CONNECTION_LOCK (connection);
3799
3800   retval = _dbus_object_tree_register (connection->objects,
3801                                        FALSE,
3802                                        (const char **) decomposed_path, vtable,
3803                                        user_data);
3804
3805   CONNECTION_UNLOCK (connection);
3806
3807   dbus_free_string_array (decomposed_path);
3808
3809   return retval;
3810 }
3811
3812 /**
3813  * Registers a fallback handler for a given subsection of the object
3814  * hierarchy.  The given vtable handles messages at or below the given
3815  * path. You can use this to establish a default message handling
3816  * policy for a whole "subdirectory."
3817  *
3818  * @param connection the connection
3819  * @param path a '/' delimited string of path elements
3820  * @param vtable the virtual table
3821  * @param user_data data to pass to functions in the vtable
3822  * @returns #FALSE if not enough memory
3823  */
3824 dbus_bool_t
3825 dbus_connection_register_fallback (DBusConnection              *connection,
3826                                    const char                  *path,
3827                                    const DBusObjectPathVTable  *vtable,
3828                                    void                        *user_data)
3829 {
3830   char **decomposed_path;
3831   dbus_bool_t retval;
3832   
3833   _dbus_return_val_if_fail (connection != NULL, FALSE);
3834   _dbus_return_val_if_fail (path != NULL, FALSE);
3835   _dbus_return_val_if_fail (path[0] == '/', FALSE);
3836   _dbus_return_val_if_fail (vtable != NULL, FALSE);
3837
3838   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
3839     return FALSE;
3840
3841   CONNECTION_LOCK (connection);
3842
3843   retval = _dbus_object_tree_register (connection->objects,
3844                                        TRUE,
3845                                        (const char **) decomposed_path, vtable,
3846                                        user_data);
3847
3848   CONNECTION_UNLOCK (connection);
3849
3850   dbus_free_string_array (decomposed_path);
3851
3852   return retval;
3853 }
3854
3855 /**
3856  * Unregisters the handler registered with exactly the given path.
3857  * It's a bug to call this function for a path that isn't registered.
3858  * Can unregister both fallback paths and object paths.
3859  *
3860  * @param connection the connection
3861  * @param path a '/' delimited string of path elements
3862  * @returns #FALSE if not enough memory
3863  */
3864 dbus_bool_t
3865 dbus_connection_unregister_object_path (DBusConnection              *connection,
3866                                         const char                  *path)
3867 {
3868   char **decomposed_path;
3869
3870   _dbus_return_val_if_fail (connection != NULL, FALSE);
3871   _dbus_return_val_if_fail (path != NULL, FALSE);
3872   _dbus_return_val_if_fail (path[0] == '/', FALSE);
3873
3874   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
3875       return FALSE;
3876
3877   CONNECTION_LOCK (connection);
3878
3879   _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
3880
3881   dbus_free_string_array (decomposed_path);
3882
3883   return TRUE;
3884 }
3885
3886 /**
3887  * Lists the registered fallback handlers and object path handlers at
3888  * the given parent_path. The returned array should be freed with
3889  * dbus_free_string_array().
3890  *
3891  * @param connection the connection
3892  * @param parent_path the path to list the child handlers of
3893  * @param child_entries returns #NULL-terminated array of children
3894  * @returns #FALSE if no memory to allocate the child entries
3895  */
3896 dbus_bool_t
3897 dbus_connection_list_registered (DBusConnection              *connection,
3898                                  const char                  *parent_path,
3899                                  char                      ***child_entries)
3900 {
3901   char **decomposed_path;
3902   dbus_bool_t retval;
3903   _dbus_return_val_if_fail (connection != NULL, FALSE);
3904   _dbus_return_val_if_fail (parent_path != NULL, FALSE);
3905   _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
3906   _dbus_return_val_if_fail (child_entries != NULL, FALSE);
3907
3908   if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
3909     return FALSE;
3910
3911   CONNECTION_LOCK (connection);
3912
3913   retval = _dbus_object_tree_list_registered_and_unlock (connection->objects,
3914                                                          (const char **) decomposed_path,
3915                                                          child_entries);
3916   dbus_free_string_array (decomposed_path);
3917
3918   return retval;
3919 }
3920
3921 static DBusDataSlotAllocator slot_allocator;
3922 _DBUS_DEFINE_GLOBAL_LOCK (connection_slots);
3923
3924 /**
3925  * Allocates an integer ID to be used for storing application-specific
3926  * data on any DBusConnection. The allocated ID may then be used
3927  * with dbus_connection_set_data() and dbus_connection_get_data().
3928  * The passed-in slot must be initialized to -1, and is filled in
3929  * with the slot ID. If the passed-in slot is not -1, it's assumed
3930  * to be already allocated, and its refcount is incremented.
3931  * 
3932  * The allocated slot is global, i.e. all DBusConnection objects will
3933  * have a slot with the given integer ID reserved.
3934  *
3935  * @param slot_p address of a global variable storing the slot
3936  * @returns #FALSE on failure (no memory)
3937  */
3938 dbus_bool_t
3939 dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
3940 {
3941   return _dbus_data_slot_allocator_alloc (&slot_allocator,
3942                                           _DBUS_LOCK_NAME (connection_slots),
3943                                           slot_p);
3944 }
3945
3946 /**
3947  * Deallocates a global ID for connection data slots.
3948  * dbus_connection_get_data() and dbus_connection_set_data() may no
3949  * longer be used with this slot.  Existing data stored on existing
3950  * DBusConnection objects will be freed when the connection is
3951  * finalized, but may not be retrieved (and may only be replaced if
3952  * someone else reallocates the slot).  When the refcount on the
3953  * passed-in slot reaches 0, it is set to -1.
3954  *
3955  * @param slot_p address storing the slot to deallocate
3956  */
3957 void
3958 dbus_connection_free_data_slot (dbus_int32_t *slot_p)
3959 {
3960   _dbus_return_if_fail (*slot_p >= 0);
3961   
3962   _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
3963 }
3964
3965 /**
3966  * Stores a pointer on a DBusConnection, along
3967  * with an optional function to be used for freeing
3968  * the data when the data is set again, or when
3969  * the connection is finalized. The slot number
3970  * must have been allocated with dbus_connection_allocate_data_slot().
3971  *
3972  * @param connection the connection
3973  * @param slot the slot number
3974  * @param data the data to store
3975  * @param free_data_func finalizer function for the data
3976  * @returns #TRUE if there was enough memory to store the data
3977  */
3978 dbus_bool_t
3979 dbus_connection_set_data (DBusConnection   *connection,
3980                           dbus_int32_t      slot,
3981                           void             *data,
3982                           DBusFreeFunction  free_data_func)
3983 {
3984   DBusFreeFunction old_free_func;
3985   void *old_data;
3986   dbus_bool_t retval;
3987
3988   _dbus_return_val_if_fail (connection != NULL, FALSE);
3989   _dbus_return_val_if_fail (slot >= 0, FALSE);
3990   
3991   CONNECTION_LOCK (connection);
3992
3993   retval = _dbus_data_slot_list_set (&slot_allocator,
3994                                      &connection->slot_list,
3995                                      slot, data, free_data_func,
3996                                      &old_free_func, &old_data);
3997   
3998   CONNECTION_UNLOCK (connection);
3999
4000   if (retval)
4001     {
4002       /* Do the actual free outside the connection lock */
4003       if (old_free_func)
4004         (* old_free_func) (old_data);
4005     }
4006
4007   return retval;
4008 }
4009
4010 /**
4011  * Retrieves data previously set with dbus_connection_set_data().
4012  * The slot must still be allocated (must not have been freed).
4013  *
4014  * @param connection the connection
4015  * @param slot the slot to get data from
4016  * @returns the data, or #NULL if not found
4017  */
4018 void*
4019 dbus_connection_get_data (DBusConnection   *connection,
4020                           dbus_int32_t      slot)
4021 {
4022   void *res;
4023
4024   _dbus_return_val_if_fail (connection != NULL, NULL);
4025   
4026   CONNECTION_LOCK (connection);
4027
4028   res = _dbus_data_slot_list_get (&slot_allocator,
4029                                   &connection->slot_list,
4030                                   slot);
4031   
4032   CONNECTION_UNLOCK (connection);
4033
4034   return res;
4035 }
4036
4037 /**
4038  * This function sets a global flag for whether dbus_connection_new()
4039  * will set SIGPIPE behavior to SIG_IGN.
4040  *
4041  * @param will_modify_sigpipe #TRUE to allow sigpipe to be set to SIG_IGN
4042  */
4043 void
4044 dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
4045 {  
4046   _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
4047 }
4048
4049 /**
4050  * Specifies the maximum size message this connection is allowed to
4051  * receive. Larger messages will result in disconnecting the
4052  * connection.
4053  * 
4054  * @param connection a #DBusConnection
4055  * @param size maximum message size the connection can receive, in bytes
4056  */
4057 void
4058 dbus_connection_set_max_message_size (DBusConnection *connection,
4059                                       long            size)
4060 {
4061   _dbus_return_if_fail (connection != NULL);
4062   
4063   CONNECTION_LOCK (connection);
4064   _dbus_transport_set_max_message_size (connection->transport,
4065                                         size);
4066   CONNECTION_UNLOCK (connection);
4067 }
4068
4069 /**
4070  * Gets the value set by dbus_connection_set_max_message_size().
4071  *
4072  * @param connection the connection
4073  * @returns the max size of a single message
4074  */
4075 long
4076 dbus_connection_get_max_message_size (DBusConnection *connection)
4077 {
4078   long res;
4079
4080   _dbus_return_val_if_fail (connection != NULL, 0);
4081   
4082   CONNECTION_LOCK (connection);
4083   res = _dbus_transport_get_max_message_size (connection->transport);
4084   CONNECTION_UNLOCK (connection);
4085   return res;
4086 }
4087
4088 /**
4089  * Sets the maximum total number of bytes that can be used for all messages
4090  * received on this connection. Messages count toward the maximum until
4091  * they are finalized. When the maximum is reached, the connection will
4092  * not read more data until some messages are finalized.
4093  *
4094  * The semantics of the maximum are: if outstanding messages are
4095  * already above the maximum, additional messages will not be read.
4096  * The semantics are not: if the next message would cause us to exceed
4097  * the maximum, we don't read it. The reason is that we don't know the
4098  * size of a message until after we read it.
4099  *
4100  * Thus, the max live messages size can actually be exceeded
4101  * by up to the maximum size of a single message.
4102  * 
4103  * Also, if we read say 1024 bytes off the wire in a single read(),
4104  * and that contains a half-dozen small messages, we may exceed the
4105  * size max by that amount. But this should be inconsequential.
4106  *
4107  * This does imply that we can't call read() with a buffer larger
4108  * than we're willing to exceed this limit by.
4109  *
4110  * @param connection the connection
4111  * @param size the maximum size in bytes of all outstanding messages
4112  */
4113 void
4114 dbus_connection_set_max_received_size (DBusConnection *connection,
4115                                        long            size)
4116 {
4117   _dbus_return_if_fail (connection != NULL);
4118   
4119   CONNECTION_LOCK (connection);
4120   _dbus_transport_set_max_received_size (connection->transport,
4121                                          size);
4122   CONNECTION_UNLOCK (connection);
4123 }
4124
4125 /**
4126  * Gets the value set by dbus_connection_set_max_received_size().
4127  *
4128  * @param connection the connection
4129  * @returns the max size of all live messages
4130  */
4131 long
4132 dbus_connection_get_max_received_size (DBusConnection *connection)
4133 {
4134   long res;
4135
4136   _dbus_return_val_if_fail (connection != NULL, 0);
4137   
4138   CONNECTION_LOCK (connection);
4139   res = _dbus_transport_get_max_received_size (connection->transport);
4140   CONNECTION_UNLOCK (connection);
4141   return res;
4142 }
4143
4144 /**
4145  * Gets the approximate size in bytes of all messages in the outgoing
4146  * message queue. The size is approximate in that you shouldn't use
4147  * it to decide how many bytes to read off the network or anything
4148  * of that nature, as optimizations may choose to tell small white lies
4149  * to avoid performance overhead.
4150  *
4151  * @param connection the connection
4152  * @returns the number of bytes that have been queued up but not sent
4153  */
4154 long
4155 dbus_connection_get_outgoing_size (DBusConnection *connection)
4156 {
4157   long res;
4158
4159   _dbus_return_val_if_fail (connection != NULL, 0);
4160   
4161   CONNECTION_LOCK (connection);
4162   res = _dbus_counter_get_value (connection->outgoing_counter);
4163   CONNECTION_UNLOCK (connection);
4164   return res;
4165 }
4166
4167 /** @} */