dbus-connection.c revision ff5283ab92c668453fd2f28c1715a1e0e9b949f5
1/* -*- mode: C; c-file-style: "gnu" -*- */
2/* dbus-connection.c DBusConnection object
3 *
4 * Copyright (C) 2002  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-transport.h"
27#include "dbus-watch.h"
28#include "dbus-connection-internal.h"
29#include "dbus-list.h"
30#include "dbus-hash.h"
31#include "dbus-message-internal.h"
32
33/**
34 * @defgroup DBusConnection DBusConnection
35 * @ingroup  DBus
36 * @brief Connection to another application
37 *
38 * A DBusConnection represents a connection to another
39 * application. Messages can be sent and received via this connection.
40 *
41 * The connection maintains a queue of incoming messages and a queue
42 * of outgoing messages. dbus_connection_pop_message() and friends
43 * can be used to read incoming messages from the queue.
44 * Outgoing messages are automatically discarded as they are
45 * written to the network.
46 *
47 * In brief a DBusConnection is a message queue associated with some
48 * message transport mechanism such as a socket.
49 *
50 */
51
52/**
53 * @defgroup DBusConnectionInternals DBusConnection implementation details
54 * @ingroup  DBusInternals
55 * @brief Implementation details of DBusConnection
56 *
57 * @{
58 */
59
60/**
61 * Implementation details of DBusConnection. All fields are private.
62 */
63struct DBusConnection
64{
65  int refcount; /**< Reference count. */
66
67  DBusList *outgoing_messages; /**< Queue of messages we need to send, send the end of the list first. */
68  DBusList *incoming_messages; /**< Queue of messages we have received, end of the list received most recently. */
69
70  int n_outgoing;              /**< Length of outgoing queue. */
71  int n_incoming;              /**< Length of incoming queue. */
72
73  DBusTransport *transport;    /**< Object that sends/receives messages over network. */
74  DBusWatchList *watches;      /**< Stores active watches. */
75
76  DBusConnectionErrorFunction error_function; /**< Callback for errors. */
77  void *error_data;                           /**< Data for error callback. */
78  DBusFreeFunction error_free_data_function;  /**< Free function for error callback data. */
79  DBusHashTable *handler_table; /**< Table of registered DBusMessageHandler */
80  DBusList *filter_list;        /**< List of filters. */
81  int filters_serial;           /**< Increments when the list of filters is changed. */
82  int handlers_serial;          /**< Increments when the handler table is changed. */
83};
84
85/**
86 * Adds a message to the incoming message queue, returning #FALSE
87 * if there's insufficient memory to queue the message.
88 *
89 * @param connection the connection.
90 * @param message the message to queue.
91 * @returns #TRUE on success.
92 */
93dbus_bool_t
94_dbus_connection_queue_received_message (DBusConnection *connection,
95                                         DBusMessage    *message)
96{
97  _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport));
98
99  if (!_dbus_list_append (&connection->incoming_messages,
100                          message))
101    return FALSE;
102
103  dbus_message_ref (message);
104  connection->n_incoming += 1;
105
106  _dbus_verbose ("Incoming message %p added to queue, %d incoming\n",
107                 message, connection->n_incoming);
108
109  return TRUE;
110}
111
112/**
113 * Checks whether there are messages in the outgoing message queue.
114 *
115 * @param connection the connection.
116 * @returns #TRUE if the outgoing queue is non-empty.
117 */
118dbus_bool_t
119_dbus_connection_have_messages_to_send (DBusConnection *connection)
120{
121  return connection->outgoing_messages != NULL;
122}
123
124/**
125 * Gets the next outgoing message. The message remanins in the
126 * queue, and the caller does not own a reference to it.
127 *
128 * @param connection the connection.
129 * @returns the message to be sent.
130 */
131DBusMessage*
132_dbus_connection_get_message_to_send (DBusConnection *connection)
133{
134  return _dbus_list_get_last (&connection->outgoing_messages);
135}
136
137/**
138 * Notifies the connection that a message has been sent, so the
139 * message can be removed from the outgoing queue.
140 *
141 * @param connection the connection.
142 * @param message the message that was sent.
143 */
144void
145_dbus_connection_message_sent (DBusConnection *connection,
146                               DBusMessage    *message)
147{
148  _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport));
149  _dbus_assert (message == _dbus_list_get_last (&connection->outgoing_messages));
150
151  _dbus_list_pop_last (&connection->outgoing_messages);
152  dbus_message_unref (message);
153
154  connection->n_outgoing -= 1;
155
156  _dbus_verbose ("Message %p removed from outgoing queue, %d left to send\n",
157                 message, connection->n_outgoing);
158
159  if (connection->n_outgoing == 0)
160    _dbus_transport_messages_pending (connection->transport,
161                                      connection->n_outgoing);
162}
163
164/**
165 * Adds a watch using the connection's DBusAddWatchFunction if
166 * available. Otherwise records the watch to be added when said
167 * function is available. Also re-adds the watch if the
168 * DBusAddWatchFunction changes. May fail due to lack of memory.
169 *
170 * @param connection the connection.
171 * @param watch the watch to add.
172 * @returns #TRUE on success.
173 */
174dbus_bool_t
175_dbus_connection_add_watch (DBusConnection *connection,
176                            DBusWatch      *watch)
177{
178  if (connection->watches) /* null during finalize */
179    return _dbus_watch_list_add_watch (connection->watches,
180                                       watch);
181  else
182    return FALSE;
183}
184
185/**
186 * Removes a watch using the connection's DBusRemoveWatchFunction
187 * if available. It's an error to call this function on a watch
188 * that was not previously added.
189 *
190 * @param connection the connection.
191 * @param watch the watch to remove.
192 */
193void
194_dbus_connection_remove_watch (DBusConnection *connection,
195                               DBusWatch      *watch)
196{
197  if (connection->watches) /* null during finalize */
198    _dbus_watch_list_remove_watch (connection->watches,
199                                   watch);
200}
201
202static void
203handle_error (DBusConnection *connection,
204              DBusResultCode  result)
205{
206  if (result != DBUS_RESULT_SUCCESS &&
207      connection->error_function != NULL)
208    {
209      dbus_connection_ref (connection);
210      (* connection->error_function) (connection, result,
211                                      connection->error_data);
212      dbus_connection_unref (connection);
213    }
214}
215
216static void
217set_result_handled (DBusConnection *connection,
218                    DBusResultCode *result_address,
219                    DBusResultCode  result)
220{
221  dbus_set_result (result_address, result);
222  handle_error (connection, result);
223}
224
225/**
226 * Reports a transport error to the connection. Typically
227 * results in an application error callback being invoked.
228 *
229 * @param connection the connection.
230 * @param result_code the error code.
231 */
232void
233_dbus_connection_transport_error (DBusConnection *connection,
234                                  DBusResultCode  result_code)
235{
236  handle_error (connection, result_code);
237}
238
239/**
240 * Queues incoming messages and sends outgoing messages for this
241 * connection, optionally blocking in the process. Each call to
242 * _dbus_connection_do_iteration() will call select() or poll() one
243 * time and then read or write data if possible.
244 *
245 * The purpose of this function is to be able to flush outgoing
246 * messages or queue up incoming messages without returning
247 * control to the application and causing reentrancy weirdness.
248 *
249 * The flags parameter allows you to specify whether to
250 * read incoming messages, write outgoing messages, or both,
251 * and whether to block if no immediate action is possible.
252 *
253 * The timeout_milliseconds parameter does nothing unless the
254 * iteration is blocking.
255 *
256 * If there are no outgoing messages and DBUS_ITERATION_DO_READING
257 * wasn't specified, then it's impossible to block, even if
258 * you specify DBUS_ITERATION_BLOCK; in that case the function
259 * returns immediately.
260 *
261 * @param connection the connection.
262 * @param flags iteration flags.
263 * @param timeout_milliseconds maximum blocking time, or -1 for no limit.
264 */
265void
266_dbus_connection_do_iteration (DBusConnection *connection,
267                               unsigned int    flags,
268                               int             timeout_milliseconds)
269{
270  if (connection->n_outgoing == 0)
271    flags &= ~DBUS_ITERATION_DO_WRITING;
272
273  _dbus_transport_do_iteration (connection->transport,
274                                flags, timeout_milliseconds);
275}
276
277/**
278 * Creates a new connection for the given transport.  A transport
279 * represents a message stream that uses some concrete mechanism, such
280 * as UNIX domain sockets. May return #NULL if insufficient
281 * memory exists to create the connection.
282 *
283 * @param transport the transport.
284 * @returns the new connection, or #NULL on failure.
285 */
286DBusConnection*
287_dbus_connection_new_for_transport (DBusTransport *transport)
288{
289  DBusConnection *connection;
290  DBusWatchList *watch_list;
291  DBusHashTable *handler_table;
292
293  watch_list = NULL;
294  connection = NULL;
295  handler_table = NULL;
296
297  watch_list = _dbus_watch_list_new ();
298  if (watch_list == NULL)
299    goto error;
300
301  handler_table =
302    _dbus_hash_table_new (DBUS_HASH_STRING,
303                          dbus_free, NULL);
304  if (handler_table == NULL)
305    goto error;
306
307  connection = dbus_new0 (DBusConnection, 1);
308  if (connection == NULL)
309    goto error;
310
311  connection->refcount = 1;
312  connection->transport = transport;
313  connection->watches = watch_list;
314  connection->handler_table = handler_table;
315  connection->filter_list = NULL;
316
317  _dbus_transport_ref (transport);
318  _dbus_transport_set_connection (transport, connection);
319
320  return connection;
321
322 error:
323
324  if (connection != NULL)
325    dbus_free (connection);
326
327  if (handler_table)
328    _dbus_hash_table_unref (handler_table);
329
330  if (watch_list)
331    _dbus_watch_list_free (watch_list);
332
333  return NULL;
334}
335
336/**
337 * Used to notify a connection when a DBusMessageHandler is
338 * destroyed, so the connection can drop any reference
339 * to the handler.
340 *
341 * @param connection the connection
342 * @param handler the handler
343 */
344void
345_dbus_connection_handler_destroyed (DBusConnection     *connection,
346                                    DBusMessageHandler *handler)
347{
348  DBusHashIter iter;
349  DBusList *link;
350
351  _dbus_hash_iter_init (connection->handler_table, &iter);
352  while (_dbus_hash_iter_next (&iter))
353    {
354      DBusMessageHandler *h = _dbus_hash_iter_get_value (&iter);
355
356      if (h == handler)
357        _dbus_hash_iter_remove_entry (&iter);
358    }
359
360  link = _dbus_list_get_first_link (&connection->filter_list);
361  while (link != NULL)
362    {
363      DBusMessageHandler *h = link->data;
364      DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
365
366      if (h == handler)
367        _dbus_list_remove_link (&connection->filter_list,
368                                link);
369
370      link = next;
371    }
372}
373
374/** @} */
375
376/**
377 * @addtogroup DBusConnection
378 *
379 * @{
380 */
381
382/**
383 * Opens a new connection to a remote address.
384 *
385 * @todo specify what the address parameter is. Right now
386 * it's just the name of a UNIX domain socket. It should be
387 * something more complex that encodes which transport to use.
388 *
389 * If the open fails, the function returns #NULL, and provides
390 * a reason for the failure in the result parameter. Pass
391 * #NULL for the result parameter if you aren't interested
392 * in the reason for failure.
393 *
394 * @param address the address.
395 * @param result address where a result code can be returned.
396 * @returns new connection, or #NULL on failure.
397 */
398DBusConnection*
399dbus_connection_open (const char     *address,
400                      DBusResultCode *result)
401{
402  DBusConnection *connection;
403  DBusTransport *transport;
404
405  transport = _dbus_transport_open (address, result);
406  if (transport == NULL)
407    return NULL;
408
409  connection = _dbus_connection_new_for_transport (transport);
410
411  _dbus_transport_unref (transport);
412
413  if (connection == NULL)
414    {
415      dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
416      return NULL;
417    }
418
419  return connection;
420}
421
422/**
423 * Increments the reference count of a DBusConnection.
424 *
425 * @param connection the connection.
426 */
427void
428dbus_connection_ref (DBusConnection *connection)
429{
430  connection->refcount += 1;
431}
432
433/**
434 * Decrements the reference count of a DBusConnection, and finalizes
435 * it if the count reaches zero.  If a connection is still connected
436 * when it's finalized, it will be disconnected (that is, associated
437 * file handles will be closed).
438 *
439 * @param connection the connection.
440 */
441void
442dbus_connection_unref (DBusConnection *connection)
443{
444  _dbus_assert (connection != NULL);
445  _dbus_assert (connection->refcount > 0);
446
447  connection->refcount -= 1;
448  if (connection->refcount == 0)
449    {
450      DBusHashIter iter;
451      DBusList *link;
452
453      /* free error data as a side effect */
454      dbus_connection_set_error_function (connection,
455                                          NULL, NULL, NULL);
456
457      _dbus_watch_list_free (connection->watches);
458      connection->watches = NULL;
459
460      _dbus_hash_iter_init (connection->handler_table, &iter);
461      while (_dbus_hash_iter_next (&iter))
462        {
463          DBusMessageHandler *h = _dbus_hash_iter_get_value (&iter);
464
465          _dbus_message_handler_remove_connection (h, connection);
466        }
467
468      link = _dbus_list_get_first_link (&connection->filter_list);
469      while (link != NULL)
470        {
471          DBusMessageHandler *h = link->data;
472          DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
473
474          _dbus_message_handler_remove_connection (h, connection);
475
476          link = next;
477        }
478
479      _dbus_hash_table_unref (connection->handler_table);
480      connection->handler_table = NULL;
481
482      _dbus_list_clear (&connection->filter_list);
483
484      _dbus_list_foreach (&connection->outgoing_messages,
485                          (DBusForeachFunction) dbus_message_unref,
486                          NULL);
487      _dbus_list_clear (&connection->outgoing_messages);
488
489      _dbus_list_foreach (&connection->incoming_messages,
490                          (DBusForeachFunction) dbus_message_unref,
491                          NULL);
492      _dbus_list_clear (&connection->incoming_messages);
493
494      _dbus_transport_unref (connection->transport);
495
496      dbus_free (connection);
497    }
498}
499
500/**
501 * Closes the connection, so no further data can be sent or received.
502 * Any further attempts to send data will result in errors.  This
503 * function does not affect the connection's reference count.  It's
504 * safe to disconnect a connection more than once; all calls after the
505 * first do nothing. It's impossible to "reconnect" a connection, a
506 * new connection must be created.
507 *
508 * @param connection the connection.
509 */
510void
511dbus_connection_disconnect (DBusConnection *connection)
512{
513  _dbus_transport_disconnect (connection->transport);
514}
515
516/**
517 * Gets whether the connection is currently connected.  All
518 * connections are connected when they are opened.  A connection may
519 * become disconnected when the remote application closes its end, or
520 * exits; a connection may also be disconnected with
521 * dbus_connection_disconnect().
522 *
523 * @param connection the connection.
524 * @returns #TRUE if the connection is still alive.
525 */
526dbus_bool_t
527dbus_connection_get_is_connected (DBusConnection *connection)
528{
529  return _dbus_transport_get_is_connected (connection->transport);
530}
531
532/**
533 * Adds a message to the outgoing message queue. Does not block to
534 * write the message to the network; that happens asynchronously. to
535 * force the message to be written, call dbus_connection_flush().
536 *
537 * If the function fails, it returns #FALSE and returns the
538 * reason for failure via the result parameter.
539 * The result parameter can be #NULL if you aren't interested
540 * in the reason for the failure.
541 *
542 * @param connection the connection.
543 * @param message the message to write.
544 * @param result address where result code can be placed.
545 * @returns #TRUE on success.
546 */
547dbus_bool_t
548dbus_connection_send_message (DBusConnection *connection,
549                              DBusMessage    *message,
550                              DBusResultCode *result)
551{
552  if (!_dbus_list_prepend (&connection->outgoing_messages,
553                           message))
554    {
555      set_result_handled (connection, result, DBUS_RESULT_NO_MEMORY);
556      return FALSE;
557    }
558
559  dbus_message_ref (message);
560  connection->n_outgoing += 1;
561
562  _dbus_verbose ("Message %p added to outgoing queue, %d pending to send\n",
563                 message, connection->n_outgoing);
564
565  _dbus_message_lock (message);
566
567  if (connection->n_outgoing == 1)
568    _dbus_transport_messages_pending (connection->transport,
569                                      connection->n_outgoing);
570
571  return TRUE;
572}
573
574/**
575 * Queues a message to send, as with dbus_connection_send_message(),
576 * but also sets up a DBusMessageHandler to receive a reply to the
577 * message. If no reply is received in the given timeout_milliseconds,
578 * expires the pending reply and sends the DBusMessageHandler a
579 * synthetic error reply (generated in-process, not by the remote
580 * application) indicating that a timeout occurred.
581 *
582 * Reply handlers see their replies after message filters see them,
583 * but before message handlers added with
584 * dbus_connection_register_handler() see them, regardless of the
585 * reply message's name. Reply handlers are only handed a single
586 * message as a reply, after a reply has been seen the handler is
587 * removed. If a filter filters out the reply before the handler sees
588 * it, the handler is not removed but the timeout will immediately
589 * fire again. If a filter was dumb and kept removing the timeout
590 * reply then we'd get in an infinite loop.
591 *
592 * If #NULL is passed for the reply_handler, the timeout reply will
593 * still be generated and placed into the message queue, but no
594 * specific message handler will receive the reply.
595 *
596 * If -1 is passed for the timeout, a sane default timeout is used. -1
597 * is typically the best value for the timeout for this reason, unless
598 * you want a very short or very long timeout.  There is no way to
599 * avoid a timeout entirely, other than passing INT_MAX for the
600 * timeout to postpone it indefinitely.
601 *
602 * @param connection the connection
603 * @param message the message to send
604 * @param reply_handler message handler expecting the reply, or #NULL
605 * @param timeout_milliseconds timeout in milliseconds or -1 for default
606 * @param result return location for result code
607 * @returns #TRUE if the message is successfully queued, #FALSE if no memory.
608 *
609 * @todo this function isn't implemented because we need message serials
610 * and other slightly more rich DBusMessage implementation in order to
611 * implement it. The basic idea will be to keep a hash of serials we're
612 * expecting a reply to, and also to add a way to tell GLib or Qt to
613 * install a timeout. Then install a timeout which is the shortest
614 * timeout of any pending reply.
615 *
616 * @todo implement non-reentrant "block for reply" variant.  i.e. send
617 * a message, block until we get a reply, then pull reply out of
618 * message queue and return it, *without dispatching any handlers for
619 * any other messages* - used for non-reentrant "method calls" We can
620 * block properly for this using _dbus_connection_do_iteration().
621 *
622 */
623dbus_bool_t
624dbus_connection_send_message_with_reply (DBusConnection     *connection,
625                                         DBusMessage        *message,
626                                         DBusMessageHandler *reply_handler,
627                                         int                 timeout_milliseconds,
628                                         DBusResultCode     *result)
629{
630  /* FIXME */
631  return dbus_connection_send_message (connection, message, result);
632}
633
634/**
635 * Blocks until the outgoing message queue is empty.
636 *
637 * @param connection the connection.
638 */
639void
640dbus_connection_flush (DBusConnection *connection)
641{
642  while (connection->n_outgoing > 0)
643    _dbus_connection_do_iteration (connection,
644                                   DBUS_ITERATION_DO_WRITING |
645                                   DBUS_ITERATION_BLOCK,
646                                   -1);
647}
648
649/**
650 * Gets the number of messages in the incoming message queue.
651 *
652 * @param connection the connection.
653 * @returns the number of messages in the queue.
654 */
655int
656dbus_connection_get_n_messages (DBusConnection *connection)
657{
658  return connection->n_incoming;
659}
660
661/**
662 * Returns the first-received message from the incoming message queue,
663 * leaving it in the queue. The caller does not own a reference to the
664 * returned message. If the queue is empty, returns #NULL.
665 *
666 * @param connection the connection.
667 * @returns next message in the incoming queue.
668 */
669DBusMessage*
670dbus_connection_peek_message  (DBusConnection *connection)
671{
672  return _dbus_list_get_first (&connection->incoming_messages);
673}
674
675/**
676 * Returns the first-received message from the incoming message queue,
677 * removing it from the queue. The caller owns a reference to the
678 * returned message. If the queue is empty, returns #NULL.
679 *
680 * @param connection the connection.
681 * @returns next message in the incoming queue.
682 */
683DBusMessage*
684dbus_connection_pop_message (DBusConnection *connection)
685{
686  if (connection->n_incoming > 0)
687    {
688      DBusMessage *message;
689
690      message = _dbus_list_pop_first (&connection->incoming_messages);
691      connection->n_incoming -= 1;
692
693      _dbus_verbose ("Incoming message %p removed from queue, %d incoming\n",
694                     message, connection->n_incoming);
695
696      return message;
697    }
698  else
699    return NULL;
700}
701
702/**
703 * Pops the first-received message from the current incoming message
704 * queue, runs any handlers for it, then unrefs the message.
705 *
706 * @param connection the connection
707 * @returns #TRUE if the queue is not empty after dispatch
708 *
709 * @todo this function is not properly robust against reentrancy,
710 * that is, if handlers are added/removed while dispatching
711 * a message, things will get messed up.
712 */
713dbus_bool_t
714dbus_connection_dispatch_message (DBusConnection *connection)
715{
716  DBusMessage *message;
717  int filter_serial;
718  int handler_serial;
719  DBusList *link;
720  DBusHandlerResult result;
721  const char *name;
722
723  dbus_connection_ref (connection);
724
725  message = dbus_connection_pop_message (connection);
726  if (message == NULL)
727    {
728      dbus_connection_unref (connection);
729      return FALSE;
730    }
731
732  filter_serial = connection->filters_serial;
733  handler_serial = connection->handlers_serial;
734
735  result = DBUS_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
736
737  link = _dbus_list_get_first_link (&connection->filter_list);
738  while (link != NULL)
739    {
740      DBusMessageHandler *handler = link->data;
741      DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
742
743      result = _dbus_message_handler_handle_message (handler, connection,
744                                                     message);
745
746      if (result == DBUS_HANDLER_RESULT_REMOVE_MESSAGE)
747        goto out;
748
749      if (filter_serial != connection->filters_serial)
750        {
751          _dbus_warn ("Message filters added or removed while dispatching filters - not currently supported!\n");
752          goto out;
753        }
754
755      link = next;
756    }
757
758  name = dbus_message_get_name (message);
759  if (name != NULL)
760    {
761      DBusMessageHandler *handler;
762
763      handler = _dbus_hash_table_lookup_string (connection->handler_table,
764                                                name);
765      if (handler != NULL)
766        {
767
768          result = _dbus_message_handler_handle_message (handler, connection,
769                                                         message);
770
771          if (result == DBUS_HANDLER_RESULT_REMOVE_MESSAGE)
772            goto out;
773
774          if (handler_serial != connection->handlers_serial)
775            {
776              _dbus_warn ("Message handlers added or removed while dispatching handlers - not currently supported!\n");
777              goto out;
778            }
779        }
780    }
781
782 out:
783  dbus_connection_unref (connection);
784  dbus_message_unref (message);
785
786  return connection->n_incoming > 0;
787}
788
789/**
790 * Sets the error handler function for the connection.
791 *
792 * @param connection the connection.
793 * @param error_function the error handler.
794 * @param data data to pass to the error handler.
795 * @param free_data_function function to be called to free the data.
796 */
797void
798dbus_connection_set_error_function  (DBusConnection              *connection,
799                                     DBusConnectionErrorFunction  error_function,
800                                     void                        *data,
801                                     DBusFreeFunction             free_data_function)
802{
803  if (connection->error_free_data_function != NULL)
804    (* connection->error_free_data_function) (connection->error_data);
805
806  connection->error_function = error_function;
807  connection->error_data = data;
808  connection->error_free_data_function = free_data_function;
809}
810
811/**
812 * Sets the watch functions for the connection. These functions are
813 * responsible for making the application's main loop aware of file
814 * descriptors that need to be monitored for events, using select() or
815 * poll(). When using Qt, typically the DBusAddWatchFunction would
816 * create a QSocketNotifier. When using GLib, the DBusAddWatchFunction
817 * could call g_io_add_watch(), or could be used as part of a more
818 * elaborate GSource.
819 *
820 * The DBusWatch can be queried for the file descriptor to watch using
821 * dbus_watch_get_fd(), and for the events to watch for using
822 * dbus_watch_get_flags(). The flags returned by
823 * dbus_watch_get_flags() will only contain DBUS_WATCH_READABLE and
824 * DBUS_WATCH_WRITABLE, never DBUS_WATCH_HANGUP or DBUS_WATCH_ERROR;
825 * all watches implicitly include a watch for hangups, errors, and
826 * other exceptional conditions.
827 *
828 * Once a file descriptor becomes readable or writable, or an exception
829 * occurs, dbus_connection_handle_watch() should be called to
830 * notify the connection of the file descriptor's condition.
831 *
832 * dbus_connection_handle_watch() cannot be called during the
833 * DBusAddWatchFunction, as the connection will not be ready to handle
834 * that watch yet.
835 *
836 * It is not allowed to reference a DBusWatch after it has been passed
837 * to remove_function.
838 *
839 * @param connection the connection.
840 * @param add_function function to begin monitoring a new descriptor.
841 * @param remove_function function to stop monitoring a descriptor.
842 * @param data data to pass to add_function and remove_function.
843 * @param free_data_function function to be called to free the data.
844 */
845void
846dbus_connection_set_watch_functions (DBusConnection              *connection,
847                                     DBusAddWatchFunction         add_function,
848                                     DBusRemoveWatchFunction      remove_function,
849                                     void                        *data,
850                                     DBusFreeFunction             free_data_function)
851{
852  /* ref connection for slightly better reentrancy */
853  dbus_connection_ref (connection);
854
855  _dbus_watch_list_set_functions (connection->watches,
856                                  add_function, remove_function,
857                                  data, free_data_function);
858
859  /* drop our paranoid refcount */
860  dbus_connection_unref (connection);
861}
862
863/**
864 * Called to notify the connection when a previously-added watch
865 * is ready for reading or writing, or has an exception such
866 * as a hangup.
867 *
868 * @param connection the connection.
869 * @param watch the watch.
870 * @param condition the current condition of the file descriptors being watched.
871 */
872void
873dbus_connection_handle_watch (DBusConnection              *connection,
874                              DBusWatch                   *watch,
875                              unsigned int                 condition)
876{
877  _dbus_transport_handle_watch (connection->transport,
878                                watch, condition);
879}
880
881/**
882 * Adds a message filter. Filters are handlers that are run on
883 * all incoming messages, prior to the normal handlers
884 * registered with dbus_connection_register_handler().
885 * Filters are run in the order that they were added.
886 * The same handler can be added as a filter more than once, in
887 * which case it will be run more than once.
888 *
889 * @param connection the connection
890 * @param handler the handler
891 * @returns #TRUE on success, #FALSE if not enough memory.
892 */
893dbus_bool_t
894dbus_connection_add_filter (DBusConnection      *connection,
895                            DBusMessageHandler  *handler)
896{
897  if (!_dbus_message_handler_add_connection (handler, connection))
898    return FALSE;
899
900  if (!_dbus_list_append (&connection->filter_list,
901                          handler))
902    {
903      _dbus_message_handler_remove_connection (handler, connection);
904      return FALSE;
905    }
906
907  connection->filters_serial += 1;
908
909  return TRUE;
910}
911
912/**
913 * Removes a previously-added message filter. It is a programming
914 * error to call this function for a handler that has not
915 * been added as a filter. If the given handler was added
916 * more than once, only one instance of it will be removed
917 * (the most recently-added instance).
918 *
919 * @param connection the connection
920 * @param handler the handler to remove
921 *
922 */
923void
924dbus_connection_remove_filter (DBusConnection      *connection,
925                               DBusMessageHandler  *handler)
926{
927  if (!_dbus_list_remove_last (&connection->filter_list, handler))
928    {
929      _dbus_warn ("Tried to remove a DBusConnection filter that had not been added\n");
930      return;
931    }
932
933  _dbus_message_handler_remove_connection (handler, connection);
934
935  connection->filters_serial += 1;
936}
937
938/**
939 * Registers a handler for a list of message names. A single handler
940 * can be registered for any number of message names, but each message
941 * name can only have one handler at a time. It's not allowed to call
942 * this function with the name of a message that already has a
943 * handler. If the function returns #FALSE, the handlers were not
944 * registered due to lack of memory.
945 *
946 * @param connection the connection
947 * @param handler the handler
948 * @param messages_to_handle the messages to handle
949 * @param n_messages the number of message names in messages_to_handle
950 * @returns #TRUE on success, #FALSE if no memory or another handler already exists
951 *
952 **/
953dbus_bool_t
954dbus_connection_register_handler (DBusConnection     *connection,
955                                  DBusMessageHandler *handler,
956                                  const char        **messages_to_handle,
957                                  int                 n_messages)
958{
959  int i;
960
961  i = 0;
962  while (i < n_messages)
963    {
964      DBusHashIter iter;
965      char *key;
966
967      key = _dbus_strdup (messages_to_handle[i]);
968      if (key == NULL)
969        goto failed;
970
971      if (!_dbus_hash_iter_lookup (connection->handler_table,
972                                   key, TRUE,
973                                   &iter))
974        {
975          dbus_free (key);
976          goto failed;
977        }
978
979      if (_dbus_hash_iter_get_value (&iter) != NULL)
980        {
981          _dbus_warn ("Bug in application: attempted to register a second handler for %s\n",
982                      messages_to_handle[i]);
983          dbus_free (key); /* won't have replaced the old key with the new one */
984          goto failed;
985        }
986
987      if (!_dbus_message_handler_add_connection (handler, connection))
988        {
989          _dbus_hash_iter_remove_entry (&iter);
990          /* key has freed on nuking the entry */
991          goto failed;
992        }
993
994      _dbus_hash_iter_set_value (&iter, handler);
995
996      connection->handlers_serial += 1;
997
998      ++i;
999    }
1000
1001  return TRUE;
1002
1003 failed:
1004  /* unregister everything registered so far,
1005   * so we don't fail partially
1006   */
1007  dbus_connection_unregister_handler (connection,
1008                                      handler,
1009                                      messages_to_handle,
1010                                      i);
1011
1012  return FALSE;
1013}
1014
1015/**
1016 * Unregisters a handler for a list of message names. The handlers
1017 * must have been previously registered.
1018 *
1019 * @param connection the connection
1020 * @param handler the handler
1021 * @param messages_to_handle the messages to handle
1022 * @param n_messages the number of message names in messages_to_handle
1023 *
1024 **/
1025void
1026dbus_connection_unregister_handler (DBusConnection     *connection,
1027                                    DBusMessageHandler *handler,
1028                                    const char        **messages_to_handle,
1029                                    int                 n_messages)
1030{
1031  int i;
1032
1033  i = 0;
1034  while (i < n_messages)
1035    {
1036      DBusHashIter iter;
1037
1038      if (!_dbus_hash_iter_lookup (connection->handler_table,
1039                                   (char*) messages_to_handle[i], FALSE,
1040                                   &iter))
1041        {
1042          _dbus_warn ("Bug in application: attempted to unregister handler for %s which was not registered\n",
1043                      messages_to_handle[i]);
1044        }
1045      else if (_dbus_hash_iter_get_value (&iter) != handler)
1046        {
1047          _dbus_warn ("Bug in application: attempted to unregister handler for %s which was registered by a different handler\n",
1048                      messages_to_handle[i]);
1049        }
1050      else
1051        {
1052          _dbus_hash_iter_remove_entry (&iter);
1053          _dbus_message_handler_remove_connection (handler, connection);
1054        }
1055
1056      ++i;
1057    }
1058
1059  connection->handlers_serial += 1;
1060}
1061
1062/** @} */
1063