2002-12-11 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  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-message-internal.h"
31
32 /**
33  * @defgroup DBusConnection DBusConnection
34  * @ingroup  DBus
35  * @brief Connection to another application
36  *
37  * A DBusConnection represents a connection to another
38  * application. Messages can be sent and received via this connection.
39  *
40  * The connection maintains a queue of incoming messages and a queue
41  * of outgoing messages. dbus_connection_pop_message() and friends
42  * can be used to read incoming messages from the queue.
43  * Outgoing messages are automatically discarded as they are
44  * written to the network.
45  *
46  * In brief a DBusConnection is a message queue associated with some
47  * message transport mechanism such as a socket.
48  * 
49  */
50
51 /**
52  * @defgroup DBusConnectionInternals DBusConnection implementation details
53  * @ingroup  DBusInternals
54  * @brief Implementation details of DBusConnection
55  *
56  * @{
57  */
58
59 /**
60  * Implementation details of DBusConnection. All fields are private.
61  */
62 struct DBusConnection
63 {
64   int refcount; /**< Reference count. */
65
66   DBusList *outgoing_messages; /**< Queue of messages we need to send, send the end of the list first. */
67   DBusList *incoming_messages; /**< Queue of messages we have received, end of the list received most recently. */
68
69   int n_outgoing;              /**< Length of outgoing queue. */
70   int n_incoming;              /**< Length of incoming queue. */
71   
72   DBusTransport *transport;    /**< Object that sends/receives messages over network. */
73   DBusWatchList *watches;      /**< Stores active watches. */
74   
75   DBusConnectionErrorFunction error_function; /**< Callback for errors. */
76   void *error_data;                           /**< Data for error callback. */
77   DBusFreeFunction error_free_data_function;  /**< Free function for error callback data. */
78 };
79
80 /**
81  * Adds a message to the incoming message queue, returning #FALSE
82  * if there's insufficient memory to queue the message.
83  *
84  * @param connection the connection.
85  * @param message the message to queue.
86  * @returns #TRUE on success.
87  */
88 dbus_bool_t
89 _dbus_connection_queue_received_message (DBusConnection *connection,
90                                          DBusMessage    *message)
91 {
92   if (!_dbus_list_append (&connection->incoming_messages,
93                           message))
94     return FALSE;
95
96   dbus_message_ref (message);
97   connection->n_incoming += 1;
98
99   return TRUE;
100 }
101
102 /**
103  * Checks whether there are messages in the outgoing message queue.
104  *
105  * @param connection the connection.
106  * @returns #TRUE if the outgoing queue is non-empty.
107  */
108 dbus_bool_t
109 _dbus_connection_have_messages_to_send (DBusConnection *connection)
110 {
111   return connection->outgoing_messages != NULL;
112 }
113
114 /**
115  * Gets the next outgoing message. The message remanins in the
116  * queue, and the caller does not own a reference to it.
117  *
118  * @param connection the connection.
119  * @returns the message to be sent.
120  */ 
121 DBusMessage*
122 _dbus_connection_get_message_to_send (DBusConnection *connection)
123 {
124   return _dbus_list_get_last (&connection->outgoing_messages);
125 }
126
127 /**
128  * Notifies the connection that a message has been sent, so the
129  * message can be removed from the outgoing queue.
130  *
131  * @param connection the connection.
132  * @param message the message that was sent.
133  */
134 void
135 _dbus_connection_message_sent (DBusConnection *connection,
136                                DBusMessage    *message)
137 {
138   _dbus_assert (message == _dbus_list_get_last (&connection->outgoing_messages));
139   _dbus_list_pop_last (&connection->outgoing_messages);
140   dbus_message_unref (message);
141   
142   connection->n_outgoing -= 1;
143   if (connection->n_outgoing == 0)
144     _dbus_transport_messages_pending (connection->transport,
145                                       connection->n_outgoing);  
146 }
147
148 /**
149  * Adds a watch using the connection's DBusAddWatchFunction if
150  * available. Otherwise records the watch to be added when said
151  * function is available. Also re-adds the watch if the
152  * DBusAddWatchFunction changes. May fail due to lack of memory.
153  *
154  * @param connection the connection.
155  * @param watch the watch to add.
156  * @returns #TRUE on success.
157  */
158 dbus_bool_t
159 _dbus_connection_add_watch (DBusConnection *connection,
160                             DBusWatch      *watch)
161 {
162   return _dbus_watch_list_add_watch (connection->watches,
163                                      watch);
164   
165   return TRUE;
166 }
167
168 /**
169  * Removes a watch using the connection's DBusRemoveWatchFunction
170  * if available. It's an error to call this function on a watch
171  * that was not previously added.
172  *
173  * @param connection the connection.
174  * @param watch the watch to remove.
175  */
176 void
177 _dbus_connection_remove_watch (DBusConnection *connection,
178                                DBusWatch      *watch)
179 {
180   _dbus_watch_list_remove_watch (connection->watches,
181                                  watch);
182 }
183
184 static void
185 handle_error (DBusConnection *connection,
186               DBusResultCode  result)
187 {
188   if (result != DBUS_RESULT_SUCCESS &&
189       connection->error_function != NULL)
190     {
191       dbus_connection_ref (connection);
192       (* connection->error_function) (connection, result,
193                                       connection->error_data);
194       dbus_connection_unref (connection);
195     }
196 }
197
198 static void
199 set_result_handled (DBusConnection *connection,
200                     DBusResultCode *result_address,
201                     DBusResultCode  result)
202 {
203   dbus_set_result (result_address, result);
204   handle_error (connection, result);
205 }
206
207 /**
208  * Reports a transport error to the connection. Typically
209  * results in an application error callback being invoked.
210  *
211  * @param connection the connection.
212  * @param result_code the error code.
213  */
214 void
215 _dbus_connection_transport_error (DBusConnection *connection,
216                                   DBusResultCode  result_code)
217 {
218   handle_error (connection, result_code);
219 }
220
221 /**
222  * Queues incoming messages and sends outgoing messages for this
223  * connection, optionally blocking in the process. Each call to
224  * _dbus_connection_do_iteration() will call select() or poll() one
225  * time and then read or write data if possible.
226  *
227  * The purpose of this function is to be able to flush outgoing
228  * messages or queue up incoming messages without returning
229  * control to the application and causing reentrancy weirdness.
230  *
231  * The flags parameter allows you to specify whether to
232  * read incoming messages, write outgoing messages, or both,
233  * and whether to block if no immediate action is possible.
234  *
235  * The timeout_milliseconds parameter does nothing unless the
236  * iteration is blocking.
237  *
238  * If there are no outgoing messages and DBUS_ITERATION_DO_READING
239  * wasn't specified, then it's impossible to block, even if
240  * you specify DBUS_ITERATION_BLOCK; in that case the function
241  * returns immediately.
242  * 
243  * @param connection the connection.
244  * @param flags iteration flags.
245  * @param timeout_milliseconds maximum blocking time, or -1 for no limit.
246  */
247 void
248 _dbus_connection_do_iteration (DBusConnection *connection,
249                                unsigned int    flags,
250                                int             timeout_milliseconds)
251 {
252   if (connection->n_outgoing == 0)
253     flags &= ~DBUS_ITERATION_DO_WRITING;
254   
255   _dbus_transport_do_iteration (connection->transport,
256                                 flags, timeout_milliseconds);
257 }
258
259 /**
260  * Creates a new connection for the given transport.  A transport
261  * represents a message stream that uses some concrete mechanism, such
262  * as UNIX domain sockets. May return #NULL if insufficient
263  * memory exists to create the connection.
264  *
265  * @param transport the transport.
266  * @returns the new connection, or #NULL on failure.
267  */
268 DBusConnection*
269 _dbus_connection_new_for_transport (DBusTransport *transport)
270 {
271   DBusConnection *connection;
272   DBusWatchList *watch_list;
273   
274   watch_list = NULL;
275   connection = NULL;
276   
277   watch_list = _dbus_watch_list_new ();
278   if (watch_list == NULL)
279     goto error;
280   
281   connection = dbus_new0 (DBusConnection, 1);
282   if (connection == NULL)
283     goto error;
284   
285   connection->refcount = 1;
286   connection->transport = transport;
287   connection->watches = watch_list;
288
289   _dbus_transport_ref (transport);
290   _dbus_transport_set_connection (transport, connection);
291   
292   return connection;
293   
294  error:
295
296   _dbus_assert (connection == NULL);  
297
298   if (watch_list)
299     _dbus_watch_list_free (watch_list);
300   
301   return NULL;
302 }
303
304 /** @} */
305
306 /**
307  * @addtogroup DBusConnection
308  *
309  * @{
310  */
311
312 /**
313  * Opens a new connection to a remote address.
314  *
315  * @todo specify what the address parameter is. Right now
316  * it's just the name of a UNIX domain socket. It should be
317  * something more complex that encodes which transport to use.
318  *
319  * If the open fails, the function returns #NULL, and provides
320  * a reason for the failure in the result parameter. Pass
321  * #NULL for the result parameter if you aren't interested
322  * in the reason for failure.
323  * 
324  * @param address the address.
325  * @param result address where a result code can be returned.
326  * @returns new connection, or #NULL on failure.
327  */
328 DBusConnection*
329 dbus_connection_open (const char     *address,
330                       DBusResultCode *result)
331 {
332   DBusConnection *connection;
333   DBusTransport *transport;
334   
335   transport = _dbus_transport_open (address, result);
336   if (transport == NULL)
337     return NULL;
338   
339   connection = _dbus_connection_new_for_transport (transport);
340
341   _dbus_transport_unref (transport);
342   
343   if (connection == NULL)
344     {
345       dbus_set_result (result, DBUS_RESULT_NO_MEMORY);
346       return NULL;
347     }
348   
349   return connection;
350 }
351
352 /**
353  * Increments the reference count of a DBusConnection.
354  *
355  * @param connection the connection.
356  */
357 void
358 dbus_connection_ref (DBusConnection *connection)
359 {
360   connection->refcount += 1;
361 }
362
363 /**
364  * Decrements the reference count of a DBusConnection, and finalizes
365  * it if the count reaches zero.  If a connection is still connected
366  * when it's finalized, it will be disconnected (that is, associated
367  * file handles will be closed).
368  *
369  * @param connection the connection.
370  */
371 void
372 dbus_connection_unref (DBusConnection *connection)
373 {
374   _dbus_assert (connection != NULL);
375   _dbus_assert (connection->refcount > 0);
376   
377   connection->refcount -= 1;
378   if (connection->refcount == 0)
379     {
380       /* free error data as a side effect */
381       dbus_connection_set_error_function (connection,
382                                           NULL, NULL, NULL);
383
384       _dbus_watch_list_free (connection->watches);
385       
386       _dbus_list_foreach (&connection->outgoing_messages,
387                           (DBusForeachFunction) dbus_message_unref,
388                           NULL);
389       _dbus_list_clear (&connection->outgoing_messages);
390
391       _dbus_list_foreach (&connection->incoming_messages,
392                           (DBusForeachFunction) dbus_message_unref,
393                           NULL);
394       _dbus_list_clear (&connection->incoming_messages);
395       
396       _dbus_transport_unref (connection->transport);
397       
398       dbus_free (connection);
399     }
400 }
401
402 /**
403  * Closes the connection, so no further data can be sent or received.
404  * Any further attempts to send data will result in errors.  This
405  * function does not affect the connection's reference count.  It's
406  * safe to disconnect a connection more than once; all calls after the
407  * first do nothing. It's impossible to "reconnect" a connection, a
408  * new connection must be created.
409  *
410  * @param connection the connection.
411  */
412 void
413 dbus_connection_disconnect (DBusConnection *connection)
414 {
415   _dbus_transport_disconnect (connection->transport);
416 }
417
418 /**
419  * Gets whether the connection is currently connected.  All
420  * connections are connected when they are opened.  A connection may
421  * become disconnected when the remote application closes its end, or
422  * exits; a connection may also be disconnected with
423  * dbus_connection_disconnect().
424  *
425  * @param connection the connection.
426  * @returns #TRUE if the connection is still alive.
427  */
428 dbus_bool_t
429 dbus_connection_get_is_connected (DBusConnection *connection)
430 {
431   return _dbus_transport_get_is_connected (connection->transport);
432 }
433
434 /**
435  * Adds a message to the outgoing message queue. Does not block to
436  * write the message to the network; that happens asynchronously. to
437  * force the message to be written, call dbus_connection_flush().
438  *
439  * If the function fails, it returns #FALSE and returns the
440  * reason for failure via the result parameter.
441  * The result parameter can be #NULL if you aren't interested
442  * in the reason for the failure.
443  * 
444  * @param connection the connection.
445  * @param message the message to write.
446  * @param result address where result code can be placed.
447  * @returns #TRUE on success.
448  */
449 dbus_bool_t
450 dbus_connection_send_message (DBusConnection *connection,
451                               DBusMessage    *message,
452                               DBusResultCode *result)
453 {  
454   if (!_dbus_list_prepend (&connection->outgoing_messages,
455                            message))
456     {
457       set_result_handled (connection, result, DBUS_RESULT_NO_MEMORY);
458       return FALSE;
459     }
460
461   dbus_message_ref (message);
462   connection->n_outgoing += 1;
463
464   _dbus_message_lock (message);
465   
466   if (connection->n_outgoing == 1)
467     _dbus_transport_messages_pending (connection->transport,
468                                       connection->n_outgoing);
469
470   return TRUE;
471 }
472
473 /**
474  * Blocks until the outgoing message queue is empty.
475  *
476  * @param connection the connection.
477  */
478 void
479 dbus_connection_flush (DBusConnection *connection)
480 {
481   while (connection->n_outgoing > 0)
482     _dbus_connection_do_iteration (connection,
483                                    DBUS_ITERATION_DO_WRITING |
484                                    DBUS_ITERATION_BLOCK,
485                                    -1);
486 }
487
488 /**
489  * Gets the number of messages in the incoming message queue.
490  *
491  * @param connection the connection.
492  * @returns the number of messages in the queue.
493  */
494 int
495 dbus_connection_get_n_messages (DBusConnection *connection)
496 {
497   return connection->n_incoming;
498 }
499
500 /**
501  * Returns the first-received message from the incoming message queue,
502  * leaving it in the queue. The caller does not own a reference to the
503  * returned message. If the queue is empty, returns #NULL.
504  *
505  * @param connection the connection.
506  * @returns next message in the incoming queue.
507  */
508 DBusMessage*
509 dbus_connection_peek_message  (DBusConnection *connection)
510 {
511   return _dbus_list_get_first (&connection->incoming_messages);
512 }
513
514 /**
515  * Returns the first-received message from the incoming message queue,
516  * removing it from the queue. The caller owns a reference to the
517  * returned message. If the queue is empty, returns #NULL.
518  *
519  * @param connection the connection.
520  * @returns next message in the incoming queue.
521  */
522 DBusMessage*
523 dbus_connection_pop_message (DBusConnection *connection)
524 {
525   if (connection->n_incoming > 0)
526     {
527       connection->n_incoming -= 1;
528       return _dbus_list_pop_first (&connection->incoming_messages);
529     }
530   else
531     return NULL;
532 }
533
534 /**
535  * Sets the error handler function for the connection.
536  * 
537  * @param connection the connection.
538  * @param error_function the error handler.
539  * @param data data to pass to the error handler.
540  * @param free_data_function function to be called to free the data.
541  */
542 void
543 dbus_connection_set_error_function  (DBusConnection              *connection,
544                                      DBusConnectionErrorFunction  error_function,
545                                      void                        *data,
546                                      DBusFreeFunction             free_data_function)
547 {
548   if (connection->error_free_data_function != NULL)
549     (* connection->error_free_data_function) (connection->error_data);
550
551   connection->error_function = error_function;
552   connection->error_data = data;
553   connection->error_free_data_function = free_data_function;
554 }
555
556 /**
557  * Sets the watch functions for the connection. These functions are
558  * responsible for making the application's main loop aware of file
559  * descriptors that need to be monitored for events, using select() or
560  * poll(). When using Qt, typically the DBusAddWatchFunction would
561  * create a QSocketNotifier. When using GLib, the DBusAddWatchFunction
562  * could call g_io_add_watch(), or could be used as part of a more
563  * elaborate GSource.
564  *
565  * The DBusWatch can be queried for the file descriptor to watch using
566  * dbus_watch_get_fd(), and for the events to watch for using
567  * dbus_watch_get_flags(). The flags returned by
568  * dbus_watch_get_flags() will only contain DBUS_WATCH_READABLE and
569  * DBUS_WATCH_WRITABLE, never DBUS_WATCH_HANGUP or DBUS_WATCH_ERROR;
570  * all watches implicitly include a watch for hangups, errors, and
571  * other exceptional conditions.
572  *
573  * Once a file descriptor becomes readable or writable, or an exception
574  * occurs, dbus_connection_handle_watch() should be called to
575  * notify the connection of the file descriptor's condition.
576  *
577  * dbus_connection_handle_watch() cannot be called during the
578  * DBusAddWatchFunction, as the connection will not be ready to handle
579  * that watch yet.
580  * 
581  * It is not allowed to reference a DBusWatch after it has been passed
582  * to remove_function.
583  * 
584  * @param connection the connection.
585  * @param add_function function to begin monitoring a new descriptor.
586  * @param remove_function function to stop monitoring a descriptor.
587  * @param data data to pass to add_function and remove_function.
588  * @param free_data_function function to be called to free the data.
589  */
590 void
591 dbus_connection_set_watch_functions (DBusConnection              *connection,
592                                      DBusAddWatchFunction         add_function,
593                                      DBusRemoveWatchFunction      remove_function,
594                                      void                        *data,
595                                      DBusFreeFunction             free_data_function)
596 {
597   /* ref connection for slightly better reentrancy */
598   dbus_connection_ref (connection);
599   
600   _dbus_watch_list_set_functions (connection->watches,
601                                   add_function, remove_function,
602                                   data, free_data_function);
603   
604   /* drop our paranoid refcount */
605   dbus_connection_unref (connection);
606 }
607
608 /**
609  * Called to notify the connection when a previously-added watch
610  * is ready for reading or writing, or has an exception such
611  * as a hangup.
612  *
613  * @param connection the connection.
614  * @param watch the watch.
615  * @param condition the current condition of the file descriptors being watched.
616  */
617 void
618 dbus_connection_handle_watch (DBusConnection              *connection,
619                               DBusWatch                   *watch,
620                               unsigned int                 condition)
621 {
622   _dbus_transport_handle_watch (connection->transport,
623                                 watch, condition);
624 }
625
626 /** @} */