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