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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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-threads.h"
00037 #include "dbus-protocol.h"
00038 #include "dbus-dataslot.h"
00039 #include "dbus-string.h"
00040 #include "dbus-pending-call.h"
00041 #include "dbus-object-tree.h"
00042 #include "dbus-threads-internal.h"
00043 #include "dbus-bus.h"
00044 
00045 #ifdef DBUS_DISABLE_CHECKS
00046 #define TOOK_LOCK_CHECK(connection)
00047 #define RELEASING_LOCK_CHECK(connection)
00048 #define HAVE_LOCK_CHECK(connection)
00049 #else
00050 #define TOOK_LOCK_CHECK(connection) do {                \
00051     _dbus_assert (!(connection)->have_connection_lock); \
00052     (connection)->have_connection_lock = TRUE;          \
00053   } while (0)
00054 #define RELEASING_LOCK_CHECK(connection) do {            \
00055     _dbus_assert ((connection)->have_connection_lock);   \
00056     (connection)->have_connection_lock = FALSE;          \
00057   } while (0)
00058 #define HAVE_LOCK_CHECK(connection)        _dbus_assert ((connection)->have_connection_lock)
00059 /* A "DO_NOT_HAVE_LOCK_CHECK" is impossible since we need the lock to check the flag */
00060 #endif
00061 
00062 #define TRACE_LOCKS 1
00063 
00064 #define CONNECTION_LOCK(connection)   do {                                      \
00065     if (TRACE_LOCKS) { _dbus_verbose ("  LOCK: %s\n", _DBUS_FUNCTION_NAME); }   \
00066     _dbus_mutex_lock ((connection)->mutex);                                      \
00067     TOOK_LOCK_CHECK (connection);                                               \
00068   } while (0)
00069 
00070 #define CONNECTION_UNLOCK(connection) do {                                              \
00071     if (TRACE_LOCKS) { _dbus_verbose ("  UNLOCK: %s\n", _DBUS_FUNCTION_NAME);  }        \
00072     RELEASING_LOCK_CHECK (connection);                                                  \
00073     _dbus_mutex_unlock ((connection)->mutex);                                            \
00074   } while (0)
00075 
00076 #define DISPATCH_STATUS_NAME(s)                                            \
00077                      ((s) == DBUS_DISPATCH_COMPLETE ? "complete" :         \
00078                       (s) == DBUS_DISPATCH_DATA_REMAINS ? "data remains" : \
00079                       (s) == DBUS_DISPATCH_NEED_MEMORY ? "need memory" :   \
00080                       "???")
00081 
00202 typedef struct DBusMessageFilter DBusMessageFilter;
00203 
00207 struct DBusMessageFilter
00208 {
00209   DBusAtomic refcount; 
00210   DBusHandleMessageFunction function; 
00211   void *user_data; 
00212   DBusFreeFunction free_user_data_function; 
00213 };
00214 
00215 
00219 struct DBusPreallocatedSend
00220 {
00221   DBusConnection *connection; 
00222   DBusList *queue_link;       
00223   DBusList *counter_link;     
00224 };
00225 
00226 static dbus_bool_t _dbus_modify_sigpipe = TRUE;
00227 
00231 struct DBusConnection
00232 {
00233   DBusAtomic refcount; 
00235   DBusMutex *mutex; 
00237   DBusMutex *dispatch_mutex;     
00238   DBusCondVar *dispatch_cond;    
00239   DBusMutex *io_path_mutex;      
00240   DBusCondVar *io_path_cond;     
00242   DBusList *outgoing_messages; 
00243   DBusList *incoming_messages; 
00245   DBusMessage *message_borrowed; 
00249   int n_outgoing;              
00250   int n_incoming;              
00252   DBusCounter *outgoing_counter; 
00254   DBusTransport *transport;    
00255   DBusWatchList *watches;      
00256   DBusTimeoutList *timeouts;   
00258   DBusList *filter_list;        
00260   DBusDataSlotList slot_list;   
00262   DBusHashTable *pending_replies;  
00264   dbus_uint32_t client_serial;       
00265   DBusList *disconnect_message_link; 
00267   DBusWakeupMainFunction wakeup_main_function; 
00268   void *wakeup_main_data; 
00269   DBusFreeFunction free_wakeup_main_data; 
00271   DBusDispatchStatusFunction dispatch_status_function; 
00272   void *dispatch_status_data; 
00273   DBusFreeFunction free_dispatch_status_data; 
00275   DBusDispatchStatus last_dispatch_status; 
00277   DBusList *link_cache; 
00280   DBusObjectTree *objects; 
00282   char *server_guid; 
00284   /* These two MUST be bools and not bitfields, because they are protected by a separate lock
00285    * from connection->mutex and all bitfields in a word have to be read/written together.
00286    * So you can't have a different lock for different bitfields in the same word.
00287    */
00288   dbus_bool_t dispatch_acquired; 
00289   dbus_bool_t io_path_acquired;  
00291   unsigned int shareable : 1; 
00293   unsigned int exit_on_disconnect : 1; 
00295   unsigned int route_peer_messages : 1; 
00297   unsigned int disconnected_message_arrived : 1;   
00301   unsigned int disconnected_message_processed : 1; 
00305 #ifndef DBUS_DISABLE_CHECKS
00306   unsigned int have_connection_lock : 1; 
00307 #endif
00308   
00309 #ifndef DBUS_DISABLE_CHECKS
00310   int generation; 
00311 #endif 
00312 };
00313 
00314 static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked      (DBusConnection     *connection);
00315 static void               _dbus_connection_update_dispatch_status_and_unlock (DBusConnection     *connection,
00316                                                                               DBusDispatchStatus  new_status);
00317 static void               _dbus_connection_last_unref                        (DBusConnection     *connection);
00318 static void               _dbus_connection_acquire_dispatch                  (DBusConnection     *connection);
00319 static void               _dbus_connection_release_dispatch                  (DBusConnection     *connection);
00320 static DBusDispatchStatus _dbus_connection_flush_unlocked                    (DBusConnection     *connection);
00321 static void               _dbus_connection_close_possibly_shared_and_unlock  (DBusConnection     *connection);
00322 static dbus_bool_t        _dbus_connection_get_is_connected_unlocked         (DBusConnection     *connection);
00323 
00324 static DBusMessageFilter *
00325 _dbus_message_filter_ref (DBusMessageFilter *filter)
00326 {
00327   _dbus_assert (filter->refcount.value > 0);
00328   _dbus_atomic_inc (&filter->refcount);
00329 
00330   return filter;
00331 }
00332 
00333 static void
00334 _dbus_message_filter_unref (DBusMessageFilter *filter)
00335 {
00336   _dbus_assert (filter->refcount.value > 0);
00337 
00338   if (_dbus_atomic_dec (&filter->refcount) == 1)
00339     {
00340       if (filter->free_user_data_function)
00341         (* filter->free_user_data_function) (filter->user_data);
00342       
00343       dbus_free (filter);
00344     }
00345 }
00346 
00352 void
00353 _dbus_connection_lock (DBusConnection *connection)
00354 {
00355   CONNECTION_LOCK (connection);
00356 }
00357 
00363 void
00364 _dbus_connection_unlock (DBusConnection *connection)
00365 {
00366   CONNECTION_UNLOCK (connection);
00367 }
00368 
00376 static void
00377 _dbus_connection_wakeup_mainloop (DBusConnection *connection)
00378 {
00379   if (connection->wakeup_main_function)
00380     (*connection->wakeup_main_function) (connection->wakeup_main_data);
00381 }
00382 
00383 #ifdef DBUS_BUILD_TESTS
00384 /* For now this function isn't used */
00394 dbus_bool_t
00395 _dbus_connection_queue_received_message (DBusConnection *connection,
00396                                          DBusMessage    *message)
00397 {
00398   DBusList *link;
00399 
00400   link = _dbus_list_alloc_link (message);
00401   if (link == NULL)
00402     return FALSE;
00403 
00404   dbus_message_ref (message);
00405   _dbus_connection_queue_received_message_link (connection, link);
00406 
00407   return TRUE;
00408 }
00409 
00422 void 
00423 _dbus_connection_test_get_locks (DBusConnection *connection,
00424                                  DBusMutex     **mutex_loc,
00425                                  DBusMutex     **dispatch_mutex_loc,
00426                                  DBusMutex     **io_path_mutex_loc,
00427                                  DBusCondVar   **dispatch_cond_loc,
00428                                  DBusCondVar   **io_path_cond_loc)
00429 {
00430   *mutex_loc = connection->mutex;
00431   *dispatch_mutex_loc = connection->dispatch_mutex;
00432   *io_path_mutex_loc = connection->io_path_mutex; 
00433   *dispatch_cond_loc = connection->dispatch_cond;
00434   *io_path_cond_loc = connection->io_path_cond;
00435 }
00436 #endif
00437 
00446 void
00447 _dbus_connection_queue_received_message_link (DBusConnection  *connection,
00448                                               DBusList        *link)
00449 {
00450   DBusPendingCall *pending;
00451   dbus_int32_t reply_serial;
00452   DBusMessage *message;
00453   
00454   _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport));
00455   
00456   _dbus_list_append_link (&connection->incoming_messages,
00457                           link);
00458   message = link->data;
00459 
00460   /* If this is a reply we're waiting on, remove timeout for it */
00461   reply_serial = dbus_message_get_reply_serial (message);
00462   if (reply_serial != -1)
00463     {
00464       pending = _dbus_hash_table_lookup_int (connection->pending_replies,
00465                                              reply_serial);
00466       if (pending != NULL)
00467         {
00468           if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00469             _dbus_connection_remove_timeout_unlocked (connection,
00470                                                       _dbus_pending_call_get_timeout_unlocked (pending));
00471 
00472           _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00473         }
00474     }
00475   
00476   
00477 
00478   connection->n_incoming += 1;
00479 
00480   _dbus_connection_wakeup_mainloop (connection);
00481   
00482   _dbus_verbose ("Message %p (%d %s %s %s '%s' reply to %u) added to incoming queue %p, %d incoming\n",
00483                  message,
00484                  dbus_message_get_type (message),
00485                  dbus_message_get_path (message) ?
00486                  dbus_message_get_path (message) :
00487                  "no path",
00488                  dbus_message_get_interface (message) ?
00489                  dbus_message_get_interface (message) :
00490                  "no interface",
00491                  dbus_message_get_member (message) ?
00492                  dbus_message_get_member (message) :
00493                  "no member",
00494                  dbus_message_get_signature (message),
00495                  dbus_message_get_reply_serial (message),
00496                  connection,
00497                  connection->n_incoming);}
00498 
00507 void
00508 _dbus_connection_queue_synthesized_message_link (DBusConnection *connection,
00509                                                  DBusList *link)
00510 {
00511   HAVE_LOCK_CHECK (connection);
00512   
00513   _dbus_list_append_link (&connection->incoming_messages, link);
00514 
00515   connection->n_incoming += 1;
00516 
00517   _dbus_connection_wakeup_mainloop (connection);
00518   
00519   _dbus_verbose ("Synthesized message %p added to incoming queue %p, %d incoming\n",
00520                  link->data, connection, connection->n_incoming);
00521 }
00522 
00523 
00531 dbus_bool_t
00532 _dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection)
00533 {
00534   HAVE_LOCK_CHECK (connection);
00535   return connection->outgoing_messages != NULL;
00536 }
00537 
00547 dbus_bool_t
00548 dbus_connection_has_messages_to_send (DBusConnection *connection)
00549 {
00550   dbus_bool_t v;
00551   
00552   _dbus_return_val_if_fail (connection != NULL, FALSE);
00553 
00554   CONNECTION_LOCK (connection);
00555   v = _dbus_connection_has_messages_to_send_unlocked (connection);
00556   CONNECTION_UNLOCK (connection);
00557 
00558   return v;
00559 }
00560 
00568 DBusMessage*
00569 _dbus_connection_get_message_to_send (DBusConnection *connection)
00570 {
00571   HAVE_LOCK_CHECK (connection);
00572   
00573   return _dbus_list_get_last (&connection->outgoing_messages);
00574 }
00575 
00584 void
00585 _dbus_connection_message_sent (DBusConnection *connection,
00586                                DBusMessage    *message)
00587 {
00588   DBusList *link;
00589 
00590   HAVE_LOCK_CHECK (connection);
00591   
00592   /* This can be called before we even complete authentication, since
00593    * it's called on disconnect to clean up the outgoing queue.
00594    * It's also called as we successfully send each message.
00595    */
00596   
00597   link = _dbus_list_get_last_link (&connection->outgoing_messages);
00598   _dbus_assert (link != NULL);
00599   _dbus_assert (link->data == message);
00600 
00601   /* Save this link in the link cache */
00602   _dbus_list_unlink (&connection->outgoing_messages,
00603                      link);
00604   _dbus_list_prepend_link (&connection->link_cache, link);
00605   
00606   connection->n_outgoing -= 1;
00607 
00608   _dbus_verbose ("Message %p (%d %s %s %s '%s') removed from outgoing queue %p, %d left to send\n",
00609                  message,
00610                  dbus_message_get_type (message),
00611                  dbus_message_get_path (message) ?
00612                  dbus_message_get_path (message) :
00613                  "no path",
00614                  dbus_message_get_interface (message) ?
00615                  dbus_message_get_interface (message) :
00616                  "no interface",
00617                  dbus_message_get_member (message) ?
00618                  dbus_message_get_member (message) :
00619                  "no member",
00620                  dbus_message_get_signature (message),
00621                  connection, connection->n_outgoing);
00622 
00623   /* Save this link in the link cache also */
00624   _dbus_message_remove_size_counter (message, connection->outgoing_counter,
00625                                      &link);
00626   _dbus_list_prepend_link (&connection->link_cache, link);
00627   
00628   dbus_message_unref (message);
00629 }
00630 
00632 typedef dbus_bool_t (* DBusWatchAddFunction)     (DBusWatchList *list,
00633                                                   DBusWatch     *watch);
00635 typedef void        (* DBusWatchRemoveFunction)  (DBusWatchList *list,
00636                                                   DBusWatch     *watch);
00638 typedef void        (* DBusWatchToggleFunction)  (DBusWatchList *list,
00639                                                   DBusWatch     *watch,
00640                                                   dbus_bool_t    enabled);
00641 
00642 static dbus_bool_t
00643 protected_change_watch (DBusConnection         *connection,
00644                         DBusWatch              *watch,
00645                         DBusWatchAddFunction    add_function,
00646                         DBusWatchRemoveFunction remove_function,
00647                         DBusWatchToggleFunction toggle_function,
00648                         dbus_bool_t             enabled)
00649 {
00650   DBusWatchList *watches;
00651   dbus_bool_t retval;
00652   
00653   HAVE_LOCK_CHECK (connection);
00654 
00655   /* This isn't really safe or reasonable; a better pattern is the "do everything, then
00656    * drop lock and call out" one; but it has to be propagated up through all callers
00657    */
00658   
00659   watches = connection->watches;
00660   if (watches)
00661     {
00662       connection->watches = NULL;
00663       _dbus_connection_ref_unlocked (connection);
00664       CONNECTION_UNLOCK (connection);
00665 
00666       if (add_function)
00667         retval = (* add_function) (watches, watch);
00668       else if (remove_function)
00669         {
00670           retval = TRUE;
00671           (* remove_function) (watches, watch);
00672         }
00673       else
00674         {
00675           retval = TRUE;
00676           (* toggle_function) (watches, watch, enabled);
00677         }
00678       
00679       CONNECTION_LOCK (connection);
00680       connection->watches = watches;
00681       _dbus_connection_unref_unlocked (connection);
00682 
00683       return retval;
00684     }
00685   else
00686     return FALSE;
00687 }
00688      
00689 
00701 dbus_bool_t
00702 _dbus_connection_add_watch_unlocked (DBusConnection *connection,
00703                                      DBusWatch      *watch)
00704 {
00705   return protected_change_watch (connection, watch,
00706                                  _dbus_watch_list_add_watch,
00707                                  NULL, NULL, FALSE);
00708 }
00709 
00719 void
00720 _dbus_connection_remove_watch_unlocked (DBusConnection *connection,
00721                                         DBusWatch      *watch)
00722 {
00723   protected_change_watch (connection, watch,
00724                           NULL,
00725                           _dbus_watch_list_remove_watch,
00726                           NULL, FALSE);
00727 }
00728 
00739 void
00740 _dbus_connection_toggle_watch_unlocked (DBusConnection *connection,
00741                                         DBusWatch      *watch,
00742                                         dbus_bool_t     enabled)
00743 {
00744   _dbus_assert (watch != NULL);
00745 
00746   protected_change_watch (connection, watch,
00747                           NULL, NULL,
00748                           _dbus_watch_list_toggle_watch,
00749                           enabled);
00750 }
00751 
00753 typedef dbus_bool_t (* DBusTimeoutAddFunction)    (DBusTimeoutList *list,
00754                                                    DBusTimeout     *timeout);
00756 typedef void        (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list,
00757                                                    DBusTimeout     *timeout);
00759 typedef void        (* DBusTimeoutToggleFunction) (DBusTimeoutList *list,
00760                                                    DBusTimeout     *timeout,
00761                                                    dbus_bool_t      enabled);
00762 
00763 static dbus_bool_t
00764 protected_change_timeout (DBusConnection           *connection,
00765                           DBusTimeout              *timeout,
00766                           DBusTimeoutAddFunction    add_function,
00767                           DBusTimeoutRemoveFunction remove_function,
00768                           DBusTimeoutToggleFunction toggle_function,
00769                           dbus_bool_t               enabled)
00770 {
00771   DBusTimeoutList *timeouts;
00772   dbus_bool_t retval;
00773   
00774   HAVE_LOCK_CHECK (connection);
00775 
00776   /* This isn't really safe or reasonable; a better pattern is the "do everything, then
00777    * drop lock and call out" one; but it has to be propagated up through all callers
00778    */
00779   
00780   timeouts = connection->timeouts;
00781   if (timeouts)
00782     {
00783       connection->timeouts = NULL;
00784       _dbus_connection_ref_unlocked (connection);
00785       CONNECTION_UNLOCK (connection);
00786 
00787       if (add_function)
00788         retval = (* add_function) (timeouts, timeout);
00789       else if (remove_function)
00790         {
00791           retval = TRUE;
00792           (* remove_function) (timeouts, timeout);
00793         }
00794       else
00795         {
00796           retval = TRUE;
00797           (* toggle_function) (timeouts, timeout, enabled);
00798         }
00799       
00800       CONNECTION_LOCK (connection);
00801       connection->timeouts = timeouts;
00802       _dbus_connection_unref_unlocked (connection);
00803 
00804       return retval;
00805     }
00806   else
00807     return FALSE;
00808 }
00809 
00822 dbus_bool_t
00823 _dbus_connection_add_timeout_unlocked (DBusConnection *connection,
00824                                        DBusTimeout    *timeout)
00825 {
00826   return protected_change_timeout (connection, timeout,
00827                                    _dbus_timeout_list_add_timeout,
00828                                    NULL, NULL, FALSE);
00829 }
00830 
00840 void
00841 _dbus_connection_remove_timeout_unlocked (DBusConnection *connection,
00842                                           DBusTimeout    *timeout)
00843 {
00844   protected_change_timeout (connection, timeout,
00845                             NULL,
00846                             _dbus_timeout_list_remove_timeout,
00847                             NULL, FALSE);
00848 }
00849 
00860 void
00861 _dbus_connection_toggle_timeout_unlocked (DBusConnection   *connection,
00862                                           DBusTimeout      *timeout,
00863                                           dbus_bool_t       enabled)
00864 {
00865   protected_change_timeout (connection, timeout,
00866                             NULL, NULL,
00867                             _dbus_timeout_list_toggle_timeout,
00868                             enabled);
00869 }
00870 
00871 static dbus_bool_t
00872 _dbus_connection_attach_pending_call_unlocked (DBusConnection  *connection,
00873                                                DBusPendingCall *pending)
00874 {
00875   dbus_uint32_t reply_serial;
00876   DBusTimeout *timeout;
00877 
00878   HAVE_LOCK_CHECK (connection);
00879 
00880   reply_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
00881 
00882   _dbus_assert (reply_serial != 0);
00883 
00884   timeout = _dbus_pending_call_get_timeout_unlocked (pending);
00885 
00886   if (!_dbus_connection_add_timeout_unlocked (connection, timeout))
00887     return FALSE;
00888   
00889   if (!_dbus_hash_table_insert_int (connection->pending_replies,
00890                                     reply_serial,
00891                                     pending))
00892     {
00893       _dbus_connection_remove_timeout_unlocked (connection, timeout);
00894 
00895       _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00896       HAVE_LOCK_CHECK (connection);
00897       return FALSE;
00898     }
00899   
00900   _dbus_pending_call_set_timeout_added_unlocked (pending, TRUE);
00901 
00902   _dbus_pending_call_ref_unlocked (pending);
00903 
00904   HAVE_LOCK_CHECK (connection);
00905   
00906   return TRUE;
00907 }
00908 
00909 static void
00910 free_pending_call_on_hash_removal (void *data)
00911 {
00912   DBusPendingCall *pending;
00913   DBusConnection  *connection;
00914   
00915   if (data == NULL)
00916     return;
00917 
00918   pending = data;
00919 
00920   connection = _dbus_pending_call_get_connection_unlocked (pending);
00921 
00922   HAVE_LOCK_CHECK (connection);
00923   
00924   if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00925     {
00926       _dbus_connection_remove_timeout_unlocked (connection,
00927                                                 _dbus_pending_call_get_timeout_unlocked (pending));
00928       
00929       _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00930     }
00931 
00932   /* FIXME 1.0? this is sort of dangerous and undesirable to drop the lock 
00933    * here, but the pending call finalizer could in principle call out to 
00934    * application code so we pretty much have to... some larger code reorg 
00935    * might be needed.
00936    */
00937   _dbus_connection_ref_unlocked (connection);
00938   _dbus_pending_call_unref_and_unlock (pending);
00939   CONNECTION_LOCK (connection);
00940   _dbus_connection_unref_unlocked (connection);
00941 }
00942 
00943 static void
00944 _dbus_connection_detach_pending_call_unlocked (DBusConnection  *connection,
00945                                                DBusPendingCall *pending)
00946 {
00947   /* This ends up unlocking to call the pending call finalizer, which is unexpected to
00948    * say the least.
00949    */
00950   _dbus_hash_table_remove_int (connection->pending_replies,
00951                                _dbus_pending_call_get_reply_serial_unlocked (pending));
00952 }
00953 
00954 static void
00955 _dbus_connection_detach_pending_call_and_unlock (DBusConnection  *connection,
00956                                                  DBusPendingCall *pending)
00957 {
00958   /* The idea here is to avoid finalizing the pending call
00959    * with the lock held, since there's a destroy notifier
00960    * in pending call that goes out to application code.
00961    *
00962    * There's an extra unlock inside the hash table
00963    * "free pending call" function FIXME...
00964    */
00965   _dbus_pending_call_ref_unlocked (pending);
00966   _dbus_hash_table_remove_int (connection->pending_replies,
00967                                _dbus_pending_call_get_reply_serial_unlocked (pending));
00968 
00969   if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00970       _dbus_connection_remove_timeout_unlocked (connection,
00971               _dbus_pending_call_get_timeout_unlocked (pending));
00972 
00973   _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00974 
00975   _dbus_pending_call_unref_and_unlock (pending);
00976 }
00977 
00986 void
00987 _dbus_connection_remove_pending_call (DBusConnection  *connection,
00988                                       DBusPendingCall *pending)
00989 {
00990   CONNECTION_LOCK (connection);
00991   _dbus_connection_detach_pending_call_and_unlock (connection, pending);
00992 }
00993 
01003 static dbus_bool_t
01004 _dbus_connection_acquire_io_path (DBusConnection *connection,
01005                                   int             timeout_milliseconds)
01006 {
01007   dbus_bool_t we_acquired;
01008   
01009   HAVE_LOCK_CHECK (connection);
01010 
01011   /* We don't want the connection to vanish */
01012   _dbus_connection_ref_unlocked (connection);
01013 
01014   /* We will only touch io_path_acquired which is protected by our mutex */
01015   CONNECTION_UNLOCK (connection);
01016   
01017   _dbus_verbose ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME);
01018   _dbus_mutex_lock (connection->io_path_mutex);
01019 
01020   _dbus_verbose ("%s start connection->io_path_acquired = %d timeout = %d\n",
01021                  _DBUS_FUNCTION_NAME, connection->io_path_acquired, timeout_milliseconds);
01022 
01023   we_acquired = FALSE;
01024   
01025   if (connection->io_path_acquired)
01026     {
01027       if (timeout_milliseconds != -1)
01028         {
01029           _dbus_verbose ("%s waiting %d for IO path to be acquirable\n",
01030                          _DBUS_FUNCTION_NAME, timeout_milliseconds);
01031 
01032           if (!_dbus_condvar_wait_timeout (connection->io_path_cond,
01033                                            connection->io_path_mutex,
01034                                            timeout_milliseconds))
01035             {
01036               /* We timed out before anyone signaled. */
01037               /* (writing the loop to handle the !timedout case by
01038                * waiting longer if needed is a pain since dbus
01039                * wraps pthread_cond_timedwait to take a relative
01040                * time instead of absolute, something kind of stupid
01041                * on our part. for now it doesn't matter, we will just
01042                * end up back here eventually.)
01043                */
01044             }
01045         }
01046       else
01047         {
01048           while (connection->io_path_acquired)
01049             {
01050               _dbus_verbose ("%s waiting for IO path to be acquirable\n", _DBUS_FUNCTION_NAME);
01051               _dbus_condvar_wait (connection->io_path_cond, 
01052                                   connection->io_path_mutex);
01053             }
01054         }
01055     }
01056   
01057   if (!connection->io_path_acquired)
01058     {
01059       we_acquired = TRUE;
01060       connection->io_path_acquired = TRUE;
01061     }
01062   
01063   _dbus_verbose ("%s end connection->io_path_acquired = %d we_acquired = %d\n",
01064                  _DBUS_FUNCTION_NAME, connection->io_path_acquired, we_acquired);
01065 
01066   _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME);
01067   _dbus_mutex_unlock (connection->io_path_mutex);
01068 
01069   CONNECTION_LOCK (connection);
01070   
01071   HAVE_LOCK_CHECK (connection);
01072 
01073   _dbus_connection_unref_unlocked (connection);
01074   
01075   return we_acquired;
01076 }
01077 
01085 static void
01086 _dbus_connection_release_io_path (DBusConnection *connection)
01087 {
01088   HAVE_LOCK_CHECK (connection);
01089   
01090   _dbus_verbose ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME);
01091   _dbus_mutex_lock (connection->io_path_mutex);
01092   
01093   _dbus_assert (connection->io_path_acquired);
01094 
01095   _dbus_verbose ("%s start connection->io_path_acquired = %d\n",
01096                  _DBUS_FUNCTION_NAME, connection->io_path_acquired);
01097   
01098   connection->io_path_acquired = FALSE;
01099   _dbus_condvar_wake_one (connection->io_path_cond);
01100 
01101   _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME);
01102   _dbus_mutex_unlock (connection->io_path_mutex);
01103 }
01104 
01133 void
01134 _dbus_connection_do_iteration_unlocked (DBusConnection *connection,
01135                                         unsigned int    flags,
01136                                         int             timeout_milliseconds)
01137 {
01138   _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
01139   
01140   HAVE_LOCK_CHECK (connection);
01141   
01142   if (connection->n_outgoing == 0)
01143     flags &= ~DBUS_ITERATION_DO_WRITING;
01144 
01145   if (_dbus_connection_acquire_io_path (connection,
01146                                         (flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0))
01147     {
01148       HAVE_LOCK_CHECK (connection);
01149       
01150       _dbus_transport_do_iteration (connection->transport,
01151                                     flags, timeout_milliseconds);
01152       _dbus_connection_release_io_path (connection);
01153     }
01154 
01155   HAVE_LOCK_CHECK (connection);
01156 
01157   _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
01158 }
01159 
01169 DBusConnection*
01170 _dbus_connection_new_for_transport (DBusTransport *transport)
01171 {
01172   DBusConnection *connection;
01173   DBusWatchList *watch_list;
01174   DBusTimeoutList *timeout_list;
01175   DBusHashTable *pending_replies;
01176   DBusList *disconnect_link;
01177   DBusMessage *disconnect_message;
01178   DBusCounter *outgoing_counter;
01179   DBusObjectTree *objects;
01180   
01181   watch_list = NULL;
01182   connection = NULL;
01183   pending_replies = NULL;
01184   timeout_list = NULL;
01185   disconnect_link = NULL;
01186   disconnect_message = NULL;
01187   outgoing_counter = NULL;
01188   objects = NULL;
01189   
01190   watch_list = _dbus_watch_list_new ();
01191   if (watch_list == NULL)
01192     goto error;
01193 
01194   timeout_list = _dbus_timeout_list_new ();
01195   if (timeout_list == NULL)
01196     goto error;  
01197 
01198   pending_replies =
01199     _dbus_hash_table_new (DBUS_HASH_INT,
01200                           NULL,
01201                           (DBusFreeFunction)free_pending_call_on_hash_removal);
01202   if (pending_replies == NULL)
01203     goto error;
01204   
01205   connection = dbus_new0 (DBusConnection, 1);
01206   if (connection == NULL)
01207     goto error;
01208 
01209   _dbus_mutex_new_at_location (&connection->mutex);
01210   if (connection->mutex == NULL)
01211     goto error;
01212 
01213   _dbus_mutex_new_at_location (&connection->io_path_mutex);
01214   if (connection->io_path_mutex == NULL)
01215     goto error;
01216 
01217   _dbus_mutex_new_at_location (&connection->dispatch_mutex);
01218   if (connection->dispatch_mutex == NULL)
01219     goto error;
01220   
01221   _dbus_condvar_new_at_location (&connection->dispatch_cond);
01222   if (connection->dispatch_cond == NULL)
01223     goto error;
01224   
01225   _dbus_condvar_new_at_location (&connection->io_path_cond);
01226   if (connection->io_path_cond == NULL)
01227     goto error;
01228 
01229   disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL,
01230                                                 DBUS_INTERFACE_LOCAL,
01231                                                 "Disconnected");
01232   
01233   if (disconnect_message == NULL)
01234     goto error;
01235 
01236   disconnect_link = _dbus_list_alloc_link (disconnect_message);
01237   if (disconnect_link == NULL)
01238     goto error;
01239 
01240   outgoing_counter = _dbus_counter_new ();
01241   if (outgoing_counter == NULL)
01242     goto error;
01243 
01244   objects = _dbus_object_tree_new (connection);
01245   if (objects == NULL)
01246     goto error;
01247   
01248   if (_dbus_modify_sigpipe)
01249     _dbus_disable_sigpipe ();
01250   
01251   connection->refcount.value = 1;
01252   connection->transport = transport;
01253   connection->watches = watch_list;
01254   connection->timeouts = timeout_list;
01255   connection->pending_replies = pending_replies;
01256   connection->outgoing_counter = outgoing_counter;
01257   connection->filter_list = NULL;
01258   connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE; /* so we're notified first time there's data */
01259   connection->objects = objects;
01260   connection->exit_on_disconnect = FALSE;
01261   connection->shareable = FALSE;
01262   connection->route_peer_messages = FALSE;
01263   connection->disconnected_message_arrived = FALSE;
01264   connection->disconnected_message_processed = FALSE;
01265   
01266 #ifndef DBUS_DISABLE_CHECKS
01267   connection->generation = _dbus_current_generation;
01268 #endif
01269   
01270   _dbus_data_slot_list_init (&connection->slot_list);
01271 
01272   connection->client_serial = 1;
01273 
01274   connection->disconnect_message_link = disconnect_link;
01275 
01276   CONNECTION_LOCK (connection);
01277   
01278   if (!_dbus_transport_set_connection (transport, connection))
01279     {
01280       CONNECTION_UNLOCK (connection);
01281 
01282       goto error;
01283     }
01284 
01285   _dbus_transport_ref (transport);
01286 
01287   CONNECTION_UNLOCK (connection);
01288   
01289   return connection;
01290   
01291  error:
01292   if (disconnect_message != NULL)
01293     dbus_message_unref (disconnect_message);
01294   
01295   if (disconnect_link != NULL)
01296     _dbus_list_free_link (disconnect_link);
01297   
01298   if (connection != NULL)
01299     {
01300       _dbus_condvar_free_at_location (&connection->io_path_cond);
01301       _dbus_condvar_free_at_location (&connection->dispatch_cond);
01302       _dbus_mutex_free_at_location (&connection->mutex);
01303       _dbus_mutex_free_at_location (&connection->io_path_mutex);
01304       _dbus_mutex_free_at_location (&connection->dispatch_mutex);
01305       dbus_free (connection);
01306     }
01307   if (pending_replies)
01308     _dbus_hash_table_unref (pending_replies);
01309   
01310   if (watch_list)
01311     _dbus_watch_list_free (watch_list);
01312 
01313   if (timeout_list)
01314     _dbus_timeout_list_free (timeout_list);
01315 
01316   if (outgoing_counter)
01317     _dbus_counter_unref (outgoing_counter);
01318 
01319   if (objects)
01320     _dbus_object_tree_unref (objects);
01321   
01322   return NULL;
01323 }
01324 
01332 DBusConnection *
01333 _dbus_connection_ref_unlocked (DBusConnection *connection)
01334 {  
01335   _dbus_assert (connection != NULL);
01336   _dbus_assert (connection->generation == _dbus_current_generation);
01337 
01338   HAVE_LOCK_CHECK (connection);
01339   
01340 #ifdef DBUS_HAVE_ATOMIC_INT
01341   _dbus_atomic_inc (&connection->refcount);
01342 #else
01343   _dbus_assert (connection->refcount.value > 0);
01344   connection->refcount.value += 1;
01345 #endif
01346 
01347   return connection;
01348 }
01349 
01356 void
01357 _dbus_connection_unref_unlocked (DBusConnection *connection)
01358 {
01359   dbus_bool_t last_unref;
01360 
01361   HAVE_LOCK_CHECK (connection);
01362   
01363   _dbus_assert (connection != NULL);
01364 
01365   /* The connection lock is better than the global
01366    * lock in the atomic increment fallback
01367    */
01368   
01369 #ifdef DBUS_HAVE_ATOMIC_INT
01370   last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
01371 #else
01372   _dbus_assert (connection->refcount.value > 0);
01373 
01374   connection->refcount.value -= 1;
01375   last_unref = (connection->refcount.value == 0);  
01376 #if 0
01377   printf ("unref_unlocked() connection %p count = %d\n", connection, connection->refcount.value);
01378 #endif
01379 #endif
01380   
01381   if (last_unref)
01382     _dbus_connection_last_unref (connection);
01383 }
01384 
01385 static dbus_uint32_t
01386 _dbus_connection_get_next_client_serial (DBusConnection *connection)
01387 {
01388   dbus_uint32_t serial;
01389 
01390   serial = connection->client_serial++;
01391 
01392   if (connection->client_serial == 0)
01393     connection->client_serial = 1;
01394 
01395   return serial;
01396 }
01397 
01411 dbus_bool_t
01412 _dbus_connection_handle_watch (DBusWatch                   *watch,
01413                                unsigned int                 condition,
01414                                void                        *data)
01415 {
01416   DBusConnection *connection;
01417   dbus_bool_t retval;
01418   DBusDispatchStatus status;
01419 
01420   connection = data;
01421 
01422   _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
01423   
01424   CONNECTION_LOCK (connection);
01425   _dbus_connection_acquire_io_path (connection, -1);
01426   HAVE_LOCK_CHECK (connection);
01427   retval = _dbus_transport_handle_watch (connection->transport,
01428                                          watch, condition);
01429 
01430   _dbus_connection_release_io_path (connection);
01431 
01432   HAVE_LOCK_CHECK (connection);
01433 
01434   _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
01435   
01436   status = _dbus_connection_get_dispatch_status_unlocked (connection);
01437 
01438   /* this calls out to user code */
01439   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01440 
01441   _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
01442   
01443   return retval;
01444 }
01445 
01446 _DBUS_DEFINE_GLOBAL_LOCK (shared_connections);
01447 static DBusHashTable *shared_connections = NULL;
01448 static DBusList *shared_connections_no_guid = NULL;
01449 
01450 static void
01451 close_connection_on_shutdown (DBusConnection *connection)
01452 {
01453   DBusMessage *message;
01454 
01455   dbus_connection_ref (connection);
01456   _dbus_connection_close_possibly_shared (connection);
01457 
01458   /* Churn through to the Disconnected message */
01459   while ((message = dbus_connection_pop_message (connection)))
01460     {
01461       dbus_message_unref (message);
01462     }
01463   dbus_connection_unref (connection);
01464 }
01465 
01466 static void
01467 shared_connections_shutdown (void *data)
01468 {
01469   int n_entries;
01470   
01471   _DBUS_LOCK (shared_connections);
01472   
01473   /* This is a little bit unpleasant... better ideas? */
01474   while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0)
01475     {
01476       DBusConnection *connection;
01477       DBusHashIter iter;
01478       
01479       _dbus_hash_iter_init (shared_connections, &iter);
01480       _dbus_hash_iter_next (&iter);
01481        
01482       connection = _dbus_hash_iter_get_value (&iter);
01483 
01484       _DBUS_UNLOCK (shared_connections);
01485       close_connection_on_shutdown (connection);
01486       _DBUS_LOCK (shared_connections);
01487 
01488       /* The connection should now be dead and not in our hash ... */
01489       _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) < n_entries);
01490     }
01491 
01492   _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) == 0);
01493   
01494   _dbus_hash_table_unref (shared_connections);
01495   shared_connections = NULL;
01496 
01497   if (shared_connections_no_guid != NULL)
01498     {
01499       DBusConnection *connection;
01500       connection = _dbus_list_pop_first (&shared_connections_no_guid);
01501       while (connection != NULL)
01502         {
01503           _DBUS_UNLOCK (shared_connections);
01504           close_connection_on_shutdown (connection);
01505           _DBUS_LOCK (shared_connections);
01506           connection = _dbus_list_pop_first (&shared_connections_no_guid);
01507         }
01508     }
01509 
01510   shared_connections_no_guid = NULL;
01511   
01512   _DBUS_UNLOCK (shared_connections);
01513 }
01514 
01515 static dbus_bool_t
01516 connection_lookup_shared (DBusAddressEntry  *entry,
01517                           DBusConnection   **result)
01518 {
01519   _dbus_verbose ("checking for existing connection\n");
01520   
01521   *result = NULL;
01522   
01523   _DBUS_LOCK (shared_connections);
01524 
01525   if (shared_connections == NULL)
01526     {
01527       _dbus_verbose ("creating shared_connections hash table\n");
01528       
01529       shared_connections = _dbus_hash_table_new (DBUS_HASH_STRING,
01530                                                  dbus_free,
01531                                                  NULL);
01532       if (shared_connections == NULL)
01533         {
01534           _DBUS_UNLOCK (shared_connections);
01535           return FALSE;
01536         }
01537 
01538       if (!_dbus_register_shutdown_func (shared_connections_shutdown, NULL))
01539         {
01540           _dbus_hash_table_unref (shared_connections);
01541           shared_connections = NULL;
01542           _DBUS_UNLOCK (shared_connections);
01543           return FALSE;
01544         }
01545 
01546       _dbus_verbose ("  successfully created shared_connections\n");
01547       
01548       _DBUS_UNLOCK (shared_connections);
01549       return TRUE; /* no point looking up in the hash we just made */
01550     }
01551   else
01552     {
01553       const char *guid;
01554 
01555       guid = dbus_address_entry_get_value (entry, "guid");
01556       
01557       if (guid != NULL)
01558         {
01559           DBusConnection *connection;
01560           
01561           connection = _dbus_hash_table_lookup_string (shared_connections,
01562                                                        guid);
01563 
01564           if (connection)
01565             {
01566               /* The DBusConnection can't be finalized without taking
01567                * the shared_connections lock to remove it from the
01568                * hash.  So it's safe to ref the connection here.
01569                * However, it may be disconnected if the Disconnected
01570                * message hasn't been processed yet, in which case we
01571                * want to pretend it isn't in the hash and avoid
01572                * returning it.
01573                *
01574                * The idea is to avoid ever returning a disconnected connection
01575                * from dbus_connection_open(). We could just synchronously
01576                * drop our shared ref to the connection on connection disconnect,
01577                * and then assert here that the connection is connected, but
01578                * that causes reentrancy headaches.
01579                */
01580               CONNECTION_LOCK (connection);
01581               if (_dbus_connection_get_is_connected_unlocked (connection))
01582                 {
01583                   _dbus_connection_ref_unlocked (connection);
01584                   *result = connection;
01585                   _dbus_verbose ("looked up existing connection to server guid %s\n",
01586                                  guid);
01587                 }
01588               else
01589                 {
01590                   _dbus_verbose ("looked up existing connection to server guid %s but it was disconnected so ignoring it\n",
01591                                  guid);
01592                 }
01593               CONNECTION_UNLOCK (connection);
01594             }
01595         }
01596       
01597       _DBUS_UNLOCK (shared_connections);
01598       return TRUE;
01599     }
01600 }
01601 
01602 static dbus_bool_t
01603 connection_record_shared_unlocked (DBusConnection *connection,
01604                                    const char     *guid)
01605 {
01606   char *guid_key;
01607   char *guid_in_connection;
01608 
01609   HAVE_LOCK_CHECK (connection);
01610   _dbus_assert (connection->server_guid == NULL);
01611   _dbus_assert (connection->shareable);
01612 
01613   /* get a hard ref on this connection, even if
01614    * we won't in fact store it in the hash, we still
01615    * need to hold a ref on it until it's disconnected.
01616    */
01617   _dbus_connection_ref_unlocked (connection);
01618 
01619   if (guid == NULL)
01620     {
01621       _DBUS_LOCK (shared_connections);
01622 
01623       if (!_dbus_list_prepend (&shared_connections_no_guid, connection))
01624         {
01625           _DBUS_UNLOCK (shared_connections);
01626           return FALSE;
01627         }
01628 
01629       _DBUS_UNLOCK (shared_connections);
01630       return TRUE; /* don't store in the hash */
01631     }
01632   
01633   /* A separate copy of the key is required in the hash table, because
01634    * we don't have a lock on the connection when we are doing a hash
01635    * lookup.
01636    */
01637   
01638   guid_key = _dbus_strdup (guid);
01639   if (guid_key == NULL)
01640     return FALSE;
01641 
01642   guid_in_connection = _dbus_strdup (guid);
01643   if (guid_in_connection == NULL)
01644     {
01645       dbus_free (guid_key);
01646       return FALSE;
01647     }
01648   
01649   _DBUS_LOCK (shared_connections);
01650   _dbus_assert (shared_connections != NULL);
01651   
01652   if (!_dbus_hash_table_insert_string (shared_connections,
01653                                        guid_key, connection))
01654     {
01655       dbus_free (guid_key);
01656       dbus_free (guid_in_connection);
01657       _DBUS_UNLOCK (shared_connections);
01658       return FALSE;
01659     }
01660 
01661   connection->server_guid = guid_in_connection;
01662 
01663   _dbus_verbose ("stored connection to %s to be shared\n",
01664                  connection->server_guid);
01665   
01666   _DBUS_UNLOCK (shared_connections);
01667 
01668   _dbus_assert (connection->server_guid != NULL);
01669   
01670   return TRUE;
01671 }
01672 
01673 static void
01674 connection_forget_shared_unlocked (DBusConnection *connection)
01675 {
01676   HAVE_LOCK_CHECK (connection);
01677 
01678   if (!connection->shareable)
01679     return;
01680   
01681   _DBUS_LOCK (shared_connections);
01682       
01683   if (connection->server_guid != NULL)
01684     {
01685       _dbus_verbose ("dropping connection to %s out of the shared table\n",
01686                      connection->server_guid);
01687       
01688       if (!_dbus_hash_table_remove_string (shared_connections,
01689                                            connection->server_guid))
01690         _dbus_assert_not_reached ("connection was not in the shared table");
01691       
01692       dbus_free (connection->server_guid);
01693       connection->server_guid = NULL;
01694     }
01695   else
01696     {
01697       _dbus_list_remove (&shared_connections_no_guid, connection);
01698     }
01699 
01700   _DBUS_UNLOCK (shared_connections);
01701   
01702   /* remove our reference held on all shareable connections */
01703   _dbus_connection_unref_unlocked (connection);
01704 }
01705 
01706 static DBusConnection*
01707 connection_try_from_address_entry (DBusAddressEntry *entry,
01708                                    DBusError        *error)
01709 {
01710   DBusTransport *transport;
01711   DBusConnection *connection;
01712 
01713   transport = _dbus_transport_open (entry, error);
01714 
01715   if (transport == NULL)
01716     {
01717       _DBUS_ASSERT_ERROR_IS_SET (error);
01718       return NULL;
01719     }
01720 
01721   connection = _dbus_connection_new_for_transport (transport);
01722 
01723   _dbus_transport_unref (transport);
01724   
01725   if (connection == NULL)
01726     {
01727       _DBUS_SET_OOM (error);
01728       return NULL;
01729     }
01730 
01731 #ifndef DBUS_DISABLE_CHECKS
01732   _dbus_assert (!connection->have_connection_lock);
01733 #endif
01734   return connection;
01735 }
01736 
01737 /*
01738  * If the shared parameter is true, then any existing connection will
01739  * be used (and if a new connection is created, it will be available
01740  * for use by others). If the shared parameter is false, a new
01741  * connection will always be created, and the new connection will
01742  * never be returned to other callers.
01743  *
01744  * @param address the address
01745  * @param shared whether the connection is shared or private
01746  * @param error error return
01747  * @returns the connection or #NULL on error
01748  */
01749 static DBusConnection*
01750 _dbus_connection_open_internal (const char     *address,
01751                                 dbus_bool_t     shared,
01752                                 DBusError      *error)
01753 {
01754   DBusConnection *connection;
01755   DBusAddressEntry **entries;
01756   DBusError tmp_error = DBUS_ERROR_INIT;
01757   DBusError first_error = DBUS_ERROR_INIT;
01758   int len, i;
01759 
01760   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01761 
01762   _dbus_verbose ("opening %s connection to: %s\n",
01763                  shared ? "shared" : "private", address);
01764   
01765   if (!dbus_parse_address (address, &entries, &len, error))
01766     return NULL;
01767 
01768   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01769   
01770   connection = NULL;
01771 
01772   for (i = 0; i < len; i++)
01773     {
01774       if (shared)
01775         {
01776           if (!connection_lookup_shared (entries[i], &connection))
01777             _DBUS_SET_OOM (&tmp_error);
01778         }
01779 
01780       if (connection == NULL)
01781         {
01782           connection = connection_try_from_address_entry (entries[i],
01783                                                           &tmp_error);
01784 
01785           if (connection != NULL && shared)
01786             {
01787               const char *guid;
01788                   
01789               connection->shareable = TRUE;
01790                   
01791               /* guid may be NULL */
01792               guid = dbus_address_entry_get_value (entries[i], "guid");
01793                   
01794               CONNECTION_LOCK (connection);
01795           
01796               if (!connection_record_shared_unlocked (connection, guid))
01797                 {
01798                   _DBUS_SET_OOM (&tmp_error);
01799                   _dbus_connection_close_possibly_shared_and_unlock (connection);
01800                   dbus_connection_unref (connection);
01801                   connection = NULL;
01802                 }
01803               else
01804                 CONNECTION_UNLOCK (connection);
01805             }
01806         }
01807       
01808       if (connection)
01809         break;
01810 
01811       _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
01812       
01813       if (i == 0)
01814         dbus_move_error (&tmp_error, &first_error);
01815       else
01816         dbus_error_free (&tmp_error);
01817     }
01818   
01819   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01820   _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
01821   
01822   if (connection == NULL)
01823     {
01824       _DBUS_ASSERT_ERROR_IS_SET (&first_error);
01825       dbus_move_error (&first_error, error);
01826     }
01827   else
01828     dbus_error_free (&first_error);
01829   
01830   dbus_address_entries_free (entries);
01831   return connection;
01832 }
01833 
01842 void
01843 _dbus_connection_close_possibly_shared (DBusConnection *connection)
01844 {
01845   _dbus_assert (connection != NULL);
01846   _dbus_assert (connection->generation == _dbus_current_generation);
01847 
01848   CONNECTION_LOCK (connection);
01849   _dbus_connection_close_possibly_shared_and_unlock (connection);
01850 }
01851 
01852 static DBusPreallocatedSend*
01853 _dbus_connection_preallocate_send_unlocked (DBusConnection *connection)
01854 {
01855   DBusPreallocatedSend *preallocated;
01856 
01857   HAVE_LOCK_CHECK (connection);
01858   
01859   _dbus_assert (connection != NULL);
01860   
01861   preallocated = dbus_new (DBusPreallocatedSend, 1);
01862   if (preallocated == NULL)
01863     return NULL;
01864 
01865   if (connection->link_cache != NULL)
01866     {
01867       preallocated->queue_link =
01868         _dbus_list_pop_first_link (&connection->link_cache);
01869       preallocated->queue_link->data = NULL;
01870     }
01871   else
01872     {
01873       preallocated->queue_link = _dbus_list_alloc_link (NULL);
01874       if (preallocated->queue_link == NULL)
01875         goto failed_0;
01876     }
01877   
01878   if (connection->link_cache != NULL)
01879     {
01880       preallocated->counter_link =
01881         _dbus_list_pop_first_link (&connection->link_cache);
01882       preallocated->counter_link->data = connection->outgoing_counter;
01883     }
01884   else
01885     {
01886       preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter);
01887       if (preallocated->counter_link == NULL)
01888         goto failed_1;
01889     }
01890 
01891   _dbus_counter_ref (preallocated->counter_link->data);
01892 
01893   preallocated->connection = connection;
01894   
01895   return preallocated;
01896   
01897  failed_1:
01898   _dbus_list_free_link (preallocated->queue_link);
01899  failed_0:
01900   dbus_free (preallocated);
01901   
01902   return NULL;
01903 }
01904 
01905 /* Called with lock held, does not update dispatch status */
01906 static void
01907 _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection       *connection,
01908                                                        DBusPreallocatedSend *preallocated,
01909                                                        DBusMessage          *message,
01910                                                        dbus_uint32_t        *client_serial)
01911 {
01912   dbus_uint32_t serial;
01913   const char *sig;
01914 
01915   preallocated->queue_link->data = message;
01916   _dbus_list_prepend_link (&connection->outgoing_messages,
01917                            preallocated->queue_link);
01918 
01919   _dbus_message_add_size_counter_link (message,
01920                                        preallocated->counter_link);
01921 
01922   dbus_free (preallocated);
01923   preallocated = NULL;
01924   
01925   dbus_message_ref (message);
01926   
01927   connection->n_outgoing += 1;
01928 
01929   sig = dbus_message_get_signature (message);
01930   
01931   _dbus_verbose ("Message %p (%d %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
01932                  message,
01933                  dbus_message_get_type (message),
01934                  dbus_message_get_path (message) ?
01935                  dbus_message_get_path (message) :
01936                  "no path",
01937                  dbus_message_get_interface (message) ?
01938                  dbus_message_get_interface (message) :
01939                  "no interface",
01940                  dbus_message_get_member (message) ?
01941                  dbus_message_get_member (message) :
01942                  "no member",
01943                  sig,
01944                  dbus_message_get_destination (message) ?
01945                  dbus_message_get_destination (message) :
01946                  "null",
01947                  connection,
01948                  connection->n_outgoing);
01949 
01950   if (dbus_message_get_serial (message) == 0)
01951     {
01952       serial = _dbus_connection_get_next_client_serial (connection);
01953       _dbus_message_set_serial (message, serial);
01954       if (client_serial)
01955         *client_serial = serial;
01956     }
01957   else
01958     {
01959       if (client_serial)
01960         *client_serial = dbus_message_get_serial (message);
01961     }
01962 
01963   _dbus_verbose ("Message %p serial is %u\n",
01964                  message, dbus_message_get_serial (message));
01965   
01966   _dbus_message_lock (message);
01967 
01968   /* Now we need to run an iteration to hopefully just write the messages
01969    * out immediately, and otherwise get them queued up
01970    */
01971   _dbus_connection_do_iteration_unlocked (connection,
01972                                           DBUS_ITERATION_DO_WRITING,
01973                                           -1);
01974 
01975   /* If stuff is still queued up, be sure we wake up the main loop */
01976   if (connection->n_outgoing > 0)
01977     _dbus_connection_wakeup_mainloop (connection);
01978 }
01979 
01980 static void
01981 _dbus_connection_send_preallocated_and_unlock (DBusConnection       *connection,
01982                                                DBusPreallocatedSend *preallocated,
01983                                                DBusMessage          *message,
01984                                                dbus_uint32_t        *client_serial)
01985 {
01986   DBusDispatchStatus status;
01987 
01988   HAVE_LOCK_CHECK (connection);
01989   
01990   _dbus_connection_send_preallocated_unlocked_no_update (connection,
01991                                                          preallocated,
01992                                                          message, client_serial);
01993 
01994   _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
01995   status = _dbus_connection_get_dispatch_status_unlocked (connection);
01996 
01997   /* this calls out to user code */
01998   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01999 }
02000 
02010 dbus_bool_t
02011 _dbus_connection_send_and_unlock (DBusConnection *connection,
02012                                   DBusMessage    *message,
02013                                   dbus_uint32_t  *client_serial)
02014 {
02015   DBusPreallocatedSend *preallocated;
02016 
02017   _dbus_assert (connection != NULL);
02018   _dbus_assert (message != NULL);
02019   
02020   preallocated = _dbus_connection_preallocate_send_unlocked (connection);
02021   if (preallocated == NULL)
02022     {
02023       CONNECTION_UNLOCK (connection);
02024       return FALSE;
02025     }
02026 
02027   _dbus_connection_send_preallocated_and_unlock (connection,
02028                                                  preallocated,
02029                                                  message,
02030                                                  client_serial);
02031   return TRUE;
02032 }
02033 
02058 void
02059 _dbus_connection_close_if_only_one_ref (DBusConnection *connection)
02060 {
02061   CONNECTION_LOCK (connection);
02062   
02063   _dbus_assert (connection->refcount.value > 0);
02064 
02065   if (connection->refcount.value == 1)
02066     _dbus_connection_close_possibly_shared_and_unlock (connection);
02067   else
02068     CONNECTION_UNLOCK (connection);
02069 }
02070 
02071 
02081 static void
02082 _dbus_memory_pause_based_on_timeout (int timeout_milliseconds)
02083 {
02084   if (timeout_milliseconds == -1)
02085     _dbus_sleep_milliseconds (1000);
02086   else if (timeout_milliseconds < 100)
02087     ; /* just busy loop */
02088   else if (timeout_milliseconds <= 1000)
02089     _dbus_sleep_milliseconds (timeout_milliseconds / 3);
02090   else
02091     _dbus_sleep_milliseconds (1000);
02092 }
02093 
02094 static DBusMessage *
02095 generate_local_error_message (dbus_uint32_t serial, 
02096                               char *error_name, 
02097                               char *error_msg)
02098 {
02099   DBusMessage *message;
02100   message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
02101   if (!message)
02102     goto out;
02103 
02104   if (!dbus_message_set_error_name (message, error_name))
02105     {
02106       dbus_message_unref (message);
02107       message = NULL;
02108       goto out; 
02109     }
02110 
02111   dbus_message_set_no_reply (message, TRUE); 
02112 
02113   if (!dbus_message_set_reply_serial (message,
02114                                       serial))
02115     {
02116       dbus_message_unref (message);
02117       message = NULL;
02118       goto out;
02119     }
02120 
02121   if (error_msg != NULL)
02122     {
02123       DBusMessageIter iter;
02124 
02125       dbus_message_iter_init_append (message, &iter);
02126       if (!dbus_message_iter_append_basic (&iter,
02127                                            DBUS_TYPE_STRING,
02128                                            &error_msg))
02129         {
02130           dbus_message_unref (message);
02131           message = NULL;
02132           goto out;
02133         }
02134     }
02135 
02136  out:
02137   return message;
02138 }
02139 
02140 
02141 /* This is slightly strange since we can pop a message here without
02142  * the dispatch lock.
02143  */
02144 static DBusMessage*
02145 check_for_reply_unlocked (DBusConnection *connection,
02146                           dbus_uint32_t   client_serial)
02147 {
02148   DBusList *link;
02149 
02150   HAVE_LOCK_CHECK (connection);
02151   
02152   link = _dbus_list_get_first_link (&connection->incoming_messages);
02153 
02154   while (link != NULL)
02155     {
02156       DBusMessage *reply = link->data;
02157 
02158       if (dbus_message_get_reply_serial (reply) == client_serial)
02159         {
02160           _dbus_list_remove_link (&connection->incoming_messages, link);
02161           connection->n_incoming  -= 1;
02162           return reply;
02163         }
02164       link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02165     }
02166 
02167   return NULL;
02168 }
02169 
02170 static void
02171 connection_timeout_and_complete_all_pending_calls_unlocked (DBusConnection *connection)
02172 {
02173    /* We can't iterate over the hash in the normal way since we'll be
02174     * dropping the lock for each item. So we restart the
02175     * iter each time as we drain the hash table.
02176     */
02177    
02178    while (_dbus_hash_table_get_n_entries (connection->pending_replies) > 0)
02179     {
02180       DBusPendingCall *pending;
02181       DBusHashIter iter;
02182       
02183       _dbus_hash_iter_init (connection->pending_replies, &iter);
02184       _dbus_hash_iter_next (&iter);
02185        
02186       pending = _dbus_hash_iter_get_value (&iter);
02187       _dbus_pending_call_ref_unlocked (pending);
02188        
02189       _dbus_pending_call_queue_timeout_error_unlocked (pending, 
02190                                                        connection);
02191       _dbus_connection_remove_timeout_unlocked (connection,
02192                                                 _dbus_pending_call_get_timeout_unlocked (pending));
02193       _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);       
02194       _dbus_hash_iter_remove_entry (&iter);
02195 
02196       _dbus_pending_call_unref_and_unlock (pending);
02197       CONNECTION_LOCK (connection);
02198     }
02199   HAVE_LOCK_CHECK (connection);
02200 }
02201 
02202 static void
02203 complete_pending_call_and_unlock (DBusConnection  *connection,
02204                                   DBusPendingCall *pending,
02205                                   DBusMessage     *message)
02206 {
02207   _dbus_pending_call_set_reply_unlocked (pending, message);
02208   _dbus_pending_call_ref_unlocked (pending); /* in case there's no app with a ref held */
02209   _dbus_connection_detach_pending_call_and_unlock (connection, pending);
02210  
02211   /* Must be called unlocked since it invokes app callback */
02212   _dbus_pending_call_complete (pending);
02213   dbus_pending_call_unref (pending);
02214 }
02215 
02216 static dbus_bool_t
02217 check_for_reply_and_update_dispatch_unlocked (DBusConnection  *connection,
02218                                               DBusPendingCall *pending)
02219 {
02220   DBusMessage *reply;
02221   DBusDispatchStatus status;
02222 
02223   reply = check_for_reply_unlocked (connection, 
02224                                     _dbus_pending_call_get_reply_serial_unlocked (pending));
02225   if (reply != NULL)
02226     {
02227       _dbus_verbose ("%s checked for reply\n", _DBUS_FUNCTION_NAME);
02228 
02229       _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
02230 
02231       complete_pending_call_and_unlock (connection, pending, reply);
02232       dbus_message_unref (reply);
02233 
02234       CONNECTION_LOCK (connection);
02235       status = _dbus_connection_get_dispatch_status_unlocked (connection);
02236       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02237       dbus_pending_call_unref (pending);
02238 
02239       return TRUE;
02240     }
02241 
02242   return FALSE;
02243 }
02244 
02259 void
02260 _dbus_connection_block_pending_call (DBusPendingCall *pending)
02261 {
02262   long start_tv_sec, start_tv_usec;
02263   long end_tv_sec, end_tv_usec;
02264   long tv_sec, tv_usec;
02265   DBusDispatchStatus status;
02266   DBusConnection *connection;
02267   dbus_uint32_t client_serial;
02268   int timeout_milliseconds;
02269 
02270   _dbus_assert (pending != NULL);
02271 
02272   if (dbus_pending_call_get_completed (pending))
02273     return;
02274 
02275   dbus_pending_call_ref (pending); /* necessary because the call could be canceled */
02276 
02277   connection = _dbus_pending_call_get_connection_and_lock (pending);
02278   
02279   /* Flush message queue - note, can affect dispatch status */
02280   _dbus_connection_flush_unlocked (connection);
02281 
02282   client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
02283 
02284   /* note that timeout_milliseconds is limited to a smallish value
02285    * in _dbus_pending_call_new() so overflows aren't possible
02286    * below
02287    */
02288   timeout_milliseconds = dbus_timeout_get_interval (_dbus_pending_call_get_timeout_unlocked (pending));
02289   
02290   _dbus_get_current_time (&start_tv_sec, &start_tv_usec);
02291   end_tv_sec = start_tv_sec + timeout_milliseconds / 1000;
02292   end_tv_usec = start_tv_usec + (timeout_milliseconds % 1000) * 1000;
02293   end_tv_sec += end_tv_usec / _DBUS_USEC_PER_SECOND;
02294   end_tv_usec = end_tv_usec % _DBUS_USEC_PER_SECOND;
02295 
02296   _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec to %ld sec %ld usec\n",
02297                  timeout_milliseconds,
02298                  client_serial,
02299                  start_tv_sec, start_tv_usec,
02300                  end_tv_sec, end_tv_usec);
02301 
02302   /* check to see if we already got the data off the socket */
02303   /* from another blocked pending call */
02304   if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02305     return;
02306 
02307   /* Now we wait... */
02308   /* always block at least once as we know we don't have the reply yet */
02309   _dbus_connection_do_iteration_unlocked (connection,
02310                                           DBUS_ITERATION_DO_READING |
02311                                           DBUS_ITERATION_BLOCK,
02312                                           timeout_milliseconds);
02313 
02314  recheck_status:
02315 
02316   _dbus_verbose ("%s top of recheck\n", _DBUS_FUNCTION_NAME);
02317   
02318   HAVE_LOCK_CHECK (connection);
02319   
02320   /* queue messages and get status */
02321 
02322   status = _dbus_connection_get_dispatch_status_unlocked (connection);
02323 
02324   /* the get_completed() is in case a dispatch() while we were blocking
02325    * got the reply instead of us.
02326    */
02327   if (_dbus_pending_call_get_completed_unlocked (pending))
02328     {
02329       _dbus_verbose ("Pending call completed by dispatch in %s\n", _DBUS_FUNCTION_NAME);
02330       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02331       dbus_pending_call_unref (pending);
02332       return;
02333     }
02334   
02335   if (status == DBUS_DISPATCH_DATA_REMAINS)
02336     {
02337       if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02338         return;
02339     }
02340   
02341   _dbus_get_current_time (&tv_sec, &tv_usec);
02342   
02343   if (!_dbus_connection_get_is_connected_unlocked (connection))
02344     {
02345       DBusMessage *error_msg;
02346 
02347       error_msg = generate_local_error_message (client_serial,
02348                                                 DBUS_ERROR_DISCONNECTED, 
02349                                                 "Connection was disconnected before a reply was received"); 
02350 
02351       /* on OOM error_msg is set to NULL */
02352       complete_pending_call_and_unlock (connection, pending, error_msg);
02353       dbus_pending_call_unref (pending);
02354       return;
02355     }
02356   else if (tv_sec < start_tv_sec)
02357     _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
02358   else if (connection->disconnect_message_link == NULL)
02359     _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
02360   else if (tv_sec < end_tv_sec ||
02361            (tv_sec == end_tv_sec && tv_usec < end_tv_usec))
02362     {
02363       timeout_milliseconds = (end_tv_sec - tv_sec) * 1000 +
02364         (end_tv_usec - tv_usec) / 1000;
02365       _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds);
02366       _dbus_assert (timeout_milliseconds >= 0);
02367       
02368       if (status == DBUS_DISPATCH_NEED_MEMORY)
02369         {
02370           /* Try sleeping a bit, as we aren't sure we need to block for reading,
02371            * we may already have a reply in the buffer and just can't process
02372            * it.
02373            */
02374           _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02375 
02376           _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
02377         }
02378       else
02379         {          
02380           /* block again, we don't have the reply buffered yet. */
02381           _dbus_connection_do_iteration_unlocked (connection,
02382                                                   DBUS_ITERATION_DO_READING |
02383                                                   DBUS_ITERATION_BLOCK,
02384                                                   timeout_milliseconds);
02385         }
02386 
02387       goto recheck_status;
02388     }
02389 
02390   _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %ld milliseconds and got no reply\n",
02391                  (tv_sec - start_tv_sec) * 1000 + (tv_usec - start_tv_usec) / 1000);
02392 
02393   _dbus_assert (!_dbus_pending_call_get_completed_unlocked (pending));
02394   
02395   /* unlock and call user code */
02396   complete_pending_call_and_unlock (connection, pending, NULL);
02397 
02398   /* update user code on dispatch status */
02399   CONNECTION_LOCK (connection);
02400   status = _dbus_connection_get_dispatch_status_unlocked (connection);
02401   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02402   dbus_pending_call_unref (pending);
02403 }
02404 
02441 DBusConnection*
02442 dbus_connection_open (const char     *address,
02443                       DBusError      *error)
02444 {
02445   DBusConnection *connection;
02446 
02447   _dbus_return_val_if_fail (address != NULL, NULL);
02448   _dbus_return_val_if_error_is_set (error, NULL);
02449 
02450   connection = _dbus_connection_open_internal (address,
02451                                                TRUE,
02452                                                error);
02453 
02454   return connection;
02455 }
02456 
02484 DBusConnection*
02485 dbus_connection_open_private (const char     *address,
02486                               DBusError      *error)
02487 {
02488   DBusConnection *connection;
02489 
02490   _dbus_return_val_if_fail (address != NULL, NULL);
02491   _dbus_return_val_if_error_is_set (error, NULL);
02492 
02493   connection = _dbus_connection_open_internal (address,
02494                                                FALSE,
02495                                                error);
02496 
02497   return connection;
02498 }
02499 
02506 DBusConnection *
02507 dbus_connection_ref (DBusConnection *connection)
02508 {
02509   _dbus_return_val_if_fail (connection != NULL, NULL);
02510   _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
02511   
02512   /* The connection lock is better than the global
02513    * lock in the atomic increment fallback
02514    */
02515   
02516 #ifdef DBUS_HAVE_ATOMIC_INT
02517   _dbus_atomic_inc (&connection->refcount);
02518 #else
02519   CONNECTION_LOCK (connection);
02520   _dbus_assert (connection->refcount.value > 0);
02521 
02522   connection->refcount.value += 1;
02523   CONNECTION_UNLOCK (connection);
02524 #endif
02525 
02526   return connection;
02527 }
02528 
02529 static void
02530 free_outgoing_message (void *element,
02531                        void *data)
02532 {
02533   DBusMessage *message = element;
02534   DBusConnection *connection = data;
02535 
02536   _dbus_message_remove_size_counter (message,
02537                                      connection->outgoing_counter,
02538                                      NULL);
02539   dbus_message_unref (message);
02540 }
02541 
02542 /* This is run without the mutex held, but after the last reference
02543  * to the connection has been dropped we should have no thread-related
02544  * problems
02545  */
02546 static void
02547 _dbus_connection_last_unref (DBusConnection *connection)
02548 {
02549   DBusList *link;
02550 
02551   _dbus_verbose ("Finalizing connection %p\n", connection);
02552   
02553   _dbus_assert (connection->refcount.value == 0);
02554   
02555   /* You have to disconnect the connection before unref:ing it. Otherwise
02556    * you won't get the disconnected message.
02557    */
02558   _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
02559   _dbus_assert (connection->server_guid == NULL);
02560   
02561   /* ---- We're going to call various application callbacks here, hope it doesn't break anything... */
02562   _dbus_object_tree_free_all_unlocked (connection->objects);
02563   
02564   dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
02565   dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
02566   dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
02567   
02568   _dbus_watch_list_free (connection->watches);
02569   connection->watches = NULL;
02570   
02571   _dbus_timeout_list_free (connection->timeouts);
02572   connection->timeouts = NULL;
02573 
02574   _dbus_data_slot_list_free (&connection->slot_list);
02575   
02576   link = _dbus_list_get_first_link (&connection->filter_list);
02577   while (link != NULL)
02578     {
02579       DBusMessageFilter *filter = link->data;
02580       DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
02581 
02582       filter->function = NULL;
02583       _dbus_message_filter_unref (filter); /* calls app callback */
02584       link->data = NULL;
02585       
02586       link = next;
02587     }
02588   _dbus_list_clear (&connection->filter_list);
02589   
02590   /* ---- Done with stuff that invokes application callbacks */
02591 
02592   _dbus_object_tree_unref (connection->objects);  
02593 
02594   _dbus_hash_table_unref (connection->pending_replies);
02595   connection->pending_replies = NULL;
02596   
02597   _dbus_list_clear (&connection->filter_list);
02598   
02599   _dbus_list_foreach (&connection->outgoing_messages,
02600                       free_outgoing_message,
02601                       connection);
02602   _dbus_list_clear (&connection->outgoing_messages);
02603   
02604   _dbus_list_foreach (&connection->incoming_messages,
02605                       (DBusForeachFunction) dbus_message_unref,
02606                       NULL);
02607   _dbus_list_clear (&connection->incoming_messages);
02608 
02609   _dbus_counter_unref (connection->outgoing_counter);
02610 
02611   _dbus_transport_unref (connection->transport);
02612 
02613   if (connection->disconnect_message_link)
02614     {
02615       DBusMessage *message = connection->disconnect_message_link->data;
02616       dbus_message_unref (message);
02617       _dbus_list_free_link (connection->disconnect_message_link);
02618     }
02619 
02620   _dbus_list_clear (&connection->link_cache);
02621   
02622   _dbus_condvar_free_at_location (&connection->dispatch_cond);
02623   _dbus_condvar_free_at_location (&connection->io_path_cond);
02624 
02625   _dbus_mutex_free_at_location (&connection->io_path_mutex);
02626   _dbus_mutex_free_at_location (&connection->dispatch_mutex);
02627 
02628   _dbus_mutex_free_at_location (&connection->mutex);
02629   
02630   dbus_free (connection);
02631 }
02632 
02652 void
02653 dbus_connection_unref (DBusConnection *connection)
02654 {
02655   dbus_bool_t last_unref;
02656 
02657   _dbus_return_if_fail (connection != NULL);
02658   _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02659   
02660   /* The connection lock is better than the global
02661    * lock in the atomic increment fallback
02662    */
02663   
02664 #ifdef DBUS_HAVE_ATOMIC_INT
02665   last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
02666 #else
02667   CONNECTION_LOCK (connection);
02668   
02669   _dbus_assert (connection->refcount.value > 0);
02670 
02671   connection->refcount.value -= 1;
02672   last_unref = (connection->refcount.value == 0);
02673 
02674 #if 0
02675   printf ("unref() connection %p count = %d\n", connection, connection->refcount.value);
02676 #endif
02677   
02678   CONNECTION_UNLOCK (connection);
02679 #endif
02680   
02681   if (last_unref)
02682     {
02683 #ifndef DBUS_DISABLE_CHECKS
02684       if (_dbus_transport_get_is_connected (connection->transport))
02685         {
02686           _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",
02687                                    connection->shareable ?
02688                                    "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" : 
02689                                     "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n");
02690           return;
02691         }
02692 #endif
02693       _dbus_connection_last_unref (connection);
02694     }
02695 }
02696 
02697 /*
02698  * Note that the transport can disconnect itself (other end drops us)
02699  * and in that case this function never runs. So this function must
02700  * not do anything more than disconnect the transport and update the
02701  * dispatch status.
02702  * 
02703  * If the transport self-disconnects, then we assume someone will
02704  * dispatch the connection to cause the dispatch status update.
02705  */
02706 static void
02707 _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection)
02708 {
02709   DBusDispatchStatus status;
02710 
02711   HAVE_LOCK_CHECK (connection);
02712   
02713   _dbus_verbose ("Disconnecting %p\n", connection);
02714 
02715   /* We need to ref because update_dispatch_status_and_unlock will unref
02716    * the connection if it was shared and libdbus was the only remaining
02717    * refcount holder.
02718    */
02719   _dbus_connection_ref_unlocked (connection);
02720   
02721   _dbus_transport_disconnect (connection->transport);
02722 
02723   /* This has the side effect of queuing the disconnect message link
02724    * (unless we don't have enough memory, possibly, so don't assert it).
02725    * After the disconnect message link is queued, dbus_bus_get/dbus_connection_open
02726    * should never again return the newly-disconnected connection.
02727    *
02728    * However, we only unref the shared connection and exit_on_disconnect when
02729    * the disconnect message reaches the head of the message queue,
02730    * NOT when it's first queued.
02731    */
02732   status = _dbus_connection_get_dispatch_status_unlocked (connection);
02733 
02734   /* This calls out to user code */
02735   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02736 
02737   /* Could also call out to user code */
02738   dbus_connection_unref (connection);
02739 }
02740 
02783 void
02784 dbus_connection_close (DBusConnection *connection)
02785 {
02786   _dbus_return_if_fail (connection != NULL);
02787   _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02788 
02789   CONNECTION_LOCK (connection);
02790 
02791 #ifndef DBUS_DISABLE_CHECKS
02792   if (connection->shareable)
02793     {
02794       CONNECTION_UNLOCK (connection);
02795 
02796       _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n");
02797       return;
02798     }
02799 #endif
02800   
02801   _dbus_connection_close_possibly_shared_and_unlock (connection);
02802 }
02803 
02804 static dbus_bool_t
02805 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
02806 {
02807   HAVE_LOCK_CHECK (connection);
02808   return _dbus_transport_get_is_connected (connection->transport);
02809 }
02810 
02824 dbus_bool_t
02825 dbus_connection_get_is_connected (DBusConnection *connection)
02826 {
02827   dbus_bool_t res;
02828 
02829   _dbus_return_val_if_fail (connection != NULL, FALSE);
02830   
02831   CONNECTION_LOCK (connection);
02832   res = _dbus_connection_get_is_connected_unlocked (connection);
02833   CONNECTION_UNLOCK (connection);
02834   
02835   return res;
02836 }
02837 
02846 dbus_bool_t
02847 dbus_connection_get_is_authenticated (DBusConnection *connection)
02848 {
02849   dbus_bool_t res;
02850 
02851   _dbus_return_val_if_fail (connection != NULL, FALSE);
02852   
02853   CONNECTION_LOCK (connection);
02854   res = _dbus_transport_get_is_authenticated (connection->transport);
02855   CONNECTION_UNLOCK (connection);
02856   
02857   return res;
02858 }
02859 
02880 dbus_bool_t
02881 dbus_connection_get_is_anonymous (DBusConnection *connection)
02882 {
02883   dbus_bool_t res;
02884 
02885   _dbus_return_val_if_fail (connection != NULL, FALSE);
02886   
02887   CONNECTION_LOCK (connection);
02888   res = _dbus_transport_get_is_anonymous (connection->transport);
02889   CONNECTION_UNLOCK (connection);
02890   
02891   return res;
02892 }
02893 
02925 char*
02926 dbus_connection_get_server_id (DBusConnection *connection)
02927 {
02928   char *id;
02929 
02930   _dbus_return_val_if_fail (connection != NULL, FALSE);
02931   
02932   CONNECTION_LOCK (connection);
02933   id = _dbus_strdup (_dbus_transport_get_server_id (connection->transport));
02934   CONNECTION_UNLOCK (connection);
02935   
02936   return id;
02937 }
02938 
02952 void
02953 dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
02954                                         dbus_bool_t     exit_on_disconnect)
02955 {
02956   _dbus_return_if_fail (connection != NULL);
02957 
02958   CONNECTION_LOCK (connection);
02959   connection->exit_on_disconnect = exit_on_disconnect != FALSE;
02960   CONNECTION_UNLOCK (connection);
02961 }
02962 
02972 DBusPreallocatedSend*
02973 dbus_connection_preallocate_send (DBusConnection *connection)
02974 {
02975   DBusPreallocatedSend *preallocated;
02976 
02977   _dbus_return_val_if_fail (connection != NULL, NULL);
02978 
02979   CONNECTION_LOCK (connection);
02980   
02981   preallocated =
02982     _dbus_connection_preallocate_send_unlocked (connection);
02983 
02984   CONNECTION_UNLOCK (connection);
02985 
02986   return preallocated;
02987 }
02988 
02998 void
02999 dbus_connection_free_preallocated_send (DBusConnection       *connection,
03000                                         DBusPreallocatedSend *preallocated)
03001 {
03002   _dbus_return_if_fail (connection != NULL);
03003   _dbus_return_if_fail (preallocated != NULL);  
03004   _dbus_return_if_fail (connection == preallocated->connection);
03005 
03006   _dbus_list_free_link (preallocated->queue_link);
03007   _dbus_counter_unref (preallocated->counter_link->data);
03008   _dbus_list_free_link (preallocated->counter_link);
03009   dbus_free (preallocated);
03010 }
03011 
03024 void
03025 dbus_connection_send_preallocated (DBusConnection       *connection,
03026                                    DBusPreallocatedSend *preallocated,
03027                                    DBusMessage          *message,
03028                                    dbus_uint32_t        *client_serial)
03029 {
03030   _dbus_return_if_fail (connection != NULL);
03031   _dbus_return_if_fail (preallocated != NULL);
03032   _dbus_return_if_fail (message != NULL);
03033   _dbus_return_if_fail (preallocated->connection == connection);
03034   _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
03035                         dbus_message_get_member (message) != NULL);
03036   _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
03037                         (dbus_message_get_interface (message) != NULL &&
03038                          dbus_message_get_member (message) != NULL));
03039   
03040   CONNECTION_LOCK (connection);
03041   _dbus_connection_send_preallocated_and_unlock (connection,
03042                                                  preallocated,
03043                                                  message, client_serial);
03044 }
03045 
03046 static dbus_bool_t
03047 _dbus_connection_send_unlocked_no_update (DBusConnection *connection,
03048                                           DBusMessage    *message,
03049                                           dbus_uint32_t  *client_serial)
03050 {
03051   DBusPreallocatedSend *preallocated;
03052 
03053   _dbus_assert (connection != NULL);
03054   _dbus_assert (message != NULL);
03055   
03056   preallocated = _dbus_connection_preallocate_send_unlocked (connection);
03057   if (preallocated == NULL)
03058     return FALSE;
03059 
03060   _dbus_connection_send_preallocated_unlocked_no_update (connection,
03061                                                          preallocated,
03062                                                          message,
03063                                                          client_serial);
03064   return TRUE;
03065 }
03066 
03094 dbus_bool_t
03095 dbus_connection_send (DBusConnection *connection,
03096                       DBusMessage    *message,
03097                       dbus_uint32_t  *serial)
03098 {
03099   _dbus_return_val_if_fail (connection != NULL, FALSE);
03100   _dbus_return_val_if_fail (message != NULL, FALSE);
03101 
03102   CONNECTION_LOCK (connection);
03103 
03104   return _dbus_connection_send_and_unlock (connection,
03105                                            message,
03106                                            serial);
03107 }
03108 
03109 static dbus_bool_t
03110 reply_handler_timeout (void *data)
03111 {
03112   DBusConnection *connection;
03113   DBusDispatchStatus status;
03114   DBusPendingCall *pending = data;
03115 
03116   connection = _dbus_pending_call_get_connection_and_lock (pending);
03117 
03118   _dbus_pending_call_queue_timeout_error_unlocked (pending, 
03119                                                    connection);
03120   _dbus_connection_remove_timeout_unlocked (connection,
03121                                             _dbus_pending_call_get_timeout_unlocked (pending));
03122   _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
03123 
03124   _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
03125   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03126 
03127   /* Unlocks, and calls out to user code */
03128   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03129   
03130   return TRUE;
03131 }
03132 
03170 dbus_bool_t
03171 dbus_connection_send_with_reply (DBusConnection     *connection,
03172                                  DBusMessage        *message,
03173                                  DBusPendingCall   **pending_return,
03174                                  int                 timeout_milliseconds)
03175 {
03176   DBusPendingCall *pending;
03177   dbus_int32_t serial = -1;
03178   DBusDispatchStatus status;
03179 
03180   _dbus_return_val_if_fail (connection != NULL, FALSE);
03181   _dbus_return_val_if_fail (message != NULL, FALSE);
03182   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03183 
03184   if (pending_return)
03185     *pending_return = NULL;
03186 
03187   CONNECTION_LOCK (connection);
03188 
03189    if (!_dbus_connection_get_is_connected_unlocked (connection))
03190     {
03191       CONNECTION_UNLOCK (connection);
03192 
03193       return TRUE;
03194     }
03195 
03196   pending = _dbus_pending_call_new_unlocked (connection,
03197                                              timeout_milliseconds,
03198                                              reply_handler_timeout);
03199 
03200   if (pending == NULL)
03201     {
03202       CONNECTION_UNLOCK (connection);
03203       return FALSE;
03204     }
03205 
03206   /* Assign a serial to the message */
03207   serial = dbus_message_get_serial (message);
03208   if (serial == 0)
03209     {
03210       serial = _dbus_connection_get_next_client_serial (connection);
03211       _dbus_message_set_serial (message, serial);
03212     }
03213 
03214   if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
03215     goto error;
03216     
03217   /* Insert the serial in the pending replies hash;
03218    * hash takes a refcount on DBusPendingCall.
03219    * Also, add the timeout.
03220    */
03221   if (!_dbus_connection_attach_pending_call_unlocked (connection,
03222                                                       pending))
03223     goto error;
03224  
03225   if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
03226     {
03227       _dbus_connection_detach_pending_call_and_unlock (connection,
03228                                                        pending);
03229       goto error_unlocked;
03230     }
03231 
03232   if (pending_return)
03233     *pending_return = pending; /* hand off refcount */
03234   else
03235     {
03236       _dbus_connection_detach_pending_call_unlocked (connection, pending);
03237       /* we still have a ref to the pending call in this case, we unref
03238        * after unlocking, below
03239        */
03240     }
03241 
03242   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03243 
03244   /* this calls out to user code */
03245   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03246 
03247   if (pending_return == NULL)
03248     dbus_pending_call_unref (pending);
03249   
03250   return TRUE;
03251 
03252  error:
03253   CONNECTION_UNLOCK (connection);
03254  error_unlocked:
03255   dbus_pending_call_unref (pending);
03256   return FALSE;
03257 }
03258 
03289 DBusMessage*
03290 dbus_connection_send_with_reply_and_block (DBusConnection     *connection,
03291                                            DBusMessage        *message,
03292                                            int                 timeout_milliseconds,
03293                                            DBusError          *error)
03294 {
03295   DBusMessage *reply;
03296   DBusPendingCall *pending;
03297   
03298   _dbus_return_val_if_fail (connection != NULL, NULL);
03299   _dbus_return_val_if_fail (message != NULL, NULL);
03300   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL);
03301   _dbus_return_val_if_error_is_set (error, NULL);
03302   
03303   if (!dbus_connection_send_with_reply (connection, message,
03304                                         &pending, timeout_milliseconds))
03305     {
03306       _DBUS_SET_OOM (error);
03307       return NULL;
03308     }
03309 
03310   if (pending == NULL)
03311     {
03312       dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Connection is closed");
03313       return NULL;
03314     }
03315   
03316   dbus_pending_call_block (pending);
03317 
03318   reply = dbus_pending_call_steal_reply (pending);
03319   dbus_pending_call_unref (pending);
03320 
03321   /* call_complete_and_unlock() called from pending_call_block() should
03322    * always fill this in.
03323    */
03324   _dbus_assert (reply != NULL);
03325   
03326    if (dbus_set_error_from_message (error, reply))
03327     {
03328       dbus_message_unref (reply);
03329       return NULL;
03330     }
03331   else
03332     return reply;
03333 }
03334 
03343 DBusDispatchStatus
03344 _dbus_connection_flush_unlocked (DBusConnection *connection)
03345 {
03346   /* We have to specify DBUS_ITERATION_DO_READING here because
03347    * otherwise we could have two apps deadlock if they are both doing
03348    * a flush(), and the kernel buffers fill up. This could change the
03349    * dispatch status.
03350    */
03351   DBusDispatchStatus status;
03352 
03353   HAVE_LOCK_CHECK (connection);
03354   
03355   while (connection->n_outgoing > 0 &&
03356          _dbus_connection_get_is_connected_unlocked (connection))
03357     {
03358       _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME);
03359       HAVE_LOCK_CHECK (connection);
03360       _dbus_connection_do_iteration_unlocked (connection,
03361                                               DBUS_ITERATION_DO_READING |
03362                                               DBUS_ITERATION_DO_WRITING |
03363                                               DBUS_ITERATION_BLOCK,
03364                                               -1);
03365     }
03366 
03367   HAVE_LOCK_CHECK (connection);
03368   _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
03369   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03370 
03371   HAVE_LOCK_CHECK (connection);
03372   return status;
03373 }
03374 
03380 void
03381 dbus_connection_flush (DBusConnection *connection)
03382 {
03383   /* We have to specify DBUS_ITERATION_DO_READING here because
03384    * otherwise we could have two apps deadlock if they are both doing
03385    * a flush(), and the kernel buffers fill up. This could change the
03386    * dispatch status.
03387    */
03388   DBusDispatchStatus status;
03389 
03390   _dbus_return_if_fail (connection != NULL);
03391   
03392   CONNECTION_LOCK (connection);
03393 
03394   status = _dbus_connection_flush_unlocked (connection);
03395   
03396   HAVE_LOCK_CHECK (connection);
03397   /* Unlocks and calls out to user code */
03398   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03399 
03400   _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
03401 }
03402 
03413 static dbus_bool_t
03414 _dbus_connection_read_write_dispatch (DBusConnection *connection,
03415                                      int             timeout_milliseconds, 
03416                                      dbus_bool_t     dispatch)
03417 {
03418   DBusDispatchStatus dstatus;
03419   dbus_bool_t progress_possible;
03420 
03421   /* Need to grab a ref here in case we're a private connection and
03422    * the user drops the last ref in a handler we call; see bug 
03423    * https://bugs.freedesktop.org/show_bug.cgi?id=15635
03424    */
03425   dbus_connection_ref (connection);
03426   dstatus = dbus_connection_get_dispatch_status (connection);
03427 
03428   if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
03429     {
03430       _dbus_verbose ("doing dispatch in %s\n", _DBUS_FUNCTION_NAME);
03431       dbus_connection_dispatch (connection);
03432       CONNECTION_LOCK (connection);
03433     }
03434   else if (dstatus == DBUS_DISPATCH_NEED_MEMORY)
03435     {
03436       _dbus_verbose ("pausing for memory in %s\n", _DBUS_FUNCTION_NAME);
03437       _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
03438       CONNECTION_LOCK (connection);
03439     }
03440   else
03441     {
03442       CONNECTION_LOCK (connection);
03443       if (_dbus_connection_get_is_connected_unlocked (connection))
03444         {
03445           _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME);
03446           _dbus_connection_do_iteration_unlocked (connection,
03447                                                   DBUS_ITERATION_DO_READING |
03448                                                   DBUS_ITERATION_DO_WRITING |
03449                                                   DBUS_ITERATION_BLOCK,
03450                                                   timeout_milliseconds);
03451         }
03452     }
03453   
03454   HAVE_LOCK_CHECK (connection);
03455   /* If we can dispatch, we can make progress until the Disconnected message
03456    * has been processed; if we can only read/write, we can make progress
03457    * as long as the transport is open.
03458    */
03459   if (dispatch)
03460     progress_possible = connection->n_incoming != 0 ||
03461       connection->disconnect_message_link != NULL;
03462   else
03463     progress_possible = _dbus_connection_get_is_connected_unlocked (connection);
03464 
03465   CONNECTION_UNLOCK (connection);
03466 
03467   dbus_connection_unref (connection);
03468 
03469   return progress_possible; /* TRUE if we can make more progress */
03470 }
03471 
03472 
03507 dbus_bool_t
03508 dbus_connection_read_write_dispatch (DBusConnection *connection,
03509                                      int             timeout_milliseconds)
03510 {
03511   _dbus_return_val_if_fail (connection != NULL, FALSE);
03512   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03513    return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE);
03514 }
03515 
03539 dbus_bool_t 
03540 dbus_connection_read_write (DBusConnection *connection, 
03541                             int             timeout_milliseconds) 
03542 { 
03543   _dbus_return_val_if_fail (connection != NULL, FALSE);
03544   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03545    return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE);
03546 }
03547 
03548 /* We need to call this anytime we pop the head of the queue, and then
03549  * update_dispatch_status_and_unlock needs to be called afterward
03550  * which will "process" the disconnected message and set
03551  * disconnected_message_processed.
03552  */
03553 static void
03554 check_disconnected_message_arrived_unlocked (DBusConnection *connection,
03555                                              DBusMessage    *head_of_queue)
03556 {
03557   HAVE_LOCK_CHECK (connection);
03558 
03559   /* checking that the link is NULL is an optimization to avoid the is_signal call */
03560   if (connection->disconnect_message_link == NULL &&
03561       dbus_message_is_signal (head_of_queue,
03562                               DBUS_INTERFACE_LOCAL,
03563                               "Disconnected"))
03564     {
03565       connection->disconnected_message_arrived = TRUE;
03566     }
03567 }
03568 
03588 DBusMessage*
03589 dbus_connection_borrow_message (DBusConnection *connection)
03590 {
03591   DBusDispatchStatus status;
03592   DBusMessage *message;
03593 
03594   _dbus_return_val_if_fail (connection != NULL, NULL);
03595 
03596   _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
03597   
03598   /* this is called for the side effect that it queues
03599    * up any messages from the transport
03600    */
03601   status = dbus_connection_get_dispatch_status (connection);
03602   if (status != DBUS_DISPATCH_DATA_REMAINS)
03603     return NULL;
03604   
03605   CONNECTION_LOCK (connection);
03606 
03607   _dbus_connection_acquire_dispatch (connection);
03608 
03609   /* While a message is outstanding, the dispatch lock is held */
03610   _dbus_assert (connection->message_borrowed == NULL);
03611 
03612   connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
03613   
03614   message = connection->message_borrowed;
03615 
03616   check_disconnected_message_arrived_unlocked (connection, message);
03617   
03618   /* Note that we KEEP the dispatch lock until the message is returned */
03619   if (message == NULL)
03620     _dbus_connection_release_dispatch (connection);
03621 
03622   CONNECTION_UNLOCK (connection);
03623 
03624   /* We don't update dispatch status until it's returned or stolen */
03625   
03626   return message;
03627 }
03628 
03637 void
03638 dbus_connection_return_message (DBusConnection *connection,
03639                                 DBusMessage    *message)
03640 {
03641   DBusDispatchStatus status;
03642   
03643   _dbus_return_if_fail (connection != NULL);
03644   _dbus_return_if_fail (message != NULL);
03645   _dbus_return_if_fail (message == connection->message_borrowed);
03646   _dbus_return_if_fail (connection->dispatch_acquired);
03647   
03648   CONNECTION_LOCK (connection);
03649   
03650   _dbus_assert (message == connection->message_borrowed);
03651   
03652   connection->message_borrowed = NULL;
03653 
03654   _dbus_connection_release_dispatch (connection); 
03655 
03656   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03657   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03658 }
03659 
03669 void
03670 dbus_connection_steal_borrowed_message (DBusConnection *connection,
03671                                         DBusMessage    *message)
03672 {
03673   DBusMessage *pop_message;
03674   DBusDispatchStatus status;
03675 
03676   _dbus_return_if_fail (connection != NULL);
03677   _dbus_return_if_fail (message != NULL);
03678   _dbus_return_if_fail (message == connection->message_borrowed);
03679   _dbus_return_if_fail (connection->dispatch_acquired);
03680   
03681   CONNECTION_LOCK (connection);
03682  
03683   _dbus_assert (message == connection->message_borrowed);
03684 
03685   pop_message = _dbus_list_pop_first (&connection->incoming_messages);
03686   _dbus_assert (message == pop_message);
03687   
03688   connection->n_incoming -= 1;
03689  
03690   _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
03691                  message, connection->n_incoming);
03692  
03693   connection->message_borrowed = NULL;
03694 
03695   _dbus_connection_release_dispatch (connection);
03696 
03697   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03698   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03699 }
03700 
03701 /* See dbus_connection_pop_message, but requires the caller to own
03702  * the lock before calling. May drop the lock while running.
03703  */
03704 static DBusList*
03705 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
03706 {
03707   HAVE_LOCK_CHECK (connection);
03708   
03709   _dbus_assert (connection->message_borrowed == NULL);
03710   
03711   if (connection->n_incoming > 0)
03712     {
03713       DBusList *link;
03714 
03715       link = _dbus_list_pop_first_link (&connection->incoming_messages);
03716       connection->n_incoming -= 1;
03717 
03718       _dbus_verbose ("Message %p (%d %s %s %s '%s') removed from incoming queue %p, %d incoming\n",
03719                      link->data,
03720                      dbus_message_get_type (link->data),
03721                      dbus_message_get_path (link->data) ?
03722                      dbus_message_get_path (link->data) :
03723                      "no path",
03724                      dbus_message_get_interface (link->data) ?
03725                      dbus_message_get_interface (link->data) :
03726                      "no interface",
03727                      dbus_message_get_member (link->data) ?
03728                      dbus_message_get_member (link->data) :
03729                      "no member",
03730                      dbus_message_get_signature (link->data),
03731                      connection, connection->n_incoming);
03732 
03733       check_disconnected_message_arrived_unlocked (connection, link->data);
03734       
03735       return link;
03736     }
03737   else
03738     return NULL;
03739 }
03740 
03741 /* See dbus_connection_pop_message, but requires the caller to own
03742  * the lock before calling. May drop the lock while running.
03743  */
03744 static DBusMessage*
03745 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
03746 {
03747   DBusList *link;
03748 
03749   HAVE_LOCK_CHECK (connection);
03750   
03751   link = _dbus_connection_pop_message_link_unlocked (connection);
03752 
03753   if (link != NULL)
03754     {
03755       DBusMessage *message;
03756       
03757       message = link->data;
03758       
03759       _dbus_list_free_link (link);
03760       
03761       return message;
03762     }
03763   else
03764     return NULL;
03765 }
03766 
03767 static void
03768 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
03769                                                 DBusList       *message_link)
03770 {
03771   HAVE_LOCK_CHECK (connection);
03772   
03773   _dbus_assert (message_link != NULL);
03774   /* You can't borrow a message while a link is outstanding */
03775   _dbus_assert (connection->message_borrowed == NULL);
03776   /* We had to have the dispatch lock across the pop/putback */
03777   _dbus_assert (connection->dispatch_acquired);
03778 
03779   _dbus_list_prepend_link (&connection->incoming_messages,
03780                            message_link);
03781   connection->n_incoming += 1;
03782 
03783   _dbus_verbose ("Message %p (%d %s %s '%s') put back into queue %p, %d incoming\n",
03784                  message_link->data,
03785                  dbus_message_get_type (message_link->data),
03786                  dbus_message_get_interface (message_link->data) ?
03787                  dbus_message_get_interface (message_link->data) :
03788                  "no interface",
03789                  dbus_message_get_member (message_link->data) ?
03790                  dbus_message_get_member (message_link->data) :
03791                  "no member",
03792                  dbus_message_get_signature (message_link->data),
03793                  connection, connection->n_incoming);
03794 }
03795 
03815 DBusMessage*
03816 dbus_connection_pop_message (DBusConnection *connection)
03817 {
03818   DBusMessage *message;
03819   DBusDispatchStatus status;
03820 
03821   _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
03822   
03823   /* this is called for the side effect that it queues
03824    * up any messages from the transport
03825    */
03826   status = dbus_connection_get_dispatch_status (connection);
03827   if (status != DBUS_DISPATCH_DATA_REMAINS)
03828     return NULL;
03829   
03830   CONNECTION_LOCK (connection);
03831   _dbus_connection_acquire_dispatch (connection);
03832   HAVE_LOCK_CHECK (connection);
03833   
03834   message = _dbus_connection_pop_message_unlocked (connection);
03835 
03836   _dbus_verbose ("Returning popped message %p\n", message);    
03837 
03838   _dbus_connection_release_dispatch (connection);
03839 
03840   status = _dbus_connection_get_dispatch_status_unlocked (connection);
03841   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03842   
03843   return message;
03844 }
03845 
03853 static void
03854 _dbus_connection_acquire_dispatch (DBusConnection *connection)
03855 {
03856   HAVE_LOCK_CHECK (connection);
03857 
03858   _dbus_connection_ref_unlocked (connection);
03859   CONNECTION_UNLOCK (connection);
03860   
03861   _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03862   _dbus_mutex_lock (connection->dispatch_mutex);
03863 
03864   while (connection->dispatch_acquired)
03865     {
03866       _dbus_verbose ("%s waiting for dispatch to be acquirable\n", _DBUS_FUNCTION_NAME);
03867       _dbus_condvar_wait (connection->dispatch_cond, 
03868                           connection->dispatch_mutex);
03869     }
03870   
03871   _dbus_assert (!connection->dispatch_acquired);
03872 
03873   connection->dispatch_acquired = TRUE;
03874 
03875   _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03876   _dbus_mutex_unlock (connection->dispatch_mutex);
03877   
03878   CONNECTION_LOCK (connection);
03879   _dbus_connection_unref_unlocked (connection);
03880 }
03881 
03889 static void
03890 _dbus_connection_release_dispatch (DBusConnection *connection)
03891 {
03892   HAVE_LOCK_CHECK (connection);
03893   
03894   _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03895   _dbus_mutex_lock (connection->dispatch_mutex);
03896   
03897   _dbus_assert (connection->dispatch_acquired);
03898 
03899   connection->dispatch_acquired = FALSE;
03900   _dbus_condvar_wake_one (connection->dispatch_cond);
03901 
03902   _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03903   _dbus_mutex_unlock (connection->dispatch_mutex);
03904 }
03905 
03906 static void
03907 _dbus_connection_failed_pop (DBusConnection *connection,
03908                              DBusList       *message_link)
03909 {
03910   _dbus_list_prepend_link (&connection->incoming_messages,
03911                            message_link);
03912   connection->n_incoming += 1;
03913 }
03914 
03915 /* Note this may be called multiple times since we don't track whether we already did it */
03916 static void
03917 notify_disconnected_unlocked (DBusConnection *connection)
03918 {
03919   HAVE_LOCK_CHECK (connection);
03920 
03921   /* Set the weakref in dbus-bus.c to NULL, so nobody will get a disconnected
03922    * connection from dbus_bus_get(). We make the same guarantee for
03923    * dbus_connection_open() but in a different way since we don't want to
03924    * unref right here; we instead check for connectedness before returning
03925    * the connection from the hash.
03926    */
03927   _dbus_bus_notify_shared_connection_disconnected_unlocked (connection);
03928 
03929   /* Dump the outgoing queue, we aren't going to be able to
03930    * send it now, and we'd like accessors like
03931    * dbus_connection_get_outgoing_size() to be accurate.
03932    */
03933   if (connection->n_outgoing > 0)
03934     {
03935       DBusList *link;
03936       
03937       _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
03938                      connection->n_outgoing);
03939       
03940       while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
03941         {
03942           _dbus_connection_message_sent (connection, link->data);
03943         }
03944     } 
03945 }
03946 
03947 /* Note this may be called multiple times since we don't track whether we already did it */
03948 static DBusDispatchStatus
03949 notify_disconnected_and_dispatch_complete_unlocked (DBusConnection *connection)
03950 {
03951   HAVE_LOCK_CHECK (connection);
03952   
03953   if (connection->disconnect_message_link != NULL)
03954     {
03955       _dbus_verbose ("Sending disconnect message from %s\n",
03956                      _DBUS_FUNCTION_NAME);
03957       
03958       /* If we have pending calls, queue their timeouts - we want the Disconnected
03959        * to be the last message, after these timeouts.
03960        */
03961       connection_timeout_and_complete_all_pending_calls_unlocked (connection);
03962       
03963       /* We haven't sent the disconnect message already,
03964        * and all real messages have been queued up.
03965        */
03966       _dbus_connection_queue_synthesized_message_link (connection,
03967                                                        connection->disconnect_message_link);
03968       connection->disconnect_message_link = NULL;
03969 
03970       return DBUS_DISPATCH_DATA_REMAINS;
03971     }
03972 
03973   return DBUS_DISPATCH_COMPLETE;
03974 }
03975 
03976 static DBusDispatchStatus
03977 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
03978 {
03979   HAVE_LOCK_CHECK (connection);
03980   
03981   if (connection->n_incoming > 0)
03982     return DBUS_DISPATCH_DATA_REMAINS;
03983   else if (!_dbus_transport_queue_messages (connection->transport))
03984     return DBUS_DISPATCH_NEED_MEMORY;
03985   else
03986     {
03987       DBusDispatchStatus status;
03988       dbus_bool_t is_connected;
03989       
03990       status = _dbus_transport_get_dispatch_status (connection->transport);
03991       is_connected = _dbus_transport_get_is_connected (connection->transport);
03992 
03993       _dbus_verbose ("dispatch status = %s is_connected = %d\n",
03994                      DISPATCH_STATUS_NAME (status), is_connected);
03995       
03996       if (!is_connected)
03997         {
03998           /* It's possible this would be better done by having an explicit
03999            * notification from _dbus_transport_disconnect() that would
04000            * synchronously do this, instead of waiting for the next dispatch
04001            * status check. However, probably not good to change until it causes
04002            * a problem.
04003            */
04004           notify_disconnected_unlocked (connection);
04005 
04006           /* I'm not sure this is needed; the idea is that we want to
04007            * queue the Disconnected only after we've read all the
04008            * messages, but if we're disconnected maybe we are guaranteed
04009            * to have read them all ?
04010            */
04011           if (status == DBUS_DISPATCH_COMPLETE)
04012             status = notify_disconnected_and_dispatch_complete_unlocked (connection);
04013         }
04014       
04015       if (status != DBUS_DISPATCH_COMPLETE)
04016         return status;
04017       else if (connection->n_incoming > 0)
04018         return DBUS_DISPATCH_DATA_REMAINS;
04019       else
04020         return DBUS_DISPATCH_COMPLETE;
04021     }
04022 }
04023 
04024 static void
04025 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection    *connection,
04026                                                     DBusDispatchStatus new_status)
04027 {
04028   dbus_bool_t changed;
04029   DBusDispatchStatusFunction function;
04030   void *data;
04031 
04032   HAVE_LOCK_CHECK (connection);
04033 
04034   _dbus_connection_ref_unlocked (connection);
04035 
04036   changed = new_status != connection->last_dispatch_status;
04037 
04038   connection->last_dispatch_status = new_status;
04039 
04040   function = connection->dispatch_status_function;
04041   data = connection->dispatch_status_data;
04042 
04043   if (connection->disconnected_message_arrived &&
04044       !connection->disconnected_message_processed)
04045     {
04046       connection->disconnected_message_processed = TRUE;
04047       
04048       /* this does an unref, but we have a ref
04049        * so we should not run the finalizer here
04050        * inside the lock.
04051        */
04052       connection_forget_shared_unlocked (connection);
04053 
04054       if (connection->exit_on_disconnect)
04055         {
04056           CONNECTION_UNLOCK (connection);            
04057           
04058           _dbus_verbose ("Exiting on Disconnected signal\n");
04059           _dbus_exit (1);
04060           _dbus_assert_not_reached ("Call to exit() returned");
04061         }
04062     }
04063   
04064   /* We drop the lock */
04065   CONNECTION_UNLOCK (connection);
04066   
04067   if (changed && function)
04068     {
04069       _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
04070                      connection, new_status,
04071                      DISPATCH_STATUS_NAME (new_status));
04072       (* function) (connection, new_status, data);      
04073     }
04074   
04075   dbus_connection_unref (connection);
04076 }
04077 
04103 DBusDispatchStatus
04104 dbus_connection_get_dispatch_status (DBusConnection *connection)
04105 {
04106   DBusDispatchStatus status;
04107 
04108   _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04109 
04110   _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
04111   
04112   CONNECTION_LOCK (connection);
04113 
04114   status = _dbus_connection_get_dispatch_status_unlocked (connection);
04115   
04116   CONNECTION_UNLOCK (connection);
04117 
04118   return status;
04119 }
04120 
04124 static DBusHandlerResult
04125 _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
04126                                                  DBusMessage    *message)
04127 {
04128   if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
04129     {
04130       /* This means we're letting the bus route this message */
04131       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04132     }
04133   else if (dbus_message_is_method_call (message,
04134                                         DBUS_INTERFACE_PEER,
04135                                         "Ping"))
04136     {
04137       DBusMessage *ret;
04138       dbus_bool_t sent;
04139       
04140       ret = dbus_message_new_method_return (message);
04141       if (ret == NULL)
04142         return DBUS_HANDLER_RESULT_NEED_MEMORY;
04143      
04144       sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04145 
04146       dbus_message_unref (ret);
04147 
04148       if (!sent)
04149         return DBUS_HANDLER_RESULT_NEED_MEMORY;
04150       
04151       return DBUS_HANDLER_RESULT_HANDLED;
04152     }
04153   else if (dbus_message_is_method_call (message,
04154                                         DBUS_INTERFACE_PEER,
04155                                         "GetMachineId"))
04156     {
04157       DBusMessage *ret;
04158       dbus_bool_t sent;
04159       DBusString uuid;
04160       
04161       ret = dbus_message_new_method_return (message);
04162       if (ret == NULL)
04163         return DBUS_HANDLER_RESULT_NEED_MEMORY;
04164 
04165       sent = FALSE;
04166       _dbus_string_init (&uuid);
04167       if (_dbus_get_local_machine_uuid_encoded (&uuid))
04168         {
04169           const char *v_STRING = _dbus_string_get_const_data (&uuid);
04170           if (dbus_message_append_args (ret,
04171                                         DBUS_TYPE_STRING, &v_STRING,
04172                                         DBUS_TYPE_INVALID))
04173             {
04174               sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04175             }
04176         }
04177       _dbus_string_free (&uuid);
04178       
04179       dbus_message_unref (ret);
04180 
04181       if (!sent)
04182         return DBUS_HANDLER_RESULT_NEED_MEMORY;
04183       
04184       return DBUS_HANDLER_RESULT_HANDLED;
04185     }
04186   else if (dbus_message_has_interface (message, DBUS_INTERFACE_PEER))
04187     {
04188       /* We need to bounce anything else with this interface, otherwise apps
04189        * could start extending the interface and when we added extensions
04190        * here to DBusConnection we'd break those apps.
04191        */
04192       
04193       DBusMessage *ret;
04194       dbus_bool_t sent;
04195       
04196       ret = dbus_message_new_error (message,
04197                                     DBUS_ERROR_UNKNOWN_METHOD,
04198                                     "Unknown method invoked on org.freedesktop.DBus.Peer interface");
04199       if (ret == NULL)
04200         return DBUS_HANDLER_RESULT_NEED_MEMORY;
04201       
04202       sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04203       
04204       dbus_message_unref (ret);
04205       
04206       if (!sent)
04207         return DBUS_HANDLER_RESULT_NEED_MEMORY;
04208       
04209       return DBUS_HANDLER_RESULT_HANDLED;
04210     }
04211   else
04212     {
04213       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04214     }
04215 }
04216 
04223 static DBusHandlerResult
04224 _dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection,
04225                                                            DBusMessage    *message)
04226 {
04227   /* We just run one filter for now but have the option to run more
04228      if the spec calls for it in the future */
04229 
04230   return _dbus_connection_peer_filter_unlocked_no_update (connection, message);
04231 }
04232 
04275 DBusDispatchStatus
04276 dbus_connection_dispatch (DBusConnection *connection)
04277 {
04278   DBusMessage *message;
04279   DBusList *link, *filter_list_copy, *message_link;
04280   DBusHandlerResult result;
04281   DBusPendingCall *pending;
04282   dbus_int32_t reply_serial;
04283   DBusDispatchStatus status;
04284 
04285   _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04286 
04287   _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
04288   
04289   CONNECTION_LOCK (connection);
04290   status = _dbus_connection_get_dispatch_status_unlocked (connection);
04291   if (status != DBUS_DISPATCH_DATA_REMAINS)
04292     {
04293       /* unlocks and calls out to user code */
04294       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04295       return status;
04296     }
04297   
04298   /* We need to ref the connection since the callback could potentially
04299    * drop the last ref to it
04300    */
04301   _dbus_connection_ref_unlocked (connection);
04302 
04303   _dbus_connection_acquire_dispatch (connection);
04304   HAVE_LOCK_CHECK (connection);
04305 
04306   message_link = _dbus_connection_pop_message_link_unlocked (connection);
04307   if (message_link == NULL)
04308     {
04309       /* another thread dispatched our stuff */
04310 
04311       _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
04312       
04313       _dbus_connection_release_dispatch (connection);
04314 
04315       status = _dbus_connection_get_dispatch_status_unlocked (connection);
04316 
04317       _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04318       
04319       dbus_connection_unref (connection);
04320       
04321       return status;
04322     }
04323 
04324   message = message_link->data;
04325 
04326   _dbus_verbose (" dispatching message %p (%d %s %s '%s')\n",
04327                  message,
04328                  dbus_message_get_type (message),
04329                  dbus_message_get_interface (message) ?
04330                  dbus_message_get_interface (message) :
04331                  "no interface",
04332                  dbus_message_get_member (message) ?
04333                  dbus_message_get_member (message) :
04334                  "no member",
04335                  dbus_message_get_signature (message));
04336 
04337   result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04338   
04339   /* Pending call handling must be first, because if you do
04340    * dbus_connection_send_with_reply_and_block() or
04341    * dbus_pending_call_block() then no handlers/filters will be run on
04342    * the reply. We want consistent semantics in the case where we
04343    * dbus_connection_dispatch() the reply.
04344    */
04345   
04346   reply_serial = dbus_message_get_reply_serial (message);
04347   pending = _dbus_hash_table_lookup_int (connection->pending_replies,
04348                                          reply_serial);
04349   if (pending)
04350     {
04351       _dbus_verbose ("Dispatching a pending reply\n");
04352       complete_pending_call_and_unlock (connection, pending, message);
04353       pending = NULL; /* it's probably unref'd */
04354       
04355       CONNECTION_LOCK (connection);
04356       _dbus_verbose ("pending call completed in dispatch\n");
04357       result = DBUS_HANDLER_RESULT_HANDLED;
04358       goto out;
04359     }
04360 
04361   result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message);
04362   if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04363     goto out;
04364  
04365   if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
04366     {
04367       _dbus_connection_release_dispatch (connection);
04368       HAVE_LOCK_CHECK (connection);
04369       
04370       _dbus_connection_failed_pop (connection, message_link);
04371 
04372       /* unlocks and calls user code */
04373       _dbus_connection_update_dispatch_status_and_unlock (connection,
04374                                                           DBUS_DISPATCH_NEED_MEMORY);
04375 
04376       if (pending)
04377         dbus_pending_call_unref (pending);
04378       dbus_connection_unref (connection);
04379       
04380       return DBUS_DISPATCH_NEED_MEMORY;
04381     }
04382   
04383   _dbus_list_foreach (&filter_list_copy,
04384                       (DBusForeachFunction)_dbus_message_filter_ref,
04385                       NULL);
04386 
04387   /* We're still protected from dispatch() reentrancy here
04388    * since we acquired the dispatcher
04389    */
04390   CONNECTION_UNLOCK (connection);
04391   
04392   link = _dbus_list_get_first_link (&filter_list_copy);
04393   while (link != NULL)
04394     {
04395       DBusMessageFilter *filter = link->data;
04396       DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
04397 
04398       if (filter->function == NULL)
04399         {
04400           _dbus_verbose ("  filter was removed in a callback function\n");
04401           link = next;
04402           continue;
04403         }
04404 
04405       _dbus_verbose ("  running filter on message %p\n", message);
04406       result = (* filter->function) (connection, message, filter->user_data);
04407 
04408       if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04409         break;
04410 
04411       link = next;
04412     }
04413 
04414   _dbus_list_foreach (&filter_list_copy,
04415                       (DBusForeachFunction)_dbus_message_filter_unref,
04416                       NULL);
04417   _dbus_list_clear (&filter_list_copy);
04418   
04419   CONNECTION_LOCK (connection);
04420 
04421   if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04422     {
04423       _dbus_verbose ("No memory in %s\n", _DBUS_FUNCTION_NAME);
04424       goto out;
04425     }
04426   else if (result == DBUS_HANDLER_RESULT_HANDLED)
04427     {
04428       _dbus_verbose ("filter handled message in dispatch\n");
04429       goto out;
04430     }
04431 
04432   /* We're still protected from dispatch() reentrancy here
04433    * since we acquired the dispatcher
04434    */
04435   _dbus_verbose ("  running object path dispatch on message %p (%d %s %s '%s')\n",
04436                  message,
04437                  dbus_message_get_type (message),
04438                  dbus_message_get_interface (message) ?
04439                  dbus_message_get_interface (message) :
04440                  "no interface",
04441                  dbus_message_get_member (message) ?
04442                  dbus_message_get_member (message) :
04443                  "no member",
04444                  dbus_message_get_signature (message));
04445 
04446   HAVE_LOCK_CHECK (connection);
04447   result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
04448                                                   message);
04449   
04450   CONNECTION_LOCK (connection);
04451 
04452   if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04453     {
04454       _dbus_verbose ("object tree handled message in dispatch\n");
04455       goto out;
04456     }
04457 
04458   if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
04459     {
04460       DBusMessage *reply;
04461       DBusString str;
04462       DBusPreallocatedSend *preallocated;
04463 
04464       _dbus_verbose ("  sending error %s\n",
04465                      DBUS_ERROR_UNKNOWN_METHOD);
04466       
04467       if (!_dbus_string_init (&str))
04468         {
04469           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04470           _dbus_verbose ("no memory for error string in dispatch\n");
04471           goto out;
04472         }
04473               
04474       if (!_dbus_string_append_printf (&str,
04475                                        "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
04476                                        dbus_message_get_member (message),
04477                                        dbus_message_get_signature (message),
04478                                        dbus_message_get_interface (message)))
04479         {
04480           _dbus_string_free (&str);
04481           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04482           _dbus_verbose ("no memory for error string in dispatch\n");
04483           goto out;
04484         }
04485       
04486       reply = dbus_message_new_error (message,
04487                                       DBUS_ERROR_UNKNOWN_METHOD,
04488                                       _dbus_string_get_const_data (&str));
04489       _dbus_string_free (&str);
04490 
04491       if (reply == NULL)
04492         {
04493           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04494           _dbus_verbose ("no memory for error reply in dispatch\n");
04495           goto out;
04496         }
04497       
04498       preallocated = _dbus_connection_preallocate_send_unlocked (connection);
04499 
04500       if (preallocated == NULL)
04501         {
04502           dbus_message_unref (reply);
04503           result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04504           _dbus_verbose ("no memory for error send in dispatch\n");
04505           goto out;
04506         }
04507 
04508       _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
04509                                                              reply, NULL);
04510 
04511       dbus_message_unref (reply);
04512       
04513       result = DBUS_HANDLER_RESULT_HANDLED;
04514     }
04515   
04516   _dbus_verbose ("  done dispatching %p (%d %s %s '%s') on connection %p\n", message,
04517                  dbus_message_get_type (message),
04518                  dbus_message_get_interface (message) ?
04519                  dbus_message_get_interface (message) :
04520                  "no interface",
04521                  dbus_message_get_member (message) ?
04522                  dbus_message_get_member (message) :
04523                  "no member",
04524                  dbus_message_get_signature (message),
04525                  connection);
04526   
04527  out:
04528   if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04529     {
04530       _dbus_verbose ("out of memory in %s\n", _DBUS_FUNCTION_NAME);
04531       
04532       /* Put message back, and we'll start over.
04533        * Yes this means handlers must be idempotent if they
04534        * don't return HANDLED; c'est la vie.
04535        */
04536       _dbus_connection_putback_message_link_unlocked (connection,
04537                                                       message_link);
04538     }
04539   else
04540     {
04541       _dbus_verbose (" ... done dispatching in %s\n", _DBUS_FUNCTION_NAME);
04542       
04543       _dbus_list_free_link (message_link);
04544       dbus_message_unref (message); /* don't want the message to count in max message limits
04545                                      * in computing dispatch status below
04546                                      */
04547     }
04548   
04549   _dbus_connection_release_dispatch (connection);
04550   HAVE_LOCK_CHECK (connection);
04551 
04552   _dbus_verbose ("%s before final status update\n", _DBUS_FUNCTION_NAME);
04553   status = _dbus_connection_get_dispatch_status_unlocked (connection);
04554 
04555   /* unlocks and calls user code */
04556   _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04557   
04558   dbus_connection_unref (connection);
04559   
04560   return status;
04561 }
04562 
04622 dbus_bool_t
04623 dbus_connection_set_watch_functions (DBusConnection              *connection,
04624                                      DBusAddWatchFunction         add_function,
04625                                      DBusRemoveWatchFunction      remove_function,
04626                                      DBusWatchToggledFunction     toggled_function,
04627                                      void                        *data,
04628                                      DBusFreeFunction             free_data_function)
04629 {
04630   dbus_bool_t retval;
04631   DBusWatchList *watches;
04632 
04633   _dbus_return_val_if_fail (connection != NULL, FALSE);
04634   
04635   CONNECTION_LOCK (connection);
04636 
04637 #ifndef DBUS_DISABLE_CHECKS
04638   if (connection->watches == NULL)
04639     {
04640       _dbus_warn_check_failed ("Re-entrant call to %s is not allowed\n",
04641                                _DBUS_FUNCTION_NAME);
04642       return FALSE;
04643     }
04644 #endif
04645   
04646   /* ref connection for slightly better reentrancy */
04647   _dbus_connection_ref_unlocked (connection);
04648 
04649   /* This can call back into user code, and we need to drop the
04650    * connection lock when it does. This is kind of a lame
04651    * way to do it.
04652    */
04653   watches = connection->watches;
04654   connection->watches = NULL;
04655   CONNECTION_UNLOCK (connection);
04656 
04657   retval = _dbus_watch_list_set_functions (watches,
04658                                            add_function, remove_function,
04659                                            toggled_function,
04660                                            data, free_data_function);
04661   CONNECTION_LOCK (connection);
04662   connection->watches = watches;
04663   
04664   CONNECTION_UNLOCK (connection);
04665   /* drop our paranoid refcount */
04666   dbus_connection_unref (connection);
04667   
04668   return retval;
04669 }
04670 
04704 dbus_bool_t
04705 dbus_connection_set_timeout_functions   (DBusConnection            *connection,
04706                                          DBusAddTimeoutFunction     add_function,
04707                                          DBusRemoveTimeoutFunction  remove_function,
04708                                          DBusTimeoutToggledFunction toggled_function,
04709                                          void                      *data,
04710                                          DBusFreeFunction           free_data_function)
04711 {
04712   dbus_bool_t retval;
04713   DBusTimeoutList *timeouts;
04714 
04715   _dbus_return_val_if_fail (connection != NULL, FALSE);
04716   
04717   CONNECTION_LOCK (connection);
04718 
04719 #ifndef DBUS_DISABLE_CHECKS
04720   if (connection->timeouts == NULL)
04721     {
04722       _dbus_warn_check_failed ("Re-entrant call to %s is not allowed\n",
04723                                _DBUS_FUNCTION_NAME);
04724       return FALSE;
04725     }
04726 #endif
04727   
04728   /* ref connection for slightly better reentrancy */
04729   _dbus_connection_ref_unlocked (connection);
04730 
04731   timeouts = connection->timeouts;
04732   connection->timeouts = NULL;
04733   CONNECTION_UNLOCK (connection);
04734   
04735   retval = _dbus_timeout_list_set_functions (timeouts,
04736                                              add_function, remove_function,
04737                                              toggled_function,
04738                                              data, free_data_function);
04739   CONNECTION_LOCK (connection);
04740   connection->timeouts = timeouts;
04741   
04742   CONNECTION_UNLOCK (connection);
04743   /* drop our paranoid refcount */
04744   dbus_connection_unref (connection);
04745 
04746   return retval;
04747 }
04748 
04763 void
04764 dbus_connection_set_wakeup_main_function (DBusConnection            *connection,
04765                                           DBusWakeupMainFunction     wakeup_main_function,
04766                                           void                      *data,
04767                                           DBusFreeFunction           free_data_function)
04768 {
04769   void *old_data;
04770   DBusFreeFunction old_free_data;
04771 
04772   _dbus_return_if_fail (connection != NULL);
04773   
04774   CONNECTION_LOCK (connection);
04775   old_data = connection->wakeup_main_data;
04776   old_free_data = connection->free_wakeup_main_data;
04777 
04778   connection->wakeup_main_function = wakeup_main_function;
04779   connection->wakeup_main_data = data;
04780   connection->free_wakeup_main_data = free_data_function;
04781   
04782   CONNECTION_UNLOCK (connection);
04783 
04784   /* Callback outside the lock */
04785   if (old_free_data)
04786     (*old_free_data) (old_data);
04787 }
04788 
04809 void
04810 dbus_connection_set_dispatch_status_function (DBusConnection             *connection,
04811                                               DBusDispatchStatusFunction  function,
04812                                               void                       *data,
04813                                               DBusFreeFunction            free_data_function)
04814 {
04815   void *old_data;
04816   DBusFreeFunction old_free_data;
04817 
04818   _dbus_return_if_fail (connection != NULL);
04819   
04820   CONNECTION_LOCK (connection);
04821   old_data = connection->dispatch_status_data;
04822   old_free_data = connection->free_dispatch_status_data;
04823 
04824   connection->dispatch_status_function = function;
04825   connection->dispatch_status_data = data;
04826   connection->free_dispatch_status_data = free_data_function;
04827   
04828   CONNECTION_UNLOCK (connection);
04829 
04830   /* Callback outside the lock */
04831   if (old_free_data)
04832     (*old_free_data) (old_data);
04833 }
04834 
04854 dbus_bool_t
04855 dbus_connection_get_unix_fd (DBusConnection *connection,
04856                              int            *fd)
04857 {
04858   _dbus_return_val_if_fail (connection != NULL, FALSE);
04859   _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
04860 
04861 #ifdef DBUS_WIN
04862   /* FIXME do this on a lower level */
04863   return FALSE;
04864 #endif
04865   
04866   return dbus_connection_get_socket(connection, fd);
04867 }
04868 
04884 dbus_bool_t
04885 dbus_connection_get_socket(DBusConnection              *connection,
04886                            int                         *fd)
04887 {
04888   dbus_bool_t retval;
04889 
04890   _dbus_return_val_if_fail (connection != NULL, FALSE);
04891   _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
04892   
04893   CONNECTION_LOCK (connection);
04894   
04895   retval = _dbus_transport_get_socket_fd (connection->transport,
04896                                           fd);
04897 
04898   CONNECTION_UNLOCK (connection);
04899 
04900   return retval;
04901 }
04902 
04903 
04926 dbus_bool_t
04927 dbus_connection_get_unix_user (DBusConnection *connection,
04928                                unsigned long  *uid)
04929 {
04930   dbus_bool_t result;
04931 
04932   _dbus_return_val_if_fail (connection != NULL, FALSE);
04933   _dbus_return_val_if_fail (uid != NULL, FALSE);
04934   
04935   CONNECTION_LOCK (connection);
04936 
04937   if (!_dbus_transport_get_is_authenticated (connection->transport))
04938     result = FALSE;
04939   else
04940     result = _dbus_transport_get_unix_user (connection->transport,
04941                                             uid);
04942 
04943 #ifdef DBUS_WIN
04944   _dbus_assert (!result);
04945 #endif
04946   
04947   CONNECTION_UNLOCK (connection);
04948 
04949   return result;
04950 }
04951 
04962 dbus_bool_t
04963 dbus_connection_get_unix_process_id (DBusConnection *connection,
04964                                      unsigned long  *pid)
04965 {
04966   dbus_bool_t result;
04967 
04968   _dbus_return_val_if_fail (connection != NULL, FALSE);
04969   _dbus_return_val_if_fail (pid != NULL, FALSE);
04970   
04971   CONNECTION_LOCK (connection);
04972 
04973   if (!_dbus_transport_get_is_authenticated (connection->transport))
04974     result = FALSE;
04975   else
04976     result = _dbus_transport_get_unix_process_id (connection->transport,
04977                                                   pid);
04978 #ifdef DBUS_WIN
04979   _dbus_assert (!result);
04980 #endif
04981   
04982   CONNECTION_UNLOCK (connection);
04983 
04984   return result;
04985 }
04986 
04997 dbus_bool_t
04998 dbus_connection_get_adt_audit_session_data (DBusConnection *connection,
04999                                             void          **data,
05000                                             dbus_int32_t   *data_size)
05001 {
05002   dbus_bool_t result;
05003 
05004   _dbus_return_val_if_fail (connection != NULL, FALSE);
05005   _dbus_return_val_if_fail (data != NULL, FALSE);
05006   _dbus_return_val_if_fail (data_size != NULL, FALSE);
05007   
05008   CONNECTION_LOCK (connection);
05009 
05010   if (!_dbus_transport_get_is_authenticated (connection->transport))
05011     result = FALSE;
05012   else
05013     result = _dbus_transport_get_adt_audit_session_data (connection->transport,
05014                                                          data,
05015                                                          data_size);
05016   CONNECTION_UNLOCK (connection);
05017 
05018   return result;
05019 }
05020 
05043 void
05044 dbus_connection_set_unix_user_function (DBusConnection             *connection,
05045                                         DBusAllowUnixUserFunction   function,
05046                                         void                       *data,
05047                                         DBusFreeFunction            free_data_function)
05048 {
05049   void *old_data = NULL;
05050   DBusFreeFunction old_free_function = NULL;
05051 
05052   _dbus_return_if_fail (connection != NULL);
05053   
05054   CONNECTION_LOCK (connection);
05055   _dbus_transport_set_unix_user_function (connection->transport,
05056                                           function, data, free_data_function,
05057                                           &old_data, &old_free_function);
05058   CONNECTION_UNLOCK (connection);
05059 
05060   if (old_free_function != NULL)
05061     (* old_free_function) (old_data);
05062 }
05063 
05095 dbus_bool_t
05096 dbus_connection_get_windows_user (DBusConnection             *connection,
05097                                   char                      **windows_sid_p)
05098 {
05099   dbus_bool_t result;
05100 
05101   _dbus_return_val_if_fail (connection != NULL, FALSE);
05102   _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
05103   
05104   CONNECTION_LOCK (connection);
05105 
05106   if (!_dbus_transport_get_is_authenticated (connection->transport))
05107     result = FALSE;
05108   else
05109     result = _dbus_transport_get_windows_user (connection->transport,
05110                                                windows_sid_p);
05111 
05112 #ifdef DBUS_UNIX
05113   _dbus_assert (!result);
05114 #endif
05115   
05116   CONNECTION_UNLOCK (connection);
05117 
05118   return result;
05119 }
05120 
05142 void
05143 dbus_connection_set_windows_user_function (DBusConnection              *connection,
05144                                            DBusAllowWindowsUserFunction function,
05145                                            void                        *data,
05146                                            DBusFreeFunction             free_data_function)
05147 {
05148   void *old_data = NULL;
05149   DBusFreeFunction old_free_function = NULL;
05150 
05151   _dbus_return_if_fail (connection != NULL);
05152   
05153   CONNECTION_LOCK (connection);
05154   _dbus_transport_set_windows_user_function (connection->transport,
05155                                              function, data, free_data_function,
05156                                              &old_data, &old_free_function);
05157   CONNECTION_UNLOCK (connection);
05158 
05159   if (old_free_function != NULL)
05160     (* old_free_function) (old_data);
05161 }
05162 
05189 void
05190 dbus_connection_set_allow_anonymous (DBusConnection             *connection,
05191                                      dbus_bool_t                 value)
05192 {
05193   _dbus_return_if_fail (connection != NULL);
05194   
05195   CONNECTION_LOCK (connection);
05196   _dbus_transport_set_allow_anonymous (connection->transport, value);
05197   CONNECTION_UNLOCK (connection);
05198 }
05199 
05217 void
05218 dbus_connection_set_route_peer_messages (DBusConnection             *connection,
05219                                          dbus_bool_t                 value)
05220 {
05221   _dbus_return_if_fail (connection != NULL);
05222   
05223   CONNECTION_LOCK (connection);
05224   connection->route_peer_messages = TRUE;
05225   CONNECTION_UNLOCK (connection);
05226 }
05227 
05249 dbus_bool_t
05250 dbus_connection_add_filter (DBusConnection            *connection,
05251                             DBusHandleMessageFunction  function,
05252                             void                      *user_data,
05253                             DBusFreeFunction           free_data_function)
05254 {
05255   DBusMessageFilter *filter;
05256   
05257   _dbus_return_val_if_fail (connection != NULL, FALSE);
05258   _dbus_return_val_if_fail (function != NULL, FALSE);
05259 
05260   filter = dbus_new0 (DBusMessageFilter, 1);
05261   if (filter == NULL)
05262     return FALSE;
05263 
05264   filter->refcount.value = 1;
05265   
05266   CONNECTION_LOCK (connection);
05267 
05268   if (!_dbus_list_append (&connection->filter_list,
05269                           filter))
05270     {
05271       _dbus_message_filter_unref (filter);
05272       CONNECTION_UNLOCK (connection);
05273       return FALSE;
05274     }
05275 
05276   /* Fill in filter after all memory allocated,
05277    * so we don't run the free_user_data_function
05278    * if the add_filter() fails
05279    */
05280   
05281   filter->function = function;
05282   filter->user_data = user_data;
05283   filter->free_user_data_function = free_data_function;
05284         
05285   CONNECTION_UNLOCK (connection);
05286   return TRUE;
05287 }
05288 
05301 void
05302 dbus_connection_remove_filter (DBusConnection            *connection,
05303                                DBusHandleMessageFunction  function,
05304                                void                      *user_data)
05305 {
05306   DBusList *link;
05307   DBusMessageFilter *filter;
05308   
05309   _dbus_return_if_fail (connection != NULL);
05310   _dbus_return_if_fail (function != NULL);
05311   
05312   CONNECTION_LOCK (connection);
05313 
05314   filter = NULL;
05315   
05316   link = _dbus_list_get_last_link (&connection->filter_list);
05317   while (link != NULL)
05318     {
05319       filter = link->data;
05320 
05321       if (filter->function == function &&
05322           filter->user_data == user_data)
05323         {
05324           _dbus_list_remove_link (&connection->filter_list, link);
05325           filter->function = NULL;
05326           
05327           break;
05328         }
05329         
05330       link = _dbus_list_get_prev_link (&connection->filter_list, link);
05331     }
05332   
05333   CONNECTION_UNLOCK (connection);
05334 
05335 #ifndef DBUS_DISABLE_CHECKS
05336   if (filter == NULL)
05337     {
05338       _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
05339                                function, user_data);
05340       return;
05341     }
05342 #endif
05343   
05344   /* Call application code */
05345   if (filter->free_user_data_function)
05346     (* filter->free_user_data_function) (filter->user_data);
05347 
05348   filter->free_user_data_function = NULL;
05349   filter->user_data = NULL;
05350   
05351   _dbus_message_filter_unref (filter);
05352 }
05353 
05366 dbus_bool_t
05367 dbus_connection_try_register_object_path (DBusConnection              *connection,
05368                                           const char                  *path,
05369                                           const DBusObjectPathVTable  *vtable,
05370                                           void                        *user_data,
05371                                           DBusError                   *error)
05372 {
05373   char **decomposed_path;
05374   dbus_bool_t retval;
05375   
05376   _dbus_return_val_if_fail (connection != NULL, FALSE);
05377   _dbus_return_val_if_fail (path != NULL, FALSE);
05378   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05379   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05380 
05381   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05382     return FALSE;
05383 
05384   CONNECTION_LOCK (connection);
05385 
05386   retval = _dbus_object_tree_register (connection->objects,
05387                                        FALSE,
05388                                        (const char **) decomposed_path, vtable,
05389                                        user_data, error);
05390 
05391   CONNECTION_UNLOCK (connection);
05392 
05393   dbus_free_string_array (decomposed_path);
05394 
05395   return retval;
05396 }
05397 
05412 dbus_bool_t
05413 dbus_connection_register_object_path (DBusConnection              *connection,
05414                                       const char                  *path,
05415                                       const DBusObjectPathVTable  *vtable,
05416                                       void                        *user_data)
05417 {
05418   char **decomposed_path;
05419   dbus_bool_t retval;
05420   DBusError error = DBUS_ERROR_INIT;
05421 
05422   _dbus_return_val_if_fail (connection != NULL, FALSE);
05423   _dbus_return_val_if_fail (path != NULL, FALSE);
05424   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05425   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05426 
05427   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05428     return FALSE;
05429 
05430   CONNECTION_LOCK (connection);
05431 
05432   retval = _dbus_object_tree_register (connection->objects,
05433                                        FALSE,
05434                                        (const char **) decomposed_path, vtable,
05435                                        user_data, &error);
05436 
05437   CONNECTION_UNLOCK (connection);
05438 
05439   dbus_free_string_array (decomposed_path);
05440 
05441   if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE))
05442     {
05443       _dbus_warn ("%s\n", error.message);
05444       dbus_error_free (&error);
05445       return FALSE;
05446     }
05447 
05448   return retval;
05449 }
05450 
05465 dbus_bool_t
05466 dbus_connection_try_register_fallback (DBusConnection              *connection,
05467                                        const char                  *path,
05468                                        const DBusObjectPathVTable  *vtable,
05469                                        void                        *user_data,
05470                                        DBusError                   *error)
05471 {
05472   char **decomposed_path;
05473   dbus_bool_t retval;
05474 
05475   _dbus_return_val_if_fail (connection != NULL, FALSE);
05476   _dbus_return_val_if_fail (path != NULL, FALSE);
05477   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05478   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05479 
05480   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05481     return FALSE;
05482 
05483   CONNECTION_LOCK (connection);
05484 
05485   retval = _dbus_object_tree_register (connection->objects,
05486                                        TRUE,
05487                                        (const char **) decomposed_path, vtable,
05488                                        user_data, error);
05489 
05490   CONNECTION_UNLOCK (connection);
05491 
05492   dbus_free_string_array (decomposed_path);
05493 
05494   return retval;
05495 }
05496 
05513 dbus_bool_t
05514 dbus_connection_register_fallback (DBusConnection              *connection,
05515                                    const char                  *path,
05516                                    const DBusObjectPathVTable  *vtable,
05517                                    void                        *user_data)
05518 {
05519   char **decomposed_path;
05520   dbus_bool_t retval;
05521   DBusError error = DBUS_ERROR_INIT;
05522 
05523   _dbus_return_val_if_fail (connection != NULL, FALSE);
05524   _dbus_return_val_if_fail (path != NULL, FALSE);
05525   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05526   _dbus_return_val_if_fail (vtable != NULL, FALSE);
05527 
05528   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05529     return FALSE;
05530 
05531   CONNECTION_LOCK (connection);
05532 
05533   retval = _dbus_object_tree_register (connection->objects,
05534                                        TRUE,
05535                                        (const char **) decomposed_path, vtable,
05536                                        user_data, &error);
05537 
05538   CONNECTION_UNLOCK (connection);
05539 
05540   dbus_free_string_array (decomposed_path);
05541 
05542   if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE))
05543     {
05544       _dbus_warn ("%s\n", error.message);
05545       dbus_error_free (&error);
05546       return FALSE;
05547     }
05548 
05549   return retval;
05550 }
05551 
05561 dbus_bool_t
05562 dbus_connection_unregister_object_path (DBusConnection              *connection,
05563                                         const char                  *path)
05564 {
05565   char **decomposed_path;
05566 
05567   _dbus_return_val_if_fail (connection != NULL, FALSE);
05568   _dbus_return_val_if_fail (path != NULL, FALSE);
05569   _dbus_return_val_if_fail (path[0] == '/', FALSE);
05570 
05571   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05572       return FALSE;
05573 
05574   CONNECTION_LOCK (connection);
05575 
05576   _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
05577 
05578   dbus_free_string_array (decomposed_path);
05579 
05580   return TRUE;
05581 }
05582 
05593 dbus_bool_t
05594 dbus_connection_get_object_path_data (DBusConnection *connection,
05595                                       const char     *path,
05596                                       void          **data_p)
05597 {
05598   char **decomposed_path;
05599 
05600   _dbus_return_val_if_fail (connection != NULL, FALSE);
05601   _dbus_return_val_if_fail (path != NULL, FALSE);
05602   _dbus_return_val_if_fail (data_p != NULL, FALSE);
05603 
05604   *data_p = NULL;
05605   
05606   if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05607     return FALSE;
05608   
05609   CONNECTION_LOCK (connection);
05610 
05611   *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path);
05612 
05613   CONNECTION_UNLOCK (connection);
05614 
05615   dbus_free_string_array (decomposed_path);
05616 
05617   return TRUE;
05618 }
05619 
05630 dbus_bool_t
05631 dbus_connection_list_registered (DBusConnection              *connection,
05632                                  const char                  *parent_path,
05633                                  char                      ***child_entries)
05634 {
05635   char **decomposed_path;
05636   dbus_bool_t retval;
05637   _dbus_return_val_if_fail (connection != NULL, FALSE);
05638   _dbus_return_val_if_fail (parent_path != NULL, FALSE);
05639   _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
05640   _dbus_return_val_if_fail (child_entries != NULL, FALSE);
05641 
05642   if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
05643     return FALSE;
05644 
05645   CONNECTION_LOCK (connection);
05646 
05647   retval = _dbus_object_tree_list_registered_and_unlock (connection->objects,
05648                                                          (const char **) decomposed_path,
05649                                                          child_entries);
05650   dbus_free_string_array (decomposed_path);
05651 
05652   return retval;
05653 }
05654 
05655 static DBusDataSlotAllocator slot_allocator;
05656 _DBUS_DEFINE_GLOBAL_LOCK (connection_slots);
05657 
05672 dbus_bool_t
05673 dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
05674 {
05675   return _dbus_data_slot_allocator_alloc (&slot_allocator,
05676                                           &_DBUS_LOCK_NAME (connection_slots),
05677                                           slot_p);
05678 }
05679 
05691 void
05692 dbus_connection_free_data_slot (dbus_int32_t *slot_p)
05693 {
05694   _dbus_return_if_fail (*slot_p >= 0);
05695   
05696   _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
05697 }
05698 
05712 dbus_bool_t
05713 dbus_connection_set_data (DBusConnection   *connection,
05714                           dbus_int32_t      slot,
05715                           void             *data,
05716                           DBusFreeFunction  free_data_func)
05717 {
05718   DBusFreeFunction old_free_func;
05719   void *old_data;
05720   dbus_bool_t retval;
05721 
05722   _dbus_return_val_if_fail (connection != NULL, FALSE);
05723   _dbus_return_val_if_fail (slot >= 0, FALSE);
05724   
05725   CONNECTION_LOCK (connection);
05726 
05727   retval = _dbus_data_slot_list_set (&slot_allocator,
05728                                      &connection->slot_list,
05729                                      slot, data, free_data_func,
05730                                      &old_free_func, &old_data);
05731   
05732   CONNECTION_UNLOCK (connection);
05733 
05734   if (retval)
05735     {
05736       /* Do the actual free outside the connection lock */
05737       if (old_free_func)
05738         (* old_free_func) (old_data);
05739     }
05740 
05741   return retval;
05742 }
05743 
05752 void*
05753 dbus_connection_get_data (DBusConnection   *connection,
05754                           dbus_int32_t      slot)
05755 {
05756   void *res;
05757 
05758   _dbus_return_val_if_fail (connection != NULL, NULL);
05759   
05760   CONNECTION_LOCK (connection);
05761 
05762   res = _dbus_data_slot_list_get (&slot_allocator,
05763                                   &connection->slot_list,
05764                                   slot);
05765   
05766   CONNECTION_UNLOCK (connection);
05767 
05768   return res;
05769 }
05770 
05777 void
05778 dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
05779 {  
05780   _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
05781 }
05782 
05791 void
05792 dbus_connection_set_max_message_size (DBusConnection *connection,
05793                                       long            size)
05794 {
05795   _dbus_return_if_fail (connection != NULL);
05796   
05797   CONNECTION_LOCK (connection);
05798   _dbus_transport_set_max_message_size (connection->transport,
05799                                         size);
05800   CONNECTION_UNLOCK (connection);
05801 }
05802 
05809 long
05810 dbus_connection_get_max_message_size (DBusConnection *connection)
05811 {
05812   long res;
05813 
05814   _dbus_return_val_if_fail (connection != NULL, 0);
05815   
05816   CONNECTION_LOCK (connection);
05817   res = _dbus_transport_get_max_message_size (connection->transport);
05818   CONNECTION_UNLOCK (connection);
05819   return res;
05820 }
05821 
05847 void
05848 dbus_connection_set_max_received_size (DBusConnection *connection,
05849                                        long            size)
05850 {
05851   _dbus_return_if_fail (connection != NULL);
05852   
05853   CONNECTION_LOCK (connection);
05854   _dbus_transport_set_max_received_size (connection->transport,
05855                                          size);
05856   CONNECTION_UNLOCK (connection);
05857 }
05858 
05865 long
05866 dbus_connection_get_max_received_size (DBusConnection *connection)
05867 {
05868   long res;
05869 
05870   _dbus_return_val_if_fail (connection != NULL, 0);
05871   
05872   CONNECTION_LOCK (connection);
05873   res = _dbus_transport_get_max_received_size (connection->transport);
05874   CONNECTION_UNLOCK (connection);
05875   return res;
05876 }
05877 
05888 long
05889 dbus_connection_get_outgoing_size (DBusConnection *connection)
05890 {
05891   long res;
05892 
05893   _dbus_return_val_if_fail (connection != NULL, 0);
05894   
05895   CONNECTION_LOCK (connection);
05896   res = _dbus_counter_get_value (connection->outgoing_counter);
05897   CONNECTION_UNLOCK (connection);
05898   return res;
05899 }
05900 

Generated on Tue Feb 24 16:40:39 2009 for D-Bus by  doxygen 1.5.1