D-Bus  1.6.30
dbus-connection.c
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
00002 /* dbus-connection.c DBusConnection object
00003  *
00004  * Copyright (C) 2002-2006  Red Hat Inc.
00005  *
00006  * Licensed under the Academic Free License version 2.1
00007  * 
00008  * This program is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  * 
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00021  *
00022  */
00023 
00024 #include <config.h>
00025 #include "dbus-shared.h"
00026 #include "dbus-connection.h"
00027 #include "dbus-list.h"
00028 #include "dbus-timeout.h"
00029 #include "dbus-transport.h"
00030 #include "dbus-watch.h"
00031 #include "dbus-connection-internal.h"
00032 #include "dbus-pending-call-internal.h"
00033 #include "dbus-list.h"
00034 #include "dbus-hash.h"
00035 #include "dbus-message-internal.h"
00036 #include "dbus-message-private.h"
00037 #include "dbus-threads.h"
00038 #include "dbus-protocol.h"
00039 #include "dbus-dataslot.h"
00040 #include "dbus-string.h"
00041 #include "dbus-signature.h"
00042 #include "dbus-pending-call.h"
00043 #include "dbus-object-tree.h"
00044 #include "dbus-threads-internal.h"
00045 #include "dbus-bus.h"
00046 #include "dbus-marshal-basic.h"
00047 
00048 #ifdef DBUS_DISABLE_CHECKS
00049 #define TOOK_LOCK_CHECK(connection)
00050 #define RELEASING_LOCK_CHECK(connection)
00051 #define HAVE_LOCK_CHECK(connection)
00052 #else
00053 #define TOOK_LOCK_CHECK(connection) do {                \
00054     _dbus_assert (!(connection)->have_connection_lock); \
00055     (connection)->have_connection_lock = TRUE;          \
00056   } while (0)
00057 #define RELEASING_LOCK_CHECK(connection) do {            \
00058     _dbus_assert ((connection)->have_connection_lock);   \
00059     (connection)->have_connection_lock = FALSE;          \
00060   } while (0)
00061 #define HAVE_LOCK_CHECK(connection)        _dbus_assert ((connection)->have_connection_lock)
00062 /* A "DO_NOT_HAVE_LOCK_CHECK" is impossible since we need the lock to check the flag */
00063 #endif
00064 
00065 #define TRACE_LOCKS 1
00066 
00067 #define CONNECTION_LOCK(connection)   do {                                      \
00068     if (TRACE_LOCKS) { _dbus_verbose ("LOCK\n"); }   \
00069     _dbus_rmutex_lock ((connection)->mutex);                                    \
00070     TOOK_LOCK_CHECK (connection);                                               \
00071   } while (0)
00072 
00073 #define CONNECTION_UNLOCK(connection) _dbus_connection_unlock (connection)
00074 
00075 #define SLOTS_LOCK(connection) do {                     \
00076     _dbus_rmutex_lock ((connection)->slot_mutex);       \
00077   } while (0)
00078 
00079 #define SLOTS_UNLOCK(connection) do {                   \
00080     _dbus_rmutex_unlock ((connection)->slot_mutex);     \
00081   } while (0)
00082 
00083 #define DISPATCH_STATUS_NAME(s)                                            \
00084                      ((s) == DBUS_DISPATCH_COMPLETE ? "complete" :         \
00085                       (s) == DBUS_DISPATCH_DATA_REMAINS ? "data remains" : \
00086                       (s) == DBUS_DISPATCH_NEED_MEMORY ? "need memory" :   \
00087                       "???")
00088 
00206 #ifdef DBUS_ENABLE_VERBOSE_MODE
00207 static void
00208 _dbus_connection_trace_ref (DBusConnection *connection,
00209     int old_refcount,
00210     int new_refcount,
00211     const char *why)
00212 {
00213   static int enabled = -1;
00214 
00215   _dbus_trace_ref ("DBusConnection", connection, old_refcount, new_refcount,
00216       why, "DBUS_CONNECTION_TRACE", &enabled);
00217 }
00218 #else
00219 #define _dbus_connection_trace_ref(c,o,n,w) \
00220   do \
00221   {\
00222     (void) (o); \
00223     (void) (n); \
00224   } while (0)
00225 #endif
00226 
00230 typedef struct DBusMessageFilter DBusMessageFilter;
00231 
00235 struct DBusMessageFilter
00236 {
00237   DBusAtomic refcount; 
00238   DBusHandleMessageFunction function; 
00239   void *user_data; 
00240   DBusFreeFunction free_user_data_function; 
00241 };
00242 
00243 
00247 struct DBusPreallocatedSend
00248 {
00249   DBusConnection *connection; 
00250   DBusList *queue_link;       
00251   DBusList *counter_link;     
00252 };
00253 
00254 #if HAVE_DECL_MSG_NOSIGNAL
00255 static dbus_bool_t _dbus_modify_sigpipe = FALSE;
00256 #else
00257 static dbus_bool_t _dbus_modify_sigpipe = TRUE;
00258 #endif
00259 
00263 struct DBusConnection
00264 {
00265   DBusAtomic refcount; 
00267   DBusRMutex *mutex; 
00269   DBusCMutex *dispatch_mutex;     
00270   DBusCondVar *dispatch_cond;    
00271   DBusCMutex *io_path_mutex;      
00272   DBusCondVar *io_path_cond;     
00274   DBusList *outgoing_messages; 
00275   DBusList *incoming_messages; 
00276   DBusList *expired_messages;  
00278   DBusMessage *message_borrowed; 
00282   int n_outgoing;              
00283   int n_incoming;              
00285   DBusCounter *outgoing_counter; 
00287   DBusTransport *transport;    
00288   DBusWatchList *watches;      
00289   DBusTimeoutList *timeouts;   
00291   DBusList *filter_list;        
00293   DBusRMutex *slot_mutex;        
00294   DBusDataSlotList slot_list;   
00296   DBusHashTable *pending_replies;  
00298   dbus_uint32_t client_serial;       
00299   DBusList *disconnect_message_link; 
00301   DBusWakeupMainFunction wakeup_main_function; 
00302   void *wakeup_main_data; 
00303   DBusFreeFunction free_wakeup_main_data; 
00305   DBusDispatchStatusFunction dispatch_status_function; 
00306   void *dispatch_status_data; 
00307   DBusFreeFunction free_dispatch_status_data; 
00309   DBusDispatchStatus last_dispatch_status; 
00311   DBusObjectTree *objects; 
00313   char *server_guid; 
00315   /* These two MUST be bools and not bitfields, because they are protected by a separate lock
00316    * from connection->mutex and all bitfields in a word have to be read/written together.
00317    * So you can't have a different lock for different bitfields in the same word.
00318    */
00319   dbus_bool_t dispatch_acquired; 
00320   dbus_bool_t io_path_acquired;  
00322   unsigned int shareable : 1; 
00324   unsigned int exit_on_disconnect : 1; 
00326   unsigned int route_peer_messages : 1; 
00328   unsigned int disconnected_message_arrived : 1;   
00332   unsigned int disconnected_message_processed : 1; 
00336 #ifndef DBUS_DISABLE_CHECKS
00337   unsigned int have_connection_lock : 1; 
00338 #endif
00339   
00340 #ifndef DBUS_DISABLE_CHECKS
00341   int generation; 
00342 #endif 
00343 };
00344 
00345 static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked      (DBusConnection     *connection);
00346 static void               _dbus_connection_update_dispatch_status_and_unlock (DBusConnection     *connection,
00347                                                                               DBusDispatchStatus  new_status);
00348 static void               _dbus_connection_last_unref                        (DBusConnection     *connection);
00349 static void               _dbus_connection_acquire_dispatch                  (DBusConnection     *connection);
00350 static void               _dbus_connection_release_dispatch                  (DBusConnection     *connection);
00351 static DBusDispatchStatus _dbus_connection_flush_unlocked                    (DBusConnection     *connection);
00352 static void               _dbus_connection_close_possibly_shared_and_unlock  (DBusConnection     *connection);
00353 static dbus_bool_t        _dbus_connection_get_is_connected_unlocked         (DBusConnection     *connection);
00354 static dbus_bool_t        _dbus_connection_peek_for_reply_unlocked           (DBusConnection     *connection,
00355                                                                               dbus_uint32_t       client_serial);
00356 
00357 static DBusMessageFilter *
00358 _dbus_message_filter_ref (DBusMessageFilter *filter)
00359 {
00360 #ifdef DBUS_DISABLE_ASSERT
00361   _dbus_atomic_inc (&filter->refcount);
00362 #else
00363   dbus_int32_t old_value;
00364 
00365   old_value = _dbus_atomic_inc (&filter->refcount);
00366   _dbus_assert (old_value > 0);
00367 #endif
00368 
00369   return filter;
00370 }
00371 
00372 static void
00373 _dbus_message_filter_unref (DBusMessageFilter *filter)
00374 {
00375   dbus_int32_t old_value;
00376 
00377   old_value = _dbus_atomic_dec (&filter->refcount);
00378   _dbus_assert (old_value > 0);
00379 
00380   if (old_value == 1)
00381     {
00382       if (filter->free_user_data_function)
00383         (* filter->free_user_data_function) (filter->user_data);
00384       
00385       dbus_free (filter);
00386     }
00387 }
00388 
00394 void
00395 _dbus_connection_lock (DBusConnection *connection)
00396 {
00397   CONNECTION_LOCK (connection);
00398 }
00399 
00405 void
00406 _dbus_connection_unlock (DBusConnection *connection)
00407 {
00408   DBusList *expired_messages;
00409   DBusList *iter;
00410 
00411   if (TRACE_LOCKS)
00412     {
00413       _dbus_verbose ("UNLOCK\n");
00414     }
00415 
00416   /* If we had messages that expired (fell off the incoming or outgoing
00417    * queues) while we were locked, actually release them now */
00418   expired_messages = connection->expired_messages;
00419   connection->expired_messages = NULL;
00420 
00421   RELEASING_LOCK_CHECK (connection);
00422   _dbus_rmutex_unlock (connection->mutex);
00423 
00424   for (iter = _dbus_list_pop_first_link (&expired_messages);
00425       iter != NULL;
00426       iter = _dbus_list_pop_first_link (&expired_messages))
00427     {
00428       DBusMessage *message = iter->data;
00429 
00430       dbus_message_unref (message);
00431       _dbus_list_free_link (iter);
00432     }
00433 }
00434 
00442 static void
00443 _dbus_connection_wakeup_mainloop (DBusConnection *connection)
00444 {
00445   if (connection->wakeup_main_function)
00446     (*connection->wakeup_main_function) (connection->wakeup_main_data);
00447 }
00448 
00449 #ifdef DBUS_BUILD_TESTS
00450 
00462 void 
00463 _dbus_connection_test_get_locks (DBusConnection *connection,
00464                                  DBusMutex     **mutex_loc,
00465                                  DBusMutex     **dispatch_mutex_loc,
00466                                  DBusMutex     **io_path_mutex_loc,
00467                                  DBusCondVar   **dispatch_cond_loc,
00468                                  DBusCondVar   **io_path_cond_loc)
00469 {
00470   *mutex_loc = (DBusMutex *) connection->mutex;
00471   *dispatch_mutex_loc = (DBusMutex *) connection->dispatch_mutex;
00472   *io_path_mutex_loc = (DBusMutex *) connection->io_path_mutex;
00473   *dispatch_cond_loc = connection->dispatch_cond;
00474   *io_path_cond_loc = connection->io_path_cond;
00475 }
00476 #endif
00477 
00486 void
00487 _dbus_connection_queue_received_message_link (DBusConnection  *connection,
00488                                               DBusList        *link)
00489 {
00490   DBusPendingCall *pending;
00491   dbus_uint32_t reply_serial;
00492   DBusMessage *message;
00493   
00494   _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport));
00495   
00496   _dbus_list_append_link (&connection->incoming_messages,
00497                           link);
00498   message = link->data;
00499 
00500   /* If this is a reply we're waiting on, remove timeout for it */
00501   reply_serial = dbus_message_get_reply_serial (message);
00502   if (reply_serial != 0)
00503     {
00504       pending = _dbus_hash_table_lookup_int (connection->pending_replies,
00505                                              reply_serial);
00506       if (pending != NULL)
00507         {
00508           if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00509             _dbus_connection_remove_timeout_unlocked (connection,
00510                                                       _dbus_pending_call_get_timeout_unlocked (pending));
00511 
00512           _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00513         }
00514     }
00515   
00516   
00517 
00518   connection->n_incoming += 1;
00519 
00520   _dbus_connection_wakeup_mainloop (connection);
00521   
00522   _dbus_verbose ("Message %p (%s %s %s %s '%s' reply to %u) added to incoming queue %p, %d incoming\n",
00523                  message,
00524                  dbus_message_type_to_string (dbus_message_get_type (message)),
00525                  dbus_message_get_path (message) ?
00526                  dbus_message_get_path (message) :
00527                  "no path",
00528                  dbus_message_get_interface (message) ?
00529                  dbus_message_get_interface (message) :
00530                  "no interface",
00531                  dbus_message_get_member (message) ?
00532                  dbus_message_get_member (message) :
00533                  "no member",
00534                  dbus_message_get_signature (message),
00535                  dbus_message_get_reply_serial (message),
00536                  connection,
00537                  connection->n_incoming);
00538 
00539   _dbus_message_trace_ref (message, -1, -1,
00540       "_dbus_conection_queue_received_message_link");
00541 }
00542 
00551 void
00552 _dbus_connection_queue_synthesized_message_link (DBusConnection *connection,
00553                                                  DBusList *link)
00554 {
00555   HAVE_LOCK_CHECK (connection);
00556   
00557   _dbus_list_append_link (&connection->incoming_messages, link);
00558 
00559   connection->n_incoming += 1;
00560 
00561   _dbus_connection_wakeup_mainloop (connection);
00562 
00563   _dbus_message_trace_ref (link->data, -1, -1,
00564       "_dbus_connection_queue_synthesized_message_link");
00565 
00566   _dbus_verbose ("Synthesized message %p added to incoming queue %p, %d incoming\n",
00567                  link->data, connection, connection->n_incoming);
00568 }
00569 
00570 
00578 dbus_bool_t
00579 _dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection)
00580 {
00581   HAVE_LOCK_CHECK (connection);
00582   return connection->outgoing_messages != NULL;
00583 }
00584 
00594 dbus_bool_t
00595 dbus_connection_has_messages_to_send (DBusConnection *connection)
00596 {
00597   dbus_bool_t v;
00598   
00599   _dbus_return_val_if_fail (connection != NULL, FALSE);
00600 
00601   CONNECTION_LOCK (connection);
00602   v = _dbus_connection_has_messages_to_send_unlocked (connection);
00603   CONNECTION_UNLOCK (connection);
00604 
00605   return v;
00606 }
00607 
00615 DBusMessage*
00616 _dbus_connection_get_message_to_send (DBusConnection *connection)
00617 {
00618   HAVE_LOCK_CHECK (connection);
00619   
00620   return _dbus_list_get_last (&connection->outgoing_messages);
00621 }
00622 
00631 void
00632 _dbus_connection_message_sent_unlocked (DBusConnection *connection,
00633                                         DBusMessage    *message)
00634 {
00635   DBusList *link;
00636 
00637   HAVE_LOCK_CHECK (connection);
00638   
00639   /* This can be called before we even complete authentication, since
00640    * it's called on disconnect to clean up the outgoing queue.
00641    * It's also called as we successfully send each message.
00642    */
00643   
00644   link = _dbus_list_get_last_link (&connection->outgoing_messages);
00645   _dbus_assert (link != NULL);
00646   _dbus_assert (link->data == message);
00647 
00648   _dbus_list_unlink (&connection->outgoing_messages,
00649                      link);
00650   _dbus_list_prepend_link (&connection->expired_messages, link);
00651 
00652   connection->n_outgoing -= 1;
00653 
00654   _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from outgoing queue %p, %d left to send\n",
00655                  message,
00656                  dbus_message_type_to_string (dbus_message_get_type (message)),
00657                  dbus_message_get_path (message) ?
00658                  dbus_message_get_path (message) :
00659                  "no path",
00660                  dbus_message_get_interface (message) ?
00661                  dbus_message_get_interface (message) :
00662                  "no interface",
00663                  dbus_message_get_member (message) ?
00664                  dbus_message_get_member (message) :
00665                  "no member",
00666                  dbus_message_get_signature (message),
00667                  connection, connection->n_outgoing);
00668 
00669   /* It's OK that in principle we call the notify function, because for the
00670    * outgoing limit, there isn't one */
00671   _dbus_message_remove_counter (message, connection->outgoing_counter);
00672 
00673   /* The message will actually be unreffed when we unlock */
00674 }
00675 
00677 typedef dbus_bool_t (* DBusWatchAddFunction)     (DBusWatchList *list,
00678                                                   DBusWatch     *watch);
00680 typedef void        (* DBusWatchRemoveFunction)  (DBusWatchList *list,
00681                                                   DBusWatch     *watch);
00683 typedef void        (* DBusWatchToggleFunction)  (DBusWatchList *list,
00684                                                   DBusWatch     *watch,
00685                                                   dbus_bool_t    enabled);
00686 
00687 static dbus_bool_t
00688 protected_change_watch (DBusConnection         *connection,
00689                         DBusWatch              *watch,
00690                         DBusWatchAddFunction    add_function,
00691                         DBusWatchRemoveFunction remove_function,
00692                         DBusWatchToggleFunction toggle_function,
00693                         dbus_bool_t             enabled)
00694 {
00695   dbus_bool_t retval;
00696 
00697   HAVE_LOCK_CHECK (connection);
00698 
00699   /* The original purpose of protected_change_watch() was to hold a
00700    * ref on the connection while dropping the connection lock, then
00701    * calling out to the app.  This was a broken hack that did not
00702    * work, since the connection was in a hosed state (no WatchList
00703    * field) while calling out.
00704    *
00705    * So for now we'll just keep the lock while calling out. This means
00706    * apps are not allowed to call DBusConnection methods inside a
00707    * watch function or they will deadlock.
00708    *
00709    * The "real fix" is to use the _and_unlock() pattern found
00710    * elsewhere in the code, to defer calling out to the app until
00711    * we're about to drop locks and return flow of control to the app
00712    * anyway.
00713    *
00714    * See http://lists.freedesktop.org/archives/dbus/2007-July/thread.html#8144
00715    */
00716 
00717   if (connection->watches)
00718     {
00719       if (add_function)
00720         retval = (* add_function) (connection->watches, watch);
00721       else if (remove_function)
00722         {
00723           retval = TRUE;
00724           (* remove_function) (connection->watches, watch);
00725         }
00726       else
00727         {
00728           retval = TRUE;
00729           (* toggle_function) (connection->watches, watch, enabled);
00730         }
00731       return retval;
00732     }
00733   else
00734     return FALSE;
00735 }
00736      
00737 
00749 dbus_bool_t
00750 _dbus_connection_add_watch_unlocked (DBusConnection *connection,
00751                                      DBusWatch      *watch)
00752 {
00753   return protected_change_watch (connection, watch,
00754                                  _dbus_watch_list_add_watch,
00755                                  NULL, NULL, FALSE);
00756 }
00757 
00767 void
00768 _dbus_connection_remove_watch_unlocked (DBusConnection *connection,
00769                                         DBusWatch      *watch)
00770 {
00771   protected_change_watch (connection, watch,
00772                           NULL,
00773                           _dbus_watch_list_remove_watch,
00774                           NULL, FALSE);
00775 }
00776 
00787 void
00788 _dbus_connection_toggle_watch_unlocked (DBusConnection *connection,
00789                                         DBusWatch      *watch,
00790                                         dbus_bool_t     enabled)
00791 {
00792   _dbus_assert (watch != NULL);
00793 
00794   protected_change_watch (connection, watch,
00795                           NULL, NULL,
00796                           _dbus_watch_list_toggle_watch,
00797                           enabled);
00798 }
00799 
00801 typedef dbus_bool_t (* DBusTimeoutAddFunction)    (DBusTimeoutList *list,
00802                                                    DBusTimeout     *timeout);
00804 typedef void        (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list,
00805                                                    DBusTimeout     *timeout);
00807 typedef void        (* DBusTimeoutToggleFunction) (DBusTimeoutList *list,
00808                                                    DBusTimeout     *timeout,
00809                                                    dbus_bool_t      enabled);
00810 
00811 static dbus_bool_t
00812 protected_change_timeout (DBusConnection           *connection,
00813                           DBusTimeout              *timeout,
00814                           DBusTimeoutAddFunction    add_function,
00815                           DBusTimeoutRemoveFunction remove_function,
00816                           DBusTimeoutToggleFunction toggle_function,
00817                           dbus_bool_t               enabled)
00818 {
00819   dbus_bool_t retval;
00820 
00821   HAVE_LOCK_CHECK (connection);
00822 
00823   /* The original purpose of protected_change_timeout() was to hold a
00824    * ref on the connection while dropping the connection lock, then
00825    * calling out to the app.  This was a broken hack that did not
00826    * work, since the connection was in a hosed state (no TimeoutList
00827    * field) while calling out.
00828    *
00829    * So for now we'll just keep the lock while calling out. This means
00830    * apps are not allowed to call DBusConnection methods inside a
00831    * timeout function or they will deadlock.
00832    *
00833    * The "real fix" is to use the _and_unlock() pattern found
00834    * elsewhere in the code, to defer calling out to the app until
00835    * we're about to drop locks and return flow of control to the app
00836    * anyway.
00837    *
00838    * See http://lists.freedesktop.org/archives/dbus/2007-July/thread.html#8144
00839    */
00840 
00841   if (connection->timeouts)
00842     {
00843       if (add_function)
00844         retval = (* add_function) (connection->timeouts, timeout);
00845       else if (remove_function)
00846         {
00847           retval = TRUE;
00848           (* remove_function) (connection->timeouts, timeout);
00849         }
00850       else
00851         {
00852           retval = TRUE;
00853           (* toggle_function) (connection->timeouts, timeout, enabled);
00854         }
00855       return retval;
00856     }
00857   else
00858     return FALSE;
00859 }
00860 
00873 dbus_bool_t
00874 _dbus_connection_add_timeout_unlocked (DBusConnection *connection,
00875                                        DBusTimeout    *timeout)
00876 {
00877   return protected_change_timeout (connection, timeout,
00878                                    _dbus_timeout_list_add_timeout,
00879                                    NULL, NULL, FALSE);
00880 }
00881 
00891 void
00892 _dbus_connection_remove_timeout_unlocked (DBusConnection *connection,
00893                                           DBusTimeout    *timeout)
00894 {
00895   protected_change_timeout (connection, timeout,
00896                             NULL,
00897                             _dbus_timeout_list_remove_timeout,
00898                             NULL, FALSE);
00899 }
00900 
00911 void
00912 _dbus_connection_toggle_timeout_unlocked (DBusConnection   *connection,
00913                                           DBusTimeout      *timeout,
00914                                           dbus_bool_t       enabled)
00915 {
00916   protected_change_timeout (connection, timeout,
00917                             NULL, NULL,
00918                             _dbus_timeout_list_toggle_timeout,
00919                             enabled);
00920 }
00921 
00922 static dbus_bool_t
00923 _dbus_connection_attach_pending_call_unlocked (DBusConnection  *connection,
00924                                                DBusPendingCall *pending)
00925 {
00926   dbus_uint32_t reply_serial;
00927   DBusTimeout *timeout;
00928 
00929   HAVE_LOCK_CHECK (connection);
00930 
00931   reply_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
00932 
00933   _dbus_assert (reply_serial != 0);
00934 
00935   timeout = _dbus_pending_call_get_timeout_unlocked (pending);
00936 
00937   if (timeout)
00938     {
00939       if (!_dbus_connection_add_timeout_unlocked (connection, timeout))
00940         return FALSE;
00941       
00942       if (!_dbus_hash_table_insert_int (connection->pending_replies,
00943                                         reply_serial,
00944                                         pending))
00945         {
00946           _dbus_connection_remove_timeout_unlocked (connection, timeout);
00947 
00948           _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00949           HAVE_LOCK_CHECK (connection);
00950           return FALSE;
00951         }
00952       
00953       _dbus_pending_call_set_timeout_added_unlocked (pending, TRUE);
00954     }
00955   else
00956     {
00957       if (!_dbus_hash_table_insert_int (connection->pending_replies,
00958                                         reply_serial,
00959                                         pending))
00960         {
00961           HAVE_LOCK_CHECK (connection);
00962           return FALSE;
00963         }
00964     }
00965 
00966   _dbus_pending_call_ref_unlocked (pending);
00967 
00968   HAVE_LOCK_CHECK (connection);
00969   
00970   return TRUE;
00971 }
00972 
00973 static void
00974 free_pending_call_on_hash_removal (void *data)
00975 {
00976   DBusPendingCall *pending;
00977   DBusConnection  *connection;
00978   
00979   if (data == NULL)
00980     return;
00981 
00982   pending = data;
00983 
00984   connection = _dbus_pending_call_get_connection_unlocked (pending);
00985 
00986   HAVE_LOCK_CHECK (connection);
00987   
00988   if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00989     {
00990       _dbus_connection_remove_timeout_unlocked (connection,
00991                                                 _dbus_pending_call_get_timeout_unlocked (pending));
00992       
00993       _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00994     }
00995 
00996   /* FIXME 1.0? this is sort of dangerous and undesirable to drop the lock 
00997    * here, but the pending call finalizer could in principle call out to 
00998    * application code so we pretty much have to... some larger code reorg 
00999    * might be needed.
01000    */
01001   _dbus_connection_ref_unlocked (connection);
01002   _dbus_pending_call_unref_and_unlock (pending);
01003   CONNECTION_LOCK (connection);
01004   _dbus_connection_unref_unlocked (connection);
01005 }
01006 
01007 static void
01008 _dbus_connection_detach_pending_call_unlocked (DBusConnection  *connection,
01009                                                DBusPendingCall *pending)
01010 {
01011   /* This ends up unlocking to call the pending call finalizer, which is unexpected to
01012    * say the least.
01013    */
01014   _dbus_hash_table_remove_int (connection->pending_replies,
01015                                _dbus_pending_call_get_reply_serial_unlocked (pending));
01016 }
01017 
01018 static void
01019 _dbus_connection_detach_pending_call_and_unlock (DBusConnection  *connection,
01020                                                  DBusPendingCall *pending)
01021 {
01022   /* The idea here is to avoid finalizing the pending call
01023    * with the lock held, since there's a destroy notifier
01024    * in pending call that goes out to application code.
01025    *
01026    * There's an extra unlock inside the hash table
01027    * "free pending call" function FIXME...
01028    */
01029   _dbus_pending_call_ref_unlocked (pending);
01030   _dbus_hash_table_remove_int (connection->pending_replies,
01031                                _dbus_pending_call_get_reply_serial_unlocked (pending));
01032 
01033   if (_dbus_pending_call_is_timeout_added_unlocked (pending))
01034       _dbus_connection_remove_timeout_unlocked (connection,
01035               _dbus_pending_call_get_timeout_unlocked (pending));
01036 
01037   _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
01038 
01039   _dbus_pending_call_unref_and_unlock (pending);
01040 }
01041 
01050 void
01051 _dbus_connection_remove_pending_call (DBusConnection  *connection,
01052                                       DBusPendingCall *pending)
01053 {
01054   CONNECTION_LOCK (connection);
01055   _dbus_connection_detach_pending_call_and_unlock (connection, pending);
01056 }
01057 
01067 static dbus_bool_t
01068 _dbus_connection_acquire_io_path (DBusConnection *connection,
01069                                   int             timeout_milliseconds)
01070 {
01071   dbus_bool_t we_acquired;
01072   
01073   HAVE_LOCK_CHECK (connection);
01074 
01075   /* We don't want the connection to vanish */
01076   _dbus_connection_ref_unlocked (connection);
01077 
01078   /* We will only touch io_path_acquired which is protected by our mutex */
01079   CONNECTION_UNLOCK (connection);
01080   
01081   _dbus_verbose ("locking io_path_mutex\n");
01082   _dbus_cmutex_lock (connection->io_path_mutex);
01083 
01084   _dbus_verbose ("start connection->io_path_acquired = %d timeout = %d\n",
01085                  connection->io_path_acquired, timeout_milliseconds);
01086 
01087   we_acquired = FALSE;
01088   
01089   if (connection->io_path_acquired)
01090     {
01091       if (timeout_milliseconds != -1)
01092         {
01093           _dbus_verbose ("waiting %d for IO path to be acquirable\n",
01094                          timeout_milliseconds);
01095 
01096           if (!_dbus_condvar_wait_timeout (connection->io_path_cond,
01097                                            connection->io_path_mutex,
01098                                            timeout_milliseconds))
01099             {
01100               /* We timed out before anyone signaled. */
01101               /* (writing the loop to handle the !timedout case by
01102                * waiting longer if needed is a pain since dbus
01103                * wraps pthread_cond_timedwait to take a relative
01104                * time instead of absolute, something kind of stupid
01105                * on our part. for now it doesn't matter, we will just
01106                * end up back here eventually.)
01107                */
01108             }
01109         }
01110       else
01111         {
01112           while (connection->io_path_acquired)
01113             {
01114               _dbus_verbose ("waiting for IO path to be acquirable\n");
01115               _dbus_condvar_wait (connection->io_path_cond, 
01116                                   connection->io_path_mutex);
01117             }
01118         }
01119     }
01120   
01121   if (!connection->io_path_acquired)
01122     {
01123       we_acquired = TRUE;
01124       connection->io_path_acquired = TRUE;
01125     }
01126   
01127   _dbus_verbose ("end connection->io_path_acquired = %d we_acquired = %d\n",
01128                  connection->io_path_acquired, we_acquired);
01129 
01130   _dbus_verbose ("unlocking io_path_mutex\n");
01131   _dbus_cmutex_unlock (connection->io_path_mutex);
01132 
01133   CONNECTION_LOCK (connection);
01134   
01135   HAVE_LOCK_CHECK (connection);
01136 
01137   _dbus_connection_unref_unlocked (connection);
01138   
01139   return we_acquired;
01140 }
01141 
01149 static void
01150 _dbus_connection_release_io_path (DBusConnection *connection)
01151 {
01152   HAVE_LOCK_CHECK (connection);
01153   
01154   _dbus_verbose ("locking io_path_mutex\n");
01155   _dbus_cmutex_lock (connection->io_path_mutex);
01156   
01157   _dbus_assert (connection->io_path_acquired);
01158 
01159   _dbus_verbose ("start connection->io_path_acquired = %d\n",
01160                  connection->io_path_acquired);
01161   
01162   connection->io_path_acquired = FALSE;
01163   _dbus_condvar_wake_one (connection->io_path_cond);
01164 
01165   _dbus_verbose ("unlocking io_path_mutex\n");
01166   _dbus_cmutex_unlock (connection->io_path_mutex);
01167 }
01168 
01204 void
01205 _dbus_connection_do_iteration_unlocked (DBusConnection *connection,
01206                                         DBusPendingCall *pending,
01207                                         unsigned int    flags,
01208                                         int             timeout_milliseconds)
01209 {
01210   _dbus_verbose ("start\n");
01211   
01212   HAVE_LOCK_CHECK (connection);
01213   
01214   if (connection->n_outgoing == 0)
01215     flags &= ~DBUS_ITERATION_DO_WRITING;
01216 
01217   if (_dbus_connection_acquire_io_path (connection,
01218                                         (flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0))
01219     {
01220       HAVE_LOCK_CHECK (connection);
01221       
01222       if ( (pending != NULL) && _dbus_pending_call_get_completed_unlocked(pending))
01223         {
01224           _dbus_verbose ("pending call completed while acquiring I/O path");
01225         }
01226       else if ( (pending != NULL) &&
01227                 _dbus_connection_peek_for_reply_unlocked (connection,
01228                                                           _dbus_pending_call_get_reply_serial_unlocked (pending)))
01229         {
01230           _dbus_verbose ("pending call completed while acquiring I/O path (reply found in queue)");
01231         }
01232       else
01233         {
01234           _dbus_transport_do_iteration (connection->transport,
01235                                         flags, timeout_milliseconds);
01236         }
01237 
01238       _dbus_connection_release_io_path (connection);
01239     }
01240 
01241   HAVE_LOCK_CHECK (connection);
01242 
01243   _dbus_verbose ("end\n");
01244 }
01245 
01255 DBusConnection*
01256 _dbus_connection_new_for_transport (DBusTransport *transport)
01257 {
01258   DBusConnection *connection;
01259   DBusWatchList *watch_list;
01260   DBusTimeoutList *timeout_list;
01261   DBusHashTable *pending_replies;
01262   DBusList *disconnect_link;
01263   DBusMessage *disconnect_message;
01264   DBusCounter *outgoing_counter;
01265   DBusObjectTree *objects;
01266   
01267   watch_list = NULL;
01268   connection = NULL;
01269   pending_replies = NULL;
01270   timeout_list = NULL;
01271   disconnect_link = NULL;
01272   disconnect_message = NULL;
01273   outgoing_counter = NULL;
01274   objects = NULL;
01275   
01276   watch_list = _dbus_watch_list_new ();
01277   if (watch_list == NULL)
01278     goto error;
01279 
01280   timeout_list = _dbus_timeout_list_new ();
01281   if (timeout_list == NULL)
01282     goto error;  
01283 
01284   pending_replies =
01285     _dbus_hash_table_new (DBUS_HASH_INT,
01286                           NULL,
01287                           (DBusFreeFunction)free_pending_call_on_hash_removal);
01288   if (pending_replies == NULL)
01289     goto error;
01290   
01291   connection = dbus_new0 (DBusConnection, 1);
01292   if (connection == NULL)
01293     goto error;
01294 
01295   _dbus_rmutex_new_at_location (&connection->mutex);
01296   if (connection->mutex == NULL)
01297     goto error;
01298 
01299   _dbus_cmutex_new_at_location (&connection->io_path_mutex);
01300   if (connection->io_path_mutex == NULL)
01301     goto error;
01302 
01303   _dbus_cmutex_new_at_location (&connection->dispatch_mutex);
01304   if (connection->dispatch_mutex == NULL)
01305     goto error;
01306   
01307   _dbus_condvar_new_at_location (&connection->dispatch_cond);
01308   if (connection->dispatch_cond == NULL)
01309     goto error;
01310   
01311   _dbus_condvar_new_at_location (&connection->io_path_cond);
01312   if (connection->io_path_cond == NULL)
01313     goto error;
01314 
01315   _dbus_rmutex_new_at_location (&connection->slot_mutex);
01316   if (connection->slot_mutex == NULL)
01317     goto error;
01318 
01319   disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL,
01320                                                 DBUS_INTERFACE_LOCAL,
01321                                                 "Disconnected");
01322   
01323   if (disconnect_message == NULL)
01324     goto error;
01325 
01326   disconnect_link = _dbus_list_alloc_link (disconnect_message);
01327   if (disconnect_link == NULL)
01328     goto error;
01329 
01330   outgoing_counter = _dbus_counter_new ();
01331   if (outgoing_counter == NULL)
01332     goto error;
01333 
01334   objects = _dbus_object_tree_new (connection);
01335   if (objects == NULL)
01336     goto error;
01337   
01338   if (_dbus_modify_sigpipe)
01339     _dbus_disable_sigpipe ();
01340 
01341   /* initialized to 0: use atomic op to avoid mixing atomic and non-atomic */
01342   _dbus_atomic_inc (&connection->refcount);
01343   connection->transport = transport;
01344   connection->watches = watch_list;
01345   connection->timeouts = timeout_list;
01346   connection->pending_replies = pending_replies;
01347   connection->outgoing_counter = outgoing_counter;
01348   connection->filter_list = NULL;
01349   connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE; /* so we're notified first time there's data */
01350   connection->objects = objects;
01351   connection->exit_on_disconnect = FALSE;
01352   connection->shareable = FALSE;
01353   connection->route_peer_messages = FALSE;
01354   connection->disconnected_message_arrived = FALSE;
01355   connection->disconnected_message_processed = FALSE;
01356   
01357 #ifndef DBUS_DISABLE_CHECKS
01358   connection->generation = _dbus_current_generation;
01359 #endif
01360   
01361   _dbus_data_slot_list_init (&connection->slot_list);
01362 
01363   connection->client_serial = 1;
01364 
01365   connection->disconnect_message_link = disconnect_link;
01366 
01367   CONNECTION_LOCK (connection);
01368   
01369   if (!_dbus_transport_set_connection (transport, connection))
01370     {
01371       CONNECTION_UNLOCK (connection);
01372 
01373       goto error;
01374     }
01375 
01376   _dbus_transport_ref (transport);
01377 
01378   CONNECTION_UNLOCK (connection);
01379 
01380   _dbus_connection_trace_ref (connection, 0, 1, "new_for_transport");
01381   return connection;
01382   
01383  error:
01384   if (disconnect_message != NULL)
01385     dbus_message_unref (disconnect_message);
01386   
01387   if (disconnect_link != NULL)
01388     _dbus_list_free_link (disconnect_link);
01389   
01390   if (connection != NULL)
01391     {
01392       _dbus_condvar_free_at_location (&connection->io_path_cond);
01393       _dbus_condvar_free_at_location (&connection->dispatch_cond);
01394       _dbus_rmutex_free_at_location (&connection->mutex);
01395       _dbus_cmutex_free_at_location (&connection->io_path_mutex);
01396       _dbus_cmutex_free_at_location (&connection->dispatch_mutex);
01397       _dbus_rmutex_free_at_location (&connection->slot_mutex);
01398       dbus_free (connection);
01399     }
01400   if (pending_replies)
01401     _dbus_hash_table_unref (pending_replies);
01402   
01403   if (watch_list)
01404     _dbus_watch_list_free (watch_list);
01405 
01406   if (timeout_list)
01407     _dbus_timeout_list_free (timeout_list);
01408 
01409   if (outgoing_counter)
01410     _dbus_counter_unref (outgoing_counter);
01411 
01412   if (objects)
01413     _dbus_object_tree_unref (objects);
01414   
01415   return NULL;
01416 }
01417 
01425 DBusConnection *
01426 _dbus_connection_ref_unlocked (DBusConnection *connection)
01427 {
01428   dbus_int32_t old_refcount;
01429 
01430   _dbus_assert (connection != NULL);
01431   _dbus_assert (connection->generation == _dbus_current_generation);
01432 
01433   HAVE_LOCK_CHECK (connection);
01434 
01435   old_refcount = _dbus_atomic_inc (&connection->refcount);
01436   _dbus_connection_trace_ref (connection, old_refcount, old_refcount + 1,
01437       "ref_unlocked");
01438 
01439   return connection;
01440 }
01441 
01448 void
01449 _dbus_connection_unref_unlocked (DBusConnection *connection)
01450 {
01451   dbus_int32_t old_refcount;
01452 
01453   HAVE_LOCK_CHECK (connection);
01454 
01455   _dbus_assert (connection != NULL);
01456 
01457   old_refcount = _dbus_atomic_dec (&connection->refcount);
01458 
01459   _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1,
01460       "unref_unlocked");
01461 
01462   if (old_refcount == 1)
01463     _dbus_connection_last_unref (connection);
01464 }
01465 
01466 static dbus_uint32_t
01467 _dbus_connection_get_next_client_serial (DBusConnection *connection)
01468 {
01469   dbus_uint32_t serial;
01470 
01471   serial = connection->client_serial++;
01472 
01473   if (connection->client_serial == 0)
01474     connection->client_serial = 1;
01475 
01476   return serial;
01477 }
01478 
01492 dbus_bool_t
01493 _dbus_connection_handle_watch (DBusWatch                   *watch,
01494                                unsigned int                 condition,
01495                                void                        *data)
01496 {
01497   DBusConnection *connection;
01498   dbus_bool_t retval;
01499   DBusDispatchStatus status;
01500 
01501   connection = data;
01502 
01503   _dbus_verbose ("start\n");
01504   
01505   CONNECTION_LOCK (connection);
01506 
01507   if (!_dbus_connection_acquire_io_path (connection, 1))
01508     {
01509       /* another thread is handling the message */
01510       CONNECTION_UNLOCK (connection);
01511       return TRUE;
01512     }
01513 
01514   HAVE_LOCK_CHECK (connection);
01515   retval = _dbus_transport_handle_watch (connection->transport,
01516                                          watch, condition);
01517 
01518   _dbus_connection_release_io_path (connection);
01519 
01520   HAVE_LOCK_CHECK (connection);
01521 
01522   _dbus_verbose ("middle\n");
01523   
01524   status = _dbus_connection_get_dispatch_status_unlocked (connection);
01525 
01526   /* this calls out to user code */
01527   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01528 
01529   _dbus_verbose ("end\n");
01530   
01531   return retval;
01532 }
01533 
01534 _DBUS_DEFINE_GLOBAL_LOCK (shared_connections);
01535 static DBusHashTable *shared_connections = NULL;
01536 static DBusList *shared_connections_no_guid = NULL;
01537 
01538 static void
01539 close_connection_on_shutdown (DBusConnection *connection)
01540 {
01541   DBusMessage *message;
01542 
01543   dbus_connection_ref (connection);
01544   _dbus_connection_close_possibly_shared (connection);
01545 
01546   /* Churn through to the Disconnected message */
01547   while ((message = dbus_connection_pop_message (connection)))
01548     {
01549       dbus_message_unref (message);
01550     }
01551   dbus_connection_unref (connection);
01552 }
01553 
01554 static void
01555 shared_connections_shutdown (void *data)
01556 {
01557   int n_entries;
01558   
01559   _DBUS_LOCK (shared_connections);
01560   
01561   /* This is a little bit unpleasant... better ideas? */
01562   while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0)
01563     {
01564       DBusConnection *connection;
01565       DBusHashIter iter;
01566       
01567       _dbus_hash_iter_init (shared_connections, &iter);
01568       _dbus_hash_iter_next (&iter);
01569        
01570       connection = _dbus_hash_iter_get_value (&iter);
01571 
01572       _DBUS_UNLOCK (shared_connections);
01573       close_connection_on_shutdown (connection);
01574       _DBUS_LOCK (shared_connections);
01575 
01576       /* The connection should now be dead and not in our hash ... */
01577       _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) < n_entries);
01578     }
01579 
01580   _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) == 0);
01581   
01582   _dbus_hash_table_unref (shared_connections);
01583   shared_connections = NULL;
01584 
01585   if (shared_connections_no_guid != NULL)
01586     {
01587       DBusConnection *connection;
01588       connection = _dbus_list_pop_first (&shared_connections_no_guid);
01589       while (connection != NULL)
01590         {
01591           _DBUS_UNLOCK (shared_connections);
01592           close_connection_on_shutdown (connection);
01593           _DBUS_LOCK (shared_connections);
01594           connection = _dbus_list_pop_first (&shared_connections_no_guid);
01595         }
01596     }
01597 
01598   shared_connections_no_guid = NULL;
01599   
01600   _DBUS_UNLOCK (shared_connections);
01601 }
01602 
01603 static dbus_bool_t
01604 connection_lookup_shared (DBusAddressEntry  *entry,
01605                           DBusConnection   **result)
01606 {
01607   _dbus_verbose ("checking for existing connection\n");
01608   
01609   *result = NULL;
01610   
01611   _DBUS_LOCK (shared_connections);
01612 
01613   if (shared_connections == NULL)
01614     {
01615       _dbus_verbose ("creating shared_connections hash table\n");
01616       
01617       shared_connections = _dbus_hash_table_new (DBUS_HASH_STRING,
01618                                                  dbus_free,
01619                                                  NULL);
01620       if (shared_connections == NULL)
01621         {
01622           _DBUS_UNLOCK (shared_connections);
01623           return FALSE;
01624         }
01625 
01626       if (!_dbus_register_shutdown_func (shared_connections_shutdown, NULL))
01627         {
01628           _dbus_hash_table_unref (shared_connections);
01629           shared_connections = NULL;
01630           _DBUS_UNLOCK (shared_connections);
01631           return FALSE;
01632         }
01633 
01634       _dbus_verbose ("  successfully created shared_connections\n");
01635       
01636       _DBUS_UNLOCK (shared_connections);
01637       return TRUE; /* no point looking up in the hash we just made */
01638     }
01639   else
01640     {
01641       const char *guid;
01642 
01643       guid = dbus_address_entry_get_value (entry, "guid");
01644       
01645       if (guid != NULL)
01646         {
01647           DBusConnection *connection;
01648           
01649           connection = _dbus_hash_table_lookup_string (shared_connections,
01650                                                        guid);
01651 
01652           if (connection)
01653             {
01654               /* The DBusConnection can't be finalized without taking
01655                * the shared_connections lock to remove it from the
01656                * hash.  So it's safe to ref the connection here.
01657                * However, it may be disconnected if the Disconnected
01658                * message hasn't been processed yet, in which case we
01659                * want to pretend it isn't in the hash and avoid
01660                * returning it.
01661                *
01662                * The idea is to avoid ever returning a disconnected connection
01663                * from dbus_connection_open(). We could just synchronously
01664                * drop our shared ref to the connection on connection disconnect,
01665                * and then assert here that the connection is connected, but
01666                * that causes reentrancy headaches.
01667                */
01668               CONNECTION_LOCK (connection);
01669               if (_dbus_connection_get_is_connected_unlocked (connection))
01670                 {
01671                   _dbus_connection_ref_unlocked (connection);
01672                   *result = connection;
01673                   _dbus_verbose ("looked up existing connection to server guid %s\n",
01674                                  guid);
01675                 }
01676               else
01677                 {
01678                   _dbus_verbose ("looked up existing connection to server guid %s but it was disconnected so ignoring it\n",
01679                                  guid);
01680                 }
01681               CONNECTION_UNLOCK (connection);
01682             }
01683         }
01684       
01685       _DBUS_UNLOCK (shared_connections);
01686       return TRUE;
01687     }
01688 }
01689 
01690 static dbus_bool_t
01691 connection_record_shared_unlocked (DBusConnection *connection,
01692                                    const char     *guid)
01693 {
01694   char *guid_key;
01695   char *guid_in_connection;
01696 
01697   HAVE_LOCK_CHECK (connection);
01698   _dbus_assert (connection->server_guid == NULL);
01699   _dbus_assert (connection->shareable);
01700 
01701   /* get a hard ref on this connection, even if
01702    * we won't in fact store it in the hash, we still
01703    * need to hold a ref on it until it's disconnected.
01704    */
01705   _dbus_connection_ref_unlocked (connection);
01706 
01707   if (guid == NULL)
01708     {
01709       _DBUS_LOCK (shared_connections);
01710 
01711       if (!_dbus_list_prepend (&shared_connections_no_guid, connection))
01712         {
01713           _DBUS_UNLOCK (shared_connections);
01714           return FALSE;
01715         }
01716 
01717       _DBUS_UNLOCK (shared_connections);
01718       return TRUE; /* don't store in the hash */
01719     }
01720   
01721   /* A separate copy of the key is required in the hash table, because
01722    * we don't have a lock on the connection when we are doing a hash
01723    * lookup.
01724    */
01725   
01726   guid_key = _dbus_strdup (guid);
01727   if (guid_key == NULL)
01728     return FALSE;
01729 
01730   guid_in_connection = _dbus_strdup (guid);
01731   if (guid_in_connection == NULL)
01732     {
01733       dbus_free (guid_key);
01734       return FALSE;
01735     }
01736   
01737   _DBUS_LOCK (shared_connections);
01738   _dbus_assert (shared_connections != NULL);
01739   
01740   if (!_dbus_hash_table_insert_string (shared_connections,
01741                                        guid_key, connection))
01742     {
01743       dbus_free (guid_key);
01744       dbus_free (guid_in_connection);
01745       _DBUS_UNLOCK (shared_connections);
01746       return FALSE;
01747     }
01748 
01749   connection->server_guid = guid_in_connection;
01750 
01751   _dbus_verbose ("stored connection to %s to be shared\n",
01752                  connection->server_guid);
01753   
01754   _DBUS_UNLOCK (shared_connections);
01755 
01756   _dbus_assert (connection->server_guid != NULL);
01757   
01758   return TRUE;
01759 }
01760 
01761 static void
01762 connection_forget_shared_unlocked (DBusConnection *connection)
01763 {
01764   HAVE_LOCK_CHECK (connection);
01765 
01766   if (!connection->shareable)
01767     return;
01768   
01769   _DBUS_LOCK (shared_connections);
01770       
01771   if (connection->server_guid != NULL)
01772     {
01773       _dbus_verbose ("dropping connection to %s out of the shared table\n",
01774                      connection->server_guid);
01775       
01776       if (!_dbus_hash_table_remove_string (shared_connections,
01777                                            connection->server_guid))
01778         _dbus_assert_not_reached ("connection was not in the shared table");
01779       
01780       dbus_free (connection->server_guid);
01781       connection->server_guid = NULL;
01782     }
01783   else
01784     {
01785       _dbus_list_remove (&shared_connections_no_guid, connection);
01786     }
01787 
01788   _DBUS_UNLOCK (shared_connections);
01789   
01790   /* remove our reference held on all shareable connections */
01791   _dbus_connection_unref_unlocked (connection);
01792 }
01793 
01794 static DBusConnection*
01795 connection_try_from_address_entry (DBusAddressEntry *entry,
01796                                    DBusError        *error)
01797 {
01798   DBusTransport *transport;
01799   DBusConnection *connection;
01800 
01801   transport = _dbus_transport_open (entry, error);
01802 
01803   if (transport == NULL)
01804     {
01805       _DBUS_ASSERT_ERROR_IS_SET (error);
01806       return NULL;
01807     }
01808 
01809   connection = _dbus_connection_new_for_transport (transport);
01810 
01811   _dbus_transport_unref (transport);
01812   
01813   if (connection == NULL)
01814     {
01815       _DBUS_SET_OOM (error);
01816       return NULL;
01817     }
01818 
01819 #ifndef DBUS_DISABLE_CHECKS
01820   _dbus_assert (!connection->have_connection_lock);
01821 #endif
01822   return connection;
01823 }
01824 
01825 /*
01826  * If the shared parameter is true, then any existing connection will
01827  * be used (and if a new connection is created, it will be available
01828  * for use by others). If the shared parameter is false, a new
01829  * connection will always be created, and the new connection will
01830  * never be returned to other callers.
01831  *
01832  * @param address the address
01833  * @param shared whether the connection is shared or private
01834  * @param error error return
01835  * @returns the connection or #NULL on error
01836  */
01837 static DBusConnection*
01838 _dbus_connection_open_internal (const char     *address,
01839                                 dbus_bool_t     shared,
01840                                 DBusError      *error)
01841 {
01842   DBusConnection *connection;
01843   DBusAddressEntry **entries;
01844   DBusError tmp_error = DBUS_ERROR_INIT;
01845   DBusError first_error = DBUS_ERROR_INIT;
01846   int len, i;
01847 
01848   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01849 
01850   _dbus_verbose ("opening %s connection to: %s\n",
01851                  shared ? "shared" : "private", address);
01852   
01853   if (!dbus_parse_address (address, &entries, &len, error))
01854     return NULL;
01855 
01856   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01857   
01858   connection = NULL;
01859 
01860   for (i = 0; i < len; i++)
01861     {
01862       if (shared)
01863         {
01864           if (!connection_lookup_shared (entries[i], &connection))
01865             _DBUS_SET_OOM (&tmp_error);
01866         }
01867 
01868       if (connection == NULL)
01869         {
01870           connection = connection_try_from_address_entry (entries[i],
01871                                                           &tmp_error);
01872 
01873           if (connection != NULL && shared)
01874             {
01875               const char *guid;
01876                   
01877               connection->shareable = TRUE;
01878                   
01879               /* guid may be NULL */
01880               guid = dbus_address_entry_get_value (entries[i], "guid");
01881                   
01882               CONNECTION_LOCK (connection);
01883           
01884               if (!connection_record_shared_unlocked (connection, guid))
01885                 {
01886                   _DBUS_SET_OOM (&tmp_error);
01887                   _dbus_connection_close_possibly_shared_and_unlock (connection);
01888                   dbus_connection_unref (connection);
01889                   connection = NULL;
01890                 }
01891               else
01892                 CONNECTION_UNLOCK (connection);
01893             }
01894         }
01895       
01896       if (connection)
01897         break;
01898 
01899       _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
01900       
01901       if (i == 0)
01902         dbus_move_error (&tmp_error, &first_error);
01903       else
01904         dbus_error_free (&tmp_error);
01905     }
01906   
01907   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01908   _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
01909   
01910   if (connection == NULL)
01911     {
01912       _DBUS_ASSERT_ERROR_IS_SET (&first_error);
01913       dbus_move_error (&first_error, error);
01914     }
01915   else
01916     dbus_error_free (&first_error);
01917   
01918   dbus_address_entries_free (entries);
01919   return connection;
01920 }
01921 
01930 void
01931 _dbus_connection_close_possibly_shared (DBusConnection *connection)
01932 {
01933   _dbus_assert (connection != NULL);
01934   _dbus_assert (connection->generation == _dbus_current_generation);
01935 
01936   CONNECTION_LOCK (connection);
01937   _dbus_connection_close_possibly_shared_and_unlock (connection);
01938 }
01939 
01940 static DBusPreallocatedSend*
01941 _dbus_connection_preallocate_send_unlocked (DBusConnection *connection)
01942 {
01943   DBusPreallocatedSend *preallocated;
01944 
01945   HAVE_LOCK_CHECK (connection);
01946   
01947   _dbus_assert (connection != NULL);
01948   
01949   preallocated = dbus_new (DBusPreallocatedSend, 1);
01950   if (preallocated == NULL)
01951     return NULL;
01952 
01953   preallocated->queue_link = _dbus_list_alloc_link (NULL);
01954   if (preallocated->queue_link == NULL)
01955     goto failed_0;
01956 
01957   preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter);
01958   if (preallocated->counter_link == NULL)
01959     goto failed_1;
01960 
01961   _dbus_counter_ref (preallocated->counter_link->data);
01962 
01963   preallocated->connection = connection;
01964   
01965   return preallocated;
01966   
01967  failed_1:
01968   _dbus_list_free_link (preallocated->queue_link);
01969  failed_0:
01970   dbus_free (preallocated);
01971   
01972   return NULL;
01973 }
01974 
01975 /* Called with lock held, does not update dispatch status */
01976 static void
01977 _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection       *connection,
01978                                                        DBusPreallocatedSend *preallocated,
01979                                                        DBusMessage          *message,
01980                                                        dbus_uint32_t        *client_serial)
01981 {
01982   dbus_uint32_t serial;
01983 
01984   preallocated->queue_link->data = message;
01985   _dbus_list_prepend_link (&connection->outgoing_messages,
01986                            preallocated->queue_link);
01987 
01988   /* It's OK that we'll never call the notify function, because for the
01989    * outgoing limit, there isn't one */
01990   _dbus_message_add_counter_link (message,
01991                                   preallocated->counter_link);
01992 
01993   dbus_free (preallocated);
01994   preallocated = NULL;
01995   
01996   dbus_message_ref (message);
01997   
01998   connection->n_outgoing += 1;
01999 
02000   _dbus_verbose ("Message %p (%s %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
02001                  message,
02002                  dbus_message_type_to_string (dbus_message_get_type (message)),
02003                  dbus_message_get_path (message) ?
02004                  dbus_message_get_path (message) :
02005                  "no path",
02006                  dbus_message_get_interface (message) ?
02007                  dbus_message_get_interface (message) :
02008                  "no interface",
02009                  dbus_message_get_member (message) ?
02010                  dbus_message_get_member (message) :
02011                  "no member",
02012                  dbus_message_get_signature (message),
02013                  dbus_message_get_destination (message) ?
02014                  dbus_message_get_destination (message) :
02015                  "null",
02016                  connection,
02017                  connection->n_outgoing);
02018 
02019   if (dbus_message_get_serial (message) == 0)
02020     {
02021       serial = _dbus_connection_get_next_client_serial (connection);
02022       dbus_message_set_serial (message, serial);
02023       if (client_serial)
02024         *client_serial = serial;
02025     }
02026   else
02027     {
02028       if (client_serial)
02029         *client_serial = dbus_message_get_serial (message);
02030     }
02031 
02032   _dbus_verbose ("Message %p serial is %u\n",
02033                  message, dbus_message_get_serial (message));
02034   
02035   dbus_message_lock (message);
02036 
02037   /* Now we need to run an iteration to hopefully just write the messages
02038    * out immediately, and otherwise get them queued up
02039    */
02040   _dbus_connection_do_iteration_unlocked (connection,
02041                                           NULL,
02042                                           DBUS_ITERATION_DO_WRITING,
02043                                           -1);
02044 
02045   /* If stuff is still queued up, be sure we wake up the main loop */
02046   if (connection->n_outgoing > 0)
02047     _dbus_connection_wakeup_mainloop (connection);
02048 }
02049 
02050 static void
02051 _dbus_connection_send_preallocated_and_unlock (DBusConnection       *connection,
02052                                                DBusPreallocatedSend *preallocated,
02053                                                DBusMessage          *message,
02054                                                dbus_uint32_t        *client_serial)
02055 {
02056   DBusDispatchStatus status;
02057 
02058   HAVE_LOCK_CHECK (connection);
02059   
02060   _dbus_connection_send_preallocated_unlocked_no_update (connection,
02061                                                          preallocated,
02062                                                          message, client_serial);
02063 
02064   _dbus_verbose ("middle\n");
02065   status = _dbus_connection_get_dispatch_status_unlocked (connection);
02066 
02067   /* this calls out to user code */
02068   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02069 }
02070 
02080 dbus_bool_t
02081 _dbus_connection_send_and_unlock (DBusConnection *connection,
02082                                   DBusMessage    *message,
02083                                   dbus_uint32_t  *client_serial)
02084 {
02085   DBusPreallocatedSend *preallocated;
02086 
02087   _dbus_assert (connection != NULL);
02088   _dbus_assert (message != NULL);
02089   
02090   preallocated = _dbus_connection_preallocate_send_unlocked (connection);
02091   if (preallocated == NULL)
02092     {
02093       CONNECTION_UNLOCK (connection);
02094       return FALSE;
02095     }
02096 
02097   _dbus_connection_send_preallocated_and_unlock (connection,
02098                                                  preallocated,
02099                                                  message,
02100                                                  client_serial);
02101   return TRUE;
02102 }
02103 
02128 void
02129 _dbus_connection_close_if_only_one_ref (DBusConnection *connection)
02130 {
02131   dbus_int32_t refcount;
02132 
02133   CONNECTION_LOCK (connection);
02134 
02135   refcount = _dbus_atomic_get (&connection->refcount);
02136   /* The caller should have at least one ref */
02137   _dbus_assert (refcount >= 1);
02138 
02139   if (refcount == 1)
02140     _dbus_connection_close_possibly_shared_and_unlock (connection);
02141   else
02142     CONNECTION_UNLOCK (connection);
02143 }
02144 
02145 
02155 static void
02156 _dbus_memory_pause_based_on_timeout (int timeout_milliseconds)
02157 {
02158   if (timeout_milliseconds == -1)
02159     _dbus_sleep_milliseconds (1000);
02160   else if (timeout_milliseconds < 100)
02161     ; /* just busy loop */
02162   else if (timeout_milliseconds <= 1000)
02163     _dbus_sleep_milliseconds (timeout_milliseconds / 3);
02164   else
02165     _dbus_sleep_milliseconds (1000);
02166 }
02167 
02168 static DBusMessage *
02169 generate_local_error_message (dbus_uint32_t serial, 
02170                               char *error_name, 
02171                               char *error_msg)
02172 {
02173   DBusMessage *message;
02174   message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
02175   if (!message)
02176     goto out;
02177 
02178   if (!dbus_message_set_error_name (message, error_name))
02179     {
02180       dbus_message_unref (message);
02181       message = NULL;
02182       goto out; 
02183     }
02184 
02185   dbus_message_set_no_reply (message, TRUE); 
02186 
02187   if (!dbus_message_set_reply_serial (message,
02188                                       serial))
02189     {
02190       dbus_message_unref (message);
02191       message = NULL;
02192       goto out;
02193     }
02194 
02195   if (error_msg != NULL)
02196     {
02197       DBusMessageIter iter;
02198 
02199       dbus_message_iter_init_append (message, &iter);
02200       if (!dbus_message_iter_append_basic (&iter,
02201                                            DBUS_TYPE_STRING,
02202                                            &error_msg))
02203         {
02204           dbus_message_unref (message);
02205           message = NULL;
02206           goto out;
02207         }
02208     }
02209 
02210  out:
02211   return message;
02212 }
02213 
02214 /*
02215  * Peek the incoming queue to see if we got reply for a specific serial
02216  */
02217 static dbus_bool_t
02218 _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection,
02219                                           dbus_uint32_t   client_serial)
02220 {
02221   DBusList *link;
02222   HAVE_LOCK_CHECK (connection);
02223 
02224   link = _dbus_list_get_first_link (&connection->incoming_messages);
02225 
02226   while (link != NULL)
02227     {
02228       DBusMessage *reply = link->data;
02229 
02230       if (dbus_message_get_reply_serial (reply) == client_serial)
02231         {
02232           _dbus_verbose ("%s reply to %d found in queue\n", _DBUS_FUNCTION_NAME, client_serial);
02233           return TRUE;
02234         }
02235       link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02236     }
02237 
02238   return FALSE;
02239 }
02240 
02241 /* This is slightly strange since we can pop a message here without
02242  * the dispatch lock.
02243  */
02244 static DBusMessage*
02245 check_for_reply_unlocked (DBusConnection *connection,
02246                           dbus_uint32_t   client_serial)
02247 {
02248   DBusList *link;
02249 
02250   HAVE_LOCK_CHECK (connection);
02251   
02252   link = _dbus_list_get_first_link (&connection->incoming_messages);
02253 
02254   while (link != NULL)
02255     {
02256       DBusMessage *reply = link->data;
02257 
02258       if (dbus_message_get_reply_serial (reply) == client_serial)
02259         {
02260           _dbus_list_remove_link (&connection->incoming_messages, link);
02261           connection->n_incoming  -= 1;
02262           return reply;
02263         }
02264       link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02265     }
02266 
02267   return NULL;
02268 }
02269 
02270 static void
02271 connection_timeout_and_complete_all_pending_calls_unlocked (DBusConnection *connection)
02272 {
02273    /* We can't iterate over the hash in the normal way since we'll be
02274     * dropping the lock for each item. So we restart the
02275     * iter each time as we drain the hash table.
02276     */
02277    
02278    while (_dbus_hash_table_get_n_entries (connection->pending_replies) > 0)
02279     {
02280       DBusPendingCall *pending;
02281       DBusHashIter iter;
02282       
02283       _dbus_hash_iter_init (connection->pending_replies, &iter);
02284       _dbus_hash_iter_next (&iter);
02285        
02286       pending = _dbus_hash_iter_get_value (&iter);
02287       _dbus_pending_call_ref_unlocked (pending);
02288        
02289       _dbus_pending_call_queue_timeout_error_unlocked (pending, 
02290                                                        connection);
02291 
02292       if (_dbus_pending_call_is_timeout_added_unlocked (pending))
02293           _dbus_connection_remove_timeout_unlocked (connection,
02294                                                     _dbus_pending_call_get_timeout_unlocked (pending));
02295       _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);       
02296       _dbus_hash_iter_remove_entry (&iter);
02297 
02298       _dbus_pending_call_unref_and_unlock (pending);
02299       CONNECTION_LOCK (connection);
02300     }
02301   HAVE_LOCK_CHECK (connection);
02302 }
02303 
02304 static void
02305 complete_pending_call_and_unlock (DBusConnection  *connection,
02306                                   DBusPendingCall *pending,
02307                                   DBusMessage     *message)
02308 {
02309   _dbus_pending_call_set_reply_unlocked (pending, message);
02310   _dbus_pending_call_ref_unlocked (pending); /* in case there's no app with a ref held */
02311   _dbus_connection_detach_pending_call_and_unlock (connection, pending);
02312  
02313   /* Must be called unlocked since it invokes app callback */
02314   _dbus_pending_call_complete (pending);
02315   dbus_pending_call_unref (pending);
02316 }
02317 
02318 static dbus_bool_t
02319 check_for_reply_and_update_dispatch_unlocked (DBusConnection  *connection,
02320                                               DBusPendingCall *pending)
02321 {
02322   DBusMessage *reply;
02323   DBusDispatchStatus status;
02324 
02325   reply = check_for_reply_unlocked (connection, 
02326                                     _dbus_pending_call_get_reply_serial_unlocked (pending));
02327   if (reply != NULL)
02328     {
02329       _dbus_verbose ("checked for reply\n");
02330 
02331       _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
02332 
02333       complete_pending_call_and_unlock (connection, pending, reply);
02334       dbus_message_unref (reply);
02335 
02336       CONNECTION_LOCK (connection);
02337       status = _dbus_connection_get_dispatch_status_unlocked (connection);
02338       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02339       dbus_pending_call_unref (pending);
02340 
02341       return TRUE;
02342     }
02343 
02344   return FALSE;
02345 }
02346 
02361 void
02362 _dbus_connection_block_pending_call (DBusPendingCall *pending)
02363 {
02364   long start_tv_sec, start_tv_usec;
02365   long tv_sec, tv_usec;
02366   DBusDispatchStatus status;
02367   DBusConnection *connection;
02368   dbus_uint32_t client_serial;
02369   DBusTimeout *timeout;
02370   int timeout_milliseconds, elapsed_milliseconds;
02371 
02372   _dbus_assert (pending != NULL);
02373 
02374   if (dbus_pending_call_get_completed (pending))
02375     return;
02376 
02377   dbus_pending_call_ref (pending); /* necessary because the call could be canceled */
02378 
02379   connection = _dbus_pending_call_get_connection_and_lock (pending);
02380   
02381   /* Flush message queue - note, can affect dispatch status */
02382   _dbus_connection_flush_unlocked (connection);
02383 
02384   client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
02385 
02386   /* note that timeout_milliseconds is limited to a smallish value
02387    * in _dbus_pending_call_new() so overflows aren't possible
02388    * below
02389    */
02390   timeout = _dbus_pending_call_get_timeout_unlocked (pending);
02391   _dbus_get_monotonic_time (&start_tv_sec, &start_tv_usec);
02392   if (timeout)
02393     {
02394       timeout_milliseconds = dbus_timeout_get_interval (timeout);
02395 
02396       _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec\n",
02397                      timeout_milliseconds,
02398                      client_serial,
02399                      start_tv_sec, start_tv_usec);
02400     }
02401   else
02402     {
02403       timeout_milliseconds = -1;
02404 
02405       _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block for reply serial %u\n", client_serial);
02406     }
02407 
02408   /* check to see if we already got the data off the socket */
02409   /* from another blocked pending call */
02410   if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02411     return;
02412 
02413   /* Now we wait... */
02414   /* always block at least once as we know we don't have the reply yet */
02415   _dbus_connection_do_iteration_unlocked (connection,
02416                                           pending,
02417                                           DBUS_ITERATION_DO_READING |
02418                                           DBUS_ITERATION_BLOCK,
02419                                           timeout_milliseconds);
02420 
02421  recheck_status:
02422 
02423   _dbus_verbose ("top of recheck\n");
02424   
02425   HAVE_LOCK_CHECK (connection);
02426   
02427   /* queue messages and get status */
02428 
02429   status = _dbus_connection_get_dispatch_status_unlocked (connection);
02430 
02431   /* the get_completed() is in case a dispatch() while we were blocking
02432    * got the reply instead of us.
02433    */
02434   if (_dbus_pending_call_get_completed_unlocked (pending))
02435     {
02436       _dbus_verbose ("Pending call completed by dispatch\n");
02437       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02438       dbus_pending_call_unref (pending);
02439       return;
02440     }
02441   
02442   if (status == DBUS_DISPATCH_DATA_REMAINS)
02443     {
02444       if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02445         return;
02446     }
02447   
02448   _dbus_get_monotonic_time (&tv_sec, &tv_usec);
02449   elapsed_milliseconds = (tv_sec - start_tv_sec) * 1000 +
02450           (tv_usec - start_tv_usec) / 1000;
02451   
02452   if (!_dbus_connection_get_is_connected_unlocked (connection))
02453     {
02454       DBusMessage *error_msg;
02455 
02456       error_msg = generate_local_error_message (client_serial,
02457                                                 DBUS_ERROR_DISCONNECTED, 
02458                                                 "Connection was disconnected before a reply was received"); 
02459 
02460       /* on OOM error_msg is set to NULL */
02461       complete_pending_call_and_unlock (connection, pending, error_msg);
02462       dbus_pending_call_unref (pending);
02463       return;
02464     }
02465   else if (connection->disconnect_message_link == NULL)
02466     _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
02467   else if (timeout == NULL)
02468     {
02469        if (status == DBUS_DISPATCH_NEED_MEMORY)
02470         {
02471           /* Try sleeping a bit, as we aren't sure we need to block for reading,
02472            * we may already have a reply in the buffer and just can't process
02473            * it.
02474            */
02475           _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02476 
02477           _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
02478         }
02479       else
02480         {          
02481           /* block again, we don't have the reply buffered yet. */
02482           _dbus_connection_do_iteration_unlocked (connection,
02483                                                   pending,
02484                                                   DBUS_ITERATION_DO_READING |
02485                                                   DBUS_ITERATION_BLOCK,
02486                                                   timeout_milliseconds - elapsed_milliseconds);
02487         }
02488 
02489       goto recheck_status;
02490     }
02491   else if (tv_sec < start_tv_sec)
02492     _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
02493   else if (elapsed_milliseconds < timeout_milliseconds)
02494     {
02495       _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds - elapsed_milliseconds);
02496       
02497       if (status == DBUS_DISPATCH_NEED_MEMORY)
02498         {
02499           /* Try sleeping a bit, as we aren't sure we need to block for reading,
02500            * we may already have a reply in the buffer and just can't process
02501            * it.
02502            */
02503           _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02504 
02505           _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
02506         }
02507       else
02508         {          
02509           /* block again, we don't have the reply buffered yet. */
02510           _dbus_connection_do_iteration_unlocked (connection,
02511                                                   NULL,
02512                                                   DBUS_ITERATION_DO_READING |
02513                                                   DBUS_ITERATION_BLOCK,
02514                                                   timeout_milliseconds - elapsed_milliseconds);
02515         }
02516 
02517       goto recheck_status;
02518     }
02519 
02520   _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %d milliseconds and got no reply\n",
02521                  elapsed_milliseconds);
02522 
02523   _dbus_assert (!_dbus_pending_call_get_completed_unlocked (pending));
02524   
02525   /* unlock and call user code */
02526   complete_pending_call_and_unlock (connection, pending, NULL);
02527 
02528   /* update user code on dispatch status */
02529   CONNECTION_LOCK (connection);
02530   status = _dbus_connection_get_dispatch_status_unlocked (connection);
02531   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02532   dbus_pending_call_unref (pending);
02533 }
02534 
02540 int
02541 _dbus_connection_get_pending_fds_count (DBusConnection *connection)
02542 {
02543   return _dbus_transport_get_pending_fds_count (connection->transport);
02544 }
02545 
02553 void
02554 _dbus_connection_set_pending_fds_function (DBusConnection *connection,
02555                                            DBusPendingFdsChangeFunction callback,
02556                                            void *data)
02557 {
02558   _dbus_transport_set_pending_fds_function (connection->transport,
02559                                             callback, data);
02560 }
02561 
02598 DBusConnection*
02599 dbus_connection_open (const char     *address,
02600                       DBusError      *error)
02601 {
02602   DBusConnection *connection;
02603 
02604   _dbus_return_val_if_fail (address != NULL, NULL);
02605   _dbus_return_val_if_error_is_set (error, NULL);
02606 
02607   connection = _dbus_connection_open_internal (address,
02608                                                TRUE,
02609                                                error);
02610 
02611   return connection;
02612 }
02613 
02641 DBusConnection*
02642 dbus_connection_open_private (const char     *address,
02643                               DBusError      *error)
02644 {
02645   DBusConnection *connection;
02646 
02647   _dbus_return_val_if_fail (address != NULL, NULL);
02648   _dbus_return_val_if_error_is_set (error, NULL);
02649 
02650   connection = _dbus_connection_open_internal (address,
02651                                                FALSE,
02652                                                error);
02653 
02654   return connection;
02655 }
02656 
02663 DBusConnection *
02664 dbus_connection_ref (DBusConnection *connection)
02665 {
02666   dbus_int32_t old_refcount;
02667 
02668   _dbus_return_val_if_fail (connection != NULL, NULL);
02669   _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
02670   old_refcount = _dbus_atomic_inc (&connection->refcount);
02671   _dbus_connection_trace_ref (connection, old_refcount, old_refcount + 1,
02672       "ref");
02673 
02674   return connection;
02675 }
02676 
02677 static void
02678 free_outgoing_message (void *element,
02679                        void *data)
02680 {
02681   DBusMessage *message = element;
02682   DBusConnection *connection = data;
02683 
02684   _dbus_message_remove_counter (message, connection->outgoing_counter);
02685   dbus_message_unref (message);
02686 }
02687 
02688 /* This is run without the mutex held, but after the last reference
02689  * to the connection has been dropped we should have no thread-related
02690  * problems
02691  */
02692 static void
02693 _dbus_connection_last_unref (DBusConnection *connection)
02694 {
02695   DBusList *link;
02696 
02697   _dbus_verbose ("Finalizing connection %p\n", connection);
02698 
02699   _dbus_assert (_dbus_atomic_get (&connection->refcount) == 0);
02700 
02701   /* You have to disconnect the connection before unref:ing it. Otherwise
02702    * you won't get the disconnected message.
02703    */
02704   _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
02705   _dbus_assert (connection->server_guid == NULL);
02706   
02707   /* ---- We're going to call various application callbacks here, hope it doesn't break anything... */
02708   _dbus_object_tree_free_all_unlocked (connection->objects);
02709   
02710   dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
02711   dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
02712   dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
02713   
02714   _dbus_watch_list_free (connection->watches);
02715   connection->watches = NULL;
02716   
02717   _dbus_timeout_list_free (connection->timeouts);
02718   connection->timeouts = NULL;
02719 
02720   _dbus_data_slot_list_free (&connection->slot_list);
02721   
02722   link = _dbus_list_get_first_link (&connection->filter_list);
02723   while (link != NULL)
02724     {
02725       DBusMessageFilter *filter = link->data;
02726       DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
02727 
02728       filter->function = NULL;
02729       _dbus_message_filter_unref (filter); /* calls app callback */
02730       link->data = NULL;
02731       
02732       link = next;
02733     }
02734   _dbus_list_clear (&connection->filter_list);
02735   
02736   /* ---- Done with stuff that invokes application callbacks */
02737 
02738   _dbus_object_tree_unref (connection->objects);  
02739 
02740   _dbus_hash_table_unref (connection->pending_replies);
02741   connection->pending_replies = NULL;
02742   
02743   _dbus_list_clear (&connection->filter_list);
02744   
02745   _dbus_list_foreach (&connection->outgoing_messages,
02746                       free_outgoing_message,
02747                       connection);
02748   _dbus_list_clear (&connection->outgoing_messages);
02749   
02750   _dbus_list_foreach (&connection->incoming_messages,
02751                       (DBusForeachFunction) dbus_message_unref,
02752                       NULL);
02753   _dbus_list_clear (&connection->incoming_messages);
02754 
02755   _dbus_counter_unref (connection->outgoing_counter);
02756 
02757   _dbus_transport_unref (connection->transport);
02758 
02759   if (connection->disconnect_message_link)
02760     {
02761       DBusMessage *message = connection->disconnect_message_link->data;
02762       dbus_message_unref (message);
02763       _dbus_list_free_link (connection->disconnect_message_link);
02764     }
02765 
02766   _dbus_condvar_free_at_location (&connection->dispatch_cond);
02767   _dbus_condvar_free_at_location (&connection->io_path_cond);
02768 
02769   _dbus_cmutex_free_at_location (&connection->io_path_mutex);
02770   _dbus_cmutex_free_at_location (&connection->dispatch_mutex);
02771 
02772   _dbus_rmutex_free_at_location (&connection->slot_mutex);
02773 
02774   _dbus_rmutex_free_at_location (&connection->mutex);
02775   
02776   dbus_free (connection);
02777 }
02778 
02798 void
02799 dbus_connection_unref (DBusConnection *connection)
02800 {
02801   dbus_int32_t old_refcount;
02802 
02803   _dbus_return_if_fail (connection != NULL);
02804   _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02805 
02806   old_refcount = _dbus_atomic_dec (&connection->refcount);
02807 
02808   _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1,
02809       "unref");
02810 
02811   if (old_refcount == 1)
02812     {
02813 #ifndef DBUS_DISABLE_CHECKS
02814       if (_dbus_transport_get_is_connected (connection->transport))
02815         {
02816           _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",
02817                                    connection->shareable ?
02818                                    "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" : 
02819                                     "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n");
02820           return;
02821         }
02822 #endif
02823       _dbus_connection_last_unref (connection);
02824     }
02825 }
02826 
02827 /*
02828  * Note that the transport can disconnect itself (other end drops us)
02829  * and in that case this function never runs. So this function must
02830  * not do anything more than disconnect the transport and update the
02831  * dispatch status.
02832  * 
02833  * If the transport self-disconnects, then we assume someone will
02834  * dispatch the connection to cause the dispatch status update.
02835  */
02836 static void
02837 _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection)
02838 {
02839   DBusDispatchStatus status;
02840 
02841   HAVE_LOCK_CHECK (connection);
02842   
02843   _dbus_verbose ("Disconnecting %p\n", connection);
02844 
02845   /* We need to ref because update_dispatch_status_and_unlock will unref
02846    * the connection if it was shared and libdbus was the only remaining
02847    * refcount holder.
02848    */
02849   _dbus_connection_ref_unlocked (connection);
02850   
02851   _dbus_transport_disconnect (connection->transport);
02852 
02853   /* This has the side effect of queuing the disconnect message link
02854    * (unless we don't have enough memory, possibly, so don't assert it).
02855    * After the disconnect message link is queued, dbus_bus_get/dbus_connection_open
02856    * should never again return the newly-disconnected connection.
02857    *
02858    * However, we only unref the shared connection and exit_on_disconnect when
02859    * the disconnect message reaches the head of the message queue,
02860    * NOT when it's first queued.
02861    */
02862   status = _dbus_connection_get_dispatch_status_unlocked (connection);
02863 
02864   /* This calls out to user code */
02865   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02866 
02867   /* Could also call out to user code */
02868   dbus_connection_unref (connection);
02869 }
02870 
02913 void
02914 dbus_connection_close (DBusConnection *connection)
02915 {
02916   _dbus_return_if_fail (connection != NULL);
02917   _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02918 
02919   CONNECTION_LOCK (connection);
02920 
02921 #ifndef DBUS_DISABLE_CHECKS
02922   if (connection->shareable)
02923     {
02924       CONNECTION_UNLOCK (connection);
02925 
02926       _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n");
02927       return;
02928     }
02929 #endif
02930   
02931   _dbus_connection_close_possibly_shared_and_unlock (connection);
02932 }
02933 
02934 static dbus_bool_t
02935 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
02936 {
02937   HAVE_LOCK_CHECK (connection);
02938   return _dbus_transport_get_is_connected (connection->transport);
02939 }
02940 
02954 dbus_bool_t
02955 dbus_connection_get_is_connected (DBusConnection *connection)
02956 {
02957   dbus_bool_t res;
02958 
02959   _dbus_return_val_if_fail (connection != NULL, FALSE);
02960   
02961   CONNECTION_LOCK (connection);
02962   res = _dbus_connection_get_is_connected_unlocked (connection);
02963   CONNECTION_UNLOCK (connection);
02964   
02965   return res;
02966 }
02967 
02976 dbus_bool_t
02977 dbus_connection_get_is_authenticated (DBusConnection *connection)
02978 {
02979   dbus_bool_t res;
02980 
02981   _dbus_return_val_if_fail (connection != NULL, FALSE);
02982   
02983   CONNECTION_LOCK (connection);
02984   res = _dbus_transport_get_is_authenticated (connection->transport);
02985   CONNECTION_UNLOCK (connection);
02986   
02987   return res;
02988 }
02989 
03010 dbus_bool_t
03011 dbus_connection_get_is_anonymous (DBusConnection *connection)
03012 {
03013   dbus_bool_t res;
03014 
03015   _dbus_return_val_if_fail (connection != NULL, FALSE);
03016   
03017   CONNECTION_LOCK (connection);
03018   res = _dbus_transport_get_is_anonymous (connection->transport);
03019   CONNECTION_UNLOCK (connection);
03020   
03021   return res;
03022 }
03023 
03055 char*
03056 dbus_connection_get_server_id (DBusConnection *connection)
03057 {
03058   char *id;
03059 
03060   _dbus_return_val_if_fail (connection != NULL, NULL);
03061 
03062   CONNECTION_LOCK (connection);
03063   id = _dbus_strdup (_dbus_transport_get_server_id (connection->transport));
03064   CONNECTION_UNLOCK (connection);
03065 
03066   return id;
03067 }
03068 
03086 dbus_bool_t
03087 dbus_connection_can_send_type(DBusConnection *connection,
03088                                   int type)
03089 {
03090   _dbus_return_val_if_fail (connection != NULL, FALSE);
03091 
03092   if (!dbus_type_is_valid (type))
03093     return FALSE;
03094 
03095   if (type != DBUS_TYPE_UNIX_FD)
03096     return TRUE;
03097 
03098 #ifdef HAVE_UNIX_FD_PASSING
03099   {
03100     dbus_bool_t b;
03101 
03102     CONNECTION_LOCK(connection);
03103     b = _dbus_transport_can_pass_unix_fd(connection->transport);
03104     CONNECTION_UNLOCK(connection);
03105 
03106     return b;
03107   }
03108 #endif
03109 
03110   return FALSE;
03111 }
03112 
03126 void
03127 dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
03128                                         dbus_bool_t     exit_on_disconnect)
03129 {
03130   _dbus_return_if_fail (connection != NULL);
03131 
03132   CONNECTION_LOCK (connection);
03133   connection->exit_on_disconnect = exit_on_disconnect != FALSE;
03134   CONNECTION_UNLOCK (connection);
03135 }
03136 
03146 DBusPreallocatedSend*
03147 dbus_connection_preallocate_send (DBusConnection *connection)
03148 {
03149   DBusPreallocatedSend *preallocated;
03150 
03151   _dbus_return_val_if_fail (connection != NULL, NULL);
03152 
03153   CONNECTION_LOCK (connection);
03154   
03155   preallocated =
03156     _dbus_connection_preallocate_send_unlocked (connection);
03157 
03158   CONNECTION_UNLOCK (connection);
03159 
03160   return preallocated;
03161 }
03162 
03172 void
03173 dbus_connection_free_preallocated_send (DBusConnection       *connection,
03174                                         DBusPreallocatedSend *preallocated)
03175 {
03176   _dbus_return_if_fail (connection != NULL);
03177   _dbus_return_if_fail (preallocated != NULL);  
03178   _dbus_return_if_fail (connection == preallocated->connection);
03179 
03180   _dbus_list_free_link (preallocated->queue_link);
03181   _dbus_counter_unref (preallocated->counter_link->data);
03182   _dbus_list_free_link (preallocated->counter_link);
03183   dbus_free (preallocated);
03184 }
03185 
03198 void
03199 dbus_connection_send_preallocated (DBusConnection       *connection,
03200                                    DBusPreallocatedSend *preallocated,
03201                                    DBusMessage          *message,
03202                                    dbus_uint32_t        *client_serial)
03203 {
03204   _dbus_return_if_fail (connection != NULL);
03205   _dbus_return_if_fail (preallocated != NULL);
03206   _dbus_return_if_fail (message != NULL);
03207   _dbus_return_if_fail (preallocated->connection == connection);
03208   _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
03209                         dbus_message_get_member (message) != NULL);
03210   _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
03211                         (dbus_message_get_interface (message) != NULL &&
03212                          dbus_message_get_member (message) != NULL));
03213 
03214   CONNECTION_LOCK (connection);
03215 
03216 #ifdef HAVE_UNIX_FD_PASSING
03217 
03218   if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03219       message->n_unix_fds > 0)
03220     {
03221       /* Refuse to send fds on a connection that cannot handle
03222          them. Unfortunately we cannot return a proper error here, so
03223          the best we can is just return. */
03224       CONNECTION_UNLOCK (connection);
03225       return;
03226     }
03227 
03228 #endif
03229 
03230   _dbus_connection_send_preallocated_and_unlock (connection,
03231                                                  preallocated,
03232                                                  message, client_serial);
03233 }
03234 
03235 static dbus_bool_t
03236 _dbus_connection_send_unlocked_no_update (DBusConnection *connection,
03237                                           DBusMessage    *message,
03238                                           dbus_uint32_t  *client_serial)
03239 {
03240   DBusPreallocatedSend *preallocated;
03241 
03242   _dbus_assert (connection != NULL);
03243   _dbus_assert (message != NULL);
03244   
03245   preallocated = _dbus_connection_preallocate_send_unlocked (connection);
03246   if (preallocated == NULL)
03247     return FALSE;
03248 
03249   _dbus_connection_send_preallocated_unlocked_no_update (connection,
03250                                                          preallocated,
03251                                                          message,
03252                                                          client_serial);
03253   return TRUE;
03254 }
03255 
03283 dbus_bool_t
03284 dbus_connection_send (DBusConnection *connection,
03285                       DBusMessage    *message,
03286                       dbus_uint32_t  *serial)
03287 {
03288   _dbus_return_val_if_fail (connection != NULL, FALSE);
03289   _dbus_return_val_if_fail (message != NULL, FALSE);
03290 
03291   CONNECTION_LOCK (connection);
03292 
03293 #ifdef HAVE_UNIX_FD_PASSING
03294 
03295   if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03296       message->n_unix_fds > 0)
03297     {
03298       /* Refuse to send fds on a connection that cannot handle
03299          them. Unfortunately we cannot return a proper error here, so
03300          the best we can is just return. */
03301       CONNECTION_UNLOCK (connection);
03302       return FALSE;
03303     }
03304 
03305 #endif
03306 
03307   return _dbus_connection_send_and_unlock (connection,
03308                                            message,
03309                                            serial);
03310 }
03311 
03312 static dbus_bool_t
03313 reply_handler_timeout (void *data)
03314 {
03315   DBusConnection *connection;
03316   DBusDispatchStatus status;
03317   DBusPendingCall *pending = data;
03318 
03319   connection = _dbus_pending_call_get_connection_and_lock (pending);
03320   _dbus_connection_ref_unlocked (connection);
03321 
03322   _dbus_pending_call_queue_timeout_error_unlocked (pending, 
03323                                                    connection);
03324   _dbus_connection_remove_timeout_unlocked (connection,
03325                                             _dbus_pending_call_get_timeout_unlocked (pending));
03326   _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
03327 
03328   _dbus_verbose ("middle\n");
03329   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03330 
03331   /* Unlocks, and calls out to user code */
03332   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03333   dbus_connection_unref (connection);
03334   
03335   return TRUE;
03336 }
03337 
03380 dbus_bool_t
03381 dbus_connection_send_with_reply (DBusConnection     *connection,
03382                                  DBusMessage        *message,
03383                                  DBusPendingCall   **pending_return,
03384                                  int                 timeout_milliseconds)
03385 {
03386   DBusPendingCall *pending;
03387   dbus_int32_t serial = -1;
03388   DBusDispatchStatus status;
03389 
03390   _dbus_return_val_if_fail (connection != NULL, FALSE);
03391   _dbus_return_val_if_fail (message != NULL, FALSE);
03392   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03393 
03394   if (pending_return)
03395     *pending_return = NULL;
03396 
03397   CONNECTION_LOCK (connection);
03398 
03399 #ifdef HAVE_UNIX_FD_PASSING
03400 
03401   if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03402       message->n_unix_fds > 0)
03403     {
03404       /* Refuse to send fds on a connection that cannot handle
03405          them. Unfortunately we cannot return a proper error here, so
03406          the best we can do is return TRUE but leave *pending_return
03407          as NULL. */
03408       CONNECTION_UNLOCK (connection);
03409       return TRUE;
03410     }
03411 
03412 #endif
03413 
03414    if (!_dbus_connection_get_is_connected_unlocked (connection))
03415     {
03416       CONNECTION_UNLOCK (connection);
03417 
03418       return TRUE;
03419     }
03420 
03421   pending = _dbus_pending_call_new_unlocked (connection,
03422                                              timeout_milliseconds,
03423                                              reply_handler_timeout);
03424 
03425   if (pending == NULL)
03426     {
03427       CONNECTION_UNLOCK (connection);
03428       return FALSE;
03429     }
03430 
03431   /* Assign a serial to the message */
03432   serial = dbus_message_get_serial (message);
03433   if (serial == 0)
03434     {
03435       serial = _dbus_connection_get_next_client_serial (connection);
03436       dbus_message_set_serial (message, serial);
03437     }
03438 
03439   if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
03440     goto error;
03441     
03442   /* Insert the serial in the pending replies hash;
03443    * hash takes a refcount on DBusPendingCall.
03444    * Also, add the timeout.
03445    */
03446   if (!_dbus_connection_attach_pending_call_unlocked (connection,
03447                                                       pending))
03448     goto error;
03449  
03450   if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
03451     {
03452       _dbus_connection_detach_pending_call_and_unlock (connection,
03453                                                        pending);
03454       goto error_unlocked;
03455     }
03456 
03457   if (pending_return)
03458     *pending_return = pending; /* hand off refcount */
03459   else
03460     {
03461       _dbus_connection_detach_pending_call_unlocked (connection, pending);
03462       /* we still have a ref to the pending call in this case, we unref
03463        * after unlocking, below
03464        */
03465     }
03466 
03467   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03468 
03469   /* this calls out to user code */
03470   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03471 
03472   if (pending_return == NULL)
03473     dbus_pending_call_unref (pending);
03474   
03475   return TRUE;
03476 
03477  error:
03478   CONNECTION_UNLOCK (connection);
03479  error_unlocked:
03480   dbus_pending_call_unref (pending);
03481   return FALSE;
03482 }
03483 
03516 DBusMessage*
03517 dbus_connection_send_with_reply_and_block (DBusConnection     *connection,
03518                                            DBusMessage        *message,
03519                                            int                 timeout_milliseconds,
03520                                            DBusError          *error)
03521 {
03522   DBusMessage *reply;
03523   DBusPendingCall *pending;
03524 
03525   _dbus_return_val_if_fail (connection != NULL, NULL);
03526   _dbus_return_val_if_fail (message != NULL, NULL);
03527   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL);
03528   _dbus_return_val_if_error_is_set (error, NULL);
03529 
03530 #ifdef HAVE_UNIX_FD_PASSING
03531 
03532   CONNECTION_LOCK (connection);
03533   if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03534       message->n_unix_fds > 0)
03535     {
03536       CONNECTION_UNLOCK (connection);
03537       dbus_set_error(error, DBUS_ERROR_FAILED, "Cannot send file descriptors on this connection.");
03538       return NULL;
03539     }
03540   CONNECTION_UNLOCK (connection);
03541 
03542 #endif
03543 
03544   if (!dbus_connection_send_with_reply (connection, message,
03545                                         &pending, timeout_milliseconds))
03546     {
03547       _DBUS_SET_OOM (error);
03548       return NULL;
03549     }
03550 
03551   if (pending == NULL)
03552     {
03553       dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Connection is closed");
03554       return NULL;
03555     }
03556   
03557   dbus_pending_call_block (pending);
03558 
03559   reply = dbus_pending_call_steal_reply (pending);
03560   dbus_pending_call_unref (pending);
03561 
03562   /* call_complete_and_unlock() called from pending_call_block() should
03563    * always fill this in.
03564    */
03565   _dbus_assert (reply != NULL);
03566   
03567    if (dbus_set_error_from_message (error, reply))
03568     {
03569       dbus_message_unref (reply);
03570       return NULL;
03571     }
03572   else
03573     return reply;
03574 }
03575 
03584 static DBusDispatchStatus
03585 _dbus_connection_flush_unlocked (DBusConnection *connection)
03586 {
03587   /* We have to specify DBUS_ITERATION_DO_READING here because
03588    * otherwise we could have two apps deadlock if they are both doing
03589    * a flush(), and the kernel buffers fill up. This could change the
03590    * dispatch status.
03591    */
03592   DBusDispatchStatus status;
03593 
03594   HAVE_LOCK_CHECK (connection);
03595   
03596   while (connection->n_outgoing > 0 &&
03597          _dbus_connection_get_is_connected_unlocked (connection))
03598     {
03599       _dbus_verbose ("doing iteration in\n");
03600       HAVE_LOCK_CHECK (connection);
03601       _dbus_connection_do_iteration_unlocked (connection,
03602                                               NULL,
03603                                               DBUS_ITERATION_DO_READING |
03604                                               DBUS_ITERATION_DO_WRITING |
03605                                               DBUS_ITERATION_BLOCK,
03606                                               -1);
03607     }
03608 
03609   HAVE_LOCK_CHECK (connection);
03610   _dbus_verbose ("middle\n");
03611   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03612 
03613   HAVE_LOCK_CHECK (connection);
03614   return status;
03615 }
03616 
03622 void
03623 dbus_connection_flush (DBusConnection *connection)
03624 {
03625   /* We have to specify DBUS_ITERATION_DO_READING here because
03626    * otherwise we could have two apps deadlock if they are both doing
03627    * a flush(), and the kernel buffers fill up. This could change the
03628    * dispatch status.
03629    */
03630   DBusDispatchStatus status;
03631 
03632   _dbus_return_if_fail (connection != NULL);
03633   
03634   CONNECTION_LOCK (connection);
03635 
03636   status = _dbus_connection_flush_unlocked (connection);
03637   
03638   HAVE_LOCK_CHECK (connection);
03639   /* Unlocks and calls out to user code */
03640   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03641 
03642   _dbus_verbose ("end\n");
03643 }
03644 
03655 static dbus_bool_t
03656 _dbus_connection_read_write_dispatch (DBusConnection *connection,
03657                                      int             timeout_milliseconds, 
03658                                      dbus_bool_t     dispatch)
03659 {
03660   DBusDispatchStatus dstatus;
03661   dbus_bool_t progress_possible;
03662 
03663   /* Need to grab a ref here in case we're a private connection and
03664    * the user drops the last ref in a handler we call; see bug 
03665    * https://bugs.freedesktop.org/show_bug.cgi?id=15635
03666    */
03667   dbus_connection_ref (connection);
03668   dstatus = dbus_connection_get_dispatch_status (connection);
03669 
03670   if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
03671     {
03672       _dbus_verbose ("doing dispatch\n");
03673       dbus_connection_dispatch (connection);
03674       CONNECTION_LOCK (connection);
03675     }
03676   else if (dstatus == DBUS_DISPATCH_NEED_MEMORY)
03677     {
03678       _dbus_verbose ("pausing for memory\n");
03679       _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
03680       CONNECTION_LOCK (connection);
03681     }
03682   else
03683     {
03684       CONNECTION_LOCK (connection);
03685       if (_dbus_connection_get_is_connected_unlocked (connection))
03686         {
03687           _dbus_verbose ("doing iteration\n");
03688           _dbus_connection_do_iteration_unlocked (connection,
03689                                                   NULL,
03690                                                   DBUS_ITERATION_DO_READING |
03691                                                   DBUS_ITERATION_DO_WRITING |
03692                                                   DBUS_ITERATION_BLOCK,
03693                                                   timeout_milliseconds);
03694         }
03695     }
03696   
03697   HAVE_LOCK_CHECK (connection);
03698   /* If we can dispatch, we can make progress until the Disconnected message
03699    * has been processed; if we can only read/write, we can make progress
03700    * as long as the transport is open.
03701    */
03702   if (dispatch)
03703     progress_possible = connection->n_incoming != 0 ||
03704       connection->disconnect_message_link != NULL;
03705   else
03706     progress_possible = _dbus_connection_get_is_connected_unlocked (connection);
03707 
03708   CONNECTION_UNLOCK (connection);
03709 
03710   dbus_connection_unref (connection);
03711 
03712   return progress_possible; /* TRUE if we can make more progress */
03713 }
03714 
03715 
03750 dbus_bool_t
03751 dbus_connection_read_write_dispatch (DBusConnection *connection,
03752                                      int             timeout_milliseconds)
03753 {
03754   _dbus_return_val_if_fail (connection != NULL, FALSE);
03755   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03756    return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE);
03757 }
03758 
03782 dbus_bool_t 
03783 dbus_connection_read_write (DBusConnection *connection, 
03784                             int             timeout_milliseconds) 
03785 { 
03786   _dbus_return_val_if_fail (connection != NULL, FALSE);
03787   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03788    return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE);
03789 }
03790 
03791 /* We need to call this anytime we pop the head of the queue, and then
03792  * update_dispatch_status_and_unlock needs to be called afterward
03793  * which will "process" the disconnected message and set
03794  * disconnected_message_processed.
03795  */
03796 static void
03797 check_disconnected_message_arrived_unlocked (DBusConnection *connection,
03798                                              DBusMessage    *head_of_queue)
03799 {
03800   HAVE_LOCK_CHECK (connection);
03801 
03802   /* checking that the link is NULL is an optimization to avoid the is_signal call */
03803   if (connection->disconnect_message_link == NULL &&
03804       dbus_message_is_signal (head_of_queue,
03805                               DBUS_INTERFACE_LOCAL,
03806                               "Disconnected"))
03807     {
03808       connection->disconnected_message_arrived = TRUE;
03809     }
03810 }
03811 
03831 DBusMessage*
03832 dbus_connection_borrow_message (DBusConnection *connection)
03833 {
03834   DBusDispatchStatus status;
03835   DBusMessage *message;
03836 
03837   _dbus_return_val_if_fail (connection != NULL, NULL);
03838 
03839   _dbus_verbose ("start\n");
03840   
03841   /* this is called for the side effect that it queues
03842    * up any messages from the transport
03843    */
03844   status = dbus_connection_get_dispatch_status (connection);
03845   if (status != DBUS_DISPATCH_DATA_REMAINS)
03846     return NULL;
03847   
03848   CONNECTION_LOCK (connection);
03849 
03850   _dbus_connection_acquire_dispatch (connection);
03851 
03852   /* While a message is outstanding, the dispatch lock is held */
03853   _dbus_assert (connection->message_borrowed == NULL);
03854 
03855   connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
03856   
03857   message = connection->message_borrowed;
03858 
03859   check_disconnected_message_arrived_unlocked (connection, message);
03860   
03861   /* Note that we KEEP the dispatch lock until the message is returned */
03862   if (message == NULL)
03863     _dbus_connection_release_dispatch (connection);
03864 
03865   CONNECTION_UNLOCK (connection);
03866 
03867   _dbus_message_trace_ref (message, -1, -1, "dbus_connection_borrow_message");
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   _dbus_message_trace_ref (message, -1, -1, "dbus_connection_return_message");
03905 }
03906 
03916 void
03917 dbus_connection_steal_borrowed_message (DBusConnection *connection,
03918                                         DBusMessage    *message)
03919 {
03920   DBusMessage *pop_message;
03921   DBusDispatchStatus status;
03922 
03923   _dbus_return_if_fail (connection != NULL);
03924   _dbus_return_if_fail (message != NULL);
03925   _dbus_return_if_fail (message == connection->message_borrowed);
03926   _dbus_return_if_fail (connection->dispatch_acquired);
03927   
03928   CONNECTION_LOCK (connection);
03929  
03930   _dbus_assert (message == connection->message_borrowed);
03931 
03932   pop_message = _dbus_list_pop_first (&connection->incoming_messages);
03933   _dbus_assert (message == pop_message);
03934   (void) pop_message; /* unused unless asserting */
03935 
03936   connection->n_incoming -= 1;
03937  
03938   _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
03939                  message, connection->n_incoming);
03940  
03941   connection->message_borrowed = NULL;
03942 
03943   _dbus_connection_release_dispatch (connection);
03944 
03945   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03946   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03947   _dbus_message_trace_ref (message, -1, -1,
03948       "dbus_connection_steal_borrowed_message");
03949 }
03950 
03951 /* See dbus_connection_pop_message, but requires the caller to own
03952  * the lock before calling. May drop the lock while running.
03953  */
03954 static DBusList*
03955 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
03956 {
03957   HAVE_LOCK_CHECK (connection);
03958   
03959   _dbus_assert (connection->message_borrowed == NULL);
03960   
03961   if (connection->n_incoming > 0)
03962     {
03963       DBusList *link;
03964 
03965       link = _dbus_list_pop_first_link (&connection->incoming_messages);
03966       connection->n_incoming -= 1;
03967 
03968       _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from incoming queue %p, %d incoming\n",
03969                      link->data,
03970                      dbus_message_type_to_string (dbus_message_get_type (link->data)),
03971                      dbus_message_get_path (link->data) ?
03972                      dbus_message_get_path (link->data) :
03973                      "no path",
03974                      dbus_message_get_interface (link->data) ?
03975                      dbus_message_get_interface (link->data) :
03976                      "no interface",
03977                      dbus_message_get_member (link->data) ?
03978                      dbus_message_get_member (link->data) :
03979                      "no member",
03980                      dbus_message_get_signature (link->data),
03981                      connection, connection->n_incoming);
03982 
03983       _dbus_message_trace_ref (link->data, -1, -1,
03984           "_dbus_connection_pop_message_link_unlocked");
03985 
03986       check_disconnected_message_arrived_unlocked (connection, link->data);
03987       
03988       return link;
03989     }
03990   else
03991     return NULL;
03992 }
03993 
03994 /* See dbus_connection_pop_message, but requires the caller to own
03995  * the lock before calling. May drop the lock while running.
03996  */
03997 static DBusMessage*
03998 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
03999 {
04000   DBusList *link;
04001 
04002   HAVE_LOCK_CHECK (connection);
04003   
04004   link = _dbus_connection_pop_message_link_unlocked (connection);
04005 
04006   if (link != NULL)
04007     {
04008       DBusMessage *message;
04009       
04010       message = link->data;
04011       
04012       _dbus_list_free_link (link);
04013       
04014       return message;
04015     }
04016   else
04017     return NULL;
04018 }
04019 
04020 static void
04021 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
04022                                                 DBusList       *message_link)
04023 {
04024   HAVE_LOCK_CHECK (connection);
04025   
04026   _dbus_assert (message_link != NULL);
04027   /* You can't borrow a message while a link is outstanding */
04028   _dbus_assert (connection->message_borrowed == NULL);
04029   /* We had to have the dispatch lock across the pop/putback */
04030   _dbus_assert (connection->dispatch_acquired);
04031 
04032   _dbus_list_prepend_link (&connection->incoming_messages,
04033                            message_link);
04034   connection->n_incoming += 1;
04035 
04036   _dbus_verbose ("Message %p (%s %s %s '%s') put back into queue %p, %d incoming\n",
04037                  message_link->data,
04038                  dbus_message_type_to_string (dbus_message_get_type (message_link->data)),
04039                  dbus_message_get_interface (message_link->data) ?
04040                  dbus_message_get_interface (message_link->data) :
04041                  "no interface",
04042                  dbus_message_get_member (message_link->data) ?
04043                  dbus_message_get_member (message_link->data) :
04044                  "no member",
04045                  dbus_message_get_signature (message_link->data),
04046                  connection, connection->n_incoming);
04047 
04048   _dbus_message_trace_ref (message_link->data, -1, -1,
04049       "_dbus_connection_putback_message_link_unlocked");
04050 }
04051 
04071 DBusMessage*
04072 dbus_connection_pop_message (DBusConnection *connection)
04073 {
04074   DBusMessage *message;
04075   DBusDispatchStatus status;
04076 
04077   _dbus_verbose ("start\n");
04078   
04079   /* this is called for the side effect that it queues
04080    * up any messages from the transport
04081    */
04082   status = dbus_connection_get_dispatch_status (connection);
04083   if (status != DBUS_DISPATCH_DATA_REMAINS)
04084     return NULL;
04085   
04086   CONNECTION_LOCK (connection);
04087   _dbus_connection_acquire_dispatch (connection);
04088   HAVE_LOCK_CHECK (connection);
04089   
04090   message = _dbus_connection_pop_message_unlocked (connection);
04091 
04092   _dbus_verbose ("Returning popped message %p\n", message);    
04093 
04094   _dbus_connection_release_dispatch (connection);
04095 
04096   status = _dbus_connection_get_dispatch_status_unlocked (connection);
04097   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04098   
04099   return message;
04100 }
04101 
04109 static void
04110 _dbus_connection_acquire_dispatch (DBusConnection *connection)
04111 {
04112   HAVE_LOCK_CHECK (connection);
04113 
04114   _dbus_connection_ref_unlocked (connection);
04115   CONNECTION_UNLOCK (connection);
04116   
04117   _dbus_verbose ("locking dispatch_mutex\n");
04118   _dbus_cmutex_lock (connection->dispatch_mutex);
04119 
04120   while (connection->dispatch_acquired)
04121     {
04122       _dbus_verbose ("waiting for dispatch to be acquirable\n");
04123       _dbus_condvar_wait (connection->dispatch_cond, 
04124                           connection->dispatch_mutex);
04125     }
04126   
04127   _dbus_assert (!connection->dispatch_acquired);
04128 
04129   connection->dispatch_acquired = TRUE;
04130 
04131   _dbus_verbose ("unlocking dispatch_mutex\n");
04132   _dbus_cmutex_unlock (connection->dispatch_mutex);
04133   
04134   CONNECTION_LOCK (connection);
04135   _dbus_connection_unref_unlocked (connection);
04136 }
04137 
04145 static void
04146 _dbus_connection_release_dispatch (DBusConnection *connection)
04147 {
04148   HAVE_LOCK_CHECK (connection);
04149   
04150   _dbus_verbose ("locking dispatch_mutex\n");
04151   _dbus_cmutex_lock (connection->dispatch_mutex);
04152   
04153   _dbus_assert (connection->dispatch_acquired);
04154 
04155   connection->dispatch_acquired = FALSE;
04156   _dbus_condvar_wake_one (connection->dispatch_cond);
04157 
04158   _dbus_verbose ("unlocking dispatch_mutex\n");
04159   _dbus_cmutex_unlock (connection->dispatch_mutex);
04160 }
04161 
04162 static void
04163 _dbus_connection_failed_pop (DBusConnection *connection,
04164                              DBusList       *message_link)
04165 {
04166   _dbus_list_prepend_link (&connection->incoming_messages,
04167                            message_link);
04168   connection->n_incoming += 1;
04169 }
04170 
04171 /* Note this may be called multiple times since we don't track whether we already did it */
04172 static void
04173 notify_disconnected_unlocked (DBusConnection *connection)
04174 {
04175   HAVE_LOCK_CHECK (connection);
04176 
04177   /* Set the weakref in dbus-bus.c to NULL, so nobody will get a disconnected
04178    * connection from dbus_bus_get(). We make the same guarantee for
04179    * dbus_connection_open() but in a different way since we don't want to
04180    * unref right here; we instead check for connectedness before returning
04181    * the connection from the hash.
04182    */
04183   _dbus_bus_notify_shared_connection_disconnected_unlocked (connection);
04184 
04185   /* Dump the outgoing queue, we aren't going to be able to
04186    * send it now, and we'd like accessors like
04187    * dbus_connection_get_outgoing_size() to be accurate.
04188    */
04189   if (connection->n_outgoing > 0)
04190     {
04191       DBusList *link;
04192       
04193       _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
04194                      connection->n_outgoing);
04195       
04196       while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
04197         {
04198           _dbus_connection_message_sent_unlocked (connection, link->data);
04199         }
04200     } 
04201 }
04202 
04203 /* Note this may be called multiple times since we don't track whether we already did it */
04204 static DBusDispatchStatus
04205 notify_disconnected_and_dispatch_complete_unlocked (DBusConnection *connection)
04206 {
04207   HAVE_LOCK_CHECK (connection);
04208   
04209   if (connection->disconnect_message_link != NULL)
04210     {
04211       _dbus_verbose ("Sending disconnect message\n");
04212       
04213       /* If we have pending calls, queue their timeouts - we want the Disconnected
04214        * to be the last message, after these timeouts.
04215        */
04216       connection_timeout_and_complete_all_pending_calls_unlocked (connection);
04217       
04218       /* We haven't sent the disconnect message already,
04219        * and all real messages have been queued up.
04220        */
04221       _dbus_connection_queue_synthesized_message_link (connection,
04222                                                        connection->disconnect_message_link);
04223       connection->disconnect_message_link = NULL;
04224 
04225       return DBUS_DISPATCH_DATA_REMAINS;
04226     }
04227 
04228   return DBUS_DISPATCH_COMPLETE;
04229 }
04230 
04231 static DBusDispatchStatus
04232 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
04233 {
04234   HAVE_LOCK_CHECK (connection);
04235   
04236   if (connection->n_incoming > 0)
04237     return DBUS_DISPATCH_DATA_REMAINS;
04238   else if (!_dbus_transport_queue_messages (connection->transport))
04239     return DBUS_DISPATCH_NEED_MEMORY;
04240   else
04241     {
04242       DBusDispatchStatus status;
04243       dbus_bool_t is_connected;
04244       
04245       status = _dbus_transport_get_dispatch_status (connection->transport);
04246       is_connected = _dbus_transport_get_is_connected (connection->transport);
04247 
04248       _dbus_verbose ("dispatch status = %s is_connected = %d\n",
04249                      DISPATCH_STATUS_NAME (status), is_connected);
04250       
04251       if (!is_connected)
04252         {
04253           /* It's possible this would be better done by having an explicit
04254            * notification from _dbus_transport_disconnect() that would
04255            * synchronously do this, instead of waiting for the next dispatch
04256            * status check. However, probably not good to change until it causes
04257            * a problem.
04258            */
04259           notify_disconnected_unlocked (connection);
04260 
04261           /* I'm not sure this is needed; the idea is that we want to
04262            * queue the Disconnected only after we've read all the
04263            * messages, but if we're disconnected maybe we are guaranteed
04264            * to have read them all ?
04265            */
04266           if (status == DBUS_DISPATCH_COMPLETE)
04267             status = notify_disconnected_and_dispatch_complete_unlocked (connection);
04268         }
04269       
04270       if (status != DBUS_DISPATCH_COMPLETE)
04271         return status;
04272       else if (connection->n_incoming > 0)
04273         return DBUS_DISPATCH_DATA_REMAINS;
04274       else
04275         return DBUS_DISPATCH_COMPLETE;
04276     }
04277 }
04278 
04279 static void
04280 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection    *connection,
04281                                                     DBusDispatchStatus new_status)
04282 {
04283   dbus_bool_t changed;
04284   DBusDispatchStatusFunction function;
04285   void *data;
04286 
04287   HAVE_LOCK_CHECK (connection);
04288 
04289   _dbus_connection_ref_unlocked (connection);
04290 
04291   changed = new_status != connection->last_dispatch_status;
04292 
04293   connection->last_dispatch_status = new_status;
04294 
04295   function = connection->dispatch_status_function;
04296   data = connection->dispatch_status_data;
04297 
04298   if (connection->disconnected_message_arrived &&
04299       !connection->disconnected_message_processed)
04300     {
04301       connection->disconnected_message_processed = TRUE;
04302       
04303       /* this does an unref, but we have a ref
04304        * so we should not run the finalizer here
04305        * inside the lock.
04306        */
04307       connection_forget_shared_unlocked (connection);
04308 
04309       if (connection->exit_on_disconnect)
04310         {
04311           CONNECTION_UNLOCK (connection);            
04312           
04313           _dbus_verbose ("Exiting on Disconnected signal\n");
04314           _dbus_exit (1);
04315           _dbus_assert_not_reached ("Call to exit() returned");
04316         }
04317     }
04318   
04319   /* We drop the lock */
04320   CONNECTION_UNLOCK (connection);
04321   
04322   if (changed && function)
04323     {
04324       _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
04325                      connection, new_status,
04326                      DISPATCH_STATUS_NAME (new_status));
04327       (* function) (connection, new_status, data);      
04328     }
04329   
04330   dbus_connection_unref (connection);
04331 }
04332 
04358 DBusDispatchStatus
04359 dbus_connection_get_dispatch_status (DBusConnection *connection)
04360 {
04361   DBusDispatchStatus status;
04362 
04363   _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04364 
04365   _dbus_verbose ("start\n");
04366   
04367   CONNECTION_LOCK (connection);
04368 
04369   status = _dbus_connection_get_dispatch_status_unlocked (connection);
04370   
04371   CONNECTION_UNLOCK (connection);
04372 
04373   return status;
04374 }
04375 
04379 static DBusHandlerResult
04380 _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
04381                                                  DBusMessage    *message)
04382 {
04383   dbus_bool_t sent = FALSE;
04384   DBusMessage *ret = NULL;
04385   DBusList *expire_link;
04386 
04387   if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
04388     {
04389       /* This means we're letting the bus route this message */
04390       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04391     }
04392 
04393   if (!dbus_message_has_interface (message, DBUS_INTERFACE_PEER))
04394     {
04395       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04396     }
04397 
04398   /* Preallocate a linked-list link, so that if we need to dispose of a
04399    * message, we can attach it to the expired list */
04400   expire_link = _dbus_list_alloc_link (NULL);
04401 
04402   if (!expire_link)
04403     return DBUS_HANDLER_RESULT_NEED_MEMORY;
04404 
04405   if (dbus_message_is_method_call (message,
04406                                    DBUS_INTERFACE_PEER,
04407                                    "Ping"))
04408     {
04409       ret = dbus_message_new_method_return (message);
04410       if (ret == NULL)
04411         goto out;
04412 
04413       sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04414     }
04415   else if (dbus_message_is_method_call (message,
04416                                         DBUS_INTERFACE_PEER,
04417                                         "GetMachineId"))
04418     {
04419       DBusString uuid;
04420       
04421       ret = dbus_message_new_method_return (message);
04422       if (ret == NULL)
04423         goto out;
04424 
04425       _dbus_string_init (&uuid);
04426       if (_dbus_get_local_machine_uuid_encoded (&uuid))
04427         {
04428           const char *v_STRING = _dbus_string_get_const_data (&uuid);
04429           if (dbus_message_append_args (ret,
04430                                         DBUS_TYPE_STRING, &v_STRING,
04431                                         DBUS_TYPE_INVALID))
04432             {
04433               sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04434             }
04435         }
04436       _dbus_string_free (&uuid);
04437     }
04438   else
04439     {
04440       /* We need to bounce anything else with this interface, otherwise apps
04441        * could start extending the interface and when we added extensions
04442        * here to DBusConnection we'd break those apps.
04443        */
04444       ret = dbus_message_new_error (message,
04445                                     DBUS_ERROR_UNKNOWN_METHOD,
04446                                     "Unknown method invoked on org.freedesktop.DBus.Peer interface");
04447       if (ret == NULL)
04448         goto out;
04449 
04450       sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04451     }
04452 
04453 out:
04454   if (ret == NULL)
04455     {
04456       _dbus_list_free_link (expire_link);
04457     }
04458   else
04459     {
04460       /* It'll be safe to unref the reply when we unlock */
04461       expire_link->data = ret;
04462       _dbus_list_prepend_link (&connection->expired_messages, expire_link);
04463     }
04464 
04465   if (!sent)
04466     return DBUS_HANDLER_RESULT_NEED_MEMORY;
04467 
04468   return DBUS_HANDLER_RESULT_HANDLED;
04469 }
04470 
04477 static DBusHandlerResult
04478 _dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection,
04479                                                            DBusMessage    *message)
04480 {
04481   /* We just run one filter for now but have the option to run more
04482      if the spec calls for it in the future */
04483 
04484   return _dbus_connection_peer_filter_unlocked_no_update (connection, message);
04485 }
04486 
04529 DBusDispatchStatus
04530 dbus_connection_dispatch (DBusConnection *connection)
04531 {
04532   DBusMessage *message;
04533   DBusList *link, *filter_list_copy, *message_link;
04534   DBusHandlerResult result;
04535   DBusPendingCall *pending;
04536   dbus_int32_t reply_serial;
04537   DBusDispatchStatus status;
04538   dbus_bool_t found_object;
04539 
04540   _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04541 
04542   _dbus_verbose ("\n");
04543   
04544   CONNECTION_LOCK (connection);
04545   status = _dbus_connection_get_dispatch_status_unlocked (connection);
04546   if (status != DBUS_DISPATCH_DATA_REMAINS)
04547     {
04548       /* unlocks and calls out to user code */
04549       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04550       return status;
04551     }
04552   
04553   /* We need to ref the connection since the callback could potentially
04554    * drop the last ref to it
04555    */
04556   _dbus_connection_ref_unlocked (connection);
04557 
04558   _dbus_connection_acquire_dispatch (connection);
04559   HAVE_LOCK_CHECK (connection);
04560 
04561   message_link = _dbus_connection_pop_message_link_unlocked (connection);
04562   if (message_link == NULL)
04563     {
04564       /* another thread dispatched our stuff */
04565 
04566       _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
04567       
04568       _dbus_connection_release_dispatch (connection);
04569 
04570       status = _dbus_connection_get_dispatch_status_unlocked (connection);
04571 
04572       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04573       
04574       dbus_connection_unref (connection);
04575       
04576       return status;
04577     }
04578 
04579   message = message_link->data;
04580 
04581   _dbus_verbose (" dispatching message %p (%s %s %s '%s')\n",
04582                  message,
04583                  dbus_message_type_to_string (dbus_message_get_type (message)),
04584                  dbus_message_get_interface (message) ?
04585                  dbus_message_get_interface (message) :
04586                  "no interface",
04587                  dbus_message_get_member (message) ?
04588                  dbus_message_get_member (message) :
04589                  "no member",
04590                  dbus_message_get_signature (message));
04591 
04592   result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04593   
04594   /* Pending call handling must be first, because if you do
04595    * dbus_connection_send_with_reply_and_block() or
04596    * dbus_pending_call_block() then no handlers/filters will be run on
04597    * the reply. We want consistent semantics in the case where we
04598    * dbus_connection_dispatch() the reply.
04599    */
04600   
04601   reply_serial = dbus_message_get_reply_serial (message);
04602   pending = _dbus_hash_table_lookup_int (connection->pending_replies,
04603                                          reply_serial);
04604   if (pending)
04605     {
04606       _dbus_verbose ("Dispatching a pending reply\n");
04607       complete_pending_call_and_unlock (connection, pending, message);
04608       pending = NULL; /* it's probably unref'd */
04609       
04610       CONNECTION_LOCK (connection);
04611       _dbus_verbose ("pending call completed in dispatch\n");
04612       result = DBUS_HANDLER_RESULT_HANDLED;
04613       goto out;
04614     }
04615 
04616   result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message);
04617   if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04618     goto out;
04619  
04620   if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
04621     {
04622       _dbus_connection_release_dispatch (connection);
04623       HAVE_LOCK_CHECK (connection);
04624       
04625       _dbus_connection_failed_pop (connection, message_link);
04626 
04627       /* unlocks and calls user code */
04628       _dbus_connection_update_dispatch_status_and_unlock (connection,
04629                                                           DBUS_DISPATCH_NEED_MEMORY);
04630       dbus_connection_unref (connection);
04631       
04632       return DBUS_DISPATCH_NEED_MEMORY;
04633     }
04634   
04635   _dbus_list_foreach (&filter_list_copy,
04636                       (DBusForeachFunction)_dbus_message_filter_ref,
04637                       NULL);
04638 
04639   /* We're still protected from dispatch() reentrancy here
04640    * since we acquired the dispatcher
04641    */
04642   CONNECTION_UNLOCK (connection);
04643   
04644   link = _dbus_list_get_first_link (&filter_list_copy);
04645   while (link != NULL)
04646     {
04647       DBusMessageFilter *filter = link->data;
04648       DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
04649 
04650       if (filter->function == NULL)
04651         {
04652           _dbus_verbose ("  filter was removed in a callback function\n");
04653           link = next;
04654           continue;
04655         }
04656 
04657       _dbus_verbose ("  running filter on message %p\n", message);
04658       result = (* filter->function) (connection, message, filter->user_data);
04659 
04660       if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04661         break;
04662 
04663       link = next;
04664     }
04665 
04666   _dbus_list_foreach (&filter_list_copy,
04667                       (DBusForeachFunction)_dbus_message_filter_unref,
04668                       NULL);
04669   _dbus_list_clear (&filter_list_copy);
04670   
04671   CONNECTION_LOCK (connection);
04672 
04673   if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04674     {
04675       _dbus_verbose ("No memory\n");
04676       goto out;
04677     }
04678   else if (result == DBUS_HANDLER_RESULT_HANDLED)
04679     {
04680       _dbus_verbose ("filter handled message in dispatch\n");
04681       goto out;
04682     }
04683 
04684   /* We're still protected from dispatch() reentrancy here
04685    * since we acquired the dispatcher
04686    */
04687   _dbus_verbose ("  running object path dispatch on message %p (%s %s %s '%s')\n",
04688                  message,
04689                  dbus_message_type_to_string (dbus_message_get_type (message)),
04690                  dbus_message_get_interface (message) ?
04691                  dbus_message_get_interface (message) :
04692                  "no interface",
04693                  dbus_message_get_member (message) ?
04694                  dbus_message_get_member (message) :
04695                  "no member",
04696                  dbus_message_get_signature (message));
04697 
04698   HAVE_LOCK_CHECK (connection);
04699   result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
04700                                                   message,
04701                                                   &found_object);
04702   
04703   CONNECTION_LOCK (connection);
04704 
04705   if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04706     {
04707       _dbus_verbose ("object tree handled message in dispatch\n");
04708       goto out;
04709     }
04710 
04711   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
04712     {
04713       DBusMessage *reply;
04714       DBusString str;
04715       DBusPreallocatedSend *preallocated;
04716       DBusList *expire_link;
04717 
04718       _dbus_verbose ("  sending error %s\n",
04719                      DBUS_ERROR_UNKNOWN_METHOD);
04720 
04721       if (!_dbus_string_init (&str))
04722         {
04723           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04724           _dbus_verbose ("no memory for error string in dispatch\n");
04725           goto out;
04726         }
04727               
04728       if (!_dbus_string_append_printf (&str,
04729                                        "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
04730                                        dbus_message_get_member (message),
04731                                        dbus_message_get_signature (message),
04732                                        dbus_message_get_interface (message)))
04733         {
04734           _dbus_string_free (&str);
04735           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04736           _dbus_verbose ("no memory for error string in dispatch\n");
04737           goto out;
04738         }
04739       
04740       reply = dbus_message_new_error (message,
04741                                       found_object ? DBUS_ERROR_UNKNOWN_METHOD : DBUS_ERROR_UNKNOWN_OBJECT,
04742                                       _dbus_string_get_const_data (&str));
04743       _dbus_string_free (&str);
04744 
04745       if (reply == NULL)
04746         {
04747           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04748           _dbus_verbose ("no memory for error reply in dispatch\n");
04749           goto out;
04750         }
04751 
04752       expire_link = _dbus_list_alloc_link (reply);
04753 
04754       if (expire_link == NULL)
04755         {
04756           dbus_message_unref (reply);
04757           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04758           _dbus_verbose ("no memory for error send in dispatch\n");
04759           goto out;
04760         }
04761 
04762       preallocated = _dbus_connection_preallocate_send_unlocked (connection);
04763 
04764       if (preallocated == NULL)
04765         {
04766           _dbus_list_free_link (expire_link);
04767           /* It's OK that this is finalized, because it hasn't been seen by
04768            * anything that could attach user callbacks */
04769           dbus_message_unref (reply);
04770           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04771           _dbus_verbose ("no memory for error send in dispatch\n");
04772           goto out;
04773         }
04774 
04775       _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
04776                                                              reply, NULL);
04777       /* reply will be freed when we release the lock */
04778       _dbus_list_prepend_link (&connection->expired_messages, expire_link);
04779 
04780       result = DBUS_HANDLER_RESULT_HANDLED;
04781     }
04782   
04783   _dbus_verbose ("  done dispatching %p (%s %s %s '%s') on connection %p\n", message,
04784                  dbus_message_type_to_string (dbus_message_get_type (message)),
04785                  dbus_message_get_interface (message) ?
04786                  dbus_message_get_interface (message) :
04787                  "no interface",
04788                  dbus_message_get_member (message) ?
04789                  dbus_message_get_member (message) :
04790                  "no member",
04791                  dbus_message_get_signature (message),
04792                  connection);
04793   
04794  out:
04795   if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04796     {
04797       _dbus_verbose ("out of memory\n");
04798       
04799       /* Put message back, and we'll start over.
04800        * Yes this means handlers must be idempotent if they
04801        * don't return HANDLED; c'est la vie.
04802        */
04803       _dbus_connection_putback_message_link_unlocked (connection,
04804                                                       message_link);
04805       /* now we don't want to free them */
04806       message_link = NULL;
04807       message = NULL;
04808     }
04809   else
04810     {
04811       _dbus_verbose (" ... done dispatching\n");
04812     }
04813 
04814   _dbus_connection_release_dispatch (connection);
04815   HAVE_LOCK_CHECK (connection);
04816 
04817   if (message != NULL)
04818     {
04819       /* We don't want this message to count in maximum message limits when
04820        * computing the dispatch status, below. We have to drop the lock
04821        * temporarily, because finalizing a message can trigger callbacks.
04822        *
04823        * We have a reference to the connection, and we don't use any cached
04824        * pointers to the connection's internals below this point, so it should
04825        * be safe to drop the lock and take it back. */
04826       CONNECTION_UNLOCK (connection);
04827       dbus_message_unref (message);
04828       CONNECTION_LOCK (connection);
04829     }
04830 
04831   if (message_link != NULL)
04832     _dbus_list_free_link (message_link);
04833 
04834   _dbus_verbose ("before final status update\n");
04835   status = _dbus_connection_get_dispatch_status_unlocked (connection);
04836 
04837   /* unlocks and calls user code */
04838   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04839   
04840   dbus_connection_unref (connection);
04841   
04842   return status;
04843 }
04844 
04906 dbus_bool_t
04907 dbus_connection_set_watch_functions (DBusConnection              *connection,
04908                                      DBusAddWatchFunction         add_function,
04909                                      DBusRemoveWatchFunction      remove_function,
04910                                      DBusWatchToggledFunction     toggled_function,
04911                                      void                        *data,
04912                                      DBusFreeFunction             free_data_function)
04913 {
04914   dbus_bool_t retval;
04915 
04916   _dbus_return_val_if_fail (connection != NULL, FALSE);
04917   
04918   CONNECTION_LOCK (connection);
04919 
04920   retval = _dbus_watch_list_set_functions (connection->watches,
04921                                            add_function, remove_function,
04922                                            toggled_function,
04923                                            data, free_data_function);
04924 
04925   CONNECTION_UNLOCK (connection);
04926 
04927   return retval;
04928 }
04929 
04969 dbus_bool_t
04970 dbus_connection_set_timeout_functions   (DBusConnection            *connection,
04971                                          DBusAddTimeoutFunction     add_function,
04972                                          DBusRemoveTimeoutFunction  remove_function,
04973                                          DBusTimeoutToggledFunction toggled_function,
04974                                          void                      *data,
04975                                          DBusFreeFunction           free_data_function)
04976 {
04977   dbus_bool_t retval;
04978 
04979   _dbus_return_val_if_fail (connection != NULL, FALSE);
04980   
04981   CONNECTION_LOCK (connection);
04982 
04983   retval = _dbus_timeout_list_set_functions (connection->timeouts,
04984                                              add_function, remove_function,
04985                                              toggled_function,
04986                                              data, free_data_function);
04987 
04988   CONNECTION_UNLOCK (connection);
04989 
04990   return retval;
04991 }
04992 
05007 void
05008 dbus_connection_set_wakeup_main_function (DBusConnection            *connection,
05009                                           DBusWakeupMainFunction     wakeup_main_function,
05010                                           void                      *data,
05011                                           DBusFreeFunction           free_data_function)
05012 {
05013   void *old_data;
05014   DBusFreeFunction old_free_data;
05015 
05016   _dbus_return_if_fail (connection != NULL);
05017   
05018   CONNECTION_LOCK (connection);
05019   old_data = connection->wakeup_main_data;
05020   old_free_data = connection->free_wakeup_main_data;
05021 
05022   connection->wakeup_main_function = wakeup_main_function;
05023   connection->wakeup_main_data = data;
05024   connection->free_wakeup_main_data = free_data_function;
05025   
05026   CONNECTION_UNLOCK (connection);
05027 
05028   /* Callback outside the lock */
05029   if (old_free_data)
05030     (*old_free_data) (old_data);
05031 }
05032 
05053 void
05054 dbus_connection_set_dispatch_status_function (DBusConnection             *connection,
05055                                               DBusDispatchStatusFunction  function,
05056                                               void                       *data,
05057                                               DBusFreeFunction            free_data_function)
05058 {
05059   void *old_data;
05060   DBusFreeFunction old_free_data;
05061 
05062   _dbus_return_if_fail (connection != NULL);
05063   
05064   CONNECTION_LOCK (connection);
05065   old_data = connection->dispatch_status_data;
05066   old_free_data = connection->free_dispatch_status_data;
05067 
05068   connection->dispatch_status_function = function;
05069   connection->dispatch_status_data = data;
05070   connection->free_dispatch_status_data = free_data_function;
05071   
05072   CONNECTION_UNLOCK (connection);
05073 
05074   /* Callback outside the lock */
05075   if (old_free_data)
05076     (*old_free_data) (old_data);
05077 }
05078 
05098 dbus_bool_t
05099 dbus_connection_get_unix_fd (DBusConnection *connection,
05100                              int            *fd)
05101 {
05102   _dbus_return_val_if_fail (connection != NULL, FALSE);
05103   _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
05104 
05105 #ifdef DBUS_WIN
05106   /* FIXME do this on a lower level */
05107   return FALSE;
05108 #endif
05109   
05110   return dbus_connection_get_socket(connection, fd);
05111 }
05112 
05128 dbus_bool_t
05129 dbus_connection_get_socket(DBusConnection              *connection,
05130                            int                         *fd)
05131 {
05132   dbus_bool_t retval;
05133 
05134   _dbus_return_val_if_fail (connection != NULL, FALSE);
05135   _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
05136   
05137   CONNECTION_LOCK (connection);
05138   
05139   retval = _dbus_transport_get_socket_fd (connection->transport,
05140                                           fd);
05141 
05142   CONNECTION_UNLOCK (connection);
05143 
05144   return retval;
05145 }
05146 
05147 
05170 dbus_bool_t
05171 dbus_connection_get_unix_user (DBusConnection *connection,
05172                                unsigned long  *uid)
05173 {
05174   dbus_bool_t result;
05175 
05176   _dbus_return_val_if_fail (connection != NULL, FALSE);
05177   _dbus_return_val_if_fail (uid != NULL, FALSE);
05178   
05179   CONNECTION_LOCK (connection);
05180 
05181   if (!_dbus_transport_get_is_authenticated (connection->transport))
05182     result = FALSE;
05183   else
05184     result = _dbus_transport_get_unix_user (connection->transport,
05185                                             uid);
05186 
05187 #ifdef DBUS_WIN
05188   _dbus_assert (!result);
05189 #endif
05190   
05191   CONNECTION_UNLOCK (connection);
05192 
05193   return result;
05194 }
05195 
05206 dbus_bool_t
05207 dbus_connection_get_unix_process_id (DBusConnection *connection,
05208                                      unsigned long  *pid)
05209 {
05210   dbus_bool_t result;
05211 
05212   _dbus_return_val_if_fail (connection != NULL, FALSE);
05213   _dbus_return_val_if_fail (pid != NULL, FALSE);
05214   
05215   CONNECTION_LOCK (connection);
05216 
05217   if (!_dbus_transport_get_is_authenticated (connection->transport))
05218     result = FALSE;
05219   else
05220     result = _dbus_transport_get_unix_process_id (connection->transport,
05221                                                   pid);
05222 
05223   CONNECTION_UNLOCK (connection);
05224 
05225   return result;
05226 }
05227 
05238 dbus_bool_t
05239 dbus_connection_get_adt_audit_session_data (DBusConnection *connection,
05240                                             void          **data,
05241                                             dbus_int32_t   *data_size)
05242 {
05243   dbus_bool_t result;
05244 
05245   _dbus_return_val_if_fail (connection != NULL, FALSE);
05246   _dbus_return_val_if_fail (data != NULL, FALSE);
05247   _dbus_return_val_if_fail (data_size != NULL, FALSE);
05248   
05249   CONNECTION_LOCK (connection);
05250 
05251   if (!_dbus_transport_get_is_authenticated (connection->transport))
05252     result = FALSE;
05253   else
05254     result = _dbus_transport_get_adt_audit_session_data (connection->transport,
05255                                                          data,
05256                                                          data_size);
05257   CONNECTION_UNLOCK (connection);
05258 
05259   return result;
05260 }
05261 
05284 void
05285 dbus_connection_set_unix_user_function (DBusConnection             *connection,
05286                                         DBusAllowUnixUserFunction   function,
05287                                         void                       *data,
05288                                         DBusFreeFunction            free_data_function)
05289 {
05290   void *old_data = NULL;
05291   DBusFreeFunction old_free_function = NULL;
05292 
05293   _dbus_return_if_fail (connection != NULL);
05294   
05295   CONNECTION_LOCK (connection);
05296   _dbus_transport_set_unix_user_function (connection->transport,
05297                                           function, data, free_data_function,
05298                                           &old_data, &old_free_function);
05299   CONNECTION_UNLOCK (connection);
05300 
05301   if (old_free_function != NULL)
05302     (* old_free_function) (old_data);
05303 }
05304 
05336 dbus_bool_t
05337 dbus_connection_get_windows_user (DBusConnection             *connection,
05338                                   char                      **windows_sid_p)
05339 {
05340   dbus_bool_t result;
05341 
05342   _dbus_return_val_if_fail (connection != NULL, FALSE);
05343   _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
05344   
05345   CONNECTION_LOCK (connection);
05346 
05347   if (!_dbus_transport_get_is_authenticated (connection->transport))
05348     result = FALSE;
05349   else
05350     result = _dbus_transport_get_windows_user (connection->transport,
05351                                                windows_sid_p);
05352 
05353 #ifdef DBUS_UNIX
05354   _dbus_assert (!result);
05355 #endif
05356   
05357   CONNECTION_UNLOCK (connection);
05358 
05359   return result;
05360 }
05361 
05383 void
05384 dbus_connection_set_windows_user_function (DBusConnection              *connection,
05385                                            DBusAllowWindowsUserFunction function,
05386                                            void                        *data,
05387                                            DBusFreeFunction             free_data_function)
05388 {
05389   void *old_data = NULL;
05390   DBusFreeFunction old_free_function = NULL;
05391 
05392   _dbus_return_if_fail (connection != NULL);
05393   
05394   CONNECTION_LOCK (connection);
05395   _dbus_transport_set_windows_user_function (connection->transport,
05396                                              function, data, free_data_function,
05397                                              &old_data, &old_free_function);
05398   CONNECTION_UNLOCK (connection);
05399 
05400   if (old_free_function != NULL)
05401     (* old_free_function) (old_data);
05402 }
05403 
05430 void
05431 dbus_connection_set_allow_anonymous (DBusConnection             *connection,
05432                                      dbus_bool_t                 value)
05433 {
05434   _dbus_return_if_fail (connection != NULL);
05435   
05436   CONNECTION_LOCK (connection);
05437   _dbus_transport_set_allow_anonymous (connection->transport, value);
05438   CONNECTION_UNLOCK (connection);
05439 }
05440 
05458 void
05459 dbus_connection_set_route_peer_messages (DBusConnection             *connection,
05460                                          dbus_bool_t                 value)
05461 {
05462   _dbus_return_if_fail (connection != NULL);
05463   
05464   CONNECTION_LOCK (connection);
05465   connection->route_peer_messages = value;
05466   CONNECTION_UNLOCK (connection);
05467 }
05468 
05490 dbus_bool_t
05491 dbus_connection_add_filter (DBusConnection            *connection,
05492                             DBusHandleMessageFunction  function,
05493                             void                      *user_data,
05494                             DBusFreeFunction           free_data_function)
05495 {
05496   DBusMessageFilter *filter;
05497   
05498   _dbus_return_val_if_fail (connection != NULL, FALSE);
05499   _dbus_return_val_if_fail (function != NULL, FALSE);
05500 
05501   filter = dbus_new0 (DBusMessageFilter, 1);
05502   if (filter == NULL)
05503     return FALSE;
05504 
05505   _dbus_atomic_inc (&filter->refcount);
05506 
05507   CONNECTION_LOCK (connection);
05508 
05509   if (!_dbus_list_append (&connection->filter_list,
05510                           filter))
05511     {
05512       _dbus_message_filter_unref (filter);
05513       CONNECTION_UNLOCK (connection);
05514       return FALSE;
05515     }
05516 
05517   /* Fill in filter after all memory allocated,
05518    * so we don't run the free_user_data_function
05519    * if the add_filter() fails
05520    */
05521   
05522   filter->function = function;
05523   filter->user_data = user_data;
05524   filter->free_user_data_function = free_data_function;
05525         
05526   CONNECTION_UNLOCK (connection);
05527   return TRUE;
05528 }
05529 
05542 void
05543 dbus_connection_remove_filter (DBusConnection            *connection,
05544                                DBusHandleMessageFunction  function,
05545                                void                      *user_data)
05546 {
05547   DBusList *link;
05548   DBusMessageFilter *filter;
05549   
05550   _dbus_return_if_fail (connection != NULL);
05551   _dbus_return_if_fail (function != NULL);
05552   
05553   CONNECTION_LOCK (connection);
05554 
05555   filter = NULL;
05556   
05557   link = _dbus_list_get_last_link (&connection->filter_list);
05558   while (link != NULL)
05559     {
05560       filter = link->data;
05561 
05562       if (filter->function == function &&
05563           filter->user_data == user_data)
05564         {
05565           _dbus_list_remove_link (&connection->filter_list, link);
05566           filter->function = NULL;
05567           
05568           break;
05569         }
05570         
05571       link = _dbus_list_get_prev_link (&connection->filter_list, link);
05572       filter = NULL;
05573     }
05574   
05575   CONNECTION_UNLOCK (connection);
05576 
05577 #ifndef DBUS_DISABLE_CHECKS
05578   if (filter == NULL)
05579     {
05580       _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
05581                                function, user_data);
05582       return;
05583     }
05584 #endif
05585   
05586   /* Call application code */
05587   if (filter->free_user_data_function)
05588     (* filter->free_user_data_function) (filter->user_data);
05589 
05590   filter->free_user_data_function = NULL;
05591   filter->user_data = NULL;
05592   
05593   _dbus_message_filter_unref (filter);
05594 }
05595 
05611 static dbus_bool_t
05612 _dbus_connection_register_object_path (DBusConnection              *connection,
05613                                        dbus_bool_t                  fallback,
05614                                        const char                  *path,
05615                                        const DBusObjectPathVTable  *vtable,
05616                                        void                        *user_data,
05617                                        DBusError                   *error)
05618 {
05619   char **decomposed_path;
05620   dbus_bool_t retval;
05621 
05622   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05623     return FALSE;
05624 
05625   CONNECTION_LOCK (connection);
05626 
05627   retval = _dbus_object_tree_register (connection->objects,
05628                                        fallback,
05629                                        (const char **) decomposed_path, vtable,
05630                                        user_data, error);
05631 
05632   CONNECTION_UNLOCK (connection);
05633 
05634   dbus_free_string_array (decomposed_path);
05635 
05636   return retval;
05637 }
05638 
05651 dbus_bool_t
05652 dbus_connection_try_register_object_path (DBusConnection              *connection,
05653                                           const char                  *path,
05654                                           const DBusObjectPathVTable  *vtable,
05655                                           void                        *user_data,
05656                                           DBusError                   *error)
05657 {
05658   _dbus_return_val_if_fail (connection != NULL, FALSE);
05659   _dbus_return_val_if_fail (path != NULL, FALSE);
05660   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05661   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05662 
05663   return _dbus_connection_register_object_path (connection, FALSE, path, vtable, user_data, error);
05664 }
05665 
05681 dbus_bool_t
05682 dbus_connection_register_object_path (DBusConnection              *connection,
05683                                       const char                  *path,
05684                                       const DBusObjectPathVTable  *vtable,
05685                                       void                        *user_data)
05686 {
05687   dbus_bool_t retval;
05688   DBusError error = DBUS_ERROR_INIT;
05689 
05690   _dbus_return_val_if_fail (connection != NULL, FALSE);
05691   _dbus_return_val_if_fail (path != NULL, FALSE);
05692   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05693   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05694 
05695   retval = _dbus_connection_register_object_path (connection, FALSE, path, vtable, user_data, &error);
05696 
05697   if (dbus_error_has_name (&error, DBUS_ERROR_OBJECT_PATH_IN_USE))
05698     {
05699       _dbus_warn ("%s\n", error.message);
05700       dbus_error_free (&error);
05701       return FALSE;
05702     }
05703 
05704   return retval;
05705 }
05706 
05721 dbus_bool_t
05722 dbus_connection_try_register_fallback (DBusConnection              *connection,
05723                                        const char                  *path,
05724                                        const DBusObjectPathVTable  *vtable,
05725                                        void                        *user_data,
05726                                        DBusError                   *error)
05727 {
05728   _dbus_return_val_if_fail (connection != NULL, FALSE);
05729   _dbus_return_val_if_fail (path != NULL, FALSE);
05730   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05731   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05732 
05733   return _dbus_connection_register_object_path (connection, TRUE, path, vtable, user_data, error);
05734 }
05735 
05753 dbus_bool_t
05754 dbus_connection_register_fallback (DBusConnection              *connection,
05755                                    const char                  *path,
05756                                    const DBusObjectPathVTable  *vtable,
05757                                    void                        *user_data)
05758 {
05759   dbus_bool_t retval;
05760   DBusError error = DBUS_ERROR_INIT;
05761 
05762   _dbus_return_val_if_fail (connection != NULL, FALSE);
05763   _dbus_return_val_if_fail (path != NULL, FALSE);
05764   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05765   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05766 
05767   retval = _dbus_connection_register_object_path (connection, TRUE, path, vtable, user_data, &error);
05768 
05769   if (dbus_error_has_name (&error, DBUS_ERROR_OBJECT_PATH_IN_USE))
05770     {
05771       _dbus_warn ("%s\n", error.message);
05772       dbus_error_free (&error);
05773       return FALSE;
05774     }
05775 
05776   return retval;
05777 }
05778 
05788 dbus_bool_t
05789 dbus_connection_unregister_object_path (DBusConnection              *connection,
05790                                         const char                  *path)
05791 {
05792   char **decomposed_path;
05793 
05794   _dbus_return_val_if_fail (connection != NULL, FALSE);
05795   _dbus_return_val_if_fail (path != NULL, FALSE);
05796   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05797 
05798   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05799       return FALSE;
05800 
05801   CONNECTION_LOCK (connection);
05802 
05803   _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
05804 
05805   dbus_free_string_array (decomposed_path);
05806 
05807   return TRUE;
05808 }
05809 
05820 dbus_bool_t
05821 dbus_connection_get_object_path_data (DBusConnection *connection,
05822                                       const char     *path,
05823                                       void          **data_p)
05824 {
05825   char **decomposed_path;
05826 
05827   _dbus_return_val_if_fail (connection != NULL, FALSE);
05828   _dbus_return_val_if_fail (path != NULL, FALSE);
05829   _dbus_return_val_if_fail (data_p != NULL, FALSE);
05830 
05831   *data_p = NULL;
05832   
05833   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05834     return FALSE;
05835   
05836   CONNECTION_LOCK (connection);
05837 
05838   *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path);
05839 
05840   CONNECTION_UNLOCK (connection);
05841 
05842   dbus_free_string_array (decomposed_path);
05843 
05844   return TRUE;
05845 }
05846 
05857 dbus_bool_t
05858 dbus_connection_list_registered (DBusConnection              *connection,
05859                                  const char                  *parent_path,
05860                                  char                      ***child_entries)
05861 {
05862   char **decomposed_path;
05863   dbus_bool_t retval;
05864   _dbus_return_val_if_fail (connection != NULL, FALSE);
05865   _dbus_return_val_if_fail (parent_path != NULL, FALSE);
05866   _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
05867   _dbus_return_val_if_fail (child_entries != NULL, FALSE);
05868 
05869   if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
05870     return FALSE;
05871 
05872   CONNECTION_LOCK (connection);
05873 
05874   retval = _dbus_object_tree_list_registered_and_unlock (connection->objects,
05875                                                          (const char **) decomposed_path,
05876                                                          child_entries);
05877   dbus_free_string_array (decomposed_path);
05878 
05879   return retval;
05880 }
05881 
05882 static DBusDataSlotAllocator slot_allocator;
05883 _DBUS_DEFINE_GLOBAL_LOCK (connection_slots);
05884 
05899 dbus_bool_t
05900 dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
05901 {
05902   return _dbus_data_slot_allocator_alloc (&slot_allocator,
05903                                           &_DBUS_LOCK_NAME (connection_slots),
05904                                           slot_p);
05905 }
05906 
05918 void
05919 dbus_connection_free_data_slot (dbus_int32_t *slot_p)
05920 {
05921   _dbus_return_if_fail (*slot_p >= 0);
05922   
05923   _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
05924 }
05925 
05948 dbus_bool_t
05949 dbus_connection_set_data (DBusConnection   *connection,
05950                           dbus_int32_t      slot,
05951                           void             *data,
05952                           DBusFreeFunction  free_data_func)
05953 {
05954   DBusFreeFunction old_free_func;
05955   void *old_data;
05956   dbus_bool_t retval;
05957 
05958   _dbus_return_val_if_fail (connection != NULL, FALSE);
05959   _dbus_return_val_if_fail (slot >= 0, FALSE);
05960   
05961   SLOTS_LOCK (connection);
05962 
05963   retval = _dbus_data_slot_list_set (&slot_allocator,
05964                                      &connection->slot_list,
05965                                      slot, data, free_data_func,
05966                                      &old_free_func, &old_data);
05967   
05968   SLOTS_UNLOCK (connection);
05969 
05970   if (retval)
05971     {
05972       /* Do the actual free outside the connection lock */
05973       if (old_free_func)
05974         (* old_free_func) (old_data);
05975     }
05976 
05977   return retval;
05978 }
05979 
05997 void*
05998 dbus_connection_get_data (DBusConnection   *connection,
05999                           dbus_int32_t      slot)
06000 {
06001   void *res;
06002 
06003   _dbus_return_val_if_fail (connection != NULL, NULL);
06004   _dbus_return_val_if_fail (slot >= 0, NULL);
06005 
06006   SLOTS_LOCK (connection);
06007 
06008   res = _dbus_data_slot_list_get (&slot_allocator,
06009                                   &connection->slot_list,
06010                                   slot);
06011   
06012   SLOTS_UNLOCK (connection);
06013 
06014   return res;
06015 }
06016 
06023 void
06024 dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
06025 {  
06026   _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
06027 }
06028 
06037 void
06038 dbus_connection_set_max_message_size (DBusConnection *connection,
06039                                       long            size)
06040 {
06041   _dbus_return_if_fail (connection != NULL);
06042   
06043   CONNECTION_LOCK (connection);
06044   _dbus_transport_set_max_message_size (connection->transport,
06045                                         size);
06046   CONNECTION_UNLOCK (connection);
06047 }
06048 
06055 long
06056 dbus_connection_get_max_message_size (DBusConnection *connection)
06057 {
06058   long res;
06059 
06060   _dbus_return_val_if_fail (connection != NULL, 0);
06061   
06062   CONNECTION_LOCK (connection);
06063   res = _dbus_transport_get_max_message_size (connection->transport);
06064   CONNECTION_UNLOCK (connection);
06065   return res;
06066 }
06067 
06076 void
06077 dbus_connection_set_max_message_unix_fds (DBusConnection *connection,
06078                                           long            n)
06079 {
06080   _dbus_return_if_fail (connection != NULL);
06081 
06082   CONNECTION_LOCK (connection);
06083   _dbus_transport_set_max_message_unix_fds (connection->transport,
06084                                             n);
06085   CONNECTION_UNLOCK (connection);
06086 }
06087 
06094 long
06095 dbus_connection_get_max_message_unix_fds (DBusConnection *connection)
06096 {
06097   long res;
06098 
06099   _dbus_return_val_if_fail (connection != NULL, 0);
06100 
06101   CONNECTION_LOCK (connection);
06102   res = _dbus_transport_get_max_message_unix_fds (connection->transport);
06103   CONNECTION_UNLOCK (connection);
06104   return res;
06105 }
06106 
06132 void
06133 dbus_connection_set_max_received_size (DBusConnection *connection,
06134                                        long            size)
06135 {
06136   _dbus_return_if_fail (connection != NULL);
06137   
06138   CONNECTION_LOCK (connection);
06139   _dbus_transport_set_max_received_size (connection->transport,
06140                                          size);
06141   CONNECTION_UNLOCK (connection);
06142 }
06143 
06150 long
06151 dbus_connection_get_max_received_size (DBusConnection *connection)
06152 {
06153   long res;
06154 
06155   _dbus_return_val_if_fail (connection != NULL, 0);
06156   
06157   CONNECTION_LOCK (connection);
06158   res = _dbus_transport_get_max_received_size (connection->transport);
06159   CONNECTION_UNLOCK (connection);
06160   return res;
06161 }
06162 
06174 void
06175 dbus_connection_set_max_received_unix_fds (DBusConnection *connection,
06176                                            long            n)
06177 {
06178   _dbus_return_if_fail (connection != NULL);
06179 
06180   CONNECTION_LOCK (connection);
06181   _dbus_transport_set_max_received_unix_fds (connection->transport,
06182                                              n);
06183   CONNECTION_UNLOCK (connection);
06184 }
06185 
06192 long
06193 dbus_connection_get_max_received_unix_fds (DBusConnection *connection)
06194 {
06195   long res;
06196 
06197   _dbus_return_val_if_fail (connection != NULL, 0);
06198 
06199   CONNECTION_LOCK (connection);
06200   res = _dbus_transport_get_max_received_unix_fds (connection->transport);
06201   CONNECTION_UNLOCK (connection);
06202   return res;
06203 }
06204 
06215 long
06216 dbus_connection_get_outgoing_size (DBusConnection *connection)
06217 {
06218   long res;
06219 
06220   _dbus_return_val_if_fail (connection != NULL, 0);
06221 
06222   CONNECTION_LOCK (connection);
06223   res = _dbus_counter_get_size_value (connection->outgoing_counter);
06224   CONNECTION_UNLOCK (connection);
06225   return res;
06226 }
06227 
06228 #ifdef DBUS_ENABLE_STATS
06229 void
06230 _dbus_connection_get_stats (DBusConnection *connection,
06231                             dbus_uint32_t  *in_messages,
06232                             dbus_uint32_t  *in_bytes,
06233                             dbus_uint32_t  *in_fds,
06234                             dbus_uint32_t  *in_peak_bytes,
06235                             dbus_uint32_t  *in_peak_fds,
06236                             dbus_uint32_t  *out_messages,
06237                             dbus_uint32_t  *out_bytes,
06238                             dbus_uint32_t  *out_fds,
06239                             dbus_uint32_t  *out_peak_bytes,
06240                             dbus_uint32_t  *out_peak_fds)
06241 {
06242   CONNECTION_LOCK (connection);
06243 
06244   if (in_messages != NULL)
06245     *in_messages = connection->n_incoming;
06246 
06247   _dbus_transport_get_stats (connection->transport,
06248                              in_bytes, in_fds, in_peak_bytes, in_peak_fds);
06249 
06250   if (out_messages != NULL)
06251     *out_messages = connection->n_outgoing;
06252 
06253   if (out_bytes != NULL)
06254     *out_bytes = _dbus_counter_get_size_value (connection->outgoing_counter);
06255 
06256   if (out_fds != NULL)
06257     *out_fds = _dbus_counter_get_unix_fd_value (connection->outgoing_counter);
06258 
06259   if (out_peak_bytes != NULL)
06260     *out_peak_bytes = _dbus_counter_get_peak_size_value (connection->outgoing_counter);
06261 
06262   if (out_peak_fds != NULL)
06263     *out_peak_fds = _dbus_counter_get_peak_unix_fd_value (connection->outgoing_counter);
06264 
06265   CONNECTION_UNLOCK (connection);
06266 }
06267 #endif /* DBUS_ENABLE_STATS */
06268 
06276 long
06277 dbus_connection_get_outgoing_unix_fds (DBusConnection *connection)
06278 {
06279   long res;
06280 
06281   _dbus_return_val_if_fail (connection != NULL, 0);
06282 
06283   CONNECTION_LOCK (connection);
06284   res = _dbus_counter_get_unix_fd_value (connection->outgoing_counter);
06285   CONNECTION_UNLOCK (connection);
06286   return res;
06287 }
06288 
06289 #ifdef DBUS_BUILD_TESTS
06290 
06296 const char*
06297 _dbus_connection_get_address (DBusConnection *connection)
06298 {
06299   return _dbus_transport_get_address (connection->transport);
06300 }
06301 #endif
06302