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