D-Bus  1.10.12
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       DBusError error = DBUS_ERROR_INIT;
04440 
04441       if (!_dbus_string_init (&uuid))
04442         goto out;
04443 
04444       if (_dbus_get_local_machine_uuid_encoded (&uuid, &error))
04445         {
04446           const char *v_STRING;
04447 
04448           ret = dbus_message_new_method_return (message);
04449 
04450           if (ret == NULL)
04451             {
04452               _dbus_string_free (&uuid);
04453               goto out;
04454             }
04455 
04456           v_STRING = _dbus_string_get_const_data (&uuid);
04457           if (dbus_message_append_args (ret,
04458                                         DBUS_TYPE_STRING, &v_STRING,
04459                                         DBUS_TYPE_INVALID))
04460             {
04461               sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04462             }
04463         }
04464       else if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
04465         {
04466           dbus_error_free (&error);
04467           goto out;
04468         }
04469       else
04470         {
04471           ret = dbus_message_new_error (message, error.name, error.message);
04472           dbus_error_free (&error);
04473 
04474           if (ret == NULL)
04475             goto out;
04476 
04477           sent = _dbus_connection_send_unlocked_no_update (connection, ret,
04478                                                            NULL);
04479         }
04480 
04481       _dbus_string_free (&uuid);
04482     }
04483   else
04484     {
04485       /* We need to bounce anything else with this interface, otherwise apps
04486        * could start extending the interface and when we added extensions
04487        * here to DBusConnection we'd break those apps.
04488        */
04489       ret = dbus_message_new_error (message,
04490                                     DBUS_ERROR_UNKNOWN_METHOD,
04491                                     "Unknown method invoked on org.freedesktop.DBus.Peer interface");
04492       if (ret == NULL)
04493         goto out;
04494 
04495       sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04496     }
04497 
04498 out:
04499   if (ret == NULL)
04500     {
04501       _dbus_list_free_link (expire_link);
04502     }
04503   else
04504     {
04505       /* It'll be safe to unref the reply when we unlock */
04506       expire_link->data = ret;
04507       _dbus_list_prepend_link (&connection->expired_messages, expire_link);
04508     }
04509 
04510   if (!sent)
04511     return DBUS_HANDLER_RESULT_NEED_MEMORY;
04512 
04513   return DBUS_HANDLER_RESULT_HANDLED;
04514 }
04515 
04522 static DBusHandlerResult
04523 _dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection,
04524                                                            DBusMessage    *message)
04525 {
04526   /* We just run one filter for now but have the option to run more
04527      if the spec calls for it in the future */
04528 
04529   return _dbus_connection_peer_filter_unlocked_no_update (connection, message);
04530 }
04531 
04574 DBusDispatchStatus
04575 dbus_connection_dispatch (DBusConnection *connection)
04576 {
04577   DBusMessage *message;
04578   DBusList *link, *filter_list_copy, *message_link;
04579   DBusHandlerResult result;
04580   DBusPendingCall *pending;
04581   dbus_int32_t reply_serial;
04582   DBusDispatchStatus status;
04583   dbus_bool_t found_object;
04584 
04585   _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04586 
04587   _dbus_verbose ("\n");
04588   
04589   CONNECTION_LOCK (connection);
04590   status = _dbus_connection_get_dispatch_status_unlocked (connection);
04591   if (status != DBUS_DISPATCH_DATA_REMAINS)
04592     {
04593       /* unlocks and calls out to user code */
04594       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04595       return status;
04596     }
04597   
04598   /* We need to ref the connection since the callback could potentially
04599    * drop the last ref to it
04600    */
04601   _dbus_connection_ref_unlocked (connection);
04602 
04603   _dbus_connection_acquire_dispatch (connection);
04604   HAVE_LOCK_CHECK (connection);
04605 
04606   message_link = _dbus_connection_pop_message_link_unlocked (connection);
04607   if (message_link == NULL)
04608     {
04609       /* another thread dispatched our stuff */
04610 
04611       _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
04612       
04613       _dbus_connection_release_dispatch (connection);
04614 
04615       status = _dbus_connection_get_dispatch_status_unlocked (connection);
04616 
04617       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04618       
04619       dbus_connection_unref (connection);
04620       
04621       return status;
04622     }
04623 
04624   message = message_link->data;
04625 
04626   _dbus_verbose (" dispatching message %p (%s %s %s '%s')\n",
04627                  message,
04628                  dbus_message_type_to_string (dbus_message_get_type (message)),
04629                  dbus_message_get_interface (message) ?
04630                  dbus_message_get_interface (message) :
04631                  "no interface",
04632                  dbus_message_get_member (message) ?
04633                  dbus_message_get_member (message) :
04634                  "no member",
04635                  dbus_message_get_signature (message));
04636 
04637   result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04638   
04639   /* Pending call handling must be first, because if you do
04640    * dbus_connection_send_with_reply_and_block() or
04641    * dbus_pending_call_block() then no handlers/filters will be run on
04642    * the reply. We want consistent semantics in the case where we
04643    * dbus_connection_dispatch() the reply.
04644    */
04645   
04646   reply_serial = dbus_message_get_reply_serial (message);
04647   pending = _dbus_hash_table_lookup_int (connection->pending_replies,
04648                                          reply_serial);
04649   if (pending)
04650     {
04651       _dbus_verbose ("Dispatching a pending reply\n");
04652       complete_pending_call_and_unlock (connection, pending, message);
04653       pending = NULL; /* it's probably unref'd */
04654       
04655       CONNECTION_LOCK (connection);
04656       _dbus_verbose ("pending call completed in dispatch\n");
04657       result = DBUS_HANDLER_RESULT_HANDLED;
04658       goto out;
04659     }
04660 
04661   result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message);
04662   if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04663     goto out;
04664  
04665   if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
04666     {
04667       _dbus_connection_release_dispatch (connection);
04668       HAVE_LOCK_CHECK (connection);
04669       
04670       _dbus_connection_failed_pop (connection, message_link);
04671 
04672       /* unlocks and calls user code */
04673       _dbus_connection_update_dispatch_status_and_unlock (connection,
04674                                                           DBUS_DISPATCH_NEED_MEMORY);
04675       dbus_connection_unref (connection);
04676       
04677       return DBUS_DISPATCH_NEED_MEMORY;
04678     }
04679   
04680   _dbus_list_foreach (&filter_list_copy,
04681                       (DBusForeachFunction)_dbus_message_filter_ref,
04682                       NULL);
04683 
04684   /* We're still protected from dispatch() reentrancy here
04685    * since we acquired the dispatcher
04686    */
04687   CONNECTION_UNLOCK (connection);
04688   
04689   link = _dbus_list_get_first_link (&filter_list_copy);
04690   while (link != NULL)
04691     {
04692       DBusMessageFilter *filter = link->data;
04693       DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
04694 
04695       if (filter->function == NULL)
04696         {
04697           _dbus_verbose ("  filter was removed in a callback function\n");
04698           link = next;
04699           continue;
04700         }
04701 
04702       _dbus_verbose ("  running filter on message %p\n", message);
04703       result = (* filter->function) (connection, message, filter->user_data);
04704 
04705       if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04706         break;
04707 
04708       link = next;
04709     }
04710 
04711   _dbus_list_foreach (&filter_list_copy,
04712                       (DBusForeachFunction)_dbus_message_filter_unref,
04713                       NULL);
04714   _dbus_list_clear (&filter_list_copy);
04715   
04716   CONNECTION_LOCK (connection);
04717 
04718   if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04719     {
04720       _dbus_verbose ("No memory\n");
04721       goto out;
04722     }
04723   else if (result == DBUS_HANDLER_RESULT_HANDLED)
04724     {
04725       _dbus_verbose ("filter handled message in dispatch\n");
04726       goto out;
04727     }
04728 
04729   /* We're still protected from dispatch() reentrancy here
04730    * since we acquired the dispatcher
04731    */
04732   _dbus_verbose ("  running object path dispatch on message %p (%s %s %s '%s')\n",
04733                  message,
04734                  dbus_message_type_to_string (dbus_message_get_type (message)),
04735                  dbus_message_get_interface (message) ?
04736                  dbus_message_get_interface (message) :
04737                  "no interface",
04738                  dbus_message_get_member (message) ?
04739                  dbus_message_get_member (message) :
04740                  "no member",
04741                  dbus_message_get_signature (message));
04742 
04743   HAVE_LOCK_CHECK (connection);
04744   result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
04745                                                   message,
04746                                                   &found_object);
04747   
04748   CONNECTION_LOCK (connection);
04749 
04750   if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04751     {
04752       _dbus_verbose ("object tree handled message in dispatch\n");
04753       goto out;
04754     }
04755 
04756   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
04757     {
04758       DBusMessage *reply;
04759       DBusString str;
04760       DBusPreallocatedSend *preallocated;
04761       DBusList *expire_link;
04762 
04763       _dbus_verbose ("  sending error %s\n",
04764                      DBUS_ERROR_UNKNOWN_METHOD);
04765 
04766       if (!_dbus_string_init (&str))
04767         {
04768           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04769           _dbus_verbose ("no memory for error string in dispatch\n");
04770           goto out;
04771         }
04772               
04773       if (!_dbus_string_append_printf (&str,
04774                                        "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
04775                                        dbus_message_get_member (message),
04776                                        dbus_message_get_signature (message),
04777                                        dbus_message_get_interface (message)))
04778         {
04779           _dbus_string_free (&str);
04780           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04781           _dbus_verbose ("no memory for error string in dispatch\n");
04782           goto out;
04783         }
04784       
04785       reply = dbus_message_new_error (message,
04786                                       found_object ? DBUS_ERROR_UNKNOWN_METHOD : DBUS_ERROR_UNKNOWN_OBJECT,
04787                                       _dbus_string_get_const_data (&str));
04788       _dbus_string_free (&str);
04789 
04790       if (reply == NULL)
04791         {
04792           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04793           _dbus_verbose ("no memory for error reply in dispatch\n");
04794           goto out;
04795         }
04796 
04797       expire_link = _dbus_list_alloc_link (reply);
04798 
04799       if (expire_link == NULL)
04800         {
04801           dbus_message_unref (reply);
04802           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04803           _dbus_verbose ("no memory for error send in dispatch\n");
04804           goto out;
04805         }
04806 
04807       preallocated = _dbus_connection_preallocate_send_unlocked (connection);
04808 
04809       if (preallocated == NULL)
04810         {
04811           _dbus_list_free_link (expire_link);
04812           /* It's OK that this is finalized, because it hasn't been seen by
04813            * anything that could attach user callbacks */
04814           dbus_message_unref (reply);
04815           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04816           _dbus_verbose ("no memory for error send in dispatch\n");
04817           goto out;
04818         }
04819 
04820       _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
04821                                                              reply, NULL);
04822       /* reply will be freed when we release the lock */
04823       _dbus_list_prepend_link (&connection->expired_messages, expire_link);
04824 
04825       result = DBUS_HANDLER_RESULT_HANDLED;
04826     }
04827   
04828   _dbus_verbose ("  done dispatching %p (%s %s %s '%s') on connection %p\n", message,
04829                  dbus_message_type_to_string (dbus_message_get_type (message)),
04830                  dbus_message_get_interface (message) ?
04831                  dbus_message_get_interface (message) :
04832                  "no interface",
04833                  dbus_message_get_member (message) ?
04834                  dbus_message_get_member (message) :
04835                  "no member",
04836                  dbus_message_get_signature (message),
04837                  connection);
04838   
04839  out:
04840   if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04841     {
04842       _dbus_verbose ("out of memory\n");
04843       
04844       /* Put message back, and we'll start over.
04845        * Yes this means handlers must be idempotent if they
04846        * don't return HANDLED; c'est la vie.
04847        */
04848       _dbus_connection_putback_message_link_unlocked (connection,
04849                                                       message_link);
04850       /* now we don't want to free them */
04851       message_link = NULL;
04852       message = NULL;
04853     }
04854   else
04855     {
04856       _dbus_verbose (" ... done dispatching\n");
04857     }
04858 
04859   _dbus_connection_release_dispatch (connection);
04860   HAVE_LOCK_CHECK (connection);
04861 
04862   if (message != NULL)
04863     {
04864       /* We don't want this message to count in maximum message limits when
04865        * computing the dispatch status, below. We have to drop the lock
04866        * temporarily, because finalizing a message can trigger callbacks.
04867        *
04868        * We have a reference to the connection, and we don't use any cached
04869        * pointers to the connection's internals below this point, so it should
04870        * be safe to drop the lock and take it back. */
04871       CONNECTION_UNLOCK (connection);
04872       dbus_message_unref (message);
04873       CONNECTION_LOCK (connection);
04874     }
04875 
04876   if (message_link != NULL)
04877     _dbus_list_free_link (message_link);
04878 
04879   _dbus_verbose ("before final status update\n");
04880   status = _dbus_connection_get_dispatch_status_unlocked (connection);
04881 
04882   /* unlocks and calls user code */
04883   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04884   
04885   dbus_connection_unref (connection);
04886   
04887   return status;
04888 }
04889 
04951 dbus_bool_t
04952 dbus_connection_set_watch_functions (DBusConnection              *connection,
04953                                      DBusAddWatchFunction         add_function,
04954                                      DBusRemoveWatchFunction      remove_function,
04955                                      DBusWatchToggledFunction     toggled_function,
04956                                      void                        *data,
04957                                      DBusFreeFunction             free_data_function)
04958 {
04959   dbus_bool_t retval;
04960 
04961   _dbus_return_val_if_fail (connection != NULL, FALSE);
04962   
04963   CONNECTION_LOCK (connection);
04964 
04965   retval = _dbus_watch_list_set_functions (connection->watches,
04966                                            add_function, remove_function,
04967                                            toggled_function,
04968                                            data, free_data_function);
04969 
04970   CONNECTION_UNLOCK (connection);
04971 
04972   return retval;
04973 }
04974 
05014 dbus_bool_t
05015 dbus_connection_set_timeout_functions   (DBusConnection            *connection,
05016                                          DBusAddTimeoutFunction     add_function,
05017                                          DBusRemoveTimeoutFunction  remove_function,
05018                                          DBusTimeoutToggledFunction toggled_function,
05019                                          void                      *data,
05020                                          DBusFreeFunction           free_data_function)
05021 {
05022   dbus_bool_t retval;
05023 
05024   _dbus_return_val_if_fail (connection != NULL, FALSE);
05025   
05026   CONNECTION_LOCK (connection);
05027 
05028   retval = _dbus_timeout_list_set_functions (connection->timeouts,
05029                                              add_function, remove_function,
05030                                              toggled_function,
05031                                              data, free_data_function);
05032 
05033   CONNECTION_UNLOCK (connection);
05034 
05035   return retval;
05036 }
05037 
05052 void
05053 dbus_connection_set_wakeup_main_function (DBusConnection            *connection,
05054                                           DBusWakeupMainFunction     wakeup_main_function,
05055                                           void                      *data,
05056                                           DBusFreeFunction           free_data_function)
05057 {
05058   void *old_data;
05059   DBusFreeFunction old_free_data;
05060 
05061   _dbus_return_if_fail (connection != NULL);
05062   
05063   CONNECTION_LOCK (connection);
05064   old_data = connection->wakeup_main_data;
05065   old_free_data = connection->free_wakeup_main_data;
05066 
05067   connection->wakeup_main_function = wakeup_main_function;
05068   connection->wakeup_main_data = data;
05069   connection->free_wakeup_main_data = free_data_function;
05070   
05071   CONNECTION_UNLOCK (connection);
05072 
05073   /* Callback outside the lock */
05074   if (old_free_data)
05075     (*old_free_data) (old_data);
05076 }
05077 
05098 void
05099 dbus_connection_set_dispatch_status_function (DBusConnection             *connection,
05100                                               DBusDispatchStatusFunction  function,
05101                                               void                       *data,
05102                                               DBusFreeFunction            free_data_function)
05103 {
05104   void *old_data;
05105   DBusFreeFunction old_free_data;
05106 
05107   _dbus_return_if_fail (connection != NULL);
05108   
05109   CONNECTION_LOCK (connection);
05110   old_data = connection->dispatch_status_data;
05111   old_free_data = connection->free_dispatch_status_data;
05112 
05113   connection->dispatch_status_function = function;
05114   connection->dispatch_status_data = data;
05115   connection->free_dispatch_status_data = free_data_function;
05116   
05117   CONNECTION_UNLOCK (connection);
05118 
05119   /* Callback outside the lock */
05120   if (old_free_data)
05121     (*old_free_data) (old_data);
05122 }
05123 
05143 dbus_bool_t
05144 dbus_connection_get_unix_fd (DBusConnection *connection,
05145                              int            *fd)
05146 {
05147   _dbus_return_val_if_fail (connection != NULL, FALSE);
05148   _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
05149 
05150 #ifdef DBUS_WIN
05151   /* FIXME do this on a lower level */
05152   return FALSE;
05153 #endif
05154   
05155   return dbus_connection_get_socket(connection, fd);
05156 }
05157 
05173 dbus_bool_t
05174 dbus_connection_get_socket(DBusConnection              *connection,
05175                            int                         *fd)
05176 {
05177   dbus_bool_t retval;
05178   DBusSocket s = DBUS_SOCKET_INIT;
05179 
05180   _dbus_return_val_if_fail (connection != NULL, FALSE);
05181   _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
05182   
05183   CONNECTION_LOCK (connection);
05184   
05185   retval = _dbus_transport_get_socket_fd (connection->transport, &s);
05186 
05187   if (retval)
05188     {
05189       *fd = _dbus_socket_get_int (s);
05190     }
05191 
05192   CONNECTION_UNLOCK (connection);
05193 
05194   return retval;
05195 }
05196 
05197 
05220 dbus_bool_t
05221 dbus_connection_get_unix_user (DBusConnection *connection,
05222                                unsigned long  *uid)
05223 {
05224   dbus_bool_t result;
05225 
05226   _dbus_return_val_if_fail (connection != NULL, FALSE);
05227   _dbus_return_val_if_fail (uid != NULL, FALSE);
05228 
05229   CONNECTION_LOCK (connection);
05230 
05231   if (!_dbus_transport_try_to_authenticate (connection->transport))
05232     result = FALSE;
05233   else
05234     result = _dbus_transport_get_unix_user (connection->transport,
05235                                             uid);
05236 
05237 #ifdef DBUS_WIN
05238   _dbus_assert (!result);
05239 #endif
05240   
05241   CONNECTION_UNLOCK (connection);
05242 
05243   return result;
05244 }
05245 
05256 dbus_bool_t
05257 dbus_connection_get_unix_process_id (DBusConnection *connection,
05258                                      unsigned long  *pid)
05259 {
05260   dbus_bool_t result;
05261 
05262   _dbus_return_val_if_fail (connection != NULL, FALSE);
05263   _dbus_return_val_if_fail (pid != NULL, FALSE);
05264 
05265   CONNECTION_LOCK (connection);
05266 
05267   if (!_dbus_transport_try_to_authenticate (connection->transport))
05268     result = FALSE;
05269   else
05270     result = _dbus_transport_get_unix_process_id (connection->transport,
05271                                                   pid);
05272 
05273   CONNECTION_UNLOCK (connection);
05274 
05275   return result;
05276 }
05277 
05289 dbus_bool_t
05290 dbus_connection_get_adt_audit_session_data (DBusConnection *connection,
05291                                             void          **data,
05292                                             dbus_int32_t   *data_size)
05293 {
05294   dbus_bool_t result;
05295 
05296   _dbus_return_val_if_fail (connection != NULL, FALSE);
05297   _dbus_return_val_if_fail (data != NULL, FALSE);
05298   _dbus_return_val_if_fail (data_size != NULL, FALSE);
05299 
05300   CONNECTION_LOCK (connection);
05301 
05302   if (!_dbus_transport_try_to_authenticate (connection->transport))
05303     result = FALSE;
05304   else
05305     result = _dbus_transport_get_adt_audit_session_data (connection->transport,
05306                                                          data,
05307                                                          data_size);
05308   CONNECTION_UNLOCK (connection);
05309 
05310   return result;
05311 }
05312 
05335 void
05336 dbus_connection_set_unix_user_function (DBusConnection             *connection,
05337                                         DBusAllowUnixUserFunction   function,
05338                                         void                       *data,
05339                                         DBusFreeFunction            free_data_function)
05340 {
05341   void *old_data = NULL;
05342   DBusFreeFunction old_free_function = NULL;
05343 
05344   _dbus_return_if_fail (connection != NULL);
05345   
05346   CONNECTION_LOCK (connection);
05347   _dbus_transport_set_unix_user_function (connection->transport,
05348                                           function, data, free_data_function,
05349                                           &old_data, &old_free_function);
05350   CONNECTION_UNLOCK (connection);
05351 
05352   if (old_free_function != NULL)
05353     (* old_free_function) (old_data);
05354 }
05355 
05356 /* Same calling convention as dbus_connection_get_windows_user */
05357 dbus_bool_t
05358 _dbus_connection_get_linux_security_label (DBusConnection  *connection,
05359                                            char           **label_p)
05360 {
05361   dbus_bool_t result;
05362 
05363   _dbus_assert (connection != NULL);
05364   _dbus_assert (label_p != NULL);
05365 
05366   CONNECTION_LOCK (connection);
05367 
05368   if (!_dbus_transport_try_to_authenticate (connection->transport))
05369     result = FALSE;
05370   else
05371     result = _dbus_transport_get_linux_security_label (connection->transport,
05372                                                        label_p);
05373 #ifndef __linux__
05374   _dbus_assert (!result);
05375 #endif
05376 
05377   CONNECTION_UNLOCK (connection);
05378 
05379   return result;
05380 }
05381 
05413 dbus_bool_t
05414 dbus_connection_get_windows_user (DBusConnection             *connection,
05415                                   char                      **windows_sid_p)
05416 {
05417   dbus_bool_t result;
05418 
05419   _dbus_return_val_if_fail (connection != NULL, FALSE);
05420   _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
05421 
05422   CONNECTION_LOCK (connection);
05423 
05424   if (!_dbus_transport_try_to_authenticate (connection->transport))
05425     result = FALSE;
05426   else
05427     result = _dbus_transport_get_windows_user (connection->transport,
05428                                                windows_sid_p);
05429 
05430 #ifdef DBUS_UNIX
05431   _dbus_assert (!result);
05432 #endif
05433   
05434   CONNECTION_UNLOCK (connection);
05435 
05436   return result;
05437 }
05438 
05460 void
05461 dbus_connection_set_windows_user_function (DBusConnection              *connection,
05462                                            DBusAllowWindowsUserFunction function,
05463                                            void                        *data,
05464                                            DBusFreeFunction             free_data_function)
05465 {
05466   void *old_data = NULL;
05467   DBusFreeFunction old_free_function = NULL;
05468 
05469   _dbus_return_if_fail (connection != NULL);
05470   
05471   CONNECTION_LOCK (connection);
05472   _dbus_transport_set_windows_user_function (connection->transport,
05473                                              function, data, free_data_function,
05474                                              &old_data, &old_free_function);
05475   CONNECTION_UNLOCK (connection);
05476 
05477   if (old_free_function != NULL)
05478     (* old_free_function) (old_data);
05479 }
05480 
05507 void
05508 dbus_connection_set_allow_anonymous (DBusConnection             *connection,
05509                                      dbus_bool_t                 value)
05510 {
05511   _dbus_return_if_fail (connection != NULL);
05512   
05513   CONNECTION_LOCK (connection);
05514   _dbus_transport_set_allow_anonymous (connection->transport, value);
05515   CONNECTION_UNLOCK (connection);
05516 }
05517 
05535 void
05536 dbus_connection_set_route_peer_messages (DBusConnection             *connection,
05537                                          dbus_bool_t                 value)
05538 {
05539   _dbus_return_if_fail (connection != NULL);
05540   
05541   CONNECTION_LOCK (connection);
05542   connection->route_peer_messages = value;
05543   CONNECTION_UNLOCK (connection);
05544 }
05545 
05567 dbus_bool_t
05568 dbus_connection_add_filter (DBusConnection            *connection,
05569                             DBusHandleMessageFunction  function,
05570                             void                      *user_data,
05571                             DBusFreeFunction           free_data_function)
05572 {
05573   DBusMessageFilter *filter;
05574   
05575   _dbus_return_val_if_fail (connection != NULL, FALSE);
05576   _dbus_return_val_if_fail (function != NULL, FALSE);
05577 
05578   filter = dbus_new0 (DBusMessageFilter, 1);
05579   if (filter == NULL)
05580     return FALSE;
05581 
05582   _dbus_atomic_inc (&filter->refcount);
05583 
05584   CONNECTION_LOCK (connection);
05585 
05586   if (!_dbus_list_append (&connection->filter_list,
05587                           filter))
05588     {
05589       _dbus_message_filter_unref (filter);
05590       CONNECTION_UNLOCK (connection);
05591       return FALSE;
05592     }
05593 
05594   /* Fill in filter after all memory allocated,
05595    * so we don't run the free_user_data_function
05596    * if the add_filter() fails
05597    */
05598   
05599   filter->function = function;
05600   filter->user_data = user_data;
05601   filter->free_user_data_function = free_data_function;
05602         
05603   CONNECTION_UNLOCK (connection);
05604   return TRUE;
05605 }
05606 
05619 void
05620 dbus_connection_remove_filter (DBusConnection            *connection,
05621                                DBusHandleMessageFunction  function,
05622                                void                      *user_data)
05623 {
05624   DBusList *link;
05625   DBusMessageFilter *filter;
05626   
05627   _dbus_return_if_fail (connection != NULL);
05628   _dbus_return_if_fail (function != NULL);
05629   
05630   CONNECTION_LOCK (connection);
05631 
05632   filter = NULL;
05633   
05634   link = _dbus_list_get_last_link (&connection->filter_list);
05635   while (link != NULL)
05636     {
05637       filter = link->data;
05638 
05639       if (filter->function == function &&
05640           filter->user_data == user_data)
05641         {
05642           _dbus_list_remove_link (&connection->filter_list, link);
05643           filter->function = NULL;
05644           
05645           break;
05646         }
05647         
05648       link = _dbus_list_get_prev_link (&connection->filter_list, link);
05649       filter = NULL;
05650     }
05651   
05652   CONNECTION_UNLOCK (connection);
05653 
05654 #ifndef DBUS_DISABLE_CHECKS
05655   if (filter == NULL)
05656     {
05657       _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
05658                                function, user_data);
05659       return;
05660     }
05661 #endif
05662   
05663   /* Call application code */
05664   if (filter->free_user_data_function)
05665     (* filter->free_user_data_function) (filter->user_data);
05666 
05667   filter->free_user_data_function = NULL;
05668   filter->user_data = NULL;
05669   
05670   _dbus_message_filter_unref (filter);
05671 }
05672 
05688 static dbus_bool_t
05689 _dbus_connection_register_object_path (DBusConnection              *connection,
05690                                        dbus_bool_t                  fallback,
05691                                        const char                  *path,
05692                                        const DBusObjectPathVTable  *vtable,
05693                                        void                        *user_data,
05694                                        DBusError                   *error)
05695 {
05696   char **decomposed_path;
05697   dbus_bool_t retval;
05698 
05699   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05700     return FALSE;
05701 
05702   CONNECTION_LOCK (connection);
05703 
05704   retval = _dbus_object_tree_register (connection->objects,
05705                                        fallback,
05706                                        (const char **) decomposed_path, vtable,
05707                                        user_data, error);
05708 
05709   CONNECTION_UNLOCK (connection);
05710 
05711   dbus_free_string_array (decomposed_path);
05712 
05713   return retval;
05714 }
05715 
05728 dbus_bool_t
05729 dbus_connection_try_register_object_path (DBusConnection              *connection,
05730                                           const char                  *path,
05731                                           const DBusObjectPathVTable  *vtable,
05732                                           void                        *user_data,
05733                                           DBusError                   *error)
05734 {
05735   _dbus_return_val_if_fail (connection != NULL, FALSE);
05736   _dbus_return_val_if_fail (path != NULL, FALSE);
05737   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05738   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05739 
05740   return _dbus_connection_register_object_path (connection, FALSE, path, vtable, user_data, error);
05741 }
05742 
05758 dbus_bool_t
05759 dbus_connection_register_object_path (DBusConnection              *connection,
05760                                       const char                  *path,
05761                                       const DBusObjectPathVTable  *vtable,
05762                                       void                        *user_data)
05763 {
05764   dbus_bool_t retval;
05765   DBusError error = DBUS_ERROR_INIT;
05766 
05767   _dbus_return_val_if_fail (connection != NULL, FALSE);
05768   _dbus_return_val_if_fail (path != NULL, FALSE);
05769   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05770   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05771 
05772   retval = _dbus_connection_register_object_path (connection, FALSE, path, vtable, user_data, &error);
05773 
05774   if (dbus_error_has_name (&error, DBUS_ERROR_OBJECT_PATH_IN_USE))
05775     {
05776       _dbus_warn ("%s\n", error.message);
05777       dbus_error_free (&error);
05778       return FALSE;
05779     }
05780 
05781   return retval;
05782 }
05783 
05798 dbus_bool_t
05799 dbus_connection_try_register_fallback (DBusConnection              *connection,
05800                                        const char                  *path,
05801                                        const DBusObjectPathVTable  *vtable,
05802                                        void                        *user_data,
05803                                        DBusError                   *error)
05804 {
05805   _dbus_return_val_if_fail (connection != NULL, FALSE);
05806   _dbus_return_val_if_fail (path != NULL, FALSE);
05807   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05808   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05809 
05810   return _dbus_connection_register_object_path (connection, TRUE, path, vtable, user_data, error);
05811 }
05812 
05830 dbus_bool_t
05831 dbus_connection_register_fallback (DBusConnection              *connection,
05832                                    const char                  *path,
05833                                    const DBusObjectPathVTable  *vtable,
05834                                    void                        *user_data)
05835 {
05836   dbus_bool_t retval;
05837   DBusError error = DBUS_ERROR_INIT;
05838 
05839   _dbus_return_val_if_fail (connection != NULL, FALSE);
05840   _dbus_return_val_if_fail (path != NULL, FALSE);
05841   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05842   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05843 
05844   retval = _dbus_connection_register_object_path (connection, TRUE, path, vtable, user_data, &error);
05845 
05846   if (dbus_error_has_name (&error, DBUS_ERROR_OBJECT_PATH_IN_USE))
05847     {
05848       _dbus_warn ("%s\n", error.message);
05849       dbus_error_free (&error);
05850       return FALSE;
05851     }
05852 
05853   return retval;
05854 }
05855 
05865 dbus_bool_t
05866 dbus_connection_unregister_object_path (DBusConnection              *connection,
05867                                         const char                  *path)
05868 {
05869   char **decomposed_path;
05870 
05871   _dbus_return_val_if_fail (connection != NULL, FALSE);
05872   _dbus_return_val_if_fail (path != NULL, FALSE);
05873   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05874 
05875   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05876       return FALSE;
05877 
05878   CONNECTION_LOCK (connection);
05879 
05880   _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
05881 
05882   dbus_free_string_array (decomposed_path);
05883 
05884   return TRUE;
05885 }
05886 
05897 dbus_bool_t
05898 dbus_connection_get_object_path_data (DBusConnection *connection,
05899                                       const char     *path,
05900                                       void          **data_p)
05901 {
05902   char **decomposed_path;
05903 
05904   _dbus_return_val_if_fail (connection != NULL, FALSE);
05905   _dbus_return_val_if_fail (path != NULL, FALSE);
05906   _dbus_return_val_if_fail (data_p != NULL, FALSE);
05907 
05908   *data_p = NULL;
05909   
05910   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05911     return FALSE;
05912   
05913   CONNECTION_LOCK (connection);
05914 
05915   *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path);
05916 
05917   CONNECTION_UNLOCK (connection);
05918 
05919   dbus_free_string_array (decomposed_path);
05920 
05921   return TRUE;
05922 }
05923 
05934 dbus_bool_t
05935 dbus_connection_list_registered (DBusConnection              *connection,
05936                                  const char                  *parent_path,
05937                                  char                      ***child_entries)
05938 {
05939   char **decomposed_path;
05940   dbus_bool_t retval;
05941   _dbus_return_val_if_fail (connection != NULL, FALSE);
05942   _dbus_return_val_if_fail (parent_path != NULL, FALSE);
05943   _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
05944   _dbus_return_val_if_fail (child_entries != NULL, FALSE);
05945 
05946   if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
05947     return FALSE;
05948 
05949   CONNECTION_LOCK (connection);
05950 
05951   retval = _dbus_object_tree_list_registered_and_unlock (connection->objects,
05952                                                          (const char **) decomposed_path,
05953                                                          child_entries);
05954   dbus_free_string_array (decomposed_path);
05955 
05956   return retval;
05957 }
05958 
05959 static DBusDataSlotAllocator slot_allocator =
05960   _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (connection_slots));
05961 
05976 dbus_bool_t
05977 dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
05978 {
05979   return _dbus_data_slot_allocator_alloc (&slot_allocator,
05980                                           slot_p);
05981 }
05982 
05994 void
05995 dbus_connection_free_data_slot (dbus_int32_t *slot_p)
05996 {
05997   _dbus_return_if_fail (*slot_p >= 0);
05998   
05999   _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
06000 }
06001 
06024 dbus_bool_t
06025 dbus_connection_set_data (DBusConnection   *connection,
06026                           dbus_int32_t      slot,
06027                           void             *data,
06028                           DBusFreeFunction  free_data_func)
06029 {
06030   DBusFreeFunction old_free_func;
06031   void *old_data;
06032   dbus_bool_t retval;
06033 
06034   _dbus_return_val_if_fail (connection != NULL, FALSE);
06035   _dbus_return_val_if_fail (slot >= 0, FALSE);
06036   
06037   SLOTS_LOCK (connection);
06038 
06039   retval = _dbus_data_slot_list_set (&slot_allocator,
06040                                      &connection->slot_list,
06041                                      slot, data, free_data_func,
06042                                      &old_free_func, &old_data);
06043   
06044   SLOTS_UNLOCK (connection);
06045 
06046   if (retval)
06047     {
06048       /* Do the actual free outside the connection lock */
06049       if (old_free_func)
06050         (* old_free_func) (old_data);
06051     }
06052 
06053   return retval;
06054 }
06055 
06073 void*
06074 dbus_connection_get_data (DBusConnection   *connection,
06075                           dbus_int32_t      slot)
06076 {
06077   void *res;
06078 
06079   _dbus_return_val_if_fail (connection != NULL, NULL);
06080   _dbus_return_val_if_fail (slot >= 0, NULL);
06081 
06082   SLOTS_LOCK (connection);
06083 
06084   res = _dbus_data_slot_list_get (&slot_allocator,
06085                                   &connection->slot_list,
06086                                   slot);
06087   
06088   SLOTS_UNLOCK (connection);
06089 
06090   return res;
06091 }
06092 
06099 void
06100 dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
06101 {  
06102   _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
06103 }
06104 
06113 void
06114 dbus_connection_set_max_message_size (DBusConnection *connection,
06115                                       long            size)
06116 {
06117   _dbus_return_if_fail (connection != NULL);
06118   
06119   CONNECTION_LOCK (connection);
06120   _dbus_transport_set_max_message_size (connection->transport,
06121                                         size);
06122   CONNECTION_UNLOCK (connection);
06123 }
06124 
06131 long
06132 dbus_connection_get_max_message_size (DBusConnection *connection)
06133 {
06134   long res;
06135 
06136   _dbus_return_val_if_fail (connection != NULL, 0);
06137   
06138   CONNECTION_LOCK (connection);
06139   res = _dbus_transport_get_max_message_size (connection->transport);
06140   CONNECTION_UNLOCK (connection);
06141   return res;
06142 }
06143 
06152 void
06153 dbus_connection_set_max_message_unix_fds (DBusConnection *connection,
06154                                           long            n)
06155 {
06156   _dbus_return_if_fail (connection != NULL);
06157 
06158   CONNECTION_LOCK (connection);
06159   _dbus_transport_set_max_message_unix_fds (connection->transport,
06160                                             n);
06161   CONNECTION_UNLOCK (connection);
06162 }
06163 
06170 long
06171 dbus_connection_get_max_message_unix_fds (DBusConnection *connection)
06172 {
06173   long res;
06174 
06175   _dbus_return_val_if_fail (connection != NULL, 0);
06176 
06177   CONNECTION_LOCK (connection);
06178   res = _dbus_transport_get_max_message_unix_fds (connection->transport);
06179   CONNECTION_UNLOCK (connection);
06180   return res;
06181 }
06182 
06208 void
06209 dbus_connection_set_max_received_size (DBusConnection *connection,
06210                                        long            size)
06211 {
06212   _dbus_return_if_fail (connection != NULL);
06213   
06214   CONNECTION_LOCK (connection);
06215   _dbus_transport_set_max_received_size (connection->transport,
06216                                          size);
06217   CONNECTION_UNLOCK (connection);
06218 }
06219 
06226 long
06227 dbus_connection_get_max_received_size (DBusConnection *connection)
06228 {
06229   long res;
06230 
06231   _dbus_return_val_if_fail (connection != NULL, 0);
06232   
06233   CONNECTION_LOCK (connection);
06234   res = _dbus_transport_get_max_received_size (connection->transport);
06235   CONNECTION_UNLOCK (connection);
06236   return res;
06237 }
06238 
06250 void
06251 dbus_connection_set_max_received_unix_fds (DBusConnection *connection,
06252                                            long            n)
06253 {
06254   _dbus_return_if_fail (connection != NULL);
06255 
06256   CONNECTION_LOCK (connection);
06257   _dbus_transport_set_max_received_unix_fds (connection->transport,
06258                                              n);
06259   CONNECTION_UNLOCK (connection);
06260 }
06261 
06268 long
06269 dbus_connection_get_max_received_unix_fds (DBusConnection *connection)
06270 {
06271   long res;
06272 
06273   _dbus_return_val_if_fail (connection != NULL, 0);
06274 
06275   CONNECTION_LOCK (connection);
06276   res = _dbus_transport_get_max_received_unix_fds (connection->transport);
06277   CONNECTION_UNLOCK (connection);
06278   return res;
06279 }
06280 
06291 long
06292 dbus_connection_get_outgoing_size (DBusConnection *connection)
06293 {
06294   long res;
06295 
06296   _dbus_return_val_if_fail (connection != NULL, 0);
06297 
06298   CONNECTION_LOCK (connection);
06299   res = _dbus_counter_get_size_value (connection->outgoing_counter);
06300   CONNECTION_UNLOCK (connection);
06301   return res;
06302 }
06303 
06304 #ifdef DBUS_ENABLE_STATS
06305 void
06306 _dbus_connection_get_stats (DBusConnection *connection,
06307                             dbus_uint32_t  *in_messages,
06308                             dbus_uint32_t  *in_bytes,
06309                             dbus_uint32_t  *in_fds,
06310                             dbus_uint32_t  *in_peak_bytes,
06311                             dbus_uint32_t  *in_peak_fds,
06312                             dbus_uint32_t  *out_messages,
06313                             dbus_uint32_t  *out_bytes,
06314                             dbus_uint32_t  *out_fds,
06315                             dbus_uint32_t  *out_peak_bytes,
06316                             dbus_uint32_t  *out_peak_fds)
06317 {
06318   CONNECTION_LOCK (connection);
06319 
06320   if (in_messages != NULL)
06321     *in_messages = connection->n_incoming;
06322 
06323   _dbus_transport_get_stats (connection->transport,
06324                              in_bytes, in_fds, in_peak_bytes, in_peak_fds);
06325 
06326   if (out_messages != NULL)
06327     *out_messages = connection->n_outgoing;
06328 
06329   if (out_bytes != NULL)
06330     *out_bytes = _dbus_counter_get_size_value (connection->outgoing_counter);
06331 
06332   if (out_fds != NULL)
06333     *out_fds = _dbus_counter_get_unix_fd_value (connection->outgoing_counter);
06334 
06335   if (out_peak_bytes != NULL)
06336     *out_peak_bytes = _dbus_counter_get_peak_size_value (connection->outgoing_counter);
06337 
06338   if (out_peak_fds != NULL)
06339     *out_peak_fds = _dbus_counter_get_peak_unix_fd_value (connection->outgoing_counter);
06340 
06341   CONNECTION_UNLOCK (connection);
06342 }
06343 #endif /* DBUS_ENABLE_STATS */
06344 
06352 long
06353 dbus_connection_get_outgoing_unix_fds (DBusConnection *connection)
06354 {
06355   long res;
06356 
06357   _dbus_return_val_if_fail (connection != NULL, 0);
06358 
06359   CONNECTION_LOCK (connection);
06360   res = _dbus_counter_get_unix_fd_value (connection->outgoing_counter);
06361   CONNECTION_UNLOCK (connection);
06362   return res;
06363 }
06364 
06365 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
06366 
06372 const char*
06373 _dbus_connection_get_address (DBusConnection *connection)
06374 {
06375   return _dbus_transport_get_address (connection->transport);
06376 }
06377 #endif
06378