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