00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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
00285
00286
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
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
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
00593
00594
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
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
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
00656
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
00777
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
00933
00934
00935
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
00948
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
00959
00960
00961
00962
00963
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 _dbus_pending_call_unref_and_unlock (pending);
00969 }
00970
00979 void
00980 _dbus_connection_remove_pending_call (DBusConnection *connection,
00981 DBusPendingCall *pending)
00982 {
00983 CONNECTION_LOCK (connection);
00984 _dbus_connection_detach_pending_call_and_unlock (connection, pending);
00985 }
00986
00996 static dbus_bool_t
00997 _dbus_connection_acquire_io_path (DBusConnection *connection,
00998 int timeout_milliseconds)
00999 {
01000 dbus_bool_t we_acquired;
01001
01002 HAVE_LOCK_CHECK (connection);
01003
01004
01005 _dbus_connection_ref_unlocked (connection);
01006
01007
01008 CONNECTION_UNLOCK (connection);
01009
01010 _dbus_verbose ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME);
01011 _dbus_mutex_lock (connection->io_path_mutex);
01012
01013 _dbus_verbose ("%s start connection->io_path_acquired = %d timeout = %d\n",
01014 _DBUS_FUNCTION_NAME, connection->io_path_acquired, timeout_milliseconds);
01015
01016 we_acquired = FALSE;
01017
01018 if (connection->io_path_acquired)
01019 {
01020 if (timeout_milliseconds != -1)
01021 {
01022 _dbus_verbose ("%s waiting %d for IO path to be acquirable\n",
01023 _DBUS_FUNCTION_NAME, timeout_milliseconds);
01024
01025 if (!_dbus_condvar_wait_timeout (connection->io_path_cond,
01026 connection->io_path_mutex,
01027 timeout_milliseconds))
01028 {
01029
01030
01031
01032
01033
01034
01035
01036
01037 }
01038 }
01039 else
01040 {
01041 while (connection->io_path_acquired)
01042 {
01043 _dbus_verbose ("%s waiting for IO path to be acquirable\n", _DBUS_FUNCTION_NAME);
01044 _dbus_condvar_wait (connection->io_path_cond,
01045 connection->io_path_mutex);
01046 }
01047 }
01048 }
01049
01050 if (!connection->io_path_acquired)
01051 {
01052 we_acquired = TRUE;
01053 connection->io_path_acquired = TRUE;
01054 }
01055
01056 _dbus_verbose ("%s end connection->io_path_acquired = %d we_acquired = %d\n",
01057 _DBUS_FUNCTION_NAME, connection->io_path_acquired, we_acquired);
01058
01059 _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME);
01060 _dbus_mutex_unlock (connection->io_path_mutex);
01061
01062 CONNECTION_LOCK (connection);
01063
01064 HAVE_LOCK_CHECK (connection);
01065
01066 _dbus_connection_unref_unlocked (connection);
01067
01068 return we_acquired;
01069 }
01070
01078 static void
01079 _dbus_connection_release_io_path (DBusConnection *connection)
01080 {
01081 HAVE_LOCK_CHECK (connection);
01082
01083 _dbus_verbose ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME);
01084 _dbus_mutex_lock (connection->io_path_mutex);
01085
01086 _dbus_assert (connection->io_path_acquired);
01087
01088 _dbus_verbose ("%s start connection->io_path_acquired = %d\n",
01089 _DBUS_FUNCTION_NAME, connection->io_path_acquired);
01090
01091 connection->io_path_acquired = FALSE;
01092 _dbus_condvar_wake_one (connection->io_path_cond);
01093
01094 _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME);
01095 _dbus_mutex_unlock (connection->io_path_mutex);
01096 }
01097
01126 void
01127 _dbus_connection_do_iteration_unlocked (DBusConnection *connection,
01128 unsigned int flags,
01129 int timeout_milliseconds)
01130 {
01131 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
01132
01133 HAVE_LOCK_CHECK (connection);
01134
01135 if (connection->n_outgoing == 0)
01136 flags &= ~DBUS_ITERATION_DO_WRITING;
01137
01138 if (_dbus_connection_acquire_io_path (connection,
01139 (flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0))
01140 {
01141 HAVE_LOCK_CHECK (connection);
01142
01143 _dbus_transport_do_iteration (connection->transport,
01144 flags, timeout_milliseconds);
01145 _dbus_connection_release_io_path (connection);
01146 }
01147
01148 HAVE_LOCK_CHECK (connection);
01149
01150 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
01151 }
01152
01162 DBusConnection*
01163 _dbus_connection_new_for_transport (DBusTransport *transport)
01164 {
01165 DBusConnection *connection;
01166 DBusWatchList *watch_list;
01167 DBusTimeoutList *timeout_list;
01168 DBusHashTable *pending_replies;
01169 DBusList *disconnect_link;
01170 DBusMessage *disconnect_message;
01171 DBusCounter *outgoing_counter;
01172 DBusObjectTree *objects;
01173
01174 watch_list = NULL;
01175 connection = NULL;
01176 pending_replies = NULL;
01177 timeout_list = NULL;
01178 disconnect_link = NULL;
01179 disconnect_message = NULL;
01180 outgoing_counter = NULL;
01181 objects = NULL;
01182
01183 watch_list = _dbus_watch_list_new ();
01184 if (watch_list == NULL)
01185 goto error;
01186
01187 timeout_list = _dbus_timeout_list_new ();
01188 if (timeout_list == NULL)
01189 goto error;
01190
01191 pending_replies =
01192 _dbus_hash_table_new (DBUS_HASH_INT,
01193 NULL,
01194 (DBusFreeFunction)free_pending_call_on_hash_removal);
01195 if (pending_replies == NULL)
01196 goto error;
01197
01198 connection = dbus_new0 (DBusConnection, 1);
01199 if (connection == NULL)
01200 goto error;
01201
01202 _dbus_mutex_new_at_location (&connection->mutex);
01203 if (connection->mutex == NULL)
01204 goto error;
01205
01206 _dbus_mutex_new_at_location (&connection->io_path_mutex);
01207 if (connection->io_path_mutex == NULL)
01208 goto error;
01209
01210 _dbus_mutex_new_at_location (&connection->dispatch_mutex);
01211 if (connection->dispatch_mutex == NULL)
01212 goto error;
01213
01214 _dbus_condvar_new_at_location (&connection->dispatch_cond);
01215 if (connection->dispatch_cond == NULL)
01216 goto error;
01217
01218 _dbus_condvar_new_at_location (&connection->io_path_cond);
01219 if (connection->io_path_cond == NULL)
01220 goto error;
01221
01222 disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL,
01223 DBUS_INTERFACE_LOCAL,
01224 "Disconnected");
01225
01226 if (disconnect_message == NULL)
01227 goto error;
01228
01229 disconnect_link = _dbus_list_alloc_link (disconnect_message);
01230 if (disconnect_link == NULL)
01231 goto error;
01232
01233 outgoing_counter = _dbus_counter_new ();
01234 if (outgoing_counter == NULL)
01235 goto error;
01236
01237 objects = _dbus_object_tree_new (connection);
01238 if (objects == NULL)
01239 goto error;
01240
01241 if (_dbus_modify_sigpipe)
01242 _dbus_disable_sigpipe ();
01243
01244 connection->refcount.value = 1;
01245 connection->transport = transport;
01246 connection->watches = watch_list;
01247 connection->timeouts = timeout_list;
01248 connection->pending_replies = pending_replies;
01249 connection->outgoing_counter = outgoing_counter;
01250 connection->filter_list = NULL;
01251 connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE;
01252 connection->objects = objects;
01253 connection->exit_on_disconnect = FALSE;
01254 connection->shareable = FALSE;
01255 connection->route_peer_messages = FALSE;
01256 connection->disconnected_message_arrived = FALSE;
01257 connection->disconnected_message_processed = FALSE;
01258
01259 #ifndef DBUS_DISABLE_CHECKS
01260 connection->generation = _dbus_current_generation;
01261 #endif
01262
01263 _dbus_data_slot_list_init (&connection->slot_list);
01264
01265 connection->client_serial = 1;
01266
01267 connection->disconnect_message_link = disconnect_link;
01268
01269 CONNECTION_LOCK (connection);
01270
01271 if (!_dbus_transport_set_connection (transport, connection))
01272 {
01273 CONNECTION_UNLOCK (connection);
01274
01275 goto error;
01276 }
01277
01278 _dbus_transport_ref (transport);
01279
01280 CONNECTION_UNLOCK (connection);
01281
01282 return connection;
01283
01284 error:
01285 if (disconnect_message != NULL)
01286 dbus_message_unref (disconnect_message);
01287
01288 if (disconnect_link != NULL)
01289 _dbus_list_free_link (disconnect_link);
01290
01291 if (connection != NULL)
01292 {
01293 _dbus_condvar_free_at_location (&connection->io_path_cond);
01294 _dbus_condvar_free_at_location (&connection->dispatch_cond);
01295 _dbus_mutex_free_at_location (&connection->mutex);
01296 _dbus_mutex_free_at_location (&connection->io_path_mutex);
01297 _dbus_mutex_free_at_location (&connection->dispatch_mutex);
01298 dbus_free (connection);
01299 }
01300 if (pending_replies)
01301 _dbus_hash_table_unref (pending_replies);
01302
01303 if (watch_list)
01304 _dbus_watch_list_free (watch_list);
01305
01306 if (timeout_list)
01307 _dbus_timeout_list_free (timeout_list);
01308
01309 if (outgoing_counter)
01310 _dbus_counter_unref (outgoing_counter);
01311
01312 if (objects)
01313 _dbus_object_tree_unref (objects);
01314
01315 return NULL;
01316 }
01317
01325 DBusConnection *
01326 _dbus_connection_ref_unlocked (DBusConnection *connection)
01327 {
01328 _dbus_assert (connection != NULL);
01329 _dbus_assert (connection->generation == _dbus_current_generation);
01330
01331 HAVE_LOCK_CHECK (connection);
01332
01333 #ifdef DBUS_HAVE_ATOMIC_INT
01334 _dbus_atomic_inc (&connection->refcount);
01335 #else
01336 _dbus_assert (connection->refcount.value > 0);
01337 connection->refcount.value += 1;
01338 #endif
01339
01340 return connection;
01341 }
01342
01349 void
01350 _dbus_connection_unref_unlocked (DBusConnection *connection)
01351 {
01352 dbus_bool_t last_unref;
01353
01354 HAVE_LOCK_CHECK (connection);
01355
01356 _dbus_assert (connection != NULL);
01357
01358
01359
01360
01361
01362 #ifdef DBUS_HAVE_ATOMIC_INT
01363 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
01364 #else
01365 _dbus_assert (connection->refcount.value > 0);
01366
01367 connection->refcount.value -= 1;
01368 last_unref = (connection->refcount.value == 0);
01369 #if 0
01370 printf ("unref_unlocked() connection %p count = %d\n", connection, connection->refcount.value);
01371 #endif
01372 #endif
01373
01374 if (last_unref)
01375 _dbus_connection_last_unref (connection);
01376 }
01377
01378 static dbus_uint32_t
01379 _dbus_connection_get_next_client_serial (DBusConnection *connection)
01380 {
01381 int serial;
01382
01383 serial = connection->client_serial++;
01384
01385 if (connection->client_serial < 0)
01386 connection->client_serial = 1;
01387
01388 return serial;
01389 }
01390
01404 dbus_bool_t
01405 _dbus_connection_handle_watch (DBusWatch *watch,
01406 unsigned int condition,
01407 void *data)
01408 {
01409 DBusConnection *connection;
01410 dbus_bool_t retval;
01411 DBusDispatchStatus status;
01412
01413 connection = data;
01414
01415 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
01416
01417 CONNECTION_LOCK (connection);
01418 _dbus_connection_acquire_io_path (connection, -1);
01419 HAVE_LOCK_CHECK (connection);
01420 retval = _dbus_transport_handle_watch (connection->transport,
01421 watch, condition);
01422
01423 _dbus_connection_release_io_path (connection);
01424
01425 HAVE_LOCK_CHECK (connection);
01426
01427 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
01428
01429 status = _dbus_connection_get_dispatch_status_unlocked (connection);
01430
01431
01432 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01433
01434 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
01435
01436 return retval;
01437 }
01438
01439 _DBUS_DEFINE_GLOBAL_LOCK (shared_connections);
01440 static DBusHashTable *shared_connections = NULL;
01441 static DBusList *shared_connections_no_guid = NULL;
01442
01443 static void
01444 close_connection_on_shutdown (DBusConnection *connection)
01445 {
01446 DBusMessage *message;
01447
01448 dbus_connection_ref (connection);
01449 _dbus_connection_close_possibly_shared (connection);
01450
01451
01452 while ((message = dbus_connection_pop_message (connection)))
01453 {
01454 dbus_message_unref (message);
01455 }
01456 dbus_connection_unref (connection);
01457 }
01458
01459 static void
01460 shared_connections_shutdown (void *data)
01461 {
01462 int n_entries;
01463
01464 _DBUS_LOCK (shared_connections);
01465
01466
01467 while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0)
01468 {
01469 DBusConnection *connection;
01470 DBusHashIter iter;
01471
01472 _dbus_hash_iter_init (shared_connections, &iter);
01473 _dbus_hash_iter_next (&iter);
01474
01475 connection = _dbus_hash_iter_get_value (&iter);
01476
01477 _DBUS_UNLOCK (shared_connections);
01478 close_connection_on_shutdown (connection);
01479 _DBUS_LOCK (shared_connections);
01480
01481
01482 _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) < n_entries);
01483 }
01484
01485 _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) == 0);
01486
01487 _dbus_hash_table_unref (shared_connections);
01488 shared_connections = NULL;
01489
01490 if (shared_connections_no_guid != NULL)
01491 {
01492 DBusConnection *connection;
01493 connection = _dbus_list_pop_first (&shared_connections_no_guid);
01494 while (connection != NULL)
01495 {
01496 _DBUS_UNLOCK (shared_connections);
01497 close_connection_on_shutdown (connection);
01498 _DBUS_LOCK (shared_connections);
01499 connection = _dbus_list_pop_first (&shared_connections_no_guid);
01500 }
01501 }
01502
01503 shared_connections_no_guid = NULL;
01504
01505 _DBUS_UNLOCK (shared_connections);
01506 }
01507
01508 static dbus_bool_t
01509 connection_lookup_shared (DBusAddressEntry *entry,
01510 DBusConnection **result)
01511 {
01512 _dbus_verbose ("checking for existing connection\n");
01513
01514 *result = NULL;
01515
01516 _DBUS_LOCK (shared_connections);
01517
01518 if (shared_connections == NULL)
01519 {
01520 _dbus_verbose ("creating shared_connections hash table\n");
01521
01522 shared_connections = _dbus_hash_table_new (DBUS_HASH_STRING,
01523 dbus_free,
01524 NULL);
01525 if (shared_connections == NULL)
01526 {
01527 _DBUS_UNLOCK (shared_connections);
01528 return FALSE;
01529 }
01530
01531 if (!_dbus_register_shutdown_func (shared_connections_shutdown, NULL))
01532 {
01533 _dbus_hash_table_unref (shared_connections);
01534 shared_connections = NULL;
01535 _DBUS_UNLOCK (shared_connections);
01536 return FALSE;
01537 }
01538
01539 _dbus_verbose (" successfully created shared_connections\n");
01540
01541 _DBUS_UNLOCK (shared_connections);
01542 return TRUE;
01543 }
01544 else
01545 {
01546 const char *guid;
01547
01548 guid = dbus_address_entry_get_value (entry, "guid");
01549
01550 if (guid != NULL)
01551 {
01552 DBusConnection *connection;
01553
01554 connection = _dbus_hash_table_lookup_string (shared_connections,
01555 guid);
01556
01557 if (connection)
01558 {
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573 CONNECTION_LOCK (connection);
01574 if (_dbus_connection_get_is_connected_unlocked (connection))
01575 {
01576 _dbus_connection_ref_unlocked (connection);
01577 *result = connection;
01578 _dbus_verbose ("looked up existing connection to server guid %s\n",
01579 guid);
01580 }
01581 else
01582 {
01583 _dbus_verbose ("looked up existing connection to server guid %s but it was disconnected so ignoring it\n",
01584 guid);
01585 }
01586 CONNECTION_UNLOCK (connection);
01587 }
01588 }
01589
01590 _DBUS_UNLOCK (shared_connections);
01591 return TRUE;
01592 }
01593 }
01594
01595 static dbus_bool_t
01596 connection_record_shared_unlocked (DBusConnection *connection,
01597 const char *guid)
01598 {
01599 char *guid_key;
01600 char *guid_in_connection;
01601
01602 HAVE_LOCK_CHECK (connection);
01603 _dbus_assert (connection->server_guid == NULL);
01604 _dbus_assert (connection->shareable);
01605
01606
01607
01608
01609
01610 _dbus_connection_ref_unlocked (connection);
01611
01612 if (guid == NULL)
01613 {
01614 _DBUS_LOCK (shared_connections);
01615
01616 if (!_dbus_list_prepend (&shared_connections_no_guid, connection))
01617 {
01618 _DBUS_UNLOCK (shared_connections);
01619 return FALSE;
01620 }
01621
01622 _DBUS_UNLOCK (shared_connections);
01623 return TRUE;
01624 }
01625
01626
01627
01628
01629
01630
01631 guid_key = _dbus_strdup (guid);
01632 if (guid_key == NULL)
01633 return FALSE;
01634
01635 guid_in_connection = _dbus_strdup (guid);
01636 if (guid_in_connection == NULL)
01637 {
01638 dbus_free (guid_key);
01639 return FALSE;
01640 }
01641
01642 _DBUS_LOCK (shared_connections);
01643 _dbus_assert (shared_connections != NULL);
01644
01645 if (!_dbus_hash_table_insert_string (shared_connections,
01646 guid_key, connection))
01647 {
01648 dbus_free (guid_key);
01649 dbus_free (guid_in_connection);
01650 _DBUS_UNLOCK (shared_connections);
01651 return FALSE;
01652 }
01653
01654 connection->server_guid = guid_in_connection;
01655
01656 _dbus_verbose ("stored connection to %s to be shared\n",
01657 connection->server_guid);
01658
01659 _DBUS_UNLOCK (shared_connections);
01660
01661 _dbus_assert (connection->server_guid != NULL);
01662
01663 return TRUE;
01664 }
01665
01666 static void
01667 connection_forget_shared_unlocked (DBusConnection *connection)
01668 {
01669 HAVE_LOCK_CHECK (connection);
01670
01671 if (!connection->shareable)
01672 return;
01673
01674 if (connection->server_guid != NULL)
01675 {
01676 _dbus_verbose ("dropping connection to %s out of the shared table\n",
01677 connection->server_guid);
01678
01679 _DBUS_LOCK (shared_connections);
01680
01681 if (!_dbus_hash_table_remove_string (shared_connections,
01682 connection->server_guid))
01683 _dbus_assert_not_reached ("connection was not in the shared table");
01684
01685 dbus_free (connection->server_guid);
01686 connection->server_guid = NULL;
01687 _DBUS_UNLOCK (shared_connections);
01688 }
01689
01690
01691 _dbus_connection_unref_unlocked (connection);
01692 }
01693
01694 static DBusConnection*
01695 connection_try_from_address_entry (DBusAddressEntry *entry,
01696 DBusError *error)
01697 {
01698 DBusTransport *transport;
01699 DBusConnection *connection;
01700
01701 transport = _dbus_transport_open (entry, error);
01702
01703 if (transport == NULL)
01704 {
01705 _DBUS_ASSERT_ERROR_IS_SET (error);
01706 return NULL;
01707 }
01708
01709 connection = _dbus_connection_new_for_transport (transport);
01710
01711 _dbus_transport_unref (transport);
01712
01713 if (connection == NULL)
01714 {
01715 _DBUS_SET_OOM (error);
01716 return NULL;
01717 }
01718
01719 #ifndef DBUS_DISABLE_CHECKS
01720 _dbus_assert (!connection->have_connection_lock);
01721 #endif
01722 return connection;
01723 }
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737 static DBusConnection*
01738 _dbus_connection_open_internal (const char *address,
01739 dbus_bool_t shared,
01740 DBusError *error)
01741 {
01742 DBusConnection *connection;
01743 DBusAddressEntry **entries;
01744 DBusError tmp_error;
01745 DBusError first_error;
01746 int len, i;
01747
01748 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01749
01750 _dbus_verbose ("opening %s connection to: %s\n",
01751 shared ? "shared" : "private", address);
01752
01753 if (!dbus_parse_address (address, &entries, &len, error))
01754 return NULL;
01755
01756 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01757
01758 connection = NULL;
01759
01760 dbus_error_init (&tmp_error);
01761 dbus_error_init (&first_error);
01762 for (i = 0; i < len; i++)
01763 {
01764 if (shared)
01765 {
01766 if (!connection_lookup_shared (entries[i], &connection))
01767 _DBUS_SET_OOM (&tmp_error);
01768 }
01769
01770 if (connection == NULL)
01771 {
01772 connection = connection_try_from_address_entry (entries[i],
01773 &tmp_error);
01774
01775 if (connection != NULL && shared)
01776 {
01777 const char *guid;
01778
01779 connection->shareable = TRUE;
01780
01781
01782 guid = dbus_address_entry_get_value (entries[i], "guid");
01783
01784 CONNECTION_LOCK (connection);
01785
01786 if (!connection_record_shared_unlocked (connection, guid))
01787 {
01788 _DBUS_SET_OOM (&tmp_error);
01789 _dbus_connection_close_possibly_shared_and_unlock (connection);
01790 dbus_connection_unref (connection);
01791 connection = NULL;
01792 }
01793 else
01794 CONNECTION_UNLOCK (connection);
01795 }
01796 }
01797
01798 if (connection)
01799 break;
01800
01801 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
01802
01803 if (i == 0)
01804 dbus_move_error (&tmp_error, &first_error);
01805 else
01806 dbus_error_free (&tmp_error);
01807 }
01808
01809 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01810 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
01811
01812 if (connection == NULL)
01813 {
01814 _DBUS_ASSERT_ERROR_IS_SET (&first_error);
01815 dbus_move_error (&first_error, error);
01816 }
01817 else
01818 dbus_error_free (&first_error);
01819
01820 dbus_address_entries_free (entries);
01821 return connection;
01822 }
01823
01832 void
01833 _dbus_connection_close_possibly_shared (DBusConnection *connection)
01834 {
01835 _dbus_assert (connection != NULL);
01836 _dbus_assert (connection->generation == _dbus_current_generation);
01837
01838 CONNECTION_LOCK (connection);
01839 _dbus_connection_close_possibly_shared_and_unlock (connection);
01840 }
01841
01842 static DBusPreallocatedSend*
01843 _dbus_connection_preallocate_send_unlocked (DBusConnection *connection)
01844 {
01845 DBusPreallocatedSend *preallocated;
01846
01847 HAVE_LOCK_CHECK (connection);
01848
01849 _dbus_assert (connection != NULL);
01850
01851 preallocated = dbus_new (DBusPreallocatedSend, 1);
01852 if (preallocated == NULL)
01853 return NULL;
01854
01855 if (connection->link_cache != NULL)
01856 {
01857 preallocated->queue_link =
01858 _dbus_list_pop_first_link (&connection->link_cache);
01859 preallocated->queue_link->data = NULL;
01860 }
01861 else
01862 {
01863 preallocated->queue_link = _dbus_list_alloc_link (NULL);
01864 if (preallocated->queue_link == NULL)
01865 goto failed_0;
01866 }
01867
01868 if (connection->link_cache != NULL)
01869 {
01870 preallocated->counter_link =
01871 _dbus_list_pop_first_link (&connection->link_cache);
01872 preallocated->counter_link->data = connection->outgoing_counter;
01873 }
01874 else
01875 {
01876 preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter);
01877 if (preallocated->counter_link == NULL)
01878 goto failed_1;
01879 }
01880
01881 _dbus_counter_ref (preallocated->counter_link->data);
01882
01883 preallocated->connection = connection;
01884
01885 return preallocated;
01886
01887 failed_1:
01888 _dbus_list_free_link (preallocated->queue_link);
01889 failed_0:
01890 dbus_free (preallocated);
01891
01892 return NULL;
01893 }
01894
01895
01896 static void
01897 _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *connection,
01898 DBusPreallocatedSend *preallocated,
01899 DBusMessage *message,
01900 dbus_uint32_t *client_serial)
01901 {
01902 dbus_uint32_t serial;
01903 const char *sig;
01904
01905 preallocated->queue_link->data = message;
01906 _dbus_list_prepend_link (&connection->outgoing_messages,
01907 preallocated->queue_link);
01908
01909 _dbus_message_add_size_counter_link (message,
01910 preallocated->counter_link);
01911
01912 dbus_free (preallocated);
01913 preallocated = NULL;
01914
01915 dbus_message_ref (message);
01916
01917 connection->n_outgoing += 1;
01918
01919 sig = dbus_message_get_signature (message);
01920
01921 _dbus_verbose ("Message %p (%d %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
01922 message,
01923 dbus_message_get_type (message),
01924 dbus_message_get_path (message) ?
01925 dbus_message_get_path (message) :
01926 "no path",
01927 dbus_message_get_interface (message) ?
01928 dbus_message_get_interface (message) :
01929 "no interface",
01930 dbus_message_get_member (message) ?
01931 dbus_message_get_member (message) :
01932 "no member",
01933 sig,
01934 dbus_message_get_destination (message) ?
01935 dbus_message_get_destination (message) :
01936 "null",
01937 connection,
01938 connection->n_outgoing);
01939
01940 if (dbus_message_get_serial (message) == 0)
01941 {
01942 serial = _dbus_connection_get_next_client_serial (connection);
01943 _dbus_message_set_serial (message, serial);
01944 if (client_serial)
01945 *client_serial = serial;
01946 }
01947 else
01948 {
01949 if (client_serial)
01950 *client_serial = dbus_message_get_serial (message);
01951 }
01952
01953 _dbus_verbose ("Message %p serial is %u\n",
01954 message, dbus_message_get_serial (message));
01955
01956 _dbus_message_lock (message);
01957
01958
01959
01960
01961 _dbus_connection_do_iteration_unlocked (connection,
01962 DBUS_ITERATION_DO_WRITING,
01963 -1);
01964
01965
01966 if (connection->n_outgoing > 0)
01967 _dbus_connection_wakeup_mainloop (connection);
01968 }
01969
01970 static void
01971 _dbus_connection_send_preallocated_and_unlock (DBusConnection *connection,
01972 DBusPreallocatedSend *preallocated,
01973 DBusMessage *message,
01974 dbus_uint32_t *client_serial)
01975 {
01976 DBusDispatchStatus status;
01977
01978 HAVE_LOCK_CHECK (connection);
01979
01980 _dbus_connection_send_preallocated_unlocked_no_update (connection,
01981 preallocated,
01982 message, client_serial);
01983
01984 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
01985 status = _dbus_connection_get_dispatch_status_unlocked (connection);
01986
01987
01988 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01989 }
01990
02000 dbus_bool_t
02001 _dbus_connection_send_and_unlock (DBusConnection *connection,
02002 DBusMessage *message,
02003 dbus_uint32_t *client_serial)
02004 {
02005 DBusPreallocatedSend *preallocated;
02006
02007 _dbus_assert (connection != NULL);
02008 _dbus_assert (message != NULL);
02009
02010 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
02011 if (preallocated == NULL)
02012 {
02013 CONNECTION_UNLOCK (connection);
02014 return FALSE;
02015 }
02016
02017 _dbus_connection_send_preallocated_and_unlock (connection,
02018 preallocated,
02019 message,
02020 client_serial);
02021 return TRUE;
02022 }
02023
02048 void
02049 _dbus_connection_close_if_only_one_ref (DBusConnection *connection)
02050 {
02051 CONNECTION_LOCK (connection);
02052
02053 _dbus_assert (connection->refcount.value > 0);
02054
02055 if (connection->refcount.value == 1)
02056 _dbus_connection_close_possibly_shared_and_unlock (connection);
02057 else
02058 CONNECTION_UNLOCK (connection);
02059 }
02060
02061
02071 static void
02072 _dbus_memory_pause_based_on_timeout (int timeout_milliseconds)
02073 {
02074 if (timeout_milliseconds == -1)
02075 _dbus_sleep_milliseconds (1000);
02076 else if (timeout_milliseconds < 100)
02077 ;
02078 else if (timeout_milliseconds <= 1000)
02079 _dbus_sleep_milliseconds (timeout_milliseconds / 3);
02080 else
02081 _dbus_sleep_milliseconds (1000);
02082 }
02083
02084 static DBusMessage *
02085 generate_local_error_message (dbus_uint32_t serial,
02086 char *error_name,
02087 char *error_msg)
02088 {
02089 DBusMessage *message;
02090 message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
02091 if (!message)
02092 goto out;
02093
02094 if (!dbus_message_set_error_name (message, error_name))
02095 {
02096 dbus_message_unref (message);
02097 message = NULL;
02098 goto out;
02099 }
02100
02101 dbus_message_set_no_reply (message, TRUE);
02102
02103 if (!dbus_message_set_reply_serial (message,
02104 serial))
02105 {
02106 dbus_message_unref (message);
02107 message = NULL;
02108 goto out;
02109 }
02110
02111 if (error_msg != NULL)
02112 {
02113 DBusMessageIter iter;
02114
02115 dbus_message_iter_init_append (message, &iter);
02116 if (!dbus_message_iter_append_basic (&iter,
02117 DBUS_TYPE_STRING,
02118 &error_msg))
02119 {
02120 dbus_message_unref (message);
02121 message = NULL;
02122 goto out;
02123 }
02124 }
02125
02126 out:
02127 return message;
02128 }
02129
02130
02131
02132
02133
02134 static DBusMessage*
02135 check_for_reply_unlocked (DBusConnection *connection,
02136 dbus_uint32_t client_serial)
02137 {
02138 DBusList *link;
02139
02140 HAVE_LOCK_CHECK (connection);
02141
02142 link = _dbus_list_get_first_link (&connection->incoming_messages);
02143
02144 while (link != NULL)
02145 {
02146 DBusMessage *reply = link->data;
02147
02148 if (dbus_message_get_reply_serial (reply) == client_serial)
02149 {
02150 _dbus_list_remove_link (&connection->incoming_messages, link);
02151 connection->n_incoming -= 1;
02152 return reply;
02153 }
02154 link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02155 }
02156
02157 return NULL;
02158 }
02159
02160 static void
02161 connection_timeout_and_complete_all_pending_calls_unlocked (DBusConnection *connection)
02162 {
02163
02164
02165
02166
02167
02168 while (_dbus_hash_table_get_n_entries (connection->pending_replies) > 0)
02169 {
02170 DBusPendingCall *pending;
02171 DBusHashIter iter;
02172
02173 _dbus_hash_iter_init (connection->pending_replies, &iter);
02174 _dbus_hash_iter_next (&iter);
02175
02176 pending = _dbus_hash_iter_get_value (&iter);
02177 _dbus_pending_call_ref_unlocked (pending);
02178
02179 _dbus_pending_call_queue_timeout_error_unlocked (pending,
02180 connection);
02181 _dbus_connection_remove_timeout_unlocked (connection,
02182 _dbus_pending_call_get_timeout_unlocked (pending));
02183 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
02184 _dbus_hash_iter_remove_entry (&iter);
02185
02186 _dbus_pending_call_unref_and_unlock (pending);
02187 CONNECTION_LOCK (connection);
02188 }
02189 HAVE_LOCK_CHECK (connection);
02190 }
02191
02192 static void
02193 complete_pending_call_and_unlock (DBusConnection *connection,
02194 DBusPendingCall *pending,
02195 DBusMessage *message)
02196 {
02197 _dbus_pending_call_set_reply_unlocked (pending, message);
02198 _dbus_pending_call_ref_unlocked (pending);
02199 _dbus_connection_detach_pending_call_and_unlock (connection, pending);
02200
02201
02202 _dbus_pending_call_complete (pending);
02203 dbus_pending_call_unref (pending);
02204 }
02205
02206 static dbus_bool_t
02207 check_for_reply_and_update_dispatch_unlocked (DBusConnection *connection,
02208 DBusPendingCall *pending)
02209 {
02210 DBusMessage *reply;
02211 DBusDispatchStatus status;
02212
02213 reply = check_for_reply_unlocked (connection,
02214 _dbus_pending_call_get_reply_serial_unlocked (pending));
02215 if (reply != NULL)
02216 {
02217 _dbus_verbose ("%s checked for reply\n", _DBUS_FUNCTION_NAME);
02218
02219 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
02220
02221 complete_pending_call_and_unlock (connection, pending, reply);
02222 dbus_message_unref (reply);
02223
02224 CONNECTION_LOCK (connection);
02225 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02226 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02227 dbus_pending_call_unref (pending);
02228
02229 return TRUE;
02230 }
02231
02232 return FALSE;
02233 }
02234
02249 void
02250 _dbus_connection_block_pending_call (DBusPendingCall *pending)
02251 {
02252 long start_tv_sec, start_tv_usec;
02253 long end_tv_sec, end_tv_usec;
02254 long tv_sec, tv_usec;
02255 DBusDispatchStatus status;
02256 DBusConnection *connection;
02257 dbus_uint32_t client_serial;
02258 int timeout_milliseconds;
02259
02260 _dbus_assert (pending != NULL);
02261
02262 if (dbus_pending_call_get_completed (pending))
02263 return;
02264
02265 dbus_pending_call_ref (pending);
02266
02267 connection = _dbus_pending_call_get_connection_and_lock (pending);
02268
02269
02270 _dbus_connection_flush_unlocked (connection);
02271
02272 client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
02273
02274
02275
02276
02277
02278 timeout_milliseconds = dbus_timeout_get_interval (_dbus_pending_call_get_timeout_unlocked (pending));
02279
02280 _dbus_get_current_time (&start_tv_sec, &start_tv_usec);
02281 end_tv_sec = start_tv_sec + timeout_milliseconds / 1000;
02282 end_tv_usec = start_tv_usec + (timeout_milliseconds % 1000) * 1000;
02283 end_tv_sec += end_tv_usec / _DBUS_USEC_PER_SECOND;
02284 end_tv_usec = end_tv_usec % _DBUS_USEC_PER_SECOND;
02285
02286 _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",
02287 timeout_milliseconds,
02288 client_serial,
02289 start_tv_sec, start_tv_usec,
02290 end_tv_sec, end_tv_usec);
02291
02292
02293
02294 if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02295 return;
02296
02297
02298
02299 _dbus_connection_do_iteration_unlocked (connection,
02300 DBUS_ITERATION_DO_READING |
02301 DBUS_ITERATION_BLOCK,
02302 timeout_milliseconds);
02303
02304 recheck_status:
02305
02306 _dbus_verbose ("%s top of recheck\n", _DBUS_FUNCTION_NAME);
02307
02308 HAVE_LOCK_CHECK (connection);
02309
02310
02311
02312 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02313
02314
02315
02316
02317 if (_dbus_pending_call_get_completed_unlocked (pending))
02318 {
02319 _dbus_verbose ("Pending call completed by dispatch in %s\n", _DBUS_FUNCTION_NAME);
02320 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02321 dbus_pending_call_unref (pending);
02322 return;
02323 }
02324
02325 if (status == DBUS_DISPATCH_DATA_REMAINS) {
02326 if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02327 return;
02328 }
02329
02330 _dbus_get_current_time (&tv_sec, &tv_usec);
02331
02332 if (!_dbus_connection_get_is_connected_unlocked (connection))
02333 {
02334 DBusMessage *error_msg;
02335
02336 error_msg = generate_local_error_message (client_serial,
02337 DBUS_ERROR_DISCONNECTED,
02338 "Connection was disconnected before a reply was received");
02339
02340
02341 complete_pending_call_and_unlock (connection, pending, error_msg);
02342 dbus_pending_call_unref (pending);
02343 return;
02344 }
02345 else if (tv_sec < start_tv_sec)
02346 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
02347 else if (connection->disconnect_message_link == NULL)
02348 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
02349 else if (tv_sec < end_tv_sec ||
02350 (tv_sec == end_tv_sec && tv_usec < end_tv_usec))
02351 {
02352 timeout_milliseconds = (end_tv_sec - tv_sec) * 1000 +
02353 (end_tv_usec - tv_usec) / 1000;
02354 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds);
02355 _dbus_assert (timeout_milliseconds >= 0);
02356
02357 if (status == DBUS_DISPATCH_NEED_MEMORY)
02358 {
02359
02360
02361
02362
02363 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02364
02365 _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
02366 }
02367 else
02368 {
02369
02370 _dbus_connection_do_iteration_unlocked (connection,
02371 DBUS_ITERATION_DO_READING |
02372 DBUS_ITERATION_BLOCK,
02373 timeout_milliseconds);
02374 }
02375
02376 goto recheck_status;
02377 }
02378
02379 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %ld milliseconds and got no reply\n",
02380 (tv_sec - start_tv_sec) * 1000 + (tv_usec - start_tv_usec) / 1000);
02381
02382 _dbus_assert (!_dbus_pending_call_get_completed_unlocked (pending));
02383
02384
02385 complete_pending_call_and_unlock (connection, pending, NULL);
02386
02387
02388 CONNECTION_LOCK (connection);
02389 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02390 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02391 dbus_pending_call_unref (pending);
02392 }
02393
02430 DBusConnection*
02431 dbus_connection_open (const char *address,
02432 DBusError *error)
02433 {
02434 DBusConnection *connection;
02435
02436 _dbus_return_val_if_fail (address != NULL, NULL);
02437 _dbus_return_val_if_error_is_set (error, NULL);
02438
02439 connection = _dbus_connection_open_internal (address,
02440 TRUE,
02441 error);
02442
02443 return connection;
02444 }
02445
02473 DBusConnection*
02474 dbus_connection_open_private (const char *address,
02475 DBusError *error)
02476 {
02477 DBusConnection *connection;
02478
02479 _dbus_return_val_if_fail (address != NULL, NULL);
02480 _dbus_return_val_if_error_is_set (error, NULL);
02481
02482 connection = _dbus_connection_open_internal (address,
02483 FALSE,
02484 error);
02485
02486 return connection;
02487 }
02488
02495 DBusConnection *
02496 dbus_connection_ref (DBusConnection *connection)
02497 {
02498 _dbus_return_val_if_fail (connection != NULL, NULL);
02499 _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
02500
02501
02502
02503
02504
02505 #ifdef DBUS_HAVE_ATOMIC_INT
02506 _dbus_atomic_inc (&connection->refcount);
02507 #else
02508 CONNECTION_LOCK (connection);
02509 _dbus_assert (connection->refcount.value > 0);
02510
02511 connection->refcount.value += 1;
02512 CONNECTION_UNLOCK (connection);
02513 #endif
02514
02515 return connection;
02516 }
02517
02518 static void
02519 free_outgoing_message (void *element,
02520 void *data)
02521 {
02522 DBusMessage *message = element;
02523 DBusConnection *connection = data;
02524
02525 _dbus_message_remove_size_counter (message,
02526 connection->outgoing_counter,
02527 NULL);
02528 dbus_message_unref (message);
02529 }
02530
02531
02532
02533
02534
02535 static void
02536 _dbus_connection_last_unref (DBusConnection *connection)
02537 {
02538 DBusList *link;
02539
02540 _dbus_verbose ("Finalizing connection %p\n", connection);
02541
02542 _dbus_assert (connection->refcount.value == 0);
02543
02544
02545
02546
02547 _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
02548 _dbus_assert (connection->server_guid == NULL);
02549
02550
02551 _dbus_object_tree_free_all_unlocked (connection->objects);
02552
02553 dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
02554 dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
02555 dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
02556
02557 _dbus_watch_list_free (connection->watches);
02558 connection->watches = NULL;
02559
02560 _dbus_timeout_list_free (connection->timeouts);
02561 connection->timeouts = NULL;
02562
02563 _dbus_data_slot_list_free (&connection->slot_list);
02564
02565 link = _dbus_list_get_first_link (&connection->filter_list);
02566 while (link != NULL)
02567 {
02568 DBusMessageFilter *filter = link->data;
02569 DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
02570
02571 filter->function = NULL;
02572 _dbus_message_filter_unref (filter);
02573 link->data = NULL;
02574
02575 link = next;
02576 }
02577 _dbus_list_clear (&connection->filter_list);
02578
02579
02580
02581 _dbus_object_tree_unref (connection->objects);
02582
02583 _dbus_hash_table_unref (connection->pending_replies);
02584 connection->pending_replies = NULL;
02585
02586 _dbus_list_clear (&connection->filter_list);
02587
02588 _dbus_list_foreach (&connection->outgoing_messages,
02589 free_outgoing_message,
02590 connection);
02591 _dbus_list_clear (&connection->outgoing_messages);
02592
02593 _dbus_list_foreach (&connection->incoming_messages,
02594 (DBusForeachFunction) dbus_message_unref,
02595 NULL);
02596 _dbus_list_clear (&connection->incoming_messages);
02597
02598 _dbus_counter_unref (connection->outgoing_counter);
02599
02600 _dbus_transport_unref (connection->transport);
02601
02602 if (connection->disconnect_message_link)
02603 {
02604 DBusMessage *message = connection->disconnect_message_link->data;
02605 dbus_message_unref (message);
02606 _dbus_list_free_link (connection->disconnect_message_link);
02607 }
02608
02609 _dbus_list_clear (&connection->link_cache);
02610
02611 _dbus_condvar_free_at_location (&connection->dispatch_cond);
02612 _dbus_condvar_free_at_location (&connection->io_path_cond);
02613
02614 _dbus_mutex_free_at_location (&connection->io_path_mutex);
02615 _dbus_mutex_free_at_location (&connection->dispatch_mutex);
02616
02617 _dbus_mutex_free_at_location (&connection->mutex);
02618
02619 dbus_free (connection);
02620 }
02621
02641 void
02642 dbus_connection_unref (DBusConnection *connection)
02643 {
02644 dbus_bool_t last_unref;
02645
02646 _dbus_return_if_fail (connection != NULL);
02647 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02648
02649
02650
02651
02652
02653 #ifdef DBUS_HAVE_ATOMIC_INT
02654 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
02655 #else
02656 CONNECTION_LOCK (connection);
02657
02658 _dbus_assert (connection->refcount.value > 0);
02659
02660 connection->refcount.value -= 1;
02661 last_unref = (connection->refcount.value == 0);
02662
02663 #if 0
02664 printf ("unref() connection %p count = %d\n", connection, connection->refcount.value);
02665 #endif
02666
02667 CONNECTION_UNLOCK (connection);
02668 #endif
02669
02670 if (last_unref)
02671 {
02672 #ifndef DBUS_DISABLE_CHECKS
02673 if (_dbus_transport_get_is_connected (connection->transport))
02674 {
02675 _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",
02676 connection->shareable ?
02677 "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" :
02678 "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n");
02679 return;
02680 }
02681 #endif
02682 _dbus_connection_last_unref (connection);
02683 }
02684 }
02685
02686
02687
02688
02689
02690
02691
02692
02693
02694
02695 static void
02696 _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection)
02697 {
02698 DBusDispatchStatus status;
02699
02700 HAVE_LOCK_CHECK (connection);
02701
02702 _dbus_verbose ("Disconnecting %p\n", connection);
02703
02704
02705
02706
02707
02708 _dbus_connection_ref_unlocked (connection);
02709
02710 _dbus_transport_disconnect (connection->transport);
02711
02712
02713
02714
02715
02716
02717
02718
02719
02720
02721 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02722
02723
02724 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02725
02726
02727 dbus_connection_unref (connection);
02728 }
02729
02772 void
02773 dbus_connection_close (DBusConnection *connection)
02774 {
02775 _dbus_return_if_fail (connection != NULL);
02776 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02777
02778 CONNECTION_LOCK (connection);
02779
02780 #ifndef DBUS_DISABLE_CHECKS
02781 if (connection->shareable)
02782 {
02783 CONNECTION_UNLOCK (connection);
02784
02785 _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n");
02786 return;
02787 }
02788 #endif
02789
02790 _dbus_connection_close_possibly_shared_and_unlock (connection);
02791 }
02792
02793 static dbus_bool_t
02794 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
02795 {
02796 HAVE_LOCK_CHECK (connection);
02797 return _dbus_transport_get_is_connected (connection->transport);
02798 }
02799
02813 dbus_bool_t
02814 dbus_connection_get_is_connected (DBusConnection *connection)
02815 {
02816 dbus_bool_t res;
02817
02818 _dbus_return_val_if_fail (connection != NULL, FALSE);
02819
02820 CONNECTION_LOCK (connection);
02821 res = _dbus_connection_get_is_connected_unlocked (connection);
02822 CONNECTION_UNLOCK (connection);
02823
02824 return res;
02825 }
02826
02835 dbus_bool_t
02836 dbus_connection_get_is_authenticated (DBusConnection *connection)
02837 {
02838 dbus_bool_t res;
02839
02840 _dbus_return_val_if_fail (connection != NULL, FALSE);
02841
02842 CONNECTION_LOCK (connection);
02843 res = _dbus_transport_get_is_authenticated (connection->transport);
02844 CONNECTION_UNLOCK (connection);
02845
02846 return res;
02847 }
02848
02862 void
02863 dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
02864 dbus_bool_t exit_on_disconnect)
02865 {
02866 _dbus_return_if_fail (connection != NULL);
02867
02868 CONNECTION_LOCK (connection);
02869 connection->exit_on_disconnect = exit_on_disconnect != FALSE;
02870 CONNECTION_UNLOCK (connection);
02871 }
02872
02882 DBusPreallocatedSend*
02883 dbus_connection_preallocate_send (DBusConnection *connection)
02884 {
02885 DBusPreallocatedSend *preallocated;
02886
02887 _dbus_return_val_if_fail (connection != NULL, NULL);
02888
02889 CONNECTION_LOCK (connection);
02890
02891 preallocated =
02892 _dbus_connection_preallocate_send_unlocked (connection);
02893
02894 CONNECTION_UNLOCK (connection);
02895
02896 return preallocated;
02897 }
02898
02908 void
02909 dbus_connection_free_preallocated_send (DBusConnection *connection,
02910 DBusPreallocatedSend *preallocated)
02911 {
02912 _dbus_return_if_fail (connection != NULL);
02913 _dbus_return_if_fail (preallocated != NULL);
02914 _dbus_return_if_fail (connection == preallocated->connection);
02915
02916 _dbus_list_free_link (preallocated->queue_link);
02917 _dbus_counter_unref (preallocated->counter_link->data);
02918 _dbus_list_free_link (preallocated->counter_link);
02919 dbus_free (preallocated);
02920 }
02921
02934 void
02935 dbus_connection_send_preallocated (DBusConnection *connection,
02936 DBusPreallocatedSend *preallocated,
02937 DBusMessage *message,
02938 dbus_uint32_t *client_serial)
02939 {
02940 _dbus_return_if_fail (connection != NULL);
02941 _dbus_return_if_fail (preallocated != NULL);
02942 _dbus_return_if_fail (message != NULL);
02943 _dbus_return_if_fail (preallocated->connection == connection);
02944 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
02945 dbus_message_get_member (message) != NULL);
02946 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
02947 (dbus_message_get_interface (message) != NULL &&
02948 dbus_message_get_member (message) != NULL));
02949
02950 CONNECTION_LOCK (connection);
02951 _dbus_connection_send_preallocated_and_unlock (connection,
02952 preallocated,
02953 message, client_serial);
02954 }
02955
02956 static dbus_bool_t
02957 _dbus_connection_send_unlocked_no_update (DBusConnection *connection,
02958 DBusMessage *message,
02959 dbus_uint32_t *client_serial)
02960 {
02961 DBusPreallocatedSend *preallocated;
02962
02963 _dbus_assert (connection != NULL);
02964 _dbus_assert (message != NULL);
02965
02966 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
02967 if (preallocated == NULL)
02968 return FALSE;
02969
02970 _dbus_connection_send_preallocated_unlocked_no_update (connection,
02971 preallocated,
02972 message,
02973 client_serial);
02974 return TRUE;
02975 }
02976
02998 dbus_bool_t
02999 dbus_connection_send (DBusConnection *connection,
03000 DBusMessage *message,
03001 dbus_uint32_t *serial)
03002 {
03003 _dbus_return_val_if_fail (connection != NULL, FALSE);
03004 _dbus_return_val_if_fail (message != NULL, FALSE);
03005
03006 CONNECTION_LOCK (connection);
03007
03008 return _dbus_connection_send_and_unlock (connection,
03009 message,
03010 serial);
03011 }
03012
03013 static dbus_bool_t
03014 reply_handler_timeout (void *data)
03015 {
03016 DBusConnection *connection;
03017 DBusDispatchStatus status;
03018 DBusPendingCall *pending = data;
03019
03020 connection = _dbus_pending_call_get_connection_and_lock (pending);
03021
03022 _dbus_pending_call_queue_timeout_error_unlocked (pending,
03023 connection);
03024 _dbus_connection_remove_timeout_unlocked (connection,
03025 _dbus_pending_call_get_timeout_unlocked (pending));
03026 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
03027
03028 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
03029 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03030
03031
03032 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03033
03034 return TRUE;
03035 }
03036
03074 dbus_bool_t
03075 dbus_connection_send_with_reply (DBusConnection *connection,
03076 DBusMessage *message,
03077 DBusPendingCall **pending_return,
03078 int timeout_milliseconds)
03079 {
03080 DBusPendingCall *pending;
03081 dbus_int32_t serial = -1;
03082 DBusDispatchStatus status;
03083
03084 _dbus_return_val_if_fail (connection != NULL, FALSE);
03085 _dbus_return_val_if_fail (message != NULL, FALSE);
03086 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03087
03088 if (pending_return)
03089 *pending_return = NULL;
03090
03091 CONNECTION_LOCK (connection);
03092
03093 if (!_dbus_connection_get_is_connected_unlocked (connection))
03094 {
03095 CONNECTION_UNLOCK (connection);
03096
03097 *pending_return = NULL;
03098
03099 return TRUE;
03100 }
03101
03102 pending = _dbus_pending_call_new_unlocked (connection,
03103 timeout_milliseconds,
03104 reply_handler_timeout);
03105
03106 if (pending == NULL)
03107 {
03108 CONNECTION_UNLOCK (connection);
03109 return FALSE;
03110 }
03111
03112
03113 serial = dbus_message_get_serial (message);
03114 if (serial == 0)
03115 {
03116 serial = _dbus_connection_get_next_client_serial (connection);
03117 _dbus_message_set_serial (message, serial);
03118 }
03119
03120 if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
03121 goto error;
03122
03123
03124
03125
03126
03127 if (!_dbus_connection_attach_pending_call_unlocked (connection,
03128 pending))
03129 goto error;
03130
03131 if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
03132 {
03133 _dbus_connection_detach_pending_call_and_unlock (connection,
03134 pending);
03135 goto error_unlocked;
03136 }
03137
03138 if (pending_return)
03139 *pending_return = pending;
03140 else
03141 {
03142 _dbus_connection_detach_pending_call_unlocked (connection, pending);
03143
03144
03145
03146 }
03147
03148 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03149
03150
03151 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03152
03153 if (pending_return == NULL)
03154 dbus_pending_call_unref (pending);
03155
03156 return TRUE;
03157
03158 error:
03159 CONNECTION_UNLOCK (connection);
03160 error_unlocked:
03161 dbus_pending_call_unref (pending);
03162 return FALSE;
03163 }
03164
03195 DBusMessage*
03196 dbus_connection_send_with_reply_and_block (DBusConnection *connection,
03197 DBusMessage *message,
03198 int timeout_milliseconds,
03199 DBusError *error)
03200 {
03201 DBusMessage *reply;
03202 DBusPendingCall *pending;
03203
03204 _dbus_return_val_if_fail (connection != NULL, NULL);
03205 _dbus_return_val_if_fail (message != NULL, NULL);
03206 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL);
03207 _dbus_return_val_if_error_is_set (error, NULL);
03208
03209 if (!dbus_connection_send_with_reply (connection, message,
03210 &pending, timeout_milliseconds))
03211 {
03212 _DBUS_SET_OOM (error);
03213 return NULL;
03214 }
03215
03216 if (pending == NULL)
03217 {
03218 dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Connection is closed");
03219 return NULL;
03220 }
03221
03222 dbus_pending_call_block (pending);
03223
03224 reply = dbus_pending_call_steal_reply (pending);
03225 dbus_pending_call_unref (pending);
03226
03227
03228
03229
03230 _dbus_assert (reply != NULL);
03231
03232 if (dbus_set_error_from_message (error, reply))
03233 {
03234 dbus_message_unref (reply);
03235 return NULL;
03236 }
03237 else
03238 return reply;
03239 }
03240
03249 DBusDispatchStatus
03250 _dbus_connection_flush_unlocked (DBusConnection *connection)
03251 {
03252
03253
03254
03255
03256
03257 DBusDispatchStatus status;
03258
03259 HAVE_LOCK_CHECK (connection);
03260
03261 while (connection->n_outgoing > 0 &&
03262 _dbus_connection_get_is_connected_unlocked (connection))
03263 {
03264 _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME);
03265 HAVE_LOCK_CHECK (connection);
03266 _dbus_connection_do_iteration_unlocked (connection,
03267 DBUS_ITERATION_DO_READING |
03268 DBUS_ITERATION_DO_WRITING |
03269 DBUS_ITERATION_BLOCK,
03270 -1);
03271 }
03272
03273 HAVE_LOCK_CHECK (connection);
03274 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
03275 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03276
03277 HAVE_LOCK_CHECK (connection);
03278 return status;
03279 }
03280
03286 void
03287 dbus_connection_flush (DBusConnection *connection)
03288 {
03289
03290
03291
03292
03293
03294 DBusDispatchStatus status;
03295
03296 _dbus_return_if_fail (connection != NULL);
03297
03298 CONNECTION_LOCK (connection);
03299
03300 status = _dbus_connection_flush_unlocked (connection);
03301
03302 HAVE_LOCK_CHECK (connection);
03303
03304 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03305
03306 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
03307 }
03308
03319 static dbus_bool_t
03320 _dbus_connection_read_write_dispatch (DBusConnection *connection,
03321 int timeout_milliseconds,
03322 dbus_bool_t dispatch)
03323 {
03324 DBusDispatchStatus dstatus;
03325 dbus_bool_t no_progress_possible;
03326
03327 dstatus = dbus_connection_get_dispatch_status (connection);
03328
03329 if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
03330 {
03331 _dbus_verbose ("doing dispatch in %s\n", _DBUS_FUNCTION_NAME);
03332 dbus_connection_dispatch (connection);
03333 CONNECTION_LOCK (connection);
03334 }
03335 else if (dstatus == DBUS_DISPATCH_NEED_MEMORY)
03336 {
03337 _dbus_verbose ("pausing for memory in %s\n", _DBUS_FUNCTION_NAME);
03338 _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
03339 CONNECTION_LOCK (connection);
03340 }
03341 else
03342 {
03343 CONNECTION_LOCK (connection);
03344 if (_dbus_connection_get_is_connected_unlocked (connection))
03345 {
03346 _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME);
03347 _dbus_connection_do_iteration_unlocked (connection,
03348 DBUS_ITERATION_DO_READING |
03349 DBUS_ITERATION_DO_WRITING |
03350 DBUS_ITERATION_BLOCK,
03351 timeout_milliseconds);
03352 }
03353 }
03354
03355 HAVE_LOCK_CHECK (connection);
03356
03357
03358
03359
03360 if (dispatch)
03361 no_progress_possible = connection->n_incoming == 0 &&
03362 connection->disconnect_message_link == NULL;
03363 else
03364 no_progress_possible = _dbus_connection_get_is_connected_unlocked (connection);
03365 CONNECTION_UNLOCK (connection);
03366 return !no_progress_possible;
03367 }
03368
03369
03404 dbus_bool_t
03405 dbus_connection_read_write_dispatch (DBusConnection *connection,
03406 int timeout_milliseconds)
03407 {
03408 _dbus_return_val_if_fail (connection != NULL, FALSE);
03409 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03410 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE);
03411 }
03412
03436 dbus_bool_t
03437 dbus_connection_read_write (DBusConnection *connection,
03438 int timeout_milliseconds)
03439 {
03440 _dbus_return_val_if_fail (connection != NULL, FALSE);
03441 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03442 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE);
03443 }
03444
03445
03446
03447
03448
03449
03450 static void
03451 check_disconnected_message_arrived_unlocked (DBusConnection *connection,
03452 DBusMessage *head_of_queue)
03453 {
03454 HAVE_LOCK_CHECK (connection);
03455
03456
03457 if (connection->disconnect_message_link == NULL &&
03458 dbus_message_is_signal (head_of_queue,
03459 DBUS_INTERFACE_LOCAL,
03460 "Disconnected"))
03461 {
03462 connection->disconnected_message_arrived = TRUE;
03463 }
03464 }
03465
03485 DBusMessage*
03486 dbus_connection_borrow_message (DBusConnection *connection)
03487 {
03488 DBusDispatchStatus status;
03489 DBusMessage *message;
03490
03491 _dbus_return_val_if_fail (connection != NULL, NULL);
03492
03493 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
03494
03495
03496
03497
03498 status = dbus_connection_get_dispatch_status (connection);
03499 if (status != DBUS_DISPATCH_DATA_REMAINS)
03500 return NULL;
03501
03502 CONNECTION_LOCK (connection);
03503
03504 _dbus_connection_acquire_dispatch (connection);
03505
03506
03507 _dbus_assert (connection->message_borrowed == NULL);
03508
03509 connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
03510
03511 message = connection->message_borrowed;
03512
03513 check_disconnected_message_arrived_unlocked (connection, message);
03514
03515
03516 if (message == NULL)
03517 _dbus_connection_release_dispatch (connection);
03518
03519 CONNECTION_UNLOCK (connection);
03520
03521
03522
03523 return message;
03524 }
03525
03534 void
03535 dbus_connection_return_message (DBusConnection *connection,
03536 DBusMessage *message)
03537 {
03538 DBusDispatchStatus status;
03539
03540 _dbus_return_if_fail (connection != NULL);
03541 _dbus_return_if_fail (message != NULL);
03542 _dbus_return_if_fail (message == connection->message_borrowed);
03543 _dbus_return_if_fail (connection->dispatch_acquired);
03544
03545 CONNECTION_LOCK (connection);
03546
03547 _dbus_assert (message == connection->message_borrowed);
03548
03549 connection->message_borrowed = NULL;
03550
03551 _dbus_connection_release_dispatch (connection);
03552
03553 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03554 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03555 }
03556
03566 void
03567 dbus_connection_steal_borrowed_message (DBusConnection *connection,
03568 DBusMessage *message)
03569 {
03570 DBusMessage *pop_message;
03571 DBusDispatchStatus status;
03572
03573 _dbus_return_if_fail (connection != NULL);
03574 _dbus_return_if_fail (message != NULL);
03575 _dbus_return_if_fail (message == connection->message_borrowed);
03576 _dbus_return_if_fail (connection->dispatch_acquired);
03577
03578 CONNECTION_LOCK (connection);
03579
03580 _dbus_assert (message == connection->message_borrowed);
03581
03582 pop_message = _dbus_list_pop_first (&connection->incoming_messages);
03583 _dbus_assert (message == pop_message);
03584
03585 connection->n_incoming -= 1;
03586
03587 _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
03588 message, connection->n_incoming);
03589
03590 connection->message_borrowed = NULL;
03591
03592 _dbus_connection_release_dispatch (connection);
03593
03594 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03595 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03596 }
03597
03598
03599
03600
03601 static DBusList*
03602 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
03603 {
03604 HAVE_LOCK_CHECK (connection);
03605
03606 _dbus_assert (connection->message_borrowed == NULL);
03607
03608 if (connection->n_incoming > 0)
03609 {
03610 DBusList *link;
03611
03612 link = _dbus_list_pop_first_link (&connection->incoming_messages);
03613 connection->n_incoming -= 1;
03614
03615 _dbus_verbose ("Message %p (%d %s %s %s '%s') removed from incoming queue %p, %d incoming\n",
03616 link->data,
03617 dbus_message_get_type (link->data),
03618 dbus_message_get_path (link->data) ?
03619 dbus_message_get_path (link->data) :
03620 "no path",
03621 dbus_message_get_interface (link->data) ?
03622 dbus_message_get_interface (link->data) :
03623 "no interface",
03624 dbus_message_get_member (link->data) ?
03625 dbus_message_get_member (link->data) :
03626 "no member",
03627 dbus_message_get_signature (link->data),
03628 connection, connection->n_incoming);
03629
03630 check_disconnected_message_arrived_unlocked (connection, link->data);
03631
03632 return link;
03633 }
03634 else
03635 return NULL;
03636 }
03637
03638
03639
03640
03641 static DBusMessage*
03642 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
03643 {
03644 DBusList *link;
03645
03646 HAVE_LOCK_CHECK (connection);
03647
03648 link = _dbus_connection_pop_message_link_unlocked (connection);
03649
03650 if (link != NULL)
03651 {
03652 DBusMessage *message;
03653
03654 message = link->data;
03655
03656 _dbus_list_free_link (link);
03657
03658 return message;
03659 }
03660 else
03661 return NULL;
03662 }
03663
03664 static void
03665 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
03666 DBusList *message_link)
03667 {
03668 HAVE_LOCK_CHECK (connection);
03669
03670 _dbus_assert (message_link != NULL);
03671
03672 _dbus_assert (connection->message_borrowed == NULL);
03673
03674 _dbus_assert (connection->dispatch_acquired);
03675
03676 _dbus_list_prepend_link (&connection->incoming_messages,
03677 message_link);
03678 connection->n_incoming += 1;
03679
03680 _dbus_verbose ("Message %p (%d %s %s '%s') put back into queue %p, %d incoming\n",
03681 message_link->data,
03682 dbus_message_get_type (message_link->data),
03683 dbus_message_get_interface (message_link->data) ?
03684 dbus_message_get_interface (message_link->data) :
03685 "no interface",
03686 dbus_message_get_member (message_link->data) ?
03687 dbus_message_get_member (message_link->data) :
03688 "no member",
03689 dbus_message_get_signature (message_link->data),
03690 connection, connection->n_incoming);
03691 }
03692
03712 DBusMessage*
03713 dbus_connection_pop_message (DBusConnection *connection)
03714 {
03715 DBusMessage *message;
03716 DBusDispatchStatus status;
03717
03718 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
03719
03720
03721
03722
03723 status = dbus_connection_get_dispatch_status (connection);
03724 if (status != DBUS_DISPATCH_DATA_REMAINS)
03725 return NULL;
03726
03727 CONNECTION_LOCK (connection);
03728 _dbus_connection_acquire_dispatch (connection);
03729 HAVE_LOCK_CHECK (connection);
03730
03731 message = _dbus_connection_pop_message_unlocked (connection);
03732
03733 _dbus_verbose ("Returning popped message %p\n", message);
03734
03735 _dbus_connection_release_dispatch (connection);
03736
03737 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03738 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03739
03740 return message;
03741 }
03742
03750 static void
03751 _dbus_connection_acquire_dispatch (DBusConnection *connection)
03752 {
03753 HAVE_LOCK_CHECK (connection);
03754
03755 _dbus_connection_ref_unlocked (connection);
03756 CONNECTION_UNLOCK (connection);
03757
03758 _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03759 _dbus_mutex_lock (connection->dispatch_mutex);
03760
03761 while (connection->dispatch_acquired)
03762 {
03763 _dbus_verbose ("%s waiting for dispatch to be acquirable\n", _DBUS_FUNCTION_NAME);
03764 _dbus_condvar_wait (connection->dispatch_cond,
03765 connection->dispatch_mutex);
03766 }
03767
03768 _dbus_assert (!connection->dispatch_acquired);
03769
03770 connection->dispatch_acquired = TRUE;
03771
03772 _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03773 _dbus_mutex_unlock (connection->dispatch_mutex);
03774
03775 CONNECTION_LOCK (connection);
03776 _dbus_connection_unref_unlocked (connection);
03777 }
03778
03786 static void
03787 _dbus_connection_release_dispatch (DBusConnection *connection)
03788 {
03789 HAVE_LOCK_CHECK (connection);
03790
03791 _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03792 _dbus_mutex_lock (connection->dispatch_mutex);
03793
03794 _dbus_assert (connection->dispatch_acquired);
03795
03796 connection->dispatch_acquired = FALSE;
03797 _dbus_condvar_wake_one (connection->dispatch_cond);
03798
03799 _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03800 _dbus_mutex_unlock (connection->dispatch_mutex);
03801 }
03802
03803 static void
03804 _dbus_connection_failed_pop (DBusConnection *connection,
03805 DBusList *message_link)
03806 {
03807 _dbus_list_prepend_link (&connection->incoming_messages,
03808 message_link);
03809 connection->n_incoming += 1;
03810 }
03811
03812
03813 static void
03814 notify_disconnected_unlocked (DBusConnection *connection)
03815 {
03816 HAVE_LOCK_CHECK (connection);
03817
03818
03819
03820
03821
03822
03823
03824 _dbus_bus_notify_shared_connection_disconnected_unlocked (connection);
03825
03826
03827
03828
03829
03830 if (connection->n_outgoing > 0)
03831 {
03832 DBusList *link;
03833
03834 _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
03835 connection->n_outgoing);
03836
03837 while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
03838 {
03839 _dbus_connection_message_sent (connection, link->data);
03840 }
03841 }
03842 }
03843
03844
03845 static DBusDispatchStatus
03846 notify_disconnected_and_dispatch_complete_unlocked (DBusConnection *connection)
03847 {
03848 HAVE_LOCK_CHECK (connection);
03849
03850 if (connection->disconnect_message_link != NULL)
03851 {
03852 _dbus_verbose ("Sending disconnect message from %s\n",
03853 _DBUS_FUNCTION_NAME);
03854
03855
03856
03857
03858 connection_timeout_and_complete_all_pending_calls_unlocked (connection);
03859
03860
03861
03862
03863 _dbus_connection_queue_synthesized_message_link (connection,
03864 connection->disconnect_message_link);
03865 connection->disconnect_message_link = NULL;
03866
03867 return DBUS_DISPATCH_DATA_REMAINS;
03868 }
03869
03870 return DBUS_DISPATCH_COMPLETE;
03871 }
03872
03873 static DBusDispatchStatus
03874 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
03875 {
03876 HAVE_LOCK_CHECK (connection);
03877
03878 if (connection->n_incoming > 0)
03879 return DBUS_DISPATCH_DATA_REMAINS;
03880 else if (!_dbus_transport_queue_messages (connection->transport))
03881 return DBUS_DISPATCH_NEED_MEMORY;
03882 else
03883 {
03884 DBusDispatchStatus status;
03885 dbus_bool_t is_connected;
03886
03887 status = _dbus_transport_get_dispatch_status (connection->transport);
03888 is_connected = _dbus_transport_get_is_connected (connection->transport);
03889
03890 _dbus_verbose ("dispatch status = %s is_connected = %d\n",
03891 DISPATCH_STATUS_NAME (status), is_connected);
03892
03893 if (!is_connected)
03894 {
03895
03896
03897
03898
03899
03900
03901 notify_disconnected_unlocked (connection);
03902
03903
03904
03905
03906
03907
03908 if (status == DBUS_DISPATCH_COMPLETE)
03909 status = notify_disconnected_and_dispatch_complete_unlocked (connection);
03910 }
03911
03912 if (status != DBUS_DISPATCH_COMPLETE)
03913 return status;
03914 else if (connection->n_incoming > 0)
03915 return DBUS_DISPATCH_DATA_REMAINS;
03916 else
03917 return DBUS_DISPATCH_COMPLETE;
03918 }
03919 }
03920
03921 static void
03922 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
03923 DBusDispatchStatus new_status)
03924 {
03925 dbus_bool_t changed;
03926 DBusDispatchStatusFunction function;
03927 void *data;
03928
03929 HAVE_LOCK_CHECK (connection);
03930
03931 _dbus_connection_ref_unlocked (connection);
03932
03933 changed = new_status != connection->last_dispatch_status;
03934
03935 connection->last_dispatch_status = new_status;
03936
03937 function = connection->dispatch_status_function;
03938 data = connection->dispatch_status_data;
03939
03940 if (connection->disconnected_message_arrived &&
03941 !connection->disconnected_message_processed)
03942 {
03943 connection->disconnected_message_processed = TRUE;
03944
03945
03946
03947
03948
03949 connection_forget_shared_unlocked (connection);
03950
03951 if (connection->exit_on_disconnect)
03952 {
03953 CONNECTION_UNLOCK (connection);
03954
03955 _dbus_verbose ("Exiting on Disconnected signal\n");
03956 _dbus_exit (1);
03957 _dbus_assert_not_reached ("Call to exit() returned");
03958 }
03959 }
03960
03961
03962 CONNECTION_UNLOCK (connection);
03963
03964 if (changed && function)
03965 {
03966 _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
03967 connection, new_status,
03968 DISPATCH_STATUS_NAME (new_status));
03969 (* function) (connection, new_status, data);
03970 }
03971
03972 dbus_connection_unref (connection);
03973 }
03974
04000 DBusDispatchStatus
04001 dbus_connection_get_dispatch_status (DBusConnection *connection)
04002 {
04003 DBusDispatchStatus status;
04004
04005 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04006
04007 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
04008
04009 CONNECTION_LOCK (connection);
04010
04011 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04012
04013 CONNECTION_UNLOCK (connection);
04014
04015 return status;
04016 }
04017
04021 static DBusHandlerResult
04022 _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
04023 DBusMessage *message)
04024 {
04025 if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
04026 {
04027
04028 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04029 }
04030 else if (dbus_message_is_method_call (message,
04031 DBUS_INTERFACE_PEER,
04032 "Ping"))
04033 {
04034 DBusMessage *ret;
04035 dbus_bool_t sent;
04036
04037 ret = dbus_message_new_method_return (message);
04038 if (ret == NULL)
04039 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04040
04041 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04042
04043 dbus_message_unref (ret);
04044
04045 if (!sent)
04046 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04047
04048 return DBUS_HANDLER_RESULT_HANDLED;
04049 }
04050 else if (dbus_message_is_method_call (message,
04051 DBUS_INTERFACE_PEER,
04052 "GetMachineId"))
04053 {
04054 DBusMessage *ret;
04055 dbus_bool_t sent;
04056 DBusString uuid;
04057
04058 ret = dbus_message_new_method_return (message);
04059 if (ret == NULL)
04060 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04061
04062 sent = FALSE;
04063 _dbus_string_init (&uuid);
04064 if (_dbus_get_local_machine_uuid_encoded (&uuid))
04065 {
04066 const char *v_STRING = _dbus_string_get_const_data (&uuid);
04067 if (dbus_message_append_args (ret,
04068 DBUS_TYPE_STRING, &v_STRING,
04069 DBUS_TYPE_INVALID))
04070 {
04071 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04072 }
04073 }
04074 _dbus_string_free (&uuid);
04075
04076 dbus_message_unref (ret);
04077
04078 if (!sent)
04079 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04080
04081 return DBUS_HANDLER_RESULT_HANDLED;
04082 }
04083 else if (dbus_message_has_interface (message, DBUS_INTERFACE_PEER))
04084 {
04085
04086
04087
04088
04089
04090 DBusMessage *ret;
04091 dbus_bool_t sent;
04092
04093 ret = dbus_message_new_error (message,
04094 DBUS_ERROR_UNKNOWN_METHOD,
04095 "Unknown method invoked on org.freedesktop.DBus.Peer interface");
04096 if (ret == NULL)
04097 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04098
04099 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04100
04101 dbus_message_unref (ret);
04102
04103 if (!sent)
04104 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04105
04106 return DBUS_HANDLER_RESULT_HANDLED;
04107 }
04108 else
04109 {
04110 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04111 }
04112 }
04113
04120 static DBusHandlerResult
04121 _dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection,
04122 DBusMessage *message)
04123 {
04124
04125
04126
04127 return _dbus_connection_peer_filter_unlocked_no_update (connection, message);
04128 }
04129
04172 DBusDispatchStatus
04173 dbus_connection_dispatch (DBusConnection *connection)
04174 {
04175 DBusMessage *message;
04176 DBusList *link, *filter_list_copy, *message_link;
04177 DBusHandlerResult result;
04178 DBusPendingCall *pending;
04179 dbus_int32_t reply_serial;
04180 DBusDispatchStatus status;
04181
04182 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04183
04184 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
04185
04186 CONNECTION_LOCK (connection);
04187 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04188 if (status != DBUS_DISPATCH_DATA_REMAINS)
04189 {
04190
04191 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04192 return status;
04193 }
04194
04195
04196
04197
04198 _dbus_connection_ref_unlocked (connection);
04199
04200 _dbus_connection_acquire_dispatch (connection);
04201 HAVE_LOCK_CHECK (connection);
04202
04203 message_link = _dbus_connection_pop_message_link_unlocked (connection);
04204 if (message_link == NULL)
04205 {
04206
04207
04208 _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
04209
04210 _dbus_connection_release_dispatch (connection);
04211
04212 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04213
04214 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04215
04216 dbus_connection_unref (connection);
04217
04218 return status;
04219 }
04220
04221 message = message_link->data;
04222
04223 _dbus_verbose (" dispatching message %p (%d %s %s '%s')\n",
04224 message,
04225 dbus_message_get_type (message),
04226 dbus_message_get_interface (message) ?
04227 dbus_message_get_interface (message) :
04228 "no interface",
04229 dbus_message_get_member (message) ?
04230 dbus_message_get_member (message) :
04231 "no member",
04232 dbus_message_get_signature (message));
04233
04234 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04235
04236
04237
04238
04239
04240
04241
04242
04243 reply_serial = dbus_message_get_reply_serial (message);
04244 pending = _dbus_hash_table_lookup_int (connection->pending_replies,
04245 reply_serial);
04246 if (pending)
04247 {
04248 _dbus_verbose ("Dispatching a pending reply\n");
04249 complete_pending_call_and_unlock (connection, pending, message);
04250 pending = NULL;
04251
04252 CONNECTION_LOCK (connection);
04253 _dbus_verbose ("pending call completed in dispatch\n");
04254 result = DBUS_HANDLER_RESULT_HANDLED;
04255 goto out;
04256 }
04257
04258 result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message);
04259 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04260 goto out;
04261
04262 if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
04263 {
04264 _dbus_connection_release_dispatch (connection);
04265 HAVE_LOCK_CHECK (connection);
04266
04267 _dbus_connection_failed_pop (connection, message_link);
04268
04269
04270 _dbus_connection_update_dispatch_status_and_unlock (connection,
04271 DBUS_DISPATCH_NEED_MEMORY);
04272
04273 if (pending)
04274 dbus_pending_call_unref (pending);
04275 dbus_connection_unref (connection);
04276
04277 return DBUS_DISPATCH_NEED_MEMORY;
04278 }
04279
04280 _dbus_list_foreach (&filter_list_copy,
04281 (DBusForeachFunction)_dbus_message_filter_ref,
04282 NULL);
04283
04284
04285
04286
04287 CONNECTION_UNLOCK (connection);
04288
04289 link = _dbus_list_get_first_link (&filter_list_copy);
04290 while (link != NULL)
04291 {
04292 DBusMessageFilter *filter = link->data;
04293 DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
04294
04295 if (filter->function == NULL)
04296 {
04297 _dbus_verbose (" filter was removed in a callback function\n");
04298 link = next;
04299 continue;
04300 }
04301
04302 _dbus_verbose (" running filter on message %p\n", message);
04303 result = (* filter->function) (connection, message, filter->user_data);
04304
04305 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04306 break;
04307
04308 link = next;
04309 }
04310
04311 _dbus_list_foreach (&filter_list_copy,
04312 (DBusForeachFunction)_dbus_message_filter_unref,
04313 NULL);
04314 _dbus_list_clear (&filter_list_copy);
04315
04316 CONNECTION_LOCK (connection);
04317
04318 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04319 {
04320 _dbus_verbose ("No memory in %s\n", _DBUS_FUNCTION_NAME);
04321 goto out;
04322 }
04323 else if (result == DBUS_HANDLER_RESULT_HANDLED)
04324 {
04325 _dbus_verbose ("filter handled message in dispatch\n");
04326 goto out;
04327 }
04328
04329
04330
04331
04332 _dbus_verbose (" running object path dispatch on message %p (%d %s %s '%s')\n",
04333 message,
04334 dbus_message_get_type (message),
04335 dbus_message_get_interface (message) ?
04336 dbus_message_get_interface (message) :
04337 "no interface",
04338 dbus_message_get_member (message) ?
04339 dbus_message_get_member (message) :
04340 "no member",
04341 dbus_message_get_signature (message));
04342
04343 HAVE_LOCK_CHECK (connection);
04344 result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
04345 message);
04346
04347 CONNECTION_LOCK (connection);
04348
04349 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04350 {
04351 _dbus_verbose ("object tree handled message in dispatch\n");
04352 goto out;
04353 }
04354
04355 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
04356 {
04357 DBusMessage *reply;
04358 DBusString str;
04359 DBusPreallocatedSend *preallocated;
04360
04361 _dbus_verbose (" sending error %s\n",
04362 DBUS_ERROR_UNKNOWN_METHOD);
04363
04364 if (!_dbus_string_init (&str))
04365 {
04366 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04367 _dbus_verbose ("no memory for error string in dispatch\n");
04368 goto out;
04369 }
04370
04371 if (!_dbus_string_append_printf (&str,
04372 "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
04373 dbus_message_get_member (message),
04374 dbus_message_get_signature (message),
04375 dbus_message_get_interface (message)))
04376 {
04377 _dbus_string_free (&str);
04378 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04379 _dbus_verbose ("no memory for error string in dispatch\n");
04380 goto out;
04381 }
04382
04383 reply = dbus_message_new_error (message,
04384 DBUS_ERROR_UNKNOWN_METHOD,
04385 _dbus_string_get_const_data (&str));
04386 _dbus_string_free (&str);
04387
04388 if (reply == NULL)
04389 {
04390 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04391 _dbus_verbose ("no memory for error reply in dispatch\n");
04392 goto out;
04393 }
04394
04395 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
04396
04397 if (preallocated == NULL)
04398 {
04399 dbus_message_unref (reply);
04400 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04401 _dbus_verbose ("no memory for error send in dispatch\n");
04402 goto out;
04403 }
04404
04405 _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
04406 reply, NULL);
04407
04408 dbus_message_unref (reply);
04409
04410 result = DBUS_HANDLER_RESULT_HANDLED;
04411 }
04412
04413 _dbus_verbose (" done dispatching %p (%d %s %s '%s') on connection %p\n", message,
04414 dbus_message_get_type (message),
04415 dbus_message_get_interface (message) ?
04416 dbus_message_get_interface (message) :
04417 "no interface",
04418 dbus_message_get_member (message) ?
04419 dbus_message_get_member (message) :
04420 "no member",
04421 dbus_message_get_signature (message),
04422 connection);
04423
04424 out:
04425 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04426 {
04427 _dbus_verbose ("out of memory in %s\n", _DBUS_FUNCTION_NAME);
04428
04429
04430
04431
04432
04433 _dbus_connection_putback_message_link_unlocked (connection,
04434 message_link);
04435 }
04436 else
04437 {
04438 _dbus_verbose (" ... done dispatching in %s\n", _DBUS_FUNCTION_NAME);
04439
04440 _dbus_list_free_link (message_link);
04441 dbus_message_unref (message);
04442
04443
04444 }
04445
04446 _dbus_connection_release_dispatch (connection);
04447 HAVE_LOCK_CHECK (connection);
04448
04449 _dbus_verbose ("%s before final status update\n", _DBUS_FUNCTION_NAME);
04450 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04451
04452
04453 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04454
04455 dbus_connection_unref (connection);
04456
04457 return status;
04458 }
04459
04518 dbus_bool_t
04519 dbus_connection_set_watch_functions (DBusConnection *connection,
04520 DBusAddWatchFunction add_function,
04521 DBusRemoveWatchFunction remove_function,
04522 DBusWatchToggledFunction toggled_function,
04523 void *data,
04524 DBusFreeFunction free_data_function)
04525 {
04526 dbus_bool_t retval;
04527 DBusWatchList *watches;
04528
04529 _dbus_return_val_if_fail (connection != NULL, FALSE);
04530
04531 CONNECTION_LOCK (connection);
04532
04533 #ifndef DBUS_DISABLE_CHECKS
04534 if (connection->watches == NULL)
04535 {
04536 _dbus_warn_check_failed ("Re-entrant call to %s is not allowed\n",
04537 _DBUS_FUNCTION_NAME);
04538 return FALSE;
04539 }
04540 #endif
04541
04542
04543 _dbus_connection_ref_unlocked (connection);
04544
04545
04546
04547
04548
04549 watches = connection->watches;
04550 connection->watches = NULL;
04551 CONNECTION_UNLOCK (connection);
04552
04553 retval = _dbus_watch_list_set_functions (watches,
04554 add_function, remove_function,
04555 toggled_function,
04556 data, free_data_function);
04557 CONNECTION_LOCK (connection);
04558 connection->watches = watches;
04559
04560 CONNECTION_UNLOCK (connection);
04561
04562 dbus_connection_unref (connection);
04563
04564 return retval;
04565 }
04566
04600 dbus_bool_t
04601 dbus_connection_set_timeout_functions (DBusConnection *connection,
04602 DBusAddTimeoutFunction add_function,
04603 DBusRemoveTimeoutFunction remove_function,
04604 DBusTimeoutToggledFunction toggled_function,
04605 void *data,
04606 DBusFreeFunction free_data_function)
04607 {
04608 dbus_bool_t retval;
04609 DBusTimeoutList *timeouts;
04610
04611 _dbus_return_val_if_fail (connection != NULL, FALSE);
04612
04613 CONNECTION_LOCK (connection);
04614
04615 #ifndef DBUS_DISABLE_CHECKS
04616 if (connection->timeouts == NULL)
04617 {
04618 _dbus_warn_check_failed ("Re-entrant call to %s is not allowed\n",
04619 _DBUS_FUNCTION_NAME);
04620 return FALSE;
04621 }
04622 #endif
04623
04624
04625 _dbus_connection_ref_unlocked (connection);
04626
04627 timeouts = connection->timeouts;
04628 connection->timeouts = NULL;
04629 CONNECTION_UNLOCK (connection);
04630
04631 retval = _dbus_timeout_list_set_functions (timeouts,
04632 add_function, remove_function,
04633 toggled_function,
04634 data, free_data_function);
04635 CONNECTION_LOCK (connection);
04636 connection->timeouts = timeouts;
04637
04638 CONNECTION_UNLOCK (connection);
04639
04640 dbus_connection_unref (connection);
04641
04642 return retval;
04643 }
04644
04659 void
04660 dbus_connection_set_wakeup_main_function (DBusConnection *connection,
04661 DBusWakeupMainFunction wakeup_main_function,
04662 void *data,
04663 DBusFreeFunction free_data_function)
04664 {
04665 void *old_data;
04666 DBusFreeFunction old_free_data;
04667
04668 _dbus_return_if_fail (connection != NULL);
04669
04670 CONNECTION_LOCK (connection);
04671 old_data = connection->wakeup_main_data;
04672 old_free_data = connection->free_wakeup_main_data;
04673
04674 connection->wakeup_main_function = wakeup_main_function;
04675 connection->wakeup_main_data = data;
04676 connection->free_wakeup_main_data = free_data_function;
04677
04678 CONNECTION_UNLOCK (connection);
04679
04680
04681 if (old_free_data)
04682 (*old_free_data) (old_data);
04683 }
04684
04705 void
04706 dbus_connection_set_dispatch_status_function (DBusConnection *connection,
04707 DBusDispatchStatusFunction function,
04708 void *data,
04709 DBusFreeFunction free_data_function)
04710 {
04711 void *old_data;
04712 DBusFreeFunction old_free_data;
04713
04714 _dbus_return_if_fail (connection != NULL);
04715
04716 CONNECTION_LOCK (connection);
04717 old_data = connection->dispatch_status_data;
04718 old_free_data = connection->free_dispatch_status_data;
04719
04720 connection->dispatch_status_function = function;
04721 connection->dispatch_status_data = data;
04722 connection->free_dispatch_status_data = free_data_function;
04723
04724 CONNECTION_UNLOCK (connection);
04725
04726
04727 if (old_free_data)
04728 (*old_free_data) (old_data);
04729 }
04730
04750 dbus_bool_t
04751 dbus_connection_get_unix_fd (DBusConnection *connection,
04752 int *fd)
04753 {
04754 _dbus_return_val_if_fail (connection != NULL, FALSE);
04755 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
04756
04757 #ifdef DBUS_WIN
04758
04759 return FALSE;
04760 #endif
04761
04762 return dbus_connection_get_socket(connection, fd);
04763 }
04764
04780 dbus_bool_t
04781 dbus_connection_get_socket(DBusConnection *connection,
04782 int *fd)
04783 {
04784 dbus_bool_t retval;
04785
04786 _dbus_return_val_if_fail (connection != NULL, FALSE);
04787 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
04788
04789 CONNECTION_LOCK (connection);
04790
04791 retval = _dbus_transport_get_socket_fd (connection->transport,
04792 fd);
04793
04794 CONNECTION_UNLOCK (connection);
04795
04796 return retval;
04797 }
04798
04799
04820 dbus_bool_t
04821 dbus_connection_get_unix_user (DBusConnection *connection,
04822 unsigned long *uid)
04823 {
04824 dbus_bool_t result;
04825
04826 _dbus_return_val_if_fail (connection != NULL, FALSE);
04827 _dbus_return_val_if_fail (uid != NULL, FALSE);
04828
04829 #ifdef DBUS_WIN
04830
04831
04832
04833
04834 return FALSE;
04835 #endif
04836
04837 CONNECTION_LOCK (connection);
04838
04839 if (!_dbus_transport_get_is_authenticated (connection->transport))
04840 result = FALSE;
04841 else
04842 result = _dbus_transport_get_unix_user (connection->transport,
04843 uid);
04844 CONNECTION_UNLOCK (connection);
04845
04846 return result;
04847 }
04848
04859 dbus_bool_t
04860 dbus_connection_get_unix_process_id (DBusConnection *connection,
04861 unsigned long *pid)
04862 {
04863 dbus_bool_t result;
04864
04865 _dbus_return_val_if_fail (connection != NULL, FALSE);
04866 _dbus_return_val_if_fail (pid != NULL, FALSE);
04867
04868 #ifdef DBUS_WIN
04869
04870
04871
04872
04873 return FALSE;
04874 #endif
04875
04876 CONNECTION_LOCK (connection);
04877
04878 if (!_dbus_transport_get_is_authenticated (connection->transport))
04879 result = FALSE;
04880 else
04881 result = _dbus_transport_get_unix_process_id (connection->transport,
04882 pid);
04883 CONNECTION_UNLOCK (connection);
04884
04885 return result;
04886 }
04887
04911 void
04912 dbus_connection_set_unix_user_function (DBusConnection *connection,
04913 DBusAllowUnixUserFunction function,
04914 void *data,
04915 DBusFreeFunction free_data_function)
04916 {
04917 void *old_data = NULL;
04918 DBusFreeFunction old_free_function = NULL;
04919
04920 _dbus_return_if_fail (connection != NULL);
04921
04922 CONNECTION_LOCK (connection);
04923 _dbus_transport_set_unix_user_function (connection->transport,
04924 function, data, free_data_function,
04925 &old_data, &old_free_function);
04926 CONNECTION_UNLOCK (connection);
04927
04928 if (old_free_function != NULL)
04929 (* old_free_function) (old_data);
04930 }
04931
04950 void
04951 dbus_connection_set_route_peer_messages (DBusConnection *connection,
04952 dbus_bool_t value)
04953 {
04954 _dbus_return_if_fail (connection != NULL);
04955
04956 CONNECTION_LOCK (connection);
04957 connection->route_peer_messages = TRUE;
04958 CONNECTION_UNLOCK (connection);
04959 }
04960
04982 dbus_bool_t
04983 dbus_connection_add_filter (DBusConnection *connection,
04984 DBusHandleMessageFunction function,
04985 void *user_data,
04986 DBusFreeFunction free_data_function)
04987 {
04988 DBusMessageFilter *filter;
04989
04990 _dbus_return_val_if_fail (connection != NULL, FALSE);
04991 _dbus_return_val_if_fail (function != NULL, FALSE);
04992
04993 filter = dbus_new0 (DBusMessageFilter, 1);
04994 if (filter == NULL)
04995 return FALSE;
04996
04997 filter->refcount.value = 1;
04998
04999 CONNECTION_LOCK (connection);
05000
05001 if (!_dbus_list_append (&connection->filter_list,
05002 filter))
05003 {
05004 _dbus_message_filter_unref (filter);
05005 CONNECTION_UNLOCK (connection);
05006 return FALSE;
05007 }
05008
05009
05010
05011
05012
05013
05014 filter->function = function;
05015 filter->user_data = user_data;
05016 filter->free_user_data_function = free_data_function;
05017
05018 CONNECTION_UNLOCK (connection);
05019 return TRUE;
05020 }
05021
05034 void
05035 dbus_connection_remove_filter (DBusConnection *connection,
05036 DBusHandleMessageFunction function,
05037 void *user_data)
05038 {
05039 DBusList *link;
05040 DBusMessageFilter *filter;
05041
05042 _dbus_return_if_fail (connection != NULL);
05043 _dbus_return_if_fail (function != NULL);
05044
05045 CONNECTION_LOCK (connection);
05046
05047 filter = NULL;
05048
05049 link = _dbus_list_get_last_link (&connection->filter_list);
05050 while (link != NULL)
05051 {
05052 filter = link->data;
05053
05054 if (filter->function == function &&
05055 filter->user_data == user_data)
05056 {
05057 _dbus_list_remove_link (&connection->filter_list, link);
05058 filter->function = NULL;
05059
05060 break;
05061 }
05062
05063 link = _dbus_list_get_prev_link (&connection->filter_list, link);
05064 }
05065
05066 CONNECTION_UNLOCK (connection);
05067
05068 #ifndef DBUS_DISABLE_CHECKS
05069 if (filter == NULL)
05070 {
05071 _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
05072 function, user_data);
05073 return;
05074 }
05075 #endif
05076
05077
05078 if (filter->free_user_data_function)
05079 (* filter->free_user_data_function) (filter->user_data);
05080
05081 filter->free_user_data_function = NULL;
05082 filter->user_data = NULL;
05083
05084 _dbus_message_filter_unref (filter);
05085 }
05086
05098 dbus_bool_t
05099 dbus_connection_register_object_path (DBusConnection *connection,
05100 const char *path,
05101 const DBusObjectPathVTable *vtable,
05102 void *user_data)
05103 {
05104 char **decomposed_path;
05105 dbus_bool_t retval;
05106
05107 _dbus_return_val_if_fail (connection != NULL, FALSE);
05108 _dbus_return_val_if_fail (path != NULL, FALSE);
05109 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05110 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05111
05112 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05113 return FALSE;
05114
05115 CONNECTION_LOCK (connection);
05116
05117 retval = _dbus_object_tree_register (connection->objects,
05118 FALSE,
05119 (const char **) decomposed_path, vtable,
05120 user_data);
05121
05122 CONNECTION_UNLOCK (connection);
05123
05124 dbus_free_string_array (decomposed_path);
05125
05126 return retval;
05127 }
05128
05141 dbus_bool_t
05142 dbus_connection_register_fallback (DBusConnection *connection,
05143 const char *path,
05144 const DBusObjectPathVTable *vtable,
05145 void *user_data)
05146 {
05147 char **decomposed_path;
05148 dbus_bool_t retval;
05149
05150 _dbus_return_val_if_fail (connection != NULL, FALSE);
05151 _dbus_return_val_if_fail (path != NULL, FALSE);
05152 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05153 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05154
05155 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05156 return FALSE;
05157
05158 CONNECTION_LOCK (connection);
05159
05160 retval = _dbus_object_tree_register (connection->objects,
05161 TRUE,
05162 (const char **) decomposed_path, vtable,
05163 user_data);
05164
05165 CONNECTION_UNLOCK (connection);
05166
05167 dbus_free_string_array (decomposed_path);
05168
05169 return retval;
05170 }
05171
05181 dbus_bool_t
05182 dbus_connection_unregister_object_path (DBusConnection *connection,
05183 const char *path)
05184 {
05185 char **decomposed_path;
05186
05187 _dbus_return_val_if_fail (connection != NULL, FALSE);
05188 _dbus_return_val_if_fail (path != NULL, FALSE);
05189 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05190
05191 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05192 return FALSE;
05193
05194 CONNECTION_LOCK (connection);
05195
05196 _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
05197
05198 dbus_free_string_array (decomposed_path);
05199
05200 return TRUE;
05201 }
05202
05213 dbus_bool_t
05214 dbus_connection_get_object_path_data (DBusConnection *connection,
05215 const char *path,
05216 void **data_p)
05217 {
05218 char **decomposed_path;
05219
05220 _dbus_return_val_if_fail (connection != NULL, FALSE);
05221 _dbus_return_val_if_fail (path != NULL, FALSE);
05222 _dbus_return_val_if_fail (data_p != NULL, FALSE);
05223
05224 *data_p = NULL;
05225
05226 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05227 return FALSE;
05228
05229 CONNECTION_LOCK (connection);
05230
05231 *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path);
05232
05233 CONNECTION_UNLOCK (connection);
05234
05235 dbus_free_string_array (decomposed_path);
05236
05237 return TRUE;
05238 }
05239
05250 dbus_bool_t
05251 dbus_connection_list_registered (DBusConnection *connection,
05252 const char *parent_path,
05253 char ***child_entries)
05254 {
05255 char **decomposed_path;
05256 dbus_bool_t retval;
05257 _dbus_return_val_if_fail (connection != NULL, FALSE);
05258 _dbus_return_val_if_fail (parent_path != NULL, FALSE);
05259 _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
05260 _dbus_return_val_if_fail (child_entries != NULL, FALSE);
05261
05262 if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
05263 return FALSE;
05264
05265 CONNECTION_LOCK (connection);
05266
05267 retval = _dbus_object_tree_list_registered_and_unlock (connection->objects,
05268 (const char **) decomposed_path,
05269 child_entries);
05270 dbus_free_string_array (decomposed_path);
05271
05272 return retval;
05273 }
05274
05275 static DBusDataSlotAllocator slot_allocator;
05276 _DBUS_DEFINE_GLOBAL_LOCK (connection_slots);
05277
05292 dbus_bool_t
05293 dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
05294 {
05295 return _dbus_data_slot_allocator_alloc (&slot_allocator,
05296 &_DBUS_LOCK_NAME (connection_slots),
05297 slot_p);
05298 }
05299
05311 void
05312 dbus_connection_free_data_slot (dbus_int32_t *slot_p)
05313 {
05314 _dbus_return_if_fail (*slot_p >= 0);
05315
05316 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
05317 }
05318
05332 dbus_bool_t
05333 dbus_connection_set_data (DBusConnection *connection,
05334 dbus_int32_t slot,
05335 void *data,
05336 DBusFreeFunction free_data_func)
05337 {
05338 DBusFreeFunction old_free_func;
05339 void *old_data;
05340 dbus_bool_t retval;
05341
05342 _dbus_return_val_if_fail (connection != NULL, FALSE);
05343 _dbus_return_val_if_fail (slot >= 0, FALSE);
05344
05345 CONNECTION_LOCK (connection);
05346
05347 retval = _dbus_data_slot_list_set (&slot_allocator,
05348 &connection->slot_list,
05349 slot, data, free_data_func,
05350 &old_free_func, &old_data);
05351
05352 CONNECTION_UNLOCK (connection);
05353
05354 if (retval)
05355 {
05356
05357 if (old_free_func)
05358 (* old_free_func) (old_data);
05359 }
05360
05361 return retval;
05362 }
05363
05372 void*
05373 dbus_connection_get_data (DBusConnection *connection,
05374 dbus_int32_t slot)
05375 {
05376 void *res;
05377
05378 _dbus_return_val_if_fail (connection != NULL, NULL);
05379
05380 CONNECTION_LOCK (connection);
05381
05382 res = _dbus_data_slot_list_get (&slot_allocator,
05383 &connection->slot_list,
05384 slot);
05385
05386 CONNECTION_UNLOCK (connection);
05387
05388 return res;
05389 }
05390
05397 void
05398 dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
05399 {
05400 _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
05401 }
05402
05411 void
05412 dbus_connection_set_max_message_size (DBusConnection *connection,
05413 long size)
05414 {
05415 _dbus_return_if_fail (connection != NULL);
05416
05417 CONNECTION_LOCK (connection);
05418 _dbus_transport_set_max_message_size (connection->transport,
05419 size);
05420 CONNECTION_UNLOCK (connection);
05421 }
05422
05429 long
05430 dbus_connection_get_max_message_size (DBusConnection *connection)
05431 {
05432 long res;
05433
05434 _dbus_return_val_if_fail (connection != NULL, 0);
05435
05436 CONNECTION_LOCK (connection);
05437 res = _dbus_transport_get_max_message_size (connection->transport);
05438 CONNECTION_UNLOCK (connection);
05439 return res;
05440 }
05441
05467 void
05468 dbus_connection_set_max_received_size (DBusConnection *connection,
05469 long size)
05470 {
05471 _dbus_return_if_fail (connection != NULL);
05472
05473 CONNECTION_LOCK (connection);
05474 _dbus_transport_set_max_received_size (connection->transport,
05475 size);
05476 CONNECTION_UNLOCK (connection);
05477 }
05478
05485 long
05486 dbus_connection_get_max_received_size (DBusConnection *connection)
05487 {
05488 long res;
05489
05490 _dbus_return_val_if_fail (connection != NULL, 0);
05491
05492 CONNECTION_LOCK (connection);
05493 res = _dbus_transport_get_max_received_size (connection->transport);
05494 CONNECTION_UNLOCK (connection);
05495 return res;
05496 }
05497
05508 long
05509 dbus_connection_get_outgoing_size (DBusConnection *connection)
05510 {
05511 long res;
05512
05513 _dbus_return_val_if_fail (connection != NULL, 0);
05514
05515 CONNECTION_LOCK (connection);
05516 res = _dbus_counter_get_value (connection->outgoing_counter);
05517 CONNECTION_UNLOCK (connection);
05518 return res;
05519 }
05520