D-Bus 1.4.0
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 #ifdef 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   const char *sig;
01984 
01985   preallocated->queue_link->data = message;
01986   _dbus_list_prepend_link (&connection->outgoing_messages,
01987                            preallocated->queue_link);
01988 
01989   _dbus_message_add_counter_link (message,
01990                                   preallocated->counter_link);
01991 
01992   dbus_free (preallocated);
01993   preallocated = NULL;
01994   
01995   dbus_message_ref (message);
01996   
01997   connection->n_outgoing += 1;
01998 
01999   sig = dbus_message_get_signature (message);
02000   
02001   _dbus_verbose ("Message %p (%s %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
02002                  message,
02003                  dbus_message_type_to_string (dbus_message_get_type (message)),
02004                  dbus_message_get_path (message) ?
02005                  dbus_message_get_path (message) :
02006                  "no path",
02007                  dbus_message_get_interface (message) ?
02008                  dbus_message_get_interface (message) :
02009                  "no interface",
02010                  dbus_message_get_member (message) ?
02011                  dbus_message_get_member (message) :
02012                  "no member",
02013                  sig,
02014                  dbus_message_get_destination (message) ?
02015                  dbus_message_get_destination (message) :
02016                  "null",
02017                  connection,
02018                  connection->n_outgoing);
02019 
02020   if (dbus_message_get_serial (message) == 0)
02021     {
02022       serial = _dbus_connection_get_next_client_serial (connection);
02023       dbus_message_set_serial (message, serial);
02024       if (client_serial)
02025         *client_serial = serial;
02026     }
02027   else
02028     {
02029       if (client_serial)
02030         *client_serial = dbus_message_get_serial (message);
02031     }
02032 
02033   _dbus_verbose ("Message %p serial is %u\n",
02034                  message, dbus_message_get_serial (message));
02035   
02036   dbus_message_lock (message);
02037 
02038   /* Now we need to run an iteration to hopefully just write the messages
02039    * out immediately, and otherwise get them queued up
02040    */
02041   _dbus_connection_do_iteration_unlocked (connection,
02042                                           NULL,
02043                                           DBUS_ITERATION_DO_WRITING,
02044                                           -1);
02045 
02046   /* If stuff is still queued up, be sure we wake up the main loop */
02047   if (connection->n_outgoing > 0)
02048     _dbus_connection_wakeup_mainloop (connection);
02049 }
02050 
02051 static void
02052 _dbus_connection_send_preallocated_and_unlock (DBusConnection       *connection,
02053                                                DBusPreallocatedSend *preallocated,
02054                                                DBusMessage          *message,
02055                                                dbus_uint32_t        *client_serial)
02056 {
02057   DBusDispatchStatus status;
02058 
02059   HAVE_LOCK_CHECK (connection);
02060   
02061   _dbus_connection_send_preallocated_unlocked_no_update (connection,
02062                                                          preallocated,
02063                                                          message, client_serial);
02064 
02065   _dbus_verbose ("middle\n");
02066   status = _dbus_connection_get_dispatch_status_unlocked (connection);
02067 
02068   /* this calls out to user code */
02069   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02070 }
02071 
02081 dbus_bool_t
02082 _dbus_connection_send_and_unlock (DBusConnection *connection,
02083                                   DBusMessage    *message,
02084                                   dbus_uint32_t  *client_serial)
02085 {
02086   DBusPreallocatedSend *preallocated;
02087 
02088   _dbus_assert (connection != NULL);
02089   _dbus_assert (message != NULL);
02090   
02091   preallocated = _dbus_connection_preallocate_send_unlocked (connection);
02092   if (preallocated == NULL)
02093     {
02094       CONNECTION_UNLOCK (connection);
02095       return FALSE;
02096     }
02097 
02098   _dbus_connection_send_preallocated_and_unlock (connection,
02099                                                  preallocated,
02100                                                  message,
02101                                                  client_serial);
02102   return TRUE;
02103 }
02104 
02129 void
02130 _dbus_connection_close_if_only_one_ref (DBusConnection *connection)
02131 {
02132   CONNECTION_LOCK (connection);
02133   
02134   _dbus_assert (connection->refcount.value > 0);
02135 
02136   if (connection->refcount.value == 1)
02137     _dbus_connection_close_possibly_shared_and_unlock (connection);
02138   else
02139     CONNECTION_UNLOCK (connection);
02140 }
02141 
02142 
02152 static void
02153 _dbus_memory_pause_based_on_timeout (int timeout_milliseconds)
02154 {
02155   if (timeout_milliseconds == -1)
02156     _dbus_sleep_milliseconds (1000);
02157   else if (timeout_milliseconds < 100)
02158     ; /* just busy loop */
02159   else if (timeout_milliseconds <= 1000)
02160     _dbus_sleep_milliseconds (timeout_milliseconds / 3);
02161   else
02162     _dbus_sleep_milliseconds (1000);
02163 }
02164 
02165 static DBusMessage *
02166 generate_local_error_message (dbus_uint32_t serial, 
02167                               char *error_name, 
02168                               char *error_msg)
02169 {
02170   DBusMessage *message;
02171   message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
02172   if (!message)
02173     goto out;
02174 
02175   if (!dbus_message_set_error_name (message, error_name))
02176     {
02177       dbus_message_unref (message);
02178       message = NULL;
02179       goto out; 
02180     }
02181 
02182   dbus_message_set_no_reply (message, TRUE); 
02183 
02184   if (!dbus_message_set_reply_serial (message,
02185                                       serial))
02186     {
02187       dbus_message_unref (message);
02188       message = NULL;
02189       goto out;
02190     }
02191 
02192   if (error_msg != NULL)
02193     {
02194       DBusMessageIter iter;
02195 
02196       dbus_message_iter_init_append (message, &iter);
02197       if (!dbus_message_iter_append_basic (&iter,
02198                                            DBUS_TYPE_STRING,
02199                                            &error_msg))
02200         {
02201           dbus_message_unref (message);
02202           message = NULL;
02203           goto out;
02204         }
02205     }
02206 
02207  out:
02208   return message;
02209 }
02210 
02211 /*
02212  * Peek the incoming queue to see if we got reply for a specific serial
02213  */
02214 static dbus_bool_t
02215 _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection,
02216                                           dbus_uint32_t   client_serial)
02217 {
02218   DBusList *link;
02219   HAVE_LOCK_CHECK (connection);
02220 
02221   link = _dbus_list_get_first_link (&connection->incoming_messages);
02222 
02223   while (link != NULL)
02224     {
02225       DBusMessage *reply = link->data;
02226 
02227       if (dbus_message_get_reply_serial (reply) == client_serial)
02228         {
02229           _dbus_verbose ("%s reply to %d found in queue\n", _DBUS_FUNCTION_NAME, client_serial);
02230           return TRUE;
02231         }
02232       link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02233     }
02234 
02235   return FALSE;
02236 }
02237 
02238 /* This is slightly strange since we can pop a message here without
02239  * the dispatch lock.
02240  */
02241 static DBusMessage*
02242 check_for_reply_unlocked (DBusConnection *connection,
02243                           dbus_uint32_t   client_serial)
02244 {
02245   DBusList *link;
02246 
02247   HAVE_LOCK_CHECK (connection);
02248   
02249   link = _dbus_list_get_first_link (&connection->incoming_messages);
02250 
02251   while (link != NULL)
02252     {
02253       DBusMessage *reply = link->data;
02254 
02255       if (dbus_message_get_reply_serial (reply) == client_serial)
02256         {
02257           _dbus_list_remove_link (&connection->incoming_messages, link);
02258           connection->n_incoming  -= 1;
02259           return reply;
02260         }
02261       link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02262     }
02263 
02264   return NULL;
02265 }
02266 
02267 static void
02268 connection_timeout_and_complete_all_pending_calls_unlocked (DBusConnection *connection)
02269 {
02270    /* We can't iterate over the hash in the normal way since we'll be
02271     * dropping the lock for each item. So we restart the
02272     * iter each time as we drain the hash table.
02273     */
02274    
02275    while (_dbus_hash_table_get_n_entries (connection->pending_replies) > 0)
02276     {
02277       DBusPendingCall *pending;
02278       DBusHashIter iter;
02279       
02280       _dbus_hash_iter_init (connection->pending_replies, &iter);
02281       _dbus_hash_iter_next (&iter);
02282        
02283       pending = _dbus_hash_iter_get_value (&iter);
02284       _dbus_pending_call_ref_unlocked (pending);
02285        
02286       _dbus_pending_call_queue_timeout_error_unlocked (pending, 
02287                                                        connection);
02288 
02289       if (_dbus_pending_call_is_timeout_added_unlocked (pending))
02290           _dbus_connection_remove_timeout_unlocked (connection,
02291                                                     _dbus_pending_call_get_timeout_unlocked (pending));
02292       _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);       
02293       _dbus_hash_iter_remove_entry (&iter);
02294 
02295       _dbus_pending_call_unref_and_unlock (pending);
02296       CONNECTION_LOCK (connection);
02297     }
02298   HAVE_LOCK_CHECK (connection);
02299 }
02300 
02301 static void
02302 complete_pending_call_and_unlock (DBusConnection  *connection,
02303                                   DBusPendingCall *pending,
02304                                   DBusMessage     *message)
02305 {
02306   _dbus_pending_call_set_reply_unlocked (pending, message);
02307   _dbus_pending_call_ref_unlocked (pending); /* in case there's no app with a ref held */
02308   _dbus_connection_detach_pending_call_and_unlock (connection, pending);
02309  
02310   /* Must be called unlocked since it invokes app callback */
02311   _dbus_pending_call_complete (pending);
02312   dbus_pending_call_unref (pending);
02313 }
02314 
02315 static dbus_bool_t
02316 check_for_reply_and_update_dispatch_unlocked (DBusConnection  *connection,
02317                                               DBusPendingCall *pending)
02318 {
02319   DBusMessage *reply;
02320   DBusDispatchStatus status;
02321 
02322   reply = check_for_reply_unlocked (connection, 
02323                                     _dbus_pending_call_get_reply_serial_unlocked (pending));
02324   if (reply != NULL)
02325     {
02326       _dbus_verbose ("checked for reply\n");
02327 
02328       _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
02329 
02330       complete_pending_call_and_unlock (connection, pending, reply);
02331       dbus_message_unref (reply);
02332 
02333       CONNECTION_LOCK (connection);
02334       status = _dbus_connection_get_dispatch_status_unlocked (connection);
02335       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02336       dbus_pending_call_unref (pending);
02337 
02338       return TRUE;
02339     }
02340 
02341   return FALSE;
02342 }
02343 
02358 void
02359 _dbus_connection_block_pending_call (DBusPendingCall *pending)
02360 {
02361   long start_tv_sec, start_tv_usec;
02362   long tv_sec, tv_usec;
02363   DBusDispatchStatus status;
02364   DBusConnection *connection;
02365   dbus_uint32_t client_serial;
02366   DBusTimeout *timeout;
02367   int timeout_milliseconds, elapsed_milliseconds;
02368 
02369   _dbus_assert (pending != NULL);
02370 
02371   if (dbus_pending_call_get_completed (pending))
02372     return;
02373 
02374   dbus_pending_call_ref (pending); /* necessary because the call could be canceled */
02375 
02376   connection = _dbus_pending_call_get_connection_and_lock (pending);
02377   
02378   /* Flush message queue - note, can affect dispatch status */
02379   _dbus_connection_flush_unlocked (connection);
02380 
02381   client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
02382 
02383   /* note that timeout_milliseconds is limited to a smallish value
02384    * in _dbus_pending_call_new() so overflows aren't possible
02385    * below
02386    */
02387   timeout = _dbus_pending_call_get_timeout_unlocked (pending);
02388   if (timeout)
02389     {
02390       timeout_milliseconds = dbus_timeout_get_interval (timeout);
02391       _dbus_get_current_time (&start_tv_sec, &start_tv_usec);
02392 
02393       _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec\n",
02394                      timeout_milliseconds,
02395                      client_serial,
02396                      start_tv_sec, start_tv_usec);
02397     }
02398   else
02399     {
02400       timeout_milliseconds = -1;
02401 
02402       _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block for reply serial %u\n", client_serial);
02403     }
02404 
02405   /* check to see if we already got the data off the socket */
02406   /* from another blocked pending call */
02407   if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02408     return;
02409 
02410   /* Now we wait... */
02411   /* always block at least once as we know we don't have the reply yet */
02412   _dbus_connection_do_iteration_unlocked (connection,
02413                                           pending,
02414                                           DBUS_ITERATION_DO_READING |
02415                                           DBUS_ITERATION_BLOCK,
02416                                           timeout_milliseconds);
02417 
02418  recheck_status:
02419 
02420   _dbus_verbose ("top of recheck\n");
02421   
02422   HAVE_LOCK_CHECK (connection);
02423   
02424   /* queue messages and get status */
02425 
02426   status = _dbus_connection_get_dispatch_status_unlocked (connection);
02427 
02428   /* the get_completed() is in case a dispatch() while we were blocking
02429    * got the reply instead of us.
02430    */
02431   if (_dbus_pending_call_get_completed_unlocked (pending))
02432     {
02433       _dbus_verbose ("Pending call completed by dispatch\n");
02434       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02435       dbus_pending_call_unref (pending);
02436       return;
02437     }
02438   
02439   if (status == DBUS_DISPATCH_DATA_REMAINS)
02440     {
02441       if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02442         return;
02443     }
02444   
02445   _dbus_get_current_time (&tv_sec, &tv_usec);
02446   elapsed_milliseconds = (tv_sec - start_tv_sec) * 1000 +
02447           (tv_usec - start_tv_usec) / 1000;
02448   
02449   if (!_dbus_connection_get_is_connected_unlocked (connection))
02450     {
02451       DBusMessage *error_msg;
02452 
02453       error_msg = generate_local_error_message (client_serial,
02454                                                 DBUS_ERROR_DISCONNECTED, 
02455                                                 "Connection was disconnected before a reply was received"); 
02456 
02457       /* on OOM error_msg is set to NULL */
02458       complete_pending_call_and_unlock (connection, pending, error_msg);
02459       dbus_pending_call_unref (pending);
02460       return;
02461     }
02462   else if (connection->disconnect_message_link == NULL)
02463     _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
02464   else if (timeout == NULL)
02465     {
02466        if (status == DBUS_DISPATCH_NEED_MEMORY)
02467         {
02468           /* Try sleeping a bit, as we aren't sure we need to block for reading,
02469            * we may already have a reply in the buffer and just can't process
02470            * it.
02471            */
02472           _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02473 
02474           _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
02475         }
02476       else
02477         {          
02478           /* block again, we don't have the reply buffered yet. */
02479           _dbus_connection_do_iteration_unlocked (connection,
02480                                                   pending,
02481                                                   DBUS_ITERATION_DO_READING |
02482                                                   DBUS_ITERATION_BLOCK,
02483                                                   timeout_milliseconds - elapsed_milliseconds);
02484         }
02485 
02486       goto recheck_status;
02487     }
02488   else if (tv_sec < start_tv_sec)
02489     _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
02490   else if (elapsed_milliseconds < timeout_milliseconds)
02491     {
02492       _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds - elapsed_milliseconds);
02493       
02494       if (status == DBUS_DISPATCH_NEED_MEMORY)
02495         {
02496           /* Try sleeping a bit, as we aren't sure we need to block for reading,
02497            * we may already have a reply in the buffer and just can't process
02498            * it.
02499            */
02500           _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02501 
02502           _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
02503         }
02504       else
02505         {          
02506           /* block again, we don't have the reply buffered yet. */
02507           _dbus_connection_do_iteration_unlocked (connection,
02508                                                   NULL,
02509                                                   DBUS_ITERATION_DO_READING |
02510                                                   DBUS_ITERATION_BLOCK,
02511                                                   timeout_milliseconds - elapsed_milliseconds);
02512         }
02513 
02514       goto recheck_status;
02515     }
02516 
02517   _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %d milliseconds and got no reply\n",
02518                  elapsed_milliseconds);
02519 
02520   _dbus_assert (!_dbus_pending_call_get_completed_unlocked (pending));
02521   
02522   /* unlock and call user code */
02523   complete_pending_call_and_unlock (connection, pending, NULL);
02524 
02525   /* update user code on dispatch status */
02526   CONNECTION_LOCK (connection);
02527   status = _dbus_connection_get_dispatch_status_unlocked (connection);
02528   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02529   dbus_pending_call_unref (pending);
02530 }
02531 
02568 DBusConnection*
02569 dbus_connection_open (const char     *address,
02570                       DBusError      *error)
02571 {
02572   DBusConnection *connection;
02573 
02574   _dbus_return_val_if_fail (address != NULL, NULL);
02575   _dbus_return_val_if_error_is_set (error, NULL);
02576 
02577   connection = _dbus_connection_open_internal (address,
02578                                                TRUE,
02579                                                error);
02580 
02581   return connection;
02582 }
02583 
02611 DBusConnection*
02612 dbus_connection_open_private (const char     *address,
02613                               DBusError      *error)
02614 {
02615   DBusConnection *connection;
02616 
02617   _dbus_return_val_if_fail (address != NULL, NULL);
02618   _dbus_return_val_if_error_is_set (error, NULL);
02619 
02620   connection = _dbus_connection_open_internal (address,
02621                                                FALSE,
02622                                                error);
02623 
02624   return connection;
02625 }
02626 
02633 DBusConnection *
02634 dbus_connection_ref (DBusConnection *connection)
02635 {
02636   _dbus_return_val_if_fail (connection != NULL, NULL);
02637   _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
02638   
02639   /* The connection lock is better than the global
02640    * lock in the atomic increment fallback
02641    *
02642    * (FIXME but for now we always use the atomic version,
02643    * to avoid taking the connection lock, due to
02644    * the mess with set_timeout_functions()/set_watch_functions()
02645    * calling out to the app without dropping locks)
02646    */
02647   
02648 #if 1
02649   _dbus_atomic_inc (&connection->refcount);
02650 #else
02651   CONNECTION_LOCK (connection);
02652   _dbus_assert (connection->refcount.value > 0);
02653 
02654   connection->refcount.value += 1;
02655   CONNECTION_UNLOCK (connection);
02656 #endif
02657 
02658   return connection;
02659 }
02660 
02661 static void
02662 free_outgoing_message (void *element,
02663                        void *data)
02664 {
02665   DBusMessage *message = element;
02666   DBusConnection *connection = data;
02667 
02668   _dbus_message_remove_counter (message,
02669                                 connection->outgoing_counter,
02670                                 NULL);
02671   dbus_message_unref (message);
02672 }
02673 
02674 /* This is run without the mutex held, but after the last reference
02675  * to the connection has been dropped we should have no thread-related
02676  * problems
02677  */
02678 static void
02679 _dbus_connection_last_unref (DBusConnection *connection)
02680 {
02681   DBusList *link;
02682 
02683   _dbus_verbose ("Finalizing connection %p\n", connection);
02684   
02685   _dbus_assert (connection->refcount.value == 0);
02686   
02687   /* You have to disconnect the connection before unref:ing it. Otherwise
02688    * you won't get the disconnected message.
02689    */
02690   _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
02691   _dbus_assert (connection->server_guid == NULL);
02692   
02693   /* ---- We're going to call various application callbacks here, hope it doesn't break anything... */
02694   _dbus_object_tree_free_all_unlocked (connection->objects);
02695   
02696   dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
02697   dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
02698   dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
02699   
02700   _dbus_watch_list_free (connection->watches);
02701   connection->watches = NULL;
02702   
02703   _dbus_timeout_list_free (connection->timeouts);
02704   connection->timeouts = NULL;
02705 
02706   _dbus_data_slot_list_free (&connection->slot_list);
02707   
02708   link = _dbus_list_get_first_link (&connection->filter_list);
02709   while (link != NULL)
02710     {
02711       DBusMessageFilter *filter = link->data;
02712       DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
02713 
02714       filter->function = NULL;
02715       _dbus_message_filter_unref (filter); /* calls app callback */
02716       link->data = NULL;
02717       
02718       link = next;
02719     }
02720   _dbus_list_clear (&connection->filter_list);
02721   
02722   /* ---- Done with stuff that invokes application callbacks */
02723 
02724   _dbus_object_tree_unref (connection->objects);  
02725 
02726   _dbus_hash_table_unref (connection->pending_replies);
02727   connection->pending_replies = NULL;
02728   
02729   _dbus_list_clear (&connection->filter_list);
02730   
02731   _dbus_list_foreach (&connection->outgoing_messages,
02732                       free_outgoing_message,
02733                       connection);
02734   _dbus_list_clear (&connection->outgoing_messages);
02735   
02736   _dbus_list_foreach (&connection->incoming_messages,
02737                       (DBusForeachFunction) dbus_message_unref,
02738                       NULL);
02739   _dbus_list_clear (&connection->incoming_messages);
02740 
02741   _dbus_counter_unref (connection->outgoing_counter);
02742 
02743   _dbus_transport_unref (connection->transport);
02744 
02745   if (connection->disconnect_message_link)
02746     {
02747       DBusMessage *message = connection->disconnect_message_link->data;
02748       dbus_message_unref (message);
02749       _dbus_list_free_link (connection->disconnect_message_link);
02750     }
02751 
02752   _dbus_list_clear (&connection->link_cache);
02753   
02754   _dbus_condvar_free_at_location (&connection->dispatch_cond);
02755   _dbus_condvar_free_at_location (&connection->io_path_cond);
02756 
02757   _dbus_mutex_free_at_location (&connection->io_path_mutex);
02758   _dbus_mutex_free_at_location (&connection->dispatch_mutex);
02759 
02760   _dbus_mutex_free_at_location (&connection->slot_mutex);
02761 
02762   _dbus_mutex_free_at_location (&connection->mutex);
02763   
02764   dbus_free (connection);
02765 }
02766 
02786 void
02787 dbus_connection_unref (DBusConnection *connection)
02788 {
02789   dbus_bool_t last_unref;
02790 
02791   _dbus_return_if_fail (connection != NULL);
02792   _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02793   
02794   /* The connection lock is better than the global
02795    * lock in the atomic increment fallback
02796    *
02797    * (FIXME but for now we always use the atomic version,
02798    * to avoid taking the connection lock, due to
02799    * the mess with set_timeout_functions()/set_watch_functions()
02800    * calling out to the app without dropping locks)
02801    */
02802   
02803 #if 1
02804   last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
02805 #else
02806   CONNECTION_LOCK (connection);
02807   
02808   _dbus_assert (connection->refcount.value > 0);
02809 
02810   connection->refcount.value -= 1;
02811   last_unref = (connection->refcount.value == 0);
02812 
02813 #if 0
02814   printf ("unref() connection %p count = %d\n", connection, connection->refcount.value);
02815 #endif
02816   
02817   CONNECTION_UNLOCK (connection);
02818 #endif
02819   
02820   if (last_unref)
02821     {
02822 #ifndef DBUS_DISABLE_CHECKS
02823       if (_dbus_transport_get_is_connected (connection->transport))
02824         {
02825           _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",
02826                                    connection->shareable ?
02827                                    "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" : 
02828                                     "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n");
02829           return;
02830         }
02831 #endif
02832       _dbus_connection_last_unref (connection);
02833     }
02834 }
02835 
02836 /*
02837  * Note that the transport can disconnect itself (other end drops us)
02838  * and in that case this function never runs. So this function must
02839  * not do anything more than disconnect the transport and update the
02840  * dispatch status.
02841  * 
02842  * If the transport self-disconnects, then we assume someone will
02843  * dispatch the connection to cause the dispatch status update.
02844  */
02845 static void
02846 _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection)
02847 {
02848   DBusDispatchStatus status;
02849 
02850   HAVE_LOCK_CHECK (connection);
02851   
02852   _dbus_verbose ("Disconnecting %p\n", connection);
02853 
02854   /* We need to ref because update_dispatch_status_and_unlock will unref
02855    * the connection if it was shared and libdbus was the only remaining
02856    * refcount holder.
02857    */
02858   _dbus_connection_ref_unlocked (connection);
02859   
02860   _dbus_transport_disconnect (connection->transport);
02861 
02862   /* This has the side effect of queuing the disconnect message link
02863    * (unless we don't have enough memory, possibly, so don't assert it).
02864    * After the disconnect message link is queued, dbus_bus_get/dbus_connection_open
02865    * should never again return the newly-disconnected connection.
02866    *
02867    * However, we only unref the shared connection and exit_on_disconnect when
02868    * the disconnect message reaches the head of the message queue,
02869    * NOT when it's first queued.
02870    */
02871   status = _dbus_connection_get_dispatch_status_unlocked (connection);
02872 
02873   /* This calls out to user code */
02874   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02875 
02876   /* Could also call out to user code */
02877   dbus_connection_unref (connection);
02878 }
02879 
02922 void
02923 dbus_connection_close (DBusConnection *connection)
02924 {
02925   _dbus_return_if_fail (connection != NULL);
02926   _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02927 
02928   CONNECTION_LOCK (connection);
02929 
02930 #ifndef DBUS_DISABLE_CHECKS
02931   if (connection->shareable)
02932     {
02933       CONNECTION_UNLOCK (connection);
02934 
02935       _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n");
02936       return;
02937     }
02938 #endif
02939   
02940   _dbus_connection_close_possibly_shared_and_unlock (connection);
02941 }
02942 
02943 static dbus_bool_t
02944 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
02945 {
02946   HAVE_LOCK_CHECK (connection);
02947   return _dbus_transport_get_is_connected (connection->transport);
02948 }
02949 
02963 dbus_bool_t
02964 dbus_connection_get_is_connected (DBusConnection *connection)
02965 {
02966   dbus_bool_t res;
02967 
02968   _dbus_return_val_if_fail (connection != NULL, FALSE);
02969   
02970   CONNECTION_LOCK (connection);
02971   res = _dbus_connection_get_is_connected_unlocked (connection);
02972   CONNECTION_UNLOCK (connection);
02973   
02974   return res;
02975 }
02976 
02985 dbus_bool_t
02986 dbus_connection_get_is_authenticated (DBusConnection *connection)
02987 {
02988   dbus_bool_t res;
02989 
02990   _dbus_return_val_if_fail (connection != NULL, FALSE);
02991   
02992   CONNECTION_LOCK (connection);
02993   res = _dbus_transport_get_is_authenticated (connection->transport);
02994   CONNECTION_UNLOCK (connection);
02995   
02996   return res;
02997 }
02998 
03019 dbus_bool_t
03020 dbus_connection_get_is_anonymous (DBusConnection *connection)
03021 {
03022   dbus_bool_t res;
03023 
03024   _dbus_return_val_if_fail (connection != NULL, FALSE);
03025   
03026   CONNECTION_LOCK (connection);
03027   res = _dbus_transport_get_is_anonymous (connection->transport);
03028   CONNECTION_UNLOCK (connection);
03029   
03030   return res;
03031 }
03032 
03064 char*
03065 dbus_connection_get_server_id (DBusConnection *connection)
03066 {
03067   char *id;
03068 
03069   _dbus_return_val_if_fail (connection != NULL, NULL);
03070 
03071   CONNECTION_LOCK (connection);
03072   id = _dbus_strdup (_dbus_transport_get_server_id (connection->transport));
03073   CONNECTION_UNLOCK (connection);
03074 
03075   return id;
03076 }
03077 
03095 dbus_bool_t
03096 dbus_connection_can_send_type(DBusConnection *connection,
03097                                   int type)
03098 {
03099   _dbus_return_val_if_fail (connection != NULL, FALSE);
03100 
03101   if (!_dbus_type_is_valid(type))
03102     return FALSE;
03103 
03104   if (type != DBUS_TYPE_UNIX_FD)
03105     return TRUE;
03106 
03107 #ifdef HAVE_UNIX_FD_PASSING
03108   {
03109     dbus_bool_t b;
03110 
03111     CONNECTION_LOCK(connection);
03112     b = _dbus_transport_can_pass_unix_fd(connection->transport);
03113     CONNECTION_UNLOCK(connection);
03114 
03115     return b;
03116   }
03117 #endif
03118 
03119   return FALSE;
03120 }
03121 
03135 void
03136 dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
03137                                         dbus_bool_t     exit_on_disconnect)
03138 {
03139   _dbus_return_if_fail (connection != NULL);
03140 
03141   CONNECTION_LOCK (connection);
03142   connection->exit_on_disconnect = exit_on_disconnect != FALSE;
03143   CONNECTION_UNLOCK (connection);
03144 }
03145 
03155 DBusPreallocatedSend*
03156 dbus_connection_preallocate_send (DBusConnection *connection)
03157 {
03158   DBusPreallocatedSend *preallocated;
03159 
03160   _dbus_return_val_if_fail (connection != NULL, NULL);
03161 
03162   CONNECTION_LOCK (connection);
03163   
03164   preallocated =
03165     _dbus_connection_preallocate_send_unlocked (connection);
03166 
03167   CONNECTION_UNLOCK (connection);
03168 
03169   return preallocated;
03170 }
03171 
03181 void
03182 dbus_connection_free_preallocated_send (DBusConnection       *connection,
03183                                         DBusPreallocatedSend *preallocated)
03184 {
03185   _dbus_return_if_fail (connection != NULL);
03186   _dbus_return_if_fail (preallocated != NULL);  
03187   _dbus_return_if_fail (connection == preallocated->connection);
03188 
03189   _dbus_list_free_link (preallocated->queue_link);
03190   _dbus_counter_unref (preallocated->counter_link->data);
03191   _dbus_list_free_link (preallocated->counter_link);
03192   dbus_free (preallocated);
03193 }
03194 
03207 void
03208 dbus_connection_send_preallocated (DBusConnection       *connection,
03209                                    DBusPreallocatedSend *preallocated,
03210                                    DBusMessage          *message,
03211                                    dbus_uint32_t        *client_serial)
03212 {
03213   _dbus_return_if_fail (connection != NULL);
03214   _dbus_return_if_fail (preallocated != NULL);
03215   _dbus_return_if_fail (message != NULL);
03216   _dbus_return_if_fail (preallocated->connection == connection);
03217   _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
03218                         dbus_message_get_member (message) != NULL);
03219   _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
03220                         (dbus_message_get_interface (message) != NULL &&
03221                          dbus_message_get_member (message) != NULL));
03222 
03223   CONNECTION_LOCK (connection);
03224 
03225 #ifdef HAVE_UNIX_FD_PASSING
03226 
03227   if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03228       message->n_unix_fds > 0)
03229     {
03230       /* Refuse to send fds on a connection that cannot handle
03231          them. Unfortunately we cannot return a proper error here, so
03232          the best we can is just return. */
03233       CONNECTION_UNLOCK (connection);
03234       return;
03235     }
03236 
03237 #endif
03238 
03239   _dbus_connection_send_preallocated_and_unlock (connection,
03240                                                  preallocated,
03241                                                  message, client_serial);
03242 }
03243 
03244 static dbus_bool_t
03245 _dbus_connection_send_unlocked_no_update (DBusConnection *connection,
03246                                           DBusMessage    *message,
03247                                           dbus_uint32_t  *client_serial)
03248 {
03249   DBusPreallocatedSend *preallocated;
03250 
03251   _dbus_assert (connection != NULL);
03252   _dbus_assert (message != NULL);
03253   
03254   preallocated = _dbus_connection_preallocate_send_unlocked (connection);
03255   if (preallocated == NULL)
03256     return FALSE;
03257 
03258   _dbus_connection_send_preallocated_unlocked_no_update (connection,
03259                                                          preallocated,
03260                                                          message,
03261                                                          client_serial);
03262   return TRUE;
03263 }
03264 
03292 dbus_bool_t
03293 dbus_connection_send (DBusConnection *connection,
03294                       DBusMessage    *message,
03295                       dbus_uint32_t  *serial)
03296 {
03297   _dbus_return_val_if_fail (connection != NULL, FALSE);
03298   _dbus_return_val_if_fail (message != NULL, FALSE);
03299 
03300   CONNECTION_LOCK (connection);
03301 
03302 #ifdef HAVE_UNIX_FD_PASSING
03303 
03304   if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03305       message->n_unix_fds > 0)
03306     {
03307       /* Refuse to send fds on a connection that cannot handle
03308          them. Unfortunately we cannot return a proper error here, so
03309          the best we can is just return. */
03310       CONNECTION_UNLOCK (connection);
03311       return FALSE;
03312     }
03313 
03314 #endif
03315 
03316   return _dbus_connection_send_and_unlock (connection,
03317                                            message,
03318                                            serial);
03319 }
03320 
03321 static dbus_bool_t
03322 reply_handler_timeout (void *data)
03323 {
03324   DBusConnection *connection;
03325   DBusDispatchStatus status;
03326   DBusPendingCall *pending = data;
03327 
03328   connection = _dbus_pending_call_get_connection_and_lock (pending);
03329 
03330   _dbus_pending_call_queue_timeout_error_unlocked (pending, 
03331                                                    connection);
03332   _dbus_connection_remove_timeout_unlocked (connection,
03333                                             _dbus_pending_call_get_timeout_unlocked (pending));
03334   _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
03335 
03336   _dbus_verbose ("middle\n");
03337   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03338 
03339   /* Unlocks, and calls out to user code */
03340   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03341   
03342   return TRUE;
03343 }
03344 
03384 dbus_bool_t
03385 dbus_connection_send_with_reply (DBusConnection     *connection,
03386                                  DBusMessage        *message,
03387                                  DBusPendingCall   **pending_return,
03388                                  int                 timeout_milliseconds)
03389 {
03390   DBusPendingCall *pending;
03391   dbus_int32_t serial = -1;
03392   DBusDispatchStatus status;
03393 
03394   _dbus_return_val_if_fail (connection != NULL, FALSE);
03395   _dbus_return_val_if_fail (message != NULL, FALSE);
03396   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03397 
03398   if (pending_return)
03399     *pending_return = NULL;
03400 
03401   CONNECTION_LOCK (connection);
03402 
03403 #ifdef HAVE_UNIX_FD_PASSING
03404 
03405   if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03406       message->n_unix_fds > 0)
03407     {
03408       /* Refuse to send fds on a connection that cannot handle
03409          them. Unfortunately we cannot return a proper error here, so
03410          the best we can do is return TRUE but leave *pending_return
03411          as NULL. */
03412       CONNECTION_UNLOCK (connection);
03413       return TRUE;
03414     }
03415 
03416 #endif
03417 
03418    if (!_dbus_connection_get_is_connected_unlocked (connection))
03419     {
03420       CONNECTION_UNLOCK (connection);
03421 
03422       return TRUE;
03423     }
03424 
03425   pending = _dbus_pending_call_new_unlocked (connection,
03426                                              timeout_milliseconds,
03427                                              reply_handler_timeout);
03428 
03429   if (pending == NULL)
03430     {
03431       CONNECTION_UNLOCK (connection);
03432       return FALSE;
03433     }
03434 
03435   /* Assign a serial to the message */
03436   serial = dbus_message_get_serial (message);
03437   if (serial == 0)
03438     {
03439       serial = _dbus_connection_get_next_client_serial (connection);
03440       dbus_message_set_serial (message, serial);
03441     }
03442 
03443   if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
03444     goto error;
03445     
03446   /* Insert the serial in the pending replies hash;
03447    * hash takes a refcount on DBusPendingCall.
03448    * Also, add the timeout.
03449    */
03450   if (!_dbus_connection_attach_pending_call_unlocked (connection,
03451                                                       pending))
03452     goto error;
03453  
03454   if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
03455     {
03456       _dbus_connection_detach_pending_call_and_unlock (connection,
03457                                                        pending);
03458       goto error_unlocked;
03459     }
03460 
03461   if (pending_return)
03462     *pending_return = pending; /* hand off refcount */
03463   else
03464     {
03465       _dbus_connection_detach_pending_call_unlocked (connection, pending);
03466       /* we still have a ref to the pending call in this case, we unref
03467        * after unlocking, below
03468        */
03469     }
03470 
03471   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03472 
03473   /* this calls out to user code */
03474   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03475 
03476   if (pending_return == NULL)
03477     dbus_pending_call_unref (pending);
03478   
03479   return TRUE;
03480 
03481  error:
03482   CONNECTION_UNLOCK (connection);
03483  error_unlocked:
03484   dbus_pending_call_unref (pending);
03485   return FALSE;
03486 }
03487 
03518 DBusMessage*
03519 dbus_connection_send_with_reply_and_block (DBusConnection     *connection,
03520                                            DBusMessage        *message,
03521                                            int                 timeout_milliseconds,
03522                                            DBusError          *error)
03523 {
03524   DBusMessage *reply;
03525   DBusPendingCall *pending;
03526 
03527   _dbus_return_val_if_fail (connection != NULL, NULL);
03528   _dbus_return_val_if_fail (message != NULL, NULL);
03529   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL);
03530   _dbus_return_val_if_error_is_set (error, NULL);
03531 
03532 #ifdef HAVE_UNIX_FD_PASSING
03533 
03534   CONNECTION_LOCK (connection);
03535   if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03536       message->n_unix_fds > 0)
03537     {
03538       CONNECTION_UNLOCK (connection);
03539       dbus_set_error(error, DBUS_ERROR_FAILED, "Cannot send file descriptors on this connection.");
03540       return NULL;
03541     }
03542   CONNECTION_UNLOCK (connection);
03543 
03544 #endif
03545 
03546   if (!dbus_connection_send_with_reply (connection, message,
03547                                         &pending, timeout_milliseconds))
03548     {
03549       _DBUS_SET_OOM (error);
03550       return NULL;
03551     }
03552 
03553   if (pending == NULL)
03554     {
03555       dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Connection is closed");
03556       return NULL;
03557     }
03558   
03559   dbus_pending_call_block (pending);
03560 
03561   reply = dbus_pending_call_steal_reply (pending);
03562   dbus_pending_call_unref (pending);
03563 
03564   /* call_complete_and_unlock() called from pending_call_block() should
03565    * always fill this in.
03566    */
03567   _dbus_assert (reply != NULL);
03568   
03569    if (dbus_set_error_from_message (error, reply))
03570     {
03571       dbus_message_unref (reply);
03572       return NULL;
03573     }
03574   else
03575     return reply;
03576 }
03577 
03586 static DBusDispatchStatus
03587 _dbus_connection_flush_unlocked (DBusConnection *connection)
03588 {
03589   /* We have to specify DBUS_ITERATION_DO_READING here because
03590    * otherwise we could have two apps deadlock if they are both doing
03591    * a flush(), and the kernel buffers fill up. This could change the
03592    * dispatch status.
03593    */
03594   DBusDispatchStatus status;
03595 
03596   HAVE_LOCK_CHECK (connection);
03597   
03598   while (connection->n_outgoing > 0 &&
03599          _dbus_connection_get_is_connected_unlocked (connection))
03600     {
03601       _dbus_verbose ("doing iteration in\n");
03602       HAVE_LOCK_CHECK (connection);
03603       _dbus_connection_do_iteration_unlocked (connection,
03604                                               NULL,
03605                                               DBUS_ITERATION_DO_READING |
03606                                               DBUS_ITERATION_DO_WRITING |
03607                                               DBUS_ITERATION_BLOCK,
03608                                               -1);
03609     }
03610 
03611   HAVE_LOCK_CHECK (connection);
03612   _dbus_verbose ("middle\n");
03613   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03614 
03615   HAVE_LOCK_CHECK (connection);
03616   return status;
03617 }
03618 
03624 void
03625 dbus_connection_flush (DBusConnection *connection)
03626 {
03627   /* We have to specify DBUS_ITERATION_DO_READING here because
03628    * otherwise we could have two apps deadlock if they are both doing
03629    * a flush(), and the kernel buffers fill up. This could change the
03630    * dispatch status.
03631    */
03632   DBusDispatchStatus status;
03633 
03634   _dbus_return_if_fail (connection != NULL);
03635   
03636   CONNECTION_LOCK (connection);
03637 
03638   status = _dbus_connection_flush_unlocked (connection);
03639   
03640   HAVE_LOCK_CHECK (connection);
03641   /* Unlocks and calls out to user code */
03642   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03643 
03644   _dbus_verbose ("end\n");
03645 }
03646 
03657 static dbus_bool_t
03658 _dbus_connection_read_write_dispatch (DBusConnection *connection,
03659                                      int             timeout_milliseconds, 
03660                                      dbus_bool_t     dispatch)
03661 {
03662   DBusDispatchStatus dstatus;
03663   dbus_bool_t progress_possible;
03664 
03665   /* Need to grab a ref here in case we're a private connection and
03666    * the user drops the last ref in a handler we call; see bug 
03667    * https://bugs.freedesktop.org/show_bug.cgi?id=15635
03668    */
03669   dbus_connection_ref (connection);
03670   dstatus = dbus_connection_get_dispatch_status (connection);
03671 
03672   if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
03673     {
03674       _dbus_verbose ("doing dispatch\n");
03675       dbus_connection_dispatch (connection);
03676       CONNECTION_LOCK (connection);
03677     }
03678   else if (dstatus == DBUS_DISPATCH_NEED_MEMORY)
03679     {
03680       _dbus_verbose ("pausing for memory\n");
03681       _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
03682       CONNECTION_LOCK (connection);
03683     }
03684   else
03685     {
03686       CONNECTION_LOCK (connection);
03687       if (_dbus_connection_get_is_connected_unlocked (connection))
03688         {
03689           _dbus_verbose ("doing iteration\n");
03690           _dbus_connection_do_iteration_unlocked (connection,
03691                                                   NULL,
03692                                                   DBUS_ITERATION_DO_READING |
03693                                                   DBUS_ITERATION_DO_WRITING |
03694                                                   DBUS_ITERATION_BLOCK,
03695                                                   timeout_milliseconds);
03696         }
03697     }
03698   
03699   HAVE_LOCK_CHECK (connection);
03700   /* If we can dispatch, we can make progress until the Disconnected message
03701    * has been processed; if we can only read/write, we can make progress
03702    * as long as the transport is open.
03703    */
03704   if (dispatch)
03705     progress_possible = connection->n_incoming != 0 ||
03706       connection->disconnect_message_link != NULL;
03707   else
03708     progress_possible = _dbus_connection_get_is_connected_unlocked (connection);
03709 
03710   CONNECTION_UNLOCK (connection);
03711 
03712   dbus_connection_unref (connection);
03713 
03714   return progress_possible; /* TRUE if we can make more progress */
03715 }
03716 
03717 
03752 dbus_bool_t
03753 dbus_connection_read_write_dispatch (DBusConnection *connection,
03754                                      int             timeout_milliseconds)
03755 {
03756   _dbus_return_val_if_fail (connection != NULL, FALSE);
03757   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03758    return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE);
03759 }
03760 
03784 dbus_bool_t 
03785 dbus_connection_read_write (DBusConnection *connection, 
03786                             int             timeout_milliseconds) 
03787 { 
03788   _dbus_return_val_if_fail (connection != NULL, FALSE);
03789   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03790    return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE);
03791 }
03792 
03793 /* We need to call this anytime we pop the head of the queue, and then
03794  * update_dispatch_status_and_unlock needs to be called afterward
03795  * which will "process" the disconnected message and set
03796  * disconnected_message_processed.
03797  */
03798 static void
03799 check_disconnected_message_arrived_unlocked (DBusConnection *connection,
03800                                              DBusMessage    *head_of_queue)
03801 {
03802   HAVE_LOCK_CHECK (connection);
03803 
03804   /* checking that the link is NULL is an optimization to avoid the is_signal call */
03805   if (connection->disconnect_message_link == NULL &&
03806       dbus_message_is_signal (head_of_queue,
03807                               DBUS_INTERFACE_LOCAL,
03808                               "Disconnected"))
03809     {
03810       connection->disconnected_message_arrived = TRUE;
03811     }
03812 }
03813 
03833 DBusMessage*
03834 dbus_connection_borrow_message (DBusConnection *connection)
03835 {
03836   DBusDispatchStatus status;
03837   DBusMessage *message;
03838 
03839   _dbus_return_val_if_fail (connection != NULL, NULL);
03840 
03841   _dbus_verbose ("start\n");
03842   
03843   /* this is called for the side effect that it queues
03844    * up any messages from the transport
03845    */
03846   status = dbus_connection_get_dispatch_status (connection);
03847   if (status != DBUS_DISPATCH_DATA_REMAINS)
03848     return NULL;
03849   
03850   CONNECTION_LOCK (connection);
03851 
03852   _dbus_connection_acquire_dispatch (connection);
03853 
03854   /* While a message is outstanding, the dispatch lock is held */
03855   _dbus_assert (connection->message_borrowed == NULL);
03856 
03857   connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
03858   
03859   message = connection->message_borrowed;
03860 
03861   check_disconnected_message_arrived_unlocked (connection, message);
03862   
03863   /* Note that we KEEP the dispatch lock until the message is returned */
03864   if (message == NULL)
03865     _dbus_connection_release_dispatch (connection);
03866 
03867   CONNECTION_UNLOCK (connection);
03868 
03869   /* We don't update dispatch status until it's returned or stolen */
03870   
03871   return message;
03872 }
03873 
03882 void
03883 dbus_connection_return_message (DBusConnection *connection,
03884                                 DBusMessage    *message)
03885 {
03886   DBusDispatchStatus status;
03887   
03888   _dbus_return_if_fail (connection != NULL);
03889   _dbus_return_if_fail (message != NULL);
03890   _dbus_return_if_fail (message == connection->message_borrowed);
03891   _dbus_return_if_fail (connection->dispatch_acquired);
03892   
03893   CONNECTION_LOCK (connection);
03894   
03895   _dbus_assert (message == connection->message_borrowed);
03896   
03897   connection->message_borrowed = NULL;
03898 
03899   _dbus_connection_release_dispatch (connection); 
03900 
03901   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03902   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03903 }
03904 
03914 void
03915 dbus_connection_steal_borrowed_message (DBusConnection *connection,
03916                                         DBusMessage    *message)
03917 {
03918   DBusMessage *pop_message;
03919   DBusDispatchStatus status;
03920 
03921   _dbus_return_if_fail (connection != NULL);
03922   _dbus_return_if_fail (message != NULL);
03923   _dbus_return_if_fail (message == connection->message_borrowed);
03924   _dbus_return_if_fail (connection->dispatch_acquired);
03925   
03926   CONNECTION_LOCK (connection);
03927  
03928   _dbus_assert (message == connection->message_borrowed);
03929 
03930   pop_message = _dbus_list_pop_first (&connection->incoming_messages);
03931   _dbus_assert (message == pop_message);
03932   
03933   connection->n_incoming -= 1;
03934  
03935   _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
03936                  message, connection->n_incoming);
03937  
03938   connection->message_borrowed = NULL;
03939 
03940   _dbus_connection_release_dispatch (connection);
03941 
03942   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03943   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03944 }
03945 
03946 /* See dbus_connection_pop_message, but requires the caller to own
03947  * the lock before calling. May drop the lock while running.
03948  */
03949 static DBusList*
03950 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
03951 {
03952   HAVE_LOCK_CHECK (connection);
03953   
03954   _dbus_assert (connection->message_borrowed == NULL);
03955   
03956   if (connection->n_incoming > 0)
03957     {
03958       DBusList *link;
03959 
03960       link = _dbus_list_pop_first_link (&connection->incoming_messages);
03961       connection->n_incoming -= 1;
03962 
03963       _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from incoming queue %p, %d incoming\n",
03964                      link->data,
03965                      dbus_message_type_to_string (dbus_message_get_type (link->data)),
03966                      dbus_message_get_path (link->data) ?
03967                      dbus_message_get_path (link->data) :
03968                      "no path",
03969                      dbus_message_get_interface (link->data) ?
03970                      dbus_message_get_interface (link->data) :
03971                      "no interface",
03972                      dbus_message_get_member (link->data) ?
03973                      dbus_message_get_member (link->data) :
03974                      "no member",
03975                      dbus_message_get_signature (link->data),
03976                      connection, connection->n_incoming);
03977 
03978       check_disconnected_message_arrived_unlocked (connection, link->data);
03979       
03980       return link;
03981     }
03982   else
03983     return NULL;
03984 }
03985 
03986 /* See dbus_connection_pop_message, but requires the caller to own
03987  * the lock before calling. May drop the lock while running.
03988  */
03989 static DBusMessage*
03990 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
03991 {
03992   DBusList *link;
03993 
03994   HAVE_LOCK_CHECK (connection);
03995   
03996   link = _dbus_connection_pop_message_link_unlocked (connection);
03997 
03998   if (link != NULL)
03999     {
04000       DBusMessage *message;
04001       
04002       message = link->data;
04003       
04004       _dbus_list_free_link (link);
04005       
04006       return message;
04007     }
04008   else
04009     return NULL;
04010 }
04011 
04012 static void
04013 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
04014                                                 DBusList       *message_link)
04015 {
04016   HAVE_LOCK_CHECK (connection);
04017   
04018   _dbus_assert (message_link != NULL);
04019   /* You can't borrow a message while a link is outstanding */
04020   _dbus_assert (connection->message_borrowed == NULL);
04021   /* We had to have the dispatch lock across the pop/putback */
04022   _dbus_assert (connection->dispatch_acquired);
04023 
04024   _dbus_list_prepend_link (&connection->incoming_messages,
04025                            message_link);
04026   connection->n_incoming += 1;
04027 
04028   _dbus_verbose ("Message %p (%s %s %s '%s') put back into queue %p, %d incoming\n",
04029                  message_link->data,
04030                  dbus_message_type_to_string (dbus_message_get_type (message_link->data)),
04031                  dbus_message_get_interface (message_link->data) ?
04032                  dbus_message_get_interface (message_link->data) :
04033                  "no interface",
04034                  dbus_message_get_member (message_link->data) ?
04035                  dbus_message_get_member (message_link->data) :
04036                  "no member",
04037                  dbus_message_get_signature (message_link->data),
04038                  connection, connection->n_incoming);
04039 }
04040 
04060 DBusMessage*
04061 dbus_connection_pop_message (DBusConnection *connection)
04062 {
04063   DBusMessage *message;
04064   DBusDispatchStatus status;
04065 
04066   _dbus_verbose ("start\n");
04067   
04068   /* this is called for the side effect that it queues
04069    * up any messages from the transport
04070    */
04071   status = dbus_connection_get_dispatch_status (connection);
04072   if (status != DBUS_DISPATCH_DATA_REMAINS)
04073     return NULL;
04074   
04075   CONNECTION_LOCK (connection);
04076   _dbus_connection_acquire_dispatch (connection);
04077   HAVE_LOCK_CHECK (connection);
04078   
04079   message = _dbus_connection_pop_message_unlocked (connection);
04080 
04081   _dbus_verbose ("Returning popped message %p\n", message);    
04082 
04083   _dbus_connection_release_dispatch (connection);
04084 
04085   status = _dbus_connection_get_dispatch_status_unlocked (connection);
04086   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04087   
04088   return message;
04089 }
04090 
04098 static void
04099 _dbus_connection_acquire_dispatch (DBusConnection *connection)
04100 {
04101   HAVE_LOCK_CHECK (connection);
04102 
04103   _dbus_connection_ref_unlocked (connection);
04104   CONNECTION_UNLOCK (connection);
04105   
04106   _dbus_verbose ("locking dispatch_mutex\n");
04107   _dbus_mutex_lock (connection->dispatch_mutex);
04108 
04109   while (connection->dispatch_acquired)
04110     {
04111       _dbus_verbose ("waiting for dispatch to be acquirable\n");
04112       _dbus_condvar_wait (connection->dispatch_cond, 
04113                           connection->dispatch_mutex);
04114     }
04115   
04116   _dbus_assert (!connection->dispatch_acquired);
04117 
04118   connection->dispatch_acquired = TRUE;
04119 
04120   _dbus_verbose ("unlocking dispatch_mutex\n");
04121   _dbus_mutex_unlock (connection->dispatch_mutex);
04122   
04123   CONNECTION_LOCK (connection);
04124   _dbus_connection_unref_unlocked (connection);
04125 }
04126 
04134 static void
04135 _dbus_connection_release_dispatch (DBusConnection *connection)
04136 {
04137   HAVE_LOCK_CHECK (connection);
04138   
04139   _dbus_verbose ("locking dispatch_mutex\n");
04140   _dbus_mutex_lock (connection->dispatch_mutex);
04141   
04142   _dbus_assert (connection->dispatch_acquired);
04143 
04144   connection->dispatch_acquired = FALSE;
04145   _dbus_condvar_wake_one (connection->dispatch_cond);
04146 
04147   _dbus_verbose ("unlocking dispatch_mutex\n");
04148   _dbus_mutex_unlock (connection->dispatch_mutex);
04149 }
04150 
04151 static void
04152 _dbus_connection_failed_pop (DBusConnection *connection,
04153                              DBusList       *message_link)
04154 {
04155   _dbus_list_prepend_link (&connection->incoming_messages,
04156                            message_link);
04157   connection->n_incoming += 1;
04158 }
04159 
04160 /* Note this may be called multiple times since we don't track whether we already did it */
04161 static void
04162 notify_disconnected_unlocked (DBusConnection *connection)
04163 {
04164   HAVE_LOCK_CHECK (connection);
04165 
04166   /* Set the weakref in dbus-bus.c to NULL, so nobody will get a disconnected
04167    * connection from dbus_bus_get(). We make the same guarantee for
04168    * dbus_connection_open() but in a different way since we don't want to
04169    * unref right here; we instead check for connectedness before returning
04170    * the connection from the hash.
04171    */
04172   _dbus_bus_notify_shared_connection_disconnected_unlocked (connection);
04173 
04174   /* Dump the outgoing queue, we aren't going to be able to
04175    * send it now, and we'd like accessors like
04176    * dbus_connection_get_outgoing_size() to be accurate.
04177    */
04178   if (connection->n_outgoing > 0)
04179     {
04180       DBusList *link;
04181       
04182       _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
04183                      connection->n_outgoing);
04184       
04185       while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
04186         {
04187           _dbus_connection_message_sent (connection, link->data);
04188         }
04189     } 
04190 }
04191 
04192 /* Note this may be called multiple times since we don't track whether we already did it */
04193 static DBusDispatchStatus
04194 notify_disconnected_and_dispatch_complete_unlocked (DBusConnection *connection)
04195 {
04196   HAVE_LOCK_CHECK (connection);
04197   
04198   if (connection->disconnect_message_link != NULL)
04199     {
04200       _dbus_verbose ("Sending disconnect message\n");
04201       
04202       /* If we have pending calls, queue their timeouts - we want the Disconnected
04203        * to be the last message, after these timeouts.
04204        */
04205       connection_timeout_and_complete_all_pending_calls_unlocked (connection);
04206       
04207       /* We haven't sent the disconnect message already,
04208        * and all real messages have been queued up.
04209        */
04210       _dbus_connection_queue_synthesized_message_link (connection,
04211                                                        connection->disconnect_message_link);
04212       connection->disconnect_message_link = NULL;
04213 
04214       return DBUS_DISPATCH_DATA_REMAINS;
04215     }
04216 
04217   return DBUS_DISPATCH_COMPLETE;
04218 }
04219 
04220 static DBusDispatchStatus
04221 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
04222 {
04223   HAVE_LOCK_CHECK (connection);
04224   
04225   if (connection->n_incoming > 0)
04226     return DBUS_DISPATCH_DATA_REMAINS;
04227   else if (!_dbus_transport_queue_messages (connection->transport))
04228     return DBUS_DISPATCH_NEED_MEMORY;
04229   else
04230     {
04231       DBusDispatchStatus status;
04232       dbus_bool_t is_connected;
04233       
04234       status = _dbus_transport_get_dispatch_status (connection->transport);
04235       is_connected = _dbus_transport_get_is_connected (connection->transport);
04236 
04237       _dbus_verbose ("dispatch status = %s is_connected = %d\n",
04238                      DISPATCH_STATUS_NAME (status), is_connected);
04239       
04240       if (!is_connected)
04241         {
04242           /* It's possible this would be better done by having an explicit
04243            * notification from _dbus_transport_disconnect() that would
04244            * synchronously do this, instead of waiting for the next dispatch
04245            * status check. However, probably not good to change until it causes
04246            * a problem.
04247            */
04248           notify_disconnected_unlocked (connection);
04249 
04250           /* I'm not sure this is needed; the idea is that we want to
04251            * queue the Disconnected only after we've read all the
04252            * messages, but if we're disconnected maybe we are guaranteed
04253            * to have read them all ?
04254            */
04255           if (status == DBUS_DISPATCH_COMPLETE)
04256             status = notify_disconnected_and_dispatch_complete_unlocked (connection);
04257         }
04258       
04259       if (status != DBUS_DISPATCH_COMPLETE)
04260         return status;
04261       else if (connection->n_incoming > 0)
04262         return DBUS_DISPATCH_DATA_REMAINS;
04263       else
04264         return DBUS_DISPATCH_COMPLETE;
04265     }
04266 }
04267 
04268 static void
04269 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection    *connection,
04270                                                     DBusDispatchStatus new_status)
04271 {
04272   dbus_bool_t changed;
04273   DBusDispatchStatusFunction function;
04274   void *data;
04275 
04276   HAVE_LOCK_CHECK (connection);
04277 
04278   _dbus_connection_ref_unlocked (connection);
04279 
04280   changed = new_status != connection->last_dispatch_status;
04281 
04282   connection->last_dispatch_status = new_status;
04283 
04284   function = connection->dispatch_status_function;
04285   data = connection->dispatch_status_data;
04286 
04287   if (connection->disconnected_message_arrived &&
04288       !connection->disconnected_message_processed)
04289     {
04290       connection->disconnected_message_processed = TRUE;
04291       
04292       /* this does an unref, but we have a ref
04293        * so we should not run the finalizer here
04294        * inside the lock.
04295        */
04296       connection_forget_shared_unlocked (connection);
04297 
04298       if (connection->exit_on_disconnect)
04299         {
04300           CONNECTION_UNLOCK (connection);            
04301           
04302           _dbus_verbose ("Exiting on Disconnected signal\n");
04303           _dbus_exit (1);
04304           _dbus_assert_not_reached ("Call to exit() returned");
04305         }
04306     }
04307   
04308   /* We drop the lock */
04309   CONNECTION_UNLOCK (connection);
04310   
04311   if (changed && function)
04312     {
04313       _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
04314                      connection, new_status,
04315                      DISPATCH_STATUS_NAME (new_status));
04316       (* function) (connection, new_status, data);      
04317     }
04318   
04319   dbus_connection_unref (connection);
04320 }
04321 
04347 DBusDispatchStatus
04348 dbus_connection_get_dispatch_status (DBusConnection *connection)
04349 {
04350   DBusDispatchStatus status;
04351 
04352   _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04353 
04354   _dbus_verbose ("start\n");
04355   
04356   CONNECTION_LOCK (connection);
04357 
04358   status = _dbus_connection_get_dispatch_status_unlocked (connection);
04359   
04360   CONNECTION_UNLOCK (connection);
04361 
04362   return status;
04363 }
04364 
04368 static DBusHandlerResult
04369 _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
04370                                                  DBusMessage    *message)
04371 {
04372   if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
04373     {
04374       /* This means we're letting the bus route this message */
04375       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04376     }
04377   else if (dbus_message_is_method_call (message,
04378                                         DBUS_INTERFACE_PEER,
04379                                         "Ping"))
04380     {
04381       DBusMessage *ret;
04382       dbus_bool_t sent;
04383       
04384       ret = dbus_message_new_method_return (message);
04385       if (ret == NULL)
04386         return DBUS_HANDLER_RESULT_NEED_MEMORY;
04387      
04388       sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04389 
04390       dbus_message_unref (ret);
04391 
04392       if (!sent)
04393         return DBUS_HANDLER_RESULT_NEED_MEMORY;
04394       
04395       return DBUS_HANDLER_RESULT_HANDLED;
04396     }
04397   else if (dbus_message_is_method_call (message,
04398                                         DBUS_INTERFACE_PEER,
04399                                         "GetMachineId"))
04400     {
04401       DBusMessage *ret;
04402       dbus_bool_t sent;
04403       DBusString uuid;
04404       
04405       ret = dbus_message_new_method_return (message);
04406       if (ret == NULL)
04407         return DBUS_HANDLER_RESULT_NEED_MEMORY;
04408 
04409       sent = FALSE;
04410       _dbus_string_init (&uuid);
04411       if (_dbus_get_local_machine_uuid_encoded (&uuid))
04412         {
04413           const char *v_STRING = _dbus_string_get_const_data (&uuid);
04414           if (dbus_message_append_args (ret,
04415                                         DBUS_TYPE_STRING, &v_STRING,
04416                                         DBUS_TYPE_INVALID))
04417             {
04418               sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04419             }
04420         }
04421       _dbus_string_free (&uuid);
04422       
04423       dbus_message_unref (ret);
04424 
04425       if (!sent)
04426         return DBUS_HANDLER_RESULT_NEED_MEMORY;
04427       
04428       return DBUS_HANDLER_RESULT_HANDLED;
04429     }
04430   else if (dbus_message_has_interface (message, DBUS_INTERFACE_PEER))
04431     {
04432       /* We need to bounce anything else with this interface, otherwise apps
04433        * could start extending the interface and when we added extensions
04434        * here to DBusConnection we'd break those apps.
04435        */
04436       
04437       DBusMessage *ret;
04438       dbus_bool_t sent;
04439       
04440       ret = dbus_message_new_error (message,
04441                                     DBUS_ERROR_UNKNOWN_METHOD,
04442                                     "Unknown method invoked on org.freedesktop.DBus.Peer interface");
04443       if (ret == NULL)
04444         return DBUS_HANDLER_RESULT_NEED_MEMORY;
04445       
04446       sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04447       
04448       dbus_message_unref (ret);
04449       
04450       if (!sent)
04451         return DBUS_HANDLER_RESULT_NEED_MEMORY;
04452       
04453       return DBUS_HANDLER_RESULT_HANDLED;
04454     }
04455   else
04456     {
04457       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04458     }
04459 }
04460 
04467 static DBusHandlerResult
04468 _dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection,
04469                                                            DBusMessage    *message)
04470 {
04471   /* We just run one filter for now but have the option to run more
04472      if the spec calls for it in the future */
04473 
04474   return _dbus_connection_peer_filter_unlocked_no_update (connection, message);
04475 }
04476 
04519 DBusDispatchStatus
04520 dbus_connection_dispatch (DBusConnection *connection)
04521 {
04522   DBusMessage *message;
04523   DBusList *link, *filter_list_copy, *message_link;
04524   DBusHandlerResult result;
04525   DBusPendingCall *pending;
04526   dbus_int32_t reply_serial;
04527   DBusDispatchStatus status;
04528 
04529   _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04530 
04531   _dbus_verbose ("\n");
04532   
04533   CONNECTION_LOCK (connection);
04534   status = _dbus_connection_get_dispatch_status_unlocked (connection);
04535   if (status != DBUS_DISPATCH_DATA_REMAINS)
04536     {
04537       /* unlocks and calls out to user code */
04538       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04539       return status;
04540     }
04541   
04542   /* We need to ref the connection since the callback could potentially
04543    * drop the last ref to it
04544    */
04545   _dbus_connection_ref_unlocked (connection);
04546 
04547   _dbus_connection_acquire_dispatch (connection);
04548   HAVE_LOCK_CHECK (connection);
04549 
04550   message_link = _dbus_connection_pop_message_link_unlocked (connection);
04551   if (message_link == NULL)
04552     {
04553       /* another thread dispatched our stuff */
04554 
04555       _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
04556       
04557       _dbus_connection_release_dispatch (connection);
04558 
04559       status = _dbus_connection_get_dispatch_status_unlocked (connection);
04560 
04561       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04562       
04563       dbus_connection_unref (connection);
04564       
04565       return status;
04566     }
04567 
04568   message = message_link->data;
04569 
04570   _dbus_verbose (" dispatching message %p (%s %s %s '%s')\n",
04571                  message,
04572                  dbus_message_type_to_string (dbus_message_get_type (message)),
04573                  dbus_message_get_interface (message) ?
04574                  dbus_message_get_interface (message) :
04575                  "no interface",
04576                  dbus_message_get_member (message) ?
04577                  dbus_message_get_member (message) :
04578                  "no member",
04579                  dbus_message_get_signature (message));
04580 
04581   result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04582   
04583   /* Pending call handling must be first, because if you do
04584    * dbus_connection_send_with_reply_and_block() or
04585    * dbus_pending_call_block() then no handlers/filters will be run on
04586    * the reply. We want consistent semantics in the case where we
04587    * dbus_connection_dispatch() the reply.
04588    */
04589   
04590   reply_serial = dbus_message_get_reply_serial (message);
04591   pending = _dbus_hash_table_lookup_int (connection->pending_replies,
04592                                          reply_serial);
04593   if (pending)
04594     {
04595       _dbus_verbose ("Dispatching a pending reply\n");
04596       complete_pending_call_and_unlock (connection, pending, message);
04597       pending = NULL; /* it's probably unref'd */
04598       
04599       CONNECTION_LOCK (connection);
04600       _dbus_verbose ("pending call completed in dispatch\n");
04601       result = DBUS_HANDLER_RESULT_HANDLED;
04602       goto out;
04603     }
04604 
04605   result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message);
04606   if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04607     goto out;
04608  
04609   if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
04610     {
04611       _dbus_connection_release_dispatch (connection);
04612       HAVE_LOCK_CHECK (connection);
04613       
04614       _dbus_connection_failed_pop (connection, message_link);
04615 
04616       /* unlocks and calls user code */
04617       _dbus_connection_update_dispatch_status_and_unlock (connection,
04618                                                           DBUS_DISPATCH_NEED_MEMORY);
04619 
04620       if (pending)
04621         dbus_pending_call_unref (pending);
04622       dbus_connection_unref (connection);
04623       
04624       return DBUS_DISPATCH_NEED_MEMORY;
04625     }
04626   
04627   _dbus_list_foreach (&filter_list_copy,
04628                       (DBusForeachFunction)_dbus_message_filter_ref,
04629                       NULL);
04630 
04631   /* We're still protected from dispatch() reentrancy here
04632    * since we acquired the dispatcher
04633    */
04634   CONNECTION_UNLOCK (connection);
04635   
04636   link = _dbus_list_get_first_link (&filter_list_copy);
04637   while (link != NULL)
04638     {
04639       DBusMessageFilter *filter = link->data;
04640       DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
04641 
04642       if (filter->function == NULL)
04643         {
04644           _dbus_verbose ("  filter was removed in a callback function\n");
04645           link = next;
04646           continue;
04647         }
04648 
04649       _dbus_verbose ("  running filter on message %p\n", message);
04650       result = (* filter->function) (connection, message, filter->user_data);
04651 
04652       if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04653         break;
04654 
04655       link = next;
04656     }
04657 
04658   _dbus_list_foreach (&filter_list_copy,
04659                       (DBusForeachFunction)_dbus_message_filter_unref,
04660                       NULL);
04661   _dbus_list_clear (&filter_list_copy);
04662   
04663   CONNECTION_LOCK (connection);
04664 
04665   if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04666     {
04667       _dbus_verbose ("No memory\n");
04668       goto out;
04669     }
04670   else if (result == DBUS_HANDLER_RESULT_HANDLED)
04671     {
04672       _dbus_verbose ("filter handled message in dispatch\n");
04673       goto out;
04674     }
04675 
04676   /* We're still protected from dispatch() reentrancy here
04677    * since we acquired the dispatcher
04678    */
04679   _dbus_verbose ("  running object path dispatch on message %p (%s %s %s '%s')\n",
04680                  message,
04681                  dbus_message_type_to_string (dbus_message_get_type (message)),
04682                  dbus_message_get_interface (message) ?
04683                  dbus_message_get_interface (message) :
04684                  "no interface",
04685                  dbus_message_get_member (message) ?
04686                  dbus_message_get_member (message) :
04687                  "no member",
04688                  dbus_message_get_signature (message));
04689 
04690   HAVE_LOCK_CHECK (connection);
04691   result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
04692                                                   message);
04693   
04694   CONNECTION_LOCK (connection);
04695 
04696   if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04697     {
04698       _dbus_verbose ("object tree handled message in dispatch\n");
04699       goto out;
04700     }
04701 
04702   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
04703     {
04704       DBusMessage *reply;
04705       DBusString str;
04706       DBusPreallocatedSend *preallocated;
04707 
04708       _dbus_verbose ("  sending error %s\n",
04709                      DBUS_ERROR_UNKNOWN_METHOD);
04710       
04711       if (!_dbus_string_init (&str))
04712         {
04713           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04714           _dbus_verbose ("no memory for error string in dispatch\n");
04715           goto out;
04716         }
04717               
04718       if (!_dbus_string_append_printf (&str,
04719                                        "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
04720                                        dbus_message_get_member (message),
04721                                        dbus_message_get_signature (message),
04722                                        dbus_message_get_interface (message)))
04723         {
04724           _dbus_string_free (&str);
04725           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04726           _dbus_verbose ("no memory for error string in dispatch\n");
04727           goto out;
04728         }
04729       
04730       reply = dbus_message_new_error (message,
04731                                       DBUS_ERROR_UNKNOWN_METHOD,
04732                                       _dbus_string_get_const_data (&str));
04733       _dbus_string_free (&str);
04734 
04735       if (reply == NULL)
04736         {
04737           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04738           _dbus_verbose ("no memory for error reply in dispatch\n");
04739           goto out;
04740         }
04741       
04742       preallocated = _dbus_connection_preallocate_send_unlocked (connection);
04743 
04744       if (preallocated == NULL)
04745         {
04746           dbus_message_unref (reply);
04747           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04748           _dbus_verbose ("no memory for error send in dispatch\n");
04749           goto out;
04750         }
04751 
04752       _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
04753                                                              reply, NULL);
04754 
04755       dbus_message_unref (reply);
04756       
04757       result = DBUS_HANDLER_RESULT_HANDLED;
04758     }
04759   
04760   _dbus_verbose ("  done dispatching %p (%s %s %s '%s') on connection %p\n", message,
04761                  dbus_message_type_to_string (dbus_message_get_type (message)),
04762                  dbus_message_get_interface (message) ?
04763                  dbus_message_get_interface (message) :
04764                  "no interface",
04765                  dbus_message_get_member (message) ?
04766                  dbus_message_get_member (message) :
04767                  "no member",
04768                  dbus_message_get_signature (message),
04769                  connection);
04770   
04771  out:
04772   if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04773     {
04774       _dbus_verbose ("out of memory\n");
04775       
04776       /* Put message back, and we'll start over.
04777        * Yes this means handlers must be idempotent if they
04778        * don't return HANDLED; c'est la vie.
04779        */
04780       _dbus_connection_putback_message_link_unlocked (connection,
04781                                                       message_link);
04782     }
04783   else
04784     {
04785       _dbus_verbose (" ... done dispatching\n");
04786       
04787       _dbus_list_free_link (message_link);
04788       dbus_message_unref (message); /* don't want the message to count in max message limits
04789                                      * in computing dispatch status below
04790                                      */
04791     }
04792   
04793   _dbus_connection_release_dispatch (connection);
04794   HAVE_LOCK_CHECK (connection);
04795 
04796   _dbus_verbose ("before final status update\n");
04797   status = _dbus_connection_get_dispatch_status_unlocked (connection);
04798 
04799   /* unlocks and calls user code */
04800   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04801   
04802   dbus_connection_unref (connection);
04803   
04804   return status;
04805 }
04806 
04868 dbus_bool_t
04869 dbus_connection_set_watch_functions (DBusConnection              *connection,
04870                                      DBusAddWatchFunction         add_function,
04871                                      DBusRemoveWatchFunction      remove_function,
04872                                      DBusWatchToggledFunction     toggled_function,
04873                                      void                        *data,
04874                                      DBusFreeFunction             free_data_function)
04875 {
04876   dbus_bool_t retval;
04877 
04878   _dbus_return_val_if_fail (connection != NULL, FALSE);
04879   
04880   CONNECTION_LOCK (connection);
04881 
04882   retval = _dbus_watch_list_set_functions (connection->watches,
04883                                            add_function, remove_function,
04884                                            toggled_function,
04885                                            data, free_data_function);
04886 
04887   CONNECTION_UNLOCK (connection);
04888 
04889   return retval;
04890 }
04891 
04931 dbus_bool_t
04932 dbus_connection_set_timeout_functions   (DBusConnection            *connection,
04933                                          DBusAddTimeoutFunction     add_function,
04934                                          DBusRemoveTimeoutFunction  remove_function,
04935                                          DBusTimeoutToggledFunction toggled_function,
04936                                          void                      *data,
04937                                          DBusFreeFunction           free_data_function)
04938 {
04939   dbus_bool_t retval;
04940 
04941   _dbus_return_val_if_fail (connection != NULL, FALSE);
04942   
04943   CONNECTION_LOCK (connection);
04944 
04945   retval = _dbus_timeout_list_set_functions (connection->timeouts,
04946                                              add_function, remove_function,
04947                                              toggled_function,
04948                                              data, free_data_function);
04949 
04950   CONNECTION_UNLOCK (connection);
04951 
04952   return retval;
04953 }
04954 
04969 void
04970 dbus_connection_set_wakeup_main_function (DBusConnection            *connection,
04971                                           DBusWakeupMainFunction     wakeup_main_function,
04972                                           void                      *data,
04973                                           DBusFreeFunction           free_data_function)
04974 {
04975   void *old_data;
04976   DBusFreeFunction old_free_data;
04977 
04978   _dbus_return_if_fail (connection != NULL);
04979   
04980   CONNECTION_LOCK (connection);
04981   old_data = connection->wakeup_main_data;
04982   old_free_data = connection->free_wakeup_main_data;
04983 
04984   connection->wakeup_main_function = wakeup_main_function;
04985   connection->wakeup_main_data = data;
04986   connection->free_wakeup_main_data = free_data_function;
04987   
04988   CONNECTION_UNLOCK (connection);
04989 
04990   /* Callback outside the lock */
04991   if (old_free_data)
04992     (*old_free_data) (old_data);
04993 }
04994 
05015 void
05016 dbus_connection_set_dispatch_status_function (DBusConnection             *connection,
05017                                               DBusDispatchStatusFunction  function,
05018                                               void                       *data,
05019                                               DBusFreeFunction            free_data_function)
05020 {
05021   void *old_data;
05022   DBusFreeFunction old_free_data;
05023 
05024   _dbus_return_if_fail (connection != NULL);
05025   
05026   CONNECTION_LOCK (connection);
05027   old_data = connection->dispatch_status_data;
05028   old_free_data = connection->free_dispatch_status_data;
05029 
05030   connection->dispatch_status_function = function;
05031   connection->dispatch_status_data = data;
05032   connection->free_dispatch_status_data = free_data_function;
05033   
05034   CONNECTION_UNLOCK (connection);
05035 
05036   /* Callback outside the lock */
05037   if (old_free_data)
05038     (*old_free_data) (old_data);
05039 }
05040 
05060 dbus_bool_t
05061 dbus_connection_get_unix_fd (DBusConnection *connection,
05062                              int            *fd)
05063 {
05064   _dbus_return_val_if_fail (connection != NULL, FALSE);
05065   _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
05066 
05067 #ifdef DBUS_WIN
05068   /* FIXME do this on a lower level */
05069   return FALSE;
05070 #endif
05071   
05072   return dbus_connection_get_socket(connection, fd);
05073 }
05074 
05090 dbus_bool_t
05091 dbus_connection_get_socket(DBusConnection              *connection,
05092                            int                         *fd)
05093 {
05094   dbus_bool_t retval;
05095 
05096   _dbus_return_val_if_fail (connection != NULL, FALSE);
05097   _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
05098   
05099   CONNECTION_LOCK (connection);
05100   
05101   retval = _dbus_transport_get_socket_fd (connection->transport,
05102                                           fd);
05103 
05104   CONNECTION_UNLOCK (connection);
05105 
05106   return retval;
05107 }
05108 
05109 
05132 dbus_bool_t
05133 dbus_connection_get_unix_user (DBusConnection *connection,
05134                                unsigned long  *uid)
05135 {
05136   dbus_bool_t result;
05137 
05138   _dbus_return_val_if_fail (connection != NULL, FALSE);
05139   _dbus_return_val_if_fail (uid != NULL, FALSE);
05140   
05141   CONNECTION_LOCK (connection);
05142 
05143   if (!_dbus_transport_get_is_authenticated (connection->transport))
05144     result = FALSE;
05145   else
05146     result = _dbus_transport_get_unix_user (connection->transport,
05147                                             uid);
05148 
05149 #ifdef DBUS_WIN
05150   _dbus_assert (!result);
05151 #endif
05152   
05153   CONNECTION_UNLOCK (connection);
05154 
05155   return result;
05156 }
05157 
05168 dbus_bool_t
05169 dbus_connection_get_unix_process_id (DBusConnection *connection,
05170                                      unsigned long  *pid)
05171 {
05172   dbus_bool_t result;
05173 
05174   _dbus_return_val_if_fail (connection != NULL, FALSE);
05175   _dbus_return_val_if_fail (pid != NULL, FALSE);
05176   
05177   CONNECTION_LOCK (connection);
05178 
05179   if (!_dbus_transport_get_is_authenticated (connection->transport))
05180     result = FALSE;
05181   else
05182     result = _dbus_transport_get_unix_process_id (connection->transport,
05183                                                   pid);
05184 
05185   CONNECTION_UNLOCK (connection);
05186 
05187   return result;
05188 }
05189 
05200 dbus_bool_t
05201 dbus_connection_get_adt_audit_session_data (DBusConnection *connection,
05202                                             void          **data,
05203                                             dbus_int32_t   *data_size)
05204 {
05205   dbus_bool_t result;
05206 
05207   _dbus_return_val_if_fail (connection != NULL, FALSE);
05208   _dbus_return_val_if_fail (data != NULL, FALSE);
05209   _dbus_return_val_if_fail (data_size != NULL, FALSE);
05210   
05211   CONNECTION_LOCK (connection);
05212 
05213   if (!_dbus_transport_get_is_authenticated (connection->transport))
05214     result = FALSE;
05215   else
05216     result = _dbus_transport_get_adt_audit_session_data (connection->transport,
05217                                                          data,
05218                                                          data_size);
05219   CONNECTION_UNLOCK (connection);
05220 
05221   return result;
05222 }
05223 
05246 void
05247 dbus_connection_set_unix_user_function (DBusConnection             *connection,
05248                                         DBusAllowUnixUserFunction   function,
05249                                         void                       *data,
05250                                         DBusFreeFunction            free_data_function)
05251 {
05252   void *old_data = NULL;
05253   DBusFreeFunction old_free_function = NULL;
05254 
05255   _dbus_return_if_fail (connection != NULL);
05256   
05257   CONNECTION_LOCK (connection);
05258   _dbus_transport_set_unix_user_function (connection->transport,
05259                                           function, data, free_data_function,
05260                                           &old_data, &old_free_function);
05261   CONNECTION_UNLOCK (connection);
05262 
05263   if (old_free_function != NULL)
05264     (* old_free_function) (old_data);
05265 }
05266 
05298 dbus_bool_t
05299 dbus_connection_get_windows_user (DBusConnection             *connection,
05300                                   char                      **windows_sid_p)
05301 {
05302   dbus_bool_t result;
05303 
05304   _dbus_return_val_if_fail (connection != NULL, FALSE);
05305   _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
05306   
05307   CONNECTION_LOCK (connection);
05308 
05309   if (!_dbus_transport_get_is_authenticated (connection->transport))
05310     result = FALSE;
05311   else
05312     result = _dbus_transport_get_windows_user (connection->transport,
05313                                                windows_sid_p);
05314 
05315 #ifdef DBUS_UNIX
05316   _dbus_assert (!result);
05317 #endif
05318   
05319   CONNECTION_UNLOCK (connection);
05320 
05321   return result;
05322 }
05323 
05345 void
05346 dbus_connection_set_windows_user_function (DBusConnection              *connection,
05347                                            DBusAllowWindowsUserFunction function,
05348                                            void                        *data,
05349                                            DBusFreeFunction             free_data_function)
05350 {
05351   void *old_data = NULL;
05352   DBusFreeFunction old_free_function = NULL;
05353 
05354   _dbus_return_if_fail (connection != NULL);
05355   
05356   CONNECTION_LOCK (connection);
05357   _dbus_transport_set_windows_user_function (connection->transport,
05358                                              function, data, free_data_function,
05359                                              &old_data, &old_free_function);
05360   CONNECTION_UNLOCK (connection);
05361 
05362   if (old_free_function != NULL)
05363     (* old_free_function) (old_data);
05364 }
05365 
05392 void
05393 dbus_connection_set_allow_anonymous (DBusConnection             *connection,
05394                                      dbus_bool_t                 value)
05395 {
05396   _dbus_return_if_fail (connection != NULL);
05397   
05398   CONNECTION_LOCK (connection);
05399   _dbus_transport_set_allow_anonymous (connection->transport, value);
05400   CONNECTION_UNLOCK (connection);
05401 }
05402 
05420 void
05421 dbus_connection_set_route_peer_messages (DBusConnection             *connection,
05422                                          dbus_bool_t                 value)
05423 {
05424   _dbus_return_if_fail (connection != NULL);
05425   
05426   CONNECTION_LOCK (connection);
05427   connection->route_peer_messages = TRUE;
05428   CONNECTION_UNLOCK (connection);
05429 }
05430 
05452 dbus_bool_t
05453 dbus_connection_add_filter (DBusConnection            *connection,
05454                             DBusHandleMessageFunction  function,
05455                             void                      *user_data,
05456                             DBusFreeFunction           free_data_function)
05457 {
05458   DBusMessageFilter *filter;
05459   
05460   _dbus_return_val_if_fail (connection != NULL, FALSE);
05461   _dbus_return_val_if_fail (function != NULL, FALSE);
05462 
05463   filter = dbus_new0 (DBusMessageFilter, 1);
05464   if (filter == NULL)
05465     return FALSE;
05466 
05467   filter->refcount.value = 1;
05468   
05469   CONNECTION_LOCK (connection);
05470 
05471   if (!_dbus_list_append (&connection->filter_list,
05472                           filter))
05473     {
05474       _dbus_message_filter_unref (filter);
05475       CONNECTION_UNLOCK (connection);
05476       return FALSE;
05477     }
05478 
05479   /* Fill in filter after all memory allocated,
05480    * so we don't run the free_user_data_function
05481    * if the add_filter() fails
05482    */
05483   
05484   filter->function = function;
05485   filter->user_data = user_data;
05486   filter->free_user_data_function = free_data_function;
05487         
05488   CONNECTION_UNLOCK (connection);
05489   return TRUE;
05490 }
05491 
05504 void
05505 dbus_connection_remove_filter (DBusConnection            *connection,
05506                                DBusHandleMessageFunction  function,
05507                                void                      *user_data)
05508 {
05509   DBusList *link;
05510   DBusMessageFilter *filter;
05511   
05512   _dbus_return_if_fail (connection != NULL);
05513   _dbus_return_if_fail (function != NULL);
05514   
05515   CONNECTION_LOCK (connection);
05516 
05517   filter = NULL;
05518   
05519   link = _dbus_list_get_last_link (&connection->filter_list);
05520   while (link != NULL)
05521     {
05522       filter = link->data;
05523 
05524       if (filter->function == function &&
05525           filter->user_data == user_data)
05526         {
05527           _dbus_list_remove_link (&connection->filter_list, link);
05528           filter->function = NULL;
05529           
05530           break;
05531         }
05532         
05533       link = _dbus_list_get_prev_link (&connection->filter_list, link);
05534       filter = NULL;
05535     }
05536   
05537   CONNECTION_UNLOCK (connection);
05538 
05539 #ifndef DBUS_DISABLE_CHECKS
05540   if (filter == NULL)
05541     {
05542       _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
05543                                function, user_data);
05544       return;
05545     }
05546 #endif
05547   
05548   /* Call application code */
05549   if (filter->free_user_data_function)
05550     (* filter->free_user_data_function) (filter->user_data);
05551 
05552   filter->free_user_data_function = NULL;
05553   filter->user_data = NULL;
05554   
05555   _dbus_message_filter_unref (filter);
05556 }
05557 
05570 dbus_bool_t
05571 dbus_connection_try_register_object_path (DBusConnection              *connection,
05572                                           const char                  *path,
05573                                           const DBusObjectPathVTable  *vtable,
05574                                           void                        *user_data,
05575                                           DBusError                   *error)
05576 {
05577   char **decomposed_path;
05578   dbus_bool_t retval;
05579   
05580   _dbus_return_val_if_fail (connection != NULL, FALSE);
05581   _dbus_return_val_if_fail (path != NULL, FALSE);
05582   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05583   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05584 
05585   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05586     return FALSE;
05587 
05588   CONNECTION_LOCK (connection);
05589 
05590   retval = _dbus_object_tree_register (connection->objects,
05591                                        FALSE,
05592                                        (const char **) decomposed_path, vtable,
05593                                        user_data, error);
05594 
05595   CONNECTION_UNLOCK (connection);
05596 
05597   dbus_free_string_array (decomposed_path);
05598 
05599   return retval;
05600 }
05601 
05616 dbus_bool_t
05617 dbus_connection_register_object_path (DBusConnection              *connection,
05618                                       const char                  *path,
05619                                       const DBusObjectPathVTable  *vtable,
05620                                       void                        *user_data)
05621 {
05622   char **decomposed_path;
05623   dbus_bool_t retval;
05624   DBusError error = DBUS_ERROR_INIT;
05625 
05626   _dbus_return_val_if_fail (connection != NULL, FALSE);
05627   _dbus_return_val_if_fail (path != NULL, FALSE);
05628   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05629   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05630 
05631   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05632     return FALSE;
05633 
05634   CONNECTION_LOCK (connection);
05635 
05636   retval = _dbus_object_tree_register (connection->objects,
05637                                        FALSE,
05638                                        (const char **) decomposed_path, vtable,
05639                                        user_data, &error);
05640 
05641   CONNECTION_UNLOCK (connection);
05642 
05643   dbus_free_string_array (decomposed_path);
05644 
05645   if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE))
05646     {
05647       _dbus_warn ("%s\n", error.message);
05648       dbus_error_free (&error);
05649       return FALSE;
05650     }
05651 
05652   return retval;
05653 }
05654 
05669 dbus_bool_t
05670 dbus_connection_try_register_fallback (DBusConnection              *connection,
05671                                        const char                  *path,
05672                                        const DBusObjectPathVTable  *vtable,
05673                                        void                        *user_data,
05674                                        DBusError                   *error)
05675 {
05676   char **decomposed_path;
05677   dbus_bool_t retval;
05678 
05679   _dbus_return_val_if_fail (connection != NULL, FALSE);
05680   _dbus_return_val_if_fail (path != NULL, FALSE);
05681   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05682   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05683 
05684   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05685     return FALSE;
05686 
05687   CONNECTION_LOCK (connection);
05688 
05689   retval = _dbus_object_tree_register (connection->objects,
05690                                        TRUE,
05691                                        (const char **) decomposed_path, vtable,
05692                                        user_data, error);
05693 
05694   CONNECTION_UNLOCK (connection);
05695 
05696   dbus_free_string_array (decomposed_path);
05697 
05698   return retval;
05699 }
05700 
05717 dbus_bool_t
05718 dbus_connection_register_fallback (DBusConnection              *connection,
05719                                    const char                  *path,
05720                                    const DBusObjectPathVTable  *vtable,
05721                                    void                        *user_data)
05722 {
05723   char **decomposed_path;
05724   dbus_bool_t retval;
05725   DBusError error = DBUS_ERROR_INIT;
05726 
05727   _dbus_return_val_if_fail (connection != NULL, FALSE);
05728   _dbus_return_val_if_fail (path != NULL, FALSE);
05729   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05730   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05731 
05732   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05733     return FALSE;
05734 
05735   CONNECTION_LOCK (connection);
05736 
05737   retval = _dbus_object_tree_register (connection->objects,
05738                                        TRUE,
05739                                        (const char **) decomposed_path, vtable,
05740                                        user_data, &error);
05741 
05742   CONNECTION_UNLOCK (connection);
05743 
05744   dbus_free_string_array (decomposed_path);
05745 
05746   if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE))
05747     {
05748       _dbus_warn ("%s\n", error.message);
05749       dbus_error_free (&error);
05750       return FALSE;
05751     }
05752 
05753   return retval;
05754 }
05755 
05765 dbus_bool_t
05766 dbus_connection_unregister_object_path (DBusConnection              *connection,
05767                                         const char                  *path)
05768 {
05769   char **decomposed_path;
05770 
05771   _dbus_return_val_if_fail (connection != NULL, FALSE);
05772   _dbus_return_val_if_fail (path != NULL, FALSE);
05773   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05774 
05775   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05776       return FALSE;
05777 
05778   CONNECTION_LOCK (connection);
05779 
05780   _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
05781 
05782   dbus_free_string_array (decomposed_path);
05783 
05784   return TRUE;
05785 }
05786 
05797 dbus_bool_t
05798 dbus_connection_get_object_path_data (DBusConnection *connection,
05799                                       const char     *path,
05800                                       void          **data_p)
05801 {
05802   char **decomposed_path;
05803 
05804   _dbus_return_val_if_fail (connection != NULL, FALSE);
05805   _dbus_return_val_if_fail (path != NULL, FALSE);
05806   _dbus_return_val_if_fail (data_p != NULL, FALSE);
05807 
05808   *data_p = NULL;
05809   
05810   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05811     return FALSE;
05812   
05813   CONNECTION_LOCK (connection);
05814 
05815   *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path);
05816 
05817   CONNECTION_UNLOCK (connection);
05818 
05819   dbus_free_string_array (decomposed_path);
05820 
05821   return TRUE;
05822 }
05823 
05834 dbus_bool_t
05835 dbus_connection_list_registered (DBusConnection              *connection,
05836                                  const char                  *parent_path,
05837                                  char                      ***child_entries)
05838 {
05839   char **decomposed_path;
05840   dbus_bool_t retval;
05841   _dbus_return_val_if_fail (connection != NULL, FALSE);
05842   _dbus_return_val_if_fail (parent_path != NULL, FALSE);
05843   _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
05844   _dbus_return_val_if_fail (child_entries != NULL, FALSE);
05845 
05846   if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
05847     return FALSE;
05848 
05849   CONNECTION_LOCK (connection);
05850 
05851   retval = _dbus_object_tree_list_registered_and_unlock (connection->objects,
05852                                                          (const char **) decomposed_path,
05853                                                          child_entries);
05854   dbus_free_string_array (decomposed_path);
05855 
05856   return retval;
05857 }
05858 
05859 static DBusDataSlotAllocator slot_allocator;
05860 _DBUS_DEFINE_GLOBAL_LOCK (connection_slots);
05861 
05876 dbus_bool_t
05877 dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
05878 {
05879   return _dbus_data_slot_allocator_alloc (&slot_allocator,
05880                                           &_DBUS_LOCK_NAME (connection_slots),
05881                                           slot_p);
05882 }
05883 
05895 void
05896 dbus_connection_free_data_slot (dbus_int32_t *slot_p)
05897 {
05898   _dbus_return_if_fail (*slot_p >= 0);
05899   
05900   _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
05901 }
05902 
05925 dbus_bool_t
05926 dbus_connection_set_data (DBusConnection   *connection,
05927                           dbus_int32_t      slot,
05928                           void             *data,
05929                           DBusFreeFunction  free_data_func)
05930 {
05931   DBusFreeFunction old_free_func;
05932   void *old_data;
05933   dbus_bool_t retval;
05934 
05935   _dbus_return_val_if_fail (connection != NULL, FALSE);
05936   _dbus_return_val_if_fail (slot >= 0, FALSE);
05937   
05938   SLOTS_LOCK (connection);
05939 
05940   retval = _dbus_data_slot_list_set (&slot_allocator,
05941                                      &connection->slot_list,
05942                                      slot, data, free_data_func,
05943                                      &old_free_func, &old_data);
05944   
05945   SLOTS_UNLOCK (connection);
05946 
05947   if (retval)
05948     {
05949       /* Do the actual free outside the connection lock */
05950       if (old_free_func)
05951         (* old_free_func) (old_data);
05952     }
05953 
05954   return retval;
05955 }
05956 
05974 void*
05975 dbus_connection_get_data (DBusConnection   *connection,
05976                           dbus_int32_t      slot)
05977 {
05978   void *res;
05979 
05980   _dbus_return_val_if_fail (connection != NULL, NULL);
05981   
05982   SLOTS_LOCK (connection);
05983 
05984   res = _dbus_data_slot_list_get (&slot_allocator,
05985                                   &connection->slot_list,
05986                                   slot);
05987   
05988   SLOTS_UNLOCK (connection);
05989 
05990   return res;
05991 }
05992 
05999 void
06000 dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
06001 {  
06002   _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
06003 }
06004 
06013 void
06014 dbus_connection_set_max_message_size (DBusConnection *connection,
06015                                       long            size)
06016 {
06017   _dbus_return_if_fail (connection != NULL);
06018   
06019   CONNECTION_LOCK (connection);
06020   _dbus_transport_set_max_message_size (connection->transport,
06021                                         size);
06022   CONNECTION_UNLOCK (connection);
06023 }
06024 
06031 long
06032 dbus_connection_get_max_message_size (DBusConnection *connection)
06033 {
06034   long res;
06035 
06036   _dbus_return_val_if_fail (connection != NULL, 0);
06037   
06038   CONNECTION_LOCK (connection);
06039   res = _dbus_transport_get_max_message_size (connection->transport);
06040   CONNECTION_UNLOCK (connection);
06041   return res;
06042 }
06043 
06052 void
06053 dbus_connection_set_max_message_unix_fds (DBusConnection *connection,
06054                                           long            n)
06055 {
06056   _dbus_return_if_fail (connection != NULL);
06057 
06058   CONNECTION_LOCK (connection);
06059   _dbus_transport_set_max_message_unix_fds (connection->transport,
06060                                             n);
06061   CONNECTION_UNLOCK (connection);
06062 }
06063 
06070 long
06071 dbus_connection_get_max_message_unix_fds (DBusConnection *connection)
06072 {
06073   long res;
06074 
06075   _dbus_return_val_if_fail (connection != NULL, 0);
06076 
06077   CONNECTION_LOCK (connection);
06078   res = _dbus_transport_get_max_message_unix_fds (connection->transport);
06079   CONNECTION_UNLOCK (connection);
06080   return res;
06081 }
06082 
06108 void
06109 dbus_connection_set_max_received_size (DBusConnection *connection,
06110                                        long            size)
06111 {
06112   _dbus_return_if_fail (connection != NULL);
06113   
06114   CONNECTION_LOCK (connection);
06115   _dbus_transport_set_max_received_size (connection->transport,
06116                                          size);
06117   CONNECTION_UNLOCK (connection);
06118 }
06119 
06126 long
06127 dbus_connection_get_max_received_size (DBusConnection *connection)
06128 {
06129   long res;
06130 
06131   _dbus_return_val_if_fail (connection != NULL, 0);
06132   
06133   CONNECTION_LOCK (connection);
06134   res = _dbus_transport_get_max_received_size (connection->transport);
06135   CONNECTION_UNLOCK (connection);
06136   return res;
06137 }
06138 
06150 void
06151 dbus_connection_set_max_received_unix_fds (DBusConnection *connection,
06152                                            long            n)
06153 {
06154   _dbus_return_if_fail (connection != NULL);
06155 
06156   CONNECTION_LOCK (connection);
06157   _dbus_transport_set_max_received_unix_fds (connection->transport,
06158                                              n);
06159   CONNECTION_UNLOCK (connection);
06160 }
06161 
06168 long
06169 dbus_connection_get_max_received_unix_fds (DBusConnection *connection)
06170 {
06171   long res;
06172 
06173   _dbus_return_val_if_fail (connection != NULL, 0);
06174 
06175   CONNECTION_LOCK (connection);
06176   res = _dbus_transport_get_max_received_unix_fds (connection->transport);
06177   CONNECTION_UNLOCK (connection);
06178   return res;
06179 }
06180 
06191 long
06192 dbus_connection_get_outgoing_size (DBusConnection *connection)
06193 {
06194   long res;
06195 
06196   _dbus_return_val_if_fail (connection != NULL, 0);
06197 
06198   CONNECTION_LOCK (connection);
06199   res = _dbus_counter_get_size_value (connection->outgoing_counter);
06200   CONNECTION_UNLOCK (connection);
06201   return res;
06202 }
06203 
06211 long
06212 dbus_connection_get_outgoing_unix_fds (DBusConnection *connection)
06213 {
06214   long res;
06215 
06216   _dbus_return_val_if_fail (connection != NULL, 0);
06217 
06218   CONNECTION_LOCK (connection);
06219   res = _dbus_counter_get_unix_fd_value (connection->outgoing_counter);
06220   CONNECTION_UNLOCK (connection);
06221   return res;
06222 }
06223