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