e5fa48f07856fbc8b114665f92b2a6561faffa7d
[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  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  */
63 struct 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  */
93 dbus_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  */
118 dbus_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  */ 
131 DBusMessage*
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  */
144 void
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  */
174 dbus_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  */
193 void
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
202 static void
203 handle_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
216 static void
217 set_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  */
232 void
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  */
265 void
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  */
286 DBusConnection*
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  */
344 void
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  */
398 DBusConnection*
399 dbus_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  */
427 void
428 dbus_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  */
441 void
442 dbus_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  */
510 void
511 dbus_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  */
526 dbus_bool_t
527 dbus_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  */
547 dbus_bool_t
548 dbus_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  */
623 dbus_bool_t
624 dbus_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  */
639 void
640 dbus_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  */
655 int
656 dbus_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  */
669 DBusMessage*
670 dbus_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  */
683 DBusMessage*
684 dbus_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  */
713 dbus_bool_t
714 dbus_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  */
797 void
798 dbus_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  */
845 void
846 dbus_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  */
872 void
873 dbus_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  */
893 dbus_bool_t
894 dbus_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  */
923 void
924 dbus_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  **/
953 dbus_bool_t
954 dbus_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  **/
1025 void
1026 dbus_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 /** @} */