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