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 - elapsed_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 - elapsed_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 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds - elapsed_milliseconds);
02407
02408 if (status == DBUS_DISPATCH_NEED_MEMORY)
02409 {
02410
02411
02412
02413
02414 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02415
02416 _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
02417 }
02418 else
02419 {
02420
02421 _dbus_connection_do_iteration_unlocked (connection,
02422 DBUS_ITERATION_DO_READING |
02423 DBUS_ITERATION_BLOCK,
02424 timeout_milliseconds - elapsed_milliseconds);
02425 }
02426
02427 goto recheck_status;
02428 }
02429
02430 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %ld milliseconds and got no reply\n",
02431 elapsed_milliseconds);
02432
02433 _dbus_assert (!_dbus_pending_call_get_completed_unlocked (pending));
02434
02435
02436 complete_pending_call_and_unlock (connection, pending, NULL);
02437
02438
02439 CONNECTION_LOCK (connection);
02440 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02441 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02442 dbus_pending_call_unref (pending);
02443 }
02444
02481 DBusConnection*
02482 dbus_connection_open (const char *address,
02483 DBusError *error)
02484 {
02485 DBusConnection *connection;
02486
02487 _dbus_return_val_if_fail (address != NULL, NULL);
02488 _dbus_return_val_if_error_is_set (error, NULL);
02489
02490 connection = _dbus_connection_open_internal (address,
02491 TRUE,
02492 error);
02493
02494 return connection;
02495 }
02496
02524 DBusConnection*
02525 dbus_connection_open_private (const char *address,
02526 DBusError *error)
02527 {
02528 DBusConnection *connection;
02529
02530 _dbus_return_val_if_fail (address != NULL, NULL);
02531 _dbus_return_val_if_error_is_set (error, NULL);
02532
02533 connection = _dbus_connection_open_internal (address,
02534 FALSE,
02535 error);
02536
02537 return connection;
02538 }
02539
02546 DBusConnection *
02547 dbus_connection_ref (DBusConnection *connection)
02548 {
02549 _dbus_return_val_if_fail (connection != NULL, NULL);
02550 _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
02551
02552
02553
02554
02555
02556 #ifdef DBUS_HAVE_ATOMIC_INT
02557 _dbus_atomic_inc (&connection->refcount);
02558 #else
02559 CONNECTION_LOCK (connection);
02560 _dbus_assert (connection->refcount.value > 0);
02561
02562 connection->refcount.value += 1;
02563 CONNECTION_UNLOCK (connection);
02564 #endif
02565
02566 return connection;
02567 }
02568
02569 static void
02570 free_outgoing_message (void *element,
02571 void *data)
02572 {
02573 DBusMessage *message = element;
02574 DBusConnection *connection = data;
02575
02576 _dbus_message_remove_size_counter (message,
02577 connection->outgoing_counter,
02578 NULL);
02579 dbus_message_unref (message);
02580 }
02581
02582
02583
02584
02585
02586 static void
02587 _dbus_connection_last_unref (DBusConnection *connection)
02588 {
02589 DBusList *link;
02590
02591 _dbus_verbose ("Finalizing connection %p\n", connection);
02592
02593 _dbus_assert (connection->refcount.value == 0);
02594
02595
02596
02597
02598 _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
02599 _dbus_assert (connection->server_guid == NULL);
02600
02601
02602 _dbus_object_tree_free_all_unlocked (connection->objects);
02603
02604 dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
02605 dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
02606 dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
02607
02608 _dbus_watch_list_free (connection->watches);
02609 connection->watches = NULL;
02610
02611 _dbus_timeout_list_free (connection->timeouts);
02612 connection->timeouts = NULL;
02613
02614 _dbus_data_slot_list_free (&connection->slot_list);
02615
02616 link = _dbus_list_get_first_link (&connection->filter_list);
02617 while (link != NULL)
02618 {
02619 DBusMessageFilter *filter = link->data;
02620 DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
02621
02622 filter->function = NULL;
02623 _dbus_message_filter_unref (filter);
02624 link->data = NULL;
02625
02626 link = next;
02627 }
02628 _dbus_list_clear (&connection->filter_list);
02629
02630
02631
02632 _dbus_object_tree_unref (connection->objects);
02633
02634 _dbus_hash_table_unref (connection->pending_replies);
02635 connection->pending_replies = NULL;
02636
02637 _dbus_list_clear (&connection->filter_list);
02638
02639 _dbus_list_foreach (&connection->outgoing_messages,
02640 free_outgoing_message,
02641 connection);
02642 _dbus_list_clear (&connection->outgoing_messages);
02643
02644 _dbus_list_foreach (&connection->incoming_messages,
02645 (DBusForeachFunction) dbus_message_unref,
02646 NULL);
02647 _dbus_list_clear (&connection->incoming_messages);
02648
02649 _dbus_counter_unref (connection->outgoing_counter);
02650
02651 _dbus_transport_unref (connection->transport);
02652
02653 if (connection->disconnect_message_link)
02654 {
02655 DBusMessage *message = connection->disconnect_message_link->data;
02656 dbus_message_unref (message);
02657 _dbus_list_free_link (connection->disconnect_message_link);
02658 }
02659
02660 _dbus_list_clear (&connection->link_cache);
02661
02662 _dbus_condvar_free_at_location (&connection->dispatch_cond);
02663 _dbus_condvar_free_at_location (&connection->io_path_cond);
02664
02665 _dbus_mutex_free_at_location (&connection->io_path_mutex);
02666 _dbus_mutex_free_at_location (&connection->dispatch_mutex);
02667
02668 _dbus_mutex_free_at_location (&connection->mutex);
02669
02670 dbus_free (connection);
02671 }
02672
02692 void
02693 dbus_connection_unref (DBusConnection *connection)
02694 {
02695 dbus_bool_t last_unref;
02696
02697 _dbus_return_if_fail (connection != NULL);
02698 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02699
02700
02701
02702
02703
02704 #ifdef DBUS_HAVE_ATOMIC_INT
02705 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
02706 #else
02707 CONNECTION_LOCK (connection);
02708
02709 _dbus_assert (connection->refcount.value > 0);
02710
02711 connection->refcount.value -= 1;
02712 last_unref = (connection->refcount.value == 0);
02713
02714 #if 0
02715 printf ("unref() connection %p count = %d\n", connection, connection->refcount.value);
02716 #endif
02717
02718 CONNECTION_UNLOCK (connection);
02719 #endif
02720
02721 if (last_unref)
02722 {
02723 #ifndef DBUS_DISABLE_CHECKS
02724 if (_dbus_transport_get_is_connected (connection->transport))
02725 {
02726 _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",
02727 connection->shareable ?
02728 "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" :
02729 "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n");
02730 return;
02731 }
02732 #endif
02733 _dbus_connection_last_unref (connection);
02734 }
02735 }
02736
02737
02738
02739
02740
02741
02742
02743
02744
02745
02746 static void
02747 _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection)
02748 {
02749 DBusDispatchStatus status;
02750
02751 HAVE_LOCK_CHECK (connection);
02752
02753 _dbus_verbose ("Disconnecting %p\n", connection);
02754
02755
02756
02757
02758
02759 _dbus_connection_ref_unlocked (connection);
02760
02761 _dbus_transport_disconnect (connection->transport);
02762
02763
02764
02765
02766
02767
02768
02769
02770
02771
02772 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02773
02774
02775 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02776
02777
02778 dbus_connection_unref (connection);
02779 }
02780
02823 void
02824 dbus_connection_close (DBusConnection *connection)
02825 {
02826 _dbus_return_if_fail (connection != NULL);
02827 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02828
02829 CONNECTION_LOCK (connection);
02830
02831 #ifndef DBUS_DISABLE_CHECKS
02832 if (connection->shareable)
02833 {
02834 CONNECTION_UNLOCK (connection);
02835
02836 _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n");
02837 return;
02838 }
02839 #endif
02840
02841 _dbus_connection_close_possibly_shared_and_unlock (connection);
02842 }
02843
02844 static dbus_bool_t
02845 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
02846 {
02847 HAVE_LOCK_CHECK (connection);
02848 return _dbus_transport_get_is_connected (connection->transport);
02849 }
02850
02864 dbus_bool_t
02865 dbus_connection_get_is_connected (DBusConnection *connection)
02866 {
02867 dbus_bool_t res;
02868
02869 _dbus_return_val_if_fail (connection != NULL, FALSE);
02870
02871 CONNECTION_LOCK (connection);
02872 res = _dbus_connection_get_is_connected_unlocked (connection);
02873 CONNECTION_UNLOCK (connection);
02874
02875 return res;
02876 }
02877
02886 dbus_bool_t
02887 dbus_connection_get_is_authenticated (DBusConnection *connection)
02888 {
02889 dbus_bool_t res;
02890
02891 _dbus_return_val_if_fail (connection != NULL, FALSE);
02892
02893 CONNECTION_LOCK (connection);
02894 res = _dbus_transport_get_is_authenticated (connection->transport);
02895 CONNECTION_UNLOCK (connection);
02896
02897 return res;
02898 }
02899
02920 dbus_bool_t
02921 dbus_connection_get_is_anonymous (DBusConnection *connection)
02922 {
02923 dbus_bool_t res;
02924
02925 _dbus_return_val_if_fail (connection != NULL, FALSE);
02926
02927 CONNECTION_LOCK (connection);
02928 res = _dbus_transport_get_is_anonymous (connection->transport);
02929 CONNECTION_UNLOCK (connection);
02930
02931 return res;
02932 }
02933
02965 char*
02966 dbus_connection_get_server_id (DBusConnection *connection)
02967 {
02968 char *id;
02969
02970 _dbus_return_val_if_fail (connection != NULL, NULL);
02971
02972 CONNECTION_LOCK (connection);
02973 id = _dbus_strdup (_dbus_transport_get_server_id (connection->transport));
02974 CONNECTION_UNLOCK (connection);
02975
02976 return id;
02977 }
02978
02992 void
02993 dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
02994 dbus_bool_t exit_on_disconnect)
02995 {
02996 _dbus_return_if_fail (connection != NULL);
02997
02998 CONNECTION_LOCK (connection);
02999 connection->exit_on_disconnect = exit_on_disconnect != FALSE;
03000 CONNECTION_UNLOCK (connection);
03001 }
03002
03012 DBusPreallocatedSend*
03013 dbus_connection_preallocate_send (DBusConnection *connection)
03014 {
03015 DBusPreallocatedSend *preallocated;
03016
03017 _dbus_return_val_if_fail (connection != NULL, NULL);
03018
03019 CONNECTION_LOCK (connection);
03020
03021 preallocated =
03022 _dbus_connection_preallocate_send_unlocked (connection);
03023
03024 CONNECTION_UNLOCK (connection);
03025
03026 return preallocated;
03027 }
03028
03038 void
03039 dbus_connection_free_preallocated_send (DBusConnection *connection,
03040 DBusPreallocatedSend *preallocated)
03041 {
03042 _dbus_return_if_fail (connection != NULL);
03043 _dbus_return_if_fail (preallocated != NULL);
03044 _dbus_return_if_fail (connection == preallocated->connection);
03045
03046 _dbus_list_free_link (preallocated->queue_link);
03047 _dbus_counter_unref (preallocated->counter_link->data);
03048 _dbus_list_free_link (preallocated->counter_link);
03049 dbus_free (preallocated);
03050 }
03051
03064 void
03065 dbus_connection_send_preallocated (DBusConnection *connection,
03066 DBusPreallocatedSend *preallocated,
03067 DBusMessage *message,
03068 dbus_uint32_t *client_serial)
03069 {
03070 _dbus_return_if_fail (connection != NULL);
03071 _dbus_return_if_fail (preallocated != NULL);
03072 _dbus_return_if_fail (message != NULL);
03073 _dbus_return_if_fail (preallocated->connection == connection);
03074 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
03075 dbus_message_get_member (message) != NULL);
03076 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
03077 (dbus_message_get_interface (message) != NULL &&
03078 dbus_message_get_member (message) != NULL));
03079
03080 CONNECTION_LOCK (connection);
03081 _dbus_connection_send_preallocated_and_unlock (connection,
03082 preallocated,
03083 message, client_serial);
03084 }
03085
03086 static dbus_bool_t
03087 _dbus_connection_send_unlocked_no_update (DBusConnection *connection,
03088 DBusMessage *message,
03089 dbus_uint32_t *client_serial)
03090 {
03091 DBusPreallocatedSend *preallocated;
03092
03093 _dbus_assert (connection != NULL);
03094 _dbus_assert (message != NULL);
03095
03096 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
03097 if (preallocated == NULL)
03098 return FALSE;
03099
03100 _dbus_connection_send_preallocated_unlocked_no_update (connection,
03101 preallocated,
03102 message,
03103 client_serial);
03104 return TRUE;
03105 }
03106
03134 dbus_bool_t
03135 dbus_connection_send (DBusConnection *connection,
03136 DBusMessage *message,
03137 dbus_uint32_t *serial)
03138 {
03139 _dbus_return_val_if_fail (connection != NULL, FALSE);
03140 _dbus_return_val_if_fail (message != NULL, FALSE);
03141
03142 CONNECTION_LOCK (connection);
03143
03144 return _dbus_connection_send_and_unlock (connection,
03145 message,
03146 serial);
03147 }
03148
03149 static dbus_bool_t
03150 reply_handler_timeout (void *data)
03151 {
03152 DBusConnection *connection;
03153 DBusDispatchStatus status;
03154 DBusPendingCall *pending = data;
03155
03156 connection = _dbus_pending_call_get_connection_and_lock (pending);
03157
03158 _dbus_pending_call_queue_timeout_error_unlocked (pending,
03159 connection);
03160 _dbus_connection_remove_timeout_unlocked (connection,
03161 _dbus_pending_call_get_timeout_unlocked (pending));
03162 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
03163
03164 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
03165 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03166
03167
03168 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03169
03170 return TRUE;
03171 }
03172
03208 dbus_bool_t
03209 dbus_connection_send_with_reply (DBusConnection *connection,
03210 DBusMessage *message,
03211 DBusPendingCall **pending_return,
03212 int timeout_milliseconds)
03213 {
03214 DBusPendingCall *pending;
03215 dbus_int32_t serial = -1;
03216 DBusDispatchStatus status;
03217
03218 _dbus_return_val_if_fail (connection != NULL, FALSE);
03219 _dbus_return_val_if_fail (message != NULL, FALSE);
03220 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03221
03222 if (pending_return)
03223 *pending_return = NULL;
03224
03225 CONNECTION_LOCK (connection);
03226
03227 if (!_dbus_connection_get_is_connected_unlocked (connection))
03228 {
03229 CONNECTION_UNLOCK (connection);
03230
03231 return TRUE;
03232 }
03233
03234 pending = _dbus_pending_call_new_unlocked (connection,
03235 timeout_milliseconds,
03236 reply_handler_timeout);
03237
03238 if (pending == NULL)
03239 {
03240 CONNECTION_UNLOCK (connection);
03241 return FALSE;
03242 }
03243
03244
03245 serial = dbus_message_get_serial (message);
03246 if (serial == 0)
03247 {
03248 serial = _dbus_connection_get_next_client_serial (connection);
03249 dbus_message_set_serial (message, serial);
03250 }
03251
03252 if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
03253 goto error;
03254
03255
03256
03257
03258
03259 if (!_dbus_connection_attach_pending_call_unlocked (connection,
03260 pending))
03261 goto error;
03262
03263 if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
03264 {
03265 _dbus_connection_detach_pending_call_and_unlock (connection,
03266 pending);
03267 goto error_unlocked;
03268 }
03269
03270 if (pending_return)
03271 *pending_return = pending;
03272 else
03273 {
03274 _dbus_connection_detach_pending_call_unlocked (connection, pending);
03275
03276
03277
03278 }
03279
03280 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03281
03282
03283 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03284
03285 if (pending_return == NULL)
03286 dbus_pending_call_unref (pending);
03287
03288 return TRUE;
03289
03290 error:
03291 CONNECTION_UNLOCK (connection);
03292 error_unlocked:
03293 dbus_pending_call_unref (pending);
03294 return FALSE;
03295 }
03296
03327 DBusMessage*
03328 dbus_connection_send_with_reply_and_block (DBusConnection *connection,
03329 DBusMessage *message,
03330 int timeout_milliseconds,
03331 DBusError *error)
03332 {
03333 DBusMessage *reply;
03334 DBusPendingCall *pending;
03335
03336 _dbus_return_val_if_fail (connection != NULL, NULL);
03337 _dbus_return_val_if_fail (message != NULL, NULL);
03338 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL);
03339 _dbus_return_val_if_error_is_set (error, NULL);
03340
03341 if (!dbus_connection_send_with_reply (connection, message,
03342 &pending, timeout_milliseconds))
03343 {
03344 _DBUS_SET_OOM (error);
03345 return NULL;
03346 }
03347
03348 if (pending == NULL)
03349 {
03350 dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Connection is closed");
03351 return NULL;
03352 }
03353
03354 dbus_pending_call_block (pending);
03355
03356 reply = dbus_pending_call_steal_reply (pending);
03357 dbus_pending_call_unref (pending);
03358
03359
03360
03361
03362 _dbus_assert (reply != NULL);
03363
03364 if (dbus_set_error_from_message (error, reply))
03365 {
03366 dbus_message_unref (reply);
03367 return NULL;
03368 }
03369 else
03370 return reply;
03371 }
03372
03381 static DBusDispatchStatus
03382 _dbus_connection_flush_unlocked (DBusConnection *connection)
03383 {
03384
03385
03386
03387
03388
03389 DBusDispatchStatus status;
03390
03391 HAVE_LOCK_CHECK (connection);
03392
03393 while (connection->n_outgoing > 0 &&
03394 _dbus_connection_get_is_connected_unlocked (connection))
03395 {
03396 _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME);
03397 HAVE_LOCK_CHECK (connection);
03398 _dbus_connection_do_iteration_unlocked (connection,
03399 DBUS_ITERATION_DO_READING |
03400 DBUS_ITERATION_DO_WRITING |
03401 DBUS_ITERATION_BLOCK,
03402 -1);
03403 }
03404
03405 HAVE_LOCK_CHECK (connection);
03406 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
03407 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03408
03409 HAVE_LOCK_CHECK (connection);
03410 return status;
03411 }
03412
03418 void
03419 dbus_connection_flush (DBusConnection *connection)
03420 {
03421
03422
03423
03424
03425
03426 DBusDispatchStatus status;
03427
03428 _dbus_return_if_fail (connection != NULL);
03429
03430 CONNECTION_LOCK (connection);
03431
03432 status = _dbus_connection_flush_unlocked (connection);
03433
03434 HAVE_LOCK_CHECK (connection);
03435
03436 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03437
03438 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
03439 }
03440
03451 static dbus_bool_t
03452 _dbus_connection_read_write_dispatch (DBusConnection *connection,
03453 int timeout_milliseconds,
03454 dbus_bool_t dispatch)
03455 {
03456 DBusDispatchStatus dstatus;
03457 dbus_bool_t progress_possible;
03458
03459
03460
03461
03462
03463 dbus_connection_ref (connection);
03464 dstatus = dbus_connection_get_dispatch_status (connection);
03465
03466 if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
03467 {
03468 _dbus_verbose ("doing dispatch in %s\n", _DBUS_FUNCTION_NAME);
03469 dbus_connection_dispatch (connection);
03470 CONNECTION_LOCK (connection);
03471 }
03472 else if (dstatus == DBUS_DISPATCH_NEED_MEMORY)
03473 {
03474 _dbus_verbose ("pausing for memory in %s\n", _DBUS_FUNCTION_NAME);
03475 _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
03476 CONNECTION_LOCK (connection);
03477 }
03478 else
03479 {
03480 CONNECTION_LOCK (connection);
03481 if (_dbus_connection_get_is_connected_unlocked (connection))
03482 {
03483 _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME);
03484 _dbus_connection_do_iteration_unlocked (connection,
03485 DBUS_ITERATION_DO_READING |
03486 DBUS_ITERATION_DO_WRITING |
03487 DBUS_ITERATION_BLOCK,
03488 timeout_milliseconds);
03489 }
03490 }
03491
03492 HAVE_LOCK_CHECK (connection);
03493
03494
03495
03496
03497 if (dispatch)
03498 progress_possible = connection->n_incoming != 0 ||
03499 connection->disconnect_message_link != NULL;
03500 else
03501 progress_possible = _dbus_connection_get_is_connected_unlocked (connection);
03502
03503 CONNECTION_UNLOCK (connection);
03504
03505 dbus_connection_unref (connection);
03506
03507 return progress_possible;
03508 }
03509
03510
03545 dbus_bool_t
03546 dbus_connection_read_write_dispatch (DBusConnection *connection,
03547 int timeout_milliseconds)
03548 {
03549 _dbus_return_val_if_fail (connection != NULL, FALSE);
03550 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03551 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE);
03552 }
03553
03577 dbus_bool_t
03578 dbus_connection_read_write (DBusConnection *connection,
03579 int timeout_milliseconds)
03580 {
03581 _dbus_return_val_if_fail (connection != NULL, FALSE);
03582 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03583 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE);
03584 }
03585
03586
03587
03588
03589
03590
03591 static void
03592 check_disconnected_message_arrived_unlocked (DBusConnection *connection,
03593 DBusMessage *head_of_queue)
03594 {
03595 HAVE_LOCK_CHECK (connection);
03596
03597
03598 if (connection->disconnect_message_link == NULL &&
03599 dbus_message_is_signal (head_of_queue,
03600 DBUS_INTERFACE_LOCAL,
03601 "Disconnected"))
03602 {
03603 connection->disconnected_message_arrived = TRUE;
03604 }
03605 }
03606
03626 DBusMessage*
03627 dbus_connection_borrow_message (DBusConnection *connection)
03628 {
03629 DBusDispatchStatus status;
03630 DBusMessage *message;
03631
03632 _dbus_return_val_if_fail (connection != NULL, NULL);
03633
03634 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
03635
03636
03637
03638
03639 status = dbus_connection_get_dispatch_status (connection);
03640 if (status != DBUS_DISPATCH_DATA_REMAINS)
03641 return NULL;
03642
03643 CONNECTION_LOCK (connection);
03644
03645 _dbus_connection_acquire_dispatch (connection);
03646
03647
03648 _dbus_assert (connection->message_borrowed == NULL);
03649
03650 connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
03651
03652 message = connection->message_borrowed;
03653
03654 check_disconnected_message_arrived_unlocked (connection, message);
03655
03656
03657 if (message == NULL)
03658 _dbus_connection_release_dispatch (connection);
03659
03660 CONNECTION_UNLOCK (connection);
03661
03662
03663
03664 return message;
03665 }
03666
03675 void
03676 dbus_connection_return_message (DBusConnection *connection,
03677 DBusMessage *message)
03678 {
03679 DBusDispatchStatus status;
03680
03681 _dbus_return_if_fail (connection != NULL);
03682 _dbus_return_if_fail (message != NULL);
03683 _dbus_return_if_fail (message == connection->message_borrowed);
03684 _dbus_return_if_fail (connection->dispatch_acquired);
03685
03686 CONNECTION_LOCK (connection);
03687
03688 _dbus_assert (message == connection->message_borrowed);
03689
03690 connection->message_borrowed = NULL;
03691
03692 _dbus_connection_release_dispatch (connection);
03693
03694 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03695 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03696 }
03697
03707 void
03708 dbus_connection_steal_borrowed_message (DBusConnection *connection,
03709 DBusMessage *message)
03710 {
03711 DBusMessage *pop_message;
03712 DBusDispatchStatus status;
03713
03714 _dbus_return_if_fail (connection != NULL);
03715 _dbus_return_if_fail (message != NULL);
03716 _dbus_return_if_fail (message == connection->message_borrowed);
03717 _dbus_return_if_fail (connection->dispatch_acquired);
03718
03719 CONNECTION_LOCK (connection);
03720
03721 _dbus_assert (message == connection->message_borrowed);
03722
03723 pop_message = _dbus_list_pop_first (&connection->incoming_messages);
03724 _dbus_assert (message == pop_message);
03725
03726 connection->n_incoming -= 1;
03727
03728 _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
03729 message, connection->n_incoming);
03730
03731 connection->message_borrowed = NULL;
03732
03733 _dbus_connection_release_dispatch (connection);
03734
03735 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03736 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03737 }
03738
03739
03740
03741
03742 static DBusList*
03743 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
03744 {
03745 HAVE_LOCK_CHECK (connection);
03746
03747 _dbus_assert (connection->message_borrowed == NULL);
03748
03749 if (connection->n_incoming > 0)
03750 {
03751 DBusList *link;
03752
03753 link = _dbus_list_pop_first_link (&connection->incoming_messages);
03754 connection->n_incoming -= 1;
03755
03756 _dbus_verbose ("Message %p (%d %s %s %s '%s') removed from incoming queue %p, %d incoming\n",
03757 link->data,
03758 dbus_message_get_type (link->data),
03759 dbus_message_get_path (link->data) ?
03760 dbus_message_get_path (link->data) :
03761 "no path",
03762 dbus_message_get_interface (link->data) ?
03763 dbus_message_get_interface (link->data) :
03764 "no interface",
03765 dbus_message_get_member (link->data) ?
03766 dbus_message_get_member (link->data) :
03767 "no member",
03768 dbus_message_get_signature (link->data),
03769 connection, connection->n_incoming);
03770
03771 check_disconnected_message_arrived_unlocked (connection, link->data);
03772
03773 return link;
03774 }
03775 else
03776 return NULL;
03777 }
03778
03779
03780
03781
03782 static DBusMessage*
03783 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
03784 {
03785 DBusList *link;
03786
03787 HAVE_LOCK_CHECK (connection);
03788
03789 link = _dbus_connection_pop_message_link_unlocked (connection);
03790
03791 if (link != NULL)
03792 {
03793 DBusMessage *message;
03794
03795 message = link->data;
03796
03797 _dbus_list_free_link (link);
03798
03799 return message;
03800 }
03801 else
03802 return NULL;
03803 }
03804
03805 static void
03806 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
03807 DBusList *message_link)
03808 {
03809 HAVE_LOCK_CHECK (connection);
03810
03811 _dbus_assert (message_link != NULL);
03812
03813 _dbus_assert (connection->message_borrowed == NULL);
03814
03815 _dbus_assert (connection->dispatch_acquired);
03816
03817 _dbus_list_prepend_link (&connection->incoming_messages,
03818 message_link);
03819 connection->n_incoming += 1;
03820
03821 _dbus_verbose ("Message %p (%d %s %s '%s') put back into queue %p, %d incoming\n",
03822 message_link->data,
03823 dbus_message_get_type (message_link->data),
03824 dbus_message_get_interface (message_link->data) ?
03825 dbus_message_get_interface (message_link->data) :
03826 "no interface",
03827 dbus_message_get_member (message_link->data) ?
03828 dbus_message_get_member (message_link->data) :
03829 "no member",
03830 dbus_message_get_signature (message_link->data),
03831 connection, connection->n_incoming);
03832 }
03833
03853 DBusMessage*
03854 dbus_connection_pop_message (DBusConnection *connection)
03855 {
03856 DBusMessage *message;
03857 DBusDispatchStatus status;
03858
03859 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
03860
03861
03862
03863
03864 status = dbus_connection_get_dispatch_status (connection);
03865 if (status != DBUS_DISPATCH_DATA_REMAINS)
03866 return NULL;
03867
03868 CONNECTION_LOCK (connection);
03869 _dbus_connection_acquire_dispatch (connection);
03870 HAVE_LOCK_CHECK (connection);
03871
03872 message = _dbus_connection_pop_message_unlocked (connection);
03873
03874 _dbus_verbose ("Returning popped message %p\n", message);
03875
03876 _dbus_connection_release_dispatch (connection);
03877
03878 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03879 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03880
03881 return message;
03882 }
03883
03891 static void
03892 _dbus_connection_acquire_dispatch (DBusConnection *connection)
03893 {
03894 HAVE_LOCK_CHECK (connection);
03895
03896 _dbus_connection_ref_unlocked (connection);
03897 CONNECTION_UNLOCK (connection);
03898
03899 _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03900 _dbus_mutex_lock (connection->dispatch_mutex);
03901
03902 while (connection->dispatch_acquired)
03903 {
03904 _dbus_verbose ("%s waiting for dispatch to be acquirable\n", _DBUS_FUNCTION_NAME);
03905 _dbus_condvar_wait (connection->dispatch_cond,
03906 connection->dispatch_mutex);
03907 }
03908
03909 _dbus_assert (!connection->dispatch_acquired);
03910
03911 connection->dispatch_acquired = TRUE;
03912
03913 _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03914 _dbus_mutex_unlock (connection->dispatch_mutex);
03915
03916 CONNECTION_LOCK (connection);
03917 _dbus_connection_unref_unlocked (connection);
03918 }
03919
03927 static void
03928 _dbus_connection_release_dispatch (DBusConnection *connection)
03929 {
03930 HAVE_LOCK_CHECK (connection);
03931
03932 _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03933 _dbus_mutex_lock (connection->dispatch_mutex);
03934
03935 _dbus_assert (connection->dispatch_acquired);
03936
03937 connection->dispatch_acquired = FALSE;
03938 _dbus_condvar_wake_one (connection->dispatch_cond);
03939
03940 _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03941 _dbus_mutex_unlock (connection->dispatch_mutex);
03942 }
03943
03944 static void
03945 _dbus_connection_failed_pop (DBusConnection *connection,
03946 DBusList *message_link)
03947 {
03948 _dbus_list_prepend_link (&connection->incoming_messages,
03949 message_link);
03950 connection->n_incoming += 1;
03951 }
03952
03953
03954 static void
03955 notify_disconnected_unlocked (DBusConnection *connection)
03956 {
03957 HAVE_LOCK_CHECK (connection);
03958
03959
03960
03961
03962
03963
03964
03965 _dbus_bus_notify_shared_connection_disconnected_unlocked (connection);
03966
03967
03968
03969
03970
03971 if (connection->n_outgoing > 0)
03972 {
03973 DBusList *link;
03974
03975 _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
03976 connection->n_outgoing);
03977
03978 while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
03979 {
03980 _dbus_connection_message_sent (connection, link->data);
03981 }
03982 }
03983 }
03984
03985
03986 static DBusDispatchStatus
03987 notify_disconnected_and_dispatch_complete_unlocked (DBusConnection *connection)
03988 {
03989 HAVE_LOCK_CHECK (connection);
03990
03991 if (connection->disconnect_message_link != NULL)
03992 {
03993 _dbus_verbose ("Sending disconnect message from %s\n",
03994 _DBUS_FUNCTION_NAME);
03995
03996
03997
03998
03999 connection_timeout_and_complete_all_pending_calls_unlocked (connection);
04000
04001
04002
04003
04004 _dbus_connection_queue_synthesized_message_link (connection,
04005 connection->disconnect_message_link);
04006 connection->disconnect_message_link = NULL;
04007
04008 return DBUS_DISPATCH_DATA_REMAINS;
04009 }
04010
04011 return DBUS_DISPATCH_COMPLETE;
04012 }
04013
04014 static DBusDispatchStatus
04015 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
04016 {
04017 HAVE_LOCK_CHECK (connection);
04018
04019 if (connection->n_incoming > 0)
04020 return DBUS_DISPATCH_DATA_REMAINS;
04021 else if (!_dbus_transport_queue_messages (connection->transport))
04022 return DBUS_DISPATCH_NEED_MEMORY;
04023 else
04024 {
04025 DBusDispatchStatus status;
04026 dbus_bool_t is_connected;
04027
04028 status = _dbus_transport_get_dispatch_status (connection->transport);
04029 is_connected = _dbus_transport_get_is_connected (connection->transport);
04030
04031 _dbus_verbose ("dispatch status = %s is_connected = %d\n",
04032 DISPATCH_STATUS_NAME (status), is_connected);
04033
04034 if (!is_connected)
04035 {
04036
04037
04038
04039
04040
04041
04042 notify_disconnected_unlocked (connection);
04043
04044
04045
04046
04047
04048
04049 if (status == DBUS_DISPATCH_COMPLETE)
04050 status = notify_disconnected_and_dispatch_complete_unlocked (connection);
04051 }
04052
04053 if (status != DBUS_DISPATCH_COMPLETE)
04054 return status;
04055 else if (connection->n_incoming > 0)
04056 return DBUS_DISPATCH_DATA_REMAINS;
04057 else
04058 return DBUS_DISPATCH_COMPLETE;
04059 }
04060 }
04061
04062 static void
04063 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
04064 DBusDispatchStatus new_status)
04065 {
04066 dbus_bool_t changed;
04067 DBusDispatchStatusFunction function;
04068 void *data;
04069
04070 HAVE_LOCK_CHECK (connection);
04071
04072 _dbus_connection_ref_unlocked (connection);
04073
04074 changed = new_status != connection->last_dispatch_status;
04075
04076 connection->last_dispatch_status = new_status;
04077
04078 function = connection->dispatch_status_function;
04079 data = connection->dispatch_status_data;
04080
04081 if (connection->disconnected_message_arrived &&
04082 !connection->disconnected_message_processed)
04083 {
04084 connection->disconnected_message_processed = TRUE;
04085
04086
04087
04088
04089
04090 connection_forget_shared_unlocked (connection);
04091
04092 if (connection->exit_on_disconnect)
04093 {
04094 CONNECTION_UNLOCK (connection);
04095
04096 _dbus_verbose ("Exiting on Disconnected signal\n");
04097 _dbus_exit (1);
04098 _dbus_assert_not_reached ("Call to exit() returned");
04099 }
04100 }
04101
04102
04103 CONNECTION_UNLOCK (connection);
04104
04105 if (changed && function)
04106 {
04107 _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
04108 connection, new_status,
04109 DISPATCH_STATUS_NAME (new_status));
04110 (* function) (connection, new_status, data);
04111 }
04112
04113 dbus_connection_unref (connection);
04114 }
04115
04141 DBusDispatchStatus
04142 dbus_connection_get_dispatch_status (DBusConnection *connection)
04143 {
04144 DBusDispatchStatus status;
04145
04146 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04147
04148 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
04149
04150 CONNECTION_LOCK (connection);
04151
04152 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04153
04154 CONNECTION_UNLOCK (connection);
04155
04156 return status;
04157 }
04158
04162 static DBusHandlerResult
04163 _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
04164 DBusMessage *message)
04165 {
04166 if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
04167 {
04168
04169 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04170 }
04171 else if (dbus_message_is_method_call (message,
04172 DBUS_INTERFACE_PEER,
04173 "Ping"))
04174 {
04175 DBusMessage *ret;
04176 dbus_bool_t sent;
04177
04178 ret = dbus_message_new_method_return (message);
04179 if (ret == NULL)
04180 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04181
04182 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04183
04184 dbus_message_unref (ret);
04185
04186 if (!sent)
04187 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04188
04189 return DBUS_HANDLER_RESULT_HANDLED;
04190 }
04191 else if (dbus_message_is_method_call (message,
04192 DBUS_INTERFACE_PEER,
04193 "GetMachineId"))
04194 {
04195 DBusMessage *ret;
04196 dbus_bool_t sent;
04197 DBusString uuid;
04198
04199 ret = dbus_message_new_method_return (message);
04200 if (ret == NULL)
04201 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04202
04203 sent = FALSE;
04204 _dbus_string_init (&uuid);
04205 if (_dbus_get_local_machine_uuid_encoded (&uuid))
04206 {
04207 const char *v_STRING = _dbus_string_get_const_data (&uuid);
04208 if (dbus_message_append_args (ret,
04209 DBUS_TYPE_STRING, &v_STRING,
04210 DBUS_TYPE_INVALID))
04211 {
04212 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04213 }
04214 }
04215 _dbus_string_free (&uuid);
04216
04217 dbus_message_unref (ret);
04218
04219 if (!sent)
04220 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04221
04222 return DBUS_HANDLER_RESULT_HANDLED;
04223 }
04224 else if (dbus_message_has_interface (message, DBUS_INTERFACE_PEER))
04225 {
04226
04227
04228
04229
04230
04231 DBusMessage *ret;
04232 dbus_bool_t sent;
04233
04234 ret = dbus_message_new_error (message,
04235 DBUS_ERROR_UNKNOWN_METHOD,
04236 "Unknown method invoked on org.freedesktop.DBus.Peer interface");
04237 if (ret == NULL)
04238 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04239
04240 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04241
04242 dbus_message_unref (ret);
04243
04244 if (!sent)
04245 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04246
04247 return DBUS_HANDLER_RESULT_HANDLED;
04248 }
04249 else
04250 {
04251 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04252 }
04253 }
04254
04261 static DBusHandlerResult
04262 _dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection,
04263 DBusMessage *message)
04264 {
04265
04266
04267
04268 return _dbus_connection_peer_filter_unlocked_no_update (connection, message);
04269 }
04270
04313 DBusDispatchStatus
04314 dbus_connection_dispatch (DBusConnection *connection)
04315 {
04316 DBusMessage *message;
04317 DBusList *link, *filter_list_copy, *message_link;
04318 DBusHandlerResult result;
04319 DBusPendingCall *pending;
04320 dbus_int32_t reply_serial;
04321 DBusDispatchStatus status;
04322
04323 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04324
04325 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
04326
04327 CONNECTION_LOCK (connection);
04328 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04329 if (status != DBUS_DISPATCH_DATA_REMAINS)
04330 {
04331
04332 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04333 return status;
04334 }
04335
04336
04337
04338
04339 _dbus_connection_ref_unlocked (connection);
04340
04341 _dbus_connection_acquire_dispatch (connection);
04342 HAVE_LOCK_CHECK (connection);
04343
04344 message_link = _dbus_connection_pop_message_link_unlocked (connection);
04345 if (message_link == NULL)
04346 {
04347
04348
04349 _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
04350
04351 _dbus_connection_release_dispatch (connection);
04352
04353 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04354
04355 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04356
04357 dbus_connection_unref (connection);
04358
04359 return status;
04360 }
04361
04362 message = message_link->data;
04363
04364 _dbus_verbose (" dispatching message %p (%d %s %s '%s')\n",
04365 message,
04366 dbus_message_get_type (message),
04367 dbus_message_get_interface (message) ?
04368 dbus_message_get_interface (message) :
04369 "no interface",
04370 dbus_message_get_member (message) ?
04371 dbus_message_get_member (message) :
04372 "no member",
04373 dbus_message_get_signature (message));
04374
04375 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04376
04377
04378
04379
04380
04381
04382
04383
04384 reply_serial = dbus_message_get_reply_serial (message);
04385 pending = _dbus_hash_table_lookup_int (connection->pending_replies,
04386 reply_serial);
04387 if (pending)
04388 {
04389 _dbus_verbose ("Dispatching a pending reply\n");
04390 complete_pending_call_and_unlock (connection, pending, message);
04391 pending = NULL;
04392
04393 CONNECTION_LOCK (connection);
04394 _dbus_verbose ("pending call completed in dispatch\n");
04395 result = DBUS_HANDLER_RESULT_HANDLED;
04396 goto out;
04397 }
04398
04399 result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message);
04400 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04401 goto out;
04402
04403 if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
04404 {
04405 _dbus_connection_release_dispatch (connection);
04406 HAVE_LOCK_CHECK (connection);
04407
04408 _dbus_connection_failed_pop (connection, message_link);
04409
04410
04411 _dbus_connection_update_dispatch_status_and_unlock (connection,
04412 DBUS_DISPATCH_NEED_MEMORY);
04413
04414 if (pending)
04415 dbus_pending_call_unref (pending);
04416 dbus_connection_unref (connection);
04417
04418 return DBUS_DISPATCH_NEED_MEMORY;
04419 }
04420
04421 _dbus_list_foreach (&filter_list_copy,
04422 (DBusForeachFunction)_dbus_message_filter_ref,
04423 NULL);
04424
04425
04426
04427
04428 CONNECTION_UNLOCK (connection);
04429
04430 link = _dbus_list_get_first_link (&filter_list_copy);
04431 while (link != NULL)
04432 {
04433 DBusMessageFilter *filter = link->data;
04434 DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
04435
04436 if (filter->function == NULL)
04437 {
04438 _dbus_verbose (" filter was removed in a callback function\n");
04439 link = next;
04440 continue;
04441 }
04442
04443 _dbus_verbose (" running filter on message %p\n", message);
04444 result = (* filter->function) (connection, message, filter->user_data);
04445
04446 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04447 break;
04448
04449 link = next;
04450 }
04451
04452 _dbus_list_foreach (&filter_list_copy,
04453 (DBusForeachFunction)_dbus_message_filter_unref,
04454 NULL);
04455 _dbus_list_clear (&filter_list_copy);
04456
04457 CONNECTION_LOCK (connection);
04458
04459 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04460 {
04461 _dbus_verbose ("No memory in %s\n", _DBUS_FUNCTION_NAME);
04462 goto out;
04463 }
04464 else if (result == DBUS_HANDLER_RESULT_HANDLED)
04465 {
04466 _dbus_verbose ("filter handled message in dispatch\n");
04467 goto out;
04468 }
04469
04470
04471
04472
04473 _dbus_verbose (" running object path dispatch on message %p (%d %s %s '%s')\n",
04474 message,
04475 dbus_message_get_type (message),
04476 dbus_message_get_interface (message) ?
04477 dbus_message_get_interface (message) :
04478 "no interface",
04479 dbus_message_get_member (message) ?
04480 dbus_message_get_member (message) :
04481 "no member",
04482 dbus_message_get_signature (message));
04483
04484 HAVE_LOCK_CHECK (connection);
04485 result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
04486 message);
04487
04488 CONNECTION_LOCK (connection);
04489
04490 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04491 {
04492 _dbus_verbose ("object tree handled message in dispatch\n");
04493 goto out;
04494 }
04495
04496 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
04497 {
04498 DBusMessage *reply;
04499 DBusString str;
04500 DBusPreallocatedSend *preallocated;
04501
04502 _dbus_verbose (" sending error %s\n",
04503 DBUS_ERROR_UNKNOWN_METHOD);
04504
04505 if (!_dbus_string_init (&str))
04506 {
04507 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04508 _dbus_verbose ("no memory for error string in dispatch\n");
04509 goto out;
04510 }
04511
04512 if (!_dbus_string_append_printf (&str,
04513 "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
04514 dbus_message_get_member (message),
04515 dbus_message_get_signature (message),
04516 dbus_message_get_interface (message)))
04517 {
04518 _dbus_string_free (&str);
04519 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04520 _dbus_verbose ("no memory for error string in dispatch\n");
04521 goto out;
04522 }
04523
04524 reply = dbus_message_new_error (message,
04525 DBUS_ERROR_UNKNOWN_METHOD,
04526 _dbus_string_get_const_data (&str));
04527 _dbus_string_free (&str);
04528
04529 if (reply == NULL)
04530 {
04531 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04532 _dbus_verbose ("no memory for error reply in dispatch\n");
04533 goto out;
04534 }
04535
04536 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
04537
04538 if (preallocated == NULL)
04539 {
04540 dbus_message_unref (reply);
04541 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04542 _dbus_verbose ("no memory for error send in dispatch\n");
04543 goto out;
04544 }
04545
04546 _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
04547 reply, NULL);
04548
04549 dbus_message_unref (reply);
04550
04551 result = DBUS_HANDLER_RESULT_HANDLED;
04552 }
04553
04554 _dbus_verbose (" done dispatching %p (%d %s %s '%s') on connection %p\n", message,
04555 dbus_message_get_type (message),
04556 dbus_message_get_interface (message) ?
04557 dbus_message_get_interface (message) :
04558 "no interface",
04559 dbus_message_get_member (message) ?
04560 dbus_message_get_member (message) :
04561 "no member",
04562 dbus_message_get_signature (message),
04563 connection);
04564
04565 out:
04566 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04567 {
04568 _dbus_verbose ("out of memory in %s\n", _DBUS_FUNCTION_NAME);
04569
04570
04571
04572
04573
04574 _dbus_connection_putback_message_link_unlocked (connection,
04575 message_link);
04576 }
04577 else
04578 {
04579 _dbus_verbose (" ... done dispatching in %s\n", _DBUS_FUNCTION_NAME);
04580
04581 _dbus_list_free_link (message_link);
04582 dbus_message_unref (message);
04583
04584
04585 }
04586
04587 _dbus_connection_release_dispatch (connection);
04588 HAVE_LOCK_CHECK (connection);
04589
04590 _dbus_verbose ("%s before final status update\n", _DBUS_FUNCTION_NAME);
04591 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04592
04593
04594 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04595
04596 dbus_connection_unref (connection);
04597
04598 return status;
04599 }
04600
04660 dbus_bool_t
04661 dbus_connection_set_watch_functions (DBusConnection *connection,
04662 DBusAddWatchFunction add_function,
04663 DBusRemoveWatchFunction remove_function,
04664 DBusWatchToggledFunction toggled_function,
04665 void *data,
04666 DBusFreeFunction free_data_function)
04667 {
04668 dbus_bool_t retval;
04669 DBusWatchList *watches;
04670
04671 _dbus_return_val_if_fail (connection != NULL, FALSE);
04672
04673 CONNECTION_LOCK (connection);
04674
04675 #ifndef DBUS_DISABLE_CHECKS
04676 if (connection->watches == NULL)
04677 {
04678 _dbus_warn_check_failed ("Re-entrant call to %s is not allowed\n",
04679 _DBUS_FUNCTION_NAME);
04680 return FALSE;
04681 }
04682 #endif
04683
04684
04685 _dbus_connection_ref_unlocked (connection);
04686
04687
04688
04689
04690
04691 watches = connection->watches;
04692 connection->watches = NULL;
04693 CONNECTION_UNLOCK (connection);
04694
04695 retval = _dbus_watch_list_set_functions (watches,
04696 add_function, remove_function,
04697 toggled_function,
04698 data, free_data_function);
04699 CONNECTION_LOCK (connection);
04700 connection->watches = watches;
04701
04702 CONNECTION_UNLOCK (connection);
04703
04704 dbus_connection_unref (connection);
04705
04706 return retval;
04707 }
04708
04742 dbus_bool_t
04743 dbus_connection_set_timeout_functions (DBusConnection *connection,
04744 DBusAddTimeoutFunction add_function,
04745 DBusRemoveTimeoutFunction remove_function,
04746 DBusTimeoutToggledFunction toggled_function,
04747 void *data,
04748 DBusFreeFunction free_data_function)
04749 {
04750 dbus_bool_t retval;
04751 DBusTimeoutList *timeouts;
04752
04753 _dbus_return_val_if_fail (connection != NULL, FALSE);
04754
04755 CONNECTION_LOCK (connection);
04756
04757 #ifndef DBUS_DISABLE_CHECKS
04758 if (connection->timeouts == NULL)
04759 {
04760 _dbus_warn_check_failed ("Re-entrant call to %s is not allowed\n",
04761 _DBUS_FUNCTION_NAME);
04762 return FALSE;
04763 }
04764 #endif
04765
04766
04767 _dbus_connection_ref_unlocked (connection);
04768
04769 timeouts = connection->timeouts;
04770 connection->timeouts = NULL;
04771 CONNECTION_UNLOCK (connection);
04772
04773 retval = _dbus_timeout_list_set_functions (timeouts,
04774 add_function, remove_function,
04775 toggled_function,
04776 data, free_data_function);
04777 CONNECTION_LOCK (connection);
04778 connection->timeouts = timeouts;
04779
04780 CONNECTION_UNLOCK (connection);
04781
04782 dbus_connection_unref (connection);
04783
04784 return retval;
04785 }
04786
04801 void
04802 dbus_connection_set_wakeup_main_function (DBusConnection *connection,
04803 DBusWakeupMainFunction wakeup_main_function,
04804 void *data,
04805 DBusFreeFunction free_data_function)
04806 {
04807 void *old_data;
04808 DBusFreeFunction old_free_data;
04809
04810 _dbus_return_if_fail (connection != NULL);
04811
04812 CONNECTION_LOCK (connection);
04813 old_data = connection->wakeup_main_data;
04814 old_free_data = connection->free_wakeup_main_data;
04815
04816 connection->wakeup_main_function = wakeup_main_function;
04817 connection->wakeup_main_data = data;
04818 connection->free_wakeup_main_data = free_data_function;
04819
04820 CONNECTION_UNLOCK (connection);
04821
04822
04823 if (old_free_data)
04824 (*old_free_data) (old_data);
04825 }
04826
04847 void
04848 dbus_connection_set_dispatch_status_function (DBusConnection *connection,
04849 DBusDispatchStatusFunction function,
04850 void *data,
04851 DBusFreeFunction free_data_function)
04852 {
04853 void *old_data;
04854 DBusFreeFunction old_free_data;
04855
04856 _dbus_return_if_fail (connection != NULL);
04857
04858 CONNECTION_LOCK (connection);
04859 old_data = connection->dispatch_status_data;
04860 old_free_data = connection->free_dispatch_status_data;
04861
04862 connection->dispatch_status_function = function;
04863 connection->dispatch_status_data = data;
04864 connection->free_dispatch_status_data = free_data_function;
04865
04866 CONNECTION_UNLOCK (connection);
04867
04868
04869 if (old_free_data)
04870 (*old_free_data) (old_data);
04871 }
04872
04892 dbus_bool_t
04893 dbus_connection_get_unix_fd (DBusConnection *connection,
04894 int *fd)
04895 {
04896 _dbus_return_val_if_fail (connection != NULL, FALSE);
04897 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
04898
04899 #ifdef DBUS_WIN
04900
04901 return FALSE;
04902 #endif
04903
04904 return dbus_connection_get_socket(connection, fd);
04905 }
04906
04922 dbus_bool_t
04923 dbus_connection_get_socket(DBusConnection *connection,
04924 int *fd)
04925 {
04926 dbus_bool_t retval;
04927
04928 _dbus_return_val_if_fail (connection != NULL, FALSE);
04929 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
04930
04931 CONNECTION_LOCK (connection);
04932
04933 retval = _dbus_transport_get_socket_fd (connection->transport,
04934 fd);
04935
04936 CONNECTION_UNLOCK (connection);
04937
04938 return retval;
04939 }
04940
04941
04964 dbus_bool_t
04965 dbus_connection_get_unix_user (DBusConnection *connection,
04966 unsigned long *uid)
04967 {
04968 dbus_bool_t result;
04969
04970 _dbus_return_val_if_fail (connection != NULL, FALSE);
04971 _dbus_return_val_if_fail (uid != NULL, FALSE);
04972
04973 CONNECTION_LOCK (connection);
04974
04975 if (!_dbus_transport_get_is_authenticated (connection->transport))
04976 result = FALSE;
04977 else
04978 result = _dbus_transport_get_unix_user (connection->transport,
04979 uid);
04980
04981 #ifdef DBUS_WIN
04982 _dbus_assert (!result);
04983 #endif
04984
04985 CONNECTION_UNLOCK (connection);
04986
04987 return result;
04988 }
04989
05000 dbus_bool_t
05001 dbus_connection_get_unix_process_id (DBusConnection *connection,
05002 unsigned long *pid)
05003 {
05004 dbus_bool_t result;
05005
05006 _dbus_return_val_if_fail (connection != NULL, FALSE);
05007 _dbus_return_val_if_fail (pid != NULL, FALSE);
05008
05009 CONNECTION_LOCK (connection);
05010
05011 if (!_dbus_transport_get_is_authenticated (connection->transport))
05012 result = FALSE;
05013 else
05014 result = _dbus_transport_get_unix_process_id (connection->transport,
05015 pid);
05016 #ifdef DBUS_WIN
05017 _dbus_assert (!result);
05018 #endif
05019
05020 CONNECTION_UNLOCK (connection);
05021
05022 return result;
05023 }
05024
05035 dbus_bool_t
05036 dbus_connection_get_adt_audit_session_data (DBusConnection *connection,
05037 void **data,
05038 dbus_int32_t *data_size)
05039 {
05040 dbus_bool_t result;
05041
05042 _dbus_return_val_if_fail (connection != NULL, FALSE);
05043 _dbus_return_val_if_fail (data != NULL, FALSE);
05044 _dbus_return_val_if_fail (data_size != NULL, FALSE);
05045
05046 CONNECTION_LOCK (connection);
05047
05048 if (!_dbus_transport_get_is_authenticated (connection->transport))
05049 result = FALSE;
05050 else
05051 result = _dbus_transport_get_adt_audit_session_data (connection->transport,
05052 data,
05053 data_size);
05054 CONNECTION_UNLOCK (connection);
05055
05056 return result;
05057 }
05058
05081 void
05082 dbus_connection_set_unix_user_function (DBusConnection *connection,
05083 DBusAllowUnixUserFunction function,
05084 void *data,
05085 DBusFreeFunction free_data_function)
05086 {
05087 void *old_data = NULL;
05088 DBusFreeFunction old_free_function = NULL;
05089
05090 _dbus_return_if_fail (connection != NULL);
05091
05092 CONNECTION_LOCK (connection);
05093 _dbus_transport_set_unix_user_function (connection->transport,
05094 function, data, free_data_function,
05095 &old_data, &old_free_function);
05096 CONNECTION_UNLOCK (connection);
05097
05098 if (old_free_function != NULL)
05099 (* old_free_function) (old_data);
05100 }
05101
05133 dbus_bool_t
05134 dbus_connection_get_windows_user (DBusConnection *connection,
05135 char **windows_sid_p)
05136 {
05137 dbus_bool_t result;
05138
05139 _dbus_return_val_if_fail (connection != NULL, FALSE);
05140 _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
05141
05142 CONNECTION_LOCK (connection);
05143
05144 if (!_dbus_transport_get_is_authenticated (connection->transport))
05145 result = FALSE;
05146 else
05147 result = _dbus_transport_get_windows_user (connection->transport,
05148 windows_sid_p);
05149
05150 #ifdef DBUS_UNIX
05151 _dbus_assert (!result);
05152 #endif
05153
05154 CONNECTION_UNLOCK (connection);
05155
05156 return result;
05157 }
05158
05180 void
05181 dbus_connection_set_windows_user_function (DBusConnection *connection,
05182 DBusAllowWindowsUserFunction function,
05183 void *data,
05184 DBusFreeFunction free_data_function)
05185 {
05186 void *old_data = NULL;
05187 DBusFreeFunction old_free_function = NULL;
05188
05189 _dbus_return_if_fail (connection != NULL);
05190
05191 CONNECTION_LOCK (connection);
05192 _dbus_transport_set_windows_user_function (connection->transport,
05193 function, data, free_data_function,
05194 &old_data, &old_free_function);
05195 CONNECTION_UNLOCK (connection);
05196
05197 if (old_free_function != NULL)
05198 (* old_free_function) (old_data);
05199 }
05200
05227 void
05228 dbus_connection_set_allow_anonymous (DBusConnection *connection,
05229 dbus_bool_t value)
05230 {
05231 _dbus_return_if_fail (connection != NULL);
05232
05233 CONNECTION_LOCK (connection);
05234 _dbus_transport_set_allow_anonymous (connection->transport, value);
05235 CONNECTION_UNLOCK (connection);
05236 }
05237
05255 void
05256 dbus_connection_set_route_peer_messages (DBusConnection *connection,
05257 dbus_bool_t value)
05258 {
05259 _dbus_return_if_fail (connection != NULL);
05260
05261 CONNECTION_LOCK (connection);
05262 connection->route_peer_messages = TRUE;
05263 CONNECTION_UNLOCK (connection);
05264 }
05265
05287 dbus_bool_t
05288 dbus_connection_add_filter (DBusConnection *connection,
05289 DBusHandleMessageFunction function,
05290 void *user_data,
05291 DBusFreeFunction free_data_function)
05292 {
05293 DBusMessageFilter *filter;
05294
05295 _dbus_return_val_if_fail (connection != NULL, FALSE);
05296 _dbus_return_val_if_fail (function != NULL, FALSE);
05297
05298 filter = dbus_new0 (DBusMessageFilter, 1);
05299 if (filter == NULL)
05300 return FALSE;
05301
05302 filter->refcount.value = 1;
05303
05304 CONNECTION_LOCK (connection);
05305
05306 if (!_dbus_list_append (&connection->filter_list,
05307 filter))
05308 {
05309 _dbus_message_filter_unref (filter);
05310 CONNECTION_UNLOCK (connection);
05311 return FALSE;
05312 }
05313
05314
05315
05316
05317
05318
05319 filter->function = function;
05320 filter->user_data = user_data;
05321 filter->free_user_data_function = free_data_function;
05322
05323 CONNECTION_UNLOCK (connection);
05324 return TRUE;
05325 }
05326
05339 void
05340 dbus_connection_remove_filter (DBusConnection *connection,
05341 DBusHandleMessageFunction function,
05342 void *user_data)
05343 {
05344 DBusList *link;
05345 DBusMessageFilter *filter;
05346
05347 _dbus_return_if_fail (connection != NULL);
05348 _dbus_return_if_fail (function != NULL);
05349
05350 CONNECTION_LOCK (connection);
05351
05352 filter = NULL;
05353
05354 link = _dbus_list_get_last_link (&connection->filter_list);
05355 while (link != NULL)
05356 {
05357 filter = link->data;
05358
05359 if (filter->function == function &&
05360 filter->user_data == user_data)
05361 {
05362 _dbus_list_remove_link (&connection->filter_list, link);
05363 filter->function = NULL;
05364
05365 break;
05366 }
05367
05368 link = _dbus_list_get_prev_link (&connection->filter_list, link);
05369 filter = NULL;
05370 }
05371
05372 CONNECTION_UNLOCK (connection);
05373
05374 #ifndef DBUS_DISABLE_CHECKS
05375 if (filter == NULL)
05376 {
05377 _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
05378 function, user_data);
05379 return;
05380 }
05381 #endif
05382
05383
05384 if (filter->free_user_data_function)
05385 (* filter->free_user_data_function) (filter->user_data);
05386
05387 filter->free_user_data_function = NULL;
05388 filter->user_data = NULL;
05389
05390 _dbus_message_filter_unref (filter);
05391 }
05392
05405 dbus_bool_t
05406 dbus_connection_try_register_object_path (DBusConnection *connection,
05407 const char *path,
05408 const DBusObjectPathVTable *vtable,
05409 void *user_data,
05410 DBusError *error)
05411 {
05412 char **decomposed_path;
05413 dbus_bool_t retval;
05414
05415 _dbus_return_val_if_fail (connection != NULL, FALSE);
05416 _dbus_return_val_if_fail (path != NULL, FALSE);
05417 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05418 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05419
05420 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05421 return FALSE;
05422
05423 CONNECTION_LOCK (connection);
05424
05425 retval = _dbus_object_tree_register (connection->objects,
05426 FALSE,
05427 (const char **) decomposed_path, vtable,
05428 user_data, error);
05429
05430 CONNECTION_UNLOCK (connection);
05431
05432 dbus_free_string_array (decomposed_path);
05433
05434 return retval;
05435 }
05436
05451 dbus_bool_t
05452 dbus_connection_register_object_path (DBusConnection *connection,
05453 const char *path,
05454 const DBusObjectPathVTable *vtable,
05455 void *user_data)
05456 {
05457 char **decomposed_path;
05458 dbus_bool_t retval;
05459 DBusError error = DBUS_ERROR_INIT;
05460
05461 _dbus_return_val_if_fail (connection != NULL, FALSE);
05462 _dbus_return_val_if_fail (path != NULL, FALSE);
05463 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05464 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05465
05466 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05467 return FALSE;
05468
05469 CONNECTION_LOCK (connection);
05470
05471 retval = _dbus_object_tree_register (connection->objects,
05472 FALSE,
05473 (const char **) decomposed_path, vtable,
05474 user_data, &error);
05475
05476 CONNECTION_UNLOCK (connection);
05477
05478 dbus_free_string_array (decomposed_path);
05479
05480 if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE))
05481 {
05482 _dbus_warn ("%s\n", error.message);
05483 dbus_error_free (&error);
05484 return FALSE;
05485 }
05486
05487 return retval;
05488 }
05489
05504 dbus_bool_t
05505 dbus_connection_try_register_fallback (DBusConnection *connection,
05506 const char *path,
05507 const DBusObjectPathVTable *vtable,
05508 void *user_data,
05509 DBusError *error)
05510 {
05511 char **decomposed_path;
05512 dbus_bool_t retval;
05513
05514 _dbus_return_val_if_fail (connection != NULL, FALSE);
05515 _dbus_return_val_if_fail (path != NULL, FALSE);
05516 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05517 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05518
05519 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05520 return FALSE;
05521
05522 CONNECTION_LOCK (connection);
05523
05524 retval = _dbus_object_tree_register (connection->objects,
05525 TRUE,
05526 (const char **) decomposed_path, vtable,
05527 user_data, error);
05528
05529 CONNECTION_UNLOCK (connection);
05530
05531 dbus_free_string_array (decomposed_path);
05532
05533 return retval;
05534 }
05535
05552 dbus_bool_t
05553 dbus_connection_register_fallback (DBusConnection *connection,
05554 const char *path,
05555 const DBusObjectPathVTable *vtable,
05556 void *user_data)
05557 {
05558 char **decomposed_path;
05559 dbus_bool_t retval;
05560 DBusError error = DBUS_ERROR_INIT;
05561
05562 _dbus_return_val_if_fail (connection != NULL, FALSE);
05563 _dbus_return_val_if_fail (path != NULL, FALSE);
05564 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05565 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05566
05567 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05568 return FALSE;
05569
05570 CONNECTION_LOCK (connection);
05571
05572 retval = _dbus_object_tree_register (connection->objects,
05573 TRUE,
05574 (const char **) decomposed_path, vtable,
05575 user_data, &error);
05576
05577 CONNECTION_UNLOCK (connection);
05578
05579 dbus_free_string_array (decomposed_path);
05580
05581 if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE))
05582 {
05583 _dbus_warn ("%s\n", error.message);
05584 dbus_error_free (&error);
05585 return FALSE;
05586 }
05587
05588 return retval;
05589 }
05590
05600 dbus_bool_t
05601 dbus_connection_unregister_object_path (DBusConnection *connection,
05602 const char *path)
05603 {
05604 char **decomposed_path;
05605
05606 _dbus_return_val_if_fail (connection != NULL, FALSE);
05607 _dbus_return_val_if_fail (path != NULL, FALSE);
05608 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05609
05610 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05611 return FALSE;
05612
05613 CONNECTION_LOCK (connection);
05614
05615 _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
05616
05617 dbus_free_string_array (decomposed_path);
05618
05619 return TRUE;
05620 }
05621
05632 dbus_bool_t
05633 dbus_connection_get_object_path_data (DBusConnection *connection,
05634 const char *path,
05635 void **data_p)
05636 {
05637 char **decomposed_path;
05638
05639 _dbus_return_val_if_fail (connection != NULL, FALSE);
05640 _dbus_return_val_if_fail (path != NULL, FALSE);
05641 _dbus_return_val_if_fail (data_p != NULL, FALSE);
05642
05643 *data_p = NULL;
05644
05645 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05646 return FALSE;
05647
05648 CONNECTION_LOCK (connection);
05649
05650 *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path);
05651
05652 CONNECTION_UNLOCK (connection);
05653
05654 dbus_free_string_array (decomposed_path);
05655
05656 return TRUE;
05657 }
05658
05669 dbus_bool_t
05670 dbus_connection_list_registered (DBusConnection *connection,
05671 const char *parent_path,
05672 char ***child_entries)
05673 {
05674 char **decomposed_path;
05675 dbus_bool_t retval;
05676 _dbus_return_val_if_fail (connection != NULL, FALSE);
05677 _dbus_return_val_if_fail (parent_path != NULL, FALSE);
05678 _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
05679 _dbus_return_val_if_fail (child_entries != NULL, FALSE);
05680
05681 if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
05682 return FALSE;
05683
05684 CONNECTION_LOCK (connection);
05685
05686 retval = _dbus_object_tree_list_registered_and_unlock (connection->objects,
05687 (const char **) decomposed_path,
05688 child_entries);
05689 dbus_free_string_array (decomposed_path);
05690
05691 return retval;
05692 }
05693
05694 static DBusDataSlotAllocator slot_allocator;
05695 _DBUS_DEFINE_GLOBAL_LOCK (connection_slots);
05696
05711 dbus_bool_t
05712 dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
05713 {
05714 return _dbus_data_slot_allocator_alloc (&slot_allocator,
05715 &_DBUS_LOCK_NAME (connection_slots),
05716 slot_p);
05717 }
05718
05730 void
05731 dbus_connection_free_data_slot (dbus_int32_t *slot_p)
05732 {
05733 _dbus_return_if_fail (*slot_p >= 0);
05734
05735 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
05736 }
05737
05751 dbus_bool_t
05752 dbus_connection_set_data (DBusConnection *connection,
05753 dbus_int32_t slot,
05754 void *data,
05755 DBusFreeFunction free_data_func)
05756 {
05757 DBusFreeFunction old_free_func;
05758 void *old_data;
05759 dbus_bool_t retval;
05760
05761 _dbus_return_val_if_fail (connection != NULL, FALSE);
05762 _dbus_return_val_if_fail (slot >= 0, FALSE);
05763
05764 CONNECTION_LOCK (connection);
05765
05766 retval = _dbus_data_slot_list_set (&slot_allocator,
05767 &connection->slot_list,
05768 slot, data, free_data_func,
05769 &old_free_func, &old_data);
05770
05771 CONNECTION_UNLOCK (connection);
05772
05773 if (retval)
05774 {
05775
05776 if (old_free_func)
05777 (* old_free_func) (old_data);
05778 }
05779
05780 return retval;
05781 }
05782
05791 void*
05792 dbus_connection_get_data (DBusConnection *connection,
05793 dbus_int32_t slot)
05794 {
05795 void *res;
05796
05797 _dbus_return_val_if_fail (connection != NULL, NULL);
05798
05799 CONNECTION_LOCK (connection);
05800
05801 res = _dbus_data_slot_list_get (&slot_allocator,
05802 &connection->slot_list,
05803 slot);
05804
05805 CONNECTION_UNLOCK (connection);
05806
05807 return res;
05808 }
05809
05816 void
05817 dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
05818 {
05819 _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
05820 }
05821
05830 void
05831 dbus_connection_set_max_message_size (DBusConnection *connection,
05832 long size)
05833 {
05834 _dbus_return_if_fail (connection != NULL);
05835
05836 CONNECTION_LOCK (connection);
05837 _dbus_transport_set_max_message_size (connection->transport,
05838 size);
05839 CONNECTION_UNLOCK (connection);
05840 }
05841
05848 long
05849 dbus_connection_get_max_message_size (DBusConnection *connection)
05850 {
05851 long res;
05852
05853 _dbus_return_val_if_fail (connection != NULL, 0);
05854
05855 CONNECTION_LOCK (connection);
05856 res = _dbus_transport_get_max_message_size (connection->transport);
05857 CONNECTION_UNLOCK (connection);
05858 return res;
05859 }
05860
05886 void
05887 dbus_connection_set_max_received_size (DBusConnection *connection,
05888 long size)
05889 {
05890 _dbus_return_if_fail (connection != NULL);
05891
05892 CONNECTION_LOCK (connection);
05893 _dbus_transport_set_max_received_size (connection->transport,
05894 size);
05895 CONNECTION_UNLOCK (connection);
05896 }
05897
05904 long
05905 dbus_connection_get_max_received_size (DBusConnection *connection)
05906 {
05907 long res;
05908
05909 _dbus_return_val_if_fail (connection != NULL, 0);
05910
05911 CONNECTION_LOCK (connection);
05912 res = _dbus_transport_get_max_received_size (connection->transport);
05913 CONNECTION_UNLOCK (connection);
05914 return res;
05915 }
05916
05927 long
05928 dbus_connection_get_outgoing_size (DBusConnection *connection)
05929 {
05930 long res;
05931
05932 _dbus_return_val_if_fail (connection != NULL, 0);
05933
05934 CONNECTION_LOCK (connection);
05935 res = _dbus_counter_get_value (connection->outgoing_counter);
05936 CONNECTION_UNLOCK (connection);
05937 return res;
05938 }
05939