D-Bus 1.4.6
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-pending-call.h"
00042 #include "dbus-object-tree.h"
00043 #include "dbus-threads-internal.h"
00044 #include "dbus-bus.h"
00045 #include "dbus-marshal-basic.h"
00046 
00047 #ifdef DBUS_DISABLE_CHECKS
00048 #define TOOK_LOCK_CHECK(connection)
00049 #define RELEASING_LOCK_CHECK(connection)
00050 #define HAVE_LOCK_CHECK(connection)
00051 #else
00052 #define TOOK_LOCK_CHECK(connection) do {                \
00053     _dbus_assert (!(connection)->have_connection_lock); \
00054     (connection)->have_connection_lock = TRUE;          \
00055   } while (0)
00056 #define RELEASING_LOCK_CHECK(connection) do {            \
00057     _dbus_assert ((connection)->have_connection_lock);   \
00058     (connection)->have_connection_lock = FALSE;          \
00059   } while (0)
00060 #define HAVE_LOCK_CHECK(connection)        _dbus_assert ((connection)->have_connection_lock)
00061 /* A "DO_NOT_HAVE_LOCK_CHECK" is impossible since we need the lock to check the flag */
00062 #endif
00063 
00064 #define TRACE_LOCKS 1
00065 
00066 #define CONNECTION_LOCK(connection)   do {                                      \
00067     if (TRACE_LOCKS) { _dbus_verbose ("LOCK\n"); }   \
00068     _dbus_mutex_lock ((connection)->mutex);                                      \
00069     TOOK_LOCK_CHECK (connection);                                               \
00070   } while (0)
00071 
00072 #define CONNECTION_UNLOCK(connection) do {                                              \
00073     if (TRACE_LOCKS) { _dbus_verbose ("UNLOCK\n");  }        \
00074     RELEASING_LOCK_CHECK (connection);                                                  \
00075     _dbus_mutex_unlock ((connection)->mutex);                                            \
00076   } while (0)
00077 
00078 #define SLOTS_LOCK(connection) do {                     \
00079     _dbus_mutex_lock ((connection)->slot_mutex);        \
00080   } while (0)
00081 
00082 #define SLOTS_UNLOCK(connection) do {                   \
00083     _dbus_mutex_unlock ((connection)->slot_mutex);      \
00084   } while (0)
00085 
00086 #define DISPATCH_STATUS_NAME(s)                                            \
00087                      ((s) == DBUS_DISPATCH_COMPLETE ? "complete" :         \
00088                       (s) == DBUS_DISPATCH_DATA_REMAINS ? "data remains" : \
00089                       (s) == DBUS_DISPATCH_NEED_MEMORY ? "need memory" :   \
00090                       "???")
00091 
00212 typedef struct DBusMessageFilter DBusMessageFilter;
00213 
00217 struct DBusMessageFilter
00218 {
00219   DBusAtomic refcount; 
00220   DBusHandleMessageFunction function; 
00221   void *user_data; 
00222   DBusFreeFunction free_user_data_function; 
00223 };
00224 
00225 
00229 struct DBusPreallocatedSend
00230 {
00231   DBusConnection *connection; 
00232   DBusList *queue_link;       
00233   DBusList *counter_link;     
00234 };
00235 
00236 #if HAVE_DECL_MSG_NOSIGNAL
00237 static dbus_bool_t _dbus_modify_sigpipe = FALSE;
00238 #else
00239 static dbus_bool_t _dbus_modify_sigpipe = TRUE;
00240 #endif
00241 
00245 struct DBusConnection
00246 {
00247   DBusAtomic refcount; 
00249   DBusMutex *mutex; 
00251   DBusMutex *dispatch_mutex;     
00252   DBusCondVar *dispatch_cond;    
00253   DBusMutex *io_path_mutex;      
00254   DBusCondVar *io_path_cond;     
00256   DBusList *outgoing_messages; 
00257   DBusList *incoming_messages; 
00259   DBusMessage *message_borrowed; 
00263   int n_outgoing;              
00264   int n_incoming;              
00266   DBusCounter *outgoing_counter; 
00268   DBusTransport *transport;    
00269   DBusWatchList *watches;      
00270   DBusTimeoutList *timeouts;   
00272   DBusList *filter_list;        
00274   DBusMutex *slot_mutex;        
00275   DBusDataSlotList slot_list;   
00277   DBusHashTable *pending_replies;  
00279   dbus_uint32_t client_serial;       
00280   DBusList *disconnect_message_link; 
00282   DBusWakeupMainFunction wakeup_main_function; 
00283   void *wakeup_main_data; 
00284   DBusFreeFunction free_wakeup_main_data; 
00286   DBusDispatchStatusFunction dispatch_status_function; 
00287   void *dispatch_status_data; 
00288   DBusFreeFunction free_dispatch_status_data; 
00290   DBusDispatchStatus last_dispatch_status; 
00292   DBusList *link_cache; 
00295   DBusObjectTree *objects; 
00297   char *server_guid; 
00299   /* These two MUST be bools and not bitfields, because they are protected by a separate lock
00300    * from connection->mutex and all bitfields in a word have to be read/written together.
00301    * So you can't have a different lock for different bitfields in the same word.
00302    */
00303   dbus_bool_t dispatch_acquired; 
00304   dbus_bool_t io_path_acquired;  
00306   unsigned int shareable : 1; 
00308   unsigned int exit_on_disconnect : 1; 
00310   unsigned int route_peer_messages : 1; 
00312   unsigned int disconnected_message_arrived : 1;   
00316   unsigned int disconnected_message_processed : 1; 
00320 #ifndef DBUS_DISABLE_CHECKS
00321   unsigned int have_connection_lock : 1; 
00322 #endif
00323   
00324 #ifndef DBUS_DISABLE_CHECKS
00325   int generation; 
00326 #endif 
00327 };
00328 
00329 static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked      (DBusConnection     *connection);
00330 static void               _dbus_connection_update_dispatch_status_and_unlock (DBusConnection     *connection,
00331                                                                               DBusDispatchStatus  new_status);
00332 static void               _dbus_connection_last_unref                        (DBusConnection     *connection);
00333 static void               _dbus_connection_acquire_dispatch                  (DBusConnection     *connection);
00334 static void               _dbus_connection_release_dispatch                  (DBusConnection     *connection);
00335 static DBusDispatchStatus _dbus_connection_flush_unlocked                    (DBusConnection     *connection);
00336 static void               _dbus_connection_close_possibly_shared_and_unlock  (DBusConnection     *connection);
00337 static dbus_bool_t        _dbus_connection_get_is_connected_unlocked         (DBusConnection     *connection);
00338 static dbus_bool_t        _dbus_connection_peek_for_reply_unlocked           (DBusConnection     *connection,
00339                                                                               dbus_uint32_t       client_serial);
00340 
00341 static DBusMessageFilter *
00342 _dbus_message_filter_ref (DBusMessageFilter *filter)
00343 {
00344   _dbus_assert (filter->refcount.value > 0);
00345   _dbus_atomic_inc (&filter->refcount);
00346 
00347   return filter;
00348 }
00349 
00350 static void
00351 _dbus_message_filter_unref (DBusMessageFilter *filter)
00352 {
00353   _dbus_assert (filter->refcount.value > 0);
00354 
00355   if (_dbus_atomic_dec (&filter->refcount) == 1)
00356     {
00357       if (filter->free_user_data_function)
00358         (* filter->free_user_data_function) (filter->user_data);
00359       
00360       dbus_free (filter);
00361     }
00362 }
00363 
00369 void
00370 _dbus_connection_lock (DBusConnection *connection)
00371 {
00372   CONNECTION_LOCK (connection);
00373 }
00374 
00380 void
00381 _dbus_connection_unlock (DBusConnection *connection)
00382 {
00383   CONNECTION_UNLOCK (connection);
00384 }
00385 
00393 static void
00394 _dbus_connection_wakeup_mainloop (DBusConnection *connection)
00395 {
00396   if (connection->wakeup_main_function)
00397     (*connection->wakeup_main_function) (connection->wakeup_main_data);
00398 }
00399 
00400 #ifdef DBUS_BUILD_TESTS
00401 /* For now this function isn't used */
00411 dbus_bool_t
00412 _dbus_connection_queue_received_message (DBusConnection *connection,
00413                                          DBusMessage    *message)
00414 {
00415   DBusList *link;
00416 
00417   link = _dbus_list_alloc_link (message);
00418   if (link == NULL)
00419     return FALSE;
00420 
00421   dbus_message_ref (message);
00422   _dbus_connection_queue_received_message_link (connection, link);
00423 
00424   return TRUE;
00425 }
00426 
00439 void 
00440 _dbus_connection_test_get_locks (DBusConnection *connection,
00441                                  DBusMutex     **mutex_loc,
00442                                  DBusMutex     **dispatch_mutex_loc,
00443                                  DBusMutex     **io_path_mutex_loc,
00444                                  DBusCondVar   **dispatch_cond_loc,
00445                                  DBusCondVar   **io_path_cond_loc)
00446 {
00447   *mutex_loc = connection->mutex;
00448   *dispatch_mutex_loc = connection->dispatch_mutex;
00449   *io_path_mutex_loc = connection->io_path_mutex; 
00450   *dispatch_cond_loc = connection->dispatch_cond;
00451   *io_path_cond_loc = connection->io_path_cond;
00452 }
00453 #endif
00454 
00463 void
00464 _dbus_connection_queue_received_message_link (DBusConnection  *connection,
00465                                               DBusList        *link)
00466 {
00467   DBusPendingCall *pending;
00468   dbus_uint32_t reply_serial;
00469   DBusMessage *message;
00470   
00471   _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport));
00472   
00473   _dbus_list_append_link (&connection->incoming_messages,
00474                           link);
00475   message = link->data;
00476 
00477   /* If this is a reply we're waiting on, remove timeout for it */
00478   reply_serial = dbus_message_get_reply_serial (message);
00479   if (reply_serial != 0)
00480     {
00481       pending = _dbus_hash_table_lookup_int (connection->pending_replies,
00482                                              reply_serial);
00483       if (pending != NULL)
00484         {
00485           if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00486             _dbus_connection_remove_timeout_unlocked (connection,
00487                                                       _dbus_pending_call_get_timeout_unlocked (pending));
00488 
00489           _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00490         }
00491     }
00492   
00493   
00494 
00495   connection->n_incoming += 1;
00496 
00497   _dbus_connection_wakeup_mainloop (connection);
00498   
00499   _dbus_verbose ("Message %p (%s %s %s %s '%s' reply to %u) added to incoming queue %p, %d incoming\n",
00500                  message,
00501                  dbus_message_type_to_string (dbus_message_get_type (message)),
00502                  dbus_message_get_path (message) ?
00503                  dbus_message_get_path (message) :
00504                  "no path",
00505                  dbus_message_get_interface (message) ?
00506                  dbus_message_get_interface (message) :
00507                  "no interface",
00508                  dbus_message_get_member (message) ?
00509                  dbus_message_get_member (message) :
00510                  "no member",
00511                  dbus_message_get_signature (message),
00512                  dbus_message_get_reply_serial (message),
00513                  connection,
00514                  connection->n_incoming);}
00515 
00524 void
00525 _dbus_connection_queue_synthesized_message_link (DBusConnection *connection,
00526                                                  DBusList *link)
00527 {
00528   HAVE_LOCK_CHECK (connection);
00529   
00530   _dbus_list_append_link (&connection->incoming_messages, link);
00531 
00532   connection->n_incoming += 1;
00533 
00534   _dbus_connection_wakeup_mainloop (connection);
00535   
00536   _dbus_verbose ("Synthesized message %p added to incoming queue %p, %d incoming\n",
00537                  link->data, connection, connection->n_incoming);
00538 }
00539 
00540 
00548 dbus_bool_t
00549 _dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection)
00550 {
00551   HAVE_LOCK_CHECK (connection);
00552   return connection->outgoing_messages != NULL;
00553 }
00554 
00564 dbus_bool_t
00565 dbus_connection_has_messages_to_send (DBusConnection *connection)
00566 {
00567   dbus_bool_t v;
00568   
00569   _dbus_return_val_if_fail (connection != NULL, FALSE);
00570 
00571   CONNECTION_LOCK (connection);
00572   v = _dbus_connection_has_messages_to_send_unlocked (connection);
00573   CONNECTION_UNLOCK (connection);
00574 
00575   return v;
00576 }
00577 
00585 DBusMessage*
00586 _dbus_connection_get_message_to_send (DBusConnection *connection)
00587 {
00588   HAVE_LOCK_CHECK (connection);
00589   
00590   return _dbus_list_get_last (&connection->outgoing_messages);
00591 }
00592 
00601 void
00602 _dbus_connection_message_sent (DBusConnection *connection,
00603                                DBusMessage    *message)
00604 {
00605   DBusList *link;
00606 
00607   HAVE_LOCK_CHECK (connection);
00608   
00609   /* This can be called before we even complete authentication, since
00610    * it's called on disconnect to clean up the outgoing queue.
00611    * It's also called as we successfully send each message.
00612    */
00613   
00614   link = _dbus_list_get_last_link (&connection->outgoing_messages);
00615   _dbus_assert (link != NULL);
00616   _dbus_assert (link->data == message);
00617 
00618   /* Save this link in the link cache */
00619   _dbus_list_unlink (&connection->outgoing_messages,
00620                      link);
00621   _dbus_list_prepend_link (&connection->link_cache, link);
00622   
00623   connection->n_outgoing -= 1;
00624 
00625   _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from outgoing queue %p, %d left to send\n",
00626                  message,
00627                  dbus_message_type_to_string (dbus_message_get_type (message)),
00628                  dbus_message_get_path (message) ?
00629                  dbus_message_get_path (message) :
00630                  "no path",
00631                  dbus_message_get_interface (message) ?
00632                  dbus_message_get_interface (message) :
00633                  "no interface",
00634                  dbus_message_get_member (message) ?
00635                  dbus_message_get_member (message) :
00636                  "no member",
00637                  dbus_message_get_signature (message),
00638                  connection, connection->n_outgoing);
00639 
00640   /* Save this link in the link cache also */
00641   _dbus_message_remove_counter (message, connection->outgoing_counter,
00642                                 &link);
00643   _dbus_list_prepend_link (&connection->link_cache, link);
00644   
00645   dbus_message_unref (message);
00646 }
00647 
00649 typedef dbus_bool_t (* DBusWatchAddFunction)     (DBusWatchList *list,
00650                                                   DBusWatch     *watch);
00652 typedef void        (* DBusWatchRemoveFunction)  (DBusWatchList *list,
00653                                                   DBusWatch     *watch);
00655 typedef void        (* DBusWatchToggleFunction)  (DBusWatchList *list,
00656                                                   DBusWatch     *watch,
00657                                                   dbus_bool_t    enabled);
00658 
00659 static dbus_bool_t
00660 protected_change_watch (DBusConnection         *connection,
00661                         DBusWatch              *watch,
00662                         DBusWatchAddFunction    add_function,
00663                         DBusWatchRemoveFunction remove_function,
00664                         DBusWatchToggleFunction toggle_function,
00665                         dbus_bool_t             enabled)
00666 {
00667   dbus_bool_t retval;
00668 
00669   HAVE_LOCK_CHECK (connection);
00670 
00671   /* The original purpose of protected_change_watch() was to hold a
00672    * ref on the connection while dropping the connection lock, then
00673    * calling out to the app.  This was a broken hack that did not
00674    * work, since the connection was in a hosed state (no WatchList
00675    * field) while calling out.
00676    *
00677    * So for now we'll just keep the lock while calling out. This means
00678    * apps are not allowed to call DBusConnection methods inside a
00679    * watch function or they will deadlock.
00680    *
00681    * The "real fix" is to use the _and_unlock() pattern found
00682    * elsewhere in the code, to defer calling out to the app until
00683    * we're about to drop locks and return flow of control to the app
00684    * anyway.
00685    *
00686    * See http://lists.freedesktop.org/archives/dbus/2007-July/thread.html#8144
00687    */
00688 
00689   if (connection->watches)
00690     {
00691       if (add_function)
00692         retval = (* add_function) (connection->watches, watch);
00693       else if (remove_function)
00694         {
00695           retval = TRUE;
00696           (* remove_function) (connection->watches, watch);
00697         }
00698       else
00699         {
00700           retval = TRUE;
00701           (* toggle_function) (connection->watches, watch, enabled);
00702         }
00703       return retval;
00704     }
00705   else
00706     return FALSE;
00707 }
00708      
00709 
00721 dbus_bool_t
00722 _dbus_connection_add_watch_unlocked (DBusConnection *connection,
00723                                      DBusWatch      *watch)
00724 {
00725   return protected_change_watch (connection, watch,
00726                                  _dbus_watch_list_add_watch,
00727                                  NULL, NULL, FALSE);
00728 }
00729 
00739 void
00740 _dbus_connection_remove_watch_unlocked (DBusConnection *connection,
00741                                         DBusWatch      *watch)
00742 {
00743   protected_change_watch (connection, watch,
00744                           NULL,
00745                           _dbus_watch_list_remove_watch,
00746                           NULL, FALSE);
00747 }
00748 
00759 void
00760 _dbus_connection_toggle_watch_unlocked (DBusConnection *connection,
00761                                         DBusWatch      *watch,
00762                                         dbus_bool_t     enabled)
00763 {
00764   _dbus_assert (watch != NULL);
00765 
00766   protected_change_watch (connection, watch,
00767                           NULL, NULL,
00768                           _dbus_watch_list_toggle_watch,
00769                           enabled);
00770 }
00771 
00773 typedef dbus_bool_t (* DBusTimeoutAddFunction)    (DBusTimeoutList *list,
00774                                                    DBusTimeout     *timeout);
00776 typedef void        (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list,
00777                                                    DBusTimeout     *timeout);
00779 typedef void        (* DBusTimeoutToggleFunction) (DBusTimeoutList *list,
00780                                                    DBusTimeout     *timeout,
00781                                                    dbus_bool_t      enabled);
00782 
00783 static dbus_bool_t
00784 protected_change_timeout (DBusConnection           *connection,
00785                           DBusTimeout              *timeout,
00786                           DBusTimeoutAddFunction    add_function,
00787                           DBusTimeoutRemoveFunction remove_function,
00788                           DBusTimeoutToggleFunction toggle_function,
00789                           dbus_bool_t               enabled)
00790 {
00791   dbus_bool_t retval;
00792 
00793   HAVE_LOCK_CHECK (connection);
00794 
00795   /* The original purpose of protected_change_timeout() was to hold a
00796    * ref on the connection while dropping the connection lock, then
00797    * calling out to the app.  This was a broken hack that did not
00798    * work, since the connection was in a hosed state (no TimeoutList
00799    * field) while calling out.
00800    *
00801    * So for now we'll just keep the lock while calling out. This means
00802    * apps are not allowed to call DBusConnection methods inside a
00803    * timeout function or they will deadlock.
00804    *
00805    * The "real fix" is to use the _and_unlock() pattern found
00806    * elsewhere in the code, to defer calling out to the app until
00807    * we're about to drop locks and return flow of control to the app
00808    * anyway.
00809    *
00810    * See http://lists.freedesktop.org/archives/dbus/2007-July/thread.html#8144
00811    */
00812 
00813   if (connection->timeouts)
00814     {
00815       if (add_function)
00816         retval = (* add_function) (connection->timeouts, timeout);
00817       else if (remove_function)
00818         {
00819           retval = TRUE;
00820           (* remove_function) (connection->timeouts, timeout);
00821         }
00822       else
00823         {
00824           retval = TRUE;
00825           (* toggle_function) (connection->timeouts, timeout, enabled);
00826         }
00827       return retval;
00828     }
00829   else
00830     return FALSE;
00831 }
00832 
00845 dbus_bool_t
00846 _dbus_connection_add_timeout_unlocked (DBusConnection *connection,
00847                                        DBusTimeout    *timeout)
00848 {
00849   return protected_change_timeout (connection, timeout,
00850                                    _dbus_timeout_list_add_timeout,
00851                                    NULL, NULL, FALSE);
00852 }
00853 
00863 void
00864 _dbus_connection_remove_timeout_unlocked (DBusConnection *connection,
00865                                           DBusTimeout    *timeout)
00866 {
00867   protected_change_timeout (connection, timeout,
00868                             NULL,
00869                             _dbus_timeout_list_remove_timeout,
00870                             NULL, FALSE);
00871 }
00872 
00883 void
00884 _dbus_connection_toggle_timeout_unlocked (DBusConnection   *connection,
00885                                           DBusTimeout      *timeout,
00886                                           dbus_bool_t       enabled)
00887 {
00888   protected_change_timeout (connection, timeout,
00889                             NULL, NULL,
00890                             _dbus_timeout_list_toggle_timeout,
00891                             enabled);
00892 }
00893 
00894 static dbus_bool_t
00895 _dbus_connection_attach_pending_call_unlocked (DBusConnection  *connection,
00896                                                DBusPendingCall *pending)
00897 {
00898   dbus_uint32_t reply_serial;
00899   DBusTimeout *timeout;
00900 
00901   HAVE_LOCK_CHECK (connection);
00902 
00903   reply_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
00904 
00905   _dbus_assert (reply_serial != 0);
00906 
00907   timeout = _dbus_pending_call_get_timeout_unlocked (pending);
00908 
00909   if (timeout)
00910     {
00911       if (!_dbus_connection_add_timeout_unlocked (connection, timeout))
00912         return FALSE;
00913       
00914       if (!_dbus_hash_table_insert_int (connection->pending_replies,
00915                                         reply_serial,
00916                                         pending))
00917         {
00918           _dbus_connection_remove_timeout_unlocked (connection, timeout);
00919 
00920           _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00921           HAVE_LOCK_CHECK (connection);
00922           return FALSE;
00923         }
00924       
00925       _dbus_pending_call_set_timeout_added_unlocked (pending, TRUE);
00926     }
00927   else
00928     {
00929       if (!_dbus_hash_table_insert_int (connection->pending_replies,
00930                                         reply_serial,
00931                                         pending))
00932         {
00933           HAVE_LOCK_CHECK (connection);
00934           return FALSE;
00935         }
00936     }
00937 
00938   _dbus_pending_call_ref_unlocked (pending);
00939 
00940   HAVE_LOCK_CHECK (connection);
00941   
00942   return TRUE;
00943 }
00944 
00945 static void
00946 free_pending_call_on_hash_removal (void *data)
00947 {
00948   DBusPendingCall *pending;
00949   DBusConnection  *connection;
00950   
00951   if (data == NULL)
00952     return;
00953 
00954   pending = data;
00955 
00956   connection = _dbus_pending_call_get_connection_unlocked (pending);
00957 
00958   HAVE_LOCK_CHECK (connection);
00959   
00960   if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00961     {
00962       _dbus_connection_remove_timeout_unlocked (connection,
00963                                                 _dbus_pending_call_get_timeout_unlocked (pending));
00964       
00965       _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00966     }
00967 
00968   /* FIXME 1.0? this is sort of dangerous and undesirable to drop the lock 
00969    * here, but the pending call finalizer could in principle call out to 
00970    * application code so we pretty much have to... some larger code reorg 
00971    * might be needed.
00972    */
00973   _dbus_connection_ref_unlocked (connection);
00974   _dbus_pending_call_unref_and_unlock (pending);
00975   CONNECTION_LOCK (connection);
00976   _dbus_connection_unref_unlocked (connection);
00977 }
00978 
00979 static void
00980 _dbus_connection_detach_pending_call_unlocked (DBusConnection  *connection,
00981                                                DBusPendingCall *pending)
00982 {
00983   /* This ends up unlocking to call the pending call finalizer, which is unexpected to
00984    * say the least.
00985    */
00986   _dbus_hash_table_remove_int (connection->pending_replies,
00987                                _dbus_pending_call_get_reply_serial_unlocked (pending));
00988 }
00989 
00990 static void
00991 _dbus_connection_detach_pending_call_and_unlock (DBusConnection  *connection,
00992                                                  DBusPendingCall *pending)
00993 {
00994   /* The idea here is to avoid finalizing the pending call
00995    * with the lock held, since there's a destroy notifier
00996    * in pending call that goes out to application code.
00997    *
00998    * There's an extra unlock inside the hash table
00999    * "free pending call" function FIXME...
01000    */
01001   _dbus_pending_call_ref_unlocked (pending);
01002   _dbus_hash_table_remove_int (connection->pending_replies,
01003                                _dbus_pending_call_get_reply_serial_unlocked (pending));
01004 
01005   if (_dbus_pending_call_is_timeout_added_unlocked (pending))
01006       _dbus_connection_remove_timeout_unlocked (connection,
01007               _dbus_pending_call_get_timeout_unlocked (pending));
01008 
01009   _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
01010 
01011   _dbus_pending_call_unref_and_unlock (pending);
01012 }
01013 
01022 void
01023 _dbus_connection_remove_pending_call (DBusConnection  *connection,
01024                                       DBusPendingCall *pending)
01025 {
01026   CONNECTION_LOCK (connection);
01027   _dbus_connection_detach_pending_call_and_unlock (connection, pending);
01028 }
01029 
01039 static dbus_bool_t
01040 _dbus_connection_acquire_io_path (DBusConnection *connection,
01041                                   int             timeout_milliseconds)
01042 {
01043   dbus_bool_t we_acquired;
01044   
01045   HAVE_LOCK_CHECK (connection);
01046 
01047   /* We don't want the connection to vanish */
01048   _dbus_connection_ref_unlocked (connection);
01049 
01050   /* We will only touch io_path_acquired which is protected by our mutex */
01051   CONNECTION_UNLOCK (connection);
01052   
01053   _dbus_verbose ("locking io_path_mutex\n");
01054   _dbus_mutex_lock (connection->io_path_mutex);
01055 
01056   _dbus_verbose ("start connection->io_path_acquired = %d timeout = %d\n",
01057                  connection->io_path_acquired, timeout_milliseconds);
01058 
01059   we_acquired = FALSE;
01060   
01061   if (connection->io_path_acquired)
01062     {
01063       if (timeout_milliseconds != -1)
01064         {
01065           _dbus_verbose ("waiting %d for IO path to be acquirable\n",
01066                          timeout_milliseconds);
01067 
01068           if (!_dbus_condvar_wait_timeout (connection->io_path_cond,
01069                                            connection->io_path_mutex,
01070                                            timeout_milliseconds))
01071             {
01072               /* We timed out before anyone signaled. */
01073               /* (writing the loop to handle the !timedout case by
01074                * waiting longer if needed is a pain since dbus
01075                * wraps pthread_cond_timedwait to take a relative
01076                * time instead of absolute, something kind of stupid
01077                * on our part. for now it doesn't matter, we will just
01078                * end up back here eventually.)
01079                */
01080             }
01081         }
01082       else
01083         {
01084           while (connection->io_path_acquired)
01085             {
01086               _dbus_verbose ("waiting for IO path to be acquirable\n");
01087               _dbus_condvar_wait (connection->io_path_cond, 
01088                                   connection->io_path_mutex);
01089             }
01090         }
01091     }
01092   
01093   if (!connection->io_path_acquired)
01094     {
01095       we_acquired = TRUE;
01096       connection->io_path_acquired = TRUE;
01097     }
01098   
01099   _dbus_verbose ("end connection->io_path_acquired = %d we_acquired = %d\n",
01100                  connection->io_path_acquired, we_acquired);
01101 
01102   _dbus_verbose ("unlocking io_path_mutex\n");
01103   _dbus_mutex_unlock (connection->io_path_mutex);
01104 
01105   CONNECTION_LOCK (connection);
01106   
01107   HAVE_LOCK_CHECK (connection);
01108 
01109   _dbus_connection_unref_unlocked (connection);
01110   
01111   return we_acquired;
01112 }
01113 
01121 static void
01122 _dbus_connection_release_io_path (DBusConnection *connection)
01123 {
01124   HAVE_LOCK_CHECK (connection);
01125   
01126   _dbus_verbose ("locking io_path_mutex\n");
01127   _dbus_mutex_lock (connection->io_path_mutex);
01128   
01129   _dbus_assert (connection->io_path_acquired);
01130 
01131   _dbus_verbose ("start connection->io_path_acquired = %d\n",
01132                  connection->io_path_acquired);
01133   
01134   connection->io_path_acquired = FALSE;
01135   _dbus_condvar_wake_one (connection->io_path_cond);
01136 
01137   _dbus_verbose ("unlocking io_path_mutex\n");
01138   _dbus_mutex_unlock (connection->io_path_mutex);
01139 }
01140 
01176 void
01177 _dbus_connection_do_iteration_unlocked (DBusConnection *connection,
01178                                         DBusPendingCall *pending,
01179                                         unsigned int    flags,
01180                                         int             timeout_milliseconds)
01181 {
01182   _dbus_verbose ("start\n");
01183   
01184   HAVE_LOCK_CHECK (connection);
01185   
01186   if (connection->n_outgoing == 0)
01187     flags &= ~DBUS_ITERATION_DO_WRITING;
01188 
01189   if (_dbus_connection_acquire_io_path (connection,
01190                                         (flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0))
01191     {
01192       HAVE_LOCK_CHECK (connection);
01193       
01194       if ( (pending != NULL) && _dbus_pending_call_get_completed_unlocked(pending))
01195         {
01196           _dbus_verbose ("pending call completed while acquiring I/O path");
01197         }
01198       else if ( (pending != NULL) &&
01199                 _dbus_connection_peek_for_reply_unlocked (connection,
01200                                                           _dbus_pending_call_get_reply_serial_unlocked (pending)))
01201         {
01202           _dbus_verbose ("pending call completed while acquiring I/O path (reply found in queue)");
01203         }
01204       else
01205         {
01206           _dbus_transport_do_iteration (connection->transport,
01207                                         flags, timeout_milliseconds);
01208         }
01209 
01210       _dbus_connection_release_io_path (connection);
01211     }
01212 
01213   HAVE_LOCK_CHECK (connection);
01214 
01215   _dbus_verbose ("end\n");
01216 }
01217 
01227 DBusConnection*
01228 _dbus_connection_new_for_transport (DBusTransport *transport)
01229 {
01230   DBusConnection *connection;
01231   DBusWatchList *watch_list;
01232   DBusTimeoutList *timeout_list;
01233   DBusHashTable *pending_replies;
01234   DBusList *disconnect_link;
01235   DBusMessage *disconnect_message;
01236   DBusCounter *outgoing_counter;
01237   DBusObjectTree *objects;
01238   
01239   watch_list = NULL;
01240   connection = NULL;
01241   pending_replies = NULL;
01242   timeout_list = NULL;
01243   disconnect_link = NULL;
01244   disconnect_message = NULL;
01245   outgoing_counter = NULL;
01246   objects = NULL;
01247   
01248   watch_list = _dbus_watch_list_new ();
01249   if (watch_list == NULL)
01250     goto error;
01251 
01252   timeout_list = _dbus_timeout_list_new ();
01253   if (timeout_list == NULL)
01254     goto error;  
01255 
01256   pending_replies =
01257     _dbus_hash_table_new (DBUS_HASH_INT,
01258                           NULL,
01259                           (DBusFreeFunction)free_pending_call_on_hash_removal);
01260   if (pending_replies == NULL)
01261     goto error;
01262   
01263   connection = dbus_new0 (DBusConnection, 1);
01264   if (connection == NULL)
01265     goto error;
01266 
01267   _dbus_mutex_new_at_location (&connection->mutex);
01268   if (connection->mutex == NULL)
01269     goto error;
01270 
01271   _dbus_mutex_new_at_location (&connection->io_path_mutex);
01272   if (connection->io_path_mutex == NULL)
01273     goto error;
01274 
01275   _dbus_mutex_new_at_location (&connection->dispatch_mutex);
01276   if (connection->dispatch_mutex == NULL)
01277     goto error;
01278   
01279   _dbus_condvar_new_at_location (&connection->dispatch_cond);
01280   if (connection->dispatch_cond == NULL)
01281     goto error;
01282   
01283   _dbus_condvar_new_at_location (&connection->io_path_cond);
01284   if (connection->io_path_cond == NULL)
01285     goto error;
01286 
01287   _dbus_mutex_new_at_location (&connection->slot_mutex);
01288   if (connection->slot_mutex == NULL)
01289     goto error;
01290 
01291   disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL,
01292                                                 DBUS_INTERFACE_LOCAL,
01293                                                 "Disconnected");
01294   
01295   if (disconnect_message == NULL)
01296     goto error;
01297 
01298   disconnect_link = _dbus_list_alloc_link (disconnect_message);
01299   if (disconnect_link == NULL)
01300     goto error;
01301 
01302   outgoing_counter = _dbus_counter_new ();
01303   if (outgoing_counter == NULL)
01304     goto error;
01305 
01306   objects = _dbus_object_tree_new (connection);
01307   if (objects == NULL)
01308     goto error;
01309   
01310   if (_dbus_modify_sigpipe)
01311     _dbus_disable_sigpipe ();
01312   
01313   connection->refcount.value = 1;
01314   connection->transport = transport;
01315   connection->watches = watch_list;
01316   connection->timeouts = timeout_list;
01317   connection->pending_replies = pending_replies;
01318   connection->outgoing_counter = outgoing_counter;
01319   connection->filter_list = NULL;
01320   connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE; /* so we're notified first time there's data */
01321   connection->objects = objects;
01322   connection->exit_on_disconnect = FALSE;
01323   connection->shareable = FALSE;
01324   connection->route_peer_messages = FALSE;
01325   connection->disconnected_message_arrived = FALSE;
01326   connection->disconnected_message_processed = FALSE;
01327   
01328 #ifndef DBUS_DISABLE_CHECKS
01329   connection->generation = _dbus_current_generation;
01330 #endif
01331   
01332   _dbus_data_slot_list_init (&connection->slot_list);
01333 
01334   connection->client_serial = 1;
01335 
01336   connection->disconnect_message_link = disconnect_link;
01337 
01338   CONNECTION_LOCK (connection);
01339   
01340   if (!_dbus_transport_set_connection (transport, connection))
01341     {
01342       CONNECTION_UNLOCK (connection);
01343 
01344       goto error;
01345     }
01346 
01347   _dbus_transport_ref (transport);
01348 
01349   CONNECTION_UNLOCK (connection);
01350   
01351   return connection;
01352   
01353  error:
01354   if (disconnect_message != NULL)
01355     dbus_message_unref (disconnect_message);
01356   
01357   if (disconnect_link != NULL)
01358     _dbus_list_free_link (disconnect_link);
01359   
01360   if (connection != NULL)
01361     {
01362       _dbus_condvar_free_at_location (&connection->io_path_cond);
01363       _dbus_condvar_free_at_location (&connection->dispatch_cond);
01364       _dbus_mutex_free_at_location (&connection->mutex);
01365       _dbus_mutex_free_at_location (&connection->io_path_mutex);
01366       _dbus_mutex_free_at_location (&connection->dispatch_mutex);
01367       _dbus_mutex_free_at_location (&connection->slot_mutex);
01368       dbus_free (connection);
01369     }
01370   if (pending_replies)
01371     _dbus_hash_table_unref (pending_replies);
01372   
01373   if (watch_list)
01374     _dbus_watch_list_free (watch_list);
01375 
01376   if (timeout_list)
01377     _dbus_timeout_list_free (timeout_list);
01378 
01379   if (outgoing_counter)
01380     _dbus_counter_unref (outgoing_counter);
01381 
01382   if (objects)
01383     _dbus_object_tree_unref (objects);
01384   
01385   return NULL;
01386 }
01387 
01395 DBusConnection *
01396 _dbus_connection_ref_unlocked (DBusConnection *connection)
01397 {  
01398   _dbus_assert (connection != NULL);
01399   _dbus_assert (connection->generation == _dbus_current_generation);
01400 
01401   HAVE_LOCK_CHECK (connection);
01402   
01403 #ifdef DBUS_HAVE_ATOMIC_INT
01404   _dbus_atomic_inc (&connection->refcount);
01405 #else
01406   _dbus_assert (connection->refcount.value > 0);
01407   connection->refcount.value += 1;
01408 #endif
01409 
01410   return connection;
01411 }
01412 
01419 void
01420 _dbus_connection_unref_unlocked (DBusConnection *connection)
01421 {
01422   dbus_bool_t last_unref;
01423 
01424   HAVE_LOCK_CHECK (connection);
01425   
01426   _dbus_assert (connection != NULL);
01427 
01428   /* The connection lock is better than the global
01429    * lock in the atomic increment fallback
01430    */
01431   
01432 #ifdef DBUS_HAVE_ATOMIC_INT
01433   last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
01434 #else
01435   _dbus_assert (connection->refcount.value > 0);
01436 
01437   connection->refcount.value -= 1;
01438   last_unref = (connection->refcount.value == 0);  
01439 #if 0
01440   printf ("unref_unlocked() connection %p count = %d\n", connection, connection->refcount.value);
01441 #endif
01442 #endif
01443   
01444   if (last_unref)
01445     _dbus_connection_last_unref (connection);
01446 }
01447 
01448 static dbus_uint32_t
01449 _dbus_connection_get_next_client_serial (DBusConnection *connection)
01450 {
01451   dbus_uint32_t serial;
01452 
01453   serial = connection->client_serial++;
01454 
01455   if (connection->client_serial == 0)
01456     connection->client_serial = 1;
01457 
01458   return serial;
01459 }
01460 
01474 dbus_bool_t
01475 _dbus_connection_handle_watch (DBusWatch                   *watch,
01476                                unsigned int                 condition,
01477                                void                        *data)
01478 {
01479   DBusConnection *connection;
01480   dbus_bool_t retval;
01481   DBusDispatchStatus status;
01482 
01483   connection = data;
01484 
01485   _dbus_verbose ("start\n");
01486   
01487   CONNECTION_LOCK (connection);
01488 
01489   if (!_dbus_connection_acquire_io_path (connection, 1))
01490     {
01491       /* another thread is handling the message */
01492       CONNECTION_UNLOCK (connection);
01493       return TRUE;
01494     }
01495 
01496   HAVE_LOCK_CHECK (connection);
01497   retval = _dbus_transport_handle_watch (connection->transport,
01498                                          watch, condition);
01499 
01500   _dbus_connection_release_io_path (connection);
01501 
01502   HAVE_LOCK_CHECK (connection);
01503 
01504   _dbus_verbose ("middle\n");
01505   
01506   status = _dbus_connection_get_dispatch_status_unlocked (connection);
01507 
01508   /* this calls out to user code */
01509   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01510 
01511   _dbus_verbose ("end\n");
01512   
01513   return retval;
01514 }
01515 
01516 _DBUS_DEFINE_GLOBAL_LOCK (shared_connections);
01517 static DBusHashTable *shared_connections = NULL;
01518 static DBusList *shared_connections_no_guid = NULL;
01519 
01520 static void
01521 close_connection_on_shutdown (DBusConnection *connection)
01522 {
01523   DBusMessage *message;
01524 
01525   dbus_connection_ref (connection);
01526   _dbus_connection_close_possibly_shared (connection);
01527 
01528   /* Churn through to the Disconnected message */
01529   while ((message = dbus_connection_pop_message (connection)))
01530     {
01531       dbus_message_unref (message);
01532     }
01533   dbus_connection_unref (connection);
01534 }
01535 
01536 static void
01537 shared_connections_shutdown (void *data)
01538 {
01539   int n_entries;
01540   
01541   _DBUS_LOCK (shared_connections);
01542   
01543   /* This is a little bit unpleasant... better ideas? */
01544   while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0)
01545     {
01546       DBusConnection *connection;
01547       DBusHashIter iter;
01548       
01549       _dbus_hash_iter_init (shared_connections, &iter);
01550       _dbus_hash_iter_next (&iter);
01551        
01552       connection = _dbus_hash_iter_get_value (&iter);
01553 
01554       _DBUS_UNLOCK (shared_connections);
01555       close_connection_on_shutdown (connection);
01556       _DBUS_LOCK (shared_connections);
01557 
01558       /* The connection should now be dead and not in our hash ... */
01559       _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) < n_entries);
01560     }
01561 
01562   _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) == 0);
01563   
01564   _dbus_hash_table_unref (shared_connections);
01565   shared_connections = NULL;
01566 
01567   if (shared_connections_no_guid != NULL)
01568     {
01569       DBusConnection *connection;
01570       connection = _dbus_list_pop_first (&shared_connections_no_guid);
01571       while (connection != NULL)
01572         {
01573           _DBUS_UNLOCK (shared_connections);
01574           close_connection_on_shutdown (connection);
01575           _DBUS_LOCK (shared_connections);
01576           connection = _dbus_list_pop_first (&shared_connections_no_guid);
01577         }
01578     }
01579 
01580   shared_connections_no_guid = NULL;
01581   
01582   _DBUS_UNLOCK (shared_connections);
01583 }
01584 
01585 static dbus_bool_t
01586 connection_lookup_shared (DBusAddressEntry  *entry,
01587                           DBusConnection   **result)
01588 {
01589   _dbus_verbose ("checking for existing connection\n");
01590   
01591   *result = NULL;
01592   
01593   _DBUS_LOCK (shared_connections);
01594 
01595   if (shared_connections == NULL)
01596     {
01597       _dbus_verbose ("creating shared_connections hash table\n");
01598       
01599       shared_connections = _dbus_hash_table_new (DBUS_HASH_STRING,
01600                                                  dbus_free,
01601                                                  NULL);
01602       if (shared_connections == NULL)
01603         {
01604           _DBUS_UNLOCK (shared_connections);
01605           return FALSE;
01606         }
01607 
01608       if (!_dbus_register_shutdown_func (shared_connections_shutdown, NULL))
01609         {
01610           _dbus_hash_table_unref (shared_connections);
01611           shared_connections = NULL;
01612           _DBUS_UNLOCK (shared_connections);
01613           return FALSE;
01614         }
01615 
01616       _dbus_verbose ("  successfully created shared_connections\n");
01617       
01618       _DBUS_UNLOCK (shared_connections);
01619       return TRUE; /* no point looking up in the hash we just made */
01620     }
01621   else
01622     {
01623       const char *guid;
01624 
01625       guid = dbus_address_entry_get_value (entry, "guid");
01626       
01627       if (guid != NULL)
01628         {
01629           DBusConnection *connection;
01630           
01631           connection = _dbus_hash_table_lookup_string (shared_connections,
01632                                                        guid);
01633 
01634           if (connection)
01635             {
01636               /* The DBusConnection can't be finalized without taking
01637                * the shared_connections lock to remove it from the
01638                * hash.  So it's safe to ref the connection here.
01639                * However, it may be disconnected if the Disconnected
01640                * message hasn't been processed yet, in which case we
01641                * want to pretend it isn't in the hash and avoid
01642                * returning it.
01643                *
01644                * The idea is to avoid ever returning a disconnected connection
01645                * from dbus_connection_open(). We could just synchronously
01646                * drop our shared ref to the connection on connection disconnect,
01647                * and then assert here that the connection is connected, but
01648                * that causes reentrancy headaches.
01649                */
01650               CONNECTION_LOCK (connection);
01651               if (_dbus_connection_get_is_connected_unlocked (connection))
01652                 {
01653                   _dbus_connection_ref_unlocked (connection);
01654                   *result = connection;
01655                   _dbus_verbose ("looked up existing connection to server guid %s\n",
01656                                  guid);
01657                 }
01658               else
01659                 {
01660                   _dbus_verbose ("looked up existing connection to server guid %s but it was disconnected so ignoring it\n",
01661                                  guid);
01662                 }
01663               CONNECTION_UNLOCK (connection);
01664             }
01665         }
01666       
01667       _DBUS_UNLOCK (shared_connections);
01668       return TRUE;
01669     }
01670 }
01671 
01672 static dbus_bool_t
01673 connection_record_shared_unlocked (DBusConnection *connection,
01674                                    const char     *guid)
01675 {
01676   char *guid_key;
01677   char *guid_in_connection;
01678 
01679   HAVE_LOCK_CHECK (connection);
01680   _dbus_assert (connection->server_guid == NULL);
01681   _dbus_assert (connection->shareable);
01682 
01683   /* get a hard ref on this connection, even if
01684    * we won't in fact store it in the hash, we still
01685    * need to hold a ref on it until it's disconnected.
01686    */
01687   _dbus_connection_ref_unlocked (connection);
01688 
01689   if (guid == NULL)
01690     {
01691       _DBUS_LOCK (shared_connections);
01692 
01693       if (!_dbus_list_prepend (&shared_connections_no_guid, connection))
01694         {
01695           _DBUS_UNLOCK (shared_connections);
01696           return FALSE;
01697         }
01698 
01699       _DBUS_UNLOCK (shared_connections);
01700       return TRUE; /* don't store in the hash */
01701     }
01702   
01703   /* A separate copy of the key is required in the hash table, because
01704    * we don't have a lock on the connection when we are doing a hash
01705    * lookup.
01706    */
01707   
01708   guid_key = _dbus_strdup (guid);
01709   if (guid_key == NULL)
01710     return FALSE;
01711 
01712   guid_in_connection = _dbus_strdup (guid);
01713   if (guid_in_connection == NULL)
01714     {
01715       dbus_free (guid_key);
01716       return FALSE;
01717     }
01718   
01719   _DBUS_LOCK (shared_connections);
01720   _dbus_assert (shared_connections != NULL);
01721   
01722   if (!_dbus_hash_table_insert_string (shared_connections,
01723                                        guid_key, connection))
01724     {
01725       dbus_free (guid_key);
01726       dbus_free (guid_in_connection);
01727       _DBUS_UNLOCK (shared_connections);
01728       return FALSE;
01729     }
01730 
01731   connection->server_guid = guid_in_connection;
01732 
01733   _dbus_verbose ("stored connection to %s to be shared\n",
01734                  connection->server_guid);
01735   
01736   _DBUS_UNLOCK (shared_connections);
01737 
01738   _dbus_assert (connection->server_guid != NULL);
01739   
01740   return TRUE;
01741 }
01742 
01743 static void
01744 connection_forget_shared_unlocked (DBusConnection *connection)
01745 {
01746   HAVE_LOCK_CHECK (connection);
01747 
01748   if (!connection->shareable)
01749     return;
01750   
01751   _DBUS_LOCK (shared_connections);
01752       
01753   if (connection->server_guid != NULL)
01754     {
01755       _dbus_verbose ("dropping connection to %s out of the shared table\n",
01756                      connection->server_guid);
01757       
01758       if (!_dbus_hash_table_remove_string (shared_connections,
01759                                            connection->server_guid))
01760         _dbus_assert_not_reached ("connection was not in the shared table");
01761       
01762       dbus_free (connection->server_guid);
01763       connection->server_guid = NULL;
01764     }
01765   else
01766     {
01767       _dbus_list_remove (&shared_connections_no_guid, connection);
01768     }
01769 
01770   _DBUS_UNLOCK (shared_connections);
01771   
01772   /* remove our reference held on all shareable connections */
01773   _dbus_connection_unref_unlocked (connection);
01774 }
01775 
01776 static DBusConnection*
01777 connection_try_from_address_entry (DBusAddressEntry *entry,
01778                                    DBusError        *error)
01779 {
01780   DBusTransport *transport;
01781   DBusConnection *connection;
01782 
01783   transport = _dbus_transport_open (entry, error);
01784 
01785   if (transport == NULL)
01786     {
01787       _DBUS_ASSERT_ERROR_IS_SET (error);
01788       return NULL;
01789     }
01790 
01791   connection = _dbus_connection_new_for_transport (transport);
01792 
01793   _dbus_transport_unref (transport);
01794   
01795   if (connection == NULL)
01796     {
01797       _DBUS_SET_OOM (error);
01798       return NULL;
01799     }
01800 
01801 #ifndef DBUS_DISABLE_CHECKS
01802   _dbus_assert (!connection->have_connection_lock);
01803 #endif
01804   return connection;
01805 }
01806 
01807 /*
01808  * If the shared parameter is true, then any existing connection will
01809  * be used (and if a new connection is created, it will be available
01810  * for use by others). If the shared parameter is false, a new
01811  * connection will always be created, and the new connection will
01812  * never be returned to other callers.
01813  *
01814  * @param address the address
01815  * @param shared whether the connection is shared or private
01816  * @param error error return
01817  * @returns the connection or #NULL on error
01818  */
01819 static DBusConnection*
01820 _dbus_connection_open_internal (const char     *address,
01821                                 dbus_bool_t     shared,
01822                                 DBusError      *error)
01823 {
01824   DBusConnection *connection;
01825   DBusAddressEntry **entries;
01826   DBusError tmp_error = DBUS_ERROR_INIT;
01827   DBusError first_error = DBUS_ERROR_INIT;
01828   int len, i;
01829 
01830   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01831 
01832   _dbus_verbose ("opening %s connection to: %s\n",
01833                  shared ? "shared" : "private", address);
01834   
01835   if (!dbus_parse_address (address, &entries, &len, error))
01836     return NULL;
01837 
01838   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01839   
01840   connection = NULL;
01841 
01842   for (i = 0; i < len; i++)
01843     {
01844       if (shared)
01845         {
01846           if (!connection_lookup_shared (entries[i], &connection))
01847             _DBUS_SET_OOM (&tmp_error);
01848         }
01849 
01850       if (connection == NULL)
01851         {
01852           connection = connection_try_from_address_entry (entries[i],
01853                                                           &tmp_error);
01854 
01855           if (connection != NULL && shared)
01856             {
01857               const char *guid;
01858                   
01859               connection->shareable = TRUE;
01860                   
01861               /* guid may be NULL */
01862               guid = dbus_address_entry_get_value (entries[i], "guid");
01863                   
01864               CONNECTION_LOCK (connection);
01865           
01866               if (!connection_record_shared_unlocked (connection, guid))
01867                 {
01868                   _DBUS_SET_OOM (&tmp_error);
01869                   _dbus_connection_close_possibly_shared_and_unlock (connection);
01870                   dbus_connection_unref (connection);
01871                   connection = NULL;
01872                 }
01873               else
01874                 CONNECTION_UNLOCK (connection);
01875             }
01876         }
01877       
01878       if (connection)
01879         break;
01880 
01881       _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
01882       
01883       if (i == 0)
01884         dbus_move_error (&tmp_error, &first_error);
01885       else
01886         dbus_error_free (&tmp_error);
01887     }
01888   
01889   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01890   _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
01891   
01892   if (connection == NULL)
01893     {
01894       _DBUS_ASSERT_ERROR_IS_SET (&first_error);
01895       dbus_move_error (&first_error, error);
01896     }
01897   else
01898     dbus_error_free (&first_error);
01899   
01900   dbus_address_entries_free (entries);
01901   return connection;
01902 }
01903 
01912 void
01913 _dbus_connection_close_possibly_shared (DBusConnection *connection)
01914 {
01915   _dbus_assert (connection != NULL);
01916   _dbus_assert (connection->generation == _dbus_current_generation);
01917 
01918   CONNECTION_LOCK (connection);
01919   _dbus_connection_close_possibly_shared_and_unlock (connection);
01920 }
01921 
01922 static DBusPreallocatedSend*
01923 _dbus_connection_preallocate_send_unlocked (DBusConnection *connection)
01924 {
01925   DBusPreallocatedSend *preallocated;
01926 
01927   HAVE_LOCK_CHECK (connection);
01928   
01929   _dbus_assert (connection != NULL);
01930   
01931   preallocated = dbus_new (DBusPreallocatedSend, 1);
01932   if (preallocated == NULL)
01933     return NULL;
01934 
01935   if (connection->link_cache != NULL)
01936     {
01937       preallocated->queue_link =
01938         _dbus_list_pop_first_link (&connection->link_cache);
01939       preallocated->queue_link->data = NULL;
01940     }
01941   else
01942     {
01943       preallocated->queue_link = _dbus_list_alloc_link (NULL);
01944       if (preallocated->queue_link == NULL)
01945         goto failed_0;
01946     }
01947   
01948   if (connection->link_cache != NULL)
01949     {
01950       preallocated->counter_link =
01951         _dbus_list_pop_first_link (&connection->link_cache);
01952       preallocated->counter_link->data = connection->outgoing_counter;
01953     }
01954   else
01955     {
01956       preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter);
01957       if (preallocated->counter_link == NULL)
01958         goto failed_1;
01959     }
01960 
01961   _dbus_counter_ref (preallocated->counter_link->data);
01962 
01963   preallocated->connection = connection;
01964   
01965   return preallocated;
01966   
01967  failed_1:
01968   _dbus_list_free_link (preallocated->queue_link);
01969  failed_0:
01970   dbus_free (preallocated);
01971   
01972   return NULL;
01973 }
01974 
01975 /* Called with lock held, does not update dispatch status */
01976 static void
01977 _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection       *connection,
01978                                                        DBusPreallocatedSend *preallocated,
01979                                                        DBusMessage          *message,
01980                                                        dbus_uint32_t        *client_serial)
01981 {
01982   dbus_uint32_t serial;
01983 
01984   preallocated->queue_link->data = message;
01985   _dbus_list_prepend_link (&connection->outgoing_messages,
01986                            preallocated->queue_link);
01987 
01988   _dbus_message_add_counter_link (message,
01989                                   preallocated->counter_link);
01990 
01991   dbus_free (preallocated);
01992   preallocated = NULL;
01993   
01994   dbus_message_ref (message);
01995   
01996   connection->n_outgoing += 1;
01997 
01998   _dbus_verbose ("Message %p (%s %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
01999                  message,
02000                  dbus_message_type_to_string (dbus_message_get_type (message)),
02001                  dbus_message_get_path (message) ?
02002                  dbus_message_get_path (message) :
02003                  "no path",
02004                  dbus_message_get_interface (message) ?
02005                  dbus_message_get_interface (message) :
02006                  "no interface",
02007                  dbus_message_get_member (message) ?
02008                  dbus_message_get_member (message) :
02009                  "no member",
02010                  dbus_message_get_signature (message),
02011                  dbus_message_get_destination (message) ?
02012                  dbus_message_get_destination (message) :
02013                  "null",
02014                  connection,
02015                  connection->n_outgoing);
02016 
02017   if (dbus_message_get_serial (message) == 0)
02018     {
02019       serial = _dbus_connection_get_next_client_serial (connection);
02020       dbus_message_set_serial (message, serial);
02021       if (client_serial)
02022         *client_serial = serial;
02023     }
02024   else
02025     {
02026       if (client_serial)
02027         *client_serial = dbus_message_get_serial (message);
02028     }
02029 
02030   _dbus_verbose ("Message %p serial is %u\n",
02031                  message, dbus_message_get_serial (message));
02032   
02033   dbus_message_lock (message);
02034 
02035   /* Now we need to run an iteration to hopefully just write the messages
02036    * out immediately, and otherwise get them queued up
02037    */
02038   _dbus_connection_do_iteration_unlocked (connection,
02039                                           NULL,
02040                                           DBUS_ITERATION_DO_WRITING,
02041                                           -1);
02042 
02043   /* If stuff is still queued up, be sure we wake up the main loop */
02044   if (connection->n_outgoing > 0)
02045     _dbus_connection_wakeup_mainloop (connection);
02046 }
02047 
02048 static void
02049 _dbus_connection_send_preallocated_and_unlock (DBusConnection       *connection,
02050                                                DBusPreallocatedSend *preallocated,
02051                                                DBusMessage          *message,
02052                                                dbus_uint32_t        *client_serial)
02053 {
02054   DBusDispatchStatus status;
02055 
02056   HAVE_LOCK_CHECK (connection);
02057   
02058   _dbus_connection_send_preallocated_unlocked_no_update (connection,
02059                                                          preallocated,
02060                                                          message, client_serial);
02061 
02062   _dbus_verbose ("middle\n");
02063   status = _dbus_connection_get_dispatch_status_unlocked (connection);
02064 
02065   /* this calls out to user code */
02066   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02067 }
02068 
02078 dbus_bool_t
02079 _dbus_connection_send_and_unlock (DBusConnection *connection,
02080                                   DBusMessage    *message,
02081                                   dbus_uint32_t  *client_serial)
02082 {
02083   DBusPreallocatedSend *preallocated;
02084 
02085   _dbus_assert (connection != NULL);
02086   _dbus_assert (message != NULL);
02087   
02088   preallocated = _dbus_connection_preallocate_send_unlocked (connection);
02089   if (preallocated == NULL)
02090     {
02091       CONNECTION_UNLOCK (connection);
02092       return FALSE;
02093     }
02094 
02095   _dbus_connection_send_preallocated_and_unlock (connection,
02096                                                  preallocated,
02097                                                  message,
02098                                                  client_serial);
02099   return TRUE;
02100 }
02101 
02126 void
02127 _dbus_connection_close_if_only_one_ref (DBusConnection *connection)
02128 {
02129   CONNECTION_LOCK (connection);
02130   
02131   _dbus_assert (connection->refcount.value > 0);
02132 
02133   if (connection->refcount.value == 1)
02134     _dbus_connection_close_possibly_shared_and_unlock (connection);
02135   else
02136     CONNECTION_UNLOCK (connection);
02137 }
02138 
02139 
02149 static void
02150 _dbus_memory_pause_based_on_timeout (int timeout_milliseconds)
02151 {
02152   if (timeout_milliseconds == -1)
02153     _dbus_sleep_milliseconds (1000);
02154   else if (timeout_milliseconds < 100)
02155     ; /* just busy loop */
02156   else if (timeout_milliseconds <= 1000)
02157     _dbus_sleep_milliseconds (timeout_milliseconds / 3);
02158   else
02159     _dbus_sleep_milliseconds (1000);
02160 }
02161 
02162 static DBusMessage *
02163 generate_local_error_message (dbus_uint32_t serial, 
02164                               char *error_name, 
02165                               char *error_msg)
02166 {
02167   DBusMessage *message;
02168   message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
02169   if (!message)
02170     goto out;
02171 
02172   if (!dbus_message_set_error_name (message, error_name))
02173     {
02174       dbus_message_unref (message);
02175       message = NULL;
02176       goto out; 
02177     }
02178 
02179   dbus_message_set_no_reply (message, TRUE); 
02180 
02181   if (!dbus_message_set_reply_serial (message,
02182                                       serial))
02183     {
02184       dbus_message_unref (message);
02185       message = NULL;
02186       goto out;
02187     }
02188 
02189   if (error_msg != NULL)
02190     {
02191       DBusMessageIter iter;
02192 
02193       dbus_message_iter_init_append (message, &iter);
02194       if (!dbus_message_iter_append_basic (&iter,
02195                                            DBUS_TYPE_STRING,
02196                                            &error_msg))
02197         {
02198           dbus_message_unref (message);
02199           message = NULL;
02200           goto out;
02201         }
02202     }
02203 
02204  out:
02205   return message;
02206 }
02207 
02208 /*
02209  * Peek the incoming queue to see if we got reply for a specific serial
02210  */
02211 static dbus_bool_t
02212 _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection,
02213                                           dbus_uint32_t   client_serial)
02214 {
02215   DBusList *link;
02216   HAVE_LOCK_CHECK (connection);
02217 
02218   link = _dbus_list_get_first_link (&connection->incoming_messages);
02219 
02220   while (link != NULL)
02221     {
02222       DBusMessage *reply = link->data;
02223 
02224       if (dbus_message_get_reply_serial (reply) == client_serial)
02225         {
02226           _dbus_verbose ("%s reply to %d found in queue\n", _DBUS_FUNCTION_NAME, client_serial);
02227           return TRUE;
02228         }
02229       link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02230     }
02231 
02232   return FALSE;
02233 }
02234 
02235 /* This is slightly strange since we can pop a message here without
02236  * the dispatch lock.
02237  */
02238 static DBusMessage*
02239 check_for_reply_unlocked (DBusConnection *connection,
02240                           dbus_uint32_t   client_serial)
02241 {
02242   DBusList *link;
02243 
02244   HAVE_LOCK_CHECK (connection);
02245   
02246   link = _dbus_list_get_first_link (&connection->incoming_messages);
02247 
02248   while (link != NULL)
02249     {
02250       DBusMessage *reply = link->data;
02251 
02252       if (dbus_message_get_reply_serial (reply) == client_serial)
02253         {
02254           _dbus_list_remove_link (&connection->incoming_messages, link);
02255           connection->n_incoming  -= 1;
02256           return reply;
02257         }
02258       link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02259     }
02260 
02261   return NULL;
02262 }
02263 
02264 static void
02265 connection_timeout_and_complete_all_pending_calls_unlocked (DBusConnection *connection)
02266 {
02267    /* We can't iterate over the hash in the normal way since we'll be
02268     * dropping the lock for each item. So we restart the
02269     * iter each time as we drain the hash table.
02270     */
02271    
02272    while (_dbus_hash_table_get_n_entries (connection->pending_replies) > 0)
02273     {
02274       DBusPendingCall *pending;
02275       DBusHashIter iter;
02276       
02277       _dbus_hash_iter_init (connection->pending_replies, &iter);
02278       _dbus_hash_iter_next (&iter);
02279        
02280       pending = _dbus_hash_iter_get_value (&iter);
02281       _dbus_pending_call_ref_unlocked (pending);
02282        
02283       _dbus_pending_call_queue_timeout_error_unlocked (pending, 
02284                                                        connection);
02285 
02286       if (_dbus_pending_call_is_timeout_added_unlocked (pending))
02287           _dbus_connection_remove_timeout_unlocked (connection,
02288                                                     _dbus_pending_call_get_timeout_unlocked (pending));
02289       _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);       
02290       _dbus_hash_iter_remove_entry (&iter);
02291 
02292       _dbus_pending_call_unref_and_unlock (pending);
02293       CONNECTION_LOCK (connection);
02294     }
02295   HAVE_LOCK_CHECK (connection);
02296 }
02297 
02298 static void
02299 complete_pending_call_and_unlock (DBusConnection  *connection,
02300                                   DBusPendingCall *pending,
02301                                   DBusMessage     *message)
02302 {
02303   _dbus_pending_call_set_reply_unlocked (pending, message);
02304   _dbus_pending_call_ref_unlocked (pending); /* in case there's no app with a ref held */
02305   _dbus_connection_detach_pending_call_and_unlock (connection, pending);
02306  
02307   /* Must be called unlocked since it invokes app callback */
02308   _dbus_pending_call_complete (pending);
02309   dbus_pending_call_unref (pending);
02310 }
02311 
02312 static dbus_bool_t
02313 check_for_reply_and_update_dispatch_unlocked (DBusConnection  *connection,
02314                                               DBusPendingCall *pending)
02315 {
02316   DBusMessage *reply;
02317   DBusDispatchStatus status;
02318 
02319   reply = check_for_reply_unlocked (connection, 
02320                                     _dbus_pending_call_get_reply_serial_unlocked (pending));
02321   if (reply != NULL)
02322     {
02323       _dbus_verbose ("checked for reply\n");
02324 
02325       _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
02326 
02327       complete_pending_call_and_unlock (connection, pending, reply);
02328       dbus_message_unref (reply);
02329 
02330       CONNECTION_LOCK (connection);
02331       status = _dbus_connection_get_dispatch_status_unlocked (connection);
02332       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02333       dbus_pending_call_unref (pending);
02334 
02335       return TRUE;
02336     }
02337 
02338   return FALSE;
02339 }
02340 
02355 void
02356 _dbus_connection_block_pending_call (DBusPendingCall *pending)
02357 {
02358   long start_tv_sec, start_tv_usec;
02359   long tv_sec, tv_usec;
02360   DBusDispatchStatus status;
02361   DBusConnection *connection;
02362   dbus_uint32_t client_serial;
02363   DBusTimeout *timeout;
02364   int timeout_milliseconds, elapsed_milliseconds;
02365 
02366   _dbus_assert (pending != NULL);
02367 
02368   if (dbus_pending_call_get_completed (pending))
02369     return;
02370 
02371   dbus_pending_call_ref (pending); /* necessary because the call could be canceled */
02372 
02373   connection = _dbus_pending_call_get_connection_and_lock (pending);
02374   
02375   /* Flush message queue - note, can affect dispatch status */
02376   _dbus_connection_flush_unlocked (connection);
02377 
02378   client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
02379 
02380   /* note that timeout_milliseconds is limited to a smallish value
02381    * in _dbus_pending_call_new() so overflows aren't possible
02382    * below
02383    */
02384   timeout = _dbus_pending_call_get_timeout_unlocked (pending);
02385   _dbus_get_current_time (&start_tv_sec, &start_tv_usec);
02386   if (timeout)
02387     {
02388       timeout_milliseconds = dbus_timeout_get_interval (timeout);
02389 
02390       _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec\n",
02391                      timeout_milliseconds,
02392                      client_serial,
02393                      start_tv_sec, start_tv_usec);
02394     }
02395   else
02396     {
02397       timeout_milliseconds = -1;
02398 
02399       _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block for reply serial %u\n", client_serial);
02400     }
02401 
02402   /* check to see if we already got the data off the socket */
02403   /* from another blocked pending call */
02404   if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02405     return;
02406 
02407   /* Now we wait... */
02408   /* always block at least once as we know we don't have the reply yet */
02409   _dbus_connection_do_iteration_unlocked (connection,
02410                                           pending,
02411                                           DBUS_ITERATION_DO_READING |
02412                                           DBUS_ITERATION_BLOCK,
02413                                           timeout_milliseconds);
02414 
02415  recheck_status:
02416 
02417   _dbus_verbose ("top of recheck\n");
02418   
02419   HAVE_LOCK_CHECK (connection);
02420   
02421   /* queue messages and get status */
02422 
02423   status = _dbus_connection_get_dispatch_status_unlocked (connection);
02424 
02425   /* the get_completed() is in case a dispatch() while we were blocking
02426    * got the reply instead of us.
02427    */
02428   if (_dbus_pending_call_get_completed_unlocked (pending))
02429     {
02430       _dbus_verbose ("Pending call completed by dispatch\n");
02431       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02432       dbus_pending_call_unref (pending);
02433       return;
02434     }
02435   
02436   if (status == DBUS_DISPATCH_DATA_REMAINS)
02437     {
02438       if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02439         return;
02440     }
02441   
02442   _dbus_get_current_time (&tv_sec, &tv_usec);
02443   elapsed_milliseconds = (tv_sec - start_tv_sec) * 1000 +
02444           (tv_usec - start_tv_usec) / 1000;
02445   
02446   if (!_dbus_connection_get_is_connected_unlocked (connection))
02447     {
02448       DBusMessage *error_msg;
02449 
02450       error_msg = generate_local_error_message (client_serial,
02451                                                 DBUS_ERROR_DISCONNECTED, 
02452                                                 "Connection was disconnected before a reply was received"); 
02453 
02454       /* on OOM error_msg is set to NULL */
02455       complete_pending_call_and_unlock (connection, pending, error_msg);
02456       dbus_pending_call_unref (pending);
02457       return;
02458     }
02459   else if (connection->disconnect_message_link == NULL)
02460     _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
02461   else if (timeout == NULL)
02462     {
02463        if (status == DBUS_DISPATCH_NEED_MEMORY)
02464         {
02465           /* Try sleeping a bit, as we aren't sure we need to block for reading,
02466            * we may already have a reply in the buffer and just can't process
02467            * it.
02468            */
02469           _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02470 
02471           _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
02472         }
02473       else
02474         {          
02475           /* block again, we don't have the reply buffered yet. */
02476           _dbus_connection_do_iteration_unlocked (connection,
02477                                                   pending,
02478                                                   DBUS_ITERATION_DO_READING |
02479                                                   DBUS_ITERATION_BLOCK,
02480                                                   timeout_milliseconds - elapsed_milliseconds);
02481         }
02482 
02483       goto recheck_status;
02484     }
02485   else if (tv_sec < start_tv_sec)
02486     _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
02487   else if (elapsed_milliseconds < timeout_milliseconds)
02488     {
02489       _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds - elapsed_milliseconds);
02490       
02491       if (status == DBUS_DISPATCH_NEED_MEMORY)
02492         {
02493           /* Try sleeping a bit, as we aren't sure we need to block for reading,
02494            * we may already have a reply in the buffer and just can't process
02495            * it.
02496            */
02497           _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02498 
02499           _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
02500         }
02501       else
02502         {          
02503           /* block again, we don't have the reply buffered yet. */
02504           _dbus_connection_do_iteration_unlocked (connection,
02505                                                   NULL,
02506                                                   DBUS_ITERATION_DO_READING |
02507                                                   DBUS_ITERATION_BLOCK,
02508                                                   timeout_milliseconds - elapsed_milliseconds);
02509         }
02510 
02511       goto recheck_status;
02512     }
02513 
02514   _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %d milliseconds and got no reply\n",
02515                  elapsed_milliseconds);
02516 
02517   _dbus_assert (!_dbus_pending_call_get_completed_unlocked (pending));
02518   
02519   /* unlock and call user code */
02520   complete_pending_call_and_unlock (connection, pending, NULL);
02521 
02522   /* update user code on dispatch status */
02523   CONNECTION_LOCK (connection);
02524   status = _dbus_connection_get_dispatch_status_unlocked (connection);
02525   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02526   dbus_pending_call_unref (pending);
02527 }
02528 
02565 DBusConnection*
02566 dbus_connection_open (const char     *address,
02567                       DBusError      *error)
02568 {
02569   DBusConnection *connection;
02570 
02571   _dbus_return_val_if_fail (address != NULL, NULL);
02572   _dbus_return_val_if_error_is_set (error, NULL);
02573 
02574   connection = _dbus_connection_open_internal (address,
02575                                                TRUE,
02576                                                error);
02577 
02578   return connection;
02579 }
02580 
02608 DBusConnection*
02609 dbus_connection_open_private (const char     *address,
02610                               DBusError      *error)
02611 {
02612   DBusConnection *connection;
02613 
02614   _dbus_return_val_if_fail (address != NULL, NULL);
02615   _dbus_return_val_if_error_is_set (error, NULL);
02616 
02617   connection = _dbus_connection_open_internal (address,
02618                                                FALSE,
02619                                                error);
02620 
02621   return connection;
02622 }
02623 
02630 DBusConnection *
02631 dbus_connection_ref (DBusConnection *connection)
02632 {
02633   _dbus_return_val_if_fail (connection != NULL, NULL);
02634   _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
02635   
02636   /* The connection lock is better than the global
02637    * lock in the atomic increment fallback
02638    *
02639    * (FIXME but for now we always use the atomic version,
02640    * to avoid taking the connection lock, due to
02641    * the mess with set_timeout_functions()/set_watch_functions()
02642    * calling out to the app without dropping locks)
02643    */
02644   
02645 #if 1
02646   _dbus_atomic_inc (&connection->refcount);
02647 #else
02648   CONNECTION_LOCK (connection);
02649   _dbus_assert (connection->refcount.value > 0);
02650 
02651   connection->refcount.value += 1;
02652   CONNECTION_UNLOCK (connection);
02653 #endif
02654 
02655   return connection;
02656 }
02657 
02658 static void
02659 free_outgoing_message (void *element,
02660                        void *data)
02661 {
02662   DBusMessage *message = element;
02663   DBusConnection *connection = data;
02664 
02665   _dbus_message_remove_counter (message,
02666                                 connection->outgoing_counter,
02667                                 NULL);
02668   dbus_message_unref (message);
02669 }
02670 
02671 /* This is run without the mutex held, but after the last reference
02672  * to the connection has been dropped we should have no thread-related
02673  * problems
02674  */
02675 static void
02676 _dbus_connection_last_unref (DBusConnection *connection)
02677 {
02678   DBusList *link;
02679 
02680   _dbus_verbose ("Finalizing connection %p\n", connection);
02681   
02682   _dbus_assert (connection->refcount.value == 0);
02683   
02684   /* You have to disconnect the connection before unref:ing it. Otherwise
02685    * you won't get the disconnected message.
02686    */
02687   _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
02688   _dbus_assert (connection->server_guid == NULL);
02689   
02690   /* ---- We're going to call various application callbacks here, hope it doesn't break anything... */
02691   _dbus_object_tree_free_all_unlocked (connection->objects);
02692   
02693   dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
02694   dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
02695   dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
02696   
02697   _dbus_watch_list_free (connection->watches);
02698   connection->watches = NULL;
02699   
02700   _dbus_timeout_list_free (connection->timeouts);
02701   connection->timeouts = NULL;
02702 
02703   _dbus_data_slot_list_free (&connection->slot_list);
02704   
02705   link = _dbus_list_get_first_link (&connection->filter_list);
02706   while (link != NULL)
02707     {
02708       DBusMessageFilter *filter = link->data;
02709       DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
02710 
02711       filter->function = NULL;
02712       _dbus_message_filter_unref (filter); /* calls app callback */
02713       link->data = NULL;
02714       
02715       link = next;
02716     }
02717   _dbus_list_clear (&connection->filter_list);
02718   
02719   /* ---- Done with stuff that invokes application callbacks */
02720 
02721   _dbus_object_tree_unref (connection->objects);  
02722 
02723   _dbus_hash_table_unref (connection->pending_replies);
02724   connection->pending_replies = NULL;
02725   
02726   _dbus_list_clear (&connection->filter_list);
02727   
02728   _dbus_list_foreach (&connection->outgoing_messages,
02729                       free_outgoing_message,
02730                       connection);
02731   _dbus_list_clear (&connection->outgoing_messages);
02732   
02733   _dbus_list_foreach (&connection->incoming_messages,
02734                       (DBusForeachFunction) dbus_message_unref,
02735                       NULL);
02736   _dbus_list_clear (&connection->incoming_messages);
02737 
02738   _dbus_counter_unref (connection->outgoing_counter);
02739 
02740   _dbus_transport_unref (connection->transport);
02741 
02742   if (connection->disconnect_message_link)
02743     {
02744       DBusMessage *message = connection->disconnect_message_link->data;
02745       dbus_message_unref (message);
02746       _dbus_list_free_link (connection->disconnect_message_link);
02747     }
02748 
02749   _dbus_list_clear (&connection->link_cache);
02750   
02751   _dbus_condvar_free_at_location (&connection->dispatch_cond);
02752   _dbus_condvar_free_at_location (&connection->io_path_cond);
02753 
02754   _dbus_mutex_free_at_location (&connection->io_path_mutex);
02755   _dbus_mutex_free_at_location (&connection->dispatch_mutex);
02756 
02757   _dbus_mutex_free_at_location (&connection->slot_mutex);
02758 
02759   _dbus_mutex_free_at_location (&connection->mutex);
02760   
02761   dbus_free (connection);
02762 }
02763 
02783 void
02784 dbus_connection_unref (DBusConnection *connection)
02785 {
02786   dbus_bool_t last_unref;
02787 
02788   _dbus_return_if_fail (connection != NULL);
02789   _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02790   
02791   /* The connection lock is better than the global
02792    * lock in the atomic increment fallback
02793    *
02794    * (FIXME but for now we always use the atomic version,
02795    * to avoid taking the connection lock, due to
02796    * the mess with set_timeout_functions()/set_watch_functions()
02797    * calling out to the app without dropping locks)
02798    */
02799   
02800 #if 1
02801   last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
02802 #else
02803   CONNECTION_LOCK (connection);
02804   
02805   _dbus_assert (connection->refcount.value > 0);
02806 
02807   connection->refcount.value -= 1;
02808   last_unref = (connection->refcount.value == 0);
02809 
02810 #if 0
02811   printf ("unref() connection %p count = %d\n", connection, connection->refcount.value);
02812 #endif
02813   
02814   CONNECTION_UNLOCK (connection);
02815 #endif
02816   
02817   if (last_unref)
02818     {
02819 #ifndef DBUS_DISABLE_CHECKS
02820       if (_dbus_transport_get_is_connected (connection->transport))
02821         {
02822           _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",
02823                                    connection->shareable ?
02824                                    "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" : 
02825                                     "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n");
02826           return;
02827         }
02828 #endif
02829       _dbus_connection_last_unref (connection);
02830     }
02831 }
02832 
02833 /*
02834  * Note that the transport can disconnect itself (other end drops us)
02835  * and in that case this function never runs. So this function must
02836  * not do anything more than disconnect the transport and update the
02837  * dispatch status.
02838  * 
02839  * If the transport self-disconnects, then we assume someone will
02840  * dispatch the connection to cause the dispatch status update.
02841  */
02842 static void
02843 _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection)
02844 {
02845   DBusDispatchStatus status;
02846 
02847   HAVE_LOCK_CHECK (connection);
02848   
02849   _dbus_verbose ("Disconnecting %p\n", connection);
02850 
02851   /* We need to ref because update_dispatch_status_and_unlock will unref
02852    * the connection if it was shared and libdbus was the only remaining
02853    * refcount holder.
02854    */
02855   _dbus_connection_ref_unlocked (connection);
02856   
02857   _dbus_transport_disconnect (connection->transport);
02858 
02859   /* This has the side effect of queuing the disconnect message link
02860    * (unless we don't have enough memory, possibly, so don't assert it).
02861    * After the disconnect message link is queued, dbus_bus_get/dbus_connection_open
02862    * should never again return the newly-disconnected connection.
02863    *
02864    * However, we only unref the shared connection and exit_on_disconnect when
02865    * the disconnect message reaches the head of the message queue,
02866    * NOT when it's first queued.
02867    */
02868   status = _dbus_connection_get_dispatch_status_unlocked (connection);
02869 
02870   /* This calls out to user code */
02871   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02872 
02873   /* Could also call out to user code */
02874   dbus_connection_unref (connection);
02875 }
02876 
02919 void
02920 dbus_connection_close (DBusConnection *connection)
02921 {
02922   _dbus_return_if_fail (connection != NULL);
02923   _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02924 
02925   CONNECTION_LOCK (connection);
02926 
02927 #ifndef DBUS_DISABLE_CHECKS
02928   if (connection->shareable)
02929     {
02930       CONNECTION_UNLOCK (connection);
02931 
02932       _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n");
02933       return;
02934     }
02935 #endif
02936   
02937   _dbus_connection_close_possibly_shared_and_unlock (connection);
02938 }
02939 
02940 static dbus_bool_t
02941 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
02942 {
02943   HAVE_LOCK_CHECK (connection);
02944   return _dbus_transport_get_is_connected (connection->transport);
02945 }
02946 
02960 dbus_bool_t
02961 dbus_connection_get_is_connected (DBusConnection *connection)
02962 {
02963   dbus_bool_t res;
02964 
02965   _dbus_return_val_if_fail (connection != NULL, FALSE);
02966   
02967   CONNECTION_LOCK (connection);
02968   res = _dbus_connection_get_is_connected_unlocked (connection);
02969   CONNECTION_UNLOCK (connection);
02970   
02971   return res;
02972 }
02973 
02982 dbus_bool_t
02983 dbus_connection_get_is_authenticated (DBusConnection *connection)
02984 {
02985   dbus_bool_t res;
02986 
02987   _dbus_return_val_if_fail (connection != NULL, FALSE);
02988   
02989   CONNECTION_LOCK (connection);
02990   res = _dbus_transport_get_is_authenticated (connection->transport);
02991   CONNECTION_UNLOCK (connection);
02992   
02993   return res;
02994 }
02995 
03016 dbus_bool_t
03017 dbus_connection_get_is_anonymous (DBusConnection *connection)
03018 {
03019   dbus_bool_t res;
03020 
03021   _dbus_return_val_if_fail (connection != NULL, FALSE);
03022   
03023   CONNECTION_LOCK (connection);
03024   res = _dbus_transport_get_is_anonymous (connection->transport);
03025   CONNECTION_UNLOCK (connection);
03026   
03027   return res;
03028 }
03029 
03061 char*
03062 dbus_connection_get_server_id (DBusConnection *connection)
03063 {
03064   char *id;
03065 
03066   _dbus_return_val_if_fail (connection != NULL, NULL);
03067 
03068   CONNECTION_LOCK (connection);
03069   id = _dbus_strdup (_dbus_transport_get_server_id (connection->transport));
03070   CONNECTION_UNLOCK (connection);
03071 
03072   return id;
03073 }
03074 
03092 dbus_bool_t
03093 dbus_connection_can_send_type(DBusConnection *connection,
03094                                   int type)
03095 {
03096   _dbus_return_val_if_fail (connection != NULL, FALSE);
03097 
03098   if (!_dbus_type_is_valid(type))
03099     return FALSE;
03100 
03101   if (type != DBUS_TYPE_UNIX_FD)
03102     return TRUE;
03103 
03104 #ifdef HAVE_UNIX_FD_PASSING
03105   {
03106     dbus_bool_t b;
03107 
03108     CONNECTION_LOCK(connection);
03109     b = _dbus_transport_can_pass_unix_fd(connection->transport);
03110     CONNECTION_UNLOCK(connection);
03111 
03112     return b;
03113   }
03114 #endif
03115 
03116   return FALSE;
03117 }
03118 
03132 void
03133 dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
03134                                         dbus_bool_t     exit_on_disconnect)
03135 {
03136   _dbus_return_if_fail (connection != NULL);
03137 
03138   CONNECTION_LOCK (connection);
03139   connection->exit_on_disconnect = exit_on_disconnect != FALSE;
03140   CONNECTION_UNLOCK (connection);
03141 }
03142 
03152 DBusPreallocatedSend*
03153 dbus_connection_preallocate_send (DBusConnection *connection)
03154 {
03155   DBusPreallocatedSend *preallocated;
03156 
03157   _dbus_return_val_if_fail (connection != NULL, NULL);
03158 
03159   CONNECTION_LOCK (connection);
03160   
03161   preallocated =
03162     _dbus_connection_preallocate_send_unlocked (connection);
03163 
03164   CONNECTION_UNLOCK (connection);
03165 
03166   return preallocated;
03167 }
03168 
03178 void
03179 dbus_connection_free_preallocated_send (DBusConnection       *connection,
03180                                         DBusPreallocatedSend *preallocated)
03181 {
03182   _dbus_return_if_fail (connection != NULL);
03183   _dbus_return_if_fail (preallocated != NULL);  
03184   _dbus_return_if_fail (connection == preallocated->connection);
03185 
03186   _dbus_list_free_link (preallocated->queue_link);
03187   _dbus_counter_unref (preallocated->counter_link->data);
03188   _dbus_list_free_link (preallocated->counter_link);
03189   dbus_free (preallocated);
03190 }
03191 
03204 void
03205 dbus_connection_send_preallocated (DBusConnection       *connection,
03206                                    DBusPreallocatedSend *preallocated,
03207                                    DBusMessage          *message,
03208                                    dbus_uint32_t        *client_serial)
03209 {
03210   _dbus_return_if_fail (connection != NULL);
03211   _dbus_return_if_fail (preallocated != NULL);
03212   _dbus_return_if_fail (message != NULL);
03213   _dbus_return_if_fail (preallocated->connection == connection);
03214   _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
03215                         dbus_message_get_member (message) != NULL);
03216   _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
03217                         (dbus_message_get_interface (message) != NULL &&
03218                          dbus_message_get_member (message) != NULL));
03219 
03220   CONNECTION_LOCK (connection);
03221 
03222 #ifdef HAVE_UNIX_FD_PASSING
03223 
03224   if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03225       message->n_unix_fds > 0)
03226     {
03227       /* Refuse to send fds on a connection that cannot handle
03228          them. Unfortunately we cannot return a proper error here, so
03229          the best we can is just return. */
03230       CONNECTION_UNLOCK (connection);
03231       return;
03232     }
03233 
03234 #endif
03235 
03236   _dbus_connection_send_preallocated_and_unlock (connection,
03237                                                  preallocated,
03238                                                  message, client_serial);
03239 }
03240 
03241 static dbus_bool_t
03242 _dbus_connection_send_unlocked_no_update (DBusConnection *connection,
03243                                           DBusMessage    *message,
03244                                           dbus_uint32_t  *client_serial)
03245 {
03246   DBusPreallocatedSend *preallocated;
03247 
03248   _dbus_assert (connection != NULL);
03249   _dbus_assert (message != NULL);
03250   
03251   preallocated = _dbus_connection_preallocate_send_unlocked (connection);
03252   if (preallocated == NULL)
03253     return FALSE;
03254 
03255   _dbus_connection_send_preallocated_unlocked_no_update (connection,
03256                                                          preallocated,
03257                                                          message,
03258                                                          client_serial);
03259   return TRUE;
03260 }
03261 
03289 dbus_bool_t
03290 dbus_connection_send (DBusConnection *connection,
03291                       DBusMessage    *message,
03292                       dbus_uint32_t  *serial)
03293 {
03294   _dbus_return_val_if_fail (connection != NULL, FALSE);
03295   _dbus_return_val_if_fail (message != NULL, FALSE);
03296 
03297   CONNECTION_LOCK (connection);
03298 
03299 #ifdef HAVE_UNIX_FD_PASSING
03300 
03301   if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03302       message->n_unix_fds > 0)
03303     {
03304       /* Refuse to send fds on a connection that cannot handle
03305          them. Unfortunately we cannot return a proper error here, so
03306          the best we can is just return. */
03307       CONNECTION_UNLOCK (connection);
03308       return FALSE;
03309     }
03310 
03311 #endif
03312 
03313   return _dbus_connection_send_and_unlock (connection,
03314                                            message,
03315                                            serial);
03316 }
03317 
03318 static dbus_bool_t
03319 reply_handler_timeout (void *data)
03320 {
03321   DBusConnection *connection;
03322   DBusDispatchStatus status;
03323   DBusPendingCall *pending = data;
03324 
03325   connection = _dbus_pending_call_get_connection_and_lock (pending);
03326 
03327   _dbus_pending_call_queue_timeout_error_unlocked (pending, 
03328                                                    connection);
03329   _dbus_connection_remove_timeout_unlocked (connection,
03330                                             _dbus_pending_call_get_timeout_unlocked (pending));
03331   _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
03332 
03333   _dbus_verbose ("middle\n");
03334   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03335 
03336   /* Unlocks, and calls out to user code */
03337   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03338   
03339   return TRUE;
03340 }
03341 
03381 dbus_bool_t
03382 dbus_connection_send_with_reply (DBusConnection     *connection,
03383                                  DBusMessage        *message,
03384                                  DBusPendingCall   **pending_return,
03385                                  int                 timeout_milliseconds)
03386 {
03387   DBusPendingCall *pending;
03388   dbus_int32_t serial = -1;
03389   DBusDispatchStatus status;
03390 
03391   _dbus_return_val_if_fail (connection != NULL, FALSE);
03392   _dbus_return_val_if_fail (message != NULL, FALSE);
03393   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03394 
03395   if (pending_return)
03396     *pending_return = NULL;
03397 
03398   CONNECTION_LOCK (connection);
03399 
03400 #ifdef HAVE_UNIX_FD_PASSING
03401 
03402   if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03403       message->n_unix_fds > 0)
03404     {
03405       /* Refuse to send fds on a connection that cannot handle
03406          them. Unfortunately we cannot return a proper error here, so
03407          the best we can do is return TRUE but leave *pending_return
03408          as NULL. */
03409       CONNECTION_UNLOCK (connection);
03410       return TRUE;
03411     }
03412 
03413 #endif
03414 
03415    if (!_dbus_connection_get_is_connected_unlocked (connection))
03416     {
03417       CONNECTION_UNLOCK (connection);
03418 
03419       return TRUE;
03420     }
03421 
03422   pending = _dbus_pending_call_new_unlocked (connection,
03423                                              timeout_milliseconds,
03424                                              reply_handler_timeout);
03425 
03426   if (pending == NULL)
03427     {
03428       CONNECTION_UNLOCK (connection);
03429       return FALSE;
03430     }
03431 
03432   /* Assign a serial to the message */
03433   serial = dbus_message_get_serial (message);
03434   if (serial == 0)
03435     {
03436       serial = _dbus_connection_get_next_client_serial (connection);
03437       dbus_message_set_serial (message, serial);
03438     }
03439 
03440   if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
03441     goto error;
03442     
03443   /* Insert the serial in the pending replies hash;
03444    * hash takes a refcount on DBusPendingCall.
03445    * Also, add the timeout.
03446    */
03447   if (!_dbus_connection_attach_pending_call_unlocked (connection,
03448                                                       pending))
03449     goto error;
03450  
03451   if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
03452     {
03453       _dbus_connection_detach_pending_call_and_unlock (connection,
03454                                                        pending);
03455       goto error_unlocked;
03456     }
03457 
03458   if (pending_return)
03459     *pending_return = pending; /* hand off refcount */
03460   else
03461     {
03462       _dbus_connection_detach_pending_call_unlocked (connection, pending);
03463       /* we still have a ref to the pending call in this case, we unref
03464        * after unlocking, below
03465        */
03466     }
03467 
03468   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03469 
03470   /* this calls out to user code */
03471   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03472 
03473   if (pending_return == NULL)
03474     dbus_pending_call_unref (pending);
03475   
03476   return TRUE;
03477 
03478  error:
03479   CONNECTION_UNLOCK (connection);
03480  error_unlocked:
03481   dbus_pending_call_unref (pending);
03482   return FALSE;
03483 }
03484 
03515 DBusMessage*
03516 dbus_connection_send_with_reply_and_block (DBusConnection     *connection,
03517                                            DBusMessage        *message,
03518                                            int                 timeout_milliseconds,
03519                                            DBusError          *error)
03520 {
03521   DBusMessage *reply;
03522   DBusPendingCall *pending;
03523 
03524   _dbus_return_val_if_fail (connection != NULL, NULL);
03525   _dbus_return_val_if_fail (message != NULL, NULL);
03526   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL);
03527   _dbus_return_val_if_error_is_set (error, NULL);
03528 
03529 #ifdef HAVE_UNIX_FD_PASSING
03530 
03531   CONNECTION_LOCK (connection);
03532   if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03533       message->n_unix_fds > 0)
03534     {
03535       CONNECTION_UNLOCK (connection);
03536       dbus_set_error(error, DBUS_ERROR_FAILED, "Cannot send file descriptors on this connection.");
03537       return NULL;
03538     }
03539   CONNECTION_UNLOCK (connection);
03540 
03541 #endif
03542 
03543   if (!dbus_connection_send_with_reply (connection, message,
03544                                         &pending, timeout_milliseconds))
03545     {
03546       _DBUS_SET_OOM (error);
03547       return NULL;
03548     }
03549 
03550   if (pending == NULL)
03551     {
03552       dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Connection is closed");
03553       return NULL;
03554     }
03555   
03556   dbus_pending_call_block (pending);
03557 
03558   reply = dbus_pending_call_steal_reply (pending);
03559   dbus_pending_call_unref (pending);
03560 
03561   /* call_complete_and_unlock() called from pending_call_block() should
03562    * always fill this in.
03563    */
03564   _dbus_assert (reply != NULL);
03565   
03566    if (dbus_set_error_from_message (error, reply))
03567     {
03568       dbus_message_unref (reply);
03569       return NULL;
03570     }
03571   else
03572     return reply;
03573 }
03574 
03583 static DBusDispatchStatus
03584 _dbus_connection_flush_unlocked (DBusConnection *connection)
03585 {
03586   /* We have to specify DBUS_ITERATION_DO_READING here because
03587    * otherwise we could have two apps deadlock if they are both doing
03588    * a flush(), and the kernel buffers fill up. This could change the
03589    * dispatch status.
03590    */
03591   DBusDispatchStatus status;
03592 
03593   HAVE_LOCK_CHECK (connection);
03594   
03595   while (connection->n_outgoing > 0 &&
03596          _dbus_connection_get_is_connected_unlocked (connection))
03597     {
03598       _dbus_verbose ("doing iteration in\n");
03599       HAVE_LOCK_CHECK (connection);
03600       _dbus_connection_do_iteration_unlocked (connection,
03601                                               NULL,
03602                                               DBUS_ITERATION_DO_READING |
03603                                               DBUS_ITERATION_DO_WRITING |
03604                                               DBUS_ITERATION_BLOCK,
03605                                               -1);
03606     }
03607 
03608   HAVE_LOCK_CHECK (connection);
03609   _dbus_verbose ("middle\n");
03610   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03611 
03612   HAVE_LOCK_CHECK (connection);
03613   return status;
03614 }
03615 
03621 void
03622 dbus_connection_flush (DBusConnection *connection)
03623 {
03624   /* We have to specify DBUS_ITERATION_DO_READING here because
03625    * otherwise we could have two apps deadlock if they are both doing
03626    * a flush(), and the kernel buffers fill up. This could change the
03627    * dispatch status.
03628    */
03629   DBusDispatchStatus status;
03630 
03631   _dbus_return_if_fail (connection != NULL);
03632   
03633   CONNECTION_LOCK (connection);
03634 
03635   status = _dbus_connection_flush_unlocked (connection);
03636   
03637   HAVE_LOCK_CHECK (connection);
03638   /* Unlocks and calls out to user code */
03639   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03640 
03641   _dbus_verbose ("end\n");
03642 }
03643 
03654 static dbus_bool_t
03655 _dbus_connection_read_write_dispatch (DBusConnection *connection,
03656                                      int             timeout_milliseconds, 
03657                                      dbus_bool_t     dispatch)
03658 {
03659   DBusDispatchStatus dstatus;
03660   dbus_bool_t progress_possible;
03661 
03662   /* Need to grab a ref here in case we're a private connection and
03663    * the user drops the last ref in a handler we call; see bug 
03664    * https://bugs.freedesktop.org/show_bug.cgi?id=15635
03665    */
03666   dbus_connection_ref (connection);
03667   dstatus = dbus_connection_get_dispatch_status (connection);
03668 
03669   if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
03670     {
03671       _dbus_verbose ("doing dispatch\n");
03672       dbus_connection_dispatch (connection);
03673       CONNECTION_LOCK (connection);
03674     }
03675   else if (dstatus == DBUS_DISPATCH_NEED_MEMORY)
03676     {
03677       _dbus_verbose ("pausing for memory\n");
03678       _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
03679       CONNECTION_LOCK (connection);
03680     }
03681   else
03682     {
03683       CONNECTION_LOCK (connection);
03684       if (_dbus_connection_get_is_connected_unlocked (connection))
03685         {
03686           _dbus_verbose ("doing iteration\n");
03687           _dbus_connection_do_iteration_unlocked (connection,
03688                                                   NULL,
03689                                                   DBUS_ITERATION_DO_READING |
03690                                                   DBUS_ITERATION_DO_WRITING |
03691                                                   DBUS_ITERATION_BLOCK,
03692                                                   timeout_milliseconds);
03693         }
03694     }
03695   
03696   HAVE_LOCK_CHECK (connection);
03697   /* If we can dispatch, we can make progress until the Disconnected message
03698    * has been processed; if we can only read/write, we can make progress
03699    * as long as the transport is open.
03700    */
03701   if (dispatch)
03702     progress_possible = connection->n_incoming != 0 ||
03703       connection->disconnect_message_link != NULL;
03704   else
03705     progress_possible = _dbus_connection_get_is_connected_unlocked (connection);
03706 
03707   CONNECTION_UNLOCK (connection);
03708 
03709   dbus_connection_unref (connection);
03710 
03711   return progress_possible; /* TRUE if we can make more progress */
03712 }
03713 
03714 
03749 dbus_bool_t
03750 dbus_connection_read_write_dispatch (DBusConnection *connection,
03751                                      int             timeout_milliseconds)
03752 {
03753   _dbus_return_val_if_fail (connection != NULL, FALSE);
03754   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03755    return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE);
03756 }
03757 
03781 dbus_bool_t 
03782 dbus_connection_read_write (DBusConnection *connection, 
03783                             int             timeout_milliseconds) 
03784 { 
03785   _dbus_return_val_if_fail (connection != NULL, FALSE);
03786   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03787    return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE);
03788 }
03789 
03790 /* We need to call this anytime we pop the head of the queue, and then
03791  * update_dispatch_status_and_unlock needs to be called afterward
03792  * which will "process" the disconnected message and set
03793  * disconnected_message_processed.
03794  */
03795 static void
03796 check_disconnected_message_arrived_unlocked (DBusConnection *connection,
03797                                              DBusMessage    *head_of_queue)
03798 {
03799   HAVE_LOCK_CHECK (connection);
03800 
03801   /* checking that the link is NULL is an optimization to avoid the is_signal call */
03802   if (connection->disconnect_message_link == NULL &&
03803       dbus_message_is_signal (head_of_queue,
03804                               DBUS_INTERFACE_LOCAL,
03805                               "Disconnected"))
03806     {
03807       connection->disconnected_message_arrived = TRUE;
03808     }
03809 }
03810 
03830 DBusMessage*
03831 dbus_connection_borrow_message (DBusConnection *connection)
03832 {
03833   DBusDispatchStatus status;
03834   DBusMessage *message;
03835 
03836   _dbus_return_val_if_fail (connection != NULL, NULL);
03837 
03838   _dbus_verbose ("start\n");
03839   
03840   /* this is called for the side effect that it queues
03841    * up any messages from the transport
03842    */
03843   status = dbus_connection_get_dispatch_status (connection);
03844   if (status != DBUS_DISPATCH_DATA_REMAINS)
03845     return NULL;
03846   
03847   CONNECTION_LOCK (connection);
03848 
03849   _dbus_connection_acquire_dispatch (connection);
03850 
03851   /* While a message is outstanding, the dispatch lock is held */
03852   _dbus_assert (connection->message_borrowed == NULL);
03853 
03854   connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
03855   
03856   message = connection->message_borrowed;
03857 
03858   check_disconnected_message_arrived_unlocked (connection, message);
03859   
03860   /* Note that we KEEP the dispatch lock until the message is returned */
03861   if (message == NULL)
03862     _dbus_connection_release_dispatch (connection);
03863 
03864   CONNECTION_UNLOCK (connection);
03865 
03866   /* We don't update dispatch status until it's returned or stolen */
03867   
03868   return message;
03869 }
03870 
03879 void
03880 dbus_connection_return_message (DBusConnection *connection,
03881                                 DBusMessage    *message)
03882 {
03883   DBusDispatchStatus status;
03884   
03885   _dbus_return_if_fail (connection != NULL);
03886   _dbus_return_if_fail (message != NULL);
03887   _dbus_return_if_fail (message == connection->message_borrowed);
03888   _dbus_return_if_fail (connection->dispatch_acquired);
03889   
03890   CONNECTION_LOCK (connection);
03891   
03892   _dbus_assert (message == connection->message_borrowed);
03893   
03894   connection->message_borrowed = NULL;
03895 
03896   _dbus_connection_release_dispatch (connection); 
03897 
03898   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03899   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03900 }
03901 
03911 void
03912 dbus_connection_steal_borrowed_message (DBusConnection *connection,
03913                                         DBusMessage    *message)
03914 {
03915   DBusMessage *pop_message;
03916   DBusDispatchStatus status;
03917 
03918   _dbus_return_if_fail (connection != NULL);
03919   _dbus_return_if_fail (message != NULL);
03920   _dbus_return_if_fail (message == connection->message_borrowed);
03921   _dbus_return_if_fail (connection->dispatch_acquired);
03922   
03923   CONNECTION_LOCK (connection);
03924  
03925   _dbus_assert (message == connection->message_borrowed);
03926 
03927   pop_message = _dbus_list_pop_first (&connection->incoming_messages);
03928   _dbus_assert (message == pop_message);
03929   
03930   connection->n_incoming -= 1;
03931  
03932   _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
03933                  message, connection->n_incoming);
03934  
03935   connection->message_borrowed = NULL;
03936 
03937   _dbus_connection_release_dispatch (connection);
03938 
03939   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03940   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03941 }
03942 
03943 /* See dbus_connection_pop_message, but requires the caller to own
03944  * the lock before calling. May drop the lock while running.
03945  */
03946 static DBusList*
03947 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
03948 {
03949   HAVE_LOCK_CHECK (connection);
03950   
03951   _dbus_assert (connection->message_borrowed == NULL);
03952   
03953   if (connection->n_incoming > 0)
03954     {
03955       DBusList *link;
03956 
03957       link = _dbus_list_pop_first_link (&connection->incoming_messages);
03958       connection->n_incoming -= 1;
03959 
03960       _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from incoming queue %p, %d incoming\n",
03961                      link->data,
03962                      dbus_message_type_to_string (dbus_message_get_type (link->data)),
03963                      dbus_message_get_path (link->data) ?
03964                      dbus_message_get_path (link->data) :
03965                      "no path",
03966                      dbus_message_get_interface (link->data) ?
03967                      dbus_message_get_interface (link->data) :
03968                      "no interface",
03969                      dbus_message_get_member (link->data) ?
03970                      dbus_message_get_member (link->data) :
03971                      "no member",
03972                      dbus_message_get_signature (link->data),
03973                      connection, connection->n_incoming);
03974 
03975       check_disconnected_message_arrived_unlocked (connection, link->data);
03976       
03977       return link;
03978     }
03979   else
03980     return NULL;
03981 }
03982 
03983 /* See dbus_connection_pop_message, but requires the caller to own
03984  * the lock before calling. May drop the lock while running.
03985  */
03986 static DBusMessage*
03987 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
03988 {
03989   DBusList *link;
03990 
03991   HAVE_LOCK_CHECK (connection);
03992   
03993   link = _dbus_connection_pop_message_link_unlocked (connection);
03994 
03995   if (link != NULL)
03996     {
03997       DBusMessage *message;
03998       
03999       message = link->data;
04000       
04001       _dbus_list_free_link (link);
04002       
04003       return message;
04004     }
04005   else
04006     return NULL;
04007 }
04008 
04009 static void
04010 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
04011                                                 DBusList       *message_link)
04012 {
04013   HAVE_LOCK_CHECK (connection);
04014   
04015   _dbus_assert (message_link != NULL);
04016   /* You can't borrow a message while a link is outstanding */
04017   _dbus_assert (connection->message_borrowed == NULL);
04018   /* We had to have the dispatch lock across the pop/putback */
04019   _dbus_assert (connection->dispatch_acquired);
04020 
04021   _dbus_list_prepend_link (&connection->incoming_messages,
04022                            message_link);
04023   connection->n_incoming += 1;
04024 
04025   _dbus_verbose ("Message %p (%s %s %s '%s') put back into queue %p, %d incoming\n",
04026                  message_link->data,
04027                  dbus_message_type_to_string (dbus_message_get_type (message_link->data)),
04028                  dbus_message_get_interface (message_link->data) ?
04029                  dbus_message_get_interface (message_link->data) :
04030                  "no interface",
04031                  dbus_message_get_member (message_link->data) ?
04032                  dbus_message_get_member (message_link->data) :
04033                  "no member",
04034                  dbus_message_get_signature (message_link->data),
04035                  connection, connection->n_incoming);
04036 }
04037 
04057 DBusMessage*
04058 dbus_connection_pop_message (DBusConnection *connection)
04059 {
04060   DBusMessage *message;
04061   DBusDispatchStatus status;
04062 
04063   _dbus_verbose ("start\n");
04064   
04065   /* this is called for the side effect that it queues
04066    * up any messages from the transport
04067    */
04068   status = dbus_connection_get_dispatch_status (connection);
04069   if (status != DBUS_DISPATCH_DATA_REMAINS)
04070     return NULL;
04071   
04072   CONNECTION_LOCK (connection);
04073   _dbus_connection_acquire_dispatch (connection);
04074   HAVE_LOCK_CHECK (connection);
04075   
04076   message = _dbus_connection_pop_message_unlocked (connection);
04077 
04078   _dbus_verbose ("Returning popped message %p\n", message);    
04079 
04080   _dbus_connection_release_dispatch (connection);
04081 
04082   status = _dbus_connection_get_dispatch_status_unlocked (connection);
04083   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04084   
04085   return message;
04086 }
04087 
04095 static void
04096 _dbus_connection_acquire_dispatch (DBusConnection *connection)
04097 {
04098   HAVE_LOCK_CHECK (connection);
04099 
04100   _dbus_connection_ref_unlocked (connection);
04101   CONNECTION_UNLOCK (connection);
04102   
04103   _dbus_verbose ("locking dispatch_mutex\n");
04104   _dbus_mutex_lock (connection->dispatch_mutex);
04105 
04106   while (connection->dispatch_acquired)
04107     {
04108       _dbus_verbose ("waiting for dispatch to be acquirable\n");
04109       _dbus_condvar_wait (connection->dispatch_cond, 
04110                           connection->dispatch_mutex);
04111     }
04112   
04113   _dbus_assert (!connection->dispatch_acquired);
04114 
04115   connection->dispatch_acquired = TRUE;
04116 
04117   _dbus_verbose ("unlocking dispatch_mutex\n");
04118   _dbus_mutex_unlock (connection->dispatch_mutex);
04119   
04120   CONNECTION_LOCK (connection);
04121   _dbus_connection_unref_unlocked (connection);
04122 }
04123 
04131 static void
04132 _dbus_connection_release_dispatch (DBusConnection *connection)
04133 {
04134   HAVE_LOCK_CHECK (connection);
04135   
04136   _dbus_verbose ("locking dispatch_mutex\n");
04137   _dbus_mutex_lock (connection->dispatch_mutex);
04138   
04139   _dbus_assert (connection->dispatch_acquired);
04140 
04141   connection->dispatch_acquired = FALSE;
04142   _dbus_condvar_wake_one (connection->dispatch_cond);
04143 
04144   _dbus_verbose ("unlocking dispatch_mutex\n");
04145   _dbus_mutex_unlock (connection->dispatch_mutex);
04146 }
04147 
04148 static void
04149 _dbus_connection_failed_pop (DBusConnection *connection,
04150                              DBusList       *message_link)
04151 {
04152   _dbus_list_prepend_link (&connection->incoming_messages,
04153                            message_link);
04154   connection->n_incoming += 1;
04155 }
04156 
04157 /* Note this may be called multiple times since we don't track whether we already did it */
04158 static void
04159 notify_disconnected_unlocked (DBusConnection *connection)
04160 {
04161   HAVE_LOCK_CHECK (connection);
04162 
04163   /* Set the weakref in dbus-bus.c to NULL, so nobody will get a disconnected
04164    * connection from dbus_bus_get(). We make the same guarantee for
04165    * dbus_connection_open() but in a different way since we don't want to
04166    * unref right here; we instead check for connectedness before returning
04167    * the connection from the hash.
04168    */
04169   _dbus_bus_notify_shared_connection_disconnected_unlocked (connection);
04170 
04171   /* Dump the outgoing queue, we aren't going to be able to
04172    * send it now, and we'd like accessors like
04173    * dbus_connection_get_outgoing_size() to be accurate.
04174    */
04175   if (connection->n_outgoing > 0)
04176     {
04177       DBusList *link;
04178       
04179       _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
04180                      connection->n_outgoing);
04181       
04182       while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
04183         {
04184           _dbus_connection_message_sent (connection, link->data);
04185         }
04186     } 
04187 }
04188 
04189 /* Note this may be called multiple times since we don't track whether we already did it */
04190 static DBusDispatchStatus
04191 notify_disconnected_and_dispatch_complete_unlocked (DBusConnection *connection)
04192 {
04193   HAVE_LOCK_CHECK (connection);
04194   
04195   if (connection->disconnect_message_link != NULL)
04196     {
04197       _dbus_verbose ("Sending disconnect message\n");
04198       
04199       /* If we have pending calls, queue their timeouts - we want the Disconnected
04200        * to be the last message, after these timeouts.
04201        */
04202       connection_timeout_and_complete_all_pending_calls_unlocked (connection);
04203       
04204       /* We haven't sent the disconnect message already,
04205        * and all real messages have been queued up.
04206        */
04207       _dbus_connection_queue_synthesized_message_link (connection,
04208                                                        connection->disconnect_message_link);
04209       connection->disconnect_message_link = NULL;
04210 
04211       return DBUS_DISPATCH_DATA_REMAINS;
04212     }
04213 
04214   return DBUS_DISPATCH_COMPLETE;
04215 }
04216 
04217 static DBusDispatchStatus
04218 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
04219 {
04220   HAVE_LOCK_CHECK (connection);
04221   
04222   if (connection->n_incoming > 0)
04223     return DBUS_DISPATCH_DATA_REMAINS;
04224   else if (!_dbus_transport_queue_messages (connection->transport))
04225     return DBUS_DISPATCH_NEED_MEMORY;
04226   else
04227     {
04228       DBusDispatchStatus status;
04229       dbus_bool_t is_connected;
04230       
04231       status = _dbus_transport_get_dispatch_status (connection->transport);
04232       is_connected = _dbus_transport_get_is_connected (connection->transport);
04233 
04234       _dbus_verbose ("dispatch status = %s is_connected = %d\n",
04235                      DISPATCH_STATUS_NAME (status), is_connected);
04236       
04237       if (!is_connected)
04238         {
04239           /* It's possible this would be better done by having an explicit
04240            * notification from _dbus_transport_disconnect() that would
04241            * synchronously do this, instead of waiting for the next dispatch
04242            * status check. However, probably not good to change until it causes
04243            * a problem.
04244            */
04245           notify_disconnected_unlocked (connection);
04246 
04247           /* I'm not sure this is needed; the idea is that we want to
04248            * queue the Disconnected only after we've read all the
04249            * messages, but if we're disconnected maybe we are guaranteed
04250            * to have read them all ?
04251            */
04252           if (status == DBUS_DISPATCH_COMPLETE)
04253             status = notify_disconnected_and_dispatch_complete_unlocked (connection);
04254         }
04255       
04256       if (status != DBUS_DISPATCH_COMPLETE)
04257         return status;
04258       else if (connection->n_incoming > 0)
04259         return DBUS_DISPATCH_DATA_REMAINS;
04260       else
04261         return DBUS_DISPATCH_COMPLETE;
04262     }
04263 }
04264 
04265 static void
04266 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection    *connection,
04267                                                     DBusDispatchStatus new_status)
04268 {
04269   dbus_bool_t changed;
04270   DBusDispatchStatusFunction function;
04271   void *data;
04272 
04273   HAVE_LOCK_CHECK (connection);
04274 
04275   _dbus_connection_ref_unlocked (connection);
04276 
04277   changed = new_status != connection->last_dispatch_status;
04278 
04279   connection->last_dispatch_status = new_status;
04280 
04281   function = connection->dispatch_status_function;
04282   data = connection->dispatch_status_data;
04283 
04284   if (connection->disconnected_message_arrived &&
04285       !connection->disconnected_message_processed)
04286     {
04287       connection->disconnected_message_processed = TRUE;
04288       
04289       /* this does an unref, but we have a ref
04290        * so we should not run the finalizer here
04291        * inside the lock.
04292        */
04293       connection_forget_shared_unlocked (connection);
04294 
04295       if (connection->exit_on_disconnect)
04296         {
04297           CONNECTION_UNLOCK (connection);            
04298           
04299           _dbus_verbose ("Exiting on Disconnected signal\n");
04300           _dbus_exit (1);
04301           _dbus_assert_not_reached ("Call to exit() returned");
04302         }
04303     }
04304   
04305   /* We drop the lock */
04306   CONNECTION_UNLOCK (connection);
04307   
04308   if (changed && function)
04309     {
04310       _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
04311                      connection, new_status,
04312                      DISPATCH_STATUS_NAME (new_status));
04313       (* function) (connection, new_status, data);      
04314     }
04315   
04316   dbus_connection_unref (connection);
04317 }
04318 
04344 DBusDispatchStatus
04345 dbus_connection_get_dispatch_status (DBusConnection *connection)
04346 {
04347   DBusDispatchStatus status;
04348 
04349   _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04350 
04351   _dbus_verbose ("start\n");
04352   
04353   CONNECTION_LOCK (connection);
04354 
04355   status = _dbus_connection_get_dispatch_status_unlocked (connection);
04356   
04357   CONNECTION_UNLOCK (connection);
04358 
04359   return status;
04360 }
04361 
04365 static DBusHandlerResult
04366 _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
04367                                                  DBusMessage    *message)
04368 {
04369   if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
04370     {
04371       /* This means we're letting the bus route this message */
04372       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04373     }
04374   else if (dbus_message_is_method_call (message,
04375                                         DBUS_INTERFACE_PEER,
04376                                         "Ping"))
04377     {
04378       DBusMessage *ret;
04379       dbus_bool_t sent;
04380       
04381       ret = dbus_message_new_method_return (message);
04382       if (ret == NULL)
04383         return DBUS_HANDLER_RESULT_NEED_MEMORY;
04384      
04385       sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04386 
04387       dbus_message_unref (ret);
04388 
04389       if (!sent)
04390         return DBUS_HANDLER_RESULT_NEED_MEMORY;
04391       
04392       return DBUS_HANDLER_RESULT_HANDLED;
04393     }
04394   else if (dbus_message_is_method_call (message,
04395                                         DBUS_INTERFACE_PEER,
04396                                         "GetMachineId"))
04397     {
04398       DBusMessage *ret;
04399       dbus_bool_t sent;
04400       DBusString uuid;
04401       
04402       ret = dbus_message_new_method_return (message);
04403       if (ret == NULL)
04404         return DBUS_HANDLER_RESULT_NEED_MEMORY;
04405 
04406       sent = FALSE;
04407       _dbus_string_init (&uuid);
04408       if (_dbus_get_local_machine_uuid_encoded (&uuid))
04409         {
04410           const char *v_STRING = _dbus_string_get_const_data (&uuid);
04411           if (dbus_message_append_args (ret,
04412                                         DBUS_TYPE_STRING, &v_STRING,
04413                                         DBUS_TYPE_INVALID))
04414             {
04415               sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04416             }
04417         }
04418       _dbus_string_free (&uuid);
04419       
04420       dbus_message_unref (ret);
04421 
04422       if (!sent)
04423         return DBUS_HANDLER_RESULT_NEED_MEMORY;
04424       
04425       return DBUS_HANDLER_RESULT_HANDLED;
04426     }
04427   else if (dbus_message_has_interface (message, DBUS_INTERFACE_PEER))
04428     {
04429       /* We need to bounce anything else with this interface, otherwise apps
04430        * could start extending the interface and when we added extensions
04431        * here to DBusConnection we'd break those apps.
04432        */
04433       
04434       DBusMessage *ret;
04435       dbus_bool_t sent;
04436       
04437       ret = dbus_message_new_error (message,
04438                                     DBUS_ERROR_UNKNOWN_METHOD,
04439                                     "Unknown method invoked on org.freedesktop.DBus.Peer interface");
04440       if (ret == NULL)
04441         return DBUS_HANDLER_RESULT_NEED_MEMORY;
04442       
04443       sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04444       
04445       dbus_message_unref (ret);
04446       
04447       if (!sent)
04448         return DBUS_HANDLER_RESULT_NEED_MEMORY;
04449       
04450       return DBUS_HANDLER_RESULT_HANDLED;
04451     }
04452   else
04453     {
04454       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04455     }
04456 }
04457 
04464 static DBusHandlerResult
04465 _dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection,
04466                                                            DBusMessage    *message)
04467 {
04468   /* We just run one filter for now but have the option to run more
04469      if the spec calls for it in the future */
04470 
04471   return _dbus_connection_peer_filter_unlocked_no_update (connection, message);
04472 }
04473 
04516 DBusDispatchStatus
04517 dbus_connection_dispatch (DBusConnection *connection)
04518 {
04519   DBusMessage *message;
04520   DBusList *link, *filter_list_copy, *message_link;
04521   DBusHandlerResult result;
04522   DBusPendingCall *pending;
04523   dbus_int32_t reply_serial;
04524   DBusDispatchStatus status;
04525 
04526   _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04527 
04528   _dbus_verbose ("\n");
04529   
04530   CONNECTION_LOCK (connection);
04531   status = _dbus_connection_get_dispatch_status_unlocked (connection);
04532   if (status != DBUS_DISPATCH_DATA_REMAINS)
04533     {
04534       /* unlocks and calls out to user code */
04535       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04536       return status;
04537     }
04538   
04539   /* We need to ref the connection since the callback could potentially
04540    * drop the last ref to it
04541    */
04542   _dbus_connection_ref_unlocked (connection);
04543 
04544   _dbus_connection_acquire_dispatch (connection);
04545   HAVE_LOCK_CHECK (connection);
04546 
04547   message_link = _dbus_connection_pop_message_link_unlocked (connection);
04548   if (message_link == NULL)
04549     {
04550       /* another thread dispatched our stuff */
04551 
04552       _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
04553       
04554       _dbus_connection_release_dispatch (connection);
04555 
04556       status = _dbus_connection_get_dispatch_status_unlocked (connection);
04557 
04558       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04559       
04560       dbus_connection_unref (connection);
04561       
04562       return status;
04563     }
04564 
04565   message = message_link->data;
04566 
04567   _dbus_verbose (" dispatching message %p (%s %s %s '%s')\n",
04568                  message,
04569                  dbus_message_type_to_string (dbus_message_get_type (message)),
04570                  dbus_message_get_interface (message) ?
04571                  dbus_message_get_interface (message) :
04572                  "no interface",
04573                  dbus_message_get_member (message) ?
04574                  dbus_message_get_member (message) :
04575                  "no member",
04576                  dbus_message_get_signature (message));
04577 
04578   result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04579   
04580   /* Pending call handling must be first, because if you do
04581    * dbus_connection_send_with_reply_and_block() or
04582    * dbus_pending_call_block() then no handlers/filters will be run on
04583    * the reply. We want consistent semantics in the case where we
04584    * dbus_connection_dispatch() the reply.
04585    */
04586   
04587   reply_serial = dbus_message_get_reply_serial (message);
04588   pending = _dbus_hash_table_lookup_int (connection->pending_replies,
04589                                          reply_serial);
04590   if (pending)
04591     {
04592       _dbus_verbose ("Dispatching a pending reply\n");
04593       complete_pending_call_and_unlock (connection, pending, message);
04594       pending = NULL; /* it's probably unref'd */
04595       
04596       CONNECTION_LOCK (connection);
04597       _dbus_verbose ("pending call completed in dispatch\n");
04598       result = DBUS_HANDLER_RESULT_HANDLED;
04599       goto out;
04600     }
04601 
04602   result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message);
04603   if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04604     goto out;
04605  
04606   if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
04607     {
04608       _dbus_connection_release_dispatch (connection);
04609       HAVE_LOCK_CHECK (connection);
04610       
04611       _dbus_connection_failed_pop (connection, message_link);
04612 
04613       /* unlocks and calls user code */
04614       _dbus_connection_update_dispatch_status_and_unlock (connection,
04615                                                           DBUS_DISPATCH_NEED_MEMORY);
04616 
04617       if (pending)
04618         dbus_pending_call_unref (pending);
04619       dbus_connection_unref (connection);
04620       
04621       return DBUS_DISPATCH_NEED_MEMORY;
04622     }
04623   
04624   _dbus_list_foreach (&filter_list_copy,
04625                       (DBusForeachFunction)_dbus_message_filter_ref,
04626                       NULL);
04627 
04628   /* We're still protected from dispatch() reentrancy here
04629    * since we acquired the dispatcher
04630    */
04631   CONNECTION_UNLOCK (connection);
04632   
04633   link = _dbus_list_get_first_link (&filter_list_copy);
04634   while (link != NULL)
04635     {
04636       DBusMessageFilter *filter = link->data;
04637       DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
04638 
04639       if (filter->function == NULL)
04640         {
04641           _dbus_verbose ("  filter was removed in a callback function\n");
04642           link = next;
04643           continue;
04644         }
04645 
04646       _dbus_verbose ("  running filter on message %p\n", message);
04647       result = (* filter->function) (connection, message, filter->user_data);
04648 
04649       if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04650         break;
04651 
04652       link = next;
04653     }
04654 
04655   _dbus_list_foreach (&filter_list_copy,
04656                       (DBusForeachFunction)_dbus_message_filter_unref,
04657                       NULL);
04658   _dbus_list_clear (&filter_list_copy);
04659   
04660   CONNECTION_LOCK (connection);
04661 
04662   if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04663     {
04664       _dbus_verbose ("No memory\n");
04665       goto out;
04666     }
04667   else if (result == DBUS_HANDLER_RESULT_HANDLED)
04668     {
04669       _dbus_verbose ("filter handled message in dispatch\n");
04670       goto out;
04671     }
04672 
04673   /* We're still protected from dispatch() reentrancy here
04674    * since we acquired the dispatcher
04675    */
04676   _dbus_verbose ("  running object path dispatch on message %p (%s %s %s '%s')\n",
04677                  message,
04678                  dbus_message_type_to_string (dbus_message_get_type (message)),
04679                  dbus_message_get_interface (message) ?
04680                  dbus_message_get_interface (message) :
04681                  "no interface",
04682                  dbus_message_get_member (message) ?
04683                  dbus_message_get_member (message) :
04684                  "no member",
04685                  dbus_message_get_signature (message));
04686 
04687   HAVE_LOCK_CHECK (connection);
04688   result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
04689                                                   message);
04690   
04691   CONNECTION_LOCK (connection);
04692 
04693   if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04694     {
04695       _dbus_verbose ("object tree handled message in dispatch\n");
04696       goto out;
04697     }
04698 
04699   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
04700     {
04701       DBusMessage *reply;
04702       DBusString str;
04703       DBusPreallocatedSend *preallocated;
04704 
04705       _dbus_verbose ("  sending error %s\n",
04706                      DBUS_ERROR_UNKNOWN_METHOD);
04707       
04708       if (!_dbus_string_init (&str))
04709         {
04710           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04711           _dbus_verbose ("no memory for error string in dispatch\n");
04712           goto out;
04713         }
04714               
04715       if (!_dbus_string_append_printf (&str,
04716                                        "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
04717                                        dbus_message_get_member (message),
04718                                        dbus_message_get_signature (message),
04719                                        dbus_message_get_interface (message)))
04720         {
04721           _dbus_string_free (&str);
04722           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04723           _dbus_verbose ("no memory for error string in dispatch\n");
04724           goto out;
04725         }
04726       
04727       reply = dbus_message_new_error (message,
04728                                       DBUS_ERROR_UNKNOWN_METHOD,
04729                                       _dbus_string_get_const_data (&str));
04730       _dbus_string_free (&str);
04731 
04732       if (reply == NULL)
04733         {
04734           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04735           _dbus_verbose ("no memory for error reply in dispatch\n");
04736           goto out;
04737         }
04738       
04739       preallocated = _dbus_connection_preallocate_send_unlocked (connection);
04740 
04741       if (preallocated == NULL)
04742         {
04743           dbus_message_unref (reply);
04744           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04745           _dbus_verbose ("no memory for error send in dispatch\n");
04746           goto out;
04747         }
04748 
04749       _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
04750                                                              reply, NULL);
04751 
04752       dbus_message_unref (reply);
04753       
04754       result = DBUS_HANDLER_RESULT_HANDLED;
04755     }
04756   
04757   _dbus_verbose ("  done dispatching %p (%s %s %s '%s') on connection %p\n", message,
04758                  dbus_message_type_to_string (dbus_message_get_type (message)),
04759                  dbus_message_get_interface (message) ?
04760                  dbus_message_get_interface (message) :
04761                  "no interface",
04762                  dbus_message_get_member (message) ?
04763                  dbus_message_get_member (message) :
04764                  "no member",
04765                  dbus_message_get_signature (message),
04766                  connection);
04767   
04768  out:
04769   if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04770     {
04771       _dbus_verbose ("out of memory\n");
04772       
04773       /* Put message back, and we'll start over.
04774        * Yes this means handlers must be idempotent if they
04775        * don't return HANDLED; c'est la vie.
04776        */
04777       _dbus_connection_putback_message_link_unlocked (connection,
04778                                                       message_link);
04779     }
04780   else
04781     {
04782       _dbus_verbose (" ... done dispatching\n");
04783       
04784       _dbus_list_free_link (message_link);
04785       dbus_message_unref (message); /* don't want the message to count in max message limits
04786                                      * in computing dispatch status below
04787                                      */
04788     }
04789   
04790   _dbus_connection_release_dispatch (connection);
04791   HAVE_LOCK_CHECK (connection);
04792 
04793   _dbus_verbose ("before final status update\n");
04794   status = _dbus_connection_get_dispatch_status_unlocked (connection);
04795 
04796   /* unlocks and calls user code */
04797   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04798   
04799   dbus_connection_unref (connection);
04800   
04801   return status;
04802 }
04803 
04865 dbus_bool_t
04866 dbus_connection_set_watch_functions (DBusConnection              *connection,
04867                                      DBusAddWatchFunction         add_function,
04868                                      DBusRemoveWatchFunction      remove_function,
04869                                      DBusWatchToggledFunction     toggled_function,
04870                                      void                        *data,
04871                                      DBusFreeFunction             free_data_function)
04872 {
04873   dbus_bool_t retval;
04874 
04875   _dbus_return_val_if_fail (connection != NULL, FALSE);
04876   
04877   CONNECTION_LOCK (connection);
04878 
04879   retval = _dbus_watch_list_set_functions (connection->watches,
04880                                            add_function, remove_function,
04881                                            toggled_function,
04882                                            data, free_data_function);
04883 
04884   CONNECTION_UNLOCK (connection);
04885 
04886   return retval;
04887 }
04888 
04928 dbus_bool_t
04929 dbus_connection_set_timeout_functions   (DBusConnection            *connection,
04930                                          DBusAddTimeoutFunction     add_function,
04931                                          DBusRemoveTimeoutFunction  remove_function,
04932                                          DBusTimeoutToggledFunction toggled_function,
04933                                          void                      *data,
04934                                          DBusFreeFunction           free_data_function)
04935 {
04936   dbus_bool_t retval;
04937 
04938   _dbus_return_val_if_fail (connection != NULL, FALSE);
04939   
04940   CONNECTION_LOCK (connection);
04941 
04942   retval = _dbus_timeout_list_set_functions (connection->timeouts,
04943                                              add_function, remove_function,
04944                                              toggled_function,
04945                                              data, free_data_function);
04946 
04947   CONNECTION_UNLOCK (connection);
04948 
04949   return retval;
04950 }
04951 
04966 void
04967 dbus_connection_set_wakeup_main_function (DBusConnection            *connection,
04968                                           DBusWakeupMainFunction     wakeup_main_function,
04969                                           void                      *data,
04970                                           DBusFreeFunction           free_data_function)
04971 {
04972   void *old_data;
04973   DBusFreeFunction old_free_data;
04974 
04975   _dbus_return_if_fail (connection != NULL);
04976   
04977   CONNECTION_LOCK (connection);
04978   old_data = connection->wakeup_main_data;
04979   old_free_data = connection->free_wakeup_main_data;
04980 
04981   connection->wakeup_main_function = wakeup_main_function;
04982   connection->wakeup_main_data = data;
04983   connection->free_wakeup_main_data = free_data_function;
04984   
04985   CONNECTION_UNLOCK (connection);
04986 
04987   /* Callback outside the lock */
04988   if (old_free_data)
04989     (*old_free_data) (old_data);
04990 }
04991 
05012 void
05013 dbus_connection_set_dispatch_status_function (DBusConnection             *connection,
05014                                               DBusDispatchStatusFunction  function,
05015                                               void                       *data,
05016                                               DBusFreeFunction            free_data_function)
05017 {
05018   void *old_data;
05019   DBusFreeFunction old_free_data;
05020 
05021   _dbus_return_if_fail (connection != NULL);
05022   
05023   CONNECTION_LOCK (connection);
05024   old_data = connection->dispatch_status_data;
05025   old_free_data = connection->free_dispatch_status_data;
05026 
05027   connection->dispatch_status_function = function;
05028   connection->dispatch_status_data = data;
05029   connection->free_dispatch_status_data = free_data_function;
05030   
05031   CONNECTION_UNLOCK (connection);
05032 
05033   /* Callback outside the lock */
05034   if (old_free_data)
05035     (*old_free_data) (old_data);
05036 }
05037 
05057 dbus_bool_t
05058 dbus_connection_get_unix_fd (DBusConnection *connection,
05059                              int            *fd)
05060 {
05061   _dbus_return_val_if_fail (connection != NULL, FALSE);
05062   _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
05063 
05064 #ifdef DBUS_WIN
05065   /* FIXME do this on a lower level */
05066   return FALSE;
05067 #endif
05068   
05069   return dbus_connection_get_socket(connection, fd);
05070 }
05071 
05087 dbus_bool_t
05088 dbus_connection_get_socket(DBusConnection              *connection,
05089                            int                         *fd)
05090 {
05091   dbus_bool_t retval;
05092 
05093   _dbus_return_val_if_fail (connection != NULL, FALSE);
05094   _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
05095   
05096   CONNECTION_LOCK (connection);
05097   
05098   retval = _dbus_transport_get_socket_fd (connection->transport,
05099                                           fd);
05100 
05101   CONNECTION_UNLOCK (connection);
05102 
05103   return retval;
05104 }
05105 
05106 
05129 dbus_bool_t
05130 dbus_connection_get_unix_user (DBusConnection *connection,
05131                                unsigned long  *uid)
05132 {
05133   dbus_bool_t result;
05134 
05135   _dbus_return_val_if_fail (connection != NULL, FALSE);
05136   _dbus_return_val_if_fail (uid != NULL, FALSE);
05137   
05138   CONNECTION_LOCK (connection);
05139 
05140   if (!_dbus_transport_get_is_authenticated (connection->transport))
05141     result = FALSE;
05142   else
05143     result = _dbus_transport_get_unix_user (connection->transport,
05144                                             uid);
05145 
05146 #ifdef DBUS_WIN
05147   _dbus_assert (!result);
05148 #endif
05149   
05150   CONNECTION_UNLOCK (connection);
05151 
05152   return result;
05153 }
05154 
05165 dbus_bool_t
05166 dbus_connection_get_unix_process_id (DBusConnection *connection,
05167                                      unsigned long  *pid)
05168 {
05169   dbus_bool_t result;
05170 
05171   _dbus_return_val_if_fail (connection != NULL, FALSE);
05172   _dbus_return_val_if_fail (pid != NULL, FALSE);
05173   
05174   CONNECTION_LOCK (connection);
05175 
05176   if (!_dbus_transport_get_is_authenticated (connection->transport))
05177     result = FALSE;
05178   else
05179     result = _dbus_transport_get_unix_process_id (connection->transport,
05180                                                   pid);
05181 
05182   CONNECTION_UNLOCK (connection);
05183 
05184   return result;
05185 }
05186 
05197 dbus_bool_t
05198 dbus_connection_get_adt_audit_session_data (DBusConnection *connection,
05199                                             void          **data,
05200                                             dbus_int32_t   *data_size)
05201 {
05202   dbus_bool_t result;
05203 
05204   _dbus_return_val_if_fail (connection != NULL, FALSE);
05205   _dbus_return_val_if_fail (data != NULL, FALSE);
05206   _dbus_return_val_if_fail (data_size != NULL, FALSE);
05207   
05208   CONNECTION_LOCK (connection);
05209 
05210   if (!_dbus_transport_get_is_authenticated (connection->transport))
05211     result = FALSE;
05212   else
05213     result = _dbus_transport_get_adt_audit_session_data (connection->transport,
05214                                                          data,
05215                                                          data_size);
05216   CONNECTION_UNLOCK (connection);
05217 
05218   return result;
05219 }
05220 
05243 void
05244 dbus_connection_set_unix_user_function (DBusConnection             *connection,
05245                                         DBusAllowUnixUserFunction   function,
05246                                         void                       *data,
05247                                         DBusFreeFunction            free_data_function)
05248 {
05249   void *old_data = NULL;
05250   DBusFreeFunction old_free_function = NULL;
05251 
05252   _dbus_return_if_fail (connection != NULL);
05253   
05254   CONNECTION_LOCK (connection);
05255   _dbus_transport_set_unix_user_function (connection->transport,
05256                                           function, data, free_data_function,
05257                                           &old_data, &old_free_function);
05258   CONNECTION_UNLOCK (connection);
05259 
05260   if (old_free_function != NULL)
05261     (* old_free_function) (old_data);
05262 }
05263 
05295 dbus_bool_t
05296 dbus_connection_get_windows_user (DBusConnection             *connection,
05297                                   char                      **windows_sid_p)
05298 {
05299   dbus_bool_t result;
05300 
05301   _dbus_return_val_if_fail (connection != NULL, FALSE);
05302   _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
05303   
05304   CONNECTION_LOCK (connection);
05305 
05306   if (!_dbus_transport_get_is_authenticated (connection->transport))
05307     result = FALSE;
05308   else
05309     result = _dbus_transport_get_windows_user (connection->transport,
05310                                                windows_sid_p);
05311 
05312 #ifdef DBUS_UNIX
05313   _dbus_assert (!result);
05314 #endif
05315   
05316   CONNECTION_UNLOCK (connection);
05317 
05318   return result;
05319 }
05320 
05342 void
05343 dbus_connection_set_windows_user_function (DBusConnection              *connection,
05344                                            DBusAllowWindowsUserFunction function,
05345                                            void                        *data,
05346                                            DBusFreeFunction             free_data_function)
05347 {
05348   void *old_data = NULL;
05349   DBusFreeFunction old_free_function = NULL;
05350 
05351   _dbus_return_if_fail (connection != NULL);
05352   
05353   CONNECTION_LOCK (connection);
05354   _dbus_transport_set_windows_user_function (connection->transport,
05355                                              function, data, free_data_function,
05356                                              &old_data, &old_free_function);
05357   CONNECTION_UNLOCK (connection);
05358 
05359   if (old_free_function != NULL)
05360     (* old_free_function) (old_data);
05361 }
05362 
05389 void
05390 dbus_connection_set_allow_anonymous (DBusConnection             *connection,
05391                                      dbus_bool_t                 value)
05392 {
05393   _dbus_return_if_fail (connection != NULL);
05394   
05395   CONNECTION_LOCK (connection);
05396   _dbus_transport_set_allow_anonymous (connection->transport, value);
05397   CONNECTION_UNLOCK (connection);
05398 }
05399 
05417 void
05418 dbus_connection_set_route_peer_messages (DBusConnection             *connection,
05419                                          dbus_bool_t                 value)
05420 {
05421   _dbus_return_if_fail (connection != NULL);
05422   
05423   CONNECTION_LOCK (connection);
05424   connection->route_peer_messages = TRUE;
05425   CONNECTION_UNLOCK (connection);
05426 }
05427 
05449 dbus_bool_t
05450 dbus_connection_add_filter (DBusConnection            *connection,
05451                             DBusHandleMessageFunction  function,
05452                             void                      *user_data,
05453                             DBusFreeFunction           free_data_function)
05454 {
05455   DBusMessageFilter *filter;
05456   
05457   _dbus_return_val_if_fail (connection != NULL, FALSE);
05458   _dbus_return_val_if_fail (function != NULL, FALSE);
05459 
05460   filter = dbus_new0 (DBusMessageFilter, 1);
05461   if (filter == NULL)
05462     return FALSE;
05463 
05464   filter->refcount.value = 1;
05465   
05466   CONNECTION_LOCK (connection);
05467 
05468   if (!_dbus_list_append (&connection->filter_list,
05469                           filter))
05470     {
05471       _dbus_message_filter_unref (filter);
05472       CONNECTION_UNLOCK (connection);
05473       return FALSE;
05474     }
05475 
05476   /* Fill in filter after all memory allocated,
05477    * so we don't run the free_user_data_function
05478    * if the add_filter() fails
05479    */
05480   
05481   filter->function = function;
05482   filter->user_data = user_data;
05483   filter->free_user_data_function = free_data_function;
05484         
05485   CONNECTION_UNLOCK (connection);
05486   return TRUE;
05487 }
05488 
05501 void
05502 dbus_connection_remove_filter (DBusConnection            *connection,
05503                                DBusHandleMessageFunction  function,
05504                                void                      *user_data)
05505 {
05506   DBusList *link;
05507   DBusMessageFilter *filter;
05508   
05509   _dbus_return_if_fail (connection != NULL);
05510   _dbus_return_if_fail (function != NULL);
05511   
05512   CONNECTION_LOCK (connection);
05513 
05514   filter = NULL;
05515   
05516   link = _dbus_list_get_last_link (&connection->filter_list);
05517   while (link != NULL)
05518     {
05519       filter = link->data;
05520 
05521       if (filter->function == function &&
05522           filter->user_data == user_data)
05523         {
05524           _dbus_list_remove_link (&connection->filter_list, link);
05525           filter->function = NULL;
05526           
05527           break;
05528         }
05529         
05530       link = _dbus_list_get_prev_link (&connection->filter_list, link);
05531       filter = NULL;
05532     }
05533   
05534   CONNECTION_UNLOCK (connection);
05535 
05536 #ifndef DBUS_DISABLE_CHECKS
05537   if (filter == NULL)
05538     {
05539       _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
05540                                function, user_data);
05541       return;
05542     }
05543 #endif
05544   
05545   /* Call application code */
05546   if (filter->free_user_data_function)
05547     (* filter->free_user_data_function) (filter->user_data);
05548 
05549   filter->free_user_data_function = NULL;
05550   filter->user_data = NULL;
05551   
05552   _dbus_message_filter_unref (filter);
05553 }
05554 
05567 dbus_bool_t
05568 dbus_connection_try_register_object_path (DBusConnection              *connection,
05569                                           const char                  *path,
05570                                           const DBusObjectPathVTable  *vtable,
05571                                           void                        *user_data,
05572                                           DBusError                   *error)
05573 {
05574   char **decomposed_path;
05575   dbus_bool_t retval;
05576   
05577   _dbus_return_val_if_fail (connection != NULL, FALSE);
05578   _dbus_return_val_if_fail (path != NULL, FALSE);
05579   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05580   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05581 
05582   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05583     return FALSE;
05584 
05585   CONNECTION_LOCK (connection);
05586 
05587   retval = _dbus_object_tree_register (connection->objects,
05588                                        FALSE,
05589                                        (const char **) decomposed_path, vtable,
05590                                        user_data, error);
05591 
05592   CONNECTION_UNLOCK (connection);
05593 
05594   dbus_free_string_array (decomposed_path);
05595 
05596   return retval;
05597 }
05598 
05613 dbus_bool_t
05614 dbus_connection_register_object_path (DBusConnection              *connection,
05615                                       const char                  *path,
05616                                       const DBusObjectPathVTable  *vtable,
05617                                       void                        *user_data)
05618 {
05619   char **decomposed_path;
05620   dbus_bool_t retval;
05621   DBusError error = DBUS_ERROR_INIT;
05622 
05623   _dbus_return_val_if_fail (connection != NULL, FALSE);
05624   _dbus_return_val_if_fail (path != NULL, FALSE);
05625   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05626   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05627 
05628   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05629     return FALSE;
05630 
05631   CONNECTION_LOCK (connection);
05632 
05633   retval = _dbus_object_tree_register (connection->objects,
05634                                        FALSE,
05635                                        (const char **) decomposed_path, vtable,
05636                                        user_data, &error);
05637 
05638   CONNECTION_UNLOCK (connection);
05639 
05640   dbus_free_string_array (decomposed_path);
05641 
05642   if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE))
05643     {
05644       _dbus_warn ("%s\n", error.message);
05645       dbus_error_free (&error);
05646       return FALSE;
05647     }
05648 
05649   return retval;
05650 }
05651 
05666 dbus_bool_t
05667 dbus_connection_try_register_fallback (DBusConnection              *connection,
05668                                        const char                  *path,
05669                                        const DBusObjectPathVTable  *vtable,
05670                                        void                        *user_data,
05671                                        DBusError                   *error)
05672 {
05673   char **decomposed_path;
05674   dbus_bool_t retval;
05675 
05676   _dbus_return_val_if_fail (connection != NULL, FALSE);
05677   _dbus_return_val_if_fail (path != NULL, FALSE);
05678   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05679   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05680 
05681   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05682     return FALSE;
05683 
05684   CONNECTION_LOCK (connection);
05685 
05686   retval = _dbus_object_tree_register (connection->objects,
05687                                        TRUE,
05688                                        (const char **) decomposed_path, vtable,
05689                                        user_data, error);
05690 
05691   CONNECTION_UNLOCK (connection);
05692 
05693   dbus_free_string_array (decomposed_path);
05694 
05695   return retval;
05696 }
05697 
05714 dbus_bool_t
05715 dbus_connection_register_fallback (DBusConnection              *connection,
05716                                    const char                  *path,
05717                                    const DBusObjectPathVTable  *vtable,
05718                                    void                        *user_data)
05719 {
05720   char **decomposed_path;
05721   dbus_bool_t retval;
05722   DBusError error = DBUS_ERROR_INIT;
05723 
05724   _dbus_return_val_if_fail (connection != NULL, FALSE);
05725   _dbus_return_val_if_fail (path != NULL, FALSE);
05726   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05727   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05728 
05729   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05730     return FALSE;
05731 
05732   CONNECTION_LOCK (connection);
05733 
05734   retval = _dbus_object_tree_register (connection->objects,
05735                                        TRUE,
05736                                        (const char **) decomposed_path, vtable,
05737                                        user_data, &error);
05738 
05739   CONNECTION_UNLOCK (connection);
05740 
05741   dbus_free_string_array (decomposed_path);
05742 
05743   if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE))
05744     {
05745       _dbus_warn ("%s\n", error.message);
05746       dbus_error_free (&error);
05747       return FALSE;
05748     }
05749 
05750   return retval;
05751 }
05752 
05762 dbus_bool_t
05763 dbus_connection_unregister_object_path (DBusConnection              *connection,
05764                                         const char                  *path)
05765 {
05766   char **decomposed_path;
05767 
05768   _dbus_return_val_if_fail (connection != NULL, FALSE);
05769   _dbus_return_val_if_fail (path != NULL, FALSE);
05770   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05771 
05772   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05773       return FALSE;
05774 
05775   CONNECTION_LOCK (connection);
05776 
05777   _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
05778 
05779   dbus_free_string_array (decomposed_path);
05780 
05781   return TRUE;
05782 }
05783 
05794 dbus_bool_t
05795 dbus_connection_get_object_path_data (DBusConnection *connection,
05796                                       const char     *path,
05797                                       void          **data_p)
05798 {
05799   char **decomposed_path;
05800 
05801   _dbus_return_val_if_fail (connection != NULL, FALSE);
05802   _dbus_return_val_if_fail (path != NULL, FALSE);
05803   _dbus_return_val_if_fail (data_p != NULL, FALSE);
05804 
05805   *data_p = NULL;
05806   
05807   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05808     return FALSE;
05809   
05810   CONNECTION_LOCK (connection);
05811 
05812   *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path);
05813 
05814   CONNECTION_UNLOCK (connection);
05815 
05816   dbus_free_string_array (decomposed_path);
05817 
05818   return TRUE;
05819 }
05820 
05831 dbus_bool_t
05832 dbus_connection_list_registered (DBusConnection              *connection,
05833                                  const char                  *parent_path,
05834                                  char                      ***child_entries)
05835 {
05836   char **decomposed_path;
05837   dbus_bool_t retval;
05838   _dbus_return_val_if_fail (connection != NULL, FALSE);
05839   _dbus_return_val_if_fail (parent_path != NULL, FALSE);
05840   _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
05841   _dbus_return_val_if_fail (child_entries != NULL, FALSE);
05842 
05843   if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
05844     return FALSE;
05845 
05846   CONNECTION_LOCK (connection);
05847 
05848   retval = _dbus_object_tree_list_registered_and_unlock (connection->objects,
05849                                                          (const char **) decomposed_path,
05850                                                          child_entries);
05851   dbus_free_string_array (decomposed_path);
05852 
05853   return retval;
05854 }
05855 
05856 static DBusDataSlotAllocator slot_allocator;
05857 _DBUS_DEFINE_GLOBAL_LOCK (connection_slots);
05858 
05873 dbus_bool_t
05874 dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
05875 {
05876   return _dbus_data_slot_allocator_alloc (&slot_allocator,
05877                                           &_DBUS_LOCK_NAME (connection_slots),
05878                                           slot_p);
05879 }
05880 
05892 void
05893 dbus_connection_free_data_slot (dbus_int32_t *slot_p)
05894 {
05895   _dbus_return_if_fail (*slot_p >= 0);
05896   
05897   _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
05898 }
05899 
05922 dbus_bool_t
05923 dbus_connection_set_data (DBusConnection   *connection,
05924                           dbus_int32_t      slot,
05925                           void             *data,
05926                           DBusFreeFunction  free_data_func)
05927 {
05928   DBusFreeFunction old_free_func;
05929   void *old_data;
05930   dbus_bool_t retval;
05931 
05932   _dbus_return_val_if_fail (connection != NULL, FALSE);
05933   _dbus_return_val_if_fail (slot >= 0, FALSE);
05934   
05935   SLOTS_LOCK (connection);
05936 
05937   retval = _dbus_data_slot_list_set (&slot_allocator,
05938                                      &connection->slot_list,
05939                                      slot, data, free_data_func,
05940                                      &old_free_func, &old_data);
05941   
05942   SLOTS_UNLOCK (connection);
05943 
05944   if (retval)
05945     {
05946       /* Do the actual free outside the connection lock */
05947       if (old_free_func)
05948         (* old_free_func) (old_data);
05949     }
05950 
05951   return retval;
05952 }
05953 
05971 void*
05972 dbus_connection_get_data (DBusConnection   *connection,
05973                           dbus_int32_t      slot)
05974 {
05975   void *res;
05976 
05977   _dbus_return_val_if_fail (connection != NULL, NULL);
05978   
05979   SLOTS_LOCK (connection);
05980 
05981   res = _dbus_data_slot_list_get (&slot_allocator,
05982                                   &connection->slot_list,
05983                                   slot);
05984   
05985   SLOTS_UNLOCK (connection);
05986 
05987   return res;
05988 }
05989 
05996 void
05997 dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
05998 {  
05999   _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
06000 }
06001 
06010 void
06011 dbus_connection_set_max_message_size (DBusConnection *connection,
06012                                       long            size)
06013 {
06014   _dbus_return_if_fail (connection != NULL);
06015   
06016   CONNECTION_LOCK (connection);
06017   _dbus_transport_set_max_message_size (connection->transport,
06018                                         size);
06019   CONNECTION_UNLOCK (connection);
06020 }
06021 
06028 long
06029 dbus_connection_get_max_message_size (DBusConnection *connection)
06030 {
06031   long res;
06032 
06033   _dbus_return_val_if_fail (connection != NULL, 0);
06034   
06035   CONNECTION_LOCK (connection);
06036   res = _dbus_transport_get_max_message_size (connection->transport);
06037   CONNECTION_UNLOCK (connection);
06038   return res;
06039 }
06040 
06049 void
06050 dbus_connection_set_max_message_unix_fds (DBusConnection *connection,
06051                                           long            n)
06052 {
06053   _dbus_return_if_fail (connection != NULL);
06054 
06055   CONNECTION_LOCK (connection);
06056   _dbus_transport_set_max_message_unix_fds (connection->transport,
06057                                             n);
06058   CONNECTION_UNLOCK (connection);
06059 }
06060 
06067 long
06068 dbus_connection_get_max_message_unix_fds (DBusConnection *connection)
06069 {
06070   long res;
06071 
06072   _dbus_return_val_if_fail (connection != NULL, 0);
06073 
06074   CONNECTION_LOCK (connection);
06075   res = _dbus_transport_get_max_message_unix_fds (connection->transport);
06076   CONNECTION_UNLOCK (connection);
06077   return res;
06078 }
06079 
06105 void
06106 dbus_connection_set_max_received_size (DBusConnection *connection,
06107                                        long            size)
06108 {
06109   _dbus_return_if_fail (connection != NULL);
06110   
06111   CONNECTION_LOCK (connection);
06112   _dbus_transport_set_max_received_size (connection->transport,
06113                                          size);
06114   CONNECTION_UNLOCK (connection);
06115 }
06116 
06123 long
06124 dbus_connection_get_max_received_size (DBusConnection *connection)
06125 {
06126   long res;
06127 
06128   _dbus_return_val_if_fail (connection != NULL, 0);
06129   
06130   CONNECTION_LOCK (connection);
06131   res = _dbus_transport_get_max_received_size (connection->transport);
06132   CONNECTION_UNLOCK (connection);
06133   return res;
06134 }
06135 
06147 void
06148 dbus_connection_set_max_received_unix_fds (DBusConnection *connection,
06149                                            long            n)
06150 {
06151   _dbus_return_if_fail (connection != NULL);
06152 
06153   CONNECTION_LOCK (connection);
06154   _dbus_transport_set_max_received_unix_fds (connection->transport,
06155                                              n);
06156   CONNECTION_UNLOCK (connection);
06157 }
06158 
06165 long
06166 dbus_connection_get_max_received_unix_fds (DBusConnection *connection)
06167 {
06168   long res;
06169 
06170   _dbus_return_val_if_fail (connection != NULL, 0);
06171 
06172   CONNECTION_LOCK (connection);
06173   res = _dbus_transport_get_max_received_unix_fds (connection->transport);
06174   CONNECTION_UNLOCK (connection);
06175   return res;
06176 }
06177 
06188 long
06189 dbus_connection_get_outgoing_size (DBusConnection *connection)
06190 {
06191   long res;
06192 
06193   _dbus_return_val_if_fail (connection != NULL, 0);
06194 
06195   CONNECTION_LOCK (connection);
06196   res = _dbus_counter_get_size_value (connection->outgoing_counter);
06197   CONNECTION_UNLOCK (connection);
06198   return res;
06199 }
06200 
06208 long
06209 dbus_connection_get_outgoing_unix_fds (DBusConnection *connection)
06210 {
06211   long res;
06212 
06213   _dbus_return_val_if_fail (connection != NULL, 0);
06214 
06215   CONNECTION_LOCK (connection);
06216   res = _dbus_counter_get_unix_fd_value (connection->outgoing_counter);
06217   CONNECTION_UNLOCK (connection);
06218   return res;
06219 }
06220