D-Bus  1.8.20
dbus-connection.c
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
00002 /* dbus-connection.c DBusConnection object
00003  *
00004  * Copyright (C) 2002-2006  Red Hat Inc.
00005  *
00006  * Licensed under the Academic Free License version 2.1
00007  * 
00008  * This program is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  * 
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00021  *
00022  */
00023 
00024 #include <config.h>
00025 #include "dbus-shared.h"
00026 #include "dbus-connection.h"
00027 #include "dbus-list.h"
00028 #include "dbus-timeout.h"
00029 #include "dbus-transport.h"
00030 #include "dbus-watch.h"
00031 #include "dbus-connection-internal.h"
00032 #include "dbus-pending-call-internal.h"
00033 #include "dbus-list.h"
00034 #include "dbus-hash.h"
00035 #include "dbus-message-internal.h"
00036 #include "dbus-message-private.h"
00037 #include "dbus-threads.h"
00038 #include "dbus-protocol.h"
00039 #include "dbus-dataslot.h"
00040 #include "dbus-string.h"
00041 #include "dbus-signature.h"
00042 #include "dbus-pending-call.h"
00043 #include "dbus-object-tree.h"
00044 #include "dbus-threads-internal.h"
00045 #include "dbus-bus.h"
00046 #include "dbus-marshal-basic.h"
00047 
00048 #ifdef DBUS_DISABLE_CHECKS
00049 #define TOOK_LOCK_CHECK(connection)
00050 #define RELEASING_LOCK_CHECK(connection)
00051 #define HAVE_LOCK_CHECK(connection)
00052 #else
00053 #define TOOK_LOCK_CHECK(connection) do {                \
00054     _dbus_assert (!(connection)->have_connection_lock); \
00055     (connection)->have_connection_lock = TRUE;          \
00056   } while (0)
00057 #define RELEASING_LOCK_CHECK(connection) do {            \
00058     _dbus_assert ((connection)->have_connection_lock);   \
00059     (connection)->have_connection_lock = FALSE;          \
00060   } while (0)
00061 #define HAVE_LOCK_CHECK(connection)        _dbus_assert ((connection)->have_connection_lock)
00062 /* A "DO_NOT_HAVE_LOCK_CHECK" is impossible since we need the lock to check the flag */
00063 #endif
00064 
00065 #define TRACE_LOCKS 1
00066 
00067 #define CONNECTION_LOCK(connection)   do {                                      \
00068     if (TRACE_LOCKS) { _dbus_verbose ("LOCK\n"); }   \
00069     _dbus_rmutex_lock ((connection)->mutex);                                    \
00070     TOOK_LOCK_CHECK (connection);                                               \
00071   } while (0)
00072 
00073 #define CONNECTION_UNLOCK(connection) _dbus_connection_unlock (connection)
00074 
00075 #define SLOTS_LOCK(connection) do {                     \
00076     _dbus_rmutex_lock ((connection)->slot_mutex);       \
00077   } while (0)
00078 
00079 #define SLOTS_UNLOCK(connection) do {                   \
00080     _dbus_rmutex_unlock ((connection)->slot_mutex);     \
00081   } while (0)
00082 
00083 #define DISPATCH_STATUS_NAME(s)                                            \
00084                      ((s) == DBUS_DISPATCH_COMPLETE ? "complete" :         \
00085                       (s) == DBUS_DISPATCH_DATA_REMAINS ? "data remains" : \
00086                       (s) == DBUS_DISPATCH_NEED_MEMORY ? "need memory" :   \
00087                       "???")
00088 
00206 static void
00207 _dbus_connection_trace_ref (DBusConnection *connection,
00208     int old_refcount,
00209     int new_refcount,
00210     const char *why)
00211 {
00212 #ifdef DBUS_ENABLE_VERBOSE_MODE
00213   static int enabled = -1;
00214 
00215   _dbus_trace_ref ("DBusConnection", connection, old_refcount, new_refcount,
00216       why, "DBUS_CONNECTION_TRACE", &enabled);
00217 #endif
00218 }
00219 
00223 typedef struct DBusMessageFilter DBusMessageFilter;
00224 
00228 struct DBusMessageFilter
00229 {
00230   DBusAtomic refcount; 
00231   DBusHandleMessageFunction function; 
00232   void *user_data; 
00233   DBusFreeFunction free_user_data_function; 
00234 };
00235 
00236 
00240 struct DBusPreallocatedSend
00241 {
00242   DBusConnection *connection; 
00243   DBusList *queue_link;       
00244   DBusList *counter_link;     
00245 };
00246 
00247 #if HAVE_DECL_MSG_NOSIGNAL
00248 static dbus_bool_t _dbus_modify_sigpipe = FALSE;
00249 #else
00250 static dbus_bool_t _dbus_modify_sigpipe = TRUE;
00251 #endif
00252 
00256 struct DBusConnection
00257 {
00258   DBusAtomic refcount; 
00260   DBusRMutex *mutex; 
00262   DBusCMutex *dispatch_mutex;     
00263   DBusCondVar *dispatch_cond;    
00264   DBusCMutex *io_path_mutex;      
00265   DBusCondVar *io_path_cond;     
00267   DBusList *outgoing_messages; 
00268   DBusList *incoming_messages; 
00269   DBusList *expired_messages;  
00271   DBusMessage *message_borrowed; 
00275   int n_outgoing;              
00276   int n_incoming;              
00278   DBusCounter *outgoing_counter; 
00280   DBusTransport *transport;    
00281   DBusWatchList *watches;      
00282   DBusTimeoutList *timeouts;   
00284   DBusList *filter_list;        
00286   DBusRMutex *slot_mutex;        
00287   DBusDataSlotList slot_list;   
00289   DBusHashTable *pending_replies;  
00291   dbus_uint32_t client_serial;       
00292   DBusList *disconnect_message_link; 
00294   DBusWakeupMainFunction wakeup_main_function; 
00295   void *wakeup_main_data; 
00296   DBusFreeFunction free_wakeup_main_data; 
00298   DBusDispatchStatusFunction dispatch_status_function; 
00299   void *dispatch_status_data; 
00300   DBusFreeFunction free_dispatch_status_data; 
00302   DBusDispatchStatus last_dispatch_status; 
00304   DBusObjectTree *objects; 
00306   char *server_guid; 
00308   /* These two MUST be bools and not bitfields, because they are protected by a separate lock
00309    * from connection->mutex and all bitfields in a word have to be read/written together.
00310    * So you can't have a different lock for different bitfields in the same word.
00311    */
00312   dbus_bool_t dispatch_acquired; 
00313   dbus_bool_t io_path_acquired;  
00315   unsigned int shareable : 1; 
00317   unsigned int exit_on_disconnect : 1; 
00319   unsigned int route_peer_messages : 1; 
00321   unsigned int disconnected_message_arrived : 1;   
00325   unsigned int disconnected_message_processed : 1; 
00329 #ifndef DBUS_DISABLE_CHECKS
00330   unsigned int have_connection_lock : 1; 
00331 #endif
00332 
00333 #if defined(DBUS_ENABLE_CHECKS) || defined(DBUS_ENABLE_ASSERT)
00334   int generation; 
00335 #endif 
00336 };
00337 
00338 static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked      (DBusConnection     *connection);
00339 static void               _dbus_connection_update_dispatch_status_and_unlock (DBusConnection     *connection,
00340                                                                               DBusDispatchStatus  new_status);
00341 static void               _dbus_connection_last_unref                        (DBusConnection     *connection);
00342 static void               _dbus_connection_acquire_dispatch                  (DBusConnection     *connection);
00343 static void               _dbus_connection_release_dispatch                  (DBusConnection     *connection);
00344 static DBusDispatchStatus _dbus_connection_flush_unlocked                    (DBusConnection     *connection);
00345 static void               _dbus_connection_close_possibly_shared_and_unlock  (DBusConnection     *connection);
00346 static dbus_bool_t        _dbus_connection_get_is_connected_unlocked         (DBusConnection     *connection);
00347 static dbus_bool_t        _dbus_connection_peek_for_reply_unlocked           (DBusConnection     *connection,
00348                                                                               dbus_uint32_t       client_serial);
00349 
00350 static DBusMessageFilter *
00351 _dbus_message_filter_ref (DBusMessageFilter *filter)
00352 {
00353 #ifdef DBUS_DISABLE_ASSERT
00354   _dbus_atomic_inc (&filter->refcount);
00355 #else
00356   dbus_int32_t old_value;
00357 
00358   old_value = _dbus_atomic_inc (&filter->refcount);
00359   _dbus_assert (old_value > 0);
00360 #endif
00361 
00362   return filter;
00363 }
00364 
00365 static void
00366 _dbus_message_filter_unref (DBusMessageFilter *filter)
00367 {
00368   dbus_int32_t old_value;
00369 
00370   old_value = _dbus_atomic_dec (&filter->refcount);
00371   _dbus_assert (old_value > 0);
00372 
00373   if (old_value == 1)
00374     {
00375       if (filter->free_user_data_function)
00376         (* filter->free_user_data_function) (filter->user_data);
00377       
00378       dbus_free (filter);
00379     }
00380 }
00381 
00387 void
00388 _dbus_connection_lock (DBusConnection *connection)
00389 {
00390   CONNECTION_LOCK (connection);
00391 }
00392 
00398 void
00399 _dbus_connection_unlock (DBusConnection *connection)
00400 {
00401   DBusList *expired_messages;
00402   DBusList *iter;
00403 
00404   if (TRACE_LOCKS)
00405     {
00406       _dbus_verbose ("UNLOCK\n");
00407     }
00408 
00409   /* If we had messages that expired (fell off the incoming or outgoing
00410    * queues) while we were locked, actually release them now */
00411   expired_messages = connection->expired_messages;
00412   connection->expired_messages = NULL;
00413 
00414   RELEASING_LOCK_CHECK (connection);
00415   _dbus_rmutex_unlock (connection->mutex);
00416 
00417   for (iter = _dbus_list_pop_first_link (&expired_messages);
00418       iter != NULL;
00419       iter = _dbus_list_pop_first_link (&expired_messages))
00420     {
00421       DBusMessage *message = iter->data;
00422 
00423       dbus_message_unref (message);
00424       _dbus_list_free_link (iter);
00425     }
00426 }
00427 
00435 static void
00436 _dbus_connection_wakeup_mainloop (DBusConnection *connection)
00437 {
00438   if (connection->wakeup_main_function)
00439     (*connection->wakeup_main_function) (connection->wakeup_main_data);
00440 }
00441 
00442 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
00443 
00455 void 
00456 _dbus_connection_test_get_locks (DBusConnection *connection,
00457                                  DBusMutex     **mutex_loc,
00458                                  DBusMutex     **dispatch_mutex_loc,
00459                                  DBusMutex     **io_path_mutex_loc,
00460                                  DBusCondVar   **dispatch_cond_loc,
00461                                  DBusCondVar   **io_path_cond_loc)
00462 {
00463   *mutex_loc = (DBusMutex *) connection->mutex;
00464   *dispatch_mutex_loc = (DBusMutex *) connection->dispatch_mutex;
00465   *io_path_mutex_loc = (DBusMutex *) connection->io_path_mutex;
00466   *dispatch_cond_loc = connection->dispatch_cond;
00467   *io_path_cond_loc = connection->io_path_cond;
00468 }
00469 #endif
00470 
00479 void
00480 _dbus_connection_queue_received_message_link (DBusConnection  *connection,
00481                                               DBusList        *link)
00482 {
00483   DBusPendingCall *pending;
00484   dbus_uint32_t reply_serial;
00485   DBusMessage *message;
00486 
00487   _dbus_assert (_dbus_transport_peek_is_authenticated (connection->transport));
00488 
00489   _dbus_list_append_link (&connection->incoming_messages,
00490                           link);
00491   message = link->data;
00492 
00493   /* If this is a reply we're waiting on, remove timeout for it */
00494   reply_serial = dbus_message_get_reply_serial (message);
00495   if (reply_serial != 0)
00496     {
00497       pending = _dbus_hash_table_lookup_int (connection->pending_replies,
00498                                              reply_serial);
00499       if (pending != NULL)
00500         {
00501           if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00502             _dbus_connection_remove_timeout_unlocked (connection,
00503                                                       _dbus_pending_call_get_timeout_unlocked (pending));
00504 
00505           _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00506         }
00507     }
00508   
00509   
00510 
00511   connection->n_incoming += 1;
00512 
00513   _dbus_connection_wakeup_mainloop (connection);
00514   
00515   _dbus_verbose ("Message %p (%s %s %s %s '%s' reply to %u) added to incoming queue %p, %d incoming\n",
00516                  message,
00517                  dbus_message_type_to_string (dbus_message_get_type (message)),
00518                  dbus_message_get_path (message) ?
00519                  dbus_message_get_path (message) :
00520                  "no path",
00521                  dbus_message_get_interface (message) ?
00522                  dbus_message_get_interface (message) :
00523                  "no interface",
00524                  dbus_message_get_member (message) ?
00525                  dbus_message_get_member (message) :
00526                  "no member",
00527                  dbus_message_get_signature (message),
00528                  dbus_message_get_reply_serial (message),
00529                  connection,
00530                  connection->n_incoming);
00531 
00532   _dbus_message_trace_ref (message, -1, -1,
00533       "_dbus_conection_queue_received_message_link");
00534 }
00535 
00544 void
00545 _dbus_connection_queue_synthesized_message_link (DBusConnection *connection,
00546                                                  DBusList *link)
00547 {
00548   HAVE_LOCK_CHECK (connection);
00549   
00550   _dbus_list_append_link (&connection->incoming_messages, link);
00551 
00552   connection->n_incoming += 1;
00553 
00554   _dbus_connection_wakeup_mainloop (connection);
00555 
00556   _dbus_message_trace_ref (link->data, -1, -1,
00557       "_dbus_connection_queue_synthesized_message_link");
00558 
00559   _dbus_verbose ("Synthesized message %p added to incoming queue %p, %d incoming\n",
00560                  link->data, connection, connection->n_incoming);
00561 }
00562 
00563 
00571 dbus_bool_t
00572 _dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection)
00573 {
00574   HAVE_LOCK_CHECK (connection);
00575   return connection->outgoing_messages != NULL;
00576 }
00577 
00587 dbus_bool_t
00588 dbus_connection_has_messages_to_send (DBusConnection *connection)
00589 {
00590   dbus_bool_t v;
00591   
00592   _dbus_return_val_if_fail (connection != NULL, FALSE);
00593 
00594   CONNECTION_LOCK (connection);
00595   v = _dbus_connection_has_messages_to_send_unlocked (connection);
00596   CONNECTION_UNLOCK (connection);
00597 
00598   return v;
00599 }
00600 
00608 DBusMessage*
00609 _dbus_connection_get_message_to_send (DBusConnection *connection)
00610 {
00611   HAVE_LOCK_CHECK (connection);
00612   
00613   return _dbus_list_get_last (&connection->outgoing_messages);
00614 }
00615 
00624 void
00625 _dbus_connection_message_sent_unlocked (DBusConnection *connection,
00626                                         DBusMessage    *message)
00627 {
00628   DBusList *link;
00629 
00630   HAVE_LOCK_CHECK (connection);
00631   
00632   /* This can be called before we even complete authentication, since
00633    * it's called on disconnect to clean up the outgoing queue.
00634    * It's also called as we successfully send each message.
00635    */
00636   
00637   link = _dbus_list_get_last_link (&connection->outgoing_messages);
00638   _dbus_assert (link != NULL);
00639   _dbus_assert (link->data == message);
00640 
00641   _dbus_list_unlink (&connection->outgoing_messages,
00642                      link);
00643   _dbus_list_prepend_link (&connection->expired_messages, link);
00644 
00645   connection->n_outgoing -= 1;
00646 
00647   _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from outgoing queue %p, %d left to send\n",
00648                  message,
00649                  dbus_message_type_to_string (dbus_message_get_type (message)),
00650                  dbus_message_get_path (message) ?
00651                  dbus_message_get_path (message) :
00652                  "no path",
00653                  dbus_message_get_interface (message) ?
00654                  dbus_message_get_interface (message) :
00655                  "no interface",
00656                  dbus_message_get_member (message) ?
00657                  dbus_message_get_member (message) :
00658                  "no member",
00659                  dbus_message_get_signature (message),
00660                  connection, connection->n_outgoing);
00661 
00662   /* It's OK that in principle we call the notify function, because for the
00663    * outgoing limit, there isn't one */
00664   _dbus_message_remove_counter (message, connection->outgoing_counter);
00665 
00666   /* The message will actually be unreffed when we unlock */
00667 }
00668 
00670 typedef dbus_bool_t (* DBusWatchAddFunction)     (DBusWatchList *list,
00671                                                   DBusWatch     *watch);
00673 typedef void        (* DBusWatchRemoveFunction)  (DBusWatchList *list,
00674                                                   DBusWatch     *watch);
00676 typedef void        (* DBusWatchToggleFunction)  (DBusWatchList *list,
00677                                                   DBusWatch     *watch,
00678                                                   dbus_bool_t    enabled);
00679 
00680 static dbus_bool_t
00681 protected_change_watch (DBusConnection         *connection,
00682                         DBusWatch              *watch,
00683                         DBusWatchAddFunction    add_function,
00684                         DBusWatchRemoveFunction remove_function,
00685                         DBusWatchToggleFunction toggle_function,
00686                         dbus_bool_t             enabled)
00687 {
00688   dbus_bool_t retval;
00689 
00690   HAVE_LOCK_CHECK (connection);
00691 
00692   /* The original purpose of protected_change_watch() was to hold a
00693    * ref on the connection while dropping the connection lock, then
00694    * calling out to the app.  This was a broken hack that did not
00695    * work, since the connection was in a hosed state (no WatchList
00696    * field) while calling out.
00697    *
00698    * So for now we'll just keep the lock while calling out. This means
00699    * apps are not allowed to call DBusConnection methods inside a
00700    * watch function or they will deadlock.
00701    *
00702    * The "real fix" is to use the _and_unlock() pattern found
00703    * elsewhere in the code, to defer calling out to the app until
00704    * we're about to drop locks and return flow of control to the app
00705    * anyway.
00706    *
00707    * See http://lists.freedesktop.org/archives/dbus/2007-July/thread.html#8144
00708    */
00709 
00710   if (connection->watches)
00711     {
00712       if (add_function)
00713         retval = (* add_function) (connection->watches, watch);
00714       else if (remove_function)
00715         {
00716           retval = TRUE;
00717           (* remove_function) (connection->watches, watch);
00718         }
00719       else
00720         {
00721           retval = TRUE;
00722           (* toggle_function) (connection->watches, watch, enabled);
00723         }
00724       return retval;
00725     }
00726   else
00727     return FALSE;
00728 }
00729      
00730 
00742 dbus_bool_t
00743 _dbus_connection_add_watch_unlocked (DBusConnection *connection,
00744                                      DBusWatch      *watch)
00745 {
00746   return protected_change_watch (connection, watch,
00747                                  _dbus_watch_list_add_watch,
00748                                  NULL, NULL, FALSE);
00749 }
00750 
00760 void
00761 _dbus_connection_remove_watch_unlocked (DBusConnection *connection,
00762                                         DBusWatch      *watch)
00763 {
00764   protected_change_watch (connection, watch,
00765                           NULL,
00766                           _dbus_watch_list_remove_watch,
00767                           NULL, FALSE);
00768 }
00769 
00780 void
00781 _dbus_connection_toggle_watch_unlocked (DBusConnection *connection,
00782                                         DBusWatch      *watch,
00783                                         dbus_bool_t     enabled)
00784 {
00785   _dbus_assert (watch != NULL);
00786 
00787   protected_change_watch (connection, watch,
00788                           NULL, NULL,
00789                           _dbus_watch_list_toggle_watch,
00790                           enabled);
00791 }
00792 
00794 typedef dbus_bool_t (* DBusTimeoutAddFunction)    (DBusTimeoutList *list,
00795                                                    DBusTimeout     *timeout);
00797 typedef void        (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list,
00798                                                    DBusTimeout     *timeout);
00800 typedef void        (* DBusTimeoutToggleFunction) (DBusTimeoutList *list,
00801                                                    DBusTimeout     *timeout,
00802                                                    dbus_bool_t      enabled);
00803 
00804 static dbus_bool_t
00805 protected_change_timeout (DBusConnection           *connection,
00806                           DBusTimeout              *timeout,
00807                           DBusTimeoutAddFunction    add_function,
00808                           DBusTimeoutRemoveFunction remove_function,
00809                           DBusTimeoutToggleFunction toggle_function,
00810                           dbus_bool_t               enabled)
00811 {
00812   dbus_bool_t retval;
00813 
00814   HAVE_LOCK_CHECK (connection);
00815 
00816   /* The original purpose of protected_change_timeout() was to hold a
00817    * ref on the connection while dropping the connection lock, then
00818    * calling out to the app.  This was a broken hack that did not
00819    * work, since the connection was in a hosed state (no TimeoutList
00820    * field) while calling out.
00821    *
00822    * So for now we'll just keep the lock while calling out. This means
00823    * apps are not allowed to call DBusConnection methods inside a
00824    * timeout function or they will deadlock.
00825    *
00826    * The "real fix" is to use the _and_unlock() pattern found
00827    * elsewhere in the code, to defer calling out to the app until
00828    * we're about to drop locks and return flow of control to the app
00829    * anyway.
00830    *
00831    * See http://lists.freedesktop.org/archives/dbus/2007-July/thread.html#8144
00832    */
00833 
00834   if (connection->timeouts)
00835     {
00836       if (add_function)
00837         retval = (* add_function) (connection->timeouts, timeout);
00838       else if (remove_function)
00839         {
00840           retval = TRUE;
00841           (* remove_function) (connection->timeouts, timeout);
00842         }
00843       else
00844         {
00845           retval = TRUE;
00846           (* toggle_function) (connection->timeouts, timeout, enabled);
00847         }
00848       return retval;
00849     }
00850   else
00851     return FALSE;
00852 }
00853 
00866 dbus_bool_t
00867 _dbus_connection_add_timeout_unlocked (DBusConnection *connection,
00868                                        DBusTimeout    *timeout)
00869 {
00870   return protected_change_timeout (connection, timeout,
00871                                    _dbus_timeout_list_add_timeout,
00872                                    NULL, NULL, FALSE);
00873 }
00874 
00884 void
00885 _dbus_connection_remove_timeout_unlocked (DBusConnection *connection,
00886                                           DBusTimeout    *timeout)
00887 {
00888   protected_change_timeout (connection, timeout,
00889                             NULL,
00890                             _dbus_timeout_list_remove_timeout,
00891                             NULL, FALSE);
00892 }
00893 
00904 void
00905 _dbus_connection_toggle_timeout_unlocked (DBusConnection   *connection,
00906                                           DBusTimeout      *timeout,
00907                                           dbus_bool_t       enabled)
00908 {
00909   protected_change_timeout (connection, timeout,
00910                             NULL, NULL,
00911                             _dbus_timeout_list_toggle_timeout,
00912                             enabled);
00913 }
00914 
00915 static dbus_bool_t
00916 _dbus_connection_attach_pending_call_unlocked (DBusConnection  *connection,
00917                                                DBusPendingCall *pending)
00918 {
00919   dbus_uint32_t reply_serial;
00920   DBusTimeout *timeout;
00921 
00922   HAVE_LOCK_CHECK (connection);
00923 
00924   reply_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
00925 
00926   _dbus_assert (reply_serial != 0);
00927 
00928   timeout = _dbus_pending_call_get_timeout_unlocked (pending);
00929 
00930   if (timeout)
00931     {
00932       if (!_dbus_connection_add_timeout_unlocked (connection, timeout))
00933         return FALSE;
00934       
00935       if (!_dbus_hash_table_insert_int (connection->pending_replies,
00936                                         reply_serial,
00937                                         pending))
00938         {
00939           _dbus_connection_remove_timeout_unlocked (connection, timeout);
00940 
00941           _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00942           HAVE_LOCK_CHECK (connection);
00943           return FALSE;
00944         }
00945       
00946       _dbus_pending_call_set_timeout_added_unlocked (pending, TRUE);
00947     }
00948   else
00949     {
00950       if (!_dbus_hash_table_insert_int (connection->pending_replies,
00951                                         reply_serial,
00952                                         pending))
00953         {
00954           HAVE_LOCK_CHECK (connection);
00955           return FALSE;
00956         }
00957     }
00958 
00959   _dbus_pending_call_ref_unlocked (pending);
00960 
00961   HAVE_LOCK_CHECK (connection);
00962   
00963   return TRUE;
00964 }
00965 
00966 static void
00967 free_pending_call_on_hash_removal (void *data)
00968 {
00969   DBusPendingCall *pending;
00970   DBusConnection  *connection;
00971   
00972   if (data == NULL)
00973     return;
00974 
00975   pending = data;
00976 
00977   connection = _dbus_pending_call_get_connection_unlocked (pending);
00978 
00979   HAVE_LOCK_CHECK (connection);
00980   
00981   if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00982     {
00983       _dbus_connection_remove_timeout_unlocked (connection,
00984                                                 _dbus_pending_call_get_timeout_unlocked (pending));
00985       
00986       _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00987     }
00988 
00989   /* FIXME 1.0? this is sort of dangerous and undesirable to drop the lock 
00990    * here, but the pending call finalizer could in principle call out to 
00991    * application code so we pretty much have to... some larger code reorg 
00992    * might be needed.
00993    */
00994   _dbus_connection_ref_unlocked (connection);
00995   _dbus_pending_call_unref_and_unlock (pending);
00996   CONNECTION_LOCK (connection);
00997   _dbus_connection_unref_unlocked (connection);
00998 }
00999 
01000 static void
01001 _dbus_connection_detach_pending_call_unlocked (DBusConnection  *connection,
01002                                                DBusPendingCall *pending)
01003 {
01004   /* This ends up unlocking to call the pending call finalizer, which is unexpected to
01005    * say the least.
01006    */
01007   _dbus_hash_table_remove_int (connection->pending_replies,
01008                                _dbus_pending_call_get_reply_serial_unlocked (pending));
01009 }
01010 
01011 static void
01012 _dbus_connection_detach_pending_call_and_unlock (DBusConnection  *connection,
01013                                                  DBusPendingCall *pending)
01014 {
01015   /* The idea here is to avoid finalizing the pending call
01016    * with the lock held, since there's a destroy notifier
01017    * in pending call that goes out to application code.
01018    *
01019    * There's an extra unlock inside the hash table
01020    * "free pending call" function FIXME...
01021    */
01022   _dbus_pending_call_ref_unlocked (pending);
01023   _dbus_hash_table_remove_int (connection->pending_replies,
01024                                _dbus_pending_call_get_reply_serial_unlocked (pending));
01025 
01026   if (_dbus_pending_call_is_timeout_added_unlocked (pending))
01027       _dbus_connection_remove_timeout_unlocked (connection,
01028               _dbus_pending_call_get_timeout_unlocked (pending));
01029 
01030   _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
01031 
01032   _dbus_pending_call_unref_and_unlock (pending);
01033 }
01034 
01043 void
01044 _dbus_connection_remove_pending_call (DBusConnection  *connection,
01045                                       DBusPendingCall *pending)
01046 {
01047   CONNECTION_LOCK (connection);
01048   _dbus_connection_detach_pending_call_and_unlock (connection, pending);
01049 }
01050 
01060 static dbus_bool_t
01061 _dbus_connection_acquire_io_path (DBusConnection *connection,
01062                                   int             timeout_milliseconds)
01063 {
01064   dbus_bool_t we_acquired;
01065   
01066   HAVE_LOCK_CHECK (connection);
01067 
01068   /* We don't want the connection to vanish */
01069   _dbus_connection_ref_unlocked (connection);
01070 
01071   /* We will only touch io_path_acquired which is protected by our mutex */
01072   CONNECTION_UNLOCK (connection);
01073   
01074   _dbus_verbose ("locking io_path_mutex\n");
01075   _dbus_cmutex_lock (connection->io_path_mutex);
01076 
01077   _dbus_verbose ("start connection->io_path_acquired = %d timeout = %d\n",
01078                  connection->io_path_acquired, timeout_milliseconds);
01079 
01080   we_acquired = FALSE;
01081   
01082   if (connection->io_path_acquired)
01083     {
01084       if (timeout_milliseconds != -1)
01085         {
01086           _dbus_verbose ("waiting %d for IO path to be acquirable\n",
01087                          timeout_milliseconds);
01088 
01089           if (!_dbus_condvar_wait_timeout (connection->io_path_cond,
01090                                            connection->io_path_mutex,
01091                                            timeout_milliseconds))
01092             {
01093               /* We timed out before anyone signaled. */
01094               /* (writing the loop to handle the !timedout case by
01095                * waiting longer if needed is a pain since dbus
01096                * wraps pthread_cond_timedwait to take a relative
01097                * time instead of absolute, something kind of stupid
01098                * on our part. for now it doesn't matter, we will just
01099                * end up back here eventually.)
01100                */
01101             }
01102         }
01103       else
01104         {
01105           while (connection->io_path_acquired)
01106             {
01107               _dbus_verbose ("waiting for IO path to be acquirable\n");
01108               _dbus_condvar_wait (connection->io_path_cond, 
01109                                   connection->io_path_mutex);
01110             }
01111         }
01112     }
01113   
01114   if (!connection->io_path_acquired)
01115     {
01116       we_acquired = TRUE;
01117       connection->io_path_acquired = TRUE;
01118     }
01119   
01120   _dbus_verbose ("end connection->io_path_acquired = %d we_acquired = %d\n",
01121                  connection->io_path_acquired, we_acquired);
01122 
01123   _dbus_verbose ("unlocking io_path_mutex\n");
01124   _dbus_cmutex_unlock (connection->io_path_mutex);
01125 
01126   CONNECTION_LOCK (connection);
01127   
01128   HAVE_LOCK_CHECK (connection);
01129 
01130   _dbus_connection_unref_unlocked (connection);
01131   
01132   return we_acquired;
01133 }
01134 
01142 static void
01143 _dbus_connection_release_io_path (DBusConnection *connection)
01144 {
01145   HAVE_LOCK_CHECK (connection);
01146   
01147   _dbus_verbose ("locking io_path_mutex\n");
01148   _dbus_cmutex_lock (connection->io_path_mutex);
01149   
01150   _dbus_assert (connection->io_path_acquired);
01151 
01152   _dbus_verbose ("start connection->io_path_acquired = %d\n",
01153                  connection->io_path_acquired);
01154   
01155   connection->io_path_acquired = FALSE;
01156   _dbus_condvar_wake_one (connection->io_path_cond);
01157 
01158   _dbus_verbose ("unlocking io_path_mutex\n");
01159   _dbus_cmutex_unlock (connection->io_path_mutex);
01160 }
01161 
01197 void
01198 _dbus_connection_do_iteration_unlocked (DBusConnection *connection,
01199                                         DBusPendingCall *pending,
01200                                         unsigned int    flags,
01201                                         int             timeout_milliseconds)
01202 {
01203   _dbus_verbose ("start\n");
01204   
01205   HAVE_LOCK_CHECK (connection);
01206   
01207   if (connection->n_outgoing == 0)
01208     flags &= ~DBUS_ITERATION_DO_WRITING;
01209 
01210   if (_dbus_connection_acquire_io_path (connection,
01211                                         (flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0))
01212     {
01213       HAVE_LOCK_CHECK (connection);
01214       
01215       if ( (pending != NULL) && _dbus_pending_call_get_completed_unlocked(pending))
01216         {
01217           _dbus_verbose ("pending call completed while acquiring I/O path");
01218         }
01219       else if ( (pending != NULL) &&
01220                 _dbus_connection_peek_for_reply_unlocked (connection,
01221                                                           _dbus_pending_call_get_reply_serial_unlocked (pending)))
01222         {
01223           _dbus_verbose ("pending call completed while acquiring I/O path (reply found in queue)");
01224         }
01225       else
01226         {
01227           _dbus_transport_do_iteration (connection->transport,
01228                                         flags, timeout_milliseconds);
01229         }
01230 
01231       _dbus_connection_release_io_path (connection);
01232     }
01233 
01234   HAVE_LOCK_CHECK (connection);
01235 
01236   _dbus_verbose ("end\n");
01237 }
01238 
01248 DBusConnection*
01249 _dbus_connection_new_for_transport (DBusTransport *transport)
01250 {
01251   DBusConnection *connection;
01252   DBusWatchList *watch_list;
01253   DBusTimeoutList *timeout_list;
01254   DBusHashTable *pending_replies;
01255   DBusList *disconnect_link;
01256   DBusMessage *disconnect_message;
01257   DBusCounter *outgoing_counter;
01258   DBusObjectTree *objects;
01259   
01260   watch_list = NULL;
01261   connection = NULL;
01262   pending_replies = NULL;
01263   timeout_list = NULL;
01264   disconnect_link = NULL;
01265   disconnect_message = NULL;
01266   outgoing_counter = NULL;
01267   objects = NULL;
01268   
01269   watch_list = _dbus_watch_list_new ();
01270   if (watch_list == NULL)
01271     goto error;
01272 
01273   timeout_list = _dbus_timeout_list_new ();
01274   if (timeout_list == NULL)
01275     goto error;  
01276 
01277   pending_replies =
01278     _dbus_hash_table_new (DBUS_HASH_INT,
01279                           NULL,
01280                           (DBusFreeFunction)free_pending_call_on_hash_removal);
01281   if (pending_replies == NULL)
01282     goto error;
01283   
01284   connection = dbus_new0 (DBusConnection, 1);
01285   if (connection == NULL)
01286     goto error;
01287 
01288   _dbus_rmutex_new_at_location (&connection->mutex);
01289   if (connection->mutex == NULL)
01290     goto error;
01291 
01292   _dbus_cmutex_new_at_location (&connection->io_path_mutex);
01293   if (connection->io_path_mutex == NULL)
01294     goto error;
01295 
01296   _dbus_cmutex_new_at_location (&connection->dispatch_mutex);
01297   if (connection->dispatch_mutex == NULL)
01298     goto error;
01299   
01300   _dbus_condvar_new_at_location (&connection->dispatch_cond);
01301   if (connection->dispatch_cond == NULL)
01302     goto error;
01303   
01304   _dbus_condvar_new_at_location (&connection->io_path_cond);
01305   if (connection->io_path_cond == NULL)
01306     goto error;
01307 
01308   _dbus_rmutex_new_at_location (&connection->slot_mutex);
01309   if (connection->slot_mutex == NULL)
01310     goto error;
01311 
01312   disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL,
01313                                                 DBUS_INTERFACE_LOCAL,
01314                                                 "Disconnected");
01315   
01316   if (disconnect_message == NULL)
01317     goto error;
01318 
01319   disconnect_link = _dbus_list_alloc_link (disconnect_message);
01320   if (disconnect_link == NULL)
01321     goto error;
01322 
01323   outgoing_counter = _dbus_counter_new ();
01324   if (outgoing_counter == NULL)
01325     goto error;
01326 
01327   objects = _dbus_object_tree_new (connection);
01328   if (objects == NULL)
01329     goto error;
01330   
01331   if (_dbus_modify_sigpipe)
01332     _dbus_disable_sigpipe ();
01333 
01334   /* initialized to 0: use atomic op to avoid mixing atomic and non-atomic */
01335   _dbus_atomic_inc (&connection->refcount);
01336   connection->transport = transport;
01337   connection->watches = watch_list;
01338   connection->timeouts = timeout_list;
01339   connection->pending_replies = pending_replies;
01340   connection->outgoing_counter = outgoing_counter;
01341   connection->filter_list = NULL;
01342   connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE; /* so we're notified first time there's data */
01343   connection->objects = objects;
01344   connection->exit_on_disconnect = FALSE;
01345   connection->shareable = FALSE;
01346   connection->route_peer_messages = FALSE;
01347   connection->disconnected_message_arrived = FALSE;
01348   connection->disconnected_message_processed = FALSE;
01349   
01350 #if defined(DBUS_ENABLE_CHECKS) || defined(DBUS_ENABLE_ASSERT)
01351   connection->generation = _dbus_current_generation;
01352 #endif
01353   
01354   _dbus_data_slot_list_init (&connection->slot_list);
01355 
01356   connection->client_serial = 1;
01357 
01358   connection->disconnect_message_link = disconnect_link;
01359 
01360   CONNECTION_LOCK (connection);
01361   
01362   if (!_dbus_transport_set_connection (transport, connection))
01363     {
01364       CONNECTION_UNLOCK (connection);
01365 
01366       goto error;
01367     }
01368 
01369   _dbus_transport_ref (transport);
01370 
01371   CONNECTION_UNLOCK (connection);
01372 
01373   _dbus_connection_trace_ref (connection, 0, 1, "new_for_transport");
01374   return connection;
01375   
01376  error:
01377   if (disconnect_message != NULL)
01378     dbus_message_unref (disconnect_message);
01379   
01380   if (disconnect_link != NULL)
01381     _dbus_list_free_link (disconnect_link);
01382   
01383   if (connection != NULL)
01384     {
01385       _dbus_condvar_free_at_location (&connection->io_path_cond);
01386       _dbus_condvar_free_at_location (&connection->dispatch_cond);
01387       _dbus_rmutex_free_at_location (&connection->mutex);
01388       _dbus_cmutex_free_at_location (&connection->io_path_mutex);
01389       _dbus_cmutex_free_at_location (&connection->dispatch_mutex);
01390       _dbus_rmutex_free_at_location (&connection->slot_mutex);
01391       dbus_free (connection);
01392     }
01393   if (pending_replies)
01394     _dbus_hash_table_unref (pending_replies);
01395   
01396   if (watch_list)
01397     _dbus_watch_list_free (watch_list);
01398 
01399   if (timeout_list)
01400     _dbus_timeout_list_free (timeout_list);
01401 
01402   if (outgoing_counter)
01403     _dbus_counter_unref (outgoing_counter);
01404 
01405   if (objects)
01406     _dbus_object_tree_unref (objects);
01407   
01408   return NULL;
01409 }
01410 
01418 DBusConnection *
01419 _dbus_connection_ref_unlocked (DBusConnection *connection)
01420 {
01421   dbus_int32_t old_refcount;
01422 
01423   _dbus_assert (connection != NULL);
01424   _dbus_assert (connection->generation == _dbus_current_generation);
01425 
01426   HAVE_LOCK_CHECK (connection);
01427 
01428   old_refcount = _dbus_atomic_inc (&connection->refcount);
01429   _dbus_connection_trace_ref (connection, old_refcount, old_refcount + 1,
01430       "ref_unlocked");
01431 
01432   return connection;
01433 }
01434 
01441 void
01442 _dbus_connection_unref_unlocked (DBusConnection *connection)
01443 {
01444   dbus_int32_t old_refcount;
01445 
01446   HAVE_LOCK_CHECK (connection);
01447 
01448   _dbus_assert (connection != NULL);
01449 
01450   old_refcount = _dbus_atomic_dec (&connection->refcount);
01451 
01452   _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1,
01453       "unref_unlocked");
01454 
01455   if (old_refcount == 1)
01456     _dbus_connection_last_unref (connection);
01457 }
01458 
01459 static dbus_uint32_t
01460 _dbus_connection_get_next_client_serial (DBusConnection *connection)
01461 {
01462   dbus_uint32_t serial;
01463 
01464   serial = connection->client_serial++;
01465 
01466   if (connection->client_serial == 0)
01467     connection->client_serial = 1;
01468 
01469   return serial;
01470 }
01471 
01485 dbus_bool_t
01486 _dbus_connection_handle_watch (DBusWatch                   *watch,
01487                                unsigned int                 condition,
01488                                void                        *data)
01489 {
01490   DBusConnection *connection;
01491   dbus_bool_t retval;
01492   DBusDispatchStatus status;
01493 
01494   connection = data;
01495 
01496   _dbus_verbose ("start\n");
01497   
01498   CONNECTION_LOCK (connection);
01499 
01500   if (!_dbus_connection_acquire_io_path (connection, 1))
01501     {
01502       /* another thread is handling the message */
01503       CONNECTION_UNLOCK (connection);
01504       return TRUE;
01505     }
01506 
01507   HAVE_LOCK_CHECK (connection);
01508   retval = _dbus_transport_handle_watch (connection->transport,
01509                                          watch, condition);
01510 
01511   _dbus_connection_release_io_path (connection);
01512 
01513   HAVE_LOCK_CHECK (connection);
01514 
01515   _dbus_verbose ("middle\n");
01516   
01517   status = _dbus_connection_get_dispatch_status_unlocked (connection);
01518 
01519   /* this calls out to user code */
01520   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01521 
01522   _dbus_verbose ("end\n");
01523   
01524   return retval;
01525 }
01526 
01527 /* Protected by _DBUS_LOCK (shared_connections) */
01528 static DBusHashTable *shared_connections = NULL;
01529 static DBusList *shared_connections_no_guid = NULL;
01530 
01531 static void
01532 close_connection_on_shutdown (DBusConnection *connection)
01533 {
01534   DBusMessage *message;
01535 
01536   dbus_connection_ref (connection);
01537   _dbus_connection_close_possibly_shared (connection);
01538 
01539   /* Churn through to the Disconnected message */
01540   while ((message = dbus_connection_pop_message (connection)))
01541     {
01542       dbus_message_unref (message);
01543     }
01544   dbus_connection_unref (connection);
01545 }
01546 
01547 static void
01548 shared_connections_shutdown (void *data)
01549 {
01550   int n_entries;
01551 
01552   if (!_DBUS_LOCK (shared_connections))
01553     {
01554       /* We'd have initialized locks before adding anything, so there
01555        * can't be anything there. */
01556       return;
01557     }
01558 
01559   /* This is a little bit unpleasant... better ideas? */
01560   while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0)
01561     {
01562       DBusConnection *connection;
01563       DBusHashIter iter;
01564       
01565       _dbus_hash_iter_init (shared_connections, &iter);
01566       _dbus_hash_iter_next (&iter);
01567        
01568       connection = _dbus_hash_iter_get_value (&iter);
01569 
01570       _DBUS_UNLOCK (shared_connections);
01571       close_connection_on_shutdown (connection);
01572       if (!_DBUS_LOCK (shared_connections))
01573         _dbus_assert_not_reached ("global locks were already initialized");
01574 
01575       /* The connection should now be dead and not in our hash ... */
01576       _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) < n_entries);
01577     }
01578 
01579   _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) == 0);
01580   
01581   _dbus_hash_table_unref (shared_connections);
01582   shared_connections = NULL;
01583 
01584   if (shared_connections_no_guid != NULL)
01585     {
01586       DBusConnection *connection;
01587       connection = _dbus_list_pop_first (&shared_connections_no_guid);
01588       while (connection != NULL)
01589         {
01590           _DBUS_UNLOCK (shared_connections);
01591           close_connection_on_shutdown (connection);
01592           if (!_DBUS_LOCK (shared_connections))
01593             _dbus_assert_not_reached ("global locks were already initialized");
01594           connection = _dbus_list_pop_first (&shared_connections_no_guid);
01595         }
01596     }
01597 
01598   shared_connections_no_guid = NULL;
01599   
01600   _DBUS_UNLOCK (shared_connections);
01601 }
01602 
01603 static dbus_bool_t
01604 connection_lookup_shared (DBusAddressEntry  *entry,
01605                           DBusConnection   **result)
01606 {
01607   _dbus_verbose ("checking for existing connection\n");
01608   
01609   *result = NULL;
01610 
01611   if (!_DBUS_LOCK (shared_connections))
01612     {
01613       /* If it was shared, we'd have initialized global locks when we put
01614        * it in shared_connections. */
01615       return FALSE;
01616     }
01617 
01618   if (shared_connections == NULL)
01619     {
01620       _dbus_verbose ("creating shared_connections hash table\n");
01621       
01622       shared_connections = _dbus_hash_table_new (DBUS_HASH_STRING,
01623                                                  dbus_free,
01624                                                  NULL);
01625       if (shared_connections == NULL)
01626         {
01627           _DBUS_UNLOCK (shared_connections);
01628           return FALSE;
01629         }
01630 
01631       if (!_dbus_register_shutdown_func (shared_connections_shutdown, NULL))
01632         {
01633           _dbus_hash_table_unref (shared_connections);
01634           shared_connections = NULL;
01635           _DBUS_UNLOCK (shared_connections);
01636           return FALSE;
01637         }
01638 
01639       _dbus_verbose ("  successfully created shared_connections\n");
01640       
01641       _DBUS_UNLOCK (shared_connections);
01642       return TRUE; /* no point looking up in the hash we just made */
01643     }
01644   else
01645     {
01646       const char *guid;
01647 
01648       guid = dbus_address_entry_get_value (entry, "guid");
01649       
01650       if (guid != NULL)
01651         {
01652           DBusConnection *connection;
01653           
01654           connection = _dbus_hash_table_lookup_string (shared_connections,
01655                                                        guid);
01656 
01657           if (connection)
01658             {
01659               /* The DBusConnection can't be finalized without taking
01660                * the shared_connections lock to remove it from the
01661                * hash.  So it's safe to ref the connection here.
01662                * However, it may be disconnected if the Disconnected
01663                * message hasn't been processed yet, in which case we
01664                * want to pretend it isn't in the hash and avoid
01665                * returning it.
01666                *
01667                * The idea is to avoid ever returning a disconnected connection
01668                * from dbus_connection_open(). We could just synchronously
01669                * drop our shared ref to the connection on connection disconnect,
01670                * and then assert here that the connection is connected, but
01671                * that causes reentrancy headaches.
01672                */
01673               CONNECTION_LOCK (connection);
01674               if (_dbus_connection_get_is_connected_unlocked (connection))
01675                 {
01676                   _dbus_connection_ref_unlocked (connection);
01677                   *result = connection;
01678                   _dbus_verbose ("looked up existing connection to server guid %s\n",
01679                                  guid);
01680                 }
01681               else
01682                 {
01683                   _dbus_verbose ("looked up existing connection to server guid %s but it was disconnected so ignoring it\n",
01684                                  guid);
01685                 }
01686               CONNECTION_UNLOCK (connection);
01687             }
01688         }
01689       
01690       _DBUS_UNLOCK (shared_connections);
01691       return TRUE;
01692     }
01693 }
01694 
01695 static dbus_bool_t
01696 connection_record_shared_unlocked (DBusConnection *connection,
01697                                    const char     *guid)
01698 {
01699   char *guid_key;
01700   char *guid_in_connection;
01701 
01702   HAVE_LOCK_CHECK (connection);
01703   _dbus_assert (connection->server_guid == NULL);
01704   _dbus_assert (connection->shareable);
01705 
01706   /* get a hard ref on this connection, even if
01707    * we won't in fact store it in the hash, we still
01708    * need to hold a ref on it until it's disconnected.
01709    */
01710   _dbus_connection_ref_unlocked (connection);
01711 
01712   if (guid == NULL)
01713     {
01714       if (!_DBUS_LOCK (shared_connections))
01715         return FALSE;
01716 
01717       if (!_dbus_list_prepend (&shared_connections_no_guid, connection))
01718         {
01719           _DBUS_UNLOCK (shared_connections);
01720           return FALSE;
01721         }
01722 
01723       _DBUS_UNLOCK (shared_connections);
01724       return TRUE; /* don't store in the hash */
01725     }
01726   
01727   /* A separate copy of the key is required in the hash table, because
01728    * we don't have a lock on the connection when we are doing a hash
01729    * lookup.
01730    */
01731   
01732   guid_key = _dbus_strdup (guid);
01733   if (guid_key == NULL)
01734     return FALSE;
01735 
01736   guid_in_connection = _dbus_strdup (guid);
01737   if (guid_in_connection == NULL)
01738     {
01739       dbus_free (guid_key);
01740       return FALSE;
01741     }
01742 
01743   if (!_DBUS_LOCK (shared_connections))
01744     {
01745       dbus_free (guid_in_connection);
01746       dbus_free (guid_key);
01747       return FALSE;
01748     }
01749 
01750   _dbus_assert (shared_connections != NULL);
01751   
01752   if (!_dbus_hash_table_insert_string (shared_connections,
01753                                        guid_key, connection))
01754     {
01755       dbus_free (guid_key);
01756       dbus_free (guid_in_connection);
01757       _DBUS_UNLOCK (shared_connections);
01758       return FALSE;
01759     }
01760 
01761   connection->server_guid = guid_in_connection;
01762 
01763   _dbus_verbose ("stored connection to %s to be shared\n",
01764                  connection->server_guid);
01765   
01766   _DBUS_UNLOCK (shared_connections);
01767 
01768   _dbus_assert (connection->server_guid != NULL);
01769   
01770   return TRUE;
01771 }
01772 
01773 static void
01774 connection_forget_shared_unlocked (DBusConnection *connection)
01775 {
01776   HAVE_LOCK_CHECK (connection);
01777 
01778   if (!connection->shareable)
01779     return;
01780 
01781   if (!_DBUS_LOCK (shared_connections))
01782     {
01783       /* If it was shared, we'd have initialized global locks when we put
01784        * it in the table; so it can't be there. */
01785       return;
01786     }
01787 
01788   if (connection->server_guid != NULL)
01789     {
01790       _dbus_verbose ("dropping connection to %s out of the shared table\n",
01791                      connection->server_guid);
01792       
01793       if (!_dbus_hash_table_remove_string (shared_connections,
01794                                            connection->server_guid))
01795         _dbus_assert_not_reached ("connection was not in the shared table");
01796       
01797       dbus_free (connection->server_guid);
01798       connection->server_guid = NULL;
01799     }
01800   else
01801     {
01802       _dbus_list_remove (&shared_connections_no_guid, connection);
01803     }
01804 
01805   _DBUS_UNLOCK (shared_connections);
01806   
01807   /* remove our reference held on all shareable connections */
01808   _dbus_connection_unref_unlocked (connection);
01809 }
01810 
01811 static DBusConnection*
01812 connection_try_from_address_entry (DBusAddressEntry *entry,
01813                                    DBusError        *error)
01814 {
01815   DBusTransport *transport;
01816   DBusConnection *connection;
01817 
01818   transport = _dbus_transport_open (entry, error);
01819 
01820   if (transport == NULL)
01821     {
01822       _DBUS_ASSERT_ERROR_IS_SET (error);
01823       return NULL;
01824     }
01825 
01826   connection = _dbus_connection_new_for_transport (transport);
01827 
01828   _dbus_transport_unref (transport);
01829   
01830   if (connection == NULL)
01831     {
01832       _DBUS_SET_OOM (error);
01833       return NULL;
01834     }
01835 
01836 #ifndef DBUS_DISABLE_CHECKS
01837   _dbus_assert (!connection->have_connection_lock);
01838 #endif
01839   return connection;
01840 }
01841 
01842 /*
01843  * If the shared parameter is true, then any existing connection will
01844  * be used (and if a new connection is created, it will be available
01845  * for use by others). If the shared parameter is false, a new
01846  * connection will always be created, and the new connection will
01847  * never be returned to other callers.
01848  *
01849  * @param address the address
01850  * @param shared whether the connection is shared or private
01851  * @param error error return
01852  * @returns the connection or #NULL on error
01853  */
01854 static DBusConnection*
01855 _dbus_connection_open_internal (const char     *address,
01856                                 dbus_bool_t     shared,
01857                                 DBusError      *error)
01858 {
01859   DBusConnection *connection;
01860   DBusAddressEntry **entries;
01861   DBusError tmp_error = DBUS_ERROR_INIT;
01862   DBusError first_error = DBUS_ERROR_INIT;
01863   int len, i;
01864 
01865   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01866 
01867   _dbus_verbose ("opening %s connection to: %s\n",
01868                  shared ? "shared" : "private", address);
01869   
01870   if (!dbus_parse_address (address, &entries, &len, error))
01871     return NULL;
01872 
01873   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01874   
01875   connection = NULL;
01876 
01877   for (i = 0; i < len; i++)
01878     {
01879       if (shared)
01880         {
01881           if (!connection_lookup_shared (entries[i], &connection))
01882             _DBUS_SET_OOM (&tmp_error);
01883         }
01884 
01885       if (connection == NULL)
01886         {
01887           connection = connection_try_from_address_entry (entries[i],
01888                                                           &tmp_error);
01889 
01890           if (connection != NULL && shared)
01891             {
01892               const char *guid;
01893                   
01894               connection->shareable = TRUE;
01895                   
01896               /* guid may be NULL */
01897               guid = dbus_address_entry_get_value (entries[i], "guid");
01898                   
01899               CONNECTION_LOCK (connection);
01900           
01901               if (!connection_record_shared_unlocked (connection, guid))
01902                 {
01903                   _DBUS_SET_OOM (&tmp_error);
01904                   _dbus_connection_close_possibly_shared_and_unlock (connection);
01905                   dbus_connection_unref (connection);
01906                   connection = NULL;
01907                 }
01908               else
01909                 CONNECTION_UNLOCK (connection);
01910             }
01911         }
01912       
01913       if (connection)
01914         break;
01915 
01916       _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
01917       
01918       if (i == 0)
01919         dbus_move_error (&tmp_error, &first_error);
01920       else
01921         dbus_error_free (&tmp_error);
01922     }
01923   
01924   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01925   _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
01926   
01927   if (connection == NULL)
01928     {
01929       _DBUS_ASSERT_ERROR_IS_SET (&first_error);
01930       dbus_move_error (&first_error, error);
01931     }
01932   else
01933     dbus_error_free (&first_error);
01934   
01935   dbus_address_entries_free (entries);
01936   return connection;
01937 }
01938 
01947 void
01948 _dbus_connection_close_possibly_shared (DBusConnection *connection)
01949 {
01950   _dbus_assert (connection != NULL);
01951   _dbus_assert (connection->generation == _dbus_current_generation);
01952 
01953   CONNECTION_LOCK (connection);
01954   _dbus_connection_close_possibly_shared_and_unlock (connection);
01955 }
01956 
01957 static DBusPreallocatedSend*
01958 _dbus_connection_preallocate_send_unlocked (DBusConnection *connection)
01959 {
01960   DBusPreallocatedSend *preallocated;
01961 
01962   HAVE_LOCK_CHECK (connection);
01963   
01964   _dbus_assert (connection != NULL);
01965   
01966   preallocated = dbus_new (DBusPreallocatedSend, 1);
01967   if (preallocated == NULL)
01968     return NULL;
01969 
01970   preallocated->queue_link = _dbus_list_alloc_link (NULL);
01971   if (preallocated->queue_link == NULL)
01972     goto failed_0;
01973 
01974   preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter);
01975   if (preallocated->counter_link == NULL)
01976     goto failed_1;
01977 
01978   _dbus_counter_ref (preallocated->counter_link->data);
01979 
01980   preallocated->connection = connection;
01981   
01982   return preallocated;
01983   
01984  failed_1:
01985   _dbus_list_free_link (preallocated->queue_link);
01986  failed_0:
01987   dbus_free (preallocated);
01988   
01989   return NULL;
01990 }
01991 
01992 /* Called with lock held, does not update dispatch status */
01993 static void
01994 _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection       *connection,
01995                                                        DBusPreallocatedSend *preallocated,
01996                                                        DBusMessage          *message,
01997                                                        dbus_uint32_t        *client_serial)
01998 {
01999   dbus_uint32_t serial;
02000 
02001   preallocated->queue_link->data = message;
02002   _dbus_list_prepend_link (&connection->outgoing_messages,
02003                            preallocated->queue_link);
02004 
02005   /* It's OK that we'll never call the notify function, because for the
02006    * outgoing limit, there isn't one */
02007   _dbus_message_add_counter_link (message,
02008                                   preallocated->counter_link);
02009 
02010   dbus_free (preallocated);
02011   preallocated = NULL;
02012   
02013   dbus_message_ref (message);
02014   
02015   connection->n_outgoing += 1;
02016 
02017   _dbus_verbose ("Message %p (%s %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
02018                  message,
02019                  dbus_message_type_to_string (dbus_message_get_type (message)),
02020                  dbus_message_get_path (message) ?
02021                  dbus_message_get_path (message) :
02022                  "no path",
02023                  dbus_message_get_interface (message) ?
02024                  dbus_message_get_interface (message) :
02025                  "no interface",
02026                  dbus_message_get_member (message) ?
02027                  dbus_message_get_member (message) :
02028                  "no member",
02029                  dbus_message_get_signature (message),
02030                  dbus_message_get_destination (message) ?
02031                  dbus_message_get_destination (message) :
02032                  "null",
02033                  connection,
02034                  connection->n_outgoing);
02035 
02036   if (dbus_message_get_serial (message) == 0)
02037     {
02038       serial = _dbus_connection_get_next_client_serial (connection);
02039       dbus_message_set_serial (message, serial);
02040       if (client_serial)
02041         *client_serial = serial;
02042     }
02043   else
02044     {
02045       if (client_serial)
02046         *client_serial = dbus_message_get_serial (message);
02047     }
02048 
02049   _dbus_verbose ("Message %p serial is %u\n",
02050                  message, dbus_message_get_serial (message));
02051   
02052   dbus_message_lock (message);
02053 
02054   /* Now we need to run an iteration to hopefully just write the messages
02055    * out immediately, and otherwise get them queued up
02056    */
02057   _dbus_connection_do_iteration_unlocked (connection,
02058                                           NULL,
02059                                           DBUS_ITERATION_DO_WRITING,
02060                                           -1);
02061 
02062   /* If stuff is still queued up, be sure we wake up the main loop */
02063   if (connection->n_outgoing > 0)
02064     _dbus_connection_wakeup_mainloop (connection);
02065 }
02066 
02067 static void
02068 _dbus_connection_send_preallocated_and_unlock (DBusConnection       *connection,
02069                                                DBusPreallocatedSend *preallocated,
02070                                                DBusMessage          *message,
02071                                                dbus_uint32_t        *client_serial)
02072 {
02073   DBusDispatchStatus status;
02074 
02075   HAVE_LOCK_CHECK (connection);
02076   
02077   _dbus_connection_send_preallocated_unlocked_no_update (connection,
02078                                                          preallocated,
02079                                                          message, client_serial);
02080 
02081   _dbus_verbose ("middle\n");
02082   status = _dbus_connection_get_dispatch_status_unlocked (connection);
02083 
02084   /* this calls out to user code */
02085   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02086 }
02087 
02097 dbus_bool_t
02098 _dbus_connection_send_and_unlock (DBusConnection *connection,
02099                                   DBusMessage    *message,
02100                                   dbus_uint32_t  *client_serial)
02101 {
02102   DBusPreallocatedSend *preallocated;
02103 
02104   _dbus_assert (connection != NULL);
02105   _dbus_assert (message != NULL);
02106   
02107   preallocated = _dbus_connection_preallocate_send_unlocked (connection);
02108   if (preallocated == NULL)
02109     {
02110       CONNECTION_UNLOCK (connection);
02111       return FALSE;
02112     }
02113 
02114   _dbus_connection_send_preallocated_and_unlock (connection,
02115                                                  preallocated,
02116                                                  message,
02117                                                  client_serial);
02118   return TRUE;
02119 }
02120 
02145 void
02146 _dbus_connection_close_if_only_one_ref (DBusConnection *connection)
02147 {
02148   dbus_int32_t refcount;
02149 
02150   CONNECTION_LOCK (connection);
02151 
02152   refcount = _dbus_atomic_get (&connection->refcount);
02153   /* The caller should have at least one ref */
02154   _dbus_assert (refcount >= 1);
02155 
02156   if (refcount == 1)
02157     _dbus_connection_close_possibly_shared_and_unlock (connection);
02158   else
02159     CONNECTION_UNLOCK (connection);
02160 }
02161 
02162 
02172 static void
02173 _dbus_memory_pause_based_on_timeout (int timeout_milliseconds)
02174 {
02175   if (timeout_milliseconds == -1)
02176     _dbus_sleep_milliseconds (1000);
02177   else if (timeout_milliseconds < 100)
02178     ; /* just busy loop */
02179   else if (timeout_milliseconds <= 1000)
02180     _dbus_sleep_milliseconds (timeout_milliseconds / 3);
02181   else
02182     _dbus_sleep_milliseconds (1000);
02183 }
02184 
02185 static DBusMessage *
02186 generate_local_error_message (dbus_uint32_t serial, 
02187                               char *error_name, 
02188                               char *error_msg)
02189 {
02190   DBusMessage *message;
02191   message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
02192   if (!message)
02193     goto out;
02194 
02195   if (!dbus_message_set_error_name (message, error_name))
02196     {
02197       dbus_message_unref (message);
02198       message = NULL;
02199       goto out; 
02200     }
02201 
02202   dbus_message_set_no_reply (message, TRUE); 
02203 
02204   if (!dbus_message_set_reply_serial (message,
02205                                       serial))
02206     {
02207       dbus_message_unref (message);
02208       message = NULL;
02209       goto out;
02210     }
02211 
02212   if (error_msg != NULL)
02213     {
02214       DBusMessageIter iter;
02215 
02216       dbus_message_iter_init_append (message, &iter);
02217       if (!dbus_message_iter_append_basic (&iter,
02218                                            DBUS_TYPE_STRING,
02219                                            &error_msg))
02220         {
02221           dbus_message_unref (message);
02222           message = NULL;
02223           goto out;
02224         }
02225     }
02226 
02227  out:
02228   return message;
02229 }
02230 
02231 /*
02232  * Peek the incoming queue to see if we got reply for a specific serial
02233  */
02234 static dbus_bool_t
02235 _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection,
02236                                           dbus_uint32_t   client_serial)
02237 {
02238   DBusList *link;
02239   HAVE_LOCK_CHECK (connection);
02240 
02241   link = _dbus_list_get_first_link (&connection->incoming_messages);
02242 
02243   while (link != NULL)
02244     {
02245       DBusMessage *reply = link->data;
02246 
02247       if (dbus_message_get_reply_serial (reply) == client_serial)
02248         {
02249           _dbus_verbose ("%s reply to %d found in queue\n", _DBUS_FUNCTION_NAME, client_serial);
02250           return TRUE;
02251         }
02252       link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02253     }
02254 
02255   return FALSE;
02256 }
02257 
02258 /* This is slightly strange since we can pop a message here without
02259  * the dispatch lock.
02260  */
02261 static DBusMessage*
02262 check_for_reply_unlocked (DBusConnection *connection,
02263                           dbus_uint32_t   client_serial)
02264 {
02265   DBusList *link;
02266 
02267   HAVE_LOCK_CHECK (connection);
02268   
02269   link = _dbus_list_get_first_link (&connection->incoming_messages);
02270 
02271   while (link != NULL)
02272     {
02273       DBusMessage *reply = link->data;
02274 
02275       if (dbus_message_get_reply_serial (reply) == client_serial)
02276         {
02277           _dbus_list_remove_link (&connection->incoming_messages, link);
02278           connection->n_incoming  -= 1;
02279           return reply;
02280         }
02281       link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02282     }
02283 
02284   return NULL;
02285 }
02286 
02287 static void
02288 connection_timeout_and_complete_all_pending_calls_unlocked (DBusConnection *connection)
02289 {
02290    /* We can't iterate over the hash in the normal way since we'll be
02291     * dropping the lock for each item. So we restart the
02292     * iter each time as we drain the hash table.
02293     */
02294    
02295    while (_dbus_hash_table_get_n_entries (connection->pending_replies) > 0)
02296     {
02297       DBusPendingCall *pending;
02298       DBusHashIter iter;
02299       
02300       _dbus_hash_iter_init (connection->pending_replies, &iter);
02301       _dbus_hash_iter_next (&iter);
02302        
02303       pending = _dbus_hash_iter_get_value (&iter);
02304       _dbus_pending_call_ref_unlocked (pending);
02305        
02306       _dbus_pending_call_queue_timeout_error_unlocked (pending, 
02307                                                        connection);
02308 
02309       if (_dbus_pending_call_is_timeout_added_unlocked (pending))
02310           _dbus_connection_remove_timeout_unlocked (connection,
02311                                                     _dbus_pending_call_get_timeout_unlocked (pending));
02312       _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);       
02313       _dbus_hash_iter_remove_entry (&iter);
02314 
02315       _dbus_pending_call_unref_and_unlock (pending);
02316       CONNECTION_LOCK (connection);
02317     }
02318   HAVE_LOCK_CHECK (connection);
02319 }
02320 
02321 static void
02322 complete_pending_call_and_unlock (DBusConnection  *connection,
02323                                   DBusPendingCall *pending,
02324                                   DBusMessage     *message)
02325 {
02326   _dbus_pending_call_set_reply_unlocked (pending, message);
02327   _dbus_pending_call_ref_unlocked (pending); /* in case there's no app with a ref held */
02328   _dbus_connection_detach_pending_call_and_unlock (connection, pending);
02329  
02330   /* Must be called unlocked since it invokes app callback */
02331   _dbus_pending_call_complete (pending);
02332   dbus_pending_call_unref (pending);
02333 }
02334 
02335 static dbus_bool_t
02336 check_for_reply_and_update_dispatch_unlocked (DBusConnection  *connection,
02337                                               DBusPendingCall *pending)
02338 {
02339   DBusMessage *reply;
02340   DBusDispatchStatus status;
02341 
02342   reply = check_for_reply_unlocked (connection, 
02343                                     _dbus_pending_call_get_reply_serial_unlocked (pending));
02344   if (reply != NULL)
02345     {
02346       _dbus_verbose ("checked for reply\n");
02347 
02348       _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
02349 
02350       complete_pending_call_and_unlock (connection, pending, reply);
02351       dbus_message_unref (reply);
02352 
02353       CONNECTION_LOCK (connection);
02354       status = _dbus_connection_get_dispatch_status_unlocked (connection);
02355       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02356       dbus_pending_call_unref (pending);
02357 
02358       return TRUE;
02359     }
02360 
02361   return FALSE;
02362 }
02363 
02378 void
02379 _dbus_connection_block_pending_call (DBusPendingCall *pending)
02380 {
02381   long start_tv_sec, start_tv_usec;
02382   long tv_sec, tv_usec;
02383   DBusDispatchStatus status;
02384   DBusConnection *connection;
02385   dbus_uint32_t client_serial;
02386   DBusTimeout *timeout;
02387   int timeout_milliseconds, elapsed_milliseconds;
02388 
02389   _dbus_assert (pending != NULL);
02390 
02391   if (dbus_pending_call_get_completed (pending))
02392     return;
02393 
02394   dbus_pending_call_ref (pending); /* necessary because the call could be canceled */
02395 
02396   connection = _dbus_pending_call_get_connection_and_lock (pending);
02397   
02398   /* Flush message queue - note, can affect dispatch status */
02399   _dbus_connection_flush_unlocked (connection);
02400 
02401   client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
02402 
02403   /* note that timeout_milliseconds is limited to a smallish value
02404    * in _dbus_pending_call_new() so overflows aren't possible
02405    * below
02406    */
02407   timeout = _dbus_pending_call_get_timeout_unlocked (pending);
02408   _dbus_get_monotonic_time (&start_tv_sec, &start_tv_usec);
02409   if (timeout)
02410     {
02411       timeout_milliseconds = dbus_timeout_get_interval (timeout);
02412 
02413       _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec\n",
02414                      timeout_milliseconds,
02415                      client_serial,
02416                      start_tv_sec, start_tv_usec);
02417     }
02418   else
02419     {
02420       timeout_milliseconds = -1;
02421 
02422       _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block for reply serial %u\n", client_serial);
02423     }
02424 
02425   /* check to see if we already got the data off the socket */
02426   /* from another blocked pending call */
02427   if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02428     return;
02429 
02430   /* Now we wait... */
02431   /* always block at least once as we know we don't have the reply yet */
02432   _dbus_connection_do_iteration_unlocked (connection,
02433                                           pending,
02434                                           DBUS_ITERATION_DO_READING |
02435                                           DBUS_ITERATION_BLOCK,
02436                                           timeout_milliseconds);
02437 
02438  recheck_status:
02439 
02440   _dbus_verbose ("top of recheck\n");
02441   
02442   HAVE_LOCK_CHECK (connection);
02443   
02444   /* queue messages and get status */
02445 
02446   status = _dbus_connection_get_dispatch_status_unlocked (connection);
02447 
02448   /* the get_completed() is in case a dispatch() while we were blocking
02449    * got the reply instead of us.
02450    */
02451   if (_dbus_pending_call_get_completed_unlocked (pending))
02452     {
02453       _dbus_verbose ("Pending call completed by dispatch\n");
02454       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02455       dbus_pending_call_unref (pending);
02456       return;
02457     }
02458   
02459   if (status == DBUS_DISPATCH_DATA_REMAINS)
02460     {
02461       if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02462         return;
02463     }
02464   
02465   _dbus_get_monotonic_time (&tv_sec, &tv_usec);
02466   elapsed_milliseconds = (tv_sec - start_tv_sec) * 1000 +
02467           (tv_usec - start_tv_usec) / 1000;
02468   
02469   if (!_dbus_connection_get_is_connected_unlocked (connection))
02470     {
02471       DBusMessage *error_msg;
02472 
02473       error_msg = generate_local_error_message (client_serial,
02474                                                 DBUS_ERROR_DISCONNECTED, 
02475                                                 "Connection was disconnected before a reply was received"); 
02476 
02477       /* on OOM error_msg is set to NULL */
02478       complete_pending_call_and_unlock (connection, pending, error_msg);
02479       dbus_pending_call_unref (pending);
02480       return;
02481     }
02482   else if (connection->disconnect_message_link == NULL)
02483     _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
02484   else if (timeout == NULL)
02485     {
02486        if (status == DBUS_DISPATCH_NEED_MEMORY)
02487         {
02488           /* Try sleeping a bit, as we aren't sure we need to block for reading,
02489            * we may already have a reply in the buffer and just can't process
02490            * it.
02491            */
02492           _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02493 
02494           _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
02495         }
02496       else
02497         {          
02498           /* block again, we don't have the reply buffered yet. */
02499           _dbus_connection_do_iteration_unlocked (connection,
02500                                                   pending,
02501                                                   DBUS_ITERATION_DO_READING |
02502                                                   DBUS_ITERATION_BLOCK,
02503                                                   timeout_milliseconds - elapsed_milliseconds);
02504         }
02505 
02506       goto recheck_status;
02507     }
02508   else if (tv_sec < start_tv_sec)
02509     _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
02510   else if (elapsed_milliseconds < timeout_milliseconds)
02511     {
02512       _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds - elapsed_milliseconds);
02513       
02514       if (status == DBUS_DISPATCH_NEED_MEMORY)
02515         {
02516           /* Try sleeping a bit, as we aren't sure we need to block for reading,
02517            * we may already have a reply in the buffer and just can't process
02518            * it.
02519            */
02520           _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02521 
02522           _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
02523         }
02524       else
02525         {          
02526           /* block again, we don't have the reply buffered yet. */
02527           _dbus_connection_do_iteration_unlocked (connection,
02528                                                   NULL,
02529                                                   DBUS_ITERATION_DO_READING |
02530                                                   DBUS_ITERATION_BLOCK,
02531                                                   timeout_milliseconds - elapsed_milliseconds);
02532         }
02533 
02534       goto recheck_status;
02535     }
02536 
02537   _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %d milliseconds and got no reply\n",
02538                  elapsed_milliseconds);
02539 
02540   _dbus_assert (!_dbus_pending_call_get_completed_unlocked (pending));
02541   
02542   /* unlock and call user code */
02543   complete_pending_call_and_unlock (connection, pending, NULL);
02544 
02545   /* update user code on dispatch status */
02546   CONNECTION_LOCK (connection);
02547   status = _dbus_connection_get_dispatch_status_unlocked (connection);
02548   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02549   dbus_pending_call_unref (pending);
02550 }
02551 
02557 int
02558 _dbus_connection_get_pending_fds_count (DBusConnection *connection)
02559 {
02560   return _dbus_transport_get_pending_fds_count (connection->transport);
02561 }
02562 
02570 void
02571 _dbus_connection_set_pending_fds_function (DBusConnection *connection,
02572                                            DBusPendingFdsChangeFunction callback,
02573                                            void *data)
02574 {
02575   _dbus_transport_set_pending_fds_function (connection->transport,
02576                                             callback, data);
02577 }
02578 
02615 DBusConnection*
02616 dbus_connection_open (const char     *address,
02617                       DBusError      *error)
02618 {
02619   DBusConnection *connection;
02620 
02621   _dbus_return_val_if_fail (address != NULL, NULL);
02622   _dbus_return_val_if_error_is_set (error, NULL);
02623 
02624   connection = _dbus_connection_open_internal (address,
02625                                                TRUE,
02626                                                error);
02627 
02628   return connection;
02629 }
02630 
02658 DBusConnection*
02659 dbus_connection_open_private (const char     *address,
02660                               DBusError      *error)
02661 {
02662   DBusConnection *connection;
02663 
02664   _dbus_return_val_if_fail (address != NULL, NULL);
02665   _dbus_return_val_if_error_is_set (error, NULL);
02666 
02667   connection = _dbus_connection_open_internal (address,
02668                                                FALSE,
02669                                                error);
02670 
02671   return connection;
02672 }
02673 
02680 DBusConnection *
02681 dbus_connection_ref (DBusConnection *connection)
02682 {
02683   dbus_int32_t old_refcount;
02684 
02685   _dbus_return_val_if_fail (connection != NULL, NULL);
02686   _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
02687   old_refcount = _dbus_atomic_inc (&connection->refcount);
02688   _dbus_connection_trace_ref (connection, old_refcount, old_refcount + 1,
02689       "ref");
02690 
02691   return connection;
02692 }
02693 
02694 static void
02695 free_outgoing_message (void *element,
02696                        void *data)
02697 {
02698   DBusMessage *message = element;
02699   DBusConnection *connection = data;
02700 
02701   _dbus_message_remove_counter (message, connection->outgoing_counter);
02702   dbus_message_unref (message);
02703 }
02704 
02705 /* This is run without the mutex held, but after the last reference
02706  * to the connection has been dropped we should have no thread-related
02707  * problems
02708  */
02709 static void
02710 _dbus_connection_last_unref (DBusConnection *connection)
02711 {
02712   DBusList *link;
02713 
02714   _dbus_verbose ("Finalizing connection %p\n", connection);
02715 
02716   _dbus_assert (_dbus_atomic_get (&connection->refcount) == 0);
02717 
02718   /* You have to disconnect the connection before unref:ing it. Otherwise
02719    * you won't get the disconnected message.
02720    */
02721   _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
02722   _dbus_assert (connection->server_guid == NULL);
02723   
02724   /* ---- We're going to call various application callbacks here, hope it doesn't break anything... */
02725   _dbus_object_tree_free_all_unlocked (connection->objects);
02726   
02727   dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
02728   dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
02729   dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
02730   dbus_connection_set_windows_user_function (connection, NULL, NULL, NULL);
02731   
02732   _dbus_watch_list_free (connection->watches);
02733   connection->watches = NULL;
02734   
02735   _dbus_timeout_list_free (connection->timeouts);
02736   connection->timeouts = NULL;
02737 
02738   _dbus_data_slot_list_free (&connection->slot_list);
02739   
02740   link = _dbus_list_get_first_link (&connection->filter_list);
02741   while (link != NULL)
02742     {
02743       DBusMessageFilter *filter = link->data;
02744       DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
02745 
02746       filter->function = NULL;
02747       _dbus_message_filter_unref (filter); /* calls app callback */
02748       link->data = NULL;
02749       
02750       link = next;
02751     }
02752   _dbus_list_clear (&connection->filter_list);
02753   
02754   /* ---- Done with stuff that invokes application callbacks */
02755 
02756   _dbus_object_tree_unref (connection->objects);  
02757 
02758   _dbus_hash_table_unref (connection->pending_replies);
02759   connection->pending_replies = NULL;
02760   
02761   _dbus_list_clear (&connection->filter_list);
02762   
02763   _dbus_list_foreach (&connection->outgoing_messages,
02764                       free_outgoing_message,
02765                       connection);
02766   _dbus_list_clear (&connection->outgoing_messages);
02767   
02768   _dbus_list_foreach (&connection->incoming_messages,
02769                       (DBusForeachFunction) dbus_message_unref,
02770                       NULL);
02771   _dbus_list_clear (&connection->incoming_messages);
02772 
02773   _dbus_counter_unref (connection->outgoing_counter);
02774 
02775   _dbus_transport_unref (connection->transport);
02776 
02777   if (connection->disconnect_message_link)
02778     {
02779       DBusMessage *message = connection->disconnect_message_link->data;
02780       dbus_message_unref (message);
02781       _dbus_list_free_link (connection->disconnect_message_link);
02782     }
02783 
02784   _dbus_condvar_free_at_location (&connection->dispatch_cond);
02785   _dbus_condvar_free_at_location (&connection->io_path_cond);
02786 
02787   _dbus_cmutex_free_at_location (&connection->io_path_mutex);
02788   _dbus_cmutex_free_at_location (&connection->dispatch_mutex);
02789 
02790   _dbus_rmutex_free_at_location (&connection->slot_mutex);
02791 
02792   _dbus_rmutex_free_at_location (&connection->mutex);
02793   
02794   dbus_free (connection);
02795 }
02796 
02816 void
02817 dbus_connection_unref (DBusConnection *connection)
02818 {
02819   dbus_int32_t old_refcount;
02820 
02821   _dbus_return_if_fail (connection != NULL);
02822   _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02823 
02824   old_refcount = _dbus_atomic_dec (&connection->refcount);
02825 
02826   _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1,
02827       "unref");
02828 
02829   if (old_refcount == 1)
02830     {
02831 #ifndef DBUS_DISABLE_CHECKS
02832       if (_dbus_transport_get_is_connected (connection->transport))
02833         {
02834           _dbus_warn_check_failed ("The last reference on a connection was dropped without closing the connection. This is a bug in an application. See dbus_connection_unref() documentation for details.\n%s",
02835                                    connection->shareable ?
02836                                    "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" : 
02837                                     "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n");
02838           return;
02839         }
02840 #endif
02841       _dbus_connection_last_unref (connection);
02842     }
02843 }
02844 
02845 /*
02846  * Note that the transport can disconnect itself (other end drops us)
02847  * and in that case this function never runs. So this function must
02848  * not do anything more than disconnect the transport and update the
02849  * dispatch status.
02850  * 
02851  * If the transport self-disconnects, then we assume someone will
02852  * dispatch the connection to cause the dispatch status update.
02853  */
02854 static void
02855 _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection)
02856 {
02857   DBusDispatchStatus status;
02858 
02859   HAVE_LOCK_CHECK (connection);
02860   
02861   _dbus_verbose ("Disconnecting %p\n", connection);
02862 
02863   /* We need to ref because update_dispatch_status_and_unlock will unref
02864    * the connection if it was shared and libdbus was the only remaining
02865    * refcount holder.
02866    */
02867   _dbus_connection_ref_unlocked (connection);
02868   
02869   _dbus_transport_disconnect (connection->transport);
02870 
02871   /* This has the side effect of queuing the disconnect message link
02872    * (unless we don't have enough memory, possibly, so don't assert it).
02873    * After the disconnect message link is queued, dbus_bus_get/dbus_connection_open
02874    * should never again return the newly-disconnected connection.
02875    *
02876    * However, we only unref the shared connection and exit_on_disconnect when
02877    * the disconnect message reaches the head of the message queue,
02878    * NOT when it's first queued.
02879    */
02880   status = _dbus_connection_get_dispatch_status_unlocked (connection);
02881 
02882   /* This calls out to user code */
02883   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02884 
02885   /* Could also call out to user code */
02886   dbus_connection_unref (connection);
02887 }
02888 
02931 void
02932 dbus_connection_close (DBusConnection *connection)
02933 {
02934   _dbus_return_if_fail (connection != NULL);
02935   _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02936 
02937   CONNECTION_LOCK (connection);
02938 
02939 #ifndef DBUS_DISABLE_CHECKS
02940   if (connection->shareable)
02941     {
02942       CONNECTION_UNLOCK (connection);
02943 
02944       _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n");
02945       return;
02946     }
02947 #endif
02948   
02949   _dbus_connection_close_possibly_shared_and_unlock (connection);
02950 }
02951 
02952 static dbus_bool_t
02953 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
02954 {
02955   HAVE_LOCK_CHECK (connection);
02956   return _dbus_transport_get_is_connected (connection->transport);
02957 }
02958 
02972 dbus_bool_t
02973 dbus_connection_get_is_connected (DBusConnection *connection)
02974 {
02975   dbus_bool_t res;
02976 
02977   _dbus_return_val_if_fail (connection != NULL, FALSE);
02978   
02979   CONNECTION_LOCK (connection);
02980   res = _dbus_connection_get_is_connected_unlocked (connection);
02981   CONNECTION_UNLOCK (connection);
02982   
02983   return res;
02984 }
02985 
02994 dbus_bool_t
02995 dbus_connection_get_is_authenticated (DBusConnection *connection)
02996 {
02997   dbus_bool_t res;
02998 
02999   _dbus_return_val_if_fail (connection != NULL, FALSE);
03000 
03001   CONNECTION_LOCK (connection);
03002   res = _dbus_transport_try_to_authenticate (connection->transport);
03003   CONNECTION_UNLOCK (connection);
03004   
03005   return res;
03006 }
03007 
03028 dbus_bool_t
03029 dbus_connection_get_is_anonymous (DBusConnection *connection)
03030 {
03031   dbus_bool_t res;
03032 
03033   _dbus_return_val_if_fail (connection != NULL, FALSE);
03034   
03035   CONNECTION_LOCK (connection);
03036   res = _dbus_transport_get_is_anonymous (connection->transport);
03037   CONNECTION_UNLOCK (connection);
03038   
03039   return res;
03040 }
03041 
03073 char*
03074 dbus_connection_get_server_id (DBusConnection *connection)
03075 {
03076   char *id;
03077 
03078   _dbus_return_val_if_fail (connection != NULL, NULL);
03079 
03080   CONNECTION_LOCK (connection);
03081   id = _dbus_strdup (_dbus_transport_get_server_id (connection->transport));
03082   CONNECTION_UNLOCK (connection);
03083 
03084   return id;
03085 }
03086 
03104 dbus_bool_t
03105 dbus_connection_can_send_type(DBusConnection *connection,
03106                                   int type)
03107 {
03108   _dbus_return_val_if_fail (connection != NULL, FALSE);
03109 
03110   if (!dbus_type_is_valid (type))
03111     return FALSE;
03112 
03113   if (type != DBUS_TYPE_UNIX_FD)
03114     return TRUE;
03115 
03116 #ifdef HAVE_UNIX_FD_PASSING
03117   {
03118     dbus_bool_t b;
03119 
03120     CONNECTION_LOCK(connection);
03121     b = _dbus_transport_can_pass_unix_fd(connection->transport);
03122     CONNECTION_UNLOCK(connection);
03123 
03124     return b;
03125   }
03126 #endif
03127 
03128   return FALSE;
03129 }
03130 
03144 void
03145 dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
03146                                         dbus_bool_t     exit_on_disconnect)
03147 {
03148   _dbus_return_if_fail (connection != NULL);
03149 
03150   CONNECTION_LOCK (connection);
03151   connection->exit_on_disconnect = exit_on_disconnect != FALSE;
03152   CONNECTION_UNLOCK (connection);
03153 }
03154 
03164 DBusPreallocatedSend*
03165 dbus_connection_preallocate_send (DBusConnection *connection)
03166 {
03167   DBusPreallocatedSend *preallocated;
03168 
03169   _dbus_return_val_if_fail (connection != NULL, NULL);
03170 
03171   CONNECTION_LOCK (connection);
03172   
03173   preallocated =
03174     _dbus_connection_preallocate_send_unlocked (connection);
03175 
03176   CONNECTION_UNLOCK (connection);
03177 
03178   return preallocated;
03179 }
03180 
03190 void
03191 dbus_connection_free_preallocated_send (DBusConnection       *connection,
03192                                         DBusPreallocatedSend *preallocated)
03193 {
03194   _dbus_return_if_fail (connection != NULL);
03195   _dbus_return_if_fail (preallocated != NULL);  
03196   _dbus_return_if_fail (connection == preallocated->connection);
03197 
03198   _dbus_list_free_link (preallocated->queue_link);
03199   _dbus_counter_unref (preallocated->counter_link->data);
03200   _dbus_list_free_link (preallocated->counter_link);
03201   dbus_free (preallocated);
03202 }
03203 
03216 void
03217 dbus_connection_send_preallocated (DBusConnection       *connection,
03218                                    DBusPreallocatedSend *preallocated,
03219                                    DBusMessage          *message,
03220                                    dbus_uint32_t        *client_serial)
03221 {
03222   _dbus_return_if_fail (connection != NULL);
03223   _dbus_return_if_fail (preallocated != NULL);
03224   _dbus_return_if_fail (message != NULL);
03225   _dbus_return_if_fail (preallocated->connection == connection);
03226   _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
03227                         dbus_message_get_member (message) != NULL);
03228   _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
03229                         (dbus_message_get_interface (message) != NULL &&
03230                          dbus_message_get_member (message) != NULL));
03231 
03232   CONNECTION_LOCK (connection);
03233 
03234 #ifdef HAVE_UNIX_FD_PASSING
03235 
03236   if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03237       message->n_unix_fds > 0)
03238     {
03239       /* Refuse to send fds on a connection that cannot handle
03240          them. Unfortunately we cannot return a proper error here, so
03241          the best we can is just return. */
03242       CONNECTION_UNLOCK (connection);
03243       return;
03244     }
03245 
03246 #endif
03247 
03248   _dbus_connection_send_preallocated_and_unlock (connection,
03249                                                  preallocated,
03250                                                  message, client_serial);
03251 }
03252 
03253 static dbus_bool_t
03254 _dbus_connection_send_unlocked_no_update (DBusConnection *connection,
03255                                           DBusMessage    *message,
03256                                           dbus_uint32_t  *client_serial)
03257 {
03258   DBusPreallocatedSend *preallocated;
03259 
03260   _dbus_assert (connection != NULL);
03261   _dbus_assert (message != NULL);
03262   
03263   preallocated = _dbus_connection_preallocate_send_unlocked (connection);
03264   if (preallocated == NULL)
03265     return FALSE;
03266 
03267   _dbus_connection_send_preallocated_unlocked_no_update (connection,
03268                                                          preallocated,
03269                                                          message,
03270                                                          client_serial);
03271   return TRUE;
03272 }
03273 
03301 dbus_bool_t
03302 dbus_connection_send (DBusConnection *connection,
03303                       DBusMessage    *message,
03304                       dbus_uint32_t  *serial)
03305 {
03306   _dbus_return_val_if_fail (connection != NULL, FALSE);
03307   _dbus_return_val_if_fail (message != NULL, FALSE);
03308 
03309   CONNECTION_LOCK (connection);
03310 
03311 #ifdef HAVE_UNIX_FD_PASSING
03312 
03313   if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03314       message->n_unix_fds > 0)
03315     {
03316       /* Refuse to send fds on a connection that cannot handle
03317          them. Unfortunately we cannot return a proper error here, so
03318          the best we can is just return. */
03319       CONNECTION_UNLOCK (connection);
03320       return FALSE;
03321     }
03322 
03323 #endif
03324 
03325   return _dbus_connection_send_and_unlock (connection,
03326                                            message,
03327                                            serial);
03328 }
03329 
03330 static dbus_bool_t
03331 reply_handler_timeout (void *data)
03332 {
03333   DBusConnection *connection;
03334   DBusDispatchStatus status;
03335   DBusPendingCall *pending = data;
03336 
03337   connection = _dbus_pending_call_get_connection_and_lock (pending);
03338   _dbus_connection_ref_unlocked (connection);
03339 
03340   _dbus_pending_call_queue_timeout_error_unlocked (pending, 
03341                                                    connection);
03342   _dbus_connection_remove_timeout_unlocked (connection,
03343                                             _dbus_pending_call_get_timeout_unlocked (pending));
03344   _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
03345 
03346   _dbus_verbose ("middle\n");
03347   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03348 
03349   /* Unlocks, and calls out to user code */
03350   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03351   dbus_connection_unref (connection);
03352   
03353   return TRUE;
03354 }
03355 
03398 dbus_bool_t
03399 dbus_connection_send_with_reply (DBusConnection     *connection,
03400                                  DBusMessage        *message,
03401                                  DBusPendingCall   **pending_return,
03402                                  int                 timeout_milliseconds)
03403 {
03404   DBusPendingCall *pending;
03405   dbus_int32_t serial = -1;
03406   DBusDispatchStatus status;
03407 
03408   _dbus_return_val_if_fail (connection != NULL, FALSE);
03409   _dbus_return_val_if_fail (message != NULL, FALSE);
03410   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03411 
03412   if (pending_return)
03413     *pending_return = NULL;
03414 
03415   CONNECTION_LOCK (connection);
03416 
03417 #ifdef HAVE_UNIX_FD_PASSING
03418 
03419   if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03420       message->n_unix_fds > 0)
03421     {
03422       /* Refuse to send fds on a connection that cannot handle
03423          them. Unfortunately we cannot return a proper error here, so
03424          the best we can do is return TRUE but leave *pending_return
03425          as NULL. */
03426       CONNECTION_UNLOCK (connection);
03427       return TRUE;
03428     }
03429 
03430 #endif
03431 
03432    if (!_dbus_connection_get_is_connected_unlocked (connection))
03433     {
03434       CONNECTION_UNLOCK (connection);
03435 
03436       return TRUE;
03437     }
03438 
03439   pending = _dbus_pending_call_new_unlocked (connection,
03440                                              timeout_milliseconds,
03441                                              reply_handler_timeout);
03442 
03443   if (pending == NULL)
03444     {
03445       CONNECTION_UNLOCK (connection);
03446       return FALSE;
03447     }
03448 
03449   /* Assign a serial to the message */
03450   serial = dbus_message_get_serial (message);
03451   if (serial == 0)
03452     {
03453       serial = _dbus_connection_get_next_client_serial (connection);
03454       dbus_message_set_serial (message, serial);
03455     }
03456 
03457   if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
03458     goto error;
03459     
03460   /* Insert the serial in the pending replies hash;
03461    * hash takes a refcount on DBusPendingCall.
03462    * Also, add the timeout.
03463    */
03464   if (!_dbus_connection_attach_pending_call_unlocked (connection,
03465                                                       pending))
03466     goto error;
03467  
03468   if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
03469     {
03470       _dbus_connection_detach_pending_call_and_unlock (connection,
03471                                                        pending);
03472       goto error_unlocked;
03473     }
03474 
03475   if (pending_return)
03476     *pending_return = pending; /* hand off refcount */
03477   else
03478     {
03479       _dbus_connection_detach_pending_call_unlocked (connection, pending);
03480       /* we still have a ref to the pending call in this case, we unref
03481        * after unlocking, below
03482        */
03483     }
03484 
03485   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03486 
03487   /* this calls out to user code */
03488   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03489 
03490   if (pending_return == NULL)
03491     dbus_pending_call_unref (pending);
03492   
03493   return TRUE;
03494 
03495  error:
03496   CONNECTION_UNLOCK (connection);
03497  error_unlocked:
03498   dbus_pending_call_unref (pending);
03499   return FALSE;
03500 }
03501 
03534 DBusMessage*
03535 dbus_connection_send_with_reply_and_block (DBusConnection     *connection,
03536                                            DBusMessage        *message,
03537                                            int                 timeout_milliseconds,
03538                                            DBusError          *error)
03539 {
03540   DBusMessage *reply;
03541   DBusPendingCall *pending;
03542 
03543   _dbus_return_val_if_fail (connection != NULL, NULL);
03544   _dbus_return_val_if_fail (message != NULL, NULL);
03545   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL);
03546   _dbus_return_val_if_error_is_set (error, NULL);
03547 
03548 #ifdef HAVE_UNIX_FD_PASSING
03549 
03550   CONNECTION_LOCK (connection);
03551   if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03552       message->n_unix_fds > 0)
03553     {
03554       CONNECTION_UNLOCK (connection);
03555       dbus_set_error(error, DBUS_ERROR_FAILED, "Cannot send file descriptors on this connection.");
03556       return NULL;
03557     }
03558   CONNECTION_UNLOCK (connection);
03559 
03560 #endif
03561 
03562   if (!dbus_connection_send_with_reply (connection, message,
03563                                         &pending, timeout_milliseconds))
03564     {
03565       _DBUS_SET_OOM (error);
03566       return NULL;
03567     }
03568 
03569   if (pending == NULL)
03570     {
03571       dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Connection is closed");
03572       return NULL;
03573     }
03574   
03575   dbus_pending_call_block (pending);
03576 
03577   reply = dbus_pending_call_steal_reply (pending);
03578   dbus_pending_call_unref (pending);
03579 
03580   /* call_complete_and_unlock() called from pending_call_block() should
03581    * always fill this in.
03582    */
03583   _dbus_assert (reply != NULL);
03584   
03585    if (dbus_set_error_from_message (error, reply))
03586     {
03587       dbus_message_unref (reply);
03588       return NULL;
03589     }
03590   else
03591     return reply;
03592 }
03593 
03602 static DBusDispatchStatus
03603 _dbus_connection_flush_unlocked (DBusConnection *connection)
03604 {
03605   /* We have to specify DBUS_ITERATION_DO_READING here because
03606    * otherwise we could have two apps deadlock if they are both doing
03607    * a flush(), and the kernel buffers fill up. This could change the
03608    * dispatch status.
03609    */
03610   DBusDispatchStatus status;
03611 
03612   HAVE_LOCK_CHECK (connection);
03613   
03614   while (connection->n_outgoing > 0 &&
03615          _dbus_connection_get_is_connected_unlocked (connection))
03616     {
03617       _dbus_verbose ("doing iteration in\n");
03618       HAVE_LOCK_CHECK (connection);
03619       _dbus_connection_do_iteration_unlocked (connection,
03620                                               NULL,
03621                                               DBUS_ITERATION_DO_READING |
03622                                               DBUS_ITERATION_DO_WRITING |
03623                                               DBUS_ITERATION_BLOCK,
03624                                               -1);
03625     }
03626 
03627   HAVE_LOCK_CHECK (connection);
03628   _dbus_verbose ("middle\n");
03629   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03630 
03631   HAVE_LOCK_CHECK (connection);
03632   return status;
03633 }
03634 
03640 void
03641 dbus_connection_flush (DBusConnection *connection)
03642 {
03643   /* We have to specify DBUS_ITERATION_DO_READING here because
03644    * otherwise we could have two apps deadlock if they are both doing
03645    * a flush(), and the kernel buffers fill up. This could change the
03646    * dispatch status.
03647    */
03648   DBusDispatchStatus status;
03649 
03650   _dbus_return_if_fail (connection != NULL);
03651   
03652   CONNECTION_LOCK (connection);
03653 
03654   status = _dbus_connection_flush_unlocked (connection);
03655   
03656   HAVE_LOCK_CHECK (connection);
03657   /* Unlocks and calls out to user code */
03658   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03659 
03660   _dbus_verbose ("end\n");
03661 }
03662 
03673 static dbus_bool_t
03674 _dbus_connection_read_write_dispatch (DBusConnection *connection,
03675                                      int             timeout_milliseconds, 
03676                                      dbus_bool_t     dispatch)
03677 {
03678   DBusDispatchStatus dstatus;
03679   dbus_bool_t progress_possible;
03680 
03681   /* Need to grab a ref here in case we're a private connection and
03682    * the user drops the last ref in a handler we call; see bug 
03683    * https://bugs.freedesktop.org/show_bug.cgi?id=15635
03684    */
03685   dbus_connection_ref (connection);
03686   dstatus = dbus_connection_get_dispatch_status (connection);
03687 
03688   if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
03689     {
03690       _dbus_verbose ("doing dispatch\n");
03691       dbus_connection_dispatch (connection);
03692       CONNECTION_LOCK (connection);
03693     }
03694   else if (dstatus == DBUS_DISPATCH_NEED_MEMORY)
03695     {
03696       _dbus_verbose ("pausing for memory\n");
03697       _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
03698       CONNECTION_LOCK (connection);
03699     }
03700   else
03701     {
03702       CONNECTION_LOCK (connection);
03703       if (_dbus_connection_get_is_connected_unlocked (connection))
03704         {
03705           _dbus_verbose ("doing iteration\n");
03706           _dbus_connection_do_iteration_unlocked (connection,
03707                                                   NULL,
03708                                                   DBUS_ITERATION_DO_READING |
03709                                                   DBUS_ITERATION_DO_WRITING |
03710                                                   DBUS_ITERATION_BLOCK,
03711                                                   timeout_milliseconds);
03712         }
03713     }
03714   
03715   HAVE_LOCK_CHECK (connection);
03716   /* If we can dispatch, we can make progress until the Disconnected message
03717    * has been processed; if we can only read/write, we can make progress
03718    * as long as the transport is open.
03719    */
03720   if (dispatch)
03721     progress_possible = connection->n_incoming != 0 ||
03722       connection->disconnect_message_link != NULL;
03723   else
03724     progress_possible = _dbus_connection_get_is_connected_unlocked (connection);
03725 
03726   CONNECTION_UNLOCK (connection);
03727 
03728   dbus_connection_unref (connection);
03729 
03730   return progress_possible; /* TRUE if we can make more progress */
03731 }
03732 
03733 
03768 dbus_bool_t
03769 dbus_connection_read_write_dispatch (DBusConnection *connection,
03770                                      int             timeout_milliseconds)
03771 {
03772   _dbus_return_val_if_fail (connection != NULL, FALSE);
03773   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03774    return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE);
03775 }
03776 
03800 dbus_bool_t 
03801 dbus_connection_read_write (DBusConnection *connection, 
03802                             int             timeout_milliseconds) 
03803 { 
03804   _dbus_return_val_if_fail (connection != NULL, FALSE);
03805   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03806    return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE);
03807 }
03808 
03809 /* We need to call this anytime we pop the head of the queue, and then
03810  * update_dispatch_status_and_unlock needs to be called afterward
03811  * which will "process" the disconnected message and set
03812  * disconnected_message_processed.
03813  */
03814 static void
03815 check_disconnected_message_arrived_unlocked (DBusConnection *connection,
03816                                              DBusMessage    *head_of_queue)
03817 {
03818   HAVE_LOCK_CHECK (connection);
03819 
03820   /* checking that the link is NULL is an optimization to avoid the is_signal call */
03821   if (connection->disconnect_message_link == NULL &&
03822       dbus_message_is_signal (head_of_queue,
03823                               DBUS_INTERFACE_LOCAL,
03824                               "Disconnected"))
03825     {
03826       connection->disconnected_message_arrived = TRUE;
03827     }
03828 }
03829 
03849 DBusMessage*
03850 dbus_connection_borrow_message (DBusConnection *connection)
03851 {
03852   DBusDispatchStatus status;
03853   DBusMessage *message;
03854 
03855   _dbus_return_val_if_fail (connection != NULL, NULL);
03856 
03857   _dbus_verbose ("start\n");
03858   
03859   /* this is called for the side effect that it queues
03860    * up any messages from the transport
03861    */
03862   status = dbus_connection_get_dispatch_status (connection);
03863   if (status != DBUS_DISPATCH_DATA_REMAINS)
03864     return NULL;
03865   
03866   CONNECTION_LOCK (connection);
03867 
03868   _dbus_connection_acquire_dispatch (connection);
03869 
03870   /* While a message is outstanding, the dispatch lock is held */
03871   _dbus_assert (connection->message_borrowed == NULL);
03872 
03873   connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
03874   
03875   message = connection->message_borrowed;
03876 
03877   check_disconnected_message_arrived_unlocked (connection, message);
03878   
03879   /* Note that we KEEP the dispatch lock until the message is returned */
03880   if (message == NULL)
03881     _dbus_connection_release_dispatch (connection);
03882 
03883   CONNECTION_UNLOCK (connection);
03884 
03885   _dbus_message_trace_ref (message, -1, -1, "dbus_connection_borrow_message");
03886 
03887   /* We don't update dispatch status until it's returned or stolen */
03888   
03889   return message;
03890 }
03891 
03900 void
03901 dbus_connection_return_message (DBusConnection *connection,
03902                                 DBusMessage    *message)
03903 {
03904   DBusDispatchStatus status;
03905   
03906   _dbus_return_if_fail (connection != NULL);
03907   _dbus_return_if_fail (message != NULL);
03908   _dbus_return_if_fail (message == connection->message_borrowed);
03909   _dbus_return_if_fail (connection->dispatch_acquired);
03910   
03911   CONNECTION_LOCK (connection);
03912   
03913   _dbus_assert (message == connection->message_borrowed);
03914   
03915   connection->message_borrowed = NULL;
03916 
03917   _dbus_connection_release_dispatch (connection); 
03918 
03919   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03920   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03921 
03922   _dbus_message_trace_ref (message, -1, -1, "dbus_connection_return_message");
03923 }
03924 
03934 void
03935 dbus_connection_steal_borrowed_message (DBusConnection *connection,
03936                                         DBusMessage    *message)
03937 {
03938   DBusMessage *pop_message;
03939   DBusDispatchStatus status;
03940 
03941   _dbus_return_if_fail (connection != NULL);
03942   _dbus_return_if_fail (message != NULL);
03943   _dbus_return_if_fail (message == connection->message_borrowed);
03944   _dbus_return_if_fail (connection->dispatch_acquired);
03945   
03946   CONNECTION_LOCK (connection);
03947  
03948   _dbus_assert (message == connection->message_borrowed);
03949 
03950   pop_message = _dbus_list_pop_first (&connection->incoming_messages);
03951   _dbus_assert (message == pop_message);
03952   (void) pop_message; /* unused unless asserting */
03953 
03954   connection->n_incoming -= 1;
03955  
03956   _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
03957                  message, connection->n_incoming);
03958  
03959   connection->message_borrowed = NULL;
03960 
03961   _dbus_connection_release_dispatch (connection);
03962 
03963   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03964   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03965   _dbus_message_trace_ref (message, -1, -1,
03966       "dbus_connection_steal_borrowed_message");
03967 }
03968 
03969 /* See dbus_connection_pop_message, but requires the caller to own
03970  * the lock before calling. May drop the lock while running.
03971  */
03972 static DBusList*
03973 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
03974 {
03975   HAVE_LOCK_CHECK (connection);
03976   
03977   _dbus_assert (connection->message_borrowed == NULL);
03978   
03979   if (connection->n_incoming > 0)
03980     {
03981       DBusList *link;
03982 
03983       link = _dbus_list_pop_first_link (&connection->incoming_messages);
03984       connection->n_incoming -= 1;
03985 
03986       _dbus_verbose ("Message %p (%s %s %s %s sig:'%s' serial:%u) removed from incoming queue %p, %d incoming\n",
03987                      link->data,
03988                      dbus_message_type_to_string (dbus_message_get_type (link->data)),
03989                      dbus_message_get_path (link->data) ?
03990                      dbus_message_get_path (link->data) :
03991                      "no path",
03992                      dbus_message_get_interface (link->data) ?
03993                      dbus_message_get_interface (link->data) :
03994                      "no interface",
03995                      dbus_message_get_member (link->data) ?
03996                      dbus_message_get_member (link->data) :
03997                      "no member",
03998                      dbus_message_get_signature (link->data),
03999                      dbus_message_get_serial (link->data),
04000                      connection, connection->n_incoming);
04001 
04002       _dbus_message_trace_ref (link->data, -1, -1,
04003           "_dbus_connection_pop_message_link_unlocked");
04004 
04005       check_disconnected_message_arrived_unlocked (connection, link->data);
04006       
04007       return link;
04008     }
04009   else
04010     return NULL;
04011 }
04012 
04013 /* See dbus_connection_pop_message, but requires the caller to own
04014  * the lock before calling. May drop the lock while running.
04015  */
04016 static DBusMessage*
04017 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
04018 {
04019   DBusList *link;
04020 
04021   HAVE_LOCK_CHECK (connection);
04022   
04023   link = _dbus_connection_pop_message_link_unlocked (connection);
04024 
04025   if (link != NULL)
04026     {
04027       DBusMessage *message;
04028       
04029       message = link->data;
04030       
04031       _dbus_list_free_link (link);
04032       
04033       return message;
04034     }
04035   else
04036     return NULL;
04037 }
04038 
04039 static void
04040 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
04041                                                 DBusList       *message_link)
04042 {
04043   HAVE_LOCK_CHECK (connection);
04044   
04045   _dbus_assert (message_link != NULL);
04046   /* You can't borrow a message while a link is outstanding */
04047   _dbus_assert (connection->message_borrowed == NULL);
04048   /* We had to have the dispatch lock across the pop/putback */
04049   _dbus_assert (connection->dispatch_acquired);
04050 
04051   _dbus_list_prepend_link (&connection->incoming_messages,
04052                            message_link);
04053   connection->n_incoming += 1;
04054 
04055   _dbus_verbose ("Message %p (%s %s %s '%s') put back into queue %p, %d incoming\n",
04056                  message_link->data,
04057                  dbus_message_type_to_string (dbus_message_get_type (message_link->data)),
04058                  dbus_message_get_interface (message_link->data) ?
04059                  dbus_message_get_interface (message_link->data) :
04060                  "no interface",
04061                  dbus_message_get_member (message_link->data) ?
04062                  dbus_message_get_member (message_link->data) :
04063                  "no member",
04064                  dbus_message_get_signature (message_link->data),
04065                  connection, connection->n_incoming);
04066 
04067   _dbus_message_trace_ref (message_link->data, -1, -1,
04068       "_dbus_connection_putback_message_link_unlocked");
04069 }
04070 
04090 DBusMessage*
04091 dbus_connection_pop_message (DBusConnection *connection)
04092 {
04093   DBusMessage *message;
04094   DBusDispatchStatus status;
04095 
04096   _dbus_verbose ("start\n");
04097   
04098   /* this is called for the side effect that it queues
04099    * up any messages from the transport
04100    */
04101   status = dbus_connection_get_dispatch_status (connection);
04102   if (status != DBUS_DISPATCH_DATA_REMAINS)
04103     return NULL;
04104   
04105   CONNECTION_LOCK (connection);
04106   _dbus_connection_acquire_dispatch (connection);
04107   HAVE_LOCK_CHECK (connection);
04108   
04109   message = _dbus_connection_pop_message_unlocked (connection);
04110 
04111   _dbus_verbose ("Returning popped message %p\n", message);    
04112 
04113   _dbus_connection_release_dispatch (connection);
04114 
04115   status = _dbus_connection_get_dispatch_status_unlocked (connection);
04116   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04117   
04118   return message;
04119 }
04120 
04128 static void
04129 _dbus_connection_acquire_dispatch (DBusConnection *connection)
04130 {
04131   HAVE_LOCK_CHECK (connection);
04132 
04133   _dbus_connection_ref_unlocked (connection);
04134   CONNECTION_UNLOCK (connection);
04135   
04136   _dbus_verbose ("locking dispatch_mutex\n");
04137   _dbus_cmutex_lock (connection->dispatch_mutex);
04138 
04139   while (connection->dispatch_acquired)
04140     {
04141       _dbus_verbose ("waiting for dispatch to be acquirable\n");
04142       _dbus_condvar_wait (connection->dispatch_cond, 
04143                           connection->dispatch_mutex);
04144     }
04145   
04146   _dbus_assert (!connection->dispatch_acquired);
04147 
04148   connection->dispatch_acquired = TRUE;
04149 
04150   _dbus_verbose ("unlocking dispatch_mutex\n");
04151   _dbus_cmutex_unlock (connection->dispatch_mutex);
04152   
04153   CONNECTION_LOCK (connection);
04154   _dbus_connection_unref_unlocked (connection);
04155 }
04156 
04164 static void
04165 _dbus_connection_release_dispatch (DBusConnection *connection)
04166 {
04167   HAVE_LOCK_CHECK (connection);
04168   
04169   _dbus_verbose ("locking dispatch_mutex\n");
04170   _dbus_cmutex_lock (connection->dispatch_mutex);
04171   
04172   _dbus_assert (connection->dispatch_acquired);
04173 
04174   connection->dispatch_acquired = FALSE;
04175   _dbus_condvar_wake_one (connection->dispatch_cond);
04176 
04177   _dbus_verbose ("unlocking dispatch_mutex\n");
04178   _dbus_cmutex_unlock (connection->dispatch_mutex);
04179 }
04180 
04181 static void
04182 _dbus_connection_failed_pop (DBusConnection *connection,
04183                              DBusList       *message_link)
04184 {
04185   _dbus_list_prepend_link (&connection->incoming_messages,
04186                            message_link);
04187   connection->n_incoming += 1;
04188 }
04189 
04190 /* Note this may be called multiple times since we don't track whether we already did it */
04191 static void
04192 notify_disconnected_unlocked (DBusConnection *connection)
04193 {
04194   HAVE_LOCK_CHECK (connection);
04195 
04196   /* Set the weakref in dbus-bus.c to NULL, so nobody will get a disconnected
04197    * connection from dbus_bus_get(). We make the same guarantee for
04198    * dbus_connection_open() but in a different way since we don't want to
04199    * unref right here; we instead check for connectedness before returning
04200    * the connection from the hash.
04201    */
04202   _dbus_bus_notify_shared_connection_disconnected_unlocked (connection);
04203 
04204   /* Dump the outgoing queue, we aren't going to be able to
04205    * send it now, and we'd like accessors like
04206    * dbus_connection_get_outgoing_size() to be accurate.
04207    */
04208   if (connection->n_outgoing > 0)
04209     {
04210       DBusList *link;
04211       
04212       _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
04213                      connection->n_outgoing);
04214       
04215       while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
04216         {
04217           _dbus_connection_message_sent_unlocked (connection, link->data);
04218         }
04219     } 
04220 }
04221 
04222 /* Note this may be called multiple times since we don't track whether we already did it */
04223 static DBusDispatchStatus
04224 notify_disconnected_and_dispatch_complete_unlocked (DBusConnection *connection)
04225 {
04226   HAVE_LOCK_CHECK (connection);
04227   
04228   if (connection->disconnect_message_link != NULL)
04229     {
04230       _dbus_verbose ("Sending disconnect message\n");
04231       
04232       /* If we have pending calls, queue their timeouts - we want the Disconnected
04233        * to be the last message, after these timeouts.
04234        */
04235       connection_timeout_and_complete_all_pending_calls_unlocked (connection);
04236       
04237       /* We haven't sent the disconnect message already,
04238        * and all real messages have been queued up.
04239        */
04240       _dbus_connection_queue_synthesized_message_link (connection,
04241                                                        connection->disconnect_message_link);
04242       connection->disconnect_message_link = NULL;
04243 
04244       return DBUS_DISPATCH_DATA_REMAINS;
04245     }
04246 
04247   return DBUS_DISPATCH_COMPLETE;
04248 }
04249 
04250 static DBusDispatchStatus
04251 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
04252 {
04253   HAVE_LOCK_CHECK (connection);
04254   
04255   if (connection->n_incoming > 0)
04256     return DBUS_DISPATCH_DATA_REMAINS;
04257   else if (!_dbus_transport_queue_messages (connection->transport))
04258     return DBUS_DISPATCH_NEED_MEMORY;
04259   else
04260     {
04261       DBusDispatchStatus status;
04262       dbus_bool_t is_connected;
04263       
04264       status = _dbus_transport_get_dispatch_status (connection->transport);
04265       is_connected = _dbus_transport_get_is_connected (connection->transport);
04266 
04267       _dbus_verbose ("dispatch status = %s is_connected = %d\n",
04268                      DISPATCH_STATUS_NAME (status), is_connected);
04269       
04270       if (!is_connected)
04271         {
04272           /* It's possible this would be better done by having an explicit
04273            * notification from _dbus_transport_disconnect() that would
04274            * synchronously do this, instead of waiting for the next dispatch
04275            * status check. However, probably not good to change until it causes
04276            * a problem.
04277            */
04278           notify_disconnected_unlocked (connection);
04279 
04280           /* I'm not sure this is needed; the idea is that we want to
04281            * queue the Disconnected only after we've read all the
04282            * messages, but if we're disconnected maybe we are guaranteed
04283            * to have read them all ?
04284            */
04285           if (status == DBUS_DISPATCH_COMPLETE)
04286             status = notify_disconnected_and_dispatch_complete_unlocked (connection);
04287         }
04288       
04289       if (status != DBUS_DISPATCH_COMPLETE)
04290         return status;
04291       else if (connection->n_incoming > 0)
04292         return DBUS_DISPATCH_DATA_REMAINS;
04293       else
04294         return DBUS_DISPATCH_COMPLETE;
04295     }
04296 }
04297 
04298 static void
04299 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection    *connection,
04300                                                     DBusDispatchStatus new_status)
04301 {
04302   dbus_bool_t changed;
04303   DBusDispatchStatusFunction function;
04304   void *data;
04305 
04306   HAVE_LOCK_CHECK (connection);
04307 
04308   _dbus_connection_ref_unlocked (connection);
04309 
04310   changed = new_status != connection->last_dispatch_status;
04311 
04312   connection->last_dispatch_status = new_status;
04313 
04314   function = connection->dispatch_status_function;
04315   data = connection->dispatch_status_data;
04316 
04317   if (connection->disconnected_message_arrived &&
04318       !connection->disconnected_message_processed)
04319     {
04320       connection->disconnected_message_processed = TRUE;
04321       
04322       /* this does an unref, but we have a ref
04323        * so we should not run the finalizer here
04324        * inside the lock.
04325        */
04326       connection_forget_shared_unlocked (connection);
04327 
04328       if (connection->exit_on_disconnect)
04329         {
04330           CONNECTION_UNLOCK (connection);            
04331           
04332           _dbus_verbose ("Exiting on Disconnected signal\n");
04333           _dbus_exit (1);
04334           _dbus_assert_not_reached ("Call to exit() returned");
04335         }
04336     }
04337   
04338   /* We drop the lock */
04339   CONNECTION_UNLOCK (connection);
04340   
04341   if (changed && function)
04342     {
04343       _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
04344                      connection, new_status,
04345                      DISPATCH_STATUS_NAME (new_status));
04346       (* function) (connection, new_status, data);      
04347     }
04348   
04349   dbus_connection_unref (connection);
04350 }
04351 
04377 DBusDispatchStatus
04378 dbus_connection_get_dispatch_status (DBusConnection *connection)
04379 {
04380   DBusDispatchStatus status;
04381 
04382   _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04383 
04384   _dbus_verbose ("start\n");
04385   
04386   CONNECTION_LOCK (connection);
04387 
04388   status = _dbus_connection_get_dispatch_status_unlocked (connection);
04389   
04390   CONNECTION_UNLOCK (connection);
04391 
04392   return status;
04393 }
04394 
04398 static DBusHandlerResult
04399 _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
04400                                                  DBusMessage    *message)
04401 {
04402   dbus_bool_t sent = FALSE;
04403   DBusMessage *ret = NULL;
04404   DBusList *expire_link;
04405 
04406   if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
04407     {
04408       /* This means we're letting the bus route this message */
04409       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04410     }
04411 
04412   if (!dbus_message_has_interface (message, DBUS_INTERFACE_PEER))
04413     {
04414       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04415     }
04416 
04417   /* Preallocate a linked-list link, so that if we need to dispose of a
04418    * message, we can attach it to the expired list */
04419   expire_link = _dbus_list_alloc_link (NULL);
04420 
04421   if (!expire_link)
04422     return DBUS_HANDLER_RESULT_NEED_MEMORY;
04423 
04424   if (dbus_message_is_method_call (message,
04425                                    DBUS_INTERFACE_PEER,
04426                                    "Ping"))
04427     {
04428       ret = dbus_message_new_method_return (message);
04429       if (ret == NULL)
04430         goto out;
04431 
04432       sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04433     }
04434   else if (dbus_message_is_method_call (message,
04435                                         DBUS_INTERFACE_PEER,
04436                                         "GetMachineId"))
04437     {
04438       DBusString uuid;
04439       
04440       ret = dbus_message_new_method_return (message);
04441       if (ret == NULL)
04442         goto out;
04443 
04444       _dbus_string_init (&uuid);
04445       if (_dbus_get_local_machine_uuid_encoded (&uuid))
04446         {
04447           const char *v_STRING = _dbus_string_get_const_data (&uuid);
04448           if (dbus_message_append_args (ret,
04449                                         DBUS_TYPE_STRING, &v_STRING,
04450                                         DBUS_TYPE_INVALID))
04451             {
04452               sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04453             }
04454         }
04455       _dbus_string_free (&uuid);
04456     }
04457   else
04458     {
04459       /* We need to bounce anything else with this interface, otherwise apps
04460        * could start extending the interface and when we added extensions
04461        * here to DBusConnection we'd break those apps.
04462        */
04463       ret = dbus_message_new_error (message,
04464                                     DBUS_ERROR_UNKNOWN_METHOD,
04465                                     "Unknown method invoked on org.freedesktop.DBus.Peer interface");
04466       if (ret == NULL)
04467         goto out;
04468 
04469       sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04470     }
04471 
04472 out:
04473   if (ret == NULL)
04474     {
04475       _dbus_list_free_link (expire_link);
04476     }
04477   else
04478     {
04479       /* It'll be safe to unref the reply when we unlock */
04480       expire_link->data = ret;
04481       _dbus_list_prepend_link (&connection->expired_messages, expire_link);
04482     }
04483 
04484   if (!sent)
04485     return DBUS_HANDLER_RESULT_NEED_MEMORY;
04486 
04487   return DBUS_HANDLER_RESULT_HANDLED;
04488 }
04489 
04496 static DBusHandlerResult
04497 _dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection,
04498                                                            DBusMessage    *message)
04499 {
04500   /* We just run one filter for now but have the option to run more
04501      if the spec calls for it in the future */
04502 
04503   return _dbus_connection_peer_filter_unlocked_no_update (connection, message);
04504 }
04505 
04548 DBusDispatchStatus
04549 dbus_connection_dispatch (DBusConnection *connection)
04550 {
04551   DBusMessage *message;
04552   DBusList *link, *filter_list_copy, *message_link;
04553   DBusHandlerResult result;
04554   DBusPendingCall *pending;
04555   dbus_int32_t reply_serial;
04556   DBusDispatchStatus status;
04557   dbus_bool_t found_object;
04558 
04559   _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04560 
04561   _dbus_verbose ("\n");
04562   
04563   CONNECTION_LOCK (connection);
04564   status = _dbus_connection_get_dispatch_status_unlocked (connection);
04565   if (status != DBUS_DISPATCH_DATA_REMAINS)
04566     {
04567       /* unlocks and calls out to user code */
04568       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04569       return status;
04570     }
04571   
04572   /* We need to ref the connection since the callback could potentially
04573    * drop the last ref to it
04574    */
04575   _dbus_connection_ref_unlocked (connection);
04576 
04577   _dbus_connection_acquire_dispatch (connection);
04578   HAVE_LOCK_CHECK (connection);
04579 
04580   message_link = _dbus_connection_pop_message_link_unlocked (connection);
04581   if (message_link == NULL)
04582     {
04583       /* another thread dispatched our stuff */
04584 
04585       _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
04586       
04587       _dbus_connection_release_dispatch (connection);
04588 
04589       status = _dbus_connection_get_dispatch_status_unlocked (connection);
04590 
04591       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04592       
04593       dbus_connection_unref (connection);
04594       
04595       return status;
04596     }
04597 
04598   message = message_link->data;
04599 
04600   _dbus_verbose (" dispatching message %p (%s %s %s '%s')\n",
04601                  message,
04602                  dbus_message_type_to_string (dbus_message_get_type (message)),
04603                  dbus_message_get_interface (message) ?
04604                  dbus_message_get_interface (message) :
04605                  "no interface",
04606                  dbus_message_get_member (message) ?
04607                  dbus_message_get_member (message) :
04608                  "no member",
04609                  dbus_message_get_signature (message));
04610 
04611   result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04612   
04613   /* Pending call handling must be first, because if you do
04614    * dbus_connection_send_with_reply_and_block() or
04615    * dbus_pending_call_block() then no handlers/filters will be run on
04616    * the reply. We want consistent semantics in the case where we
04617    * dbus_connection_dispatch() the reply.
04618    */
04619   
04620   reply_serial = dbus_message_get_reply_serial (message);
04621   pending = _dbus_hash_table_lookup_int (connection->pending_replies,
04622                                          reply_serial);
04623   if (pending)
04624     {
04625       _dbus_verbose ("Dispatching a pending reply\n");
04626       complete_pending_call_and_unlock (connection, pending, message);
04627       pending = NULL; /* it's probably unref'd */
04628       
04629       CONNECTION_LOCK (connection);
04630       _dbus_verbose ("pending call completed in dispatch\n");
04631       result = DBUS_HANDLER_RESULT_HANDLED;
04632       goto out;
04633     }
04634 
04635   result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message);
04636   if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04637     goto out;
04638  
04639   if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
04640     {
04641       _dbus_connection_release_dispatch (connection);
04642       HAVE_LOCK_CHECK (connection);
04643       
04644       _dbus_connection_failed_pop (connection, message_link);
04645 
04646       /* unlocks and calls user code */
04647       _dbus_connection_update_dispatch_status_and_unlock (connection,
04648                                                           DBUS_DISPATCH_NEED_MEMORY);
04649       dbus_connection_unref (connection);
04650       
04651       return DBUS_DISPATCH_NEED_MEMORY;
04652     }
04653   
04654   _dbus_list_foreach (&filter_list_copy,
04655                       (DBusForeachFunction)_dbus_message_filter_ref,
04656                       NULL);
04657 
04658   /* We're still protected from dispatch() reentrancy here
04659    * since we acquired the dispatcher
04660    */
04661   CONNECTION_UNLOCK (connection);
04662   
04663   link = _dbus_list_get_first_link (&filter_list_copy);
04664   while (link != NULL)
04665     {
04666       DBusMessageFilter *filter = link->data;
04667       DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
04668 
04669       if (filter->function == NULL)
04670         {
04671           _dbus_verbose ("  filter was removed in a callback function\n");
04672           link = next;
04673           continue;
04674         }
04675 
04676       _dbus_verbose ("  running filter on message %p\n", message);
04677       result = (* filter->function) (connection, message, filter->user_data);
04678 
04679       if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04680         break;
04681 
04682       link = next;
04683     }
04684 
04685   _dbus_list_foreach (&filter_list_copy,
04686                       (DBusForeachFunction)_dbus_message_filter_unref,
04687                       NULL);
04688   _dbus_list_clear (&filter_list_copy);
04689   
04690   CONNECTION_LOCK (connection);
04691 
04692   if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04693     {
04694       _dbus_verbose ("No memory\n");
04695       goto out;
04696     }
04697   else if (result == DBUS_HANDLER_RESULT_HANDLED)
04698     {
04699       _dbus_verbose ("filter handled message in dispatch\n");
04700       goto out;
04701     }
04702 
04703   /* We're still protected from dispatch() reentrancy here
04704    * since we acquired the dispatcher
04705    */
04706   _dbus_verbose ("  running object path dispatch on message %p (%s %s %s '%s')\n",
04707                  message,
04708                  dbus_message_type_to_string (dbus_message_get_type (message)),
04709                  dbus_message_get_interface (message) ?
04710                  dbus_message_get_interface (message) :
04711                  "no interface",
04712                  dbus_message_get_member (message) ?
04713                  dbus_message_get_member (message) :
04714                  "no member",
04715                  dbus_message_get_signature (message));
04716 
04717   HAVE_LOCK_CHECK (connection);
04718   result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
04719                                                   message,
04720                                                   &found_object);
04721   
04722   CONNECTION_LOCK (connection);
04723 
04724   if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04725     {
04726       _dbus_verbose ("object tree handled message in dispatch\n");
04727       goto out;
04728     }
04729 
04730   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
04731     {
04732       DBusMessage *reply;
04733       DBusString str;
04734       DBusPreallocatedSend *preallocated;
04735       DBusList *expire_link;
04736 
04737       _dbus_verbose ("  sending error %s\n",
04738                      DBUS_ERROR_UNKNOWN_METHOD);
04739 
04740       if (!_dbus_string_init (&str))
04741         {
04742           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04743           _dbus_verbose ("no memory for error string in dispatch\n");
04744           goto out;
04745         }
04746               
04747       if (!_dbus_string_append_printf (&str,
04748                                        "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
04749                                        dbus_message_get_member (message),
04750                                        dbus_message_get_signature (message),
04751                                        dbus_message_get_interface (message)))
04752         {
04753           _dbus_string_free (&str);
04754           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04755           _dbus_verbose ("no memory for error string in dispatch\n");
04756           goto out;
04757         }
04758       
04759       reply = dbus_message_new_error (message,
04760                                       found_object ? DBUS_ERROR_UNKNOWN_METHOD : DBUS_ERROR_UNKNOWN_OBJECT,
04761                                       _dbus_string_get_const_data (&str));
04762       _dbus_string_free (&str);
04763 
04764       if (reply == NULL)
04765         {
04766           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04767           _dbus_verbose ("no memory for error reply in dispatch\n");
04768           goto out;
04769         }
04770 
04771       expire_link = _dbus_list_alloc_link (reply);
04772 
04773       if (expire_link == NULL)
04774         {
04775           dbus_message_unref (reply);
04776           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04777           _dbus_verbose ("no memory for error send in dispatch\n");
04778           goto out;
04779         }
04780 
04781       preallocated = _dbus_connection_preallocate_send_unlocked (connection);
04782 
04783       if (preallocated == NULL)
04784         {
04785           _dbus_list_free_link (expire_link);
04786           /* It's OK that this is finalized, because it hasn't been seen by
04787            * anything that could attach user callbacks */
04788           dbus_message_unref (reply);
04789           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04790           _dbus_verbose ("no memory for error send in dispatch\n");
04791           goto out;
04792         }
04793 
04794       _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
04795                                                              reply, NULL);
04796       /* reply will be freed when we release the lock */
04797       _dbus_list_prepend_link (&connection->expired_messages, expire_link);
04798 
04799       result = DBUS_HANDLER_RESULT_HANDLED;
04800     }
04801   
04802   _dbus_verbose ("  done dispatching %p (%s %s %s '%s') on connection %p\n", message,
04803                  dbus_message_type_to_string (dbus_message_get_type (message)),
04804                  dbus_message_get_interface (message) ?
04805                  dbus_message_get_interface (message) :
04806                  "no interface",
04807                  dbus_message_get_member (message) ?
04808                  dbus_message_get_member (message) :
04809                  "no member",
04810                  dbus_message_get_signature (message),
04811                  connection);
04812   
04813  out:
04814   if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04815     {
04816       _dbus_verbose ("out of memory\n");
04817       
04818       /* Put message back, and we'll start over.
04819        * Yes this means handlers must be idempotent if they
04820        * don't return HANDLED; c'est la vie.
04821        */
04822       _dbus_connection_putback_message_link_unlocked (connection,
04823                                                       message_link);
04824       /* now we don't want to free them */
04825       message_link = NULL;
04826       message = NULL;
04827     }
04828   else
04829     {
04830       _dbus_verbose (" ... done dispatching\n");
04831     }
04832 
04833   _dbus_connection_release_dispatch (connection);
04834   HAVE_LOCK_CHECK (connection);
04835 
04836   if (message != NULL)
04837     {
04838       /* We don't want this message to count in maximum message limits when
04839        * computing the dispatch status, below. We have to drop the lock
04840        * temporarily, because finalizing a message can trigger callbacks.
04841        *
04842        * We have a reference to the connection, and we don't use any cached
04843        * pointers to the connection's internals below this point, so it should
04844        * be safe to drop the lock and take it back. */
04845       CONNECTION_UNLOCK (connection);
04846       dbus_message_unref (message);
04847       CONNECTION_LOCK (connection);
04848     }
04849 
04850   if (message_link != NULL)
04851     _dbus_list_free_link (message_link);
04852 
04853   _dbus_verbose ("before final status update\n");
04854   status = _dbus_connection_get_dispatch_status_unlocked (connection);
04855 
04856   /* unlocks and calls user code */
04857   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04858   
04859   dbus_connection_unref (connection);
04860   
04861   return status;
04862 }
04863 
04925 dbus_bool_t
04926 dbus_connection_set_watch_functions (DBusConnection              *connection,
04927                                      DBusAddWatchFunction         add_function,
04928                                      DBusRemoveWatchFunction      remove_function,
04929                                      DBusWatchToggledFunction     toggled_function,
04930                                      void                        *data,
04931                                      DBusFreeFunction             free_data_function)
04932 {
04933   dbus_bool_t retval;
04934 
04935   _dbus_return_val_if_fail (connection != NULL, FALSE);
04936   
04937   CONNECTION_LOCK (connection);
04938 
04939   retval = _dbus_watch_list_set_functions (connection->watches,
04940                                            add_function, remove_function,
04941                                            toggled_function,
04942                                            data, free_data_function);
04943 
04944   CONNECTION_UNLOCK (connection);
04945 
04946   return retval;
04947 }
04948 
04988 dbus_bool_t
04989 dbus_connection_set_timeout_functions   (DBusConnection            *connection,
04990                                          DBusAddTimeoutFunction     add_function,
04991                                          DBusRemoveTimeoutFunction  remove_function,
04992                                          DBusTimeoutToggledFunction toggled_function,
04993                                          void                      *data,
04994                                          DBusFreeFunction           free_data_function)
04995 {
04996   dbus_bool_t retval;
04997 
04998   _dbus_return_val_if_fail (connection != NULL, FALSE);
04999   
05000   CONNECTION_LOCK (connection);
05001 
05002   retval = _dbus_timeout_list_set_functions (connection->timeouts,
05003                                              add_function, remove_function,
05004                                              toggled_function,
05005                                              data, free_data_function);
05006 
05007   CONNECTION_UNLOCK (connection);
05008 
05009   return retval;
05010 }
05011 
05026 void
05027 dbus_connection_set_wakeup_main_function (DBusConnection            *connection,
05028                                           DBusWakeupMainFunction     wakeup_main_function,
05029                                           void                      *data,
05030                                           DBusFreeFunction           free_data_function)
05031 {
05032   void *old_data;
05033   DBusFreeFunction old_free_data;
05034 
05035   _dbus_return_if_fail (connection != NULL);
05036   
05037   CONNECTION_LOCK (connection);
05038   old_data = connection->wakeup_main_data;
05039   old_free_data = connection->free_wakeup_main_data;
05040 
05041   connection->wakeup_main_function = wakeup_main_function;
05042   connection->wakeup_main_data = data;
05043   connection->free_wakeup_main_data = free_data_function;
05044   
05045   CONNECTION_UNLOCK (connection);
05046 
05047   /* Callback outside the lock */
05048   if (old_free_data)
05049     (*old_free_data) (old_data);
05050 }
05051 
05072 void
05073 dbus_connection_set_dispatch_status_function (DBusConnection             *connection,
05074                                               DBusDispatchStatusFunction  function,
05075                                               void                       *data,
05076                                               DBusFreeFunction            free_data_function)
05077 {
05078   void *old_data;
05079   DBusFreeFunction old_free_data;
05080 
05081   _dbus_return_if_fail (connection != NULL);
05082   
05083   CONNECTION_LOCK (connection);
05084   old_data = connection->dispatch_status_data;
05085   old_free_data = connection->free_dispatch_status_data;
05086 
05087   connection->dispatch_status_function = function;
05088   connection->dispatch_status_data = data;
05089   connection->free_dispatch_status_data = free_data_function;
05090   
05091   CONNECTION_UNLOCK (connection);
05092 
05093   /* Callback outside the lock */
05094   if (old_free_data)
05095     (*old_free_data) (old_data);
05096 }
05097 
05117 dbus_bool_t
05118 dbus_connection_get_unix_fd (DBusConnection *connection,
05119                              int            *fd)
05120 {
05121   _dbus_return_val_if_fail (connection != NULL, FALSE);
05122   _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
05123 
05124 #ifdef DBUS_WIN
05125   /* FIXME do this on a lower level */
05126   return FALSE;
05127 #endif
05128   
05129   return dbus_connection_get_socket(connection, fd);
05130 }
05131 
05147 dbus_bool_t
05148 dbus_connection_get_socket(DBusConnection              *connection,
05149                            int                         *fd)
05150 {
05151   dbus_bool_t retval;
05152 
05153   _dbus_return_val_if_fail (connection != NULL, FALSE);
05154   _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
05155   
05156   CONNECTION_LOCK (connection);
05157   
05158   retval = _dbus_transport_get_socket_fd (connection->transport,
05159                                           fd);
05160 
05161   CONNECTION_UNLOCK (connection);
05162 
05163   return retval;
05164 }
05165 
05166 
05189 dbus_bool_t
05190 dbus_connection_get_unix_user (DBusConnection *connection,
05191                                unsigned long  *uid)
05192 {
05193   dbus_bool_t result;
05194 
05195   _dbus_return_val_if_fail (connection != NULL, FALSE);
05196   _dbus_return_val_if_fail (uid != NULL, FALSE);
05197 
05198   CONNECTION_LOCK (connection);
05199 
05200   if (!_dbus_transport_try_to_authenticate (connection->transport))
05201     result = FALSE;
05202   else
05203     result = _dbus_transport_get_unix_user (connection->transport,
05204                                             uid);
05205 
05206 #ifdef DBUS_WIN
05207   _dbus_assert (!result);
05208 #endif
05209   
05210   CONNECTION_UNLOCK (connection);
05211 
05212   return result;
05213 }
05214 
05225 dbus_bool_t
05226 dbus_connection_get_unix_process_id (DBusConnection *connection,
05227                                      unsigned long  *pid)
05228 {
05229   dbus_bool_t result;
05230 
05231   _dbus_return_val_if_fail (connection != NULL, FALSE);
05232   _dbus_return_val_if_fail (pid != NULL, FALSE);
05233 
05234   CONNECTION_LOCK (connection);
05235 
05236   if (!_dbus_transport_try_to_authenticate (connection->transport))
05237     result = FALSE;
05238   else
05239     result = _dbus_transport_get_unix_process_id (connection->transport,
05240                                                   pid);
05241 
05242   CONNECTION_UNLOCK (connection);
05243 
05244   return result;
05245 }
05246 
05258 dbus_bool_t
05259 dbus_connection_get_adt_audit_session_data (DBusConnection *connection,
05260                                             void          **data,
05261                                             dbus_int32_t   *data_size)
05262 {
05263   dbus_bool_t result;
05264 
05265   _dbus_return_val_if_fail (connection != NULL, FALSE);
05266   _dbus_return_val_if_fail (data != NULL, FALSE);
05267   _dbus_return_val_if_fail (data_size != NULL, FALSE);
05268 
05269   CONNECTION_LOCK (connection);
05270 
05271   if (!_dbus_transport_try_to_authenticate (connection->transport))
05272     result = FALSE;
05273   else
05274     result = _dbus_transport_get_adt_audit_session_data (connection->transport,
05275                                                          data,
05276                                                          data_size);
05277   CONNECTION_UNLOCK (connection);
05278 
05279   return result;
05280 }
05281 
05304 void
05305 dbus_connection_set_unix_user_function (DBusConnection             *connection,
05306                                         DBusAllowUnixUserFunction   function,
05307                                         void                       *data,
05308                                         DBusFreeFunction            free_data_function)
05309 {
05310   void *old_data = NULL;
05311   DBusFreeFunction old_free_function = NULL;
05312 
05313   _dbus_return_if_fail (connection != NULL);
05314   
05315   CONNECTION_LOCK (connection);
05316   _dbus_transport_set_unix_user_function (connection->transport,
05317                                           function, data, free_data_function,
05318                                           &old_data, &old_free_function);
05319   CONNECTION_UNLOCK (connection);
05320 
05321   if (old_free_function != NULL)
05322     (* old_free_function) (old_data);
05323 }
05324 
05356 dbus_bool_t
05357 dbus_connection_get_windows_user (DBusConnection             *connection,
05358                                   char                      **windows_sid_p)
05359 {
05360   dbus_bool_t result;
05361 
05362   _dbus_return_val_if_fail (connection != NULL, FALSE);
05363   _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
05364 
05365   CONNECTION_LOCK (connection);
05366 
05367   if (!_dbus_transport_try_to_authenticate (connection->transport))
05368     result = FALSE;
05369   else
05370     result = _dbus_transport_get_windows_user (connection->transport,
05371                                                windows_sid_p);
05372 
05373 #ifdef DBUS_UNIX
05374   _dbus_assert (!result);
05375 #endif
05376   
05377   CONNECTION_UNLOCK (connection);
05378 
05379   return result;
05380 }
05381 
05403 void
05404 dbus_connection_set_windows_user_function (DBusConnection              *connection,
05405                                            DBusAllowWindowsUserFunction function,
05406                                            void                        *data,
05407                                            DBusFreeFunction             free_data_function)
05408 {
05409   void *old_data = NULL;
05410   DBusFreeFunction old_free_function = NULL;
05411 
05412   _dbus_return_if_fail (connection != NULL);
05413   
05414   CONNECTION_LOCK (connection);
05415   _dbus_transport_set_windows_user_function (connection->transport,
05416                                              function, data, free_data_function,
05417                                              &old_data, &old_free_function);
05418   CONNECTION_UNLOCK (connection);
05419 
05420   if (old_free_function != NULL)
05421     (* old_free_function) (old_data);
05422 }
05423 
05450 void
05451 dbus_connection_set_allow_anonymous (DBusConnection             *connection,
05452                                      dbus_bool_t                 value)
05453 {
05454   _dbus_return_if_fail (connection != NULL);
05455   
05456   CONNECTION_LOCK (connection);
05457   _dbus_transport_set_allow_anonymous (connection->transport, value);
05458   CONNECTION_UNLOCK (connection);
05459 }
05460 
05478 void
05479 dbus_connection_set_route_peer_messages (DBusConnection             *connection,
05480                                          dbus_bool_t                 value)
05481 {
05482   _dbus_return_if_fail (connection != NULL);
05483   
05484   CONNECTION_LOCK (connection);
05485   connection->route_peer_messages = value;
05486   CONNECTION_UNLOCK (connection);
05487 }
05488 
05510 dbus_bool_t
05511 dbus_connection_add_filter (DBusConnection            *connection,
05512                             DBusHandleMessageFunction  function,
05513                             void                      *user_data,
05514                             DBusFreeFunction           free_data_function)
05515 {
05516   DBusMessageFilter *filter;
05517   
05518   _dbus_return_val_if_fail (connection != NULL, FALSE);
05519   _dbus_return_val_if_fail (function != NULL, FALSE);
05520 
05521   filter = dbus_new0 (DBusMessageFilter, 1);
05522   if (filter == NULL)
05523     return FALSE;
05524 
05525   _dbus_atomic_inc (&filter->refcount);
05526 
05527   CONNECTION_LOCK (connection);
05528 
05529   if (!_dbus_list_append (&connection->filter_list,
05530                           filter))
05531     {
05532       _dbus_message_filter_unref (filter);
05533       CONNECTION_UNLOCK (connection);
05534       return FALSE;
05535     }
05536 
05537   /* Fill in filter after all memory allocated,
05538    * so we don't run the free_user_data_function
05539    * if the add_filter() fails
05540    */
05541   
05542   filter->function = function;
05543   filter->user_data = user_data;
05544   filter->free_user_data_function = free_data_function;
05545         
05546   CONNECTION_UNLOCK (connection);
05547   return TRUE;
05548 }
05549 
05562 void
05563 dbus_connection_remove_filter (DBusConnection            *connection,
05564                                DBusHandleMessageFunction  function,
05565                                void                      *user_data)
05566 {
05567   DBusList *link;
05568   DBusMessageFilter *filter;
05569   
05570   _dbus_return_if_fail (connection != NULL);
05571   _dbus_return_if_fail (function != NULL);
05572   
05573   CONNECTION_LOCK (connection);
05574 
05575   filter = NULL;
05576   
05577   link = _dbus_list_get_last_link (&connection->filter_list);
05578   while (link != NULL)
05579     {
05580       filter = link->data;
05581 
05582       if (filter->function == function &&
05583           filter->user_data == user_data)
05584         {
05585           _dbus_list_remove_link (&connection->filter_list, link);
05586           filter->function = NULL;
05587           
05588           break;
05589         }
05590         
05591       link = _dbus_list_get_prev_link (&connection->filter_list, link);
05592       filter = NULL;
05593     }
05594   
05595   CONNECTION_UNLOCK (connection);
05596 
05597 #ifndef DBUS_DISABLE_CHECKS
05598   if (filter == NULL)
05599     {
05600       _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
05601                                function, user_data);
05602       return;
05603     }
05604 #endif
05605   
05606   /* Call application code */
05607   if (filter->free_user_data_function)
05608     (* filter->free_user_data_function) (filter->user_data);
05609 
05610   filter->free_user_data_function = NULL;
05611   filter->user_data = NULL;
05612   
05613   _dbus_message_filter_unref (filter);
05614 }
05615 
05631 static dbus_bool_t
05632 _dbus_connection_register_object_path (DBusConnection              *connection,
05633                                        dbus_bool_t                  fallback,
05634                                        const char                  *path,
05635                                        const DBusObjectPathVTable  *vtable,
05636                                        void                        *user_data,
05637                                        DBusError                   *error)
05638 {
05639   char **decomposed_path;
05640   dbus_bool_t retval;
05641 
05642   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05643     return FALSE;
05644 
05645   CONNECTION_LOCK (connection);
05646 
05647   retval = _dbus_object_tree_register (connection->objects,
05648                                        fallback,
05649                                        (const char **) decomposed_path, vtable,
05650                                        user_data, error);
05651 
05652   CONNECTION_UNLOCK (connection);
05653 
05654   dbus_free_string_array (decomposed_path);
05655 
05656   return retval;
05657 }
05658 
05671 dbus_bool_t
05672 dbus_connection_try_register_object_path (DBusConnection              *connection,
05673                                           const char                  *path,
05674                                           const DBusObjectPathVTable  *vtable,
05675                                           void                        *user_data,
05676                                           DBusError                   *error)
05677 {
05678   _dbus_return_val_if_fail (connection != NULL, FALSE);
05679   _dbus_return_val_if_fail (path != NULL, FALSE);
05680   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05681   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05682 
05683   return _dbus_connection_register_object_path (connection, FALSE, path, vtable, user_data, error);
05684 }
05685 
05701 dbus_bool_t
05702 dbus_connection_register_object_path (DBusConnection              *connection,
05703                                       const char                  *path,
05704                                       const DBusObjectPathVTable  *vtable,
05705                                       void                        *user_data)
05706 {
05707   dbus_bool_t retval;
05708   DBusError error = DBUS_ERROR_INIT;
05709 
05710   _dbus_return_val_if_fail (connection != NULL, FALSE);
05711   _dbus_return_val_if_fail (path != NULL, FALSE);
05712   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05713   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05714 
05715   retval = _dbus_connection_register_object_path (connection, FALSE, path, vtable, user_data, &error);
05716 
05717   if (dbus_error_has_name (&error, DBUS_ERROR_OBJECT_PATH_IN_USE))
05718     {
05719       _dbus_warn ("%s\n", error.message);
05720       dbus_error_free (&error);
05721       return FALSE;
05722     }
05723 
05724   return retval;
05725 }
05726 
05741 dbus_bool_t
05742 dbus_connection_try_register_fallback (DBusConnection              *connection,
05743                                        const char                  *path,
05744                                        const DBusObjectPathVTable  *vtable,
05745                                        void                        *user_data,
05746                                        DBusError                   *error)
05747 {
05748   _dbus_return_val_if_fail (connection != NULL, FALSE);
05749   _dbus_return_val_if_fail (path != NULL, FALSE);
05750   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05751   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05752 
05753   return _dbus_connection_register_object_path (connection, TRUE, path, vtable, user_data, error);
05754 }
05755 
05773 dbus_bool_t
05774 dbus_connection_register_fallback (DBusConnection              *connection,
05775                                    const char                  *path,
05776                                    const DBusObjectPathVTable  *vtable,
05777                                    void                        *user_data)
05778 {
05779   dbus_bool_t retval;
05780   DBusError error = DBUS_ERROR_INIT;
05781 
05782   _dbus_return_val_if_fail (connection != NULL, FALSE);
05783   _dbus_return_val_if_fail (path != NULL, FALSE);
05784   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05785   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05786 
05787   retval = _dbus_connection_register_object_path (connection, TRUE, path, vtable, user_data, &error);
05788 
05789   if (dbus_error_has_name (&error, DBUS_ERROR_OBJECT_PATH_IN_USE))
05790     {
05791       _dbus_warn ("%s\n", error.message);
05792       dbus_error_free (&error);
05793       return FALSE;
05794     }
05795 
05796   return retval;
05797 }
05798 
05808 dbus_bool_t
05809 dbus_connection_unregister_object_path (DBusConnection              *connection,
05810                                         const char                  *path)
05811 {
05812   char **decomposed_path;
05813 
05814   _dbus_return_val_if_fail (connection != NULL, FALSE);
05815   _dbus_return_val_if_fail (path != NULL, FALSE);
05816   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05817 
05818   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05819       return FALSE;
05820 
05821   CONNECTION_LOCK (connection);
05822 
05823   _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
05824 
05825   dbus_free_string_array (decomposed_path);
05826 
05827   return TRUE;
05828 }
05829 
05840 dbus_bool_t
05841 dbus_connection_get_object_path_data (DBusConnection *connection,
05842                                       const char     *path,
05843                                       void          **data_p)
05844 {
05845   char **decomposed_path;
05846 
05847   _dbus_return_val_if_fail (connection != NULL, FALSE);
05848   _dbus_return_val_if_fail (path != NULL, FALSE);
05849   _dbus_return_val_if_fail (data_p != NULL, FALSE);
05850 
05851   *data_p = NULL;
05852   
05853   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05854     return FALSE;
05855   
05856   CONNECTION_LOCK (connection);
05857 
05858   *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path);
05859 
05860   CONNECTION_UNLOCK (connection);
05861 
05862   dbus_free_string_array (decomposed_path);
05863 
05864   return TRUE;
05865 }
05866 
05877 dbus_bool_t
05878 dbus_connection_list_registered (DBusConnection              *connection,
05879                                  const char                  *parent_path,
05880                                  char                      ***child_entries)
05881 {
05882   char **decomposed_path;
05883   dbus_bool_t retval;
05884   _dbus_return_val_if_fail (connection != NULL, FALSE);
05885   _dbus_return_val_if_fail (parent_path != NULL, FALSE);
05886   _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
05887   _dbus_return_val_if_fail (child_entries != NULL, FALSE);
05888 
05889   if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
05890     return FALSE;
05891 
05892   CONNECTION_LOCK (connection);
05893 
05894   retval = _dbus_object_tree_list_registered_and_unlock (connection->objects,
05895                                                          (const char **) decomposed_path,
05896                                                          child_entries);
05897   dbus_free_string_array (decomposed_path);
05898 
05899   return retval;
05900 }
05901 
05902 static DBusDataSlotAllocator slot_allocator =
05903   _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (connection_slots));
05904 
05919 dbus_bool_t
05920 dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
05921 {
05922   return _dbus_data_slot_allocator_alloc (&slot_allocator,
05923                                           slot_p);
05924 }
05925 
05937 void
05938 dbus_connection_free_data_slot (dbus_int32_t *slot_p)
05939 {
05940   _dbus_return_if_fail (*slot_p >= 0);
05941   
05942   _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
05943 }
05944 
05967 dbus_bool_t
05968 dbus_connection_set_data (DBusConnection   *connection,
05969                           dbus_int32_t      slot,
05970                           void             *data,
05971                           DBusFreeFunction  free_data_func)
05972 {
05973   DBusFreeFunction old_free_func;
05974   void *old_data;
05975   dbus_bool_t retval;
05976 
05977   _dbus_return_val_if_fail (connection != NULL, FALSE);
05978   _dbus_return_val_if_fail (slot >= 0, FALSE);
05979   
05980   SLOTS_LOCK (connection);
05981 
05982   retval = _dbus_data_slot_list_set (&slot_allocator,
05983                                      &connection->slot_list,
05984                                      slot, data, free_data_func,
05985                                      &old_free_func, &old_data);
05986   
05987   SLOTS_UNLOCK (connection);
05988 
05989   if (retval)
05990     {
05991       /* Do the actual free outside the connection lock */
05992       if (old_free_func)
05993         (* old_free_func) (old_data);
05994     }
05995 
05996   return retval;
05997 }
05998 
06016 void*
06017 dbus_connection_get_data (DBusConnection   *connection,
06018                           dbus_int32_t      slot)
06019 {
06020   void *res;
06021 
06022   _dbus_return_val_if_fail (connection != NULL, NULL);
06023   _dbus_return_val_if_fail (slot >= 0, NULL);
06024 
06025   SLOTS_LOCK (connection);
06026 
06027   res = _dbus_data_slot_list_get (&slot_allocator,
06028                                   &connection->slot_list,
06029                                   slot);
06030   
06031   SLOTS_UNLOCK (connection);
06032 
06033   return res;
06034 }
06035 
06042 void
06043 dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
06044 {  
06045   _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
06046 }
06047 
06056 void
06057 dbus_connection_set_max_message_size (DBusConnection *connection,
06058                                       long            size)
06059 {
06060   _dbus_return_if_fail (connection != NULL);
06061   
06062   CONNECTION_LOCK (connection);
06063   _dbus_transport_set_max_message_size (connection->transport,
06064                                         size);
06065   CONNECTION_UNLOCK (connection);
06066 }
06067 
06074 long
06075 dbus_connection_get_max_message_size (DBusConnection *connection)
06076 {
06077   long res;
06078 
06079   _dbus_return_val_if_fail (connection != NULL, 0);
06080   
06081   CONNECTION_LOCK (connection);
06082   res = _dbus_transport_get_max_message_size (connection->transport);
06083   CONNECTION_UNLOCK (connection);
06084   return res;
06085 }
06086 
06095 void
06096 dbus_connection_set_max_message_unix_fds (DBusConnection *connection,
06097                                           long            n)
06098 {
06099   _dbus_return_if_fail (connection != NULL);
06100 
06101   CONNECTION_LOCK (connection);
06102   _dbus_transport_set_max_message_unix_fds (connection->transport,
06103                                             n);
06104   CONNECTION_UNLOCK (connection);
06105 }
06106 
06113 long
06114 dbus_connection_get_max_message_unix_fds (DBusConnection *connection)
06115 {
06116   long res;
06117 
06118   _dbus_return_val_if_fail (connection != NULL, 0);
06119 
06120   CONNECTION_LOCK (connection);
06121   res = _dbus_transport_get_max_message_unix_fds (connection->transport);
06122   CONNECTION_UNLOCK (connection);
06123   return res;
06124 }
06125 
06151 void
06152 dbus_connection_set_max_received_size (DBusConnection *connection,
06153                                        long            size)
06154 {
06155   _dbus_return_if_fail (connection != NULL);
06156   
06157   CONNECTION_LOCK (connection);
06158   _dbus_transport_set_max_received_size (connection->transport,
06159                                          size);
06160   CONNECTION_UNLOCK (connection);
06161 }
06162 
06169 long
06170 dbus_connection_get_max_received_size (DBusConnection *connection)
06171 {
06172   long res;
06173 
06174   _dbus_return_val_if_fail (connection != NULL, 0);
06175   
06176   CONNECTION_LOCK (connection);
06177   res = _dbus_transport_get_max_received_size (connection->transport);
06178   CONNECTION_UNLOCK (connection);
06179   return res;
06180 }
06181 
06193 void
06194 dbus_connection_set_max_received_unix_fds (DBusConnection *connection,
06195                                            long            n)
06196 {
06197   _dbus_return_if_fail (connection != NULL);
06198 
06199   CONNECTION_LOCK (connection);
06200   _dbus_transport_set_max_received_unix_fds (connection->transport,
06201                                              n);
06202   CONNECTION_UNLOCK (connection);
06203 }
06204 
06211 long
06212 dbus_connection_get_max_received_unix_fds (DBusConnection *connection)
06213 {
06214   long res;
06215 
06216   _dbus_return_val_if_fail (connection != NULL, 0);
06217 
06218   CONNECTION_LOCK (connection);
06219   res = _dbus_transport_get_max_received_unix_fds (connection->transport);
06220   CONNECTION_UNLOCK (connection);
06221   return res;
06222 }
06223 
06234 long
06235 dbus_connection_get_outgoing_size (DBusConnection *connection)
06236 {
06237   long res;
06238 
06239   _dbus_return_val_if_fail (connection != NULL, 0);
06240 
06241   CONNECTION_LOCK (connection);
06242   res = _dbus_counter_get_size_value (connection->outgoing_counter);
06243   CONNECTION_UNLOCK (connection);
06244   return res;
06245 }
06246 
06247 #ifdef DBUS_ENABLE_STATS
06248 void
06249 _dbus_connection_get_stats (DBusConnection *connection,
06250                             dbus_uint32_t  *in_messages,
06251                             dbus_uint32_t  *in_bytes,
06252                             dbus_uint32_t  *in_fds,
06253                             dbus_uint32_t  *in_peak_bytes,
06254                             dbus_uint32_t  *in_peak_fds,
06255                             dbus_uint32_t  *out_messages,
06256                             dbus_uint32_t  *out_bytes,
06257                             dbus_uint32_t  *out_fds,
06258                             dbus_uint32_t  *out_peak_bytes,
06259                             dbus_uint32_t  *out_peak_fds)
06260 {
06261   CONNECTION_LOCK (connection);
06262 
06263   if (in_messages != NULL)
06264     *in_messages = connection->n_incoming;
06265 
06266   _dbus_transport_get_stats (connection->transport,
06267                              in_bytes, in_fds, in_peak_bytes, in_peak_fds);
06268 
06269   if (out_messages != NULL)
06270     *out_messages = connection->n_outgoing;
06271 
06272   if (out_bytes != NULL)
06273     *out_bytes = _dbus_counter_get_size_value (connection->outgoing_counter);
06274 
06275   if (out_fds != NULL)
06276     *out_fds = _dbus_counter_get_unix_fd_value (connection->outgoing_counter);
06277 
06278   if (out_peak_bytes != NULL)
06279     *out_peak_bytes = _dbus_counter_get_peak_size_value (connection->outgoing_counter);
06280 
06281   if (out_peak_fds != NULL)
06282     *out_peak_fds = _dbus_counter_get_peak_unix_fd_value (connection->outgoing_counter);
06283 
06284   CONNECTION_UNLOCK (connection);
06285 }
06286 #endif /* DBUS_ENABLE_STATS */
06287 
06295 long
06296 dbus_connection_get_outgoing_unix_fds (DBusConnection *connection)
06297 {
06298   long res;
06299 
06300   _dbus_return_val_if_fail (connection != NULL, 0);
06301 
06302   CONNECTION_LOCK (connection);
06303   res = _dbus_counter_get_unix_fd_value (connection->outgoing_counter);
06304   CONNECTION_UNLOCK (connection);
06305   return res;
06306 }
06307 
06308 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
06309 
06315 const char*
06316 _dbus_connection_get_address (DBusConnection *connection)
06317 {
06318   return _dbus_transport_get_address (connection->transport);
06319 }
06320 #endif
06321