2003-02-27 Havoc Pennington <hp@pobox.com>
[platform/upstream/dbus.git] / dbus / dbus-connection.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-connection.c DBusConnection object
3  *
4  * Copyright (C) 2002, 2003  Red Hat Inc.
5  *
6  * Licensed under the Academic Free License version 1.2
7  * 
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  * 
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  */
23
24 #include "dbus-connection.h"
25 #include "dbus-list.h"
26 #include "dbus-timeout.h"
27 #include "dbus-transport.h"
28 #include "dbus-watch.h"
29 #include "dbus-connection-internal.h"
30 #include "dbus-list.h"
31 #include "dbus-hash.h"
32 #include "dbus-message-internal.h"
33 #include "dbus-message-handler.h"
34 #include "dbus-threads.h"
35 #include "dbus-protocol.h"
36 #include "dbus-dataslot.h"
37
38 /**
39  * @defgroup DBusConnection DBusConnection
40  * @ingroup  DBus
41  * @brief Connection to another application
42  *
43  * A DBusConnection represents a connection to another
44  * application. Messages can be sent and received via this connection.
45  *
46  * The connection maintains a queue of incoming messages and a queue
47  * of outgoing messages. dbus_connection_pop_message() and friends
48  * can be used to read incoming messages from the queue.
49  * Outgoing messages are automatically discarded as they are
50  * written to the network.
51  *
52  * In brief a DBusConnection is a message queue associated with some
53  * message transport mechanism such as a socket.
54  * 
55  */
56
57 /**
58  * @defgroup DBusConnectionInternals DBusConnection implementation details
59  * @ingroup  DBusInternals
60  * @brief Implementation details of DBusConnection
61  *
62  * @{
63  */
64
65 /** default timeout value when waiting for a message reply */
66 #define DEFAULT_TIMEOUT_VALUE (15 * 1000)
67
68 static dbus_bool_t _dbus_modify_sigpipe = TRUE;
69
70 /**
71  * Implementation details of DBusConnection. All fields are private.
72  */
73 struct DBusConnection
74 {
75   int refcount; /**< Reference count. */
76
77   DBusMutex *mutex; /**< Lock on the entire DBusConnection */
78
79   dbus_bool_t dispatch_acquired; /**< Protects dispatch_message */
80   DBusCondVar *dispatch_cond;    /**< Protects dispatch_message */
81
82   dbus_bool_t io_path_acquired;  /**< Protects transport io path */
83   DBusCondVar *io_path_cond;     /**< Protects transport io path */
84   
85   DBusList *outgoing_messages; /**< Queue of messages we need to send, send the end of the list first. */
86   DBusList *incoming_messages; /**< Queue of messages we have received, end of the list received most recently. */
87
88   DBusMessage *message_borrowed; /**< True if the first incoming message has been borrowed */
89   DBusCondVar *message_returned_cond; /**< Used with dbus_connection_borrow_message() */
90   
91   int n_outgoing;              /**< Length of outgoing queue. */
92   int n_incoming;              /**< Length of incoming queue. */
93   
94   DBusTransport *transport;    /**< Object that sends/receives messages over network. */
95   DBusWatchList *watches;      /**< Stores active watches. */
96   DBusTimeoutList *timeouts;   /**< Stores active timeouts. */
97   
98   DBusHashTable *handler_table; /**< Table of registered DBusMessageHandler */
99   DBusList *filter_list;        /**< List of filters. */
100
101   DBusDataSlotList slot_list;   /**< Data stored by allocated integer ID */
102
103   DBusHashTable *pending_replies;  /**< Hash of message serials and their message handlers. */  
104   DBusCounter *connection_counter; /**< Counter that we decrement when finalized */
105   
106   int client_serial;            /**< Client serial. Increments each time a message is sent  */
107   DBusList *disconnect_message_link; /**< Preallocated list node for queueing the disconnection message */
108
109   DBusWakeupMainFunction wakeup_main_function; /**< Function to wake up the mainloop  */
110   void *wakeup_main_data; /**< Application data for wakeup_main_function */
111   DBusFreeFunction free_wakeup_main_data; /**< free wakeup_main_data */
112 };
113
114 typedef struct
115 {
116   DBusConnection *connection;
117   DBusMessageHandler *handler;
118   DBusTimeout *timeout;
119   int serial;
120
121   DBusList *timeout_link; /* Preallocated timeout response */
122   
123   dbus_bool_t timeout_added;
124   dbus_bool_t connection_added;
125 } ReplyHandlerData;
126
127 static void reply_handler_data_free (ReplyHandlerData *data);
128
129 static void _dbus_connection_remove_timeout_locked (DBusConnection *connection,
130                                                     DBusTimeout    *timeout);
131
132 /**
133  * Acquires the connection lock.
134  *
135  * @param connection the connection.
136  */
137 void
138 _dbus_connection_lock (DBusConnection *connection)
139 {
140   dbus_mutex_lock (connection->mutex);
141 }
142
143 /**
144  * Releases the connection lock.
145  *
146  * @param connection the connection.
147  */
148 void
149 _dbus_connection_unlock (DBusConnection *connection)
150 {
151   dbus_mutex_unlock (connection->mutex);
152 }
153
154 /**
155  * Wakes up the main loop if it is sleeping
156  * Needed if we're e.g. queueing outgoing messages
157  * on a thread while the mainloop sleeps.
158  *
159  * @param connection the connection.
160  */
161 static void
162 _dbus_connection_wakeup_mainloop (DBusConnection *connection)
163 {
164   if (connection->wakeup_main_function)
165     (*connection->wakeup_main_function) (connection->wakeup_main_data);
166 }
167
168 /**
169  * Adds a message to the incoming message queue, returning #FALSE
170  * if there's insufficient memory to queue the message.
171  *
172  * @param connection the connection.
173  * @param message the message to queue.
174  * @returns #TRUE on success.
175  */
176 dbus_bool_t
177 _dbus_connection_queue_received_message (DBusConnection *connection,
178                                          DBusMessage    *message)
179 {
180   ReplyHandlerData *reply_handler_data;
181   dbus_int32_t reply_serial;
182   
183   _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport));
184   
185   if (!_dbus_list_append (&connection->incoming_messages,
186                           message))
187     return FALSE;
188
189   /* If this is a reply we're waiting on, remove timeout for it */
190   reply_serial = _dbus_message_get_reply_serial (message);
191   if (reply_serial != -1)
192     {
193       reply_handler_data = _dbus_hash_table_lookup_int (connection->pending_replies,
194                                                         reply_serial);
195       if (reply_handler_data != NULL)
196         {
197           if (reply_handler_data->timeout_added)
198             _dbus_connection_remove_timeout_locked (connection,
199                                                     reply_handler_data->timeout);
200           reply_handler_data->timeout_added = FALSE;
201         }
202     }
203   
204   dbus_message_ref (message);
205   connection->n_incoming += 1;
206
207   _dbus_connection_wakeup_mainloop (connection);
208   
209   _dbus_verbose ("Incoming message %p added to queue, %d incoming\n",
210                  message, connection->n_incoming);
211   
212   return TRUE;
213 }
214
215 /**
216  * Adds a link + message to the incoming message queue.
217  * Can't fail. Takes ownership of both link and message.
218  *
219  * @param connection the connection.
220  * @param link the list node and message to queue.
221  *
222  * @todo This needs to wake up the mainloop if it is in
223  * a poll/select and this is a multithreaded app.
224  */
225 static void
226 _dbus_connection_queue_synthesized_message_link (DBusConnection *connection,
227                                                  DBusList *link)
228 {
229   _dbus_list_append_link (&connection->incoming_messages, link);
230
231   connection->n_incoming += 1;
232
233   _dbus_connection_wakeup_mainloop (connection);
234   
235   _dbus_verbose ("Incoming synthesized message %p added to queue, %d incoming\n",
236                  link->data, connection->n_incoming);
237 }
238
239
240 /**
241  * Checks whether there are messages in the outgoing message queue.
242  *
243  * @param connection the connection.
244  * @returns #TRUE if the outgoing queue is non-empty.
245  */
246 dbus_bool_t
247 _dbus_connection_have_messages_to_send (DBusConnection *connection)
248 {
249   return connection->outgoing_messages != NULL;
250 }
251
252 /**
253  * Gets the next outgoing message. The message remains in the
254  * queue, and the caller does not own a reference to it.
255  *
256  * @param connection the connection.
257  * @returns the message to be sent.
258  */ 
259 DBusMessage*
260 _dbus_connection_get_message_to_send (DBusConnection *connection)
261 {
262   return _dbus_list_get_last (&connection->outgoing_messages);
263 }
264
265 /**
266  * Notifies the connection that a message has been sent, so the
267  * message can be removed from the outgoing queue.
268  *
269  * @param connection the connection.
270  * @param message the message that was sent.
271  */
272 void
273 _dbus_connection_message_sent (DBusConnection *connection,
274                                DBusMessage    *message)
275 {
276   _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport));
277   _dbus_assert (message == _dbus_list_get_last (&connection->outgoing_messages));
278   
279   _dbus_list_pop_last (&connection->outgoing_messages);
280   dbus_message_unref (message);
281   
282   connection->n_outgoing -= 1;
283
284   _dbus_verbose ("Message %p removed from outgoing queue, %d left to send\n",
285                  message, connection->n_outgoing);
286   
287   if (connection->n_outgoing == 0)
288     _dbus_transport_messages_pending (connection->transport,
289                                       connection->n_outgoing);  
290 }
291
292 /**
293  * Adds a watch using the connection's DBusAddWatchFunction if
294  * available. Otherwise records the watch to be added when said
295  * function is available. Also re-adds the watch if the
296  * DBusAddWatchFunction changes. May fail due to lack of memory.
297  *
298  * @param connection the connection.
299  * @param watch the watch to add.
300  * @returns #TRUE on success.
301  */
302 dbus_bool_t
303 _dbus_connection_add_watch (DBusConnection *connection,
304                             DBusWatch      *watch)
305 {
306   if (connection->watches) /* null during finalize */
307     return _dbus_watch_list_add_watch (connection->watches,
308                                        watch);
309   else
310     return FALSE;
311 }
312
313 /**
314  * Removes a watch using the connection's DBusRemoveWatchFunction
315  * if available. It's an error to call this function on a watch
316  * that was not previously added.
317  *
318  * @param connection the connection.
319  * @param watch the watch to remove.
320  */
321 void
322 _dbus_connection_remove_watch (DBusConnection *connection,
323                                DBusWatch      *watch)
324 {
325   if (connection->watches) /* null during finalize */
326     _dbus_watch_list_remove_watch (connection->watches,
327                                    watch);
328 }
329
330 /**
331  * Adds a timeout using the connection's DBusAddTimeoutFunction if
332  * available. Otherwise records the timeout to be added when said
333  * function is available. Also re-adds the timeout if the
334  * DBusAddTimeoutFunction changes. May fail due to lack of memory.
335  *
336  * @param connection the connection.
337  * @param timeout the timeout to add.
338  * @returns #TRUE on success.
339  */
340 dbus_bool_t
341 _dbus_connection_add_timeout (DBusConnection *connection,
342                               DBusTimeout    *timeout)
343 {
344  if (connection->timeouts) /* null during finalize */
345     return _dbus_timeout_list_add_timeout (connection->timeouts,
346                                            timeout);
347   else
348     return FALSE;  
349 }
350
351 /**
352  * Removes a timeout using the connection's DBusRemoveTimeoutFunction
353  * if available. It's an error to call this function on a timeout
354  * that was not previously added.
355  *
356  * @param connection the connection.
357  * @param timeout the timeout to remove.
358  */
359 void
360 _dbus_connection_remove_timeout (DBusConnection *connection,
361                                  DBusTimeout    *timeout)
362 {
363   if (connection->timeouts) /* null during finalize */
364     _dbus_timeout_list_remove_timeout (connection->timeouts,
365                                        timeout);
366 }
367
368 static void
369 _dbus_connection_remove_timeout_locked (DBusConnection *connection,
370                                         DBusTimeout    *timeout)
371 {
372   dbus_mutex_lock (connection->mutex);
373   _dbus_connection_remove_timeout (connection, timeout);
374   dbus_mutex_unlock (connection->mutex);
375 }
376
377
378 /**
379  * Tells the connection that the transport has been disconnected.
380  * Results in posting a disconnect message on the incoming message
381  * queue.  Only has an effect the first time it's called.
382  *
383  * @param connection the connection
384  */
385 void
386 _dbus_connection_notify_disconnected (DBusConnection *connection)
387 {
388   if (connection->disconnect_message_link)
389     {
390       /* We haven't sent the disconnect message already */
391       _dbus_connection_queue_synthesized_message_link (connection,
392                                                        connection->disconnect_message_link);
393       connection->disconnect_message_link = NULL;
394     }
395 }
396
397
398 /**
399  * Acquire the transporter I/O path. This must be done before
400  * doing any I/O in the transporter. May sleep and drop the
401  * connection mutex while waiting for the I/O path.
402  *
403  * @param connection the connection.
404  * @param timeout_milliseconds maximum blocking time, or -1 for no limit.
405  * @returns TRUE if the I/O path was acquired.
406  */
407 static dbus_bool_t
408 _dbus_connection_acquire_io_path (DBusConnection *connection,
409                                   int timeout_milliseconds)
410 {
411   dbus_bool_t res = TRUE;
412
413   if (connection->io_path_acquired)
414     {
415       if (timeout_milliseconds != -1) 
416         res = dbus_condvar_wait_timeout (connection->io_path_cond,
417                                          connection->mutex,
418                                          timeout_milliseconds);
419       else
420         dbus_condvar_wait (connection->io_path_cond, connection->mutex);
421     }
422   
423   if (res)
424     {
425       _dbus_assert (!connection->io_path_acquired);
426
427       connection->io_path_acquired = TRUE;
428     }
429   
430   return res;
431 }
432
433 /**
434  * Release the I/O path when you're done with it. Only call
435  * after you've acquired the I/O. Wakes up at most one thread
436  * currently waiting to acquire the I/O path.
437  *
438  * @param connection the connection.
439  */
440 static void
441 _dbus_connection_release_io_path (DBusConnection *connection)
442 {
443   _dbus_assert (connection->io_path_acquired);
444
445   connection->io_path_acquired = FALSE;
446   dbus_condvar_wake_one (connection->io_path_cond);
447 }
448
449
450 /**
451  * Queues incoming messages and sends outgoing messages for this
452  * connection, optionally blocking in the process. Each call to
453  * _dbus_connection_do_iteration() will call select() or poll() one
454  * time and then read or write data if possible.
455  *
456  * The purpose of this function is to be able to flush outgoing
457  * messages or queue up incoming messages without returning
458  * control to the application and causing reentrancy weirdness.
459  *
460  * The flags parameter allows you to specify whether to
461  * read incoming messages, write outgoing messages, or both,
462  * and whether to block if no immediate action is possible.
463  *
464  * The timeout_milliseconds parameter does nothing unless the
465  * iteration is blocking.
466  *
467  * If there are no outgoing messages and DBUS_ITERATION_DO_READING
468  * wasn't specified, then it's impossible to block, even if
469  * you specify DBUS_ITERATION_BLOCK; in that case the function
470  * returns immediately.
471  * 
472  * @param connection the connection.
473  * @param flags iteration flags.
474  * @param timeout_milliseconds maximum blocking time, or -1 for no limit.
475  */
476 void
477 _dbus_connection_do_iteration (DBusConnection *connection,
478                                unsigned int    flags,
479                                int             timeout_milliseconds)
480 {
481   if (connection->n_outgoing == 0)
482     flags &= ~DBUS_ITERATION_DO_WRITING;
483
484   if (_dbus_connection_acquire_io_path (connection,
485                                         (flags & DBUS_ITERATION_BLOCK)?timeout_milliseconds:0))
486     {
487       _dbus_transport_do_iteration (connection->transport,
488                                     flags, timeout_milliseconds);
489       _dbus_connection_release_io_path (connection);
490     }
491 }
492
493 /**
494  * Creates a new connection for the given transport.  A transport
495  * represents a message stream that uses some concrete mechanism, such
496  * as UNIX domain sockets. May return #NULL if insufficient
497  * memory exists to create the connection.
498  *
499  * @param transport the transport.
500  * @returns the new connection, or #NULL on failure.
501  */
502 DBusConnection*
503 _dbus_connection_new_for_transport (DBusTransport *transport)
504 {
505   DBusConnection *connection;
506   DBusWatchList *watch_list;
507   DBusTimeoutList *timeout_list;
508   DBusHashTable *handler_table, *pending_replies;
509   DBusMutex *mutex;
510   DBusCondVar *message_returned_cond;
511   DBusCondVar *dispatch_cond;
512   DBusCondVar *io_path_cond;
513   DBusList *disconnect_link;
514   DBusMessage *disconnect_message;
515
516   watch_list = NULL;
517   connection = NULL;
518   handler_table = NULL;
519   pending_replies = NULL;
520   timeout_list = NULL;
521   mutex = NULL;
522   message_returned_cond = NULL;
523   dispatch_cond = NULL;
524   io_path_cond = NULL;
525   disconnect_link = NULL;
526   disconnect_message = NULL;
527   
528   watch_list = _dbus_watch_list_new ();
529   if (watch_list == NULL)
530     goto error;
531
532   timeout_list = _dbus_timeout_list_new ();
533   if (timeout_list == NULL)
534     goto error;
535   
536   handler_table =
537     _dbus_hash_table_new (DBUS_HASH_STRING,
538                           dbus_free, NULL);
539   if (handler_table == NULL)
540     goto error;
541
542   pending_replies =
543     _dbus_hash_table_new (DBUS_HASH_INT,
544                           NULL, (DBusFreeFunction)reply_handler_data_free);
545   if (pending_replies == NULL)
546     goto error;
547   
548   connection = dbus_new0 (DBusConnection, 1);
549   if (connection == NULL)
550     goto error;
551
552   mutex = dbus_mutex_new ();
553   if (mutex == NULL)
554     goto error;
555   
556   message_returned_cond = dbus_condvar_new ();
557   if (message_returned_cond == NULL)
558     goto error;
559   
560   dispatch_cond = dbus_condvar_new ();
561   if (dispatch_cond == NULL)
562     goto error;
563   
564   io_path_cond = dbus_condvar_new ();
565   if (io_path_cond == NULL)
566     goto error;
567
568   disconnect_message = dbus_message_new (NULL, DBUS_MESSAGE_LOCAL_DISCONNECT);
569   if (disconnect_message == NULL)
570     goto error;
571
572   disconnect_link = _dbus_list_alloc_link (disconnect_message);
573   if (disconnect_link == NULL)
574     goto error;
575
576   if (_dbus_modify_sigpipe)
577     _dbus_disable_sigpipe ();
578   
579   connection->refcount = 1;
580   connection->mutex = mutex;
581   connection->dispatch_cond = dispatch_cond;
582   connection->io_path_cond = io_path_cond;
583   connection->message_returned_cond = message_returned_cond;
584   connection->transport = transport;
585   connection->watches = watch_list;
586   connection->timeouts = timeout_list;
587   connection->handler_table = handler_table;
588   connection->pending_replies = pending_replies;
589   connection->filter_list = NULL;
590
591   _dbus_data_slot_list_init (&connection->slot_list);
592
593   connection->client_serial = 1;
594
595   connection->disconnect_message_link = disconnect_link;
596   
597   _dbus_transport_ref (transport);
598   _dbus_transport_set_connection (transport, connection);
599   
600   return connection;
601   
602  error:
603   if (disconnect_message != NULL)
604     dbus_message_unref (disconnect_message);
605   
606   if (disconnect_link != NULL)
607     _dbus_list_free_link (disconnect_link);
608   
609   if (io_path_cond != NULL)
610     dbus_condvar_free (io_path_cond);
611   
612   if (dispatch_cond != NULL)
613     dbus_condvar_free (dispatch_cond);
614   
615   if (message_returned_cond != NULL)
616     dbus_condvar_free (message_returned_cond);
617   
618   if (mutex != NULL)
619     dbus_mutex_free (mutex);
620
621   if (connection != NULL)
622     dbus_free (connection);
623
624   if (handler_table)
625     _dbus_hash_table_unref (handler_table);
626
627   if (pending_replies)
628     _dbus_hash_table_unref (pending_replies);
629   
630   if (watch_list)
631     _dbus_watch_list_free (watch_list);
632
633   if (timeout_list)
634     _dbus_timeout_list_free (timeout_list);
635   
636   return NULL;
637 }
638
639 static dbus_int32_t
640 _dbus_connection_get_next_client_serial (DBusConnection *connection)
641 {
642   int serial;
643
644   serial = connection->client_serial++;
645
646   if (connection->client_serial < 0)
647     connection->client_serial = 1;
648   
649   return serial;
650 }
651
652 /**
653  * Used to notify a connection when a DBusMessageHandler is
654  * destroyed, so the connection can drop any reference
655  * to the handler. This is a private function, but still
656  * takes the connection lock. Don't call it with the lock held.
657  *
658  * @todo needs to check in pending_replies too.
659  * 
660  * @param connection the connection
661  * @param handler the handler
662  */
663 void
664 _dbus_connection_handler_destroyed_locked (DBusConnection     *connection,
665                                            DBusMessageHandler *handler)
666 {
667   DBusHashIter iter;
668   DBusList *link;
669
670   dbus_mutex_lock (connection->mutex);
671   
672   _dbus_hash_iter_init (connection->handler_table, &iter);
673   while (_dbus_hash_iter_next (&iter))
674     {
675       DBusMessageHandler *h = _dbus_hash_iter_get_value (&iter);
676
677       if (h == handler)
678         _dbus_hash_iter_remove_entry (&iter);
679     }
680
681   link = _dbus_list_get_first_link (&connection->filter_list);
682   while (link != NULL)
683     {
684       DBusMessageHandler *h = link->data;
685       DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
686
687       if (h == handler)
688         _dbus_list_remove_link (&connection->filter_list,
689                                 link);
690       
691       link = next;
692     }
693   dbus_mutex_unlock (connection->mutex);
694 }
695
696 /**
697  * Adds the counter used to count the number of open connections.
698  * Increments the counter by one, and saves it to be decremented
699  * again when this connection is finalized.
700  *
701  * @param connection a #DBusConnection
702  * @param counter counter that tracks number of connections
703  */
704 void
705 _dbus_connection_set_connection_counter (DBusConnection *connection,
706                                          DBusCounter    *counter)
707 {
708   _dbus_assert (connection->connection_counter == NULL);
709   
710   connection->connection_counter = counter;
711   _dbus_counter_ref (connection->connection_counter);
712   _dbus_counter_adjust (connection->connection_counter, 1);
713 }
714
715 /** @} */
716
717 /**
718  * @addtogroup DBusConnection
719  *
720  * @{
721  */
722
723 /**
724  * Opens a new connection to a remote address.
725  *
726  * @todo specify what the address parameter is. Right now
727  * it's just the name of a UNIX domain socket. It should be
728  * something more complex that encodes which transport to use.
729  *
730  * If the open fails, the function returns #NULL, and provides
731  * a reason for the failure in the result parameter. Pass
732  * #NULL for the result parameter if you aren't interested
733  * in the reason for failure.
734  * 
735  * @param address the address.
736  * @param result address where a result code can be returned.
737  * @returns new connection, or #NULL on failure.
738  */
739 DBusConnection*
740 dbus_connection_open (const char     *address,
741                       DBusResultCode *result)
742 {
743   DBusConnection *connection;
744   DBusTransport *transport;
745   
746   transport = _dbus_transport_open (address, result);
747   if (transport == NULL)
748     return NULL;
749   
750   connection = _dbus_connection_new_for_transport (transport);
751
752   _dbus_transport_unref (transport);
753   
754   if (connection == NULL)
755     {
756       dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
757       return NULL;
758     }
759   
760   return connection;
761 }
762
763 /**
764  * Increments the reference count of a DBusConnection.
765  *
766  * @param connection the connection.
767  */
768 void
769 dbus_connection_ref (DBusConnection *connection)
770 {
771   dbus_mutex_lock (connection->mutex);
772   _dbus_assert (connection->refcount > 0);
773
774   connection->refcount += 1;
775   dbus_mutex_unlock (connection->mutex);
776 }
777
778 /**
779  * Increments the reference count of a DBusConnection.
780  * Requires that the caller already holds the connection lock.
781  *
782  * @param connection the connection.
783  */
784 void
785 _dbus_connection_ref_unlocked (DBusConnection *connection)
786 {
787   _dbus_assert (connection->refcount > 0);
788   connection->refcount += 1;
789 }
790
791
792 /* This is run without the mutex held, but after the last reference
793  * to the connection has been dropped we should have no thread-related
794  * problems
795  */
796 static void
797 _dbus_connection_last_unref (DBusConnection *connection)
798 {
799   DBusHashIter iter;
800   DBusList *link;
801
802   /* You have to disconnect the connection before unref:ing it. Otherwise
803    * you won't get the disconnected message.
804    */
805   _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
806   
807   if (connection->connection_counter != NULL)
808     {
809       /* subtract ourselves from the counter */
810       _dbus_counter_adjust (connection->connection_counter, - 1);
811       _dbus_counter_unref (connection->connection_counter);
812       connection->connection_counter = NULL;
813     }
814   
815   _dbus_watch_list_free (connection->watches);
816   connection->watches = NULL;
817   
818   _dbus_timeout_list_free (connection->timeouts);
819   connection->timeouts = NULL;
820
821   /* calls out to application code... */
822   _dbus_data_slot_list_free (&connection->slot_list);
823   
824   _dbus_hash_iter_init (connection->handler_table, &iter);
825   while (_dbus_hash_iter_next (&iter))
826     {
827       DBusMessageHandler *h = _dbus_hash_iter_get_value (&iter);
828       
829       _dbus_message_handler_remove_connection (h, connection);
830     }
831   
832   link = _dbus_list_get_first_link (&connection->filter_list);
833   while (link != NULL)
834     {
835       DBusMessageHandler *h = link->data;
836       DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
837       
838       _dbus_message_handler_remove_connection (h, connection);
839       
840       link = next;
841     }
842
843   _dbus_hash_table_unref (connection->handler_table);
844   connection->handler_table = NULL;
845
846   _dbus_hash_table_unref (connection->pending_replies);
847   connection->pending_replies = NULL;
848   
849   _dbus_list_clear (&connection->filter_list);
850   
851   _dbus_list_foreach (&connection->outgoing_messages,
852                       (DBusForeachFunction) dbus_message_unref,
853                       NULL);
854   _dbus_list_clear (&connection->outgoing_messages);
855   
856   _dbus_list_foreach (&connection->incoming_messages,
857                       (DBusForeachFunction) dbus_message_unref,
858                       NULL);
859   _dbus_list_clear (&connection->incoming_messages);
860   
861   _dbus_transport_unref (connection->transport);
862
863   if (connection->disconnect_message_link)
864     {
865       DBusMessage *message = connection->disconnect_message_link->data;
866       dbus_message_unref (message);
867       _dbus_list_free_link (connection->disconnect_message_link);
868     }
869   
870   dbus_condvar_free (connection->dispatch_cond);
871   dbus_condvar_free (connection->io_path_cond);
872   dbus_condvar_free (connection->message_returned_cond);
873   
874   dbus_mutex_free (connection->mutex);
875   
876   dbus_free (connection);
877 }
878
879 /**
880  * Decrements the reference count of a DBusConnection, and finalizes
881  * it if the count reaches zero.  It is a bug to drop the last reference
882  * to a connection that has not been disconnected.
883  *
884  * @param connection the connection.
885  */
886 void
887 dbus_connection_unref (DBusConnection *connection)
888 {
889   dbus_bool_t last_unref;
890   
891   dbus_mutex_lock (connection->mutex);
892   
893   _dbus_assert (connection != NULL);
894   _dbus_assert (connection->refcount > 0);
895
896   connection->refcount -= 1;
897   last_unref = (connection->refcount == 0);
898
899   dbus_mutex_unlock (connection->mutex);
900
901   if (last_unref)
902     _dbus_connection_last_unref (connection);
903 }
904
905 /**
906  * Closes the connection, so no further data can be sent or received.
907  * Any further attempts to send data will result in errors.  This
908  * function does not affect the connection's reference count.  It's
909  * safe to disconnect a connection more than once; all calls after the
910  * first do nothing. It's impossible to "reconnect" a connection, a
911  * new connection must be created.
912  *
913  * @param connection the connection.
914  */
915 void
916 dbus_connection_disconnect (DBusConnection *connection)
917 {
918   dbus_mutex_lock (connection->mutex);
919   _dbus_transport_disconnect (connection->transport);
920   dbus_mutex_unlock (connection->mutex);
921 }
922
923 /**
924  * Gets whether the connection is currently connected.  All
925  * connections are connected when they are opened.  A connection may
926  * become disconnected when the remote application closes its end, or
927  * exits; a connection may also be disconnected with
928  * dbus_connection_disconnect().
929  *
930  * @param connection the connection.
931  * @returns #TRUE if the connection is still alive.
932  */
933 dbus_bool_t
934 dbus_connection_get_is_connected (DBusConnection *connection)
935 {
936   dbus_bool_t res;
937   
938   dbus_mutex_lock (connection->mutex);
939   res = _dbus_transport_get_is_connected (connection->transport);
940   dbus_mutex_unlock (connection->mutex);
941   
942   return res;
943 }
944
945 /**
946  * Gets whether the connection was authenticated. (Note that
947  * if the connection was authenticated then disconnected,
948  * this function still returns #TRUE)
949  *
950  * @param connection the connection
951  * @returns #TRUE if the connection was ever authenticated
952  */
953 dbus_bool_t
954 dbus_connection_get_is_authenticated (DBusConnection *connection)
955 {
956   dbus_bool_t res;
957   
958   dbus_mutex_lock (connection->mutex);
959   res = _dbus_transport_get_is_authenticated (connection->transport);
960   dbus_mutex_unlock (connection->mutex);
961   
962   return res;
963 }
964
965 /**
966  * Adds a message to the outgoing message queue. Does not block to
967  * write the message to the network; that happens asynchronously. to
968  * force the message to be written, call dbus_connection_flush().
969  *
970  * If the function fails, it returns #FALSE and returns the
971  * reason for failure via the result parameter.
972  * The result parameter can be #NULL if you aren't interested
973  * in the reason for the failure.
974  * 
975  * @param connection the connection.
976  * @param message the message to write.
977  * @param client_serial return location for client serial.
978  * @param result address where result code can be placed.
979  * @returns #TRUE on success.
980  */
981 dbus_bool_t
982 dbus_connection_send_message (DBusConnection *connection,
983                               DBusMessage    *message,
984                               dbus_int32_t   *client_serial,
985                               DBusResultCode *result)
986
987 {
988   dbus_int32_t serial;
989
990   dbus_mutex_lock (connection->mutex);
991
992   if (!_dbus_list_prepend (&connection->outgoing_messages,
993                            message))
994     {
995       dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
996       dbus_mutex_unlock (connection->mutex);
997       return FALSE;
998     }
999
1000   dbus_message_ref (message);
1001   connection->n_outgoing += 1;
1002
1003   _dbus_verbose ("Message %p added to outgoing queue, %d pending to send\n",
1004                  message, connection->n_outgoing);
1005
1006   if (_dbus_message_get_client_serial (message) == -1)
1007     {
1008       serial = _dbus_connection_get_next_client_serial (connection);
1009       _dbus_message_set_client_serial (message, serial);
1010     }
1011   
1012   if (client_serial)
1013     *client_serial = _dbus_message_get_client_serial (message);
1014   
1015   _dbus_message_lock (message);
1016
1017   if (connection->n_outgoing == 1)
1018     _dbus_transport_messages_pending (connection->transport,
1019                                       connection->n_outgoing);
1020   
1021   _dbus_connection_wakeup_mainloop (connection);
1022
1023   dbus_mutex_unlock (connection->mutex);
1024   
1025   return TRUE;
1026 }
1027
1028 static void
1029 reply_handler_timeout (void *data)
1030 {
1031   DBusConnection *connection;
1032   ReplyHandlerData *reply_handler_data = data;
1033
1034   connection = reply_handler_data->connection;
1035   
1036   dbus_mutex_lock (connection->mutex);
1037   if (reply_handler_data->timeout_link)
1038     {
1039       _dbus_connection_queue_synthesized_message_link (connection,
1040                                                        reply_handler_data->timeout_link);
1041       reply_handler_data->timeout_link = NULL;
1042     }
1043
1044   _dbus_connection_remove_timeout (connection,
1045                                    reply_handler_data->timeout);
1046   reply_handler_data->timeout_added = FALSE;
1047   
1048   dbus_mutex_unlock (connection->mutex);
1049 }
1050
1051 static void
1052 reply_handler_data_free (ReplyHandlerData *data)
1053 {
1054   if (!data)
1055     return;
1056
1057   if (data->timeout_added)
1058     _dbus_connection_remove_timeout_locked (data->connection,
1059                                             data->timeout);
1060
1061   if (data->connection_added)
1062     _dbus_message_handler_remove_connection (data->handler,
1063                                              data->connection);
1064
1065   if (data->timeout_link)
1066     {
1067       dbus_message_unref ((DBusMessage *)data->timeout_link->data);
1068       _dbus_list_free_link (data->timeout_link);
1069     }
1070   
1071   dbus_message_handler_unref (data->handler);
1072   
1073   dbus_free (data);
1074 }
1075
1076 /**
1077  * Queues a message to send, as with dbus_connection_send_message(),
1078  * but also sets up a DBusMessageHandler to receive a reply to the
1079  * message. If no reply is received in the given timeout_milliseconds,
1080  * expires the pending reply and sends the DBusMessageHandler a
1081  * synthetic error reply (generated in-process, not by the remote
1082  * application) indicating that a timeout occurred.
1083  *
1084  * Reply handlers see their replies after message filters see them,
1085  * but before message handlers added with
1086  * dbus_connection_register_handler() see them, regardless of the
1087  * reply message's name. Reply handlers are only handed a single
1088  * message as a reply, after one reply has been seen the handler is
1089  * removed. If a filter filters out the reply before the handler sees
1090  * it, the reply is immediately timed out and a timeout error reply is
1091  * generated. If a filter removes the timeout error reply then the
1092  * reply handler will never be called. Filters should not do this.
1093  * 
1094  * If #NULL is passed for the reply_handler, the timeout reply will
1095  * still be generated and placed into the message queue, but no
1096  * specific message handler will receive the reply.
1097  *
1098  * If -1 is passed for the timeout, a sane default timeout is used. -1
1099  * is typically the best value for the timeout for this reason, unless
1100  * you want a very short or very long timeout.  There is no way to
1101  * avoid a timeout entirely, other than passing INT_MAX for the
1102  * timeout to postpone it indefinitely.
1103  *
1104  * @todo I think we should rename this function family
1105  * dbus_connection_send(), send_with_reply(), etc. (i.e.
1106  * drop the "message" part), the names are too long.
1107  * 
1108  * @param connection the connection
1109  * @param message the message to send
1110  * @param reply_handler message handler expecting the reply, or #NULL
1111  * @param timeout_milliseconds timeout in milliseconds or -1 for default
1112  * @param result return location for result code
1113  * @returns #TRUE if the message is successfully queued, #FALSE if no memory.
1114  *
1115  */
1116 dbus_bool_t
1117 dbus_connection_send_message_with_reply (DBusConnection     *connection,
1118                                          DBusMessage        *message,
1119                                          DBusMessageHandler *reply_handler,
1120                                          int                 timeout_milliseconds,
1121                                          DBusResultCode     *result)
1122 {
1123   DBusTimeout *timeout;
1124   ReplyHandlerData *data;
1125   DBusMessage *reply;
1126   DBusList *reply_link;
1127   dbus_int32_t serial = -1;
1128   
1129   if (timeout_milliseconds == -1)
1130     timeout_milliseconds = DEFAULT_TIMEOUT_VALUE;
1131
1132   data = dbus_new0 (ReplyHandlerData, 1);
1133
1134   if (!data)
1135     {
1136       dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
1137       return FALSE;
1138     }
1139   
1140   timeout = _dbus_timeout_new (timeout_milliseconds, reply_handler_timeout,
1141                                data, NULL);
1142
1143   if (!timeout)
1144     {
1145       reply_handler_data_free (data);
1146       dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
1147       return FALSE;
1148     }
1149
1150   dbus_mutex_lock (connection->mutex);
1151   
1152   /* Add timeout */
1153   if (!_dbus_connection_add_timeout (connection, timeout))
1154     {
1155       reply_handler_data_free (data);
1156       _dbus_timeout_unref (timeout);
1157       dbus_mutex_unlock (connection->mutex);
1158       
1159       dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
1160       return FALSE;
1161     }
1162
1163   /* The connection now owns the reference to the timeout. */
1164   _dbus_timeout_unref (timeout);
1165   
1166   data->timeout_added = TRUE;
1167   data->timeout = timeout;
1168   data->connection = connection;
1169   
1170   if (!_dbus_message_handler_add_connection (reply_handler, connection))
1171     {
1172       dbus_mutex_unlock (connection->mutex);
1173       reply_handler_data_free (data);
1174       
1175       dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
1176       return FALSE;
1177     }
1178   data->connection_added = TRUE;
1179   
1180   /* Assign a serial to the message */
1181   if (_dbus_message_get_client_serial (message) == -1)
1182     {
1183       serial = _dbus_connection_get_next_client_serial (connection);
1184       _dbus_message_set_client_serial (message, serial);
1185     }
1186
1187   data->handler = reply_handler;
1188   data->serial = serial;
1189
1190   dbus_message_handler_ref (reply_handler);
1191
1192   reply = dbus_message_new_error_reply (message, DBUS_ERROR_NO_REPLY,
1193                                         "No reply within specified time");
1194   if (!reply)
1195     {
1196       dbus_mutex_unlock (connection->mutex);
1197       reply_handler_data_free (data);
1198       
1199       dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
1200       return FALSE;
1201     }
1202
1203   reply_link = _dbus_list_alloc_link (reply);
1204   if (!reply)
1205     {
1206       dbus_mutex_unlock (connection->mutex);
1207       dbus_message_unref (reply);
1208       reply_handler_data_free (data);
1209       
1210       dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
1211       return FALSE;
1212     }
1213
1214   data->timeout_link = reply_link;
1215   
1216   /* Insert the serial in the pending replies hash. */
1217   if (!_dbus_hash_table_insert_int (connection->pending_replies, serial, data))
1218     {
1219       dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
1220       dbus_mutex_unlock (connection->mutex);
1221       reply_handler_data_free (data);
1222       
1223       return FALSE;
1224     }
1225
1226   dbus_mutex_unlock (connection->mutex);
1227   
1228   if (!dbus_connection_send_message (connection, message, NULL, result))
1229     {
1230       /* This will free the handler data too */
1231       _dbus_hash_table_remove_int (connection->pending_replies, serial);
1232       return FALSE;
1233     }
1234
1235   dbus_set_result (result, DBUS_RESULT_SUCCESS);  
1236   return TRUE;
1237 }
1238
1239 /**
1240  * Sends a message and blocks a certain time period while waiting for a reply.
1241  * This function does not dispatch any message handlers until the main loop
1242  * has been reached. This function is used to do non-reentrant "method calls."
1243  * If a reply is received, it is returned, and removed from the incoming
1244  * message queue. If it is not received, #NULL is returned and the
1245  * result is set to #DBUS_RESULT_NO_REPLY. If something else goes
1246  * wrong, result is set to whatever is appropriate, such as
1247  * #DBUS_RESULT_NO_MEMORY.
1248  *
1249  * @todo could use performance improvements (it keeps scanning
1250  * the whole message queue for example) and has thread issues,
1251  * see comments in source
1252  *
1253  * @param connection the connection
1254  * @param message the message to send
1255  * @param timeout_milliseconds timeout in milliseconds or -1 for default
1256  * @param result return location for result code
1257  * @returns the message that is the reply or #NULL with an error code if the
1258  * function fails.
1259  */
1260 DBusMessage *
1261 dbus_connection_send_message_with_reply_and_block (DBusConnection     *connection,
1262                                                    DBusMessage        *message,
1263                                                    int                 timeout_milliseconds,
1264                                                    DBusResultCode     *result)
1265 {
1266   dbus_int32_t client_serial;
1267   DBusList *link;
1268   long start_tv_sec, start_tv_usec;
1269   long end_tv_sec, end_tv_usec;
1270   long tv_sec, tv_usec;
1271
1272   if (timeout_milliseconds == -1)
1273     timeout_milliseconds = DEFAULT_TIMEOUT_VALUE;
1274
1275   /* it would probably seem logical to pass in _DBUS_INT_MAX
1276    * for infinite timeout, but then math below would get
1277    * all overflow-prone, so smack that down.
1278    */
1279   if (timeout_milliseconds > _DBUS_ONE_HOUR_IN_MILLISECONDS * 6)
1280     timeout_milliseconds = _DBUS_ONE_HOUR_IN_MILLISECONDS * 6;
1281   
1282   if (!dbus_connection_send_message (connection, message, &client_serial, result))
1283     return NULL;
1284
1285   message = NULL;
1286   
1287   /* Flush message queue */
1288   dbus_connection_flush (connection);
1289
1290   dbus_mutex_lock (connection->mutex);
1291
1292   _dbus_get_current_time (&start_tv_sec, &start_tv_usec);
1293   end_tv_sec = start_tv_sec + timeout_milliseconds / 1000;
1294   end_tv_usec = start_tv_usec + (timeout_milliseconds % 1000) * 1000;
1295   end_tv_sec += end_tv_usec / _DBUS_USEC_PER_SECOND;
1296   end_tv_usec = end_tv_usec % _DBUS_USEC_PER_SECOND;
1297
1298   _dbus_verbose ("will block %d milliseconds from %ld sec %ld usec to %ld sec %ld usec\n",
1299                  timeout_milliseconds,
1300                  start_tv_sec, start_tv_usec,
1301                  end_tv_sec, end_tv_usec);
1302   
1303   /* Now we wait... */
1304   /* THREAD TODO: This is busted. What if a dispatch_message or pop_message
1305    * gets the message before we do?
1306    */
1307  block_again:  
1308   
1309   _dbus_connection_do_iteration (connection,
1310                                  DBUS_ITERATION_DO_READING |
1311                                  DBUS_ITERATION_BLOCK,
1312                                  timeout_milliseconds);
1313
1314   /* Check if we've gotten a reply */
1315   link = _dbus_list_get_first_link (&connection->incoming_messages);
1316
1317   while (link != NULL)
1318     {
1319       DBusMessage *reply = link->data;
1320
1321       if (_dbus_message_get_reply_serial (reply) == client_serial)
1322         {
1323           _dbus_list_remove_link (&connection->incoming_messages, link);
1324           dbus_message_ref (reply);
1325
1326           if (result)
1327             *result = DBUS_RESULT_SUCCESS;
1328           
1329           dbus_mutex_unlock (connection->mutex);
1330           return reply;
1331         }
1332       link = _dbus_list_get_next_link (&connection->incoming_messages, link);
1333     }
1334
1335   _dbus_get_current_time (&tv_sec, &tv_usec);
1336   
1337   if (tv_sec < start_tv_sec)
1338     ; /* clock set backward, bail out */
1339   else if (connection->disconnect_message_link == NULL)
1340     ; /* we're disconnected, bail out */
1341   else if (tv_sec < end_tv_sec ||
1342            (tv_sec == end_tv_sec && tv_usec < end_tv_usec))
1343     {
1344       timeout_milliseconds = (end_tv_sec - tv_sec) * 1000 +
1345         (end_tv_usec - tv_usec) / 1000;
1346       _dbus_verbose ("%d milliseconds remain\n", timeout_milliseconds);
1347       _dbus_assert (timeout_milliseconds > 0);
1348
1349       goto block_again; /* not expired yet */
1350     }
1351
1352   if (dbus_connection_get_is_connected (connection))
1353     dbus_set_result (result, DBUS_RESULT_NO_REPLY);
1354   else
1355     dbus_set_result (result, DBUS_RESULT_DISCONNECTED);
1356
1357   dbus_mutex_unlock (connection->mutex);
1358
1359   return NULL;
1360 }
1361
1362 /**
1363  * Blocks until the outgoing message queue is empty.
1364  *
1365  * @param connection the connection.
1366  */
1367 void
1368 dbus_connection_flush (DBusConnection *connection)
1369 {
1370   dbus_mutex_lock (connection->mutex);
1371   while (connection->n_outgoing > 0)
1372     _dbus_connection_do_iteration (connection,
1373                                    DBUS_ITERATION_DO_WRITING |
1374                                    DBUS_ITERATION_BLOCK,
1375                                    -1);
1376   dbus_mutex_unlock (connection->mutex);
1377 }
1378
1379 /**
1380  * Gets the number of messages in the incoming message queue.
1381  *
1382  * @param connection the connection.
1383  * @returns the number of messages in the queue.
1384  */
1385 int
1386 dbus_connection_get_n_messages (DBusConnection *connection)
1387 {
1388   int res;
1389
1390   dbus_mutex_lock (connection->mutex);
1391   res = connection->n_incoming;
1392   dbus_mutex_unlock (connection->mutex);
1393   return res;
1394 }
1395
1396
1397 /* Call with mutex held. Will drop it while waiting and re-acquire
1398  * before returning
1399  */
1400 static void
1401 _dbus_connection_wait_for_borrowed (DBusConnection *connection)
1402 {
1403   _dbus_assert (connection->message_borrowed != NULL);
1404
1405   while (connection->message_borrowed != NULL)
1406     dbus_condvar_wait (connection->message_returned_cond, connection->mutex);
1407 }
1408
1409 /**
1410  * Returns the first-received message from the incoming message queue,
1411  * leaving it in the queue. If the queue is empty, returns #NULL.
1412  * 
1413  * The caller does not own a reference to the returned message, and must
1414  * either return it using dbus_connection_return_message or keep it after
1415  * calling dbus_connection_steal_borrowed_message. No one can get at the
1416  * message while its borrowed, so return it as quickly as possible and
1417  * don't keep a reference to it after returning it. If you need to keep
1418  * the message, make a copy of it.
1419  *
1420  * @param connection the connection.
1421  * @returns next message in the incoming queue.
1422  */
1423 DBusMessage*
1424 dbus_connection_borrow_message  (DBusConnection *connection)
1425 {
1426   DBusMessage *message;
1427
1428   dbus_mutex_lock (connection->mutex);
1429
1430   if (connection->message_borrowed != NULL)
1431     _dbus_connection_wait_for_borrowed (connection);
1432   
1433   message = _dbus_list_get_first (&connection->incoming_messages);
1434
1435   if (message) 
1436     connection->message_borrowed = message;
1437   
1438   dbus_mutex_unlock (connection->mutex);
1439   return message;
1440 }
1441
1442 /**
1443  * @todo docs
1444  */
1445 void
1446 dbus_connection_return_message (DBusConnection *connection,
1447                                 DBusMessage    *message)
1448 {
1449   dbus_mutex_lock (connection->mutex);
1450   
1451   _dbus_assert (message == connection->message_borrowed);
1452   
1453   connection->message_borrowed = NULL;
1454   dbus_condvar_wake_all (connection->message_returned_cond);
1455   
1456   dbus_mutex_unlock (connection->mutex);
1457 }
1458
1459 /**
1460  * @todo docs
1461  */
1462 void
1463 dbus_connection_steal_borrowed_message (DBusConnection *connection,
1464                                         DBusMessage    *message)
1465 {
1466   DBusMessage *pop_message;
1467   
1468   dbus_mutex_lock (connection->mutex);
1469  
1470   _dbus_assert (message == connection->message_borrowed);
1471
1472   pop_message = _dbus_list_pop_first (&connection->incoming_messages);
1473   _dbus_assert (message == pop_message);
1474   
1475   connection->n_incoming -= 1;
1476  
1477   _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
1478                  message, connection->n_incoming);
1479  
1480   connection->message_borrowed = NULL;
1481   dbus_condvar_wake_all (connection->message_returned_cond);
1482   
1483   dbus_mutex_unlock (connection->mutex);
1484 }
1485
1486
1487 /* See dbus_connection_pop_message, but requires the caller to own
1488  * the lock before calling. May drop the lock while running.
1489  */
1490 static DBusMessage*
1491 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
1492 {
1493   if (connection->message_borrowed != NULL)
1494     _dbus_connection_wait_for_borrowed (connection);
1495   
1496   if (connection->n_incoming > 0)
1497     {
1498       DBusMessage *message;
1499
1500       message = _dbus_list_pop_first (&connection->incoming_messages);
1501       connection->n_incoming -= 1;
1502
1503       _dbus_verbose ("Incoming message %p removed from queue, %d incoming\n",
1504                      message, connection->n_incoming);
1505
1506       return message;
1507     }
1508   else
1509     return NULL;
1510 }
1511
1512
1513 /**
1514  * Returns the first-received message from the incoming message queue,
1515  * removing it from the queue. The caller owns a reference to the
1516  * returned message. If the queue is empty, returns #NULL.
1517  *
1518  * @param connection the connection.
1519  * @returns next message in the incoming queue.
1520  */
1521 DBusMessage*
1522 dbus_connection_pop_message (DBusConnection *connection)
1523 {
1524   DBusMessage *message;
1525   dbus_mutex_lock (connection->mutex);
1526
1527   message = _dbus_connection_pop_message_unlocked (connection);
1528   
1529   dbus_mutex_unlock (connection->mutex);
1530   
1531   return message;
1532 }
1533
1534 /**
1535  * Acquire the dispatcher. This must be done before dispatching
1536  * messages in order to guarantee the right order of
1537  * message delivery. May sleep and drop the connection mutex
1538  * while waiting for the dispatcher.
1539  *
1540  * @param connection the connection.
1541  */
1542 static void
1543 _dbus_connection_acquire_dispatch (DBusConnection *connection)
1544 {
1545   if (connection->dispatch_acquired)
1546     dbus_condvar_wait (connection->dispatch_cond, connection->mutex);
1547   _dbus_assert (!connection->dispatch_acquired);
1548
1549   connection->dispatch_acquired = TRUE;
1550 }
1551
1552 /**
1553  * Release the dispatcher when you're done with it. Only call
1554  * after you've acquired the dispatcher. Wakes up at most one
1555  * thread currently waiting to acquire the dispatcher.
1556  *
1557  * @param connection the connection.
1558  */
1559 static void
1560 _dbus_connection_release_dispatch (DBusConnection *connection)
1561 {
1562   _dbus_assert (connection->dispatch_acquired);
1563
1564   connection->dispatch_acquired = FALSE;
1565   dbus_condvar_wake_one (connection->dispatch_cond);
1566 }
1567
1568 static void
1569 _dbus_connection_failed_pop (DBusConnection *connection,
1570                              DBusList *message_link)
1571 {
1572   _dbus_list_prepend_link (&connection->incoming_messages,
1573                            message_link);
1574   connection->n_incoming += 1;
1575 }
1576
1577 /**
1578  * Pops the first-received message from the current incoming message
1579  * queue, runs any handlers for it, then unrefs the message.
1580  *
1581  * @param connection the connection
1582  * @returns #TRUE if the queue is not empty after dispatch
1583  */
1584 dbus_bool_t
1585 dbus_connection_dispatch_message (DBusConnection *connection)
1586 {
1587   DBusMessageHandler *handler;
1588   DBusMessage *message;
1589   DBusList *link, *filter_list_copy, *message_link;
1590   DBusHandlerResult result;
1591   ReplyHandlerData *reply_handler_data;
1592   const char *name;
1593   dbus_int32_t reply_serial;
1594
1595   /* Preallocate link so we can put the message back on failure */
1596   message_link = _dbus_list_alloc_link (NULL);
1597   if (message_link == NULL)
1598     return FALSE;
1599   
1600   dbus_mutex_lock (connection->mutex);
1601
1602   /* We need to ref the connection since the callback could potentially
1603    * drop the last ref to it */
1604   _dbus_connection_ref_unlocked (connection);
1605
1606   _dbus_connection_acquire_dispatch (connection);
1607   
1608   /* This call may drop the lock during the execution (if waiting for
1609    * borrowed messages to be returned) but the order of message
1610    * dispatch if several threads call dispatch_message is still
1611    * protected by the lock, since only one will get the lock, and that
1612    * one will finish the message dispatching
1613    */
1614   message = _dbus_connection_pop_message_unlocked (connection);
1615   if (message == NULL)
1616     {
1617       _dbus_connection_release_dispatch (connection);
1618       dbus_mutex_unlock (connection->mutex);
1619       dbus_connection_unref (connection);
1620       return FALSE;
1621     }
1622   
1623   message_link->data = message;
1624   
1625   result = DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
1626
1627   reply_serial = _dbus_message_get_reply_serial (message);
1628   reply_handler_data = _dbus_hash_table_lookup_int (connection->pending_replies,
1629                                                     reply_serial);
1630   
1631   if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
1632     {
1633       _dbus_connection_release_dispatch (connection);
1634       dbus_mutex_unlock (connection->mutex);
1635       _dbus_connection_failed_pop (connection, message_link);
1636       dbus_connection_unref (connection);
1637       return FALSE;
1638     }
1639   
1640   _dbus_list_foreach (&filter_list_copy,
1641                       (DBusForeachFunction)dbus_message_handler_ref,
1642                       NULL);
1643
1644   /* We're still protected from dispatch_message reentrancy here
1645    * since we acquired the dispatcher
1646    */
1647   dbus_mutex_unlock (connection->mutex);
1648   
1649   link = _dbus_list_get_first_link (&filter_list_copy);
1650   while (link != NULL)
1651     {
1652       DBusMessageHandler *handler = link->data;
1653       DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
1654
1655       result = _dbus_message_handler_handle_message (handler, connection,
1656                                                      message);
1657
1658       if (result == DBUS_HANDLER_RESULT_REMOVE_MESSAGE)
1659         break;
1660
1661       link = next;
1662     }
1663
1664   _dbus_list_foreach (&filter_list_copy,
1665                       (DBusForeachFunction)dbus_message_handler_unref,
1666                       NULL);
1667   _dbus_list_clear (&filter_list_copy);
1668   
1669   dbus_mutex_lock (connection->mutex);
1670
1671   /* Did a reply we were waiting on get filtered? */
1672   if (reply_handler_data && result == DBUS_HANDLER_RESULT_REMOVE_MESSAGE)
1673     {
1674       /* Queue the timeout immediately! */
1675       if (reply_handler_data->timeout_link)
1676         {
1677           _dbus_connection_queue_synthesized_message_link (connection,
1678                                                            reply_handler_data->timeout_link);
1679           reply_handler_data->timeout_link = NULL;
1680         }
1681       else
1682         {
1683           /* We already queued the timeout? Then it was filtered! */
1684           _dbus_warn ("The timeout error with reply serial %d was filtered, so the reply handler will never be called.\n", reply_serial);
1685         }
1686     }
1687   
1688   if (result == DBUS_HANDLER_RESULT_REMOVE_MESSAGE)
1689     goto out;
1690
1691   if (reply_handler_data)
1692     {
1693       dbus_mutex_unlock (connection->mutex);
1694       result = _dbus_message_handler_handle_message (reply_handler_data->handler,
1695                                                      connection, message);
1696       reply_handler_data_free (reply_handler_data);
1697       dbus_mutex_lock (connection->mutex);
1698       goto out;
1699     }
1700   
1701   name = dbus_message_get_name (message);
1702   if (name != NULL)
1703     {
1704       handler = _dbus_hash_table_lookup_string (connection->handler_table,
1705                                                 name);
1706       if (handler != NULL)
1707         {
1708           /* We're still protected from dispatch_message reentrancy here
1709            * since we acquired the dispatcher */
1710           dbus_mutex_unlock (connection->mutex);
1711           result = _dbus_message_handler_handle_message (handler, connection,
1712                                                          message);
1713           dbus_mutex_lock (connection->mutex);
1714           if (result == DBUS_HANDLER_RESULT_REMOVE_MESSAGE)
1715             goto out;
1716         }
1717     }
1718
1719  out:
1720   _dbus_connection_release_dispatch (connection);
1721   dbus_mutex_unlock (connection->mutex);
1722   _dbus_list_free_link (message_link);
1723   dbus_connection_unref (connection);
1724   dbus_message_unref (message);
1725   
1726   return connection->n_incoming > 0;
1727 }
1728
1729 /**
1730  * Sets the watch functions for the connection. These functions are
1731  * responsible for making the application's main loop aware of file
1732  * descriptors that need to be monitored for events, using select() or
1733  * poll(). When using Qt, typically the DBusAddWatchFunction would
1734  * create a QSocketNotifier. When using GLib, the DBusAddWatchFunction
1735  * could call g_io_add_watch(), or could be used as part of a more
1736  * elaborate GSource.
1737  *
1738  * The DBusWatch can be queried for the file descriptor to watch using
1739  * dbus_watch_get_fd(), and for the events to watch for using
1740  * dbus_watch_get_flags(). The flags returned by
1741  * dbus_watch_get_flags() will only contain DBUS_WATCH_READABLE and
1742  * DBUS_WATCH_WRITABLE, never DBUS_WATCH_HANGUP or DBUS_WATCH_ERROR;
1743  * all watches implicitly include a watch for hangups, errors, and
1744  * other exceptional conditions.
1745  *
1746  * Once a file descriptor becomes readable or writable, or an exception
1747  * occurs, dbus_connection_handle_watch() should be called to
1748  * notify the connection of the file descriptor's condition.
1749  *
1750  * dbus_connection_handle_watch() cannot be called during the
1751  * DBusAddWatchFunction, as the connection will not be ready to handle
1752  * that watch yet.
1753  * 
1754  * It is not allowed to reference a DBusWatch after it has been passed
1755  * to remove_function.
1756  * 
1757  * @param connection the connection.
1758  * @param add_function function to begin monitoring a new descriptor.
1759  * @param remove_function function to stop monitoring a descriptor.
1760  * @param data data to pass to add_function and remove_function.
1761  * @param free_data_function function to be called to free the data.
1762  */
1763 void
1764 dbus_connection_set_watch_functions (DBusConnection              *connection,
1765                                      DBusAddWatchFunction         add_function,
1766                                      DBusRemoveWatchFunction      remove_function,
1767                                      void                        *data,
1768                                      DBusFreeFunction             free_data_function)
1769 {
1770   dbus_mutex_lock (connection->mutex);
1771   /* ref connection for slightly better reentrancy */
1772   _dbus_connection_ref_unlocked (connection);
1773   
1774   _dbus_watch_list_set_functions (connection->watches,
1775                                   add_function, remove_function,
1776                                   data, free_data_function);
1777   
1778   dbus_mutex_unlock (connection->mutex);
1779   /* drop our paranoid refcount */
1780   dbus_connection_unref (connection);
1781 }
1782
1783 /**
1784  * Sets the timeout functions for the connection. These functions are
1785  * responsible for making the application's main loop aware of timeouts.
1786  * When using Qt, typically the DBusAddTimeoutFunction would create a
1787  * QTimer. When using GLib, the DBusAddTimeoutFunction would call
1788  * g_timeout_add.
1789  *
1790  * The DBusTimeout can be queried for the timer interval using
1791  * dbus_timeout_get_interval.
1792  *
1793  * Once a timeout occurs, dbus_timeout_handle should be called to invoke
1794  * the timeout's callback.
1795  *
1796  * @param connection the connection.
1797  * @param add_function function to add a timeout.
1798  * @param remove_function function to remove a timeout.
1799  * @param data data to pass to add_function and remove_function.
1800  * @param free_data_function function to be called to free the data.
1801  */
1802 void
1803 dbus_connection_set_timeout_functions   (DBusConnection            *connection,
1804                                          DBusAddTimeoutFunction     add_function,
1805                                          DBusRemoveTimeoutFunction  remove_function,
1806                                          void                      *data,
1807                                          DBusFreeFunction           free_data_function)
1808 {
1809   dbus_mutex_lock (connection->mutex);
1810   /* ref connection for slightly better reentrancy */
1811   _dbus_connection_ref_unlocked (connection);
1812   
1813   _dbus_timeout_list_set_functions (connection->timeouts,
1814                                     add_function, remove_function,
1815                                     data, free_data_function);
1816   
1817   dbus_mutex_unlock (connection->mutex);
1818   /* drop our paranoid refcount */
1819   dbus_connection_unref (connection);  
1820 }
1821
1822 /**
1823  * Sets the mainloop wakeup function for the connection. Thi function is
1824  * responsible for waking up the main loop (if its sleeping) when some some
1825  * change has happened to the connection that the mainloop needs to reconsiders
1826  * (e.g. a message has been queued for writing).
1827  * When using Qt, this typically results in a call to QEventLoop::wakeUp().
1828  * When using GLib, it would call g_main_context_wakeup().
1829  *
1830  *
1831  * @param connection the connection.
1832  * @param wakeup_main_function function to wake up the mainloop
1833  * @param data data to pass wakeup_main_function
1834  * @param free_data_function function to be called to free the data.
1835  */
1836 void
1837 dbus_connection_set_wakeup_main_function (DBusConnection            *connection,
1838                                           DBusWakeupMainFunction     wakeup_main_function,
1839                                           void                      *data,
1840                                           DBusFreeFunction           free_data_function)
1841 {
1842   void *old_data;
1843   DBusFreeFunction old_free_data;
1844   
1845   dbus_mutex_lock (connection->mutex);
1846   old_data = connection->wakeup_main_data;
1847   old_free_data = connection->free_wakeup_main_data;
1848
1849   connection->wakeup_main_function = wakeup_main_function;
1850   connection->wakeup_main_data = data;
1851   connection->free_wakeup_main_data = free_data_function;
1852   
1853   dbus_mutex_unlock (connection->mutex);
1854
1855   /* Callback outside the lock */
1856   if (old_free_data)
1857     (*old_free_data) (old_data);
1858 }
1859
1860 /**
1861  * Called to notify the connection when a previously-added watch
1862  * is ready for reading or writing, or has an exception such
1863  * as a hangup.
1864  *
1865  * @param connection the connection.
1866  * @param watch the watch.
1867  * @param condition the current condition of the file descriptors being watched.
1868  */
1869 void
1870 dbus_connection_handle_watch (DBusConnection              *connection,
1871                               DBusWatch                   *watch,
1872                               unsigned int                 condition)
1873 {
1874   dbus_mutex_lock (connection->mutex);
1875   _dbus_connection_acquire_io_path (connection, -1);
1876   _dbus_transport_handle_watch (connection->transport,
1877                                 watch, condition);
1878   _dbus_connection_release_io_path (connection);
1879   dbus_mutex_unlock (connection->mutex);
1880 }
1881
1882 /**
1883  * Adds a message filter. Filters are handlers that are run on
1884  * all incoming messages, prior to the normal handlers
1885  * registered with dbus_connection_register_handler().
1886  * Filters are run in the order that they were added.
1887  * The same handler can be added as a filter more than once, in
1888  * which case it will be run more than once.
1889  * Filters added during a filter callback won't be run on the
1890  * message being processed.
1891  *
1892  * @param connection the connection
1893  * @param handler the handler
1894  * @returns #TRUE on success, #FALSE if not enough memory.
1895  */
1896 dbus_bool_t
1897 dbus_connection_add_filter (DBusConnection      *connection,
1898                             DBusMessageHandler  *handler)
1899 {
1900   dbus_mutex_lock (connection->mutex);
1901   if (!_dbus_message_handler_add_connection (handler, connection))
1902     {
1903       dbus_mutex_unlock (connection->mutex);
1904       return FALSE;
1905     }
1906
1907   if (!_dbus_list_append (&connection->filter_list,
1908                           handler))
1909     {
1910       _dbus_message_handler_remove_connection (handler, connection);
1911       dbus_mutex_unlock (connection->mutex);
1912       return FALSE;
1913     }
1914
1915   dbus_mutex_unlock (connection->mutex);
1916   return TRUE;
1917 }
1918
1919 /**
1920  * Removes a previously-added message filter. It is a programming
1921  * error to call this function for a handler that has not
1922  * been added as a filter. If the given handler was added
1923  * more than once, only one instance of it will be removed
1924  * (the most recently-added instance).
1925  *
1926  * @param connection the connection
1927  * @param handler the handler to remove
1928  *
1929  */
1930 void
1931 dbus_connection_remove_filter (DBusConnection      *connection,
1932                                DBusMessageHandler  *handler)
1933 {
1934   dbus_mutex_lock (connection->mutex);
1935   if (!_dbus_list_remove_last (&connection->filter_list, handler))
1936     {
1937       _dbus_warn ("Tried to remove a DBusConnection filter that had not been added\n");
1938       dbus_mutex_unlock (connection->mutex);
1939       return;
1940     }
1941
1942   _dbus_message_handler_remove_connection (handler, connection);
1943
1944   dbus_mutex_unlock (connection->mutex);
1945 }
1946
1947 /**
1948  * Registers a handler for a list of message names. A single handler
1949  * can be registered for any number of message names, but each message
1950  * name can only have one handler at a time. It's not allowed to call
1951  * this function with the name of a message that already has a
1952  * handler. If the function returns #FALSE, the handlers were not
1953  * registered due to lack of memory.
1954  *
1955  * @todo the messages_to_handle arg may be more convenient if it's a
1956  * single string instead of an array. Though right now MessageHandler
1957  * is sort of designed to say be associated with an entire object with
1958  * multiple methods, that's why for example the connection only
1959  * weakrefs it.  So maybe the "manual" API should be different.
1960  * 
1961  * @param connection the connection
1962  * @param handler the handler
1963  * @param messages_to_handle the messages to handle
1964  * @param n_messages the number of message names in messages_to_handle
1965  * @returns #TRUE on success, #FALSE if no memory or another handler already exists
1966  * 
1967  **/
1968 dbus_bool_t
1969 dbus_connection_register_handler (DBusConnection     *connection,
1970                                   DBusMessageHandler *handler,
1971                                   const char        **messages_to_handle,
1972                                   int                 n_messages)
1973 {
1974   int i;
1975
1976   dbus_mutex_lock (connection->mutex);
1977   i = 0;
1978   while (i < n_messages)
1979     {
1980       DBusHashIter iter;
1981       char *key;
1982
1983       key = _dbus_strdup (messages_to_handle[i]);
1984       if (key == NULL)
1985         goto failed;
1986       
1987       if (!_dbus_hash_iter_lookup (connection->handler_table,
1988                                    key, TRUE,
1989                                    &iter))
1990         {
1991           dbus_free (key);
1992           goto failed;
1993         }
1994
1995       if (_dbus_hash_iter_get_value (&iter) != NULL)
1996         {
1997           _dbus_warn ("Bug in application: attempted to register a second handler for %s\n",
1998                       messages_to_handle[i]);
1999           dbus_free (key); /* won't have replaced the old key with the new one */
2000           goto failed;
2001         }
2002
2003       if (!_dbus_message_handler_add_connection (handler, connection))
2004         {
2005           _dbus_hash_iter_remove_entry (&iter);
2006           /* key has freed on nuking the entry */
2007           goto failed;
2008         }
2009       
2010       _dbus_hash_iter_set_value (&iter, handler);
2011
2012       ++i;
2013     }
2014   
2015   dbus_mutex_unlock (connection->mutex);
2016   return TRUE;
2017   
2018  failed:
2019   /* unregister everything registered so far,
2020    * so we don't fail partially
2021    */
2022   dbus_connection_unregister_handler (connection,
2023                                       handler,
2024                                       messages_to_handle,
2025                                       i);
2026
2027   dbus_mutex_unlock (connection->mutex);
2028   return FALSE;
2029 }
2030
2031 /**
2032  * Unregisters a handler for a list of message names. The handlers
2033  * must have been previously registered.
2034  *
2035  * @param connection the connection
2036  * @param handler the handler
2037  * @param messages_to_handle the messages to handle
2038  * @param n_messages the number of message names in messages_to_handle
2039  * 
2040  **/
2041 void
2042 dbus_connection_unregister_handler (DBusConnection     *connection,
2043                                     DBusMessageHandler *handler,
2044                                     const char        **messages_to_handle,
2045                                     int                 n_messages)
2046 {
2047   int i;
2048
2049   dbus_mutex_lock (connection->mutex);
2050   i = 0;
2051   while (i < n_messages)
2052     {
2053       DBusHashIter iter;
2054
2055       if (!_dbus_hash_iter_lookup (connection->handler_table,
2056                                    (char*) messages_to_handle[i], FALSE,
2057                                    &iter))
2058         {
2059           _dbus_warn ("Bug in application: attempted to unregister handler for %s which was not registered\n",
2060                       messages_to_handle[i]);
2061         }
2062       else if (_dbus_hash_iter_get_value (&iter) != handler)
2063         {
2064           _dbus_warn ("Bug in application: attempted to unregister handler for %s which was registered by a different handler\n",
2065                       messages_to_handle[i]);
2066         }
2067       else
2068         {
2069           _dbus_hash_iter_remove_entry (&iter);
2070           _dbus_message_handler_remove_connection (handler, connection);
2071         }
2072
2073       ++i;
2074     }
2075
2076   dbus_mutex_unlock (connection->mutex);
2077 }
2078
2079 static DBusDataSlotAllocator slot_allocator;
2080
2081 /**
2082  * Initialize the mutex used for #DBusConnection data
2083  * slot reservations.
2084  *
2085  * @returns the mutex
2086  */
2087 DBusMutex *
2088 _dbus_connection_slots_init_lock (void)
2089 {
2090   if (!_dbus_data_slot_allocator_init (&slot_allocator))
2091     return NULL;
2092   else
2093     return slot_allocator.lock;
2094 }
2095
2096 /**
2097  * Allocates an integer ID to be used for storing application-specific
2098  * data on any DBusConnection. The allocated ID may then be used
2099  * with dbus_connection_set_data() and dbus_connection_get_data().
2100  * If allocation fails, -1 is returned. Again, the allocated
2101  * slot is global, i.e. all DBusConnection objects will
2102  * have a slot with the given integer ID reserved.
2103  *
2104  * @returns -1 on failure, otherwise the data slot ID
2105  */
2106 int
2107 dbus_connection_allocate_data_slot (void)
2108 {
2109   return _dbus_data_slot_allocator_alloc (&slot_allocator);
2110 }
2111
2112 /**
2113  * Deallocates a global ID for connection data slots.
2114  * dbus_connection_get_data() and dbus_connection_set_data()
2115  * may no longer be used with this slot.
2116  * Existing data stored on existing DBusConnection objects
2117  * will be freed when the connection is finalized,
2118  * but may not be retrieved (and may only be replaced
2119  * if someone else reallocates the slot).
2120  *
2121  * @param slot the slot to deallocate
2122  */
2123 void
2124 dbus_connection_free_data_slot (int slot)
2125 {
2126   _dbus_data_slot_allocator_free (&slot_allocator, slot);
2127 }
2128
2129 /**
2130  * Stores a pointer on a DBusConnection, along
2131  * with an optional function to be used for freeing
2132  * the data when the data is set again, or when
2133  * the connection is finalized. The slot number
2134  * must have been allocated with dbus_connection_allocate_data_slot().
2135  *
2136  * @param connection the connection
2137  * @param slot the slot number
2138  * @param data the data to store
2139  * @param free_data_func finalizer function for the data
2140  * @returns #TRUE if there was enough memory to store the data
2141  */
2142 dbus_bool_t
2143 dbus_connection_set_data (DBusConnection   *connection,
2144                           int               slot,
2145                           void             *data,
2146                           DBusFreeFunction  free_data_func)
2147 {
2148   DBusFreeFunction old_free_func;
2149   void *old_data;
2150   dbus_bool_t retval;
2151   
2152   dbus_mutex_lock (connection->mutex);
2153
2154   retval = _dbus_data_slot_list_set (&slot_allocator,
2155                                      &connection->slot_list,
2156                                      slot, data, free_data_func,
2157                                      &old_free_func, &old_data);
2158   
2159   dbus_mutex_unlock (connection->mutex);
2160
2161   if (retval)
2162     {
2163       /* Do the actual free outside the connection lock */
2164       if (old_free_func)
2165         (* old_free_func) (old_data);
2166     }
2167
2168   return retval;
2169 }
2170
2171 /**
2172  * Retrieves data previously set with dbus_connection_set_data().
2173  * The slot must still be allocated (must not have been freed).
2174  *
2175  * @param connection the connection
2176  * @param slot the slot to get data from
2177  * @returns the data, or #NULL if not found
2178  */
2179 void*
2180 dbus_connection_get_data (DBusConnection   *connection,
2181                           int               slot)
2182 {
2183   void *res;
2184   
2185   dbus_mutex_lock (connection->mutex);
2186
2187   res = _dbus_data_slot_list_get (&slot_allocator,
2188                                   &connection->slot_list,
2189                                   slot);
2190   
2191   dbus_mutex_unlock (connection->mutex);
2192
2193   return res;
2194 }
2195
2196 /**
2197  * This function sets a global flag for whether dbus_connection_new()
2198  * will set SIGPIPE behavior to SIG_IGN.
2199  *
2200  * @param will_modify_sigpipe #TRUE to allow sigpipe to be set to SIG_IGN
2201  */
2202 void
2203 dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
2204 {
2205   _dbus_modify_sigpipe = will_modify_sigpipe;
2206 }
2207
2208 /**
2209  * Specifies the maximum size message this connection is allowed to
2210  * receive. Larger messages will result in disconnecting the
2211  * connection.
2212  * 
2213  * @param connection a #DBusConnection
2214  * @param size maximum message size the connection can receive, in bytes
2215  */
2216 void
2217 dbus_connection_set_max_message_size (DBusConnection *connection,
2218                                       long            size)
2219 {
2220   dbus_mutex_lock (connection->mutex);
2221   _dbus_transport_set_max_message_size (connection->transport,
2222                                         size);
2223   dbus_mutex_unlock (connection->mutex);
2224 }
2225
2226 /**
2227  * Gets the value set by dbus_connection_set_max_message_size().
2228  *
2229  * @param connection the connection
2230  * @returns the max size of a single message
2231  */
2232 long
2233 dbus_connection_get_max_message_size (DBusConnection *connection)
2234 {
2235   long res;
2236   dbus_mutex_lock (connection->mutex);
2237   res = _dbus_transport_get_max_message_size (connection->transport);
2238   dbus_mutex_unlock (connection->mutex);
2239   return res;
2240 }
2241
2242 /**
2243  * Sets the maximum total number of bytes that can be used for all messages
2244  * received on this connection. Messages count toward the maximum until
2245  * they are finalized. When the maximum is reached, the connection will
2246  * not read more data until some messages are finalized.
2247  *
2248  * The semantics of the maximum are: if outstanding messages are
2249  * already above the maximum, additional messages will not be read.
2250  * The semantics are not: if the next message would cause us to exceed
2251  * the maximum, we don't read it. The reason is that we don't know the
2252  * size of a message until after we read it.
2253  *
2254  * Thus, the max live messages size can actually be exceeded
2255  * by up to the maximum size of a single message.
2256  * 
2257  * Also, if we read say 1024 bytes off the wire in a single read(),
2258  * and that contains a half-dozen small messages, we may exceed the
2259  * size max by that amount. But this should be inconsequential.
2260  *
2261  * @param connection the connection
2262  * @param size the maximum size in bytes of all outstanding messages
2263  */
2264 void
2265 dbus_connection_set_max_live_messages_size (DBusConnection *connection,
2266                                             long            size)
2267 {
2268   dbus_mutex_lock (connection->mutex);
2269   _dbus_transport_set_max_live_messages_size (connection->transport,
2270                                               size);
2271   dbus_mutex_unlock (connection->mutex);
2272 }
2273
2274 /**
2275  * Gets the value set by dbus_connection_set_max_live_messages_size().
2276  *
2277  * @param connection the connection
2278  * @returns the max size of all live messages
2279  */
2280 long
2281 dbus_connection_get_max_live_messages_size (DBusConnection *connection)
2282 {
2283   long res;
2284   dbus_mutex_lock (connection->mutex);
2285   res = _dbus_transport_get_max_live_messages_size (connection->transport);
2286   dbus_mutex_unlock (connection->mutex);
2287   return res;
2288 }
2289
2290 /** @} */