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