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