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
01439 if (!_dbus_connection_acquire_io_path (connection, 1))
01440 {
01441
01442 CONNECTION_UNLOCK (connection);
01443 return TRUE;
01444 }
01445
01446 HAVE_LOCK_CHECK (connection);
01447 retval = _dbus_transport_handle_watch (connection->transport,
01448 watch, condition);
01449
01450 _dbus_connection_release_io_path (connection);
01451
01452 HAVE_LOCK_CHECK (connection);
01453
01454 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
01455
01456 status = _dbus_connection_get_dispatch_status_unlocked (connection);
01457
01458
01459 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01460
01461 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
01462
01463 return retval;
01464 }
01465
01466 _DBUS_DEFINE_GLOBAL_LOCK (shared_connections);
01467 static DBusHashTable *shared_connections = NULL;
01468 static DBusList *shared_connections_no_guid = NULL;
01469
01470 static void
01471 close_connection_on_shutdown (DBusConnection *connection)
01472 {
01473 DBusMessage *message;
01474
01475 dbus_connection_ref (connection);
01476 _dbus_connection_close_possibly_shared (connection);
01477
01478
01479 while ((message = dbus_connection_pop_message (connection)))
01480 {
01481 dbus_message_unref (message);
01482 }
01483 dbus_connection_unref (connection);
01484 }
01485
01486 static void
01487 shared_connections_shutdown (void *data)
01488 {
01489 int n_entries;
01490
01491 _DBUS_LOCK (shared_connections);
01492
01493
01494 while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0)
01495 {
01496 DBusConnection *connection;
01497 DBusHashIter iter;
01498
01499 _dbus_hash_iter_init (shared_connections, &iter);
01500 _dbus_hash_iter_next (&iter);
01501
01502 connection = _dbus_hash_iter_get_value (&iter);
01503
01504 _DBUS_UNLOCK (shared_connections);
01505 close_connection_on_shutdown (connection);
01506 _DBUS_LOCK (shared_connections);
01507
01508
01509 _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) < n_entries);
01510 }
01511
01512 _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) == 0);
01513
01514 _dbus_hash_table_unref (shared_connections);
01515 shared_connections = NULL;
01516
01517 if (shared_connections_no_guid != NULL)
01518 {
01519 DBusConnection *connection;
01520 connection = _dbus_list_pop_first (&shared_connections_no_guid);
01521 while (connection != NULL)
01522 {
01523 _DBUS_UNLOCK (shared_connections);
01524 close_connection_on_shutdown (connection);
01525 _DBUS_LOCK (shared_connections);
01526 connection = _dbus_list_pop_first (&shared_connections_no_guid);
01527 }
01528 }
01529
01530 shared_connections_no_guid = NULL;
01531
01532 _DBUS_UNLOCK (shared_connections);
01533 }
01534
01535 static dbus_bool_t
01536 connection_lookup_shared (DBusAddressEntry *entry,
01537 DBusConnection **result)
01538 {
01539 _dbus_verbose ("checking for existing connection\n");
01540
01541 *result = NULL;
01542
01543 _DBUS_LOCK (shared_connections);
01544
01545 if (shared_connections == NULL)
01546 {
01547 _dbus_verbose ("creating shared_connections hash table\n");
01548
01549 shared_connections = _dbus_hash_table_new (DBUS_HASH_STRING,
01550 dbus_free,
01551 NULL);
01552 if (shared_connections == NULL)
01553 {
01554 _DBUS_UNLOCK (shared_connections);
01555 return FALSE;
01556 }
01557
01558 if (!_dbus_register_shutdown_func (shared_connections_shutdown, NULL))
01559 {
01560 _dbus_hash_table_unref (shared_connections);
01561 shared_connections = NULL;
01562 _DBUS_UNLOCK (shared_connections);
01563 return FALSE;
01564 }
01565
01566 _dbus_verbose (" successfully created shared_connections\n");
01567
01568 _DBUS_UNLOCK (shared_connections);
01569 return TRUE;
01570 }
01571 else
01572 {
01573 const char *guid;
01574
01575 guid = dbus_address_entry_get_value (entry, "guid");
01576
01577 if (guid != NULL)
01578 {
01579 DBusConnection *connection;
01580
01581 connection = _dbus_hash_table_lookup_string (shared_connections,
01582 guid);
01583
01584 if (connection)
01585 {
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600 CONNECTION_LOCK (connection);
01601 if (_dbus_connection_get_is_connected_unlocked (connection))
01602 {
01603 _dbus_connection_ref_unlocked (connection);
01604 *result = connection;
01605 _dbus_verbose ("looked up existing connection to server guid %s\n",
01606 guid);
01607 }
01608 else
01609 {
01610 _dbus_verbose ("looked up existing connection to server guid %s but it was disconnected so ignoring it\n",
01611 guid);
01612 }
01613 CONNECTION_UNLOCK (connection);
01614 }
01615 }
01616
01617 _DBUS_UNLOCK (shared_connections);
01618 return TRUE;
01619 }
01620 }
01621
01622 static dbus_bool_t
01623 connection_record_shared_unlocked (DBusConnection *connection,
01624 const char *guid)
01625 {
01626 char *guid_key;
01627 char *guid_in_connection;
01628
01629 HAVE_LOCK_CHECK (connection);
01630 _dbus_assert (connection->server_guid == NULL);
01631 _dbus_assert (connection->shareable);
01632
01633
01634
01635
01636
01637 _dbus_connection_ref_unlocked (connection);
01638
01639 if (guid == NULL)
01640 {
01641 _DBUS_LOCK (shared_connections);
01642
01643 if (!_dbus_list_prepend (&shared_connections_no_guid, connection))
01644 {
01645 _DBUS_UNLOCK (shared_connections);
01646 return FALSE;
01647 }
01648
01649 _DBUS_UNLOCK (shared_connections);
01650 return TRUE;
01651 }
01652
01653
01654
01655
01656
01657
01658 guid_key = _dbus_strdup (guid);
01659 if (guid_key == NULL)
01660 return FALSE;
01661
01662 guid_in_connection = _dbus_strdup (guid);
01663 if (guid_in_connection == NULL)
01664 {
01665 dbus_free (guid_key);
01666 return FALSE;
01667 }
01668
01669 _DBUS_LOCK (shared_connections);
01670 _dbus_assert (shared_connections != NULL);
01671
01672 if (!_dbus_hash_table_insert_string (shared_connections,
01673 guid_key, connection))
01674 {
01675 dbus_free (guid_key);
01676 dbus_free (guid_in_connection);
01677 _DBUS_UNLOCK (shared_connections);
01678 return FALSE;
01679 }
01680
01681 connection->server_guid = guid_in_connection;
01682
01683 _dbus_verbose ("stored connection to %s to be shared\n",
01684 connection->server_guid);
01685
01686 _DBUS_UNLOCK (shared_connections);
01687
01688 _dbus_assert (connection->server_guid != NULL);
01689
01690 return TRUE;
01691 }
01692
01693 static void
01694 connection_forget_shared_unlocked (DBusConnection *connection)
01695 {
01696 HAVE_LOCK_CHECK (connection);
01697
01698 if (!connection->shareable)
01699 return;
01700
01701 _DBUS_LOCK (shared_connections);
01702
01703 if (connection->server_guid != NULL)
01704 {
01705 _dbus_verbose ("dropping connection to %s out of the shared table\n",
01706 connection->server_guid);
01707
01708 if (!_dbus_hash_table_remove_string (shared_connections,
01709 connection->server_guid))
01710 _dbus_assert_not_reached ("connection was not in the shared table");
01711
01712 dbus_free (connection->server_guid);
01713 connection->server_guid = NULL;
01714 }
01715 else
01716 {
01717 _dbus_list_remove (&shared_connections_no_guid, connection);
01718 }
01719
01720 _DBUS_UNLOCK (shared_connections);
01721
01722
01723 _dbus_connection_unref_unlocked (connection);
01724 }
01725
01726 static DBusConnection*
01727 connection_try_from_address_entry (DBusAddressEntry *entry,
01728 DBusError *error)
01729 {
01730 DBusTransport *transport;
01731 DBusConnection *connection;
01732
01733 transport = _dbus_transport_open (entry, error);
01734
01735 if (transport == NULL)
01736 {
01737 _DBUS_ASSERT_ERROR_IS_SET (error);
01738 return NULL;
01739 }
01740
01741 connection = _dbus_connection_new_for_transport (transport);
01742
01743 _dbus_transport_unref (transport);
01744
01745 if (connection == NULL)
01746 {
01747 _DBUS_SET_OOM (error);
01748 return NULL;
01749 }
01750
01751 #ifndef DBUS_DISABLE_CHECKS
01752 _dbus_assert (!connection->have_connection_lock);
01753 #endif
01754 return connection;
01755 }
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769 static DBusConnection*
01770 _dbus_connection_open_internal (const char *address,
01771 dbus_bool_t shared,
01772 DBusError *error)
01773 {
01774 DBusConnection *connection;
01775 DBusAddressEntry **entries;
01776 DBusError tmp_error = DBUS_ERROR_INIT;
01777 DBusError first_error = DBUS_ERROR_INIT;
01778 int len, i;
01779
01780 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01781
01782 _dbus_verbose ("opening %s connection to: %s\n",
01783 shared ? "shared" : "private", address);
01784
01785 if (!dbus_parse_address (address, &entries, &len, error))
01786 return NULL;
01787
01788 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01789
01790 connection = NULL;
01791
01792 for (i = 0; i < len; i++)
01793 {
01794 if (shared)
01795 {
01796 if (!connection_lookup_shared (entries[i], &connection))
01797 _DBUS_SET_OOM (&tmp_error);
01798 }
01799
01800 if (connection == NULL)
01801 {
01802 connection = connection_try_from_address_entry (entries[i],
01803 &tmp_error);
01804
01805 if (connection != NULL && shared)
01806 {
01807 const char *guid;
01808
01809 connection->shareable = TRUE;
01810
01811
01812 guid = dbus_address_entry_get_value (entries[i], "guid");
01813
01814 CONNECTION_LOCK (connection);
01815
01816 if (!connection_record_shared_unlocked (connection, guid))
01817 {
01818 _DBUS_SET_OOM (&tmp_error);
01819 _dbus_connection_close_possibly_shared_and_unlock (connection);
01820 dbus_connection_unref (connection);
01821 connection = NULL;
01822 }
01823 else
01824 CONNECTION_UNLOCK (connection);
01825 }
01826 }
01827
01828 if (connection)
01829 break;
01830
01831 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
01832
01833 if (i == 0)
01834 dbus_move_error (&tmp_error, &first_error);
01835 else
01836 dbus_error_free (&tmp_error);
01837 }
01838
01839 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01840 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
01841
01842 if (connection == NULL)
01843 {
01844 _DBUS_ASSERT_ERROR_IS_SET (&first_error);
01845 dbus_move_error (&first_error, error);
01846 }
01847 else
01848 dbus_error_free (&first_error);
01849
01850 dbus_address_entries_free (entries);
01851 return connection;
01852 }
01853
01862 void
01863 _dbus_connection_close_possibly_shared (DBusConnection *connection)
01864 {
01865 _dbus_assert (connection != NULL);
01866 _dbus_assert (connection->generation == _dbus_current_generation);
01867
01868 CONNECTION_LOCK (connection);
01869 _dbus_connection_close_possibly_shared_and_unlock (connection);
01870 }
01871
01872 static DBusPreallocatedSend*
01873 _dbus_connection_preallocate_send_unlocked (DBusConnection *connection)
01874 {
01875 DBusPreallocatedSend *preallocated;
01876
01877 HAVE_LOCK_CHECK (connection);
01878
01879 _dbus_assert (connection != NULL);
01880
01881 preallocated = dbus_new (DBusPreallocatedSend, 1);
01882 if (preallocated == NULL)
01883 return NULL;
01884
01885 if (connection->link_cache != NULL)
01886 {
01887 preallocated->queue_link =
01888 _dbus_list_pop_first_link (&connection->link_cache);
01889 preallocated->queue_link->data = NULL;
01890 }
01891 else
01892 {
01893 preallocated->queue_link = _dbus_list_alloc_link (NULL);
01894 if (preallocated->queue_link == NULL)
01895 goto failed_0;
01896 }
01897
01898 if (connection->link_cache != NULL)
01899 {
01900 preallocated->counter_link =
01901 _dbus_list_pop_first_link (&connection->link_cache);
01902 preallocated->counter_link->data = connection->outgoing_counter;
01903 }
01904 else
01905 {
01906 preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter);
01907 if (preallocated->counter_link == NULL)
01908 goto failed_1;
01909 }
01910
01911 _dbus_counter_ref (preallocated->counter_link->data);
01912
01913 preallocated->connection = connection;
01914
01915 return preallocated;
01916
01917 failed_1:
01918 _dbus_list_free_link (preallocated->queue_link);
01919 failed_0:
01920 dbus_free (preallocated);
01921
01922 return NULL;
01923 }
01924
01925
01926 static void
01927 _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *connection,
01928 DBusPreallocatedSend *preallocated,
01929 DBusMessage *message,
01930 dbus_uint32_t *client_serial)
01931 {
01932 dbus_uint32_t serial;
01933 const char *sig;
01934
01935 preallocated->queue_link->data = message;
01936 _dbus_list_prepend_link (&connection->outgoing_messages,
01937 preallocated->queue_link);
01938
01939 _dbus_message_add_size_counter_link (message,
01940 preallocated->counter_link);
01941
01942 dbus_free (preallocated);
01943 preallocated = NULL;
01944
01945 dbus_message_ref (message);
01946
01947 connection->n_outgoing += 1;
01948
01949 sig = dbus_message_get_signature (message);
01950
01951 _dbus_verbose ("Message %p (%d %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
01952 message,
01953 dbus_message_get_type (message),
01954 dbus_message_get_path (message) ?
01955 dbus_message_get_path (message) :
01956 "no path",
01957 dbus_message_get_interface (message) ?
01958 dbus_message_get_interface (message) :
01959 "no interface",
01960 dbus_message_get_member (message) ?
01961 dbus_message_get_member (message) :
01962 "no member",
01963 sig,
01964 dbus_message_get_destination (message) ?
01965 dbus_message_get_destination (message) :
01966 "null",
01967 connection,
01968 connection->n_outgoing);
01969
01970 if (dbus_message_get_serial (message) == 0)
01971 {
01972 serial = _dbus_connection_get_next_client_serial (connection);
01973 dbus_message_set_serial (message, serial);
01974 if (client_serial)
01975 *client_serial = serial;
01976 }
01977 else
01978 {
01979 if (client_serial)
01980 *client_serial = dbus_message_get_serial (message);
01981 }
01982
01983 _dbus_verbose ("Message %p serial is %u\n",
01984 message, dbus_message_get_serial (message));
01985
01986 dbus_message_lock (message);
01987
01988
01989
01990
01991 _dbus_connection_do_iteration_unlocked (connection,
01992 DBUS_ITERATION_DO_WRITING,
01993 -1);
01994
01995
01996 if (connection->n_outgoing > 0)
01997 _dbus_connection_wakeup_mainloop (connection);
01998 }
01999
02000 static void
02001 _dbus_connection_send_preallocated_and_unlock (DBusConnection *connection,
02002 DBusPreallocatedSend *preallocated,
02003 DBusMessage *message,
02004 dbus_uint32_t *client_serial)
02005 {
02006 DBusDispatchStatus status;
02007
02008 HAVE_LOCK_CHECK (connection);
02009
02010 _dbus_connection_send_preallocated_unlocked_no_update (connection,
02011 preallocated,
02012 message, client_serial);
02013
02014 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
02015 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02016
02017
02018 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02019 }
02020
02030 dbus_bool_t
02031 _dbus_connection_send_and_unlock (DBusConnection *connection,
02032 DBusMessage *message,
02033 dbus_uint32_t *client_serial)
02034 {
02035 DBusPreallocatedSend *preallocated;
02036
02037 _dbus_assert (connection != NULL);
02038 _dbus_assert (message != NULL);
02039
02040 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
02041 if (preallocated == NULL)
02042 {
02043 CONNECTION_UNLOCK (connection);
02044 return FALSE;
02045 }
02046
02047 _dbus_connection_send_preallocated_and_unlock (connection,
02048 preallocated,
02049 message,
02050 client_serial);
02051 return TRUE;
02052 }
02053
02078 void
02079 _dbus_connection_close_if_only_one_ref (DBusConnection *connection)
02080 {
02081 CONNECTION_LOCK (connection);
02082
02083 _dbus_assert (connection->refcount.value > 0);
02084
02085 if (connection->refcount.value == 1)
02086 _dbus_connection_close_possibly_shared_and_unlock (connection);
02087 else
02088 CONNECTION_UNLOCK (connection);
02089 }
02090
02091
02101 static void
02102 _dbus_memory_pause_based_on_timeout (int timeout_milliseconds)
02103 {
02104 if (timeout_milliseconds == -1)
02105 _dbus_sleep_milliseconds (1000);
02106 else if (timeout_milliseconds < 100)
02107 ;
02108 else if (timeout_milliseconds <= 1000)
02109 _dbus_sleep_milliseconds (timeout_milliseconds / 3);
02110 else
02111 _dbus_sleep_milliseconds (1000);
02112 }
02113
02114 static DBusMessage *
02115 generate_local_error_message (dbus_uint32_t serial,
02116 char *error_name,
02117 char *error_msg)
02118 {
02119 DBusMessage *message;
02120 message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
02121 if (!message)
02122 goto out;
02123
02124 if (!dbus_message_set_error_name (message, error_name))
02125 {
02126 dbus_message_unref (message);
02127 message = NULL;
02128 goto out;
02129 }
02130
02131 dbus_message_set_no_reply (message, TRUE);
02132
02133 if (!dbus_message_set_reply_serial (message,
02134 serial))
02135 {
02136 dbus_message_unref (message);
02137 message = NULL;
02138 goto out;
02139 }
02140
02141 if (error_msg != NULL)
02142 {
02143 DBusMessageIter iter;
02144
02145 dbus_message_iter_init_append (message, &iter);
02146 if (!dbus_message_iter_append_basic (&iter,
02147 DBUS_TYPE_STRING,
02148 &error_msg))
02149 {
02150 dbus_message_unref (message);
02151 message = NULL;
02152 goto out;
02153 }
02154 }
02155
02156 out:
02157 return message;
02158 }
02159
02160
02161
02162
02163
02164 static DBusMessage*
02165 check_for_reply_unlocked (DBusConnection *connection,
02166 dbus_uint32_t client_serial)
02167 {
02168 DBusList *link;
02169
02170 HAVE_LOCK_CHECK (connection);
02171
02172 link = _dbus_list_get_first_link (&connection->incoming_messages);
02173
02174 while (link != NULL)
02175 {
02176 DBusMessage *reply = link->data;
02177
02178 if (dbus_message_get_reply_serial (reply) == client_serial)
02179 {
02180 _dbus_list_remove_link (&connection->incoming_messages, link);
02181 connection->n_incoming -= 1;
02182 return reply;
02183 }
02184 link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02185 }
02186
02187 return NULL;
02188 }
02189
02190 static void
02191 connection_timeout_and_complete_all_pending_calls_unlocked (DBusConnection *connection)
02192 {
02193
02194
02195
02196
02197
02198 while (_dbus_hash_table_get_n_entries (connection->pending_replies) > 0)
02199 {
02200 DBusPendingCall *pending;
02201 DBusHashIter iter;
02202
02203 _dbus_hash_iter_init (connection->pending_replies, &iter);
02204 _dbus_hash_iter_next (&iter);
02205
02206 pending = _dbus_hash_iter_get_value (&iter);
02207 _dbus_pending_call_ref_unlocked (pending);
02208
02209 _dbus_pending_call_queue_timeout_error_unlocked (pending,
02210 connection);
02211
02212 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
02213 _dbus_connection_remove_timeout_unlocked (connection,
02214 _dbus_pending_call_get_timeout_unlocked (pending));
02215 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
02216 _dbus_hash_iter_remove_entry (&iter);
02217
02218 _dbus_pending_call_unref_and_unlock (pending);
02219 CONNECTION_LOCK (connection);
02220 }
02221 HAVE_LOCK_CHECK (connection);
02222 }
02223
02224 static void
02225 complete_pending_call_and_unlock (DBusConnection *connection,
02226 DBusPendingCall *pending,
02227 DBusMessage *message)
02228 {
02229 _dbus_pending_call_set_reply_unlocked (pending, message);
02230 _dbus_pending_call_ref_unlocked (pending);
02231 _dbus_connection_detach_pending_call_and_unlock (connection, pending);
02232
02233
02234 _dbus_pending_call_complete (pending);
02235 dbus_pending_call_unref (pending);
02236 }
02237
02238 static dbus_bool_t
02239 check_for_reply_and_update_dispatch_unlocked (DBusConnection *connection,
02240 DBusPendingCall *pending)
02241 {
02242 DBusMessage *reply;
02243 DBusDispatchStatus status;
02244
02245 reply = check_for_reply_unlocked (connection,
02246 _dbus_pending_call_get_reply_serial_unlocked (pending));
02247 if (reply != NULL)
02248 {
02249 _dbus_verbose ("%s checked for reply\n", _DBUS_FUNCTION_NAME);
02250
02251 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
02252
02253 complete_pending_call_and_unlock (connection, pending, reply);
02254 dbus_message_unref (reply);
02255
02256 CONNECTION_LOCK (connection);
02257 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02258 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02259 dbus_pending_call_unref (pending);
02260
02261 return TRUE;
02262 }
02263
02264 return FALSE;
02265 }
02266
02281 void
02282 _dbus_connection_block_pending_call (DBusPendingCall *pending)
02283 {
02284 long start_tv_sec, start_tv_usec;
02285 long tv_sec, tv_usec;
02286 DBusDispatchStatus status;
02287 DBusConnection *connection;
02288 dbus_uint32_t client_serial;
02289 DBusTimeout *timeout;
02290 int timeout_milliseconds, elapsed_milliseconds;
02291
02292 _dbus_assert (pending != NULL);
02293
02294 if (dbus_pending_call_get_completed (pending))
02295 return;
02296
02297 dbus_pending_call_ref (pending);
02298
02299 connection = _dbus_pending_call_get_connection_and_lock (pending);
02300
02301
02302 _dbus_connection_flush_unlocked (connection);
02303
02304 client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
02305
02306
02307
02308
02309
02310 timeout = _dbus_pending_call_get_timeout_unlocked (pending);
02311 if (timeout)
02312 {
02313 timeout_milliseconds = dbus_timeout_get_interval (timeout);
02314 _dbus_get_current_time (&start_tv_sec, &start_tv_usec);
02315
02316 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec\n",
02317 timeout_milliseconds,
02318 client_serial,
02319 start_tv_sec, start_tv_usec);
02320 }
02321 else
02322 {
02323 timeout_milliseconds = -1;
02324
02325 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block for reply serial %u\n", client_serial);
02326 }
02327
02328
02329
02330 if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02331 return;
02332
02333
02334
02335 _dbus_connection_do_iteration_unlocked (connection,
02336 DBUS_ITERATION_DO_READING |
02337 DBUS_ITERATION_BLOCK,
02338 timeout_milliseconds);
02339
02340 recheck_status:
02341
02342 _dbus_verbose ("%s top of recheck\n", _DBUS_FUNCTION_NAME);
02343
02344 HAVE_LOCK_CHECK (connection);
02345
02346
02347
02348 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02349
02350
02351
02352
02353 if (_dbus_pending_call_get_completed_unlocked (pending))
02354 {
02355 _dbus_verbose ("Pending call completed by dispatch in %s\n", _DBUS_FUNCTION_NAME);
02356 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02357 dbus_pending_call_unref (pending);
02358 return;
02359 }
02360
02361 if (status == DBUS_DISPATCH_DATA_REMAINS)
02362 {
02363 if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02364 return;
02365 }
02366
02367 _dbus_get_current_time (&tv_sec, &tv_usec);
02368 elapsed_milliseconds = (tv_sec - start_tv_sec) * 1000 +
02369 (tv_usec - start_tv_usec) / 1000;
02370
02371 if (!_dbus_connection_get_is_connected_unlocked (connection))
02372 {
02373 DBusMessage *error_msg;
02374
02375 error_msg = generate_local_error_message (client_serial,
02376 DBUS_ERROR_DISCONNECTED,
02377 "Connection was disconnected before a reply was received");
02378
02379
02380 complete_pending_call_and_unlock (connection, pending, error_msg);
02381 dbus_pending_call_unref (pending);
02382 return;
02383 }
02384 else if (connection->disconnect_message_link == NULL)
02385 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
02386 else if (timeout == NULL)
02387 {
02388 if (status == DBUS_DISPATCH_NEED_MEMORY)
02389 {
02390
02391
02392
02393
02394 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02395
02396 _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
02397 }
02398 else
02399 {
02400
02401 _dbus_connection_do_iteration_unlocked (connection,
02402 DBUS_ITERATION_DO_READING |
02403 DBUS_ITERATION_BLOCK,
02404 timeout_milliseconds - elapsed_milliseconds);
02405 }
02406
02407 goto recheck_status;
02408 }
02409 else if (tv_sec < start_tv_sec)
02410 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
02411 else if (elapsed_milliseconds < timeout_milliseconds)
02412 {
02413 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds - elapsed_milliseconds);
02414
02415 if (status == DBUS_DISPATCH_NEED_MEMORY)
02416 {
02417
02418
02419
02420
02421 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02422
02423 _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
02424 }
02425 else
02426 {
02427
02428 _dbus_connection_do_iteration_unlocked (connection,
02429 DBUS_ITERATION_DO_READING |
02430 DBUS_ITERATION_BLOCK,
02431 timeout_milliseconds - elapsed_milliseconds);
02432 }
02433
02434 goto recheck_status;
02435 }
02436
02437 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %d milliseconds and got no reply\n",
02438 elapsed_milliseconds);
02439
02440 _dbus_assert (!_dbus_pending_call_get_completed_unlocked (pending));
02441
02442
02443 complete_pending_call_and_unlock (connection, pending, NULL);
02444
02445
02446 CONNECTION_LOCK (connection);
02447 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02448 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02449 dbus_pending_call_unref (pending);
02450 }
02451
02488 DBusConnection*
02489 dbus_connection_open (const char *address,
02490 DBusError *error)
02491 {
02492 DBusConnection *connection;
02493
02494 _dbus_return_val_if_fail (address != NULL, NULL);
02495 _dbus_return_val_if_error_is_set (error, NULL);
02496
02497 connection = _dbus_connection_open_internal (address,
02498 TRUE,
02499 error);
02500
02501 return connection;
02502 }
02503
02531 DBusConnection*
02532 dbus_connection_open_private (const char *address,
02533 DBusError *error)
02534 {
02535 DBusConnection *connection;
02536
02537 _dbus_return_val_if_fail (address != NULL, NULL);
02538 _dbus_return_val_if_error_is_set (error, NULL);
02539
02540 connection = _dbus_connection_open_internal (address,
02541 FALSE,
02542 error);
02543
02544 return connection;
02545 }
02546
02553 DBusConnection *
02554 dbus_connection_ref (DBusConnection *connection)
02555 {
02556 _dbus_return_val_if_fail (connection != NULL, NULL);
02557 _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
02558
02559
02560
02561
02562
02563 #ifdef DBUS_HAVE_ATOMIC_INT
02564 _dbus_atomic_inc (&connection->refcount);
02565 #else
02566 CONNECTION_LOCK (connection);
02567 _dbus_assert (connection->refcount.value > 0);
02568
02569 connection->refcount.value += 1;
02570 CONNECTION_UNLOCK (connection);
02571 #endif
02572
02573 return connection;
02574 }
02575
02576 static void
02577 free_outgoing_message (void *element,
02578 void *data)
02579 {
02580 DBusMessage *message = element;
02581 DBusConnection *connection = data;
02582
02583 _dbus_message_remove_size_counter (message,
02584 connection->outgoing_counter,
02585 NULL);
02586 dbus_message_unref (message);
02587 }
02588
02589
02590
02591
02592
02593 static void
02594 _dbus_connection_last_unref (DBusConnection *connection)
02595 {
02596 DBusList *link;
02597
02598 _dbus_verbose ("Finalizing connection %p\n", connection);
02599
02600 _dbus_assert (connection->refcount.value == 0);
02601
02602
02603
02604
02605 _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
02606 _dbus_assert (connection->server_guid == NULL);
02607
02608
02609 _dbus_object_tree_free_all_unlocked (connection->objects);
02610
02611 dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
02612 dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
02613 dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
02614
02615 _dbus_watch_list_free (connection->watches);
02616 connection->watches = NULL;
02617
02618 _dbus_timeout_list_free (connection->timeouts);
02619 connection->timeouts = NULL;
02620
02621 _dbus_data_slot_list_free (&connection->slot_list);
02622
02623 link = _dbus_list_get_first_link (&connection->filter_list);
02624 while (link != NULL)
02625 {
02626 DBusMessageFilter *filter = link->data;
02627 DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
02628
02629 filter->function = NULL;
02630 _dbus_message_filter_unref (filter);
02631 link->data = NULL;
02632
02633 link = next;
02634 }
02635 _dbus_list_clear (&connection->filter_list);
02636
02637
02638
02639 _dbus_object_tree_unref (connection->objects);
02640
02641 _dbus_hash_table_unref (connection->pending_replies);
02642 connection->pending_replies = NULL;
02643
02644 _dbus_list_clear (&connection->filter_list);
02645
02646 _dbus_list_foreach (&connection->outgoing_messages,
02647 free_outgoing_message,
02648 connection);
02649 _dbus_list_clear (&connection->outgoing_messages);
02650
02651 _dbus_list_foreach (&connection->incoming_messages,
02652 (DBusForeachFunction) dbus_message_unref,
02653 NULL);
02654 _dbus_list_clear (&connection->incoming_messages);
02655
02656 _dbus_counter_unref (connection->outgoing_counter);
02657
02658 _dbus_transport_unref (connection->transport);
02659
02660 if (connection->disconnect_message_link)
02661 {
02662 DBusMessage *message = connection->disconnect_message_link->data;
02663 dbus_message_unref (message);
02664 _dbus_list_free_link (connection->disconnect_message_link);
02665 }
02666
02667 _dbus_list_clear (&connection->link_cache);
02668
02669 _dbus_condvar_free_at_location (&connection->dispatch_cond);
02670 _dbus_condvar_free_at_location (&connection->io_path_cond);
02671
02672 _dbus_mutex_free_at_location (&connection->io_path_mutex);
02673 _dbus_mutex_free_at_location (&connection->dispatch_mutex);
02674
02675 _dbus_mutex_free_at_location (&connection->mutex);
02676
02677 dbus_free (connection);
02678 }
02679
02699 void
02700 dbus_connection_unref (DBusConnection *connection)
02701 {
02702 dbus_bool_t last_unref;
02703
02704 _dbus_return_if_fail (connection != NULL);
02705 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02706
02707
02708
02709
02710
02711 #ifdef DBUS_HAVE_ATOMIC_INT
02712 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
02713 #else
02714 CONNECTION_LOCK (connection);
02715
02716 _dbus_assert (connection->refcount.value > 0);
02717
02718 connection->refcount.value -= 1;
02719 last_unref = (connection->refcount.value == 0);
02720
02721 #if 0
02722 printf ("unref() connection %p count = %d\n", connection, connection->refcount.value);
02723 #endif
02724
02725 CONNECTION_UNLOCK (connection);
02726 #endif
02727
02728 if (last_unref)
02729 {
02730 #ifndef DBUS_DISABLE_CHECKS
02731 if (_dbus_transport_get_is_connected (connection->transport))
02732 {
02733 _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",
02734 connection->shareable ?
02735 "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" :
02736 "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n");
02737 return;
02738 }
02739 #endif
02740 _dbus_connection_last_unref (connection);
02741 }
02742 }
02743
02744
02745
02746
02747
02748
02749
02750
02751
02752
02753 static void
02754 _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection)
02755 {
02756 DBusDispatchStatus status;
02757
02758 HAVE_LOCK_CHECK (connection);
02759
02760 _dbus_verbose ("Disconnecting %p\n", connection);
02761
02762
02763
02764
02765
02766 _dbus_connection_ref_unlocked (connection);
02767
02768 _dbus_transport_disconnect (connection->transport);
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02780
02781
02782 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02783
02784
02785 dbus_connection_unref (connection);
02786 }
02787
02830 void
02831 dbus_connection_close (DBusConnection *connection)
02832 {
02833 _dbus_return_if_fail (connection != NULL);
02834 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02835
02836 CONNECTION_LOCK (connection);
02837
02838 #ifndef DBUS_DISABLE_CHECKS
02839 if (connection->shareable)
02840 {
02841 CONNECTION_UNLOCK (connection);
02842
02843 _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n");
02844 return;
02845 }
02846 #endif
02847
02848 _dbus_connection_close_possibly_shared_and_unlock (connection);
02849 }
02850
02851 static dbus_bool_t
02852 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
02853 {
02854 HAVE_LOCK_CHECK (connection);
02855 return _dbus_transport_get_is_connected (connection->transport);
02856 }
02857
02871 dbus_bool_t
02872 dbus_connection_get_is_connected (DBusConnection *connection)
02873 {
02874 dbus_bool_t res;
02875
02876 _dbus_return_val_if_fail (connection != NULL, FALSE);
02877
02878 CONNECTION_LOCK (connection);
02879 res = _dbus_connection_get_is_connected_unlocked (connection);
02880 CONNECTION_UNLOCK (connection);
02881
02882 return res;
02883 }
02884
02893 dbus_bool_t
02894 dbus_connection_get_is_authenticated (DBusConnection *connection)
02895 {
02896 dbus_bool_t res;
02897
02898 _dbus_return_val_if_fail (connection != NULL, FALSE);
02899
02900 CONNECTION_LOCK (connection);
02901 res = _dbus_transport_get_is_authenticated (connection->transport);
02902 CONNECTION_UNLOCK (connection);
02903
02904 return res;
02905 }
02906
02927 dbus_bool_t
02928 dbus_connection_get_is_anonymous (DBusConnection *connection)
02929 {
02930 dbus_bool_t res;
02931
02932 _dbus_return_val_if_fail (connection != NULL, FALSE);
02933
02934 CONNECTION_LOCK (connection);
02935 res = _dbus_transport_get_is_anonymous (connection->transport);
02936 CONNECTION_UNLOCK (connection);
02937
02938 return res;
02939 }
02940
02972 char*
02973 dbus_connection_get_server_id (DBusConnection *connection)
02974 {
02975 char *id;
02976
02977 _dbus_return_val_if_fail (connection != NULL, NULL);
02978
02979 CONNECTION_LOCK (connection);
02980 id = _dbus_strdup (_dbus_transport_get_server_id (connection->transport));
02981 CONNECTION_UNLOCK (connection);
02982
02983 return id;
02984 }
02985
02999 void
03000 dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
03001 dbus_bool_t exit_on_disconnect)
03002 {
03003 _dbus_return_if_fail (connection != NULL);
03004
03005 CONNECTION_LOCK (connection);
03006 connection->exit_on_disconnect = exit_on_disconnect != FALSE;
03007 CONNECTION_UNLOCK (connection);
03008 }
03009
03019 DBusPreallocatedSend*
03020 dbus_connection_preallocate_send (DBusConnection *connection)
03021 {
03022 DBusPreallocatedSend *preallocated;
03023
03024 _dbus_return_val_if_fail (connection != NULL, NULL);
03025
03026 CONNECTION_LOCK (connection);
03027
03028 preallocated =
03029 _dbus_connection_preallocate_send_unlocked (connection);
03030
03031 CONNECTION_UNLOCK (connection);
03032
03033 return preallocated;
03034 }
03035
03045 void
03046 dbus_connection_free_preallocated_send (DBusConnection *connection,
03047 DBusPreallocatedSend *preallocated)
03048 {
03049 _dbus_return_if_fail (connection != NULL);
03050 _dbus_return_if_fail (preallocated != NULL);
03051 _dbus_return_if_fail (connection == preallocated->connection);
03052
03053 _dbus_list_free_link (preallocated->queue_link);
03054 _dbus_counter_unref (preallocated->counter_link->data);
03055 _dbus_list_free_link (preallocated->counter_link);
03056 dbus_free (preallocated);
03057 }
03058
03071 void
03072 dbus_connection_send_preallocated (DBusConnection *connection,
03073 DBusPreallocatedSend *preallocated,
03074 DBusMessage *message,
03075 dbus_uint32_t *client_serial)
03076 {
03077 _dbus_return_if_fail (connection != NULL);
03078 _dbus_return_if_fail (preallocated != NULL);
03079 _dbus_return_if_fail (message != NULL);
03080 _dbus_return_if_fail (preallocated->connection == connection);
03081 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
03082 dbus_message_get_member (message) != NULL);
03083 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
03084 (dbus_message_get_interface (message) != NULL &&
03085 dbus_message_get_member (message) != NULL));
03086
03087 CONNECTION_LOCK (connection);
03088 _dbus_connection_send_preallocated_and_unlock (connection,
03089 preallocated,
03090 message, client_serial);
03091 }
03092
03093 static dbus_bool_t
03094 _dbus_connection_send_unlocked_no_update (DBusConnection *connection,
03095 DBusMessage *message,
03096 dbus_uint32_t *client_serial)
03097 {
03098 DBusPreallocatedSend *preallocated;
03099
03100 _dbus_assert (connection != NULL);
03101 _dbus_assert (message != NULL);
03102
03103 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
03104 if (preallocated == NULL)
03105 return FALSE;
03106
03107 _dbus_connection_send_preallocated_unlocked_no_update (connection,
03108 preallocated,
03109 message,
03110 client_serial);
03111 return TRUE;
03112 }
03113
03141 dbus_bool_t
03142 dbus_connection_send (DBusConnection *connection,
03143 DBusMessage *message,
03144 dbus_uint32_t *serial)
03145 {
03146 _dbus_return_val_if_fail (connection != NULL, FALSE);
03147 _dbus_return_val_if_fail (message != NULL, FALSE);
03148
03149 CONNECTION_LOCK (connection);
03150
03151 return _dbus_connection_send_and_unlock (connection,
03152 message,
03153 serial);
03154 }
03155
03156 static dbus_bool_t
03157 reply_handler_timeout (void *data)
03158 {
03159 DBusConnection *connection;
03160 DBusDispatchStatus status;
03161 DBusPendingCall *pending = data;
03162
03163 connection = _dbus_pending_call_get_connection_and_lock (pending);
03164
03165 _dbus_pending_call_queue_timeout_error_unlocked (pending,
03166 connection);
03167 _dbus_connection_remove_timeout_unlocked (connection,
03168 _dbus_pending_call_get_timeout_unlocked (pending));
03169 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
03170
03171 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
03172 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03173
03174
03175 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03176
03177 return TRUE;
03178 }
03179
03215 dbus_bool_t
03216 dbus_connection_send_with_reply (DBusConnection *connection,
03217 DBusMessage *message,
03218 DBusPendingCall **pending_return,
03219 int timeout_milliseconds)
03220 {
03221 DBusPendingCall *pending;
03222 dbus_int32_t serial = -1;
03223 DBusDispatchStatus status;
03224
03225 _dbus_return_val_if_fail (connection != NULL, FALSE);
03226 _dbus_return_val_if_fail (message != NULL, FALSE);
03227 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03228
03229 if (pending_return)
03230 *pending_return = NULL;
03231
03232 CONNECTION_LOCK (connection);
03233
03234 if (!_dbus_connection_get_is_connected_unlocked (connection))
03235 {
03236 CONNECTION_UNLOCK (connection);
03237
03238 return TRUE;
03239 }
03240
03241 pending = _dbus_pending_call_new_unlocked (connection,
03242 timeout_milliseconds,
03243 reply_handler_timeout);
03244
03245 if (pending == NULL)
03246 {
03247 CONNECTION_UNLOCK (connection);
03248 return FALSE;
03249 }
03250
03251
03252 serial = dbus_message_get_serial (message);
03253 if (serial == 0)
03254 {
03255 serial = _dbus_connection_get_next_client_serial (connection);
03256 dbus_message_set_serial (message, serial);
03257 }
03258
03259 if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
03260 goto error;
03261
03262
03263
03264
03265
03266 if (!_dbus_connection_attach_pending_call_unlocked (connection,
03267 pending))
03268 goto error;
03269
03270 if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
03271 {
03272 _dbus_connection_detach_pending_call_and_unlock (connection,
03273 pending);
03274 goto error_unlocked;
03275 }
03276
03277 if (pending_return)
03278 *pending_return = pending;
03279 else
03280 {
03281 _dbus_connection_detach_pending_call_unlocked (connection, pending);
03282
03283
03284
03285 }
03286
03287 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03288
03289
03290 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03291
03292 if (pending_return == NULL)
03293 dbus_pending_call_unref (pending);
03294
03295 return TRUE;
03296
03297 error:
03298 CONNECTION_UNLOCK (connection);
03299 error_unlocked:
03300 dbus_pending_call_unref (pending);
03301 return FALSE;
03302 }
03303
03334 DBusMessage*
03335 dbus_connection_send_with_reply_and_block (DBusConnection *connection,
03336 DBusMessage *message,
03337 int timeout_milliseconds,
03338 DBusError *error)
03339 {
03340 DBusMessage *reply;
03341 DBusPendingCall *pending;
03342
03343 _dbus_return_val_if_fail (connection != NULL, NULL);
03344 _dbus_return_val_if_fail (message != NULL, NULL);
03345 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL);
03346 _dbus_return_val_if_error_is_set (error, NULL);
03347
03348 if (!dbus_connection_send_with_reply (connection, message,
03349 &pending, timeout_milliseconds))
03350 {
03351 _DBUS_SET_OOM (error);
03352 return NULL;
03353 }
03354
03355 if (pending == NULL)
03356 {
03357 dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Connection is closed");
03358 return NULL;
03359 }
03360
03361 dbus_pending_call_block (pending);
03362
03363 reply = dbus_pending_call_steal_reply (pending);
03364 dbus_pending_call_unref (pending);
03365
03366
03367
03368
03369 _dbus_assert (reply != NULL);
03370
03371 if (dbus_set_error_from_message (error, reply))
03372 {
03373 dbus_message_unref (reply);
03374 return NULL;
03375 }
03376 else
03377 return reply;
03378 }
03379
03388 static DBusDispatchStatus
03389 _dbus_connection_flush_unlocked (DBusConnection *connection)
03390 {
03391
03392
03393
03394
03395
03396 DBusDispatchStatus status;
03397
03398 HAVE_LOCK_CHECK (connection);
03399
03400 while (connection->n_outgoing > 0 &&
03401 _dbus_connection_get_is_connected_unlocked (connection))
03402 {
03403 _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME);
03404 HAVE_LOCK_CHECK (connection);
03405 _dbus_connection_do_iteration_unlocked (connection,
03406 DBUS_ITERATION_DO_READING |
03407 DBUS_ITERATION_DO_WRITING |
03408 DBUS_ITERATION_BLOCK,
03409 -1);
03410 }
03411
03412 HAVE_LOCK_CHECK (connection);
03413 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
03414 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03415
03416 HAVE_LOCK_CHECK (connection);
03417 return status;
03418 }
03419
03425 void
03426 dbus_connection_flush (DBusConnection *connection)
03427 {
03428
03429
03430
03431
03432
03433 DBusDispatchStatus status;
03434
03435 _dbus_return_if_fail (connection != NULL);
03436
03437 CONNECTION_LOCK (connection);
03438
03439 status = _dbus_connection_flush_unlocked (connection);
03440
03441 HAVE_LOCK_CHECK (connection);
03442
03443 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03444
03445 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
03446 }
03447
03458 static dbus_bool_t
03459 _dbus_connection_read_write_dispatch (DBusConnection *connection,
03460 int timeout_milliseconds,
03461 dbus_bool_t dispatch)
03462 {
03463 DBusDispatchStatus dstatus;
03464 dbus_bool_t progress_possible;
03465
03466
03467
03468
03469
03470 dbus_connection_ref (connection);
03471 dstatus = dbus_connection_get_dispatch_status (connection);
03472
03473 if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
03474 {
03475 _dbus_verbose ("doing dispatch in %s\n", _DBUS_FUNCTION_NAME);
03476 dbus_connection_dispatch (connection);
03477 CONNECTION_LOCK (connection);
03478 }
03479 else if (dstatus == DBUS_DISPATCH_NEED_MEMORY)
03480 {
03481 _dbus_verbose ("pausing for memory in %s\n", _DBUS_FUNCTION_NAME);
03482 _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
03483 CONNECTION_LOCK (connection);
03484 }
03485 else
03486 {
03487 CONNECTION_LOCK (connection);
03488 if (_dbus_connection_get_is_connected_unlocked (connection))
03489 {
03490 _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME);
03491 _dbus_connection_do_iteration_unlocked (connection,
03492 DBUS_ITERATION_DO_READING |
03493 DBUS_ITERATION_DO_WRITING |
03494 DBUS_ITERATION_BLOCK,
03495 timeout_milliseconds);
03496 }
03497 }
03498
03499 HAVE_LOCK_CHECK (connection);
03500
03501
03502
03503
03504 if (dispatch)
03505 progress_possible = connection->n_incoming != 0 ||
03506 connection->disconnect_message_link != NULL;
03507 else
03508 progress_possible = _dbus_connection_get_is_connected_unlocked (connection);
03509
03510 CONNECTION_UNLOCK (connection);
03511
03512 dbus_connection_unref (connection);
03513
03514 return progress_possible;
03515 }
03516
03517
03552 dbus_bool_t
03553 dbus_connection_read_write_dispatch (DBusConnection *connection,
03554 int timeout_milliseconds)
03555 {
03556 _dbus_return_val_if_fail (connection != NULL, FALSE);
03557 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03558 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE);
03559 }
03560
03584 dbus_bool_t
03585 dbus_connection_read_write (DBusConnection *connection,
03586 int timeout_milliseconds)
03587 {
03588 _dbus_return_val_if_fail (connection != NULL, FALSE);
03589 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03590 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE);
03591 }
03592
03593
03594
03595
03596
03597
03598 static void
03599 check_disconnected_message_arrived_unlocked (DBusConnection *connection,
03600 DBusMessage *head_of_queue)
03601 {
03602 HAVE_LOCK_CHECK (connection);
03603
03604
03605 if (connection->disconnect_message_link == NULL &&
03606 dbus_message_is_signal (head_of_queue,
03607 DBUS_INTERFACE_LOCAL,
03608 "Disconnected"))
03609 {
03610 connection->disconnected_message_arrived = TRUE;
03611 }
03612 }
03613
03633 DBusMessage*
03634 dbus_connection_borrow_message (DBusConnection *connection)
03635 {
03636 DBusDispatchStatus status;
03637 DBusMessage *message;
03638
03639 _dbus_return_val_if_fail (connection != NULL, NULL);
03640
03641 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
03642
03643
03644
03645
03646 status = dbus_connection_get_dispatch_status (connection);
03647 if (status != DBUS_DISPATCH_DATA_REMAINS)
03648 return NULL;
03649
03650 CONNECTION_LOCK (connection);
03651
03652 _dbus_connection_acquire_dispatch (connection);
03653
03654
03655 _dbus_assert (connection->message_borrowed == NULL);
03656
03657 connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
03658
03659 message = connection->message_borrowed;
03660
03661 check_disconnected_message_arrived_unlocked (connection, message);
03662
03663
03664 if (message == NULL)
03665 _dbus_connection_release_dispatch (connection);
03666
03667 CONNECTION_UNLOCK (connection);
03668
03669
03670
03671 return message;
03672 }
03673
03682 void
03683 dbus_connection_return_message (DBusConnection *connection,
03684 DBusMessage *message)
03685 {
03686 DBusDispatchStatus status;
03687
03688 _dbus_return_if_fail (connection != NULL);
03689 _dbus_return_if_fail (message != NULL);
03690 _dbus_return_if_fail (message == connection->message_borrowed);
03691 _dbus_return_if_fail (connection->dispatch_acquired);
03692
03693 CONNECTION_LOCK (connection);
03694
03695 _dbus_assert (message == connection->message_borrowed);
03696
03697 connection->message_borrowed = NULL;
03698
03699 _dbus_connection_release_dispatch (connection);
03700
03701 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03702 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03703 }
03704
03714 void
03715 dbus_connection_steal_borrowed_message (DBusConnection *connection,
03716 DBusMessage *message)
03717 {
03718 DBusMessage *pop_message;
03719 DBusDispatchStatus status;
03720
03721 _dbus_return_if_fail (connection != NULL);
03722 _dbus_return_if_fail (message != NULL);
03723 _dbus_return_if_fail (message == connection->message_borrowed);
03724 _dbus_return_if_fail (connection->dispatch_acquired);
03725
03726 CONNECTION_LOCK (connection);
03727
03728 _dbus_assert (message == connection->message_borrowed);
03729
03730 pop_message = _dbus_list_pop_first (&connection->incoming_messages);
03731 _dbus_assert (message == pop_message);
03732
03733 connection->n_incoming -= 1;
03734
03735 _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
03736 message, connection->n_incoming);
03737
03738 connection->message_borrowed = NULL;
03739
03740 _dbus_connection_release_dispatch (connection);
03741
03742 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03743 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03744 }
03745
03746
03747
03748
03749 static DBusList*
03750 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
03751 {
03752 HAVE_LOCK_CHECK (connection);
03753
03754 _dbus_assert (connection->message_borrowed == NULL);
03755
03756 if (connection->n_incoming > 0)
03757 {
03758 DBusList *link;
03759
03760 link = _dbus_list_pop_first_link (&connection->incoming_messages);
03761 connection->n_incoming -= 1;
03762
03763 _dbus_verbose ("Message %p (%d %s %s %s '%s') removed from incoming queue %p, %d incoming\n",
03764 link->data,
03765 dbus_message_get_type (link->data),
03766 dbus_message_get_path (link->data) ?
03767 dbus_message_get_path (link->data) :
03768 "no path",
03769 dbus_message_get_interface (link->data) ?
03770 dbus_message_get_interface (link->data) :
03771 "no interface",
03772 dbus_message_get_member (link->data) ?
03773 dbus_message_get_member (link->data) :
03774 "no member",
03775 dbus_message_get_signature (link->data),
03776 connection, connection->n_incoming);
03777
03778 check_disconnected_message_arrived_unlocked (connection, link->data);
03779
03780 return link;
03781 }
03782 else
03783 return NULL;
03784 }
03785
03786
03787
03788
03789 static DBusMessage*
03790 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
03791 {
03792 DBusList *link;
03793
03794 HAVE_LOCK_CHECK (connection);
03795
03796 link = _dbus_connection_pop_message_link_unlocked (connection);
03797
03798 if (link != NULL)
03799 {
03800 DBusMessage *message;
03801
03802 message = link->data;
03803
03804 _dbus_list_free_link (link);
03805
03806 return message;
03807 }
03808 else
03809 return NULL;
03810 }
03811
03812 static void
03813 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
03814 DBusList *message_link)
03815 {
03816 HAVE_LOCK_CHECK (connection);
03817
03818 _dbus_assert (message_link != NULL);
03819
03820 _dbus_assert (connection->message_borrowed == NULL);
03821
03822 _dbus_assert (connection->dispatch_acquired);
03823
03824 _dbus_list_prepend_link (&connection->incoming_messages,
03825 message_link);
03826 connection->n_incoming += 1;
03827
03828 _dbus_verbose ("Message %p (%d %s %s '%s') put back into queue %p, %d incoming\n",
03829 message_link->data,
03830 dbus_message_get_type (message_link->data),
03831 dbus_message_get_interface (message_link->data) ?
03832 dbus_message_get_interface (message_link->data) :
03833 "no interface",
03834 dbus_message_get_member (message_link->data) ?
03835 dbus_message_get_member (message_link->data) :
03836 "no member",
03837 dbus_message_get_signature (message_link->data),
03838 connection, connection->n_incoming);
03839 }
03840
03860 DBusMessage*
03861 dbus_connection_pop_message (DBusConnection *connection)
03862 {
03863 DBusMessage *message;
03864 DBusDispatchStatus status;
03865
03866 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
03867
03868
03869
03870
03871 status = dbus_connection_get_dispatch_status (connection);
03872 if (status != DBUS_DISPATCH_DATA_REMAINS)
03873 return NULL;
03874
03875 CONNECTION_LOCK (connection);
03876 _dbus_connection_acquire_dispatch (connection);
03877 HAVE_LOCK_CHECK (connection);
03878
03879 message = _dbus_connection_pop_message_unlocked (connection);
03880
03881 _dbus_verbose ("Returning popped message %p\n", message);
03882
03883 _dbus_connection_release_dispatch (connection);
03884
03885 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03886 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03887
03888 return message;
03889 }
03890
03898 static void
03899 _dbus_connection_acquire_dispatch (DBusConnection *connection)
03900 {
03901 HAVE_LOCK_CHECK (connection);
03902
03903 _dbus_connection_ref_unlocked (connection);
03904 CONNECTION_UNLOCK (connection);
03905
03906 _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03907 _dbus_mutex_lock (connection->dispatch_mutex);
03908
03909 while (connection->dispatch_acquired)
03910 {
03911 _dbus_verbose ("%s waiting for dispatch to be acquirable\n", _DBUS_FUNCTION_NAME);
03912 _dbus_condvar_wait (connection->dispatch_cond,
03913 connection->dispatch_mutex);
03914 }
03915
03916 _dbus_assert (!connection->dispatch_acquired);
03917
03918 connection->dispatch_acquired = TRUE;
03919
03920 _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03921 _dbus_mutex_unlock (connection->dispatch_mutex);
03922
03923 CONNECTION_LOCK (connection);
03924 _dbus_connection_unref_unlocked (connection);
03925 }
03926
03934 static void
03935 _dbus_connection_release_dispatch (DBusConnection *connection)
03936 {
03937 HAVE_LOCK_CHECK (connection);
03938
03939 _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03940 _dbus_mutex_lock (connection->dispatch_mutex);
03941
03942 _dbus_assert (connection->dispatch_acquired);
03943
03944 connection->dispatch_acquired = FALSE;
03945 _dbus_condvar_wake_one (connection->dispatch_cond);
03946
03947 _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03948 _dbus_mutex_unlock (connection->dispatch_mutex);
03949 }
03950
03951 static void
03952 _dbus_connection_failed_pop (DBusConnection *connection,
03953 DBusList *message_link)
03954 {
03955 _dbus_list_prepend_link (&connection->incoming_messages,
03956 message_link);
03957 connection->n_incoming += 1;
03958 }
03959
03960
03961 static void
03962 notify_disconnected_unlocked (DBusConnection *connection)
03963 {
03964 HAVE_LOCK_CHECK (connection);
03965
03966
03967
03968
03969
03970
03971
03972 _dbus_bus_notify_shared_connection_disconnected_unlocked (connection);
03973
03974
03975
03976
03977
03978 if (connection->n_outgoing > 0)
03979 {
03980 DBusList *link;
03981
03982 _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
03983 connection->n_outgoing);
03984
03985 while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
03986 {
03987 _dbus_connection_message_sent (connection, link->data);
03988 }
03989 }
03990 }
03991
03992
03993 static DBusDispatchStatus
03994 notify_disconnected_and_dispatch_complete_unlocked (DBusConnection *connection)
03995 {
03996 HAVE_LOCK_CHECK (connection);
03997
03998 if (connection->disconnect_message_link != NULL)
03999 {
04000 _dbus_verbose ("Sending disconnect message from %s\n",
04001 _DBUS_FUNCTION_NAME);
04002
04003
04004
04005
04006 connection_timeout_and_complete_all_pending_calls_unlocked (connection);
04007
04008
04009
04010
04011 _dbus_connection_queue_synthesized_message_link (connection,
04012 connection->disconnect_message_link);
04013 connection->disconnect_message_link = NULL;
04014
04015 return DBUS_DISPATCH_DATA_REMAINS;
04016 }
04017
04018 return DBUS_DISPATCH_COMPLETE;
04019 }
04020
04021 static DBusDispatchStatus
04022 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
04023 {
04024 HAVE_LOCK_CHECK (connection);
04025
04026 if (connection->n_incoming > 0)
04027 return DBUS_DISPATCH_DATA_REMAINS;
04028 else if (!_dbus_transport_queue_messages (connection->transport))
04029 return DBUS_DISPATCH_NEED_MEMORY;
04030 else
04031 {
04032 DBusDispatchStatus status;
04033 dbus_bool_t is_connected;
04034
04035 status = _dbus_transport_get_dispatch_status (connection->transport);
04036 is_connected = _dbus_transport_get_is_connected (connection->transport);
04037
04038 _dbus_verbose ("dispatch status = %s is_connected = %d\n",
04039 DISPATCH_STATUS_NAME (status), is_connected);
04040
04041 if (!is_connected)
04042 {
04043
04044
04045
04046
04047
04048
04049 notify_disconnected_unlocked (connection);
04050
04051
04052
04053
04054
04055
04056 if (status == DBUS_DISPATCH_COMPLETE)
04057 status = notify_disconnected_and_dispatch_complete_unlocked (connection);
04058 }
04059
04060 if (status != DBUS_DISPATCH_COMPLETE)
04061 return status;
04062 else if (connection->n_incoming > 0)
04063 return DBUS_DISPATCH_DATA_REMAINS;
04064 else
04065 return DBUS_DISPATCH_COMPLETE;
04066 }
04067 }
04068
04069 static void
04070 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
04071 DBusDispatchStatus new_status)
04072 {
04073 dbus_bool_t changed;
04074 DBusDispatchStatusFunction function;
04075 void *data;
04076
04077 HAVE_LOCK_CHECK (connection);
04078
04079 _dbus_connection_ref_unlocked (connection);
04080
04081 changed = new_status != connection->last_dispatch_status;
04082
04083 connection->last_dispatch_status = new_status;
04084
04085 function = connection->dispatch_status_function;
04086 data = connection->dispatch_status_data;
04087
04088 if (connection->disconnected_message_arrived &&
04089 !connection->disconnected_message_processed)
04090 {
04091 connection->disconnected_message_processed = TRUE;
04092
04093
04094
04095
04096
04097 connection_forget_shared_unlocked (connection);
04098
04099 if (connection->exit_on_disconnect)
04100 {
04101 CONNECTION_UNLOCK (connection);
04102
04103 _dbus_verbose ("Exiting on Disconnected signal\n");
04104 _dbus_exit (1);
04105 _dbus_assert_not_reached ("Call to exit() returned");
04106 }
04107 }
04108
04109
04110 CONNECTION_UNLOCK (connection);
04111
04112 if (changed && function)
04113 {
04114 _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
04115 connection, new_status,
04116 DISPATCH_STATUS_NAME (new_status));
04117 (* function) (connection, new_status, data);
04118 }
04119
04120 dbus_connection_unref (connection);
04121 }
04122
04148 DBusDispatchStatus
04149 dbus_connection_get_dispatch_status (DBusConnection *connection)
04150 {
04151 DBusDispatchStatus status;
04152
04153 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04154
04155 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
04156
04157 CONNECTION_LOCK (connection);
04158
04159 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04160
04161 CONNECTION_UNLOCK (connection);
04162
04163 return status;
04164 }
04165
04169 static DBusHandlerResult
04170 _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
04171 DBusMessage *message)
04172 {
04173 if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
04174 {
04175
04176 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04177 }
04178 else if (dbus_message_is_method_call (message,
04179 DBUS_INTERFACE_PEER,
04180 "Ping"))
04181 {
04182 DBusMessage *ret;
04183 dbus_bool_t sent;
04184
04185 ret = dbus_message_new_method_return (message);
04186 if (ret == NULL)
04187 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04188
04189 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04190
04191 dbus_message_unref (ret);
04192
04193 if (!sent)
04194 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04195
04196 return DBUS_HANDLER_RESULT_HANDLED;
04197 }
04198 else if (dbus_message_is_method_call (message,
04199 DBUS_INTERFACE_PEER,
04200 "GetMachineId"))
04201 {
04202 DBusMessage *ret;
04203 dbus_bool_t sent;
04204 DBusString uuid;
04205
04206 ret = dbus_message_new_method_return (message);
04207 if (ret == NULL)
04208 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04209
04210 sent = FALSE;
04211 _dbus_string_init (&uuid);
04212 if (_dbus_get_local_machine_uuid_encoded (&uuid))
04213 {
04214 const char *v_STRING = _dbus_string_get_const_data (&uuid);
04215 if (dbus_message_append_args (ret,
04216 DBUS_TYPE_STRING, &v_STRING,
04217 DBUS_TYPE_INVALID))
04218 {
04219 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04220 }
04221 }
04222 _dbus_string_free (&uuid);
04223
04224 dbus_message_unref (ret);
04225
04226 if (!sent)
04227 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04228
04229 return DBUS_HANDLER_RESULT_HANDLED;
04230 }
04231 else if (dbus_message_has_interface (message, DBUS_INTERFACE_PEER))
04232 {
04233
04234
04235
04236
04237
04238 DBusMessage *ret;
04239 dbus_bool_t sent;
04240
04241 ret = dbus_message_new_error (message,
04242 DBUS_ERROR_UNKNOWN_METHOD,
04243 "Unknown method invoked on org.freedesktop.DBus.Peer interface");
04244 if (ret == NULL)
04245 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04246
04247 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04248
04249 dbus_message_unref (ret);
04250
04251 if (!sent)
04252 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04253
04254 return DBUS_HANDLER_RESULT_HANDLED;
04255 }
04256 else
04257 {
04258 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04259 }
04260 }
04261
04268 static DBusHandlerResult
04269 _dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection,
04270 DBusMessage *message)
04271 {
04272
04273
04274
04275 return _dbus_connection_peer_filter_unlocked_no_update (connection, message);
04276 }
04277
04320 DBusDispatchStatus
04321 dbus_connection_dispatch (DBusConnection *connection)
04322 {
04323 DBusMessage *message;
04324 DBusList *link, *filter_list_copy, *message_link;
04325 DBusHandlerResult result;
04326 DBusPendingCall *pending;
04327 dbus_int32_t reply_serial;
04328 DBusDispatchStatus status;
04329
04330 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04331
04332 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
04333
04334 CONNECTION_LOCK (connection);
04335 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04336 if (status != DBUS_DISPATCH_DATA_REMAINS)
04337 {
04338
04339 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04340 return status;
04341 }
04342
04343
04344
04345
04346 _dbus_connection_ref_unlocked (connection);
04347
04348 _dbus_connection_acquire_dispatch (connection);
04349 HAVE_LOCK_CHECK (connection);
04350
04351 message_link = _dbus_connection_pop_message_link_unlocked (connection);
04352 if (message_link == NULL)
04353 {
04354
04355
04356 _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
04357
04358 _dbus_connection_release_dispatch (connection);
04359
04360 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04361
04362 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04363
04364 dbus_connection_unref (connection);
04365
04366 return status;
04367 }
04368
04369 message = message_link->data;
04370
04371 _dbus_verbose (" dispatching message %p (%d %s %s '%s')\n",
04372 message,
04373 dbus_message_get_type (message),
04374 dbus_message_get_interface (message) ?
04375 dbus_message_get_interface (message) :
04376 "no interface",
04377 dbus_message_get_member (message) ?
04378 dbus_message_get_member (message) :
04379 "no member",
04380 dbus_message_get_signature (message));
04381
04382 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04383
04384
04385
04386
04387
04388
04389
04390
04391 reply_serial = dbus_message_get_reply_serial (message);
04392 pending = _dbus_hash_table_lookup_int (connection->pending_replies,
04393 reply_serial);
04394 if (pending)
04395 {
04396 _dbus_verbose ("Dispatching a pending reply\n");
04397 complete_pending_call_and_unlock (connection, pending, message);
04398 pending = NULL;
04399
04400 CONNECTION_LOCK (connection);
04401 _dbus_verbose ("pending call completed in dispatch\n");
04402 result = DBUS_HANDLER_RESULT_HANDLED;
04403 goto out;
04404 }
04405
04406 result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message);
04407 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04408 goto out;
04409
04410 if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
04411 {
04412 _dbus_connection_release_dispatch (connection);
04413 HAVE_LOCK_CHECK (connection);
04414
04415 _dbus_connection_failed_pop (connection, message_link);
04416
04417
04418 _dbus_connection_update_dispatch_status_and_unlock (connection,
04419 DBUS_DISPATCH_NEED_MEMORY);
04420
04421 if (pending)
04422 dbus_pending_call_unref (pending);
04423 dbus_connection_unref (connection);
04424
04425 return DBUS_DISPATCH_NEED_MEMORY;
04426 }
04427
04428 _dbus_list_foreach (&filter_list_copy,
04429 (DBusForeachFunction)_dbus_message_filter_ref,
04430 NULL);
04431
04432
04433
04434
04435 CONNECTION_UNLOCK (connection);
04436
04437 link = _dbus_list_get_first_link (&filter_list_copy);
04438 while (link != NULL)
04439 {
04440 DBusMessageFilter *filter = link->data;
04441 DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
04442
04443 if (filter->function == NULL)
04444 {
04445 _dbus_verbose (" filter was removed in a callback function\n");
04446 link = next;
04447 continue;
04448 }
04449
04450 _dbus_verbose (" running filter on message %p\n", message);
04451 result = (* filter->function) (connection, message, filter->user_data);
04452
04453 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04454 break;
04455
04456 link = next;
04457 }
04458
04459 _dbus_list_foreach (&filter_list_copy,
04460 (DBusForeachFunction)_dbus_message_filter_unref,
04461 NULL);
04462 _dbus_list_clear (&filter_list_copy);
04463
04464 CONNECTION_LOCK (connection);
04465
04466 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04467 {
04468 _dbus_verbose ("No memory in %s\n", _DBUS_FUNCTION_NAME);
04469 goto out;
04470 }
04471 else if (result == DBUS_HANDLER_RESULT_HANDLED)
04472 {
04473 _dbus_verbose ("filter handled message in dispatch\n");
04474 goto out;
04475 }
04476
04477
04478
04479
04480 _dbus_verbose (" running object path dispatch on message %p (%d %s %s '%s')\n",
04481 message,
04482 dbus_message_get_type (message),
04483 dbus_message_get_interface (message) ?
04484 dbus_message_get_interface (message) :
04485 "no interface",
04486 dbus_message_get_member (message) ?
04487 dbus_message_get_member (message) :
04488 "no member",
04489 dbus_message_get_signature (message));
04490
04491 HAVE_LOCK_CHECK (connection);
04492 result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
04493 message);
04494
04495 CONNECTION_LOCK (connection);
04496
04497 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04498 {
04499 _dbus_verbose ("object tree handled message in dispatch\n");
04500 goto out;
04501 }
04502
04503 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
04504 {
04505 DBusMessage *reply;
04506 DBusString str;
04507 DBusPreallocatedSend *preallocated;
04508
04509 _dbus_verbose (" sending error %s\n",
04510 DBUS_ERROR_UNKNOWN_METHOD);
04511
04512 if (!_dbus_string_init (&str))
04513 {
04514 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04515 _dbus_verbose ("no memory for error string in dispatch\n");
04516 goto out;
04517 }
04518
04519 if (!_dbus_string_append_printf (&str,
04520 "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
04521 dbus_message_get_member (message),
04522 dbus_message_get_signature (message),
04523 dbus_message_get_interface (message)))
04524 {
04525 _dbus_string_free (&str);
04526 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04527 _dbus_verbose ("no memory for error string in dispatch\n");
04528 goto out;
04529 }
04530
04531 reply = dbus_message_new_error (message,
04532 DBUS_ERROR_UNKNOWN_METHOD,
04533 _dbus_string_get_const_data (&str));
04534 _dbus_string_free (&str);
04535
04536 if (reply == NULL)
04537 {
04538 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04539 _dbus_verbose ("no memory for error reply in dispatch\n");
04540 goto out;
04541 }
04542
04543 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
04544
04545 if (preallocated == NULL)
04546 {
04547 dbus_message_unref (reply);
04548 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04549 _dbus_verbose ("no memory for error send in dispatch\n");
04550 goto out;
04551 }
04552
04553 _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
04554 reply, NULL);
04555
04556 dbus_message_unref (reply);
04557
04558 result = DBUS_HANDLER_RESULT_HANDLED;
04559 }
04560
04561 _dbus_verbose (" done dispatching %p (%d %s %s '%s') on connection %p\n", message,
04562 dbus_message_get_type (message),
04563 dbus_message_get_interface (message) ?
04564 dbus_message_get_interface (message) :
04565 "no interface",
04566 dbus_message_get_member (message) ?
04567 dbus_message_get_member (message) :
04568 "no member",
04569 dbus_message_get_signature (message),
04570 connection);
04571
04572 out:
04573 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04574 {
04575 _dbus_verbose ("out of memory in %s\n", _DBUS_FUNCTION_NAME);
04576
04577
04578
04579
04580
04581 _dbus_connection_putback_message_link_unlocked (connection,
04582 message_link);
04583 }
04584 else
04585 {
04586 _dbus_verbose (" ... done dispatching in %s\n", _DBUS_FUNCTION_NAME);
04587
04588 _dbus_list_free_link (message_link);
04589 dbus_message_unref (message);
04590
04591
04592 }
04593
04594 _dbus_connection_release_dispatch (connection);
04595 HAVE_LOCK_CHECK (connection);
04596
04597 _dbus_verbose ("%s before final status update\n", _DBUS_FUNCTION_NAME);
04598 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04599
04600
04601 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04602
04603 dbus_connection_unref (connection);
04604
04605 return status;
04606 }
04607
04667 dbus_bool_t
04668 dbus_connection_set_watch_functions (DBusConnection *connection,
04669 DBusAddWatchFunction add_function,
04670 DBusRemoveWatchFunction remove_function,
04671 DBusWatchToggledFunction toggled_function,
04672 void *data,
04673 DBusFreeFunction free_data_function)
04674 {
04675 dbus_bool_t retval;
04676 DBusWatchList *watches;
04677
04678 _dbus_return_val_if_fail (connection != NULL, FALSE);
04679
04680 CONNECTION_LOCK (connection);
04681
04682 #ifndef DBUS_DISABLE_CHECKS
04683 if (connection->watches == NULL)
04684 {
04685 _dbus_warn_check_failed ("Re-entrant call to %s is not allowed\n",
04686 _DBUS_FUNCTION_NAME);
04687 return FALSE;
04688 }
04689 #endif
04690
04691
04692 _dbus_connection_ref_unlocked (connection);
04693
04694
04695
04696
04697
04698 watches = connection->watches;
04699 connection->watches = NULL;
04700 CONNECTION_UNLOCK (connection);
04701
04702 retval = _dbus_watch_list_set_functions (watches,
04703 add_function, remove_function,
04704 toggled_function,
04705 data, free_data_function);
04706 CONNECTION_LOCK (connection);
04707 connection->watches = watches;
04708
04709 CONNECTION_UNLOCK (connection);
04710
04711 dbus_connection_unref (connection);
04712
04713 return retval;
04714 }
04715
04749 dbus_bool_t
04750 dbus_connection_set_timeout_functions (DBusConnection *connection,
04751 DBusAddTimeoutFunction add_function,
04752 DBusRemoveTimeoutFunction remove_function,
04753 DBusTimeoutToggledFunction toggled_function,
04754 void *data,
04755 DBusFreeFunction free_data_function)
04756 {
04757 dbus_bool_t retval;
04758 DBusTimeoutList *timeouts;
04759
04760 _dbus_return_val_if_fail (connection != NULL, FALSE);
04761
04762 CONNECTION_LOCK (connection);
04763
04764 #ifndef DBUS_DISABLE_CHECKS
04765 if (connection->timeouts == NULL)
04766 {
04767 _dbus_warn_check_failed ("Re-entrant call to %s is not allowed\n",
04768 _DBUS_FUNCTION_NAME);
04769 return FALSE;
04770 }
04771 #endif
04772
04773
04774 _dbus_connection_ref_unlocked (connection);
04775
04776 timeouts = connection->timeouts;
04777 connection->timeouts = NULL;
04778 CONNECTION_UNLOCK (connection);
04779
04780 retval = _dbus_timeout_list_set_functions (timeouts,
04781 add_function, remove_function,
04782 toggled_function,
04783 data, free_data_function);
04784 CONNECTION_LOCK (connection);
04785 connection->timeouts = timeouts;
04786
04787 CONNECTION_UNLOCK (connection);
04788
04789 dbus_connection_unref (connection);
04790
04791 return retval;
04792 }
04793
04808 void
04809 dbus_connection_set_wakeup_main_function (DBusConnection *connection,
04810 DBusWakeupMainFunction wakeup_main_function,
04811 void *data,
04812 DBusFreeFunction free_data_function)
04813 {
04814 void *old_data;
04815 DBusFreeFunction old_free_data;
04816
04817 _dbus_return_if_fail (connection != NULL);
04818
04819 CONNECTION_LOCK (connection);
04820 old_data = connection->wakeup_main_data;
04821 old_free_data = connection->free_wakeup_main_data;
04822
04823 connection->wakeup_main_function = wakeup_main_function;
04824 connection->wakeup_main_data = data;
04825 connection->free_wakeup_main_data = free_data_function;
04826
04827 CONNECTION_UNLOCK (connection);
04828
04829
04830 if (old_free_data)
04831 (*old_free_data) (old_data);
04832 }
04833
04854 void
04855 dbus_connection_set_dispatch_status_function (DBusConnection *connection,
04856 DBusDispatchStatusFunction function,
04857 void *data,
04858 DBusFreeFunction free_data_function)
04859 {
04860 void *old_data;
04861 DBusFreeFunction old_free_data;
04862
04863 _dbus_return_if_fail (connection != NULL);
04864
04865 CONNECTION_LOCK (connection);
04866 old_data = connection->dispatch_status_data;
04867 old_free_data = connection->free_dispatch_status_data;
04868
04869 connection->dispatch_status_function = function;
04870 connection->dispatch_status_data = data;
04871 connection->free_dispatch_status_data = free_data_function;
04872
04873 CONNECTION_UNLOCK (connection);
04874
04875
04876 if (old_free_data)
04877 (*old_free_data) (old_data);
04878 }
04879
04899 dbus_bool_t
04900 dbus_connection_get_unix_fd (DBusConnection *connection,
04901 int *fd)
04902 {
04903 _dbus_return_val_if_fail (connection != NULL, FALSE);
04904 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
04905
04906 #ifdef DBUS_WIN
04907
04908 return FALSE;
04909 #endif
04910
04911 return dbus_connection_get_socket(connection, fd);
04912 }
04913
04929 dbus_bool_t
04930 dbus_connection_get_socket(DBusConnection *connection,
04931 int *fd)
04932 {
04933 dbus_bool_t retval;
04934
04935 _dbus_return_val_if_fail (connection != NULL, FALSE);
04936 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
04937
04938 CONNECTION_LOCK (connection);
04939
04940 retval = _dbus_transport_get_socket_fd (connection->transport,
04941 fd);
04942
04943 CONNECTION_UNLOCK (connection);
04944
04945 return retval;
04946 }
04947
04948
04971 dbus_bool_t
04972 dbus_connection_get_unix_user (DBusConnection *connection,
04973 unsigned long *uid)
04974 {
04975 dbus_bool_t result;
04976
04977 _dbus_return_val_if_fail (connection != NULL, FALSE);
04978 _dbus_return_val_if_fail (uid != NULL, FALSE);
04979
04980 CONNECTION_LOCK (connection);
04981
04982 if (!_dbus_transport_get_is_authenticated (connection->transport))
04983 result = FALSE;
04984 else
04985 result = _dbus_transport_get_unix_user (connection->transport,
04986 uid);
04987
04988 #ifdef DBUS_WIN
04989 _dbus_assert (!result);
04990 #endif
04991
04992 CONNECTION_UNLOCK (connection);
04993
04994 return result;
04995 }
04996
05007 dbus_bool_t
05008 dbus_connection_get_unix_process_id (DBusConnection *connection,
05009 unsigned long *pid)
05010 {
05011 dbus_bool_t result;
05012
05013 _dbus_return_val_if_fail (connection != NULL, FALSE);
05014 _dbus_return_val_if_fail (pid != NULL, FALSE);
05015
05016 CONNECTION_LOCK (connection);
05017
05018 if (!_dbus_transport_get_is_authenticated (connection->transport))
05019 result = FALSE;
05020 else
05021 result = _dbus_transport_get_unix_process_id (connection->transport,
05022 pid);
05023 #ifdef DBUS_WIN
05024 _dbus_assert (!result);
05025 #endif
05026
05027 CONNECTION_UNLOCK (connection);
05028
05029 return result;
05030 }
05031
05042 dbus_bool_t
05043 dbus_connection_get_adt_audit_session_data (DBusConnection *connection,
05044 void **data,
05045 dbus_int32_t *data_size)
05046 {
05047 dbus_bool_t result;
05048
05049 _dbus_return_val_if_fail (connection != NULL, FALSE);
05050 _dbus_return_val_if_fail (data != NULL, FALSE);
05051 _dbus_return_val_if_fail (data_size != NULL, FALSE);
05052
05053 CONNECTION_LOCK (connection);
05054
05055 if (!_dbus_transport_get_is_authenticated (connection->transport))
05056 result = FALSE;
05057 else
05058 result = _dbus_transport_get_adt_audit_session_data (connection->transport,
05059 data,
05060 data_size);
05061 CONNECTION_UNLOCK (connection);
05062
05063 return result;
05064 }
05065
05088 void
05089 dbus_connection_set_unix_user_function (DBusConnection *connection,
05090 DBusAllowUnixUserFunction function,
05091 void *data,
05092 DBusFreeFunction free_data_function)
05093 {
05094 void *old_data = NULL;
05095 DBusFreeFunction old_free_function = NULL;
05096
05097 _dbus_return_if_fail (connection != NULL);
05098
05099 CONNECTION_LOCK (connection);
05100 _dbus_transport_set_unix_user_function (connection->transport,
05101 function, data, free_data_function,
05102 &old_data, &old_free_function);
05103 CONNECTION_UNLOCK (connection);
05104
05105 if (old_free_function != NULL)
05106 (* old_free_function) (old_data);
05107 }
05108
05140 dbus_bool_t
05141 dbus_connection_get_windows_user (DBusConnection *connection,
05142 char **windows_sid_p)
05143 {
05144 dbus_bool_t result;
05145
05146 _dbus_return_val_if_fail (connection != NULL, FALSE);
05147 _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
05148
05149 CONNECTION_LOCK (connection);
05150
05151 if (!_dbus_transport_get_is_authenticated (connection->transport))
05152 result = FALSE;
05153 else
05154 result = _dbus_transport_get_windows_user (connection->transport,
05155 windows_sid_p);
05156
05157 #ifdef DBUS_UNIX
05158 _dbus_assert (!result);
05159 #endif
05160
05161 CONNECTION_UNLOCK (connection);
05162
05163 return result;
05164 }
05165
05187 void
05188 dbus_connection_set_windows_user_function (DBusConnection *connection,
05189 DBusAllowWindowsUserFunction function,
05190 void *data,
05191 DBusFreeFunction free_data_function)
05192 {
05193 void *old_data = NULL;
05194 DBusFreeFunction old_free_function = NULL;
05195
05196 _dbus_return_if_fail (connection != NULL);
05197
05198 CONNECTION_LOCK (connection);
05199 _dbus_transport_set_windows_user_function (connection->transport,
05200 function, data, free_data_function,
05201 &old_data, &old_free_function);
05202 CONNECTION_UNLOCK (connection);
05203
05204 if (old_free_function != NULL)
05205 (* old_free_function) (old_data);
05206 }
05207
05234 void
05235 dbus_connection_set_allow_anonymous (DBusConnection *connection,
05236 dbus_bool_t value)
05237 {
05238 _dbus_return_if_fail (connection != NULL);
05239
05240 CONNECTION_LOCK (connection);
05241 _dbus_transport_set_allow_anonymous (connection->transport, value);
05242 CONNECTION_UNLOCK (connection);
05243 }
05244
05262 void
05263 dbus_connection_set_route_peer_messages (DBusConnection *connection,
05264 dbus_bool_t value)
05265 {
05266 _dbus_return_if_fail (connection != NULL);
05267
05268 CONNECTION_LOCK (connection);
05269 connection->route_peer_messages = TRUE;
05270 CONNECTION_UNLOCK (connection);
05271 }
05272
05294 dbus_bool_t
05295 dbus_connection_add_filter (DBusConnection *connection,
05296 DBusHandleMessageFunction function,
05297 void *user_data,
05298 DBusFreeFunction free_data_function)
05299 {
05300 DBusMessageFilter *filter;
05301
05302 _dbus_return_val_if_fail (connection != NULL, FALSE);
05303 _dbus_return_val_if_fail (function != NULL, FALSE);
05304
05305 filter = dbus_new0 (DBusMessageFilter, 1);
05306 if (filter == NULL)
05307 return FALSE;
05308
05309 filter->refcount.value = 1;
05310
05311 CONNECTION_LOCK (connection);
05312
05313 if (!_dbus_list_append (&connection->filter_list,
05314 filter))
05315 {
05316 _dbus_message_filter_unref (filter);
05317 CONNECTION_UNLOCK (connection);
05318 return FALSE;
05319 }
05320
05321
05322
05323
05324
05325
05326 filter->function = function;
05327 filter->user_data = user_data;
05328 filter->free_user_data_function = free_data_function;
05329
05330 CONNECTION_UNLOCK (connection);
05331 return TRUE;
05332 }
05333
05346 void
05347 dbus_connection_remove_filter (DBusConnection *connection,
05348 DBusHandleMessageFunction function,
05349 void *user_data)
05350 {
05351 DBusList *link;
05352 DBusMessageFilter *filter;
05353
05354 _dbus_return_if_fail (connection != NULL);
05355 _dbus_return_if_fail (function != NULL);
05356
05357 CONNECTION_LOCK (connection);
05358
05359 filter = NULL;
05360
05361 link = _dbus_list_get_last_link (&connection->filter_list);
05362 while (link != NULL)
05363 {
05364 filter = link->data;
05365
05366 if (filter->function == function &&
05367 filter->user_data == user_data)
05368 {
05369 _dbus_list_remove_link (&connection->filter_list, link);
05370 filter->function = NULL;
05371
05372 break;
05373 }
05374
05375 link = _dbus_list_get_prev_link (&connection->filter_list, link);
05376 filter = NULL;
05377 }
05378
05379 CONNECTION_UNLOCK (connection);
05380
05381 #ifndef DBUS_DISABLE_CHECKS
05382 if (filter == NULL)
05383 {
05384 _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
05385 function, user_data);
05386 return;
05387 }
05388 #endif
05389
05390
05391 if (filter->free_user_data_function)
05392 (* filter->free_user_data_function) (filter->user_data);
05393
05394 filter->free_user_data_function = NULL;
05395 filter->user_data = NULL;
05396
05397 _dbus_message_filter_unref (filter);
05398 }
05399
05412 dbus_bool_t
05413 dbus_connection_try_register_object_path (DBusConnection *connection,
05414 const char *path,
05415 const DBusObjectPathVTable *vtable,
05416 void *user_data,
05417 DBusError *error)
05418 {
05419 char **decomposed_path;
05420 dbus_bool_t retval;
05421
05422 _dbus_return_val_if_fail (connection != NULL, FALSE);
05423 _dbus_return_val_if_fail (path != NULL, FALSE);
05424 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05425 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05426
05427 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05428 return FALSE;
05429
05430 CONNECTION_LOCK (connection);
05431
05432 retval = _dbus_object_tree_register (connection->objects,
05433 FALSE,
05434 (const char **) decomposed_path, vtable,
05435 user_data, error);
05436
05437 CONNECTION_UNLOCK (connection);
05438
05439 dbus_free_string_array (decomposed_path);
05440
05441 return retval;
05442 }
05443
05458 dbus_bool_t
05459 dbus_connection_register_object_path (DBusConnection *connection,
05460 const char *path,
05461 const DBusObjectPathVTable *vtable,
05462 void *user_data)
05463 {
05464 char **decomposed_path;
05465 dbus_bool_t retval;
05466 DBusError error = DBUS_ERROR_INIT;
05467
05468 _dbus_return_val_if_fail (connection != NULL, FALSE);
05469 _dbus_return_val_if_fail (path != NULL, FALSE);
05470 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05471 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05472
05473 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05474 return FALSE;
05475
05476 CONNECTION_LOCK (connection);
05477
05478 retval = _dbus_object_tree_register (connection->objects,
05479 FALSE,
05480 (const char **) decomposed_path, vtable,
05481 user_data, &error);
05482
05483 CONNECTION_UNLOCK (connection);
05484
05485 dbus_free_string_array (decomposed_path);
05486
05487 if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE))
05488 {
05489 _dbus_warn ("%s\n", error.message);
05490 dbus_error_free (&error);
05491 return FALSE;
05492 }
05493
05494 return retval;
05495 }
05496
05511 dbus_bool_t
05512 dbus_connection_try_register_fallback (DBusConnection *connection,
05513 const char *path,
05514 const DBusObjectPathVTable *vtable,
05515 void *user_data,
05516 DBusError *error)
05517 {
05518 char **decomposed_path;
05519 dbus_bool_t retval;
05520
05521 _dbus_return_val_if_fail (connection != NULL, FALSE);
05522 _dbus_return_val_if_fail (path != NULL, FALSE);
05523 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05524 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05525
05526 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05527 return FALSE;
05528
05529 CONNECTION_LOCK (connection);
05530
05531 retval = _dbus_object_tree_register (connection->objects,
05532 TRUE,
05533 (const char **) decomposed_path, vtable,
05534 user_data, error);
05535
05536 CONNECTION_UNLOCK (connection);
05537
05538 dbus_free_string_array (decomposed_path);
05539
05540 return retval;
05541 }
05542
05559 dbus_bool_t
05560 dbus_connection_register_fallback (DBusConnection *connection,
05561 const char *path,
05562 const DBusObjectPathVTable *vtable,
05563 void *user_data)
05564 {
05565 char **decomposed_path;
05566 dbus_bool_t retval;
05567 DBusError error = DBUS_ERROR_INIT;
05568
05569 _dbus_return_val_if_fail (connection != NULL, FALSE);
05570 _dbus_return_val_if_fail (path != NULL, FALSE);
05571 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05572 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05573
05574 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05575 return FALSE;
05576
05577 CONNECTION_LOCK (connection);
05578
05579 retval = _dbus_object_tree_register (connection->objects,
05580 TRUE,
05581 (const char **) decomposed_path, vtable,
05582 user_data, &error);
05583
05584 CONNECTION_UNLOCK (connection);
05585
05586 dbus_free_string_array (decomposed_path);
05587
05588 if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE))
05589 {
05590 _dbus_warn ("%s\n", error.message);
05591 dbus_error_free (&error);
05592 return FALSE;
05593 }
05594
05595 return retval;
05596 }
05597
05607 dbus_bool_t
05608 dbus_connection_unregister_object_path (DBusConnection *connection,
05609 const char *path)
05610 {
05611 char **decomposed_path;
05612
05613 _dbus_return_val_if_fail (connection != NULL, FALSE);
05614 _dbus_return_val_if_fail (path != NULL, FALSE);
05615 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05616
05617 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05618 return FALSE;
05619
05620 CONNECTION_LOCK (connection);
05621
05622 _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
05623
05624 dbus_free_string_array (decomposed_path);
05625
05626 return TRUE;
05627 }
05628
05639 dbus_bool_t
05640 dbus_connection_get_object_path_data (DBusConnection *connection,
05641 const char *path,
05642 void **data_p)
05643 {
05644 char **decomposed_path;
05645
05646 _dbus_return_val_if_fail (connection != NULL, FALSE);
05647 _dbus_return_val_if_fail (path != NULL, FALSE);
05648 _dbus_return_val_if_fail (data_p != NULL, FALSE);
05649
05650 *data_p = NULL;
05651
05652 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05653 return FALSE;
05654
05655 CONNECTION_LOCK (connection);
05656
05657 *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path);
05658
05659 CONNECTION_UNLOCK (connection);
05660
05661 dbus_free_string_array (decomposed_path);
05662
05663 return TRUE;
05664 }
05665
05676 dbus_bool_t
05677 dbus_connection_list_registered (DBusConnection *connection,
05678 const char *parent_path,
05679 char ***child_entries)
05680 {
05681 char **decomposed_path;
05682 dbus_bool_t retval;
05683 _dbus_return_val_if_fail (connection != NULL, FALSE);
05684 _dbus_return_val_if_fail (parent_path != NULL, FALSE);
05685 _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
05686 _dbus_return_val_if_fail (child_entries != NULL, FALSE);
05687
05688 if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
05689 return FALSE;
05690
05691 CONNECTION_LOCK (connection);
05692
05693 retval = _dbus_object_tree_list_registered_and_unlock (connection->objects,
05694 (const char **) decomposed_path,
05695 child_entries);
05696 dbus_free_string_array (decomposed_path);
05697
05698 return retval;
05699 }
05700
05701 static DBusDataSlotAllocator slot_allocator;
05702 _DBUS_DEFINE_GLOBAL_LOCK (connection_slots);
05703
05718 dbus_bool_t
05719 dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
05720 {
05721 return _dbus_data_slot_allocator_alloc (&slot_allocator,
05722 &_DBUS_LOCK_NAME (connection_slots),
05723 slot_p);
05724 }
05725
05737 void
05738 dbus_connection_free_data_slot (dbus_int32_t *slot_p)
05739 {
05740 _dbus_return_if_fail (*slot_p >= 0);
05741
05742 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
05743 }
05744
05758 dbus_bool_t
05759 dbus_connection_set_data (DBusConnection *connection,
05760 dbus_int32_t slot,
05761 void *data,
05762 DBusFreeFunction free_data_func)
05763 {
05764 DBusFreeFunction old_free_func;
05765 void *old_data;
05766 dbus_bool_t retval;
05767
05768 _dbus_return_val_if_fail (connection != NULL, FALSE);
05769 _dbus_return_val_if_fail (slot >= 0, FALSE);
05770
05771 CONNECTION_LOCK (connection);
05772
05773 retval = _dbus_data_slot_list_set (&slot_allocator,
05774 &connection->slot_list,
05775 slot, data, free_data_func,
05776 &old_free_func, &old_data);
05777
05778 CONNECTION_UNLOCK (connection);
05779
05780 if (retval)
05781 {
05782
05783 if (old_free_func)
05784 (* old_free_func) (old_data);
05785 }
05786
05787 return retval;
05788 }
05789
05798 void*
05799 dbus_connection_get_data (DBusConnection *connection,
05800 dbus_int32_t slot)
05801 {
05802 void *res;
05803
05804 _dbus_return_val_if_fail (connection != NULL, NULL);
05805
05806 CONNECTION_LOCK (connection);
05807
05808 res = _dbus_data_slot_list_get (&slot_allocator,
05809 &connection->slot_list,
05810 slot);
05811
05812 CONNECTION_UNLOCK (connection);
05813
05814 return res;
05815 }
05816
05823 void
05824 dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
05825 {
05826 _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
05827 }
05828
05837 void
05838 dbus_connection_set_max_message_size (DBusConnection *connection,
05839 long size)
05840 {
05841 _dbus_return_if_fail (connection != NULL);
05842
05843 CONNECTION_LOCK (connection);
05844 _dbus_transport_set_max_message_size (connection->transport,
05845 size);
05846 CONNECTION_UNLOCK (connection);
05847 }
05848
05855 long
05856 dbus_connection_get_max_message_size (DBusConnection *connection)
05857 {
05858 long res;
05859
05860 _dbus_return_val_if_fail (connection != NULL, 0);
05861
05862 CONNECTION_LOCK (connection);
05863 res = _dbus_transport_get_max_message_size (connection->transport);
05864 CONNECTION_UNLOCK (connection);
05865 return res;
05866 }
05867
05893 void
05894 dbus_connection_set_max_received_size (DBusConnection *connection,
05895 long size)
05896 {
05897 _dbus_return_if_fail (connection != NULL);
05898
05899 CONNECTION_LOCK (connection);
05900 _dbus_transport_set_max_received_size (connection->transport,
05901 size);
05902 CONNECTION_UNLOCK (connection);
05903 }
05904
05911 long
05912 dbus_connection_get_max_received_size (DBusConnection *connection)
05913 {
05914 long res;
05915
05916 _dbus_return_val_if_fail (connection != NULL, 0);
05917
05918 CONNECTION_LOCK (connection);
05919 res = _dbus_transport_get_max_received_size (connection->transport);
05920 CONNECTION_UNLOCK (connection);
05921 return res;
05922 }
05923
05934 long
05935 dbus_connection_get_outgoing_size (DBusConnection *connection)
05936 {
05937 long res;
05938
05939 _dbus_return_val_if_fail (connection != NULL, 0);
05940
05941 CONNECTION_LOCK (connection);
05942 res = _dbus_counter_get_value (connection->outgoing_counter);
05943 CONNECTION_UNLOCK (connection);
05944 return res;
05945 }
05946