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_uint32_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 != 0)
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 (timeout)
00887 {
00888 if (!_dbus_connection_add_timeout_unlocked (connection, timeout))
00889 return FALSE;
00890
00891 if (!_dbus_hash_table_insert_int (connection->pending_replies,
00892 reply_serial,
00893 pending))
00894 {
00895 _dbus_connection_remove_timeout_unlocked (connection, timeout);
00896
00897 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00898 HAVE_LOCK_CHECK (connection);
00899 return FALSE;
00900 }
00901
00902 _dbus_pending_call_set_timeout_added_unlocked (pending, TRUE);
00903 }
00904 else
00905 {
00906 if (!_dbus_hash_table_insert_int (connection->pending_replies,
00907 reply_serial,
00908 pending))
00909 {
00910 HAVE_LOCK_CHECK (connection);
00911 return FALSE;
00912 }
00913 }
00914
00915 _dbus_pending_call_ref_unlocked (pending);
00916
00917 HAVE_LOCK_CHECK (connection);
00918
00919 return TRUE;
00920 }
00921
00922 static void
00923 free_pending_call_on_hash_removal (void *data)
00924 {
00925 DBusPendingCall *pending;
00926 DBusConnection *connection;
00927
00928 if (data == NULL)
00929 return;
00930
00931 pending = data;
00932
00933 connection = _dbus_pending_call_get_connection_unlocked (pending);
00934
00935 HAVE_LOCK_CHECK (connection);
00936
00937 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00938 {
00939 _dbus_connection_remove_timeout_unlocked (connection,
00940 _dbus_pending_call_get_timeout_unlocked (pending));
00941
00942 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00943 }
00944
00945
00946
00947
00948
00949
00950 _dbus_connection_ref_unlocked (connection);
00951 _dbus_pending_call_unref_and_unlock (pending);
00952 CONNECTION_LOCK (connection);
00953 _dbus_connection_unref_unlocked (connection);
00954 }
00955
00956 static void
00957 _dbus_connection_detach_pending_call_unlocked (DBusConnection *connection,
00958 DBusPendingCall *pending)
00959 {
00960
00961
00962
00963 _dbus_hash_table_remove_int (connection->pending_replies,
00964 _dbus_pending_call_get_reply_serial_unlocked (pending));
00965 }
00966
00967 static void
00968 _dbus_connection_detach_pending_call_and_unlock (DBusConnection *connection,
00969 DBusPendingCall *pending)
00970 {
00971
00972
00973
00974
00975
00976
00977
00978 _dbus_pending_call_ref_unlocked (pending);
00979 _dbus_hash_table_remove_int (connection->pending_replies,
00980 _dbus_pending_call_get_reply_serial_unlocked (pending));
00981
00982 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00983 _dbus_connection_remove_timeout_unlocked (connection,
00984 _dbus_pending_call_get_timeout_unlocked (pending));
00985
00986 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00987
00988 _dbus_pending_call_unref_and_unlock (pending);
00989 }
00990
00999 void
01000 _dbus_connection_remove_pending_call (DBusConnection *connection,
01001 DBusPendingCall *pending)
01002 {
01003 CONNECTION_LOCK (connection);
01004 _dbus_connection_detach_pending_call_and_unlock (connection, pending);
01005 }
01006
01016 static dbus_bool_t
01017 _dbus_connection_acquire_io_path (DBusConnection *connection,
01018 int timeout_milliseconds)
01019 {
01020 dbus_bool_t we_acquired;
01021
01022 HAVE_LOCK_CHECK (connection);
01023
01024
01025 _dbus_connection_ref_unlocked (connection);
01026
01027
01028 CONNECTION_UNLOCK (connection);
01029
01030 _dbus_verbose ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME);
01031 _dbus_mutex_lock (connection->io_path_mutex);
01032
01033 _dbus_verbose ("%s start connection->io_path_acquired = %d timeout = %d\n",
01034 _DBUS_FUNCTION_NAME, connection->io_path_acquired, timeout_milliseconds);
01035
01036 we_acquired = FALSE;
01037
01038 if (connection->io_path_acquired)
01039 {
01040 if (timeout_milliseconds != -1)
01041 {
01042 _dbus_verbose ("%s waiting %d for IO path to be acquirable\n",
01043 _DBUS_FUNCTION_NAME, timeout_milliseconds);
01044
01045 if (!_dbus_condvar_wait_timeout (connection->io_path_cond,
01046 connection->io_path_mutex,
01047 timeout_milliseconds))
01048 {
01049
01050
01051
01052
01053
01054
01055
01056
01057 }
01058 }
01059 else
01060 {
01061 while (connection->io_path_acquired)
01062 {
01063 _dbus_verbose ("%s waiting for IO path to be acquirable\n", _DBUS_FUNCTION_NAME);
01064 _dbus_condvar_wait (connection->io_path_cond,
01065 connection->io_path_mutex);
01066 }
01067 }
01068 }
01069
01070 if (!connection->io_path_acquired)
01071 {
01072 we_acquired = TRUE;
01073 connection->io_path_acquired = TRUE;
01074 }
01075
01076 _dbus_verbose ("%s end connection->io_path_acquired = %d we_acquired = %d\n",
01077 _DBUS_FUNCTION_NAME, connection->io_path_acquired, we_acquired);
01078
01079 _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME);
01080 _dbus_mutex_unlock (connection->io_path_mutex);
01081
01082 CONNECTION_LOCK (connection);
01083
01084 HAVE_LOCK_CHECK (connection);
01085
01086 _dbus_connection_unref_unlocked (connection);
01087
01088 return we_acquired;
01089 }
01090
01098 static void
01099 _dbus_connection_release_io_path (DBusConnection *connection)
01100 {
01101 HAVE_LOCK_CHECK (connection);
01102
01103 _dbus_verbose ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME);
01104 _dbus_mutex_lock (connection->io_path_mutex);
01105
01106 _dbus_assert (connection->io_path_acquired);
01107
01108 _dbus_verbose ("%s start connection->io_path_acquired = %d\n",
01109 _DBUS_FUNCTION_NAME, connection->io_path_acquired);
01110
01111 connection->io_path_acquired = FALSE;
01112 _dbus_condvar_wake_one (connection->io_path_cond);
01113
01114 _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME);
01115 _dbus_mutex_unlock (connection->io_path_mutex);
01116 }
01117
01146 void
01147 _dbus_connection_do_iteration_unlocked (DBusConnection *connection,
01148 unsigned int flags,
01149 int timeout_milliseconds)
01150 {
01151 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
01152
01153 HAVE_LOCK_CHECK (connection);
01154
01155 if (connection->n_outgoing == 0)
01156 flags &= ~DBUS_ITERATION_DO_WRITING;
01157
01158 if (_dbus_connection_acquire_io_path (connection,
01159 (flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0))
01160 {
01161 HAVE_LOCK_CHECK (connection);
01162
01163 _dbus_transport_do_iteration (connection->transport,
01164 flags, timeout_milliseconds);
01165 _dbus_connection_release_io_path (connection);
01166 }
01167
01168 HAVE_LOCK_CHECK (connection);
01169
01170 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
01171 }
01172
01182 DBusConnection*
01183 _dbus_connection_new_for_transport (DBusTransport *transport)
01184 {
01185 DBusConnection *connection;
01186 DBusWatchList *watch_list;
01187 DBusTimeoutList *timeout_list;
01188 DBusHashTable *pending_replies;
01189 DBusList *disconnect_link;
01190 DBusMessage *disconnect_message;
01191 DBusCounter *outgoing_counter;
01192 DBusObjectTree *objects;
01193
01194 watch_list = NULL;
01195 connection = NULL;
01196 pending_replies = NULL;
01197 timeout_list = NULL;
01198 disconnect_link = NULL;
01199 disconnect_message = NULL;
01200 outgoing_counter = NULL;
01201 objects = NULL;
01202
01203 watch_list = _dbus_watch_list_new ();
01204 if (watch_list == NULL)
01205 goto error;
01206
01207 timeout_list = _dbus_timeout_list_new ();
01208 if (timeout_list == NULL)
01209 goto error;
01210
01211 pending_replies =
01212 _dbus_hash_table_new (DBUS_HASH_INT,
01213 NULL,
01214 (DBusFreeFunction)free_pending_call_on_hash_removal);
01215 if (pending_replies == NULL)
01216 goto error;
01217
01218 connection = dbus_new0 (DBusConnection, 1);
01219 if (connection == NULL)
01220 goto error;
01221
01222 _dbus_mutex_new_at_location (&connection->mutex);
01223 if (connection->mutex == NULL)
01224 goto error;
01225
01226 _dbus_mutex_new_at_location (&connection->io_path_mutex);
01227 if (connection->io_path_mutex == NULL)
01228 goto error;
01229
01230 _dbus_mutex_new_at_location (&connection->dispatch_mutex);
01231 if (connection->dispatch_mutex == NULL)
01232 goto error;
01233
01234 _dbus_condvar_new_at_location (&connection->dispatch_cond);
01235 if (connection->dispatch_cond == NULL)
01236 goto error;
01237
01238 _dbus_condvar_new_at_location (&connection->io_path_cond);
01239 if (connection->io_path_cond == NULL)
01240 goto error;
01241
01242 disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL,
01243 DBUS_INTERFACE_LOCAL,
01244 "Disconnected");
01245
01246 if (disconnect_message == NULL)
01247 goto error;
01248
01249 disconnect_link = _dbus_list_alloc_link (disconnect_message);
01250 if (disconnect_link == NULL)
01251 goto error;
01252
01253 outgoing_counter = _dbus_counter_new ();
01254 if (outgoing_counter == NULL)
01255 goto error;
01256
01257 objects = _dbus_object_tree_new (connection);
01258 if (objects == NULL)
01259 goto error;
01260
01261 if (_dbus_modify_sigpipe)
01262 _dbus_disable_sigpipe ();
01263
01264 connection->refcount.value = 1;
01265 connection->transport = transport;
01266 connection->watches = watch_list;
01267 connection->timeouts = timeout_list;
01268 connection->pending_replies = pending_replies;
01269 connection->outgoing_counter = outgoing_counter;
01270 connection->filter_list = NULL;
01271 connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE;
01272 connection->objects = objects;
01273 connection->exit_on_disconnect = FALSE;
01274 connection->shareable = FALSE;
01275 connection->route_peer_messages = FALSE;
01276 connection->disconnected_message_arrived = FALSE;
01277 connection->disconnected_message_processed = FALSE;
01278
01279 #ifndef DBUS_DISABLE_CHECKS
01280 connection->generation = _dbus_current_generation;
01281 #endif
01282
01283 _dbus_data_slot_list_init (&connection->slot_list);
01284
01285 connection->client_serial = 1;
01286
01287 connection->disconnect_message_link = disconnect_link;
01288
01289 CONNECTION_LOCK (connection);
01290
01291 if (!_dbus_transport_set_connection (transport, connection))
01292 {
01293 CONNECTION_UNLOCK (connection);
01294
01295 goto error;
01296 }
01297
01298 _dbus_transport_ref (transport);
01299
01300 CONNECTION_UNLOCK (connection);
01301
01302 return connection;
01303
01304 error:
01305 if (disconnect_message != NULL)
01306 dbus_message_unref (disconnect_message);
01307
01308 if (disconnect_link != NULL)
01309 _dbus_list_free_link (disconnect_link);
01310
01311 if (connection != NULL)
01312 {
01313 _dbus_condvar_free_at_location (&connection->io_path_cond);
01314 _dbus_condvar_free_at_location (&connection->dispatch_cond);
01315 _dbus_mutex_free_at_location (&connection->mutex);
01316 _dbus_mutex_free_at_location (&connection->io_path_mutex);
01317 _dbus_mutex_free_at_location (&connection->dispatch_mutex);
01318 dbus_free (connection);
01319 }
01320 if (pending_replies)
01321 _dbus_hash_table_unref (pending_replies);
01322
01323 if (watch_list)
01324 _dbus_watch_list_free (watch_list);
01325
01326 if (timeout_list)
01327 _dbus_timeout_list_free (timeout_list);
01328
01329 if (outgoing_counter)
01330 _dbus_counter_unref (outgoing_counter);
01331
01332 if (objects)
01333 _dbus_object_tree_unref (objects);
01334
01335 return NULL;
01336 }
01337
01345 DBusConnection *
01346 _dbus_connection_ref_unlocked (DBusConnection *connection)
01347 {
01348 _dbus_assert (connection != NULL);
01349 _dbus_assert (connection->generation == _dbus_current_generation);
01350
01351 HAVE_LOCK_CHECK (connection);
01352
01353 #ifdef DBUS_HAVE_ATOMIC_INT
01354 _dbus_atomic_inc (&connection->refcount);
01355 #else
01356 _dbus_assert (connection->refcount.value > 0);
01357 connection->refcount.value += 1;
01358 #endif
01359
01360 return connection;
01361 }
01362
01369 void
01370 _dbus_connection_unref_unlocked (DBusConnection *connection)
01371 {
01372 dbus_bool_t last_unref;
01373
01374 HAVE_LOCK_CHECK (connection);
01375
01376 _dbus_assert (connection != NULL);
01377
01378
01379
01380
01381
01382 #ifdef DBUS_HAVE_ATOMIC_INT
01383 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
01384 #else
01385 _dbus_assert (connection->refcount.value > 0);
01386
01387 connection->refcount.value -= 1;
01388 last_unref = (connection->refcount.value == 0);
01389 #if 0
01390 printf ("unref_unlocked() connection %p count = %d\n", connection, connection->refcount.value);
01391 #endif
01392 #endif
01393
01394 if (last_unref)
01395 _dbus_connection_last_unref (connection);
01396 }
01397
01398 static dbus_uint32_t
01399 _dbus_connection_get_next_client_serial (DBusConnection *connection)
01400 {
01401 dbus_uint32_t serial;
01402
01403 serial = connection->client_serial++;
01404
01405 if (connection->client_serial == 0)
01406 connection->client_serial = 1;
01407
01408 return serial;
01409 }
01410
01424 dbus_bool_t
01425 _dbus_connection_handle_watch (DBusWatch *watch,
01426 unsigned int condition,
01427 void *data)
01428 {
01429 DBusConnection *connection;
01430 dbus_bool_t retval;
01431 DBusDispatchStatus status;
01432
01433 connection = data;
01434
01435 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
01436
01437 CONNECTION_LOCK (connection);
01438 _dbus_connection_acquire_io_path (connection, -1);
01439 HAVE_LOCK_CHECK (connection);
01440 retval = _dbus_transport_handle_watch (connection->transport,
01441 watch, condition);
01442
01443 _dbus_connection_release_io_path (connection);
01444
01445 HAVE_LOCK_CHECK (connection);
01446
01447 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
01448
01449 status = _dbus_connection_get_dispatch_status_unlocked (connection);
01450
01451
01452 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01453
01454 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
01455
01456 return retval;
01457 }
01458
01459 _DBUS_DEFINE_GLOBAL_LOCK (shared_connections);
01460 static DBusHashTable *shared_connections = NULL;
01461 static DBusList *shared_connections_no_guid = NULL;
01462
01463 static void
01464 close_connection_on_shutdown (DBusConnection *connection)
01465 {
01466 DBusMessage *message;
01467
01468 dbus_connection_ref (connection);
01469 _dbus_connection_close_possibly_shared (connection);
01470
01471
01472 while ((message = dbus_connection_pop_message (connection)))
01473 {
01474 dbus_message_unref (message);
01475 }
01476 dbus_connection_unref (connection);
01477 }
01478
01479 static void
01480 shared_connections_shutdown (void *data)
01481 {
01482 int n_entries;
01483
01484 _DBUS_LOCK (shared_connections);
01485
01486
01487 while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0)
01488 {
01489 DBusConnection *connection;
01490 DBusHashIter iter;
01491
01492 _dbus_hash_iter_init (shared_connections, &iter);
01493 _dbus_hash_iter_next (&iter);
01494
01495 connection = _dbus_hash_iter_get_value (&iter);
01496
01497 _DBUS_UNLOCK (shared_connections);
01498 close_connection_on_shutdown (connection);
01499 _DBUS_LOCK (shared_connections);
01500
01501
01502 _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) < n_entries);
01503 }
01504
01505 _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) == 0);
01506
01507 _dbus_hash_table_unref (shared_connections);
01508 shared_connections = NULL;
01509
01510 if (shared_connections_no_guid != NULL)
01511 {
01512 DBusConnection *connection;
01513 connection = _dbus_list_pop_first (&shared_connections_no_guid);
01514 while (connection != NULL)
01515 {
01516 _DBUS_UNLOCK (shared_connections);
01517 close_connection_on_shutdown (connection);
01518 _DBUS_LOCK (shared_connections);
01519 connection = _dbus_list_pop_first (&shared_connections_no_guid);
01520 }
01521 }
01522
01523 shared_connections_no_guid = NULL;
01524
01525 _DBUS_UNLOCK (shared_connections);
01526 }
01527
01528 static dbus_bool_t
01529 connection_lookup_shared (DBusAddressEntry *entry,
01530 DBusConnection **result)
01531 {
01532 _dbus_verbose ("checking for existing connection\n");
01533
01534 *result = NULL;
01535
01536 _DBUS_LOCK (shared_connections);
01537
01538 if (shared_connections == NULL)
01539 {
01540 _dbus_verbose ("creating shared_connections hash table\n");
01541
01542 shared_connections = _dbus_hash_table_new (DBUS_HASH_STRING,
01543 dbus_free,
01544 NULL);
01545 if (shared_connections == NULL)
01546 {
01547 _DBUS_UNLOCK (shared_connections);
01548 return FALSE;
01549 }
01550
01551 if (!_dbus_register_shutdown_func (shared_connections_shutdown, NULL))
01552 {
01553 _dbus_hash_table_unref (shared_connections);
01554 shared_connections = NULL;
01555 _DBUS_UNLOCK (shared_connections);
01556 return FALSE;
01557 }
01558
01559 _dbus_verbose (" successfully created shared_connections\n");
01560
01561 _DBUS_UNLOCK (shared_connections);
01562 return TRUE;
01563 }
01564 else
01565 {
01566 const char *guid;
01567
01568 guid = dbus_address_entry_get_value (entry, "guid");
01569
01570 if (guid != NULL)
01571 {
01572 DBusConnection *connection;
01573
01574 connection = _dbus_hash_table_lookup_string (shared_connections,
01575 guid);
01576
01577 if (connection)
01578 {
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593 CONNECTION_LOCK (connection);
01594 if (_dbus_connection_get_is_connected_unlocked (connection))
01595 {
01596 _dbus_connection_ref_unlocked (connection);
01597 *result = connection;
01598 _dbus_verbose ("looked up existing connection to server guid %s\n",
01599 guid);
01600 }
01601 else
01602 {
01603 _dbus_verbose ("looked up existing connection to server guid %s but it was disconnected so ignoring it\n",
01604 guid);
01605 }
01606 CONNECTION_UNLOCK (connection);
01607 }
01608 }
01609
01610 _DBUS_UNLOCK (shared_connections);
01611 return TRUE;
01612 }
01613 }
01614
01615 static dbus_bool_t
01616 connection_record_shared_unlocked (DBusConnection *connection,
01617 const char *guid)
01618 {
01619 char *guid_key;
01620 char *guid_in_connection;
01621
01622 HAVE_LOCK_CHECK (connection);
01623 _dbus_assert (connection->server_guid == NULL);
01624 _dbus_assert (connection->shareable);
01625
01626
01627
01628
01629
01630 _dbus_connection_ref_unlocked (connection);
01631
01632 if (guid == NULL)
01633 {
01634 _DBUS_LOCK (shared_connections);
01635
01636 if (!_dbus_list_prepend (&shared_connections_no_guid, connection))
01637 {
01638 _DBUS_UNLOCK (shared_connections);
01639 return FALSE;
01640 }
01641
01642 _DBUS_UNLOCK (shared_connections);
01643 return TRUE;
01644 }
01645
01646
01647
01648
01649
01650
01651 guid_key = _dbus_strdup (guid);
01652 if (guid_key == NULL)
01653 return FALSE;
01654
01655 guid_in_connection = _dbus_strdup (guid);
01656 if (guid_in_connection == NULL)
01657 {
01658 dbus_free (guid_key);
01659 return FALSE;
01660 }
01661
01662 _DBUS_LOCK (shared_connections);
01663 _dbus_assert (shared_connections != NULL);
01664
01665 if (!_dbus_hash_table_insert_string (shared_connections,
01666 guid_key, connection))
01667 {
01668 dbus_free (guid_key);
01669 dbus_free (guid_in_connection);
01670 _DBUS_UNLOCK (shared_connections);
01671 return FALSE;
01672 }
01673
01674 connection->server_guid = guid_in_connection;
01675
01676 _dbus_verbose ("stored connection to %s to be shared\n",
01677 connection->server_guid);
01678
01679 _DBUS_UNLOCK (shared_connections);
01680
01681 _dbus_assert (connection->server_guid != NULL);
01682
01683 return TRUE;
01684 }
01685
01686 static void
01687 connection_forget_shared_unlocked (DBusConnection *connection)
01688 {
01689 HAVE_LOCK_CHECK (connection);
01690
01691 if (!connection->shareable)
01692 return;
01693
01694 _DBUS_LOCK (shared_connections);
01695
01696 if (connection->server_guid != NULL)
01697 {
01698 _dbus_verbose ("dropping connection to %s out of the shared table\n",
01699 connection->server_guid);
01700
01701 if (!_dbus_hash_table_remove_string (shared_connections,
01702 connection->server_guid))
01703 _dbus_assert_not_reached ("connection was not in the shared table");
01704
01705 dbus_free (connection->server_guid);
01706 connection->server_guid = NULL;
01707 }
01708 else
01709 {
01710 _dbus_list_remove (&shared_connections_no_guid, connection);
01711 }
01712
01713 _DBUS_UNLOCK (shared_connections);
01714
01715
01716 _dbus_connection_unref_unlocked (connection);
01717 }
01718
01719 static DBusConnection*
01720 connection_try_from_address_entry (DBusAddressEntry *entry,
01721 DBusError *error)
01722 {
01723 DBusTransport *transport;
01724 DBusConnection *connection;
01725
01726 transport = _dbus_transport_open (entry, error);
01727
01728 if (transport == NULL)
01729 {
01730 _DBUS_ASSERT_ERROR_IS_SET (error);
01731 return NULL;
01732 }
01733
01734 connection = _dbus_connection_new_for_transport (transport);
01735
01736 _dbus_transport_unref (transport);
01737
01738 if (connection == NULL)
01739 {
01740 _DBUS_SET_OOM (error);
01741 return NULL;
01742 }
01743
01744 #ifndef DBUS_DISABLE_CHECKS
01745 _dbus_assert (!connection->have_connection_lock);
01746 #endif
01747 return connection;
01748 }
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762 static DBusConnection*
01763 _dbus_connection_open_internal (const char *address,
01764 dbus_bool_t shared,
01765 DBusError *error)
01766 {
01767 DBusConnection *connection;
01768 DBusAddressEntry **entries;
01769 DBusError tmp_error = DBUS_ERROR_INIT;
01770 DBusError first_error = DBUS_ERROR_INIT;
01771 int len, i;
01772
01773 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01774
01775 _dbus_verbose ("opening %s connection to: %s\n",
01776 shared ? "shared" : "private", address);
01777
01778 if (!dbus_parse_address (address, &entries, &len, error))
01779 return NULL;
01780
01781 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01782
01783 connection = NULL;
01784
01785 for (i = 0; i < len; i++)
01786 {
01787 if (shared)
01788 {
01789 if (!connection_lookup_shared (entries[i], &connection))
01790 _DBUS_SET_OOM (&tmp_error);
01791 }
01792
01793 if (connection == NULL)
01794 {
01795 connection = connection_try_from_address_entry (entries[i],
01796 &tmp_error);
01797
01798 if (connection != NULL && shared)
01799 {
01800 const char *guid;
01801
01802 connection->shareable = TRUE;
01803
01804
01805 guid = dbus_address_entry_get_value (entries[i], "guid");
01806
01807 CONNECTION_LOCK (connection);
01808
01809 if (!connection_record_shared_unlocked (connection, guid))
01810 {
01811 _DBUS_SET_OOM (&tmp_error);
01812 _dbus_connection_close_possibly_shared_and_unlock (connection);
01813 dbus_connection_unref (connection);
01814 connection = NULL;
01815 }
01816 else
01817 CONNECTION_UNLOCK (connection);
01818 }
01819 }
01820
01821 if (connection)
01822 break;
01823
01824 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
01825
01826 if (i == 0)
01827 dbus_move_error (&tmp_error, &first_error);
01828 else
01829 dbus_error_free (&tmp_error);
01830 }
01831
01832 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01833 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
01834
01835 if (connection == NULL)
01836 {
01837 _DBUS_ASSERT_ERROR_IS_SET (&first_error);
01838 dbus_move_error (&first_error, error);
01839 }
01840 else
01841 dbus_error_free (&first_error);
01842
01843 dbus_address_entries_free (entries);
01844 return connection;
01845 }
01846
01855 void
01856 _dbus_connection_close_possibly_shared (DBusConnection *connection)
01857 {
01858 _dbus_assert (connection != NULL);
01859 _dbus_assert (connection->generation == _dbus_current_generation);
01860
01861 CONNECTION_LOCK (connection);
01862 _dbus_connection_close_possibly_shared_and_unlock (connection);
01863 }
01864
01865 static DBusPreallocatedSend*
01866 _dbus_connection_preallocate_send_unlocked (DBusConnection *connection)
01867 {
01868 DBusPreallocatedSend *preallocated;
01869
01870 HAVE_LOCK_CHECK (connection);
01871
01872 _dbus_assert (connection != NULL);
01873
01874 preallocated = dbus_new (DBusPreallocatedSend, 1);
01875 if (preallocated == NULL)
01876 return NULL;
01877
01878 if (connection->link_cache != NULL)
01879 {
01880 preallocated->queue_link =
01881 _dbus_list_pop_first_link (&connection->link_cache);
01882 preallocated->queue_link->data = NULL;
01883 }
01884 else
01885 {
01886 preallocated->queue_link = _dbus_list_alloc_link (NULL);
01887 if (preallocated->queue_link == NULL)
01888 goto failed_0;
01889 }
01890
01891 if (connection->link_cache != NULL)
01892 {
01893 preallocated->counter_link =
01894 _dbus_list_pop_first_link (&connection->link_cache);
01895 preallocated->counter_link->data = connection->outgoing_counter;
01896 }
01897 else
01898 {
01899 preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter);
01900 if (preallocated->counter_link == NULL)
01901 goto failed_1;
01902 }
01903
01904 _dbus_counter_ref (preallocated->counter_link->data);
01905
01906 preallocated->connection = connection;
01907
01908 return preallocated;
01909
01910 failed_1:
01911 _dbus_list_free_link (preallocated->queue_link);
01912 failed_0:
01913 dbus_free (preallocated);
01914
01915 return NULL;
01916 }
01917
01918
01919 static void
01920 _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *connection,
01921 DBusPreallocatedSend *preallocated,
01922 DBusMessage *message,
01923 dbus_uint32_t *client_serial)
01924 {
01925 dbus_uint32_t serial;
01926 const char *sig;
01927
01928 preallocated->queue_link->data = message;
01929 _dbus_list_prepend_link (&connection->outgoing_messages,
01930 preallocated->queue_link);
01931
01932 _dbus_message_add_size_counter_link (message,
01933 preallocated->counter_link);
01934
01935 dbus_free (preallocated);
01936 preallocated = NULL;
01937
01938 dbus_message_ref (message);
01939
01940 connection->n_outgoing += 1;
01941
01942 sig = dbus_message_get_signature (message);
01943
01944 _dbus_verbose ("Message %p (%d %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
01945 message,
01946 dbus_message_get_type (message),
01947 dbus_message_get_path (message) ?
01948 dbus_message_get_path (message) :
01949 "no path",
01950 dbus_message_get_interface (message) ?
01951 dbus_message_get_interface (message) :
01952 "no interface",
01953 dbus_message_get_member (message) ?
01954 dbus_message_get_member (message) :
01955 "no member",
01956 sig,
01957 dbus_message_get_destination (message) ?
01958 dbus_message_get_destination (message) :
01959 "null",
01960 connection,
01961 connection->n_outgoing);
01962
01963 if (dbus_message_get_serial (message) == 0)
01964 {
01965 serial = _dbus_connection_get_next_client_serial (connection);
01966 dbus_message_set_serial (message, serial);
01967 if (client_serial)
01968 *client_serial = serial;
01969 }
01970 else
01971 {
01972 if (client_serial)
01973 *client_serial = dbus_message_get_serial (message);
01974 }
01975
01976 _dbus_verbose ("Message %p serial is %u\n",
01977 message, dbus_message_get_serial (message));
01978
01979 dbus_message_lock (message);
01980
01981
01982
01983
01984 _dbus_connection_do_iteration_unlocked (connection,
01985 DBUS_ITERATION_DO_WRITING,
01986 -1);
01987
01988
01989 if (connection->n_outgoing > 0)
01990 _dbus_connection_wakeup_mainloop (connection);
01991 }
01992
01993 static void
01994 _dbus_connection_send_preallocated_and_unlock (DBusConnection *connection,
01995 DBusPreallocatedSend *preallocated,
01996 DBusMessage *message,
01997 dbus_uint32_t *client_serial)
01998 {
01999 DBusDispatchStatus status;
02000
02001 HAVE_LOCK_CHECK (connection);
02002
02003 _dbus_connection_send_preallocated_unlocked_no_update (connection,
02004 preallocated,
02005 message, client_serial);
02006
02007 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
02008 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02009
02010
02011 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02012 }
02013
02023 dbus_bool_t
02024 _dbus_connection_send_and_unlock (DBusConnection *connection,
02025 DBusMessage *message,
02026 dbus_uint32_t *client_serial)
02027 {
02028 DBusPreallocatedSend *preallocated;
02029
02030 _dbus_assert (connection != NULL);
02031 _dbus_assert (message != NULL);
02032
02033 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
02034 if (preallocated == NULL)
02035 {
02036 CONNECTION_UNLOCK (connection);
02037 return FALSE;
02038 }
02039
02040 _dbus_connection_send_preallocated_and_unlock (connection,
02041 preallocated,
02042 message,
02043 client_serial);
02044 return TRUE;
02045 }
02046
02071 void
02072 _dbus_connection_close_if_only_one_ref (DBusConnection *connection)
02073 {
02074 CONNECTION_LOCK (connection);
02075
02076 _dbus_assert (connection->refcount.value > 0);
02077
02078 if (connection->refcount.value == 1)
02079 _dbus_connection_close_possibly_shared_and_unlock (connection);
02080 else
02081 CONNECTION_UNLOCK (connection);
02082 }
02083
02084
02094 static void
02095 _dbus_memory_pause_based_on_timeout (int timeout_milliseconds)
02096 {
02097 if (timeout_milliseconds == -1)
02098 _dbus_sleep_milliseconds (1000);
02099 else if (timeout_milliseconds < 100)
02100 ;
02101 else if (timeout_milliseconds <= 1000)
02102 _dbus_sleep_milliseconds (timeout_milliseconds / 3);
02103 else
02104 _dbus_sleep_milliseconds (1000);
02105 }
02106
02107 static DBusMessage *
02108 generate_local_error_message (dbus_uint32_t serial,
02109 char *error_name,
02110 char *error_msg)
02111 {
02112 DBusMessage *message;
02113 message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
02114 if (!message)
02115 goto out;
02116
02117 if (!dbus_message_set_error_name (message, error_name))
02118 {
02119 dbus_message_unref (message);
02120 message = NULL;
02121 goto out;
02122 }
02123
02124 dbus_message_set_no_reply (message, TRUE);
02125
02126 if (!dbus_message_set_reply_serial (message,
02127 serial))
02128 {
02129 dbus_message_unref (message);
02130 message = NULL;
02131 goto out;
02132 }
02133
02134 if (error_msg != NULL)
02135 {
02136 DBusMessageIter iter;
02137
02138 dbus_message_iter_init_append (message, &iter);
02139 if (!dbus_message_iter_append_basic (&iter,
02140 DBUS_TYPE_STRING,
02141 &error_msg))
02142 {
02143 dbus_message_unref (message);
02144 message = NULL;
02145 goto out;
02146 }
02147 }
02148
02149 out:
02150 return message;
02151 }
02152
02153
02154
02155
02156
02157 static DBusMessage*
02158 check_for_reply_unlocked (DBusConnection *connection,
02159 dbus_uint32_t client_serial)
02160 {
02161 DBusList *link;
02162
02163 HAVE_LOCK_CHECK (connection);
02164
02165 link = _dbus_list_get_first_link (&connection->incoming_messages);
02166
02167 while (link != NULL)
02168 {
02169 DBusMessage *reply = link->data;
02170
02171 if (dbus_message_get_reply_serial (reply) == client_serial)
02172 {
02173 _dbus_list_remove_link (&connection->incoming_messages, link);
02174 connection->n_incoming -= 1;
02175 return reply;
02176 }
02177 link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02178 }
02179
02180 return NULL;
02181 }
02182
02183 static void
02184 connection_timeout_and_complete_all_pending_calls_unlocked (DBusConnection *connection)
02185 {
02186
02187
02188
02189
02190
02191 while (_dbus_hash_table_get_n_entries (connection->pending_replies) > 0)
02192 {
02193 DBusPendingCall *pending;
02194 DBusHashIter iter;
02195
02196 _dbus_hash_iter_init (connection->pending_replies, &iter);
02197 _dbus_hash_iter_next (&iter);
02198
02199 pending = _dbus_hash_iter_get_value (&iter);
02200 _dbus_pending_call_ref_unlocked (pending);
02201
02202 _dbus_pending_call_queue_timeout_error_unlocked (pending,
02203 connection);
02204
02205 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
02206 _dbus_connection_remove_timeout_unlocked (connection,
02207 _dbus_pending_call_get_timeout_unlocked (pending));
02208 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
02209 _dbus_hash_iter_remove_entry (&iter);
02210
02211 _dbus_pending_call_unref_and_unlock (pending);
02212 CONNECTION_LOCK (connection);
02213 }
02214 HAVE_LOCK_CHECK (connection);
02215 }
02216
02217 static void
02218 complete_pending_call_and_unlock (DBusConnection *connection,
02219 DBusPendingCall *pending,
02220 DBusMessage *message)
02221 {
02222 _dbus_pending_call_set_reply_unlocked (pending, message);
02223 _dbus_pending_call_ref_unlocked (pending);
02224 _dbus_connection_detach_pending_call_and_unlock (connection, pending);
02225
02226
02227 _dbus_pending_call_complete (pending);
02228 dbus_pending_call_unref (pending);
02229 }
02230
02231 static dbus_bool_t
02232 check_for_reply_and_update_dispatch_unlocked (DBusConnection *connection,
02233 DBusPendingCall *pending)
02234 {
02235 DBusMessage *reply;
02236 DBusDispatchStatus status;
02237
02238 reply = check_for_reply_unlocked (connection,
02239 _dbus_pending_call_get_reply_serial_unlocked (pending));
02240 if (reply != NULL)
02241 {
02242 _dbus_verbose ("%s checked for reply\n", _DBUS_FUNCTION_NAME);
02243
02244 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
02245
02246 complete_pending_call_and_unlock (connection, pending, reply);
02247 dbus_message_unref (reply);
02248
02249 CONNECTION_LOCK (connection);
02250 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02251 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02252 dbus_pending_call_unref (pending);
02253
02254 return TRUE;
02255 }
02256
02257 return FALSE;
02258 }
02259
02274 void
02275 _dbus_connection_block_pending_call (DBusPendingCall *pending)
02276 {
02277 long start_tv_sec, start_tv_usec;
02278 long tv_sec, tv_usec;
02279 DBusDispatchStatus status;
02280 DBusConnection *connection;
02281 dbus_uint32_t client_serial;
02282 DBusTimeout *timeout;
02283 int timeout_milliseconds, elapsed_milliseconds;
02284
02285 _dbus_assert (pending != NULL);
02286
02287 if (dbus_pending_call_get_completed (pending))
02288 return;
02289
02290 dbus_pending_call_ref (pending);
02291
02292 connection = _dbus_pending_call_get_connection_and_lock (pending);
02293
02294
02295 _dbus_connection_flush_unlocked (connection);
02296
02297 client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
02298
02299
02300
02301
02302
02303 timeout = _dbus_pending_call_get_timeout_unlocked (pending);
02304 if (timeout)
02305 {
02306 timeout_milliseconds = dbus_timeout_get_interval (timeout);
02307 _dbus_get_current_time (&start_tv_sec, &start_tv_usec);
02308
02309 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec\n",
02310 timeout_milliseconds,
02311 client_serial,
02312 start_tv_sec, start_tv_usec);
02313 }
02314 else
02315 {
02316 timeout_milliseconds = -1;
02317
02318 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block for reply serial %u\n", client_serial);
02319 }
02320
02321
02322
02323 if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02324 return;
02325
02326
02327
02328 _dbus_connection_do_iteration_unlocked (connection,
02329 DBUS_ITERATION_DO_READING |
02330 DBUS_ITERATION_BLOCK,
02331 timeout_milliseconds);
02332
02333 recheck_status:
02334
02335 _dbus_verbose ("%s top of recheck\n", _DBUS_FUNCTION_NAME);
02336
02337 HAVE_LOCK_CHECK (connection);
02338
02339
02340
02341 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02342
02343
02344
02345
02346 if (_dbus_pending_call_get_completed_unlocked (pending))
02347 {
02348 _dbus_verbose ("Pending call completed by dispatch in %s\n", _DBUS_FUNCTION_NAME);
02349 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02350 dbus_pending_call_unref (pending);
02351 return;
02352 }
02353
02354 if (status == DBUS_DISPATCH_DATA_REMAINS)
02355 {
02356 if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02357 return;
02358 }
02359
02360 _dbus_get_current_time (&tv_sec, &tv_usec);
02361 elapsed_milliseconds = (tv_sec - start_tv_sec) * 1000 +
02362 (tv_usec - start_tv_usec) / 1000;
02363
02364 if (!_dbus_connection_get_is_connected_unlocked (connection))
02365 {
02366 DBusMessage *error_msg;
02367
02368 error_msg = generate_local_error_message (client_serial,
02369 DBUS_ERROR_DISCONNECTED,
02370 "Connection was disconnected before a reply was received");
02371
02372
02373 complete_pending_call_and_unlock (connection, pending, error_msg);
02374 dbus_pending_call_unref (pending);
02375 return;
02376 }
02377 else if (connection->disconnect_message_link == NULL)
02378 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
02379 else if (timeout == NULL)
02380 {
02381 if (status == DBUS_DISPATCH_NEED_MEMORY)
02382 {
02383
02384
02385
02386
02387 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02388
02389 _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
02390 }
02391 else
02392 {
02393
02394 _dbus_connection_do_iteration_unlocked (connection,
02395 DBUS_ITERATION_DO_READING |
02396 DBUS_ITERATION_BLOCK,
02397 timeout_milliseconds);
02398 }
02399
02400 goto recheck_status;
02401 }
02402 else if (tv_sec < start_tv_sec)
02403 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
02404 else if (elapsed_milliseconds < timeout_milliseconds)
02405 {
02406 timeout_milliseconds -= elapsed_milliseconds;
02407 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds);
02408 _dbus_assert (timeout_milliseconds >= 0);
02409
02410 if (status == DBUS_DISPATCH_NEED_MEMORY)
02411 {
02412
02413
02414
02415
02416 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02417
02418 _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
02419 }
02420 else
02421 {
02422
02423 _dbus_connection_do_iteration_unlocked (connection,
02424 DBUS_ITERATION_DO_READING |
02425 DBUS_ITERATION_BLOCK,
02426 timeout_milliseconds);
02427 }
02428
02429 goto recheck_status;
02430 }
02431
02432 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %ld milliseconds and got no reply\n",
02433 (tv_sec - start_tv_sec) * 1000 + (tv_usec - start_tv_usec) / 1000);
02434
02435 _dbus_assert (!_dbus_pending_call_get_completed_unlocked (pending));
02436
02437
02438 complete_pending_call_and_unlock (connection, pending, NULL);
02439
02440
02441 CONNECTION_LOCK (connection);
02442 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02443 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02444 dbus_pending_call_unref (pending);
02445 }
02446
02483 DBusConnection*
02484 dbus_connection_open (const char *address,
02485 DBusError *error)
02486 {
02487 DBusConnection *connection;
02488
02489 _dbus_return_val_if_fail (address != NULL, NULL);
02490 _dbus_return_val_if_error_is_set (error, NULL);
02491
02492 connection = _dbus_connection_open_internal (address,
02493 TRUE,
02494 error);
02495
02496 return connection;
02497 }
02498
02526 DBusConnection*
02527 dbus_connection_open_private (const char *address,
02528 DBusError *error)
02529 {
02530 DBusConnection *connection;
02531
02532 _dbus_return_val_if_fail (address != NULL, NULL);
02533 _dbus_return_val_if_error_is_set (error, NULL);
02534
02535 connection = _dbus_connection_open_internal (address,
02536 FALSE,
02537 error);
02538
02539 return connection;
02540 }
02541
02548 DBusConnection *
02549 dbus_connection_ref (DBusConnection *connection)
02550 {
02551 _dbus_return_val_if_fail (connection != NULL, NULL);
02552 _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
02553
02554
02555
02556
02557
02558 #ifdef DBUS_HAVE_ATOMIC_INT
02559 _dbus_atomic_inc (&connection->refcount);
02560 #else
02561 CONNECTION_LOCK (connection);
02562 _dbus_assert (connection->refcount.value > 0);
02563
02564 connection->refcount.value += 1;
02565 CONNECTION_UNLOCK (connection);
02566 #endif
02567
02568 return connection;
02569 }
02570
02571 static void
02572 free_outgoing_message (void *element,
02573 void *data)
02574 {
02575 DBusMessage *message = element;
02576 DBusConnection *connection = data;
02577
02578 _dbus_message_remove_size_counter (message,
02579 connection->outgoing_counter,
02580 NULL);
02581 dbus_message_unref (message);
02582 }
02583
02584
02585
02586
02587
02588 static void
02589 _dbus_connection_last_unref (DBusConnection *connection)
02590 {
02591 DBusList *link;
02592
02593 _dbus_verbose ("Finalizing connection %p\n", connection);
02594
02595 _dbus_assert (connection->refcount.value == 0);
02596
02597
02598
02599
02600 _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
02601 _dbus_assert (connection->server_guid == NULL);
02602
02603
02604 _dbus_object_tree_free_all_unlocked (connection->objects);
02605
02606 dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
02607 dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
02608 dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
02609
02610 _dbus_watch_list_free (connection->watches);
02611 connection->watches = NULL;
02612
02613 _dbus_timeout_list_free (connection->timeouts);
02614 connection->timeouts = NULL;
02615
02616 _dbus_data_slot_list_free (&connection->slot_list);
02617
02618 link = _dbus_list_get_first_link (&connection->filter_list);
02619 while (link != NULL)
02620 {
02621 DBusMessageFilter *filter = link->data;
02622 DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
02623
02624 filter->function = NULL;
02625 _dbus_message_filter_unref (filter);
02626 link->data = NULL;
02627
02628 link = next;
02629 }
02630 _dbus_list_clear (&connection->filter_list);
02631
02632
02633
02634 _dbus_object_tree_unref (connection->objects);
02635
02636 _dbus_hash_table_unref (connection->pending_replies);
02637 connection->pending_replies = NULL;
02638
02639 _dbus_list_clear (&connection->filter_list);
02640
02641 _dbus_list_foreach (&connection->outgoing_messages,
02642 free_outgoing_message,
02643 connection);
02644 _dbus_list_clear (&connection->outgoing_messages);
02645
02646 _dbus_list_foreach (&connection->incoming_messages,
02647 (DBusForeachFunction) dbus_message_unref,
02648 NULL);
02649 _dbus_list_clear (&connection->incoming_messages);
02650
02651 _dbus_counter_unref (connection->outgoing_counter);
02652
02653 _dbus_transport_unref (connection->transport);
02654
02655 if (connection->disconnect_message_link)
02656 {
02657 DBusMessage *message = connection->disconnect_message_link->data;
02658 dbus_message_unref (message);
02659 _dbus_list_free_link (connection->disconnect_message_link);
02660 }
02661
02662 _dbus_list_clear (&connection->link_cache);
02663
02664 _dbus_condvar_free_at_location (&connection->dispatch_cond);
02665 _dbus_condvar_free_at_location (&connection->io_path_cond);
02666
02667 _dbus_mutex_free_at_location (&connection->io_path_mutex);
02668 _dbus_mutex_free_at_location (&connection->dispatch_mutex);
02669
02670 _dbus_mutex_free_at_location (&connection->mutex);
02671
02672 dbus_free (connection);
02673 }
02674
02694 void
02695 dbus_connection_unref (DBusConnection *connection)
02696 {
02697 dbus_bool_t last_unref;
02698
02699 _dbus_return_if_fail (connection != NULL);
02700 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02701
02702
02703
02704
02705
02706 #ifdef DBUS_HAVE_ATOMIC_INT
02707 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
02708 #else
02709 CONNECTION_LOCK (connection);
02710
02711 _dbus_assert (connection->refcount.value > 0);
02712
02713 connection->refcount.value -= 1;
02714 last_unref = (connection->refcount.value == 0);
02715
02716 #if 0
02717 printf ("unref() connection %p count = %d\n", connection, connection->refcount.value);
02718 #endif
02719
02720 CONNECTION_UNLOCK (connection);
02721 #endif
02722
02723 if (last_unref)
02724 {
02725 #ifndef DBUS_DISABLE_CHECKS
02726 if (_dbus_transport_get_is_connected (connection->transport))
02727 {
02728 _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",
02729 connection->shareable ?
02730 "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" :
02731 "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n");
02732 return;
02733 }
02734 #endif
02735 _dbus_connection_last_unref (connection);
02736 }
02737 }
02738
02739
02740
02741
02742
02743
02744
02745
02746
02747
02748 static void
02749 _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection)
02750 {
02751 DBusDispatchStatus status;
02752
02753 HAVE_LOCK_CHECK (connection);
02754
02755 _dbus_verbose ("Disconnecting %p\n", connection);
02756
02757
02758
02759
02760
02761 _dbus_connection_ref_unlocked (connection);
02762
02763 _dbus_transport_disconnect (connection->transport);
02764
02765
02766
02767
02768
02769
02770
02771
02772
02773
02774 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02775
02776
02777 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02778
02779
02780 dbus_connection_unref (connection);
02781 }
02782
02825 void
02826 dbus_connection_close (DBusConnection *connection)
02827 {
02828 _dbus_return_if_fail (connection != NULL);
02829 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02830
02831 CONNECTION_LOCK (connection);
02832
02833 #ifndef DBUS_DISABLE_CHECKS
02834 if (connection->shareable)
02835 {
02836 CONNECTION_UNLOCK (connection);
02837
02838 _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n");
02839 return;
02840 }
02841 #endif
02842
02843 _dbus_connection_close_possibly_shared_and_unlock (connection);
02844 }
02845
02846 static dbus_bool_t
02847 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
02848 {
02849 HAVE_LOCK_CHECK (connection);
02850 return _dbus_transport_get_is_connected (connection->transport);
02851 }
02852
02866 dbus_bool_t
02867 dbus_connection_get_is_connected (DBusConnection *connection)
02868 {
02869 dbus_bool_t res;
02870
02871 _dbus_return_val_if_fail (connection != NULL, FALSE);
02872
02873 CONNECTION_LOCK (connection);
02874 res = _dbus_connection_get_is_connected_unlocked (connection);
02875 CONNECTION_UNLOCK (connection);
02876
02877 return res;
02878 }
02879
02888 dbus_bool_t
02889 dbus_connection_get_is_authenticated (DBusConnection *connection)
02890 {
02891 dbus_bool_t res;
02892
02893 _dbus_return_val_if_fail (connection != NULL, FALSE);
02894
02895 CONNECTION_LOCK (connection);
02896 res = _dbus_transport_get_is_authenticated (connection->transport);
02897 CONNECTION_UNLOCK (connection);
02898
02899 return res;
02900 }
02901
02922 dbus_bool_t
02923 dbus_connection_get_is_anonymous (DBusConnection *connection)
02924 {
02925 dbus_bool_t res;
02926
02927 _dbus_return_val_if_fail (connection != NULL, FALSE);
02928
02929 CONNECTION_LOCK (connection);
02930 res = _dbus_transport_get_is_anonymous (connection->transport);
02931 CONNECTION_UNLOCK (connection);
02932
02933 return res;
02934 }
02935
02967 char*
02968 dbus_connection_get_server_id (DBusConnection *connection)
02969 {
02970 char *id;
02971
02972 _dbus_return_val_if_fail (connection != NULL, NULL);
02973
02974 CONNECTION_LOCK (connection);
02975 id = _dbus_strdup (_dbus_transport_get_server_id (connection->transport));
02976 CONNECTION_UNLOCK (connection);
02977
02978 return id;
02979 }
02980
02994 void
02995 dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
02996 dbus_bool_t exit_on_disconnect)
02997 {
02998 _dbus_return_if_fail (connection != NULL);
02999
03000 CONNECTION_LOCK (connection);
03001 connection->exit_on_disconnect = exit_on_disconnect != FALSE;
03002 CONNECTION_UNLOCK (connection);
03003 }
03004
03014 DBusPreallocatedSend*
03015 dbus_connection_preallocate_send (DBusConnection *connection)
03016 {
03017 DBusPreallocatedSend *preallocated;
03018
03019 _dbus_return_val_if_fail (connection != NULL, NULL);
03020
03021 CONNECTION_LOCK (connection);
03022
03023 preallocated =
03024 _dbus_connection_preallocate_send_unlocked (connection);
03025
03026 CONNECTION_UNLOCK (connection);
03027
03028 return preallocated;
03029 }
03030
03040 void
03041 dbus_connection_free_preallocated_send (DBusConnection *connection,
03042 DBusPreallocatedSend *preallocated)
03043 {
03044 _dbus_return_if_fail (connection != NULL);
03045 _dbus_return_if_fail (preallocated != NULL);
03046 _dbus_return_if_fail (connection == preallocated->connection);
03047
03048 _dbus_list_free_link (preallocated->queue_link);
03049 _dbus_counter_unref (preallocated->counter_link->data);
03050 _dbus_list_free_link (preallocated->counter_link);
03051 dbus_free (preallocated);
03052 }
03053
03066 void
03067 dbus_connection_send_preallocated (DBusConnection *connection,
03068 DBusPreallocatedSend *preallocated,
03069 DBusMessage *message,
03070 dbus_uint32_t *client_serial)
03071 {
03072 _dbus_return_if_fail (connection != NULL);
03073 _dbus_return_if_fail (preallocated != NULL);
03074 _dbus_return_if_fail (message != NULL);
03075 _dbus_return_if_fail (preallocated->connection == connection);
03076 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
03077 dbus_message_get_member (message) != NULL);
03078 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
03079 (dbus_message_get_interface (message) != NULL &&
03080 dbus_message_get_member (message) != NULL));
03081
03082 CONNECTION_LOCK (connection);
03083 _dbus_connection_send_preallocated_and_unlock (connection,
03084 preallocated,
03085 message, client_serial);
03086 }
03087
03088 static dbus_bool_t
03089 _dbus_connection_send_unlocked_no_update (DBusConnection *connection,
03090 DBusMessage *message,
03091 dbus_uint32_t *client_serial)
03092 {
03093 DBusPreallocatedSend *preallocated;
03094
03095 _dbus_assert (connection != NULL);
03096 _dbus_assert (message != NULL);
03097
03098 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
03099 if (preallocated == NULL)
03100 return FALSE;
03101
03102 _dbus_connection_send_preallocated_unlocked_no_update (connection,
03103 preallocated,
03104 message,
03105 client_serial);
03106 return TRUE;
03107 }
03108
03136 dbus_bool_t
03137 dbus_connection_send (DBusConnection *connection,
03138 DBusMessage *message,
03139 dbus_uint32_t *serial)
03140 {
03141 _dbus_return_val_if_fail (connection != NULL, FALSE);
03142 _dbus_return_val_if_fail (message != NULL, FALSE);
03143
03144 CONNECTION_LOCK (connection);
03145
03146 return _dbus_connection_send_and_unlock (connection,
03147 message,
03148 serial);
03149 }
03150
03151 static dbus_bool_t
03152 reply_handler_timeout (void *data)
03153 {
03154 DBusConnection *connection;
03155 DBusDispatchStatus status;
03156 DBusPendingCall *pending = data;
03157
03158 connection = _dbus_pending_call_get_connection_and_lock (pending);
03159
03160 _dbus_pending_call_queue_timeout_error_unlocked (pending,
03161 connection);
03162 _dbus_connection_remove_timeout_unlocked (connection,
03163 _dbus_pending_call_get_timeout_unlocked (pending));
03164 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
03165
03166 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
03167 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03168
03169
03170 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03171
03172 return TRUE;
03173 }
03174
03210 dbus_bool_t
03211 dbus_connection_send_with_reply (DBusConnection *connection,
03212 DBusMessage *message,
03213 DBusPendingCall **pending_return,
03214 int timeout_milliseconds)
03215 {
03216 DBusPendingCall *pending;
03217 dbus_int32_t serial = -1;
03218 DBusDispatchStatus status;
03219
03220 _dbus_return_val_if_fail (connection != NULL, FALSE);
03221 _dbus_return_val_if_fail (message != NULL, FALSE);
03222 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03223
03224 if (pending_return)
03225 *pending_return = NULL;
03226
03227 CONNECTION_LOCK (connection);
03228
03229 if (!_dbus_connection_get_is_connected_unlocked (connection))
03230 {
03231 CONNECTION_UNLOCK (connection);
03232
03233 return TRUE;
03234 }
03235
03236 pending = _dbus_pending_call_new_unlocked (connection,
03237 timeout_milliseconds,
03238 reply_handler_timeout);
03239
03240 if (pending == NULL)
03241 {
03242 CONNECTION_UNLOCK (connection);
03243 return FALSE;
03244 }
03245
03246
03247 serial = dbus_message_get_serial (message);
03248 if (serial == 0)
03249 {
03250 serial = _dbus_connection_get_next_client_serial (connection);
03251 dbus_message_set_serial (message, serial);
03252 }
03253
03254 if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
03255 goto error;
03256
03257
03258
03259
03260
03261 if (!_dbus_connection_attach_pending_call_unlocked (connection,
03262 pending))
03263 goto error;
03264
03265 if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
03266 {
03267 _dbus_connection_detach_pending_call_and_unlock (connection,
03268 pending);
03269 goto error_unlocked;
03270 }
03271
03272 if (pending_return)
03273 *pending_return = pending;
03274 else
03275 {
03276 _dbus_connection_detach_pending_call_unlocked (connection, pending);
03277
03278
03279
03280 }
03281
03282 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03283
03284
03285 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03286
03287 if (pending_return == NULL)
03288 dbus_pending_call_unref (pending);
03289
03290 return TRUE;
03291
03292 error:
03293 CONNECTION_UNLOCK (connection);
03294 error_unlocked:
03295 dbus_pending_call_unref (pending);
03296 return FALSE;
03297 }
03298
03329 DBusMessage*
03330 dbus_connection_send_with_reply_and_block (DBusConnection *connection,
03331 DBusMessage *message,
03332 int timeout_milliseconds,
03333 DBusError *error)
03334 {
03335 DBusMessage *reply;
03336 DBusPendingCall *pending;
03337
03338 _dbus_return_val_if_fail (connection != NULL, NULL);
03339 _dbus_return_val_if_fail (message != NULL, NULL);
03340 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL);
03341 _dbus_return_val_if_error_is_set (error, NULL);
03342
03343 if (!dbus_connection_send_with_reply (connection, message,
03344 &pending, timeout_milliseconds))
03345 {
03346 _DBUS_SET_OOM (error);
03347 return NULL;
03348 }
03349
03350 if (pending == NULL)
03351 {
03352 dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Connection is closed");
03353 return NULL;
03354 }
03355
03356 dbus_pending_call_block (pending);
03357
03358 reply = dbus_pending_call_steal_reply (pending);
03359 dbus_pending_call_unref (pending);
03360
03361
03362
03363
03364 _dbus_assert (reply != NULL);
03365
03366 if (dbus_set_error_from_message (error, reply))
03367 {
03368 dbus_message_unref (reply);
03369 return NULL;
03370 }
03371 else
03372 return reply;
03373 }
03374
03383 static DBusDispatchStatus
03384 _dbus_connection_flush_unlocked (DBusConnection *connection)
03385 {
03386
03387
03388
03389
03390
03391 DBusDispatchStatus status;
03392
03393 HAVE_LOCK_CHECK (connection);
03394
03395 while (connection->n_outgoing > 0 &&
03396 _dbus_connection_get_is_connected_unlocked (connection))
03397 {
03398 _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME);
03399 HAVE_LOCK_CHECK (connection);
03400 _dbus_connection_do_iteration_unlocked (connection,
03401 DBUS_ITERATION_DO_READING |
03402 DBUS_ITERATION_DO_WRITING |
03403 DBUS_ITERATION_BLOCK,
03404 -1);
03405 }
03406
03407 HAVE_LOCK_CHECK (connection);
03408 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
03409 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03410
03411 HAVE_LOCK_CHECK (connection);
03412 return status;
03413 }
03414
03420 void
03421 dbus_connection_flush (DBusConnection *connection)
03422 {
03423
03424
03425
03426
03427
03428 DBusDispatchStatus status;
03429
03430 _dbus_return_if_fail (connection != NULL);
03431
03432 CONNECTION_LOCK (connection);
03433
03434 status = _dbus_connection_flush_unlocked (connection);
03435
03436 HAVE_LOCK_CHECK (connection);
03437
03438 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03439
03440 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
03441 }
03442
03453 static dbus_bool_t
03454 _dbus_connection_read_write_dispatch (DBusConnection *connection,
03455 int timeout_milliseconds,
03456 dbus_bool_t dispatch)
03457 {
03458 DBusDispatchStatus dstatus;
03459 dbus_bool_t progress_possible;
03460
03461
03462
03463
03464
03465 dbus_connection_ref (connection);
03466 dstatus = dbus_connection_get_dispatch_status (connection);
03467
03468 if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
03469 {
03470 _dbus_verbose ("doing dispatch in %s\n", _DBUS_FUNCTION_NAME);
03471 dbus_connection_dispatch (connection);
03472 CONNECTION_LOCK (connection);
03473 }
03474 else if (dstatus == DBUS_DISPATCH_NEED_MEMORY)
03475 {
03476 _dbus_verbose ("pausing for memory in %s\n", _DBUS_FUNCTION_NAME);
03477 _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
03478 CONNECTION_LOCK (connection);
03479 }
03480 else
03481 {
03482 CONNECTION_LOCK (connection);
03483 if (_dbus_connection_get_is_connected_unlocked (connection))
03484 {
03485 _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME);
03486 _dbus_connection_do_iteration_unlocked (connection,
03487 DBUS_ITERATION_DO_READING |
03488 DBUS_ITERATION_DO_WRITING |
03489 DBUS_ITERATION_BLOCK,
03490 timeout_milliseconds);
03491 }
03492 }
03493
03494 HAVE_LOCK_CHECK (connection);
03495
03496
03497
03498
03499 if (dispatch)
03500 progress_possible = connection->n_incoming != 0 ||
03501 connection->disconnect_message_link != NULL;
03502 else
03503 progress_possible = _dbus_connection_get_is_connected_unlocked (connection);
03504
03505 CONNECTION_UNLOCK (connection);
03506
03507 dbus_connection_unref (connection);
03508
03509 return progress_possible;
03510 }
03511
03512
03547 dbus_bool_t
03548 dbus_connection_read_write_dispatch (DBusConnection *connection,
03549 int timeout_milliseconds)
03550 {
03551 _dbus_return_val_if_fail (connection != NULL, FALSE);
03552 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03553 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE);
03554 }
03555
03579 dbus_bool_t
03580 dbus_connection_read_write (DBusConnection *connection,
03581 int timeout_milliseconds)
03582 {
03583 _dbus_return_val_if_fail (connection != NULL, FALSE);
03584 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03585 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE);
03586 }
03587
03588
03589
03590
03591
03592
03593 static void
03594 check_disconnected_message_arrived_unlocked (DBusConnection *connection,
03595 DBusMessage *head_of_queue)
03596 {
03597 HAVE_LOCK_CHECK (connection);
03598
03599
03600 if (connection->disconnect_message_link == NULL &&
03601 dbus_message_is_signal (head_of_queue,
03602 DBUS_INTERFACE_LOCAL,
03603 "Disconnected"))
03604 {
03605 connection->disconnected_message_arrived = TRUE;
03606 }
03607 }
03608
03628 DBusMessage*
03629 dbus_connection_borrow_message (DBusConnection *connection)
03630 {
03631 DBusDispatchStatus status;
03632 DBusMessage *message;
03633
03634 _dbus_return_val_if_fail (connection != NULL, NULL);
03635
03636 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
03637
03638
03639
03640
03641 status = dbus_connection_get_dispatch_status (connection);
03642 if (status != DBUS_DISPATCH_DATA_REMAINS)
03643 return NULL;
03644
03645 CONNECTION_LOCK (connection);
03646
03647 _dbus_connection_acquire_dispatch (connection);
03648
03649
03650 _dbus_assert (connection->message_borrowed == NULL);
03651
03652 connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
03653
03654 message = connection->message_borrowed;
03655
03656 check_disconnected_message_arrived_unlocked (connection, message);
03657
03658
03659 if (message == NULL)
03660 _dbus_connection_release_dispatch (connection);
03661
03662 CONNECTION_UNLOCK (connection);
03663
03664
03665
03666 return message;
03667 }
03668
03677 void
03678 dbus_connection_return_message (DBusConnection *connection,
03679 DBusMessage *message)
03680 {
03681 DBusDispatchStatus status;
03682
03683 _dbus_return_if_fail (connection != NULL);
03684 _dbus_return_if_fail (message != NULL);
03685 _dbus_return_if_fail (message == connection->message_borrowed);
03686 _dbus_return_if_fail (connection->dispatch_acquired);
03687
03688 CONNECTION_LOCK (connection);
03689
03690 _dbus_assert (message == connection->message_borrowed);
03691
03692 connection->message_borrowed = NULL;
03693
03694 _dbus_connection_release_dispatch (connection);
03695
03696 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03697 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03698 }
03699
03709 void
03710 dbus_connection_steal_borrowed_message (DBusConnection *connection,
03711 DBusMessage *message)
03712 {
03713 DBusMessage *pop_message;
03714 DBusDispatchStatus status;
03715
03716 _dbus_return_if_fail (connection != NULL);
03717 _dbus_return_if_fail (message != NULL);
03718 _dbus_return_if_fail (message == connection->message_borrowed);
03719 _dbus_return_if_fail (connection->dispatch_acquired);
03720
03721 CONNECTION_LOCK (connection);
03722
03723 _dbus_assert (message == connection->message_borrowed);
03724
03725 pop_message = _dbus_list_pop_first (&connection->incoming_messages);
03726 _dbus_assert (message == pop_message);
03727
03728 connection->n_incoming -= 1;
03729
03730 _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
03731 message, connection->n_incoming);
03732
03733 connection->message_borrowed = NULL;
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
03741
03742
03743
03744 static DBusList*
03745 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
03746 {
03747 HAVE_LOCK_CHECK (connection);
03748
03749 _dbus_assert (connection->message_borrowed == NULL);
03750
03751 if (connection->n_incoming > 0)
03752 {
03753 DBusList *link;
03754
03755 link = _dbus_list_pop_first_link (&connection->incoming_messages);
03756 connection->n_incoming -= 1;
03757
03758 _dbus_verbose ("Message %p (%d %s %s %s '%s') removed from incoming queue %p, %d incoming\n",
03759 link->data,
03760 dbus_message_get_type (link->data),
03761 dbus_message_get_path (link->data) ?
03762 dbus_message_get_path (link->data) :
03763 "no path",
03764 dbus_message_get_interface (link->data) ?
03765 dbus_message_get_interface (link->data) :
03766 "no interface",
03767 dbus_message_get_member (link->data) ?
03768 dbus_message_get_member (link->data) :
03769 "no member",
03770 dbus_message_get_signature (link->data),
03771 connection, connection->n_incoming);
03772
03773 check_disconnected_message_arrived_unlocked (connection, link->data);
03774
03775 return link;
03776 }
03777 else
03778 return NULL;
03779 }
03780
03781
03782
03783
03784 static DBusMessage*
03785 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
03786 {
03787 DBusList *link;
03788
03789 HAVE_LOCK_CHECK (connection);
03790
03791 link = _dbus_connection_pop_message_link_unlocked (connection);
03792
03793 if (link != NULL)
03794 {
03795 DBusMessage *message;
03796
03797 message = link->data;
03798
03799 _dbus_list_free_link (link);
03800
03801 return message;
03802 }
03803 else
03804 return NULL;
03805 }
03806
03807 static void
03808 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
03809 DBusList *message_link)
03810 {
03811 HAVE_LOCK_CHECK (connection);
03812
03813 _dbus_assert (message_link != NULL);
03814
03815 _dbus_assert (connection->message_borrowed == NULL);
03816
03817 _dbus_assert (connection->dispatch_acquired);
03818
03819 _dbus_list_prepend_link (&connection->incoming_messages,
03820 message_link);
03821 connection->n_incoming += 1;
03822
03823 _dbus_verbose ("Message %p (%d %s %s '%s') put back into queue %p, %d incoming\n",
03824 message_link->data,
03825 dbus_message_get_type (message_link->data),
03826 dbus_message_get_interface (message_link->data) ?
03827 dbus_message_get_interface (message_link->data) :
03828 "no interface",
03829 dbus_message_get_member (message_link->data) ?
03830 dbus_message_get_member (message_link->data) :
03831 "no member",
03832 dbus_message_get_signature (message_link->data),
03833 connection, connection->n_incoming);
03834 }
03835
03855 DBusMessage*
03856 dbus_connection_pop_message (DBusConnection *connection)
03857 {
03858 DBusMessage *message;
03859 DBusDispatchStatus status;
03860
03861 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
03862
03863
03864
03865
03866 status = dbus_connection_get_dispatch_status (connection);
03867 if (status != DBUS_DISPATCH_DATA_REMAINS)
03868 return NULL;
03869
03870 CONNECTION_LOCK (connection);
03871 _dbus_connection_acquire_dispatch (connection);
03872 HAVE_LOCK_CHECK (connection);
03873
03874 message = _dbus_connection_pop_message_unlocked (connection);
03875
03876 _dbus_verbose ("Returning popped message %p\n", message);
03877
03878 _dbus_connection_release_dispatch (connection);
03879
03880 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03881 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03882
03883 return message;
03884 }
03885
03893 static void
03894 _dbus_connection_acquire_dispatch (DBusConnection *connection)
03895 {
03896 HAVE_LOCK_CHECK (connection);
03897
03898 _dbus_connection_ref_unlocked (connection);
03899 CONNECTION_UNLOCK (connection);
03900
03901 _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03902 _dbus_mutex_lock (connection->dispatch_mutex);
03903
03904 while (connection->dispatch_acquired)
03905 {
03906 _dbus_verbose ("%s waiting for dispatch to be acquirable\n", _DBUS_FUNCTION_NAME);
03907 _dbus_condvar_wait (connection->dispatch_cond,
03908 connection->dispatch_mutex);
03909 }
03910
03911 _dbus_assert (!connection->dispatch_acquired);
03912
03913 connection->dispatch_acquired = TRUE;
03914
03915 _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03916 _dbus_mutex_unlock (connection->dispatch_mutex);
03917
03918 CONNECTION_LOCK (connection);
03919 _dbus_connection_unref_unlocked (connection);
03920 }
03921
03929 static void
03930 _dbus_connection_release_dispatch (DBusConnection *connection)
03931 {
03932 HAVE_LOCK_CHECK (connection);
03933
03934 _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03935 _dbus_mutex_lock (connection->dispatch_mutex);
03936
03937 _dbus_assert (connection->dispatch_acquired);
03938
03939 connection->dispatch_acquired = FALSE;
03940 _dbus_condvar_wake_one (connection->dispatch_cond);
03941
03942 _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03943 _dbus_mutex_unlock (connection->dispatch_mutex);
03944 }
03945
03946 static void
03947 _dbus_connection_failed_pop (DBusConnection *connection,
03948 DBusList *message_link)
03949 {
03950 _dbus_list_prepend_link (&connection->incoming_messages,
03951 message_link);
03952 connection->n_incoming += 1;
03953 }
03954
03955
03956 static void
03957 notify_disconnected_unlocked (DBusConnection *connection)
03958 {
03959 HAVE_LOCK_CHECK (connection);
03960
03961
03962
03963
03964
03965
03966
03967 _dbus_bus_notify_shared_connection_disconnected_unlocked (connection);
03968
03969
03970
03971
03972
03973 if (connection->n_outgoing > 0)
03974 {
03975 DBusList *link;
03976
03977 _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
03978 connection->n_outgoing);
03979
03980 while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
03981 {
03982 _dbus_connection_message_sent (connection, link->data);
03983 }
03984 }
03985 }
03986
03987
03988 static DBusDispatchStatus
03989 notify_disconnected_and_dispatch_complete_unlocked (DBusConnection *connection)
03990 {
03991 HAVE_LOCK_CHECK (connection);
03992
03993 if (connection->disconnect_message_link != NULL)
03994 {
03995 _dbus_verbose ("Sending disconnect message from %s\n",
03996 _DBUS_FUNCTION_NAME);
03997
03998
03999
04000
04001 connection_timeout_and_complete_all_pending_calls_unlocked (connection);
04002
04003
04004
04005
04006 _dbus_connection_queue_synthesized_message_link (connection,
04007 connection->disconnect_message_link);
04008 connection->disconnect_message_link = NULL;
04009
04010 return DBUS_DISPATCH_DATA_REMAINS;
04011 }
04012
04013 return DBUS_DISPATCH_COMPLETE;
04014 }
04015
04016 static DBusDispatchStatus
04017 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
04018 {
04019 HAVE_LOCK_CHECK (connection);
04020
04021 if (connection->n_incoming > 0)
04022 return DBUS_DISPATCH_DATA_REMAINS;
04023 else if (!_dbus_transport_queue_messages (connection->transport))
04024 return DBUS_DISPATCH_NEED_MEMORY;
04025 else
04026 {
04027 DBusDispatchStatus status;
04028 dbus_bool_t is_connected;
04029
04030 status = _dbus_transport_get_dispatch_status (connection->transport);
04031 is_connected = _dbus_transport_get_is_connected (connection->transport);
04032
04033 _dbus_verbose ("dispatch status = %s is_connected = %d\n",
04034 DISPATCH_STATUS_NAME (status), is_connected);
04035
04036 if (!is_connected)
04037 {
04038
04039
04040
04041
04042
04043
04044 notify_disconnected_unlocked (connection);
04045
04046
04047
04048
04049
04050
04051 if (status == DBUS_DISPATCH_COMPLETE)
04052 status = notify_disconnected_and_dispatch_complete_unlocked (connection);
04053 }
04054
04055 if (status != DBUS_DISPATCH_COMPLETE)
04056 return status;
04057 else if (connection->n_incoming > 0)
04058 return DBUS_DISPATCH_DATA_REMAINS;
04059 else
04060 return DBUS_DISPATCH_COMPLETE;
04061 }
04062 }
04063
04064 static void
04065 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
04066 DBusDispatchStatus new_status)
04067 {
04068 dbus_bool_t changed;
04069 DBusDispatchStatusFunction function;
04070 void *data;
04071
04072 HAVE_LOCK_CHECK (connection);
04073
04074 _dbus_connection_ref_unlocked (connection);
04075
04076 changed = new_status != connection->last_dispatch_status;
04077
04078 connection->last_dispatch_status = new_status;
04079
04080 function = connection->dispatch_status_function;
04081 data = connection->dispatch_status_data;
04082
04083 if (connection->disconnected_message_arrived &&
04084 !connection->disconnected_message_processed)
04085 {
04086 connection->disconnected_message_processed = TRUE;
04087
04088
04089
04090
04091
04092 connection_forget_shared_unlocked (connection);
04093
04094 if (connection->exit_on_disconnect)
04095 {
04096 CONNECTION_UNLOCK (connection);
04097
04098 _dbus_verbose ("Exiting on Disconnected signal\n");
04099 _dbus_exit (1);
04100 _dbus_assert_not_reached ("Call to exit() returned");
04101 }
04102 }
04103
04104
04105 CONNECTION_UNLOCK (connection);
04106
04107 if (changed && function)
04108 {
04109 _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
04110 connection, new_status,
04111 DISPATCH_STATUS_NAME (new_status));
04112 (* function) (connection, new_status, data);
04113 }
04114
04115 dbus_connection_unref (connection);
04116 }
04117
04143 DBusDispatchStatus
04144 dbus_connection_get_dispatch_status (DBusConnection *connection)
04145 {
04146 DBusDispatchStatus status;
04147
04148 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04149
04150 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
04151
04152 CONNECTION_LOCK (connection);
04153
04154 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04155
04156 CONNECTION_UNLOCK (connection);
04157
04158 return status;
04159 }
04160
04164 static DBusHandlerResult
04165 _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
04166 DBusMessage *message)
04167 {
04168 if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
04169 {
04170
04171 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04172 }
04173 else if (dbus_message_is_method_call (message,
04174 DBUS_INTERFACE_PEER,
04175 "Ping"))
04176 {
04177 DBusMessage *ret;
04178 dbus_bool_t sent;
04179
04180 ret = dbus_message_new_method_return (message);
04181 if (ret == NULL)
04182 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04183
04184 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04185
04186 dbus_message_unref (ret);
04187
04188 if (!sent)
04189 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04190
04191 return DBUS_HANDLER_RESULT_HANDLED;
04192 }
04193 else if (dbus_message_is_method_call (message,
04194 DBUS_INTERFACE_PEER,
04195 "GetMachineId"))
04196 {
04197 DBusMessage *ret;
04198 dbus_bool_t sent;
04199 DBusString uuid;
04200
04201 ret = dbus_message_new_method_return (message);
04202 if (ret == NULL)
04203 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04204
04205 sent = FALSE;
04206 _dbus_string_init (&uuid);
04207 if (_dbus_get_local_machine_uuid_encoded (&uuid))
04208 {
04209 const char *v_STRING = _dbus_string_get_const_data (&uuid);
04210 if (dbus_message_append_args (ret,
04211 DBUS_TYPE_STRING, &v_STRING,
04212 DBUS_TYPE_INVALID))
04213 {
04214 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04215 }
04216 }
04217 _dbus_string_free (&uuid);
04218
04219 dbus_message_unref (ret);
04220
04221 if (!sent)
04222 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04223
04224 return DBUS_HANDLER_RESULT_HANDLED;
04225 }
04226 else if (dbus_message_has_interface (message, DBUS_INTERFACE_PEER))
04227 {
04228
04229
04230
04231
04232
04233 DBusMessage *ret;
04234 dbus_bool_t sent;
04235
04236 ret = dbus_message_new_error (message,
04237 DBUS_ERROR_UNKNOWN_METHOD,
04238 "Unknown method invoked on org.freedesktop.DBus.Peer interface");
04239 if (ret == NULL)
04240 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04241
04242 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04243
04244 dbus_message_unref (ret);
04245
04246 if (!sent)
04247 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04248
04249 return DBUS_HANDLER_RESULT_HANDLED;
04250 }
04251 else
04252 {
04253 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04254 }
04255 }
04256
04263 static DBusHandlerResult
04264 _dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection,
04265 DBusMessage *message)
04266 {
04267
04268
04269
04270 return _dbus_connection_peer_filter_unlocked_no_update (connection, message);
04271 }
04272
04315 DBusDispatchStatus
04316 dbus_connection_dispatch (DBusConnection *connection)
04317 {
04318 DBusMessage *message;
04319 DBusList *link, *filter_list_copy, *message_link;
04320 DBusHandlerResult result;
04321 DBusPendingCall *pending;
04322 dbus_int32_t reply_serial;
04323 DBusDispatchStatus status;
04324
04325 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04326
04327 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
04328
04329 CONNECTION_LOCK (connection);
04330 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04331 if (status != DBUS_DISPATCH_DATA_REMAINS)
04332 {
04333
04334 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04335 return status;
04336 }
04337
04338
04339
04340
04341 _dbus_connection_ref_unlocked (connection);
04342
04343 _dbus_connection_acquire_dispatch (connection);
04344 HAVE_LOCK_CHECK (connection);
04345
04346 message_link = _dbus_connection_pop_message_link_unlocked (connection);
04347 if (message_link == NULL)
04348 {
04349
04350
04351 _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
04352
04353 _dbus_connection_release_dispatch (connection);
04354
04355 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04356
04357 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04358
04359 dbus_connection_unref (connection);
04360
04361 return status;
04362 }
04363
04364 message = message_link->data;
04365
04366 _dbus_verbose (" dispatching message %p (%d %s %s '%s')\n",
04367 message,
04368 dbus_message_get_type (message),
04369 dbus_message_get_interface (message) ?
04370 dbus_message_get_interface (message) :
04371 "no interface",
04372 dbus_message_get_member (message) ?
04373 dbus_message_get_member (message) :
04374 "no member",
04375 dbus_message_get_signature (message));
04376
04377 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04378
04379
04380
04381
04382
04383
04384
04385
04386 reply_serial = dbus_message_get_reply_serial (message);
04387 pending = _dbus_hash_table_lookup_int (connection->pending_replies,
04388 reply_serial);
04389 if (pending)
04390 {
04391 _dbus_verbose ("Dispatching a pending reply\n");
04392 complete_pending_call_and_unlock (connection, pending, message);
04393 pending = NULL;
04394
04395 CONNECTION_LOCK (connection);
04396 _dbus_verbose ("pending call completed in dispatch\n");
04397 result = DBUS_HANDLER_RESULT_HANDLED;
04398 goto out;
04399 }
04400
04401 result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message);
04402 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04403 goto out;
04404
04405 if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
04406 {
04407 _dbus_connection_release_dispatch (connection);
04408 HAVE_LOCK_CHECK (connection);
04409
04410 _dbus_connection_failed_pop (connection, message_link);
04411
04412
04413 _dbus_connection_update_dispatch_status_and_unlock (connection,
04414 DBUS_DISPATCH_NEED_MEMORY);
04415
04416 if (pending)
04417 dbus_pending_call_unref (pending);
04418 dbus_connection_unref (connection);
04419
04420 return DBUS_DISPATCH_NEED_MEMORY;
04421 }
04422
04423 _dbus_list_foreach (&filter_list_copy,
04424 (DBusForeachFunction)_dbus_message_filter_ref,
04425 NULL);
04426
04427
04428
04429
04430 CONNECTION_UNLOCK (connection);
04431
04432 link = _dbus_list_get_first_link (&filter_list_copy);
04433 while (link != NULL)
04434 {
04435 DBusMessageFilter *filter = link->data;
04436 DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
04437
04438 if (filter->function == NULL)
04439 {
04440 _dbus_verbose (" filter was removed in a callback function\n");
04441 link = next;
04442 continue;
04443 }
04444
04445 _dbus_verbose (" running filter on message %p\n", message);
04446 result = (* filter->function) (connection, message, filter->user_data);
04447
04448 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04449 break;
04450
04451 link = next;
04452 }
04453
04454 _dbus_list_foreach (&filter_list_copy,
04455 (DBusForeachFunction)_dbus_message_filter_unref,
04456 NULL);
04457 _dbus_list_clear (&filter_list_copy);
04458
04459 CONNECTION_LOCK (connection);
04460
04461 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04462 {
04463 _dbus_verbose ("No memory in %s\n", _DBUS_FUNCTION_NAME);
04464 goto out;
04465 }
04466 else if (result == DBUS_HANDLER_RESULT_HANDLED)
04467 {
04468 _dbus_verbose ("filter handled message in dispatch\n");
04469 goto out;
04470 }
04471
04472
04473
04474
04475 _dbus_verbose (" running object path dispatch on message %p (%d %s %s '%s')\n",
04476 message,
04477 dbus_message_get_type (message),
04478 dbus_message_get_interface (message) ?
04479 dbus_message_get_interface (message) :
04480 "no interface",
04481 dbus_message_get_member (message) ?
04482 dbus_message_get_member (message) :
04483 "no member",
04484 dbus_message_get_signature (message));
04485
04486 HAVE_LOCK_CHECK (connection);
04487 result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
04488 message);
04489
04490 CONNECTION_LOCK (connection);
04491
04492 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04493 {
04494 _dbus_verbose ("object tree handled message in dispatch\n");
04495 goto out;
04496 }
04497
04498 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
04499 {
04500 DBusMessage *reply;
04501 DBusString str;
04502 DBusPreallocatedSend *preallocated;
04503
04504 _dbus_verbose (" sending error %s\n",
04505 DBUS_ERROR_UNKNOWN_METHOD);
04506
04507 if (!_dbus_string_init (&str))
04508 {
04509 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04510 _dbus_verbose ("no memory for error string in dispatch\n");
04511 goto out;
04512 }
04513
04514 if (!_dbus_string_append_printf (&str,
04515 "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
04516 dbus_message_get_member (message),
04517 dbus_message_get_signature (message),
04518 dbus_message_get_interface (message)))
04519 {
04520 _dbus_string_free (&str);
04521 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04522 _dbus_verbose ("no memory for error string in dispatch\n");
04523 goto out;
04524 }
04525
04526 reply = dbus_message_new_error (message,
04527 DBUS_ERROR_UNKNOWN_METHOD,
04528 _dbus_string_get_const_data (&str));
04529 _dbus_string_free (&str);
04530
04531 if (reply == NULL)
04532 {
04533 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04534 _dbus_verbose ("no memory for error reply in dispatch\n");
04535 goto out;
04536 }
04537
04538 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
04539
04540 if (preallocated == NULL)
04541 {
04542 dbus_message_unref (reply);
04543 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04544 _dbus_verbose ("no memory for error send in dispatch\n");
04545 goto out;
04546 }
04547
04548 _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
04549 reply, NULL);
04550
04551 dbus_message_unref (reply);
04552
04553 result = DBUS_HANDLER_RESULT_HANDLED;
04554 }
04555
04556 _dbus_verbose (" done dispatching %p (%d %s %s '%s') on connection %p\n", message,
04557 dbus_message_get_type (message),
04558 dbus_message_get_interface (message) ?
04559 dbus_message_get_interface (message) :
04560 "no interface",
04561 dbus_message_get_member (message) ?
04562 dbus_message_get_member (message) :
04563 "no member",
04564 dbus_message_get_signature (message),
04565 connection);
04566
04567 out:
04568 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04569 {
04570 _dbus_verbose ("out of memory in %s\n", _DBUS_FUNCTION_NAME);
04571
04572
04573
04574
04575
04576 _dbus_connection_putback_message_link_unlocked (connection,
04577 message_link);
04578 }
04579 else
04580 {
04581 _dbus_verbose (" ... done dispatching in %s\n", _DBUS_FUNCTION_NAME);
04582
04583 _dbus_list_free_link (message_link);
04584 dbus_message_unref (message);
04585
04586
04587 }
04588
04589 _dbus_connection_release_dispatch (connection);
04590 HAVE_LOCK_CHECK (connection);
04591
04592 _dbus_verbose ("%s before final status update\n", _DBUS_FUNCTION_NAME);
04593 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04594
04595
04596 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04597
04598 dbus_connection_unref (connection);
04599
04600 return status;
04601 }
04602
04662 dbus_bool_t
04663 dbus_connection_set_watch_functions (DBusConnection *connection,
04664 DBusAddWatchFunction add_function,
04665 DBusRemoveWatchFunction remove_function,
04666 DBusWatchToggledFunction toggled_function,
04667 void *data,
04668 DBusFreeFunction free_data_function)
04669 {
04670 dbus_bool_t retval;
04671 DBusWatchList *watches;
04672
04673 _dbus_return_val_if_fail (connection != NULL, FALSE);
04674
04675 CONNECTION_LOCK (connection);
04676
04677 #ifndef DBUS_DISABLE_CHECKS
04678 if (connection->watches == NULL)
04679 {
04680 _dbus_warn_check_failed ("Re-entrant call to %s is not allowed\n",
04681 _DBUS_FUNCTION_NAME);
04682 return FALSE;
04683 }
04684 #endif
04685
04686
04687 _dbus_connection_ref_unlocked (connection);
04688
04689
04690
04691
04692
04693 watches = connection->watches;
04694 connection->watches = NULL;
04695 CONNECTION_UNLOCK (connection);
04696
04697 retval = _dbus_watch_list_set_functions (watches,
04698 add_function, remove_function,
04699 toggled_function,
04700 data, free_data_function);
04701 CONNECTION_LOCK (connection);
04702 connection->watches = watches;
04703
04704 CONNECTION_UNLOCK (connection);
04705
04706 dbus_connection_unref (connection);
04707
04708 return retval;
04709 }
04710
04744 dbus_bool_t
04745 dbus_connection_set_timeout_functions (DBusConnection *connection,
04746 DBusAddTimeoutFunction add_function,
04747 DBusRemoveTimeoutFunction remove_function,
04748 DBusTimeoutToggledFunction toggled_function,
04749 void *data,
04750 DBusFreeFunction free_data_function)
04751 {
04752 dbus_bool_t retval;
04753 DBusTimeoutList *timeouts;
04754
04755 _dbus_return_val_if_fail (connection != NULL, FALSE);
04756
04757 CONNECTION_LOCK (connection);
04758
04759 #ifndef DBUS_DISABLE_CHECKS
04760 if (connection->timeouts == NULL)
04761 {
04762 _dbus_warn_check_failed ("Re-entrant call to %s is not allowed\n",
04763 _DBUS_FUNCTION_NAME);
04764 return FALSE;
04765 }
04766 #endif
04767
04768
04769 _dbus_connection_ref_unlocked (connection);
04770
04771 timeouts = connection->timeouts;
04772 connection->timeouts = NULL;
04773 CONNECTION_UNLOCK (connection);
04774
04775 retval = _dbus_timeout_list_set_functions (timeouts,
04776 add_function, remove_function,
04777 toggled_function,
04778 data, free_data_function);
04779 CONNECTION_LOCK (connection);
04780 connection->timeouts = timeouts;
04781
04782 CONNECTION_UNLOCK (connection);
04783
04784 dbus_connection_unref (connection);
04785
04786 return retval;
04787 }
04788
04803 void
04804 dbus_connection_set_wakeup_main_function (DBusConnection *connection,
04805 DBusWakeupMainFunction wakeup_main_function,
04806 void *data,
04807 DBusFreeFunction free_data_function)
04808 {
04809 void *old_data;
04810 DBusFreeFunction old_free_data;
04811
04812 _dbus_return_if_fail (connection != NULL);
04813
04814 CONNECTION_LOCK (connection);
04815 old_data = connection->wakeup_main_data;
04816 old_free_data = connection->free_wakeup_main_data;
04817
04818 connection->wakeup_main_function = wakeup_main_function;
04819 connection->wakeup_main_data = data;
04820 connection->free_wakeup_main_data = free_data_function;
04821
04822 CONNECTION_UNLOCK (connection);
04823
04824
04825 if (old_free_data)
04826 (*old_free_data) (old_data);
04827 }
04828
04849 void
04850 dbus_connection_set_dispatch_status_function (DBusConnection *connection,
04851 DBusDispatchStatusFunction function,
04852 void *data,
04853 DBusFreeFunction free_data_function)
04854 {
04855 void *old_data;
04856 DBusFreeFunction old_free_data;
04857
04858 _dbus_return_if_fail (connection != NULL);
04859
04860 CONNECTION_LOCK (connection);
04861 old_data = connection->dispatch_status_data;
04862 old_free_data = connection->free_dispatch_status_data;
04863
04864 connection->dispatch_status_function = function;
04865 connection->dispatch_status_data = data;
04866 connection->free_dispatch_status_data = free_data_function;
04867
04868 CONNECTION_UNLOCK (connection);
04869
04870
04871 if (old_free_data)
04872 (*old_free_data) (old_data);
04873 }
04874
04894 dbus_bool_t
04895 dbus_connection_get_unix_fd (DBusConnection *connection,
04896 int *fd)
04897 {
04898 _dbus_return_val_if_fail (connection != NULL, FALSE);
04899 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
04900
04901 #ifdef DBUS_WIN
04902
04903 return FALSE;
04904 #endif
04905
04906 return dbus_connection_get_socket(connection, fd);
04907 }
04908
04924 dbus_bool_t
04925 dbus_connection_get_socket(DBusConnection *connection,
04926 int *fd)
04927 {
04928 dbus_bool_t retval;
04929
04930 _dbus_return_val_if_fail (connection != NULL, FALSE);
04931 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
04932
04933 CONNECTION_LOCK (connection);
04934
04935 retval = _dbus_transport_get_socket_fd (connection->transport,
04936 fd);
04937
04938 CONNECTION_UNLOCK (connection);
04939
04940 return retval;
04941 }
04942
04943
04966 dbus_bool_t
04967 dbus_connection_get_unix_user (DBusConnection *connection,
04968 unsigned long *uid)
04969 {
04970 dbus_bool_t result;
04971
04972 _dbus_return_val_if_fail (connection != NULL, FALSE);
04973 _dbus_return_val_if_fail (uid != NULL, FALSE);
04974
04975 CONNECTION_LOCK (connection);
04976
04977 if (!_dbus_transport_get_is_authenticated (connection->transport))
04978 result = FALSE;
04979 else
04980 result = _dbus_transport_get_unix_user (connection->transport,
04981 uid);
04982
04983 #ifdef DBUS_WIN
04984 _dbus_assert (!result);
04985 #endif
04986
04987 CONNECTION_UNLOCK (connection);
04988
04989 return result;
04990 }
04991
05002 dbus_bool_t
05003 dbus_connection_get_unix_process_id (DBusConnection *connection,
05004 unsigned long *pid)
05005 {
05006 dbus_bool_t result;
05007
05008 _dbus_return_val_if_fail (connection != NULL, FALSE);
05009 _dbus_return_val_if_fail (pid != NULL, FALSE);
05010
05011 CONNECTION_LOCK (connection);
05012
05013 if (!_dbus_transport_get_is_authenticated (connection->transport))
05014 result = FALSE;
05015 else
05016 result = _dbus_transport_get_unix_process_id (connection->transport,
05017 pid);
05018 #ifdef DBUS_WIN
05019 _dbus_assert (!result);
05020 #endif
05021
05022 CONNECTION_UNLOCK (connection);
05023
05024 return result;
05025 }
05026
05037 dbus_bool_t
05038 dbus_connection_get_adt_audit_session_data (DBusConnection *connection,
05039 void **data,
05040 dbus_int32_t *data_size)
05041 {
05042 dbus_bool_t result;
05043
05044 _dbus_return_val_if_fail (connection != NULL, FALSE);
05045 _dbus_return_val_if_fail (data != NULL, FALSE);
05046 _dbus_return_val_if_fail (data_size != NULL, FALSE);
05047
05048 CONNECTION_LOCK (connection);
05049
05050 if (!_dbus_transport_get_is_authenticated (connection->transport))
05051 result = FALSE;
05052 else
05053 result = _dbus_transport_get_adt_audit_session_data (connection->transport,
05054 data,
05055 data_size);
05056 CONNECTION_UNLOCK (connection);
05057
05058 return result;
05059 }
05060
05083 void
05084 dbus_connection_set_unix_user_function (DBusConnection *connection,
05085 DBusAllowUnixUserFunction function,
05086 void *data,
05087 DBusFreeFunction free_data_function)
05088 {
05089 void *old_data = NULL;
05090 DBusFreeFunction old_free_function = NULL;
05091
05092 _dbus_return_if_fail (connection != NULL);
05093
05094 CONNECTION_LOCK (connection);
05095 _dbus_transport_set_unix_user_function (connection->transport,
05096 function, data, free_data_function,
05097 &old_data, &old_free_function);
05098 CONNECTION_UNLOCK (connection);
05099
05100 if (old_free_function != NULL)
05101 (* old_free_function) (old_data);
05102 }
05103
05135 dbus_bool_t
05136 dbus_connection_get_windows_user (DBusConnection *connection,
05137 char **windows_sid_p)
05138 {
05139 dbus_bool_t result;
05140
05141 _dbus_return_val_if_fail (connection != NULL, FALSE);
05142 _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
05143
05144 CONNECTION_LOCK (connection);
05145
05146 if (!_dbus_transport_get_is_authenticated (connection->transport))
05147 result = FALSE;
05148 else
05149 result = _dbus_transport_get_windows_user (connection->transport,
05150 windows_sid_p);
05151
05152 #ifdef DBUS_UNIX
05153 _dbus_assert (!result);
05154 #endif
05155
05156 CONNECTION_UNLOCK (connection);
05157
05158 return result;
05159 }
05160
05182 void
05183 dbus_connection_set_windows_user_function (DBusConnection *connection,
05184 DBusAllowWindowsUserFunction function,
05185 void *data,
05186 DBusFreeFunction free_data_function)
05187 {
05188 void *old_data = NULL;
05189 DBusFreeFunction old_free_function = NULL;
05190
05191 _dbus_return_if_fail (connection != NULL);
05192
05193 CONNECTION_LOCK (connection);
05194 _dbus_transport_set_windows_user_function (connection->transport,
05195 function, data, free_data_function,
05196 &old_data, &old_free_function);
05197 CONNECTION_UNLOCK (connection);
05198
05199 if (old_free_function != NULL)
05200 (* old_free_function) (old_data);
05201 }
05202
05229 void
05230 dbus_connection_set_allow_anonymous (DBusConnection *connection,
05231 dbus_bool_t value)
05232 {
05233 _dbus_return_if_fail (connection != NULL);
05234
05235 CONNECTION_LOCK (connection);
05236 _dbus_transport_set_allow_anonymous (connection->transport, value);
05237 CONNECTION_UNLOCK (connection);
05238 }
05239
05257 void
05258 dbus_connection_set_route_peer_messages (DBusConnection *connection,
05259 dbus_bool_t value)
05260 {
05261 _dbus_return_if_fail (connection != NULL);
05262
05263 CONNECTION_LOCK (connection);
05264 connection->route_peer_messages = TRUE;
05265 CONNECTION_UNLOCK (connection);
05266 }
05267
05289 dbus_bool_t
05290 dbus_connection_add_filter (DBusConnection *connection,
05291 DBusHandleMessageFunction function,
05292 void *user_data,
05293 DBusFreeFunction free_data_function)
05294 {
05295 DBusMessageFilter *filter;
05296
05297 _dbus_return_val_if_fail (connection != NULL, FALSE);
05298 _dbus_return_val_if_fail (function != NULL, FALSE);
05299
05300 filter = dbus_new0 (DBusMessageFilter, 1);
05301 if (filter == NULL)
05302 return FALSE;
05303
05304 filter->refcount.value = 1;
05305
05306 CONNECTION_LOCK (connection);
05307
05308 if (!_dbus_list_append (&connection->filter_list,
05309 filter))
05310 {
05311 _dbus_message_filter_unref (filter);
05312 CONNECTION_UNLOCK (connection);
05313 return FALSE;
05314 }
05315
05316
05317
05318
05319
05320
05321 filter->function = function;
05322 filter->user_data = user_data;
05323 filter->free_user_data_function = free_data_function;
05324
05325 CONNECTION_UNLOCK (connection);
05326 return TRUE;
05327 }
05328
05341 void
05342 dbus_connection_remove_filter (DBusConnection *connection,
05343 DBusHandleMessageFunction function,
05344 void *user_data)
05345 {
05346 DBusList *link;
05347 DBusMessageFilter *filter;
05348
05349 _dbus_return_if_fail (connection != NULL);
05350 _dbus_return_if_fail (function != NULL);
05351
05352 CONNECTION_LOCK (connection);
05353
05354 filter = NULL;
05355
05356 link = _dbus_list_get_last_link (&connection->filter_list);
05357 while (link != NULL)
05358 {
05359 filter = link->data;
05360
05361 if (filter->function == function &&
05362 filter->user_data == user_data)
05363 {
05364 _dbus_list_remove_link (&connection->filter_list, link);
05365 filter->function = NULL;
05366
05367 break;
05368 }
05369
05370 link = _dbus_list_get_prev_link (&connection->filter_list, link);
05371 filter = NULL;
05372 }
05373
05374 CONNECTION_UNLOCK (connection);
05375
05376 #ifndef DBUS_DISABLE_CHECKS
05377 if (filter == NULL)
05378 {
05379 _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
05380 function, user_data);
05381 return;
05382 }
05383 #endif
05384
05385
05386 if (filter->free_user_data_function)
05387 (* filter->free_user_data_function) (filter->user_data);
05388
05389 filter->free_user_data_function = NULL;
05390 filter->user_data = NULL;
05391
05392 _dbus_message_filter_unref (filter);
05393 }
05394
05407 dbus_bool_t
05408 dbus_connection_try_register_object_path (DBusConnection *connection,
05409 const char *path,
05410 const DBusObjectPathVTable *vtable,
05411 void *user_data,
05412 DBusError *error)
05413 {
05414 char **decomposed_path;
05415 dbus_bool_t retval;
05416
05417 _dbus_return_val_if_fail (connection != NULL, FALSE);
05418 _dbus_return_val_if_fail (path != NULL, FALSE);
05419 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05420 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05421
05422 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05423 return FALSE;
05424
05425 CONNECTION_LOCK (connection);
05426
05427 retval = _dbus_object_tree_register (connection->objects,
05428 FALSE,
05429 (const char **) decomposed_path, vtable,
05430 user_data, error);
05431
05432 CONNECTION_UNLOCK (connection);
05433
05434 dbus_free_string_array (decomposed_path);
05435
05436 return retval;
05437 }
05438
05453 dbus_bool_t
05454 dbus_connection_register_object_path (DBusConnection *connection,
05455 const char *path,
05456 const DBusObjectPathVTable *vtable,
05457 void *user_data)
05458 {
05459 char **decomposed_path;
05460 dbus_bool_t retval;
05461 DBusError error = DBUS_ERROR_INIT;
05462
05463 _dbus_return_val_if_fail (connection != NULL, FALSE);
05464 _dbus_return_val_if_fail (path != NULL, FALSE);
05465 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05466 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05467
05468 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05469 return FALSE;
05470
05471 CONNECTION_LOCK (connection);
05472
05473 retval = _dbus_object_tree_register (connection->objects,
05474 FALSE,
05475 (const char **) decomposed_path, vtable,
05476 user_data, &error);
05477
05478 CONNECTION_UNLOCK (connection);
05479
05480 dbus_free_string_array (decomposed_path);
05481
05482 if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE))
05483 {
05484 _dbus_warn ("%s\n", error.message);
05485 dbus_error_free (&error);
05486 return FALSE;
05487 }
05488
05489 return retval;
05490 }
05491
05506 dbus_bool_t
05507 dbus_connection_try_register_fallback (DBusConnection *connection,
05508 const char *path,
05509 const DBusObjectPathVTable *vtable,
05510 void *user_data,
05511 DBusError *error)
05512 {
05513 char **decomposed_path;
05514 dbus_bool_t retval;
05515
05516 _dbus_return_val_if_fail (connection != NULL, FALSE);
05517 _dbus_return_val_if_fail (path != NULL, FALSE);
05518 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05519 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05520
05521 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05522 return FALSE;
05523
05524 CONNECTION_LOCK (connection);
05525
05526 retval = _dbus_object_tree_register (connection->objects,
05527 TRUE,
05528 (const char **) decomposed_path, vtable,
05529 user_data, error);
05530
05531 CONNECTION_UNLOCK (connection);
05532
05533 dbus_free_string_array (decomposed_path);
05534
05535 return retval;
05536 }
05537
05554 dbus_bool_t
05555 dbus_connection_register_fallback (DBusConnection *connection,
05556 const char *path,
05557 const DBusObjectPathVTable *vtable,
05558 void *user_data)
05559 {
05560 char **decomposed_path;
05561 dbus_bool_t retval;
05562 DBusError error = DBUS_ERROR_INIT;
05563
05564 _dbus_return_val_if_fail (connection != NULL, FALSE);
05565 _dbus_return_val_if_fail (path != NULL, FALSE);
05566 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05567 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05568
05569 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05570 return FALSE;
05571
05572 CONNECTION_LOCK (connection);
05573
05574 retval = _dbus_object_tree_register (connection->objects,
05575 TRUE,
05576 (const char **) decomposed_path, vtable,
05577 user_data, &error);
05578
05579 CONNECTION_UNLOCK (connection);
05580
05581 dbus_free_string_array (decomposed_path);
05582
05583 if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE))
05584 {
05585 _dbus_warn ("%s\n", error.message);
05586 dbus_error_free (&error);
05587 return FALSE;
05588 }
05589
05590 return retval;
05591 }
05592
05602 dbus_bool_t
05603 dbus_connection_unregister_object_path (DBusConnection *connection,
05604 const char *path)
05605 {
05606 char **decomposed_path;
05607
05608 _dbus_return_val_if_fail (connection != NULL, FALSE);
05609 _dbus_return_val_if_fail (path != NULL, FALSE);
05610 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05611
05612 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05613 return FALSE;
05614
05615 CONNECTION_LOCK (connection);
05616
05617 _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
05618
05619 dbus_free_string_array (decomposed_path);
05620
05621 return TRUE;
05622 }
05623
05634 dbus_bool_t
05635 dbus_connection_get_object_path_data (DBusConnection *connection,
05636 const char *path,
05637 void **data_p)
05638 {
05639 char **decomposed_path;
05640
05641 _dbus_return_val_if_fail (connection != NULL, FALSE);
05642 _dbus_return_val_if_fail (path != NULL, FALSE);
05643 _dbus_return_val_if_fail (data_p != NULL, FALSE);
05644
05645 *data_p = NULL;
05646
05647 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05648 return FALSE;
05649
05650 CONNECTION_LOCK (connection);
05651
05652 *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path);
05653
05654 CONNECTION_UNLOCK (connection);
05655
05656 dbus_free_string_array (decomposed_path);
05657
05658 return TRUE;
05659 }
05660
05671 dbus_bool_t
05672 dbus_connection_list_registered (DBusConnection *connection,
05673 const char *parent_path,
05674 char ***child_entries)
05675 {
05676 char **decomposed_path;
05677 dbus_bool_t retval;
05678 _dbus_return_val_if_fail (connection != NULL, FALSE);
05679 _dbus_return_val_if_fail (parent_path != NULL, FALSE);
05680 _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
05681 _dbus_return_val_if_fail (child_entries != NULL, FALSE);
05682
05683 if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
05684 return FALSE;
05685
05686 CONNECTION_LOCK (connection);
05687
05688 retval = _dbus_object_tree_list_registered_and_unlock (connection->objects,
05689 (const char **) decomposed_path,
05690 child_entries);
05691 dbus_free_string_array (decomposed_path);
05692
05693 return retval;
05694 }
05695
05696 static DBusDataSlotAllocator slot_allocator;
05697 _DBUS_DEFINE_GLOBAL_LOCK (connection_slots);
05698
05713 dbus_bool_t
05714 dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
05715 {
05716 return _dbus_data_slot_allocator_alloc (&slot_allocator,
05717 &_DBUS_LOCK_NAME (connection_slots),
05718 slot_p);
05719 }
05720
05732 void
05733 dbus_connection_free_data_slot (dbus_int32_t *slot_p)
05734 {
05735 _dbus_return_if_fail (*slot_p >= 0);
05736
05737 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
05738 }
05739
05753 dbus_bool_t
05754 dbus_connection_set_data (DBusConnection *connection,
05755 dbus_int32_t slot,
05756 void *data,
05757 DBusFreeFunction free_data_func)
05758 {
05759 DBusFreeFunction old_free_func;
05760 void *old_data;
05761 dbus_bool_t retval;
05762
05763 _dbus_return_val_if_fail (connection != NULL, FALSE);
05764 _dbus_return_val_if_fail (slot >= 0, FALSE);
05765
05766 CONNECTION_LOCK (connection);
05767
05768 retval = _dbus_data_slot_list_set (&slot_allocator,
05769 &connection->slot_list,
05770 slot, data, free_data_func,
05771 &old_free_func, &old_data);
05772
05773 CONNECTION_UNLOCK (connection);
05774
05775 if (retval)
05776 {
05777
05778 if (old_free_func)
05779 (* old_free_func) (old_data);
05780 }
05781
05782 return retval;
05783 }
05784
05793 void*
05794 dbus_connection_get_data (DBusConnection *connection,
05795 dbus_int32_t slot)
05796 {
05797 void *res;
05798
05799 _dbus_return_val_if_fail (connection != NULL, NULL);
05800
05801 CONNECTION_LOCK (connection);
05802
05803 res = _dbus_data_slot_list_get (&slot_allocator,
05804 &connection->slot_list,
05805 slot);
05806
05807 CONNECTION_UNLOCK (connection);
05808
05809 return res;
05810 }
05811
05818 void
05819 dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
05820 {
05821 _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
05822 }
05823
05832 void
05833 dbus_connection_set_max_message_size (DBusConnection *connection,
05834 long size)
05835 {
05836 _dbus_return_if_fail (connection != NULL);
05837
05838 CONNECTION_LOCK (connection);
05839 _dbus_transport_set_max_message_size (connection->transport,
05840 size);
05841 CONNECTION_UNLOCK (connection);
05842 }
05843
05850 long
05851 dbus_connection_get_max_message_size (DBusConnection *connection)
05852 {
05853 long res;
05854
05855 _dbus_return_val_if_fail (connection != NULL, 0);
05856
05857 CONNECTION_LOCK (connection);
05858 res = _dbus_transport_get_max_message_size (connection->transport);
05859 CONNECTION_UNLOCK (connection);
05860 return res;
05861 }
05862
05888 void
05889 dbus_connection_set_max_received_size (DBusConnection *connection,
05890 long size)
05891 {
05892 _dbus_return_if_fail (connection != NULL);
05893
05894 CONNECTION_LOCK (connection);
05895 _dbus_transport_set_max_received_size (connection->transport,
05896 size);
05897 CONNECTION_UNLOCK (connection);
05898 }
05899
05906 long
05907 dbus_connection_get_max_received_size (DBusConnection *connection)
05908 {
05909 long res;
05910
05911 _dbus_return_val_if_fail (connection != NULL, 0);
05912
05913 CONNECTION_LOCK (connection);
05914 res = _dbus_transport_get_max_received_size (connection->transport);
05915 CONNECTION_UNLOCK (connection);
05916 return res;
05917 }
05918
05929 long
05930 dbus_connection_get_outgoing_size (DBusConnection *connection)
05931 {
05932 long res;
05933
05934 _dbus_return_val_if_fail (connection != NULL, 0);
05935
05936 CONNECTION_LOCK (connection);
05937 res = _dbus_counter_get_value (connection->outgoing_counter);
05938 CONNECTION_UNLOCK (connection);
05939 return res;
05940 }
05941