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-message-private.h"
00037 #include "dbus-threads.h"
00038 #include "dbus-protocol.h"
00039 #include "dbus-dataslot.h"
00040 #include "dbus-string.h"
00041 #include "dbus-pending-call.h"
00042 #include "dbus-object-tree.h"
00043 #include "dbus-threads-internal.h"
00044 #include "dbus-bus.h"
00045 #include "dbus-marshal-basic.h"
00046
00047 #ifdef DBUS_DISABLE_CHECKS
00048 #define TOOK_LOCK_CHECK(connection)
00049 #define RELEASING_LOCK_CHECK(connection)
00050 #define HAVE_LOCK_CHECK(connection)
00051 #else
00052 #define TOOK_LOCK_CHECK(connection) do { \
00053 _dbus_assert (!(connection)->have_connection_lock); \
00054 (connection)->have_connection_lock = TRUE; \
00055 } while (0)
00056 #define RELEASING_LOCK_CHECK(connection) do { \
00057 _dbus_assert ((connection)->have_connection_lock); \
00058 (connection)->have_connection_lock = FALSE; \
00059 } while (0)
00060 #define HAVE_LOCK_CHECK(connection) _dbus_assert ((connection)->have_connection_lock)
00061
00062 #endif
00063
00064 #define TRACE_LOCKS 1
00065
00066 #define CONNECTION_LOCK(connection) do { \
00067 if (TRACE_LOCKS) { _dbus_verbose ("LOCK\n"); } \
00068 _dbus_mutex_lock ((connection)->mutex); \
00069 TOOK_LOCK_CHECK (connection); \
00070 } while (0)
00071
00072 #define CONNECTION_UNLOCK(connection) do { \
00073 if (TRACE_LOCKS) { _dbus_verbose ("UNLOCK\n"); } \
00074 RELEASING_LOCK_CHECK (connection); \
00075 _dbus_mutex_unlock ((connection)->mutex); \
00076 } while (0)
00077
00078 #define SLOTS_LOCK(connection) do { \
00079 _dbus_mutex_lock ((connection)->slot_mutex); \
00080 } while (0)
00081
00082 #define SLOTS_UNLOCK(connection) do { \
00083 _dbus_mutex_unlock ((connection)->slot_mutex); \
00084 } while (0)
00085
00086 #define DISPATCH_STATUS_NAME(s) \
00087 ((s) == DBUS_DISPATCH_COMPLETE ? "complete" : \
00088 (s) == DBUS_DISPATCH_DATA_REMAINS ? "data remains" : \
00089 (s) == DBUS_DISPATCH_NEED_MEMORY ? "need memory" : \
00090 "???")
00091
00212 typedef struct DBusMessageFilter DBusMessageFilter;
00213
00217 struct DBusMessageFilter
00218 {
00219 DBusAtomic refcount;
00220 DBusHandleMessageFunction function;
00221 void *user_data;
00222 DBusFreeFunction free_user_data_function;
00223 };
00224
00225
00229 struct DBusPreallocatedSend
00230 {
00231 DBusConnection *connection;
00232 DBusList *queue_link;
00233 DBusList *counter_link;
00234 };
00235
00236 #if HAVE_DECL_MSG_NOSIGNAL
00237 static dbus_bool_t _dbus_modify_sigpipe = FALSE;
00238 #else
00239 static dbus_bool_t _dbus_modify_sigpipe = TRUE;
00240 #endif
00241
00245 struct DBusConnection
00246 {
00247 DBusAtomic refcount;
00249 DBusMutex *mutex;
00251 DBusMutex *dispatch_mutex;
00252 DBusCondVar *dispatch_cond;
00253 DBusMutex *io_path_mutex;
00254 DBusCondVar *io_path_cond;
00256 DBusList *outgoing_messages;
00257 DBusList *incoming_messages;
00259 DBusMessage *message_borrowed;
00263 int n_outgoing;
00264 int n_incoming;
00266 DBusCounter *outgoing_counter;
00268 DBusTransport *transport;
00269 DBusWatchList *watches;
00270 DBusTimeoutList *timeouts;
00272 DBusList *filter_list;
00274 DBusMutex *slot_mutex;
00275 DBusDataSlotList slot_list;
00277 DBusHashTable *pending_replies;
00279 dbus_uint32_t client_serial;
00280 DBusList *disconnect_message_link;
00282 DBusWakeupMainFunction wakeup_main_function;
00283 void *wakeup_main_data;
00284 DBusFreeFunction free_wakeup_main_data;
00286 DBusDispatchStatusFunction dispatch_status_function;
00287 void *dispatch_status_data;
00288 DBusFreeFunction free_dispatch_status_data;
00290 DBusDispatchStatus last_dispatch_status;
00292 DBusList *link_cache;
00295 DBusObjectTree *objects;
00297 char *server_guid;
00299
00300
00301
00302
00303 dbus_bool_t dispatch_acquired;
00304 dbus_bool_t io_path_acquired;
00306 unsigned int shareable : 1;
00308 unsigned int exit_on_disconnect : 1;
00310 unsigned int route_peer_messages : 1;
00312 unsigned int disconnected_message_arrived : 1;
00316 unsigned int disconnected_message_processed : 1;
00320 #ifndef DBUS_DISABLE_CHECKS
00321 unsigned int have_connection_lock : 1;
00322 #endif
00323
00324 #ifndef DBUS_DISABLE_CHECKS
00325 int generation;
00326 #endif
00327 };
00328
00329 static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection);
00330 static void _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
00331 DBusDispatchStatus new_status);
00332 static void _dbus_connection_last_unref (DBusConnection *connection);
00333 static void _dbus_connection_acquire_dispatch (DBusConnection *connection);
00334 static void _dbus_connection_release_dispatch (DBusConnection *connection);
00335 static DBusDispatchStatus _dbus_connection_flush_unlocked (DBusConnection *connection);
00336 static void _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection);
00337 static dbus_bool_t _dbus_connection_get_is_connected_unlocked (DBusConnection *connection);
00338 static dbus_bool_t _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection,
00339 dbus_uint32_t client_serial);
00340
00341 static DBusMessageFilter *
00342 _dbus_message_filter_ref (DBusMessageFilter *filter)
00343 {
00344 #ifdef DBUS_DISABLE_ASSERT
00345 _dbus_atomic_inc (&filter->refcount);
00346 #else
00347 dbus_int32_t old_value;
00348
00349 old_value = _dbus_atomic_inc (&filter->refcount);
00350 _dbus_assert (old_value > 0);
00351 #endif
00352
00353 return filter;
00354 }
00355
00356 static void
00357 _dbus_message_filter_unref (DBusMessageFilter *filter)
00358 {
00359 dbus_int32_t old_value;
00360
00361 old_value = _dbus_atomic_dec (&filter->refcount);
00362 _dbus_assert (old_value > 0);
00363
00364 if (old_value == 1)
00365 {
00366 if (filter->free_user_data_function)
00367 (* filter->free_user_data_function) (filter->user_data);
00368
00369 dbus_free (filter);
00370 }
00371 }
00372
00378 void
00379 _dbus_connection_lock (DBusConnection *connection)
00380 {
00381 CONNECTION_LOCK (connection);
00382 }
00383
00389 void
00390 _dbus_connection_unlock (DBusConnection *connection)
00391 {
00392 CONNECTION_UNLOCK (connection);
00393 }
00394
00402 static void
00403 _dbus_connection_wakeup_mainloop (DBusConnection *connection)
00404 {
00405 if (connection->wakeup_main_function)
00406 (*connection->wakeup_main_function) (connection->wakeup_main_data);
00407 }
00408
00409 #ifdef DBUS_BUILD_TESTS
00410
00420 dbus_bool_t
00421 _dbus_connection_queue_received_message (DBusConnection *connection,
00422 DBusMessage *message)
00423 {
00424 DBusList *link;
00425
00426 link = _dbus_list_alloc_link (message);
00427 if (link == NULL)
00428 return FALSE;
00429
00430 dbus_message_ref (message);
00431 _dbus_connection_queue_received_message_link (connection, link);
00432
00433 return TRUE;
00434 }
00435
00448 void
00449 _dbus_connection_test_get_locks (DBusConnection *connection,
00450 DBusMutex **mutex_loc,
00451 DBusMutex **dispatch_mutex_loc,
00452 DBusMutex **io_path_mutex_loc,
00453 DBusCondVar **dispatch_cond_loc,
00454 DBusCondVar **io_path_cond_loc)
00455 {
00456 *mutex_loc = connection->mutex;
00457 *dispatch_mutex_loc = connection->dispatch_mutex;
00458 *io_path_mutex_loc = connection->io_path_mutex;
00459 *dispatch_cond_loc = connection->dispatch_cond;
00460 *io_path_cond_loc = connection->io_path_cond;
00461 }
00462 #endif
00463
00472 void
00473 _dbus_connection_queue_received_message_link (DBusConnection *connection,
00474 DBusList *link)
00475 {
00476 DBusPendingCall *pending;
00477 dbus_uint32_t reply_serial;
00478 DBusMessage *message;
00479
00480 _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport));
00481
00482 _dbus_list_append_link (&connection->incoming_messages,
00483 link);
00484 message = link->data;
00485
00486
00487 reply_serial = dbus_message_get_reply_serial (message);
00488 if (reply_serial != 0)
00489 {
00490 pending = _dbus_hash_table_lookup_int (connection->pending_replies,
00491 reply_serial);
00492 if (pending != NULL)
00493 {
00494 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00495 _dbus_connection_remove_timeout_unlocked (connection,
00496 _dbus_pending_call_get_timeout_unlocked (pending));
00497
00498 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00499 }
00500 }
00501
00502
00503
00504 connection->n_incoming += 1;
00505
00506 _dbus_connection_wakeup_mainloop (connection);
00507
00508 _dbus_verbose ("Message %p (%s %s %s %s '%s' reply to %u) added to incoming queue %p, %d incoming\n",
00509 message,
00510 dbus_message_type_to_string (dbus_message_get_type (message)),
00511 dbus_message_get_path (message) ?
00512 dbus_message_get_path (message) :
00513 "no path",
00514 dbus_message_get_interface (message) ?
00515 dbus_message_get_interface (message) :
00516 "no interface",
00517 dbus_message_get_member (message) ?
00518 dbus_message_get_member (message) :
00519 "no member",
00520 dbus_message_get_signature (message),
00521 dbus_message_get_reply_serial (message),
00522 connection,
00523 connection->n_incoming);}
00524
00533 void
00534 _dbus_connection_queue_synthesized_message_link (DBusConnection *connection,
00535 DBusList *link)
00536 {
00537 HAVE_LOCK_CHECK (connection);
00538
00539 _dbus_list_append_link (&connection->incoming_messages, link);
00540
00541 connection->n_incoming += 1;
00542
00543 _dbus_connection_wakeup_mainloop (connection);
00544
00545 _dbus_verbose ("Synthesized message %p added to incoming queue %p, %d incoming\n",
00546 link->data, connection, connection->n_incoming);
00547 }
00548
00549
00557 dbus_bool_t
00558 _dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection)
00559 {
00560 HAVE_LOCK_CHECK (connection);
00561 return connection->outgoing_messages != NULL;
00562 }
00563
00573 dbus_bool_t
00574 dbus_connection_has_messages_to_send (DBusConnection *connection)
00575 {
00576 dbus_bool_t v;
00577
00578 _dbus_return_val_if_fail (connection != NULL, FALSE);
00579
00580 CONNECTION_LOCK (connection);
00581 v = _dbus_connection_has_messages_to_send_unlocked (connection);
00582 CONNECTION_UNLOCK (connection);
00583
00584 return v;
00585 }
00586
00594 DBusMessage*
00595 _dbus_connection_get_message_to_send (DBusConnection *connection)
00596 {
00597 HAVE_LOCK_CHECK (connection);
00598
00599 return _dbus_list_get_last (&connection->outgoing_messages);
00600 }
00601
00610 void
00611 _dbus_connection_message_sent (DBusConnection *connection,
00612 DBusMessage *message)
00613 {
00614 DBusList *link;
00615
00616 HAVE_LOCK_CHECK (connection);
00617
00618
00619
00620
00621
00622
00623 link = _dbus_list_get_last_link (&connection->outgoing_messages);
00624 _dbus_assert (link != NULL);
00625 _dbus_assert (link->data == message);
00626
00627
00628 _dbus_list_unlink (&connection->outgoing_messages,
00629 link);
00630 _dbus_list_prepend_link (&connection->link_cache, link);
00631
00632 connection->n_outgoing -= 1;
00633
00634 _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from outgoing queue %p, %d left to send\n",
00635 message,
00636 dbus_message_type_to_string (dbus_message_get_type (message)),
00637 dbus_message_get_path (message) ?
00638 dbus_message_get_path (message) :
00639 "no path",
00640 dbus_message_get_interface (message) ?
00641 dbus_message_get_interface (message) :
00642 "no interface",
00643 dbus_message_get_member (message) ?
00644 dbus_message_get_member (message) :
00645 "no member",
00646 dbus_message_get_signature (message),
00647 connection, connection->n_outgoing);
00648
00649
00650 _dbus_message_remove_counter (message, connection->outgoing_counter,
00651 &link);
00652 _dbus_list_prepend_link (&connection->link_cache, link);
00653
00654 dbus_message_unref (message);
00655 }
00656
00658 typedef dbus_bool_t (* DBusWatchAddFunction) (DBusWatchList *list,
00659 DBusWatch *watch);
00661 typedef void (* DBusWatchRemoveFunction) (DBusWatchList *list,
00662 DBusWatch *watch);
00664 typedef void (* DBusWatchToggleFunction) (DBusWatchList *list,
00665 DBusWatch *watch,
00666 dbus_bool_t enabled);
00667
00668 static dbus_bool_t
00669 protected_change_watch (DBusConnection *connection,
00670 DBusWatch *watch,
00671 DBusWatchAddFunction add_function,
00672 DBusWatchRemoveFunction remove_function,
00673 DBusWatchToggleFunction toggle_function,
00674 dbus_bool_t enabled)
00675 {
00676 dbus_bool_t retval;
00677
00678 HAVE_LOCK_CHECK (connection);
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698 if (connection->watches)
00699 {
00700 if (add_function)
00701 retval = (* add_function) (connection->watches, watch);
00702 else if (remove_function)
00703 {
00704 retval = TRUE;
00705 (* remove_function) (connection->watches, watch);
00706 }
00707 else
00708 {
00709 retval = TRUE;
00710 (* toggle_function) (connection->watches, watch, enabled);
00711 }
00712 return retval;
00713 }
00714 else
00715 return FALSE;
00716 }
00717
00718
00730 dbus_bool_t
00731 _dbus_connection_add_watch_unlocked (DBusConnection *connection,
00732 DBusWatch *watch)
00733 {
00734 return protected_change_watch (connection, watch,
00735 _dbus_watch_list_add_watch,
00736 NULL, NULL, FALSE);
00737 }
00738
00748 void
00749 _dbus_connection_remove_watch_unlocked (DBusConnection *connection,
00750 DBusWatch *watch)
00751 {
00752 protected_change_watch (connection, watch,
00753 NULL,
00754 _dbus_watch_list_remove_watch,
00755 NULL, FALSE);
00756 }
00757
00768 void
00769 _dbus_connection_toggle_watch_unlocked (DBusConnection *connection,
00770 DBusWatch *watch,
00771 dbus_bool_t enabled)
00772 {
00773 _dbus_assert (watch != NULL);
00774
00775 protected_change_watch (connection, watch,
00776 NULL, NULL,
00777 _dbus_watch_list_toggle_watch,
00778 enabled);
00779 }
00780
00782 typedef dbus_bool_t (* DBusTimeoutAddFunction) (DBusTimeoutList *list,
00783 DBusTimeout *timeout);
00785 typedef void (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list,
00786 DBusTimeout *timeout);
00788 typedef void (* DBusTimeoutToggleFunction) (DBusTimeoutList *list,
00789 DBusTimeout *timeout,
00790 dbus_bool_t enabled);
00791
00792 static dbus_bool_t
00793 protected_change_timeout (DBusConnection *connection,
00794 DBusTimeout *timeout,
00795 DBusTimeoutAddFunction add_function,
00796 DBusTimeoutRemoveFunction remove_function,
00797 DBusTimeoutToggleFunction toggle_function,
00798 dbus_bool_t enabled)
00799 {
00800 dbus_bool_t retval;
00801
00802 HAVE_LOCK_CHECK (connection);
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822 if (connection->timeouts)
00823 {
00824 if (add_function)
00825 retval = (* add_function) (connection->timeouts, timeout);
00826 else if (remove_function)
00827 {
00828 retval = TRUE;
00829 (* remove_function) (connection->timeouts, timeout);
00830 }
00831 else
00832 {
00833 retval = TRUE;
00834 (* toggle_function) (connection->timeouts, timeout, enabled);
00835 }
00836 return retval;
00837 }
00838 else
00839 return FALSE;
00840 }
00841
00854 dbus_bool_t
00855 _dbus_connection_add_timeout_unlocked (DBusConnection *connection,
00856 DBusTimeout *timeout)
00857 {
00858 return protected_change_timeout (connection, timeout,
00859 _dbus_timeout_list_add_timeout,
00860 NULL, NULL, FALSE);
00861 }
00862
00872 void
00873 _dbus_connection_remove_timeout_unlocked (DBusConnection *connection,
00874 DBusTimeout *timeout)
00875 {
00876 protected_change_timeout (connection, timeout,
00877 NULL,
00878 _dbus_timeout_list_remove_timeout,
00879 NULL, FALSE);
00880 }
00881
00892 void
00893 _dbus_connection_toggle_timeout_unlocked (DBusConnection *connection,
00894 DBusTimeout *timeout,
00895 dbus_bool_t enabled)
00896 {
00897 protected_change_timeout (connection, timeout,
00898 NULL, NULL,
00899 _dbus_timeout_list_toggle_timeout,
00900 enabled);
00901 }
00902
00903 static dbus_bool_t
00904 _dbus_connection_attach_pending_call_unlocked (DBusConnection *connection,
00905 DBusPendingCall *pending)
00906 {
00907 dbus_uint32_t reply_serial;
00908 DBusTimeout *timeout;
00909
00910 HAVE_LOCK_CHECK (connection);
00911
00912 reply_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
00913
00914 _dbus_assert (reply_serial != 0);
00915
00916 timeout = _dbus_pending_call_get_timeout_unlocked (pending);
00917
00918 if (timeout)
00919 {
00920 if (!_dbus_connection_add_timeout_unlocked (connection, timeout))
00921 return FALSE;
00922
00923 if (!_dbus_hash_table_insert_int (connection->pending_replies,
00924 reply_serial,
00925 pending))
00926 {
00927 _dbus_connection_remove_timeout_unlocked (connection, timeout);
00928
00929 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00930 HAVE_LOCK_CHECK (connection);
00931 return FALSE;
00932 }
00933
00934 _dbus_pending_call_set_timeout_added_unlocked (pending, TRUE);
00935 }
00936 else
00937 {
00938 if (!_dbus_hash_table_insert_int (connection->pending_replies,
00939 reply_serial,
00940 pending))
00941 {
00942 HAVE_LOCK_CHECK (connection);
00943 return FALSE;
00944 }
00945 }
00946
00947 _dbus_pending_call_ref_unlocked (pending);
00948
00949 HAVE_LOCK_CHECK (connection);
00950
00951 return TRUE;
00952 }
00953
00954 static void
00955 free_pending_call_on_hash_removal (void *data)
00956 {
00957 DBusPendingCall *pending;
00958 DBusConnection *connection;
00959
00960 if (data == NULL)
00961 return;
00962
00963 pending = data;
00964
00965 connection = _dbus_pending_call_get_connection_unlocked (pending);
00966
00967 HAVE_LOCK_CHECK (connection);
00968
00969 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00970 {
00971 _dbus_connection_remove_timeout_unlocked (connection,
00972 _dbus_pending_call_get_timeout_unlocked (pending));
00973
00974 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00975 }
00976
00977
00978
00979
00980
00981
00982 _dbus_connection_ref_unlocked (connection);
00983 _dbus_pending_call_unref_and_unlock (pending);
00984 CONNECTION_LOCK (connection);
00985 _dbus_connection_unref_unlocked (connection);
00986 }
00987
00988 static void
00989 _dbus_connection_detach_pending_call_unlocked (DBusConnection *connection,
00990 DBusPendingCall *pending)
00991 {
00992
00993
00994
00995 _dbus_hash_table_remove_int (connection->pending_replies,
00996 _dbus_pending_call_get_reply_serial_unlocked (pending));
00997 }
00998
00999 static void
01000 _dbus_connection_detach_pending_call_and_unlock (DBusConnection *connection,
01001 DBusPendingCall *pending)
01002 {
01003
01004
01005
01006
01007
01008
01009
01010 _dbus_pending_call_ref_unlocked (pending);
01011 _dbus_hash_table_remove_int (connection->pending_replies,
01012 _dbus_pending_call_get_reply_serial_unlocked (pending));
01013
01014 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
01015 _dbus_connection_remove_timeout_unlocked (connection,
01016 _dbus_pending_call_get_timeout_unlocked (pending));
01017
01018 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
01019
01020 _dbus_pending_call_unref_and_unlock (pending);
01021 }
01022
01031 void
01032 _dbus_connection_remove_pending_call (DBusConnection *connection,
01033 DBusPendingCall *pending)
01034 {
01035 CONNECTION_LOCK (connection);
01036 _dbus_connection_detach_pending_call_and_unlock (connection, pending);
01037 }
01038
01048 static dbus_bool_t
01049 _dbus_connection_acquire_io_path (DBusConnection *connection,
01050 int timeout_milliseconds)
01051 {
01052 dbus_bool_t we_acquired;
01053
01054 HAVE_LOCK_CHECK (connection);
01055
01056
01057 _dbus_connection_ref_unlocked (connection);
01058
01059
01060 CONNECTION_UNLOCK (connection);
01061
01062 _dbus_verbose ("locking io_path_mutex\n");
01063 _dbus_mutex_lock (connection->io_path_mutex);
01064
01065 _dbus_verbose ("start connection->io_path_acquired = %d timeout = %d\n",
01066 connection->io_path_acquired, timeout_milliseconds);
01067
01068 we_acquired = FALSE;
01069
01070 if (connection->io_path_acquired)
01071 {
01072 if (timeout_milliseconds != -1)
01073 {
01074 _dbus_verbose ("waiting %d for IO path to be acquirable\n",
01075 timeout_milliseconds);
01076
01077 if (!_dbus_condvar_wait_timeout (connection->io_path_cond,
01078 connection->io_path_mutex,
01079 timeout_milliseconds))
01080 {
01081
01082
01083
01084
01085
01086
01087
01088
01089 }
01090 }
01091 else
01092 {
01093 while (connection->io_path_acquired)
01094 {
01095 _dbus_verbose ("waiting for IO path to be acquirable\n");
01096 _dbus_condvar_wait (connection->io_path_cond,
01097 connection->io_path_mutex);
01098 }
01099 }
01100 }
01101
01102 if (!connection->io_path_acquired)
01103 {
01104 we_acquired = TRUE;
01105 connection->io_path_acquired = TRUE;
01106 }
01107
01108 _dbus_verbose ("end connection->io_path_acquired = %d we_acquired = %d\n",
01109 connection->io_path_acquired, we_acquired);
01110
01111 _dbus_verbose ("unlocking io_path_mutex\n");
01112 _dbus_mutex_unlock (connection->io_path_mutex);
01113
01114 CONNECTION_LOCK (connection);
01115
01116 HAVE_LOCK_CHECK (connection);
01117
01118 _dbus_connection_unref_unlocked (connection);
01119
01120 return we_acquired;
01121 }
01122
01130 static void
01131 _dbus_connection_release_io_path (DBusConnection *connection)
01132 {
01133 HAVE_LOCK_CHECK (connection);
01134
01135 _dbus_verbose ("locking io_path_mutex\n");
01136 _dbus_mutex_lock (connection->io_path_mutex);
01137
01138 _dbus_assert (connection->io_path_acquired);
01139
01140 _dbus_verbose ("start connection->io_path_acquired = %d\n",
01141 connection->io_path_acquired);
01142
01143 connection->io_path_acquired = FALSE;
01144 _dbus_condvar_wake_one (connection->io_path_cond);
01145
01146 _dbus_verbose ("unlocking io_path_mutex\n");
01147 _dbus_mutex_unlock (connection->io_path_mutex);
01148 }
01149
01185 void
01186 _dbus_connection_do_iteration_unlocked (DBusConnection *connection,
01187 DBusPendingCall *pending,
01188 unsigned int flags,
01189 int timeout_milliseconds)
01190 {
01191 _dbus_verbose ("start\n");
01192
01193 HAVE_LOCK_CHECK (connection);
01194
01195 if (connection->n_outgoing == 0)
01196 flags &= ~DBUS_ITERATION_DO_WRITING;
01197
01198 if (_dbus_connection_acquire_io_path (connection,
01199 (flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0))
01200 {
01201 HAVE_LOCK_CHECK (connection);
01202
01203 if ( (pending != NULL) && _dbus_pending_call_get_completed_unlocked(pending))
01204 {
01205 _dbus_verbose ("pending call completed while acquiring I/O path");
01206 }
01207 else if ( (pending != NULL) &&
01208 _dbus_connection_peek_for_reply_unlocked (connection,
01209 _dbus_pending_call_get_reply_serial_unlocked (pending)))
01210 {
01211 _dbus_verbose ("pending call completed while acquiring I/O path (reply found in queue)");
01212 }
01213 else
01214 {
01215 _dbus_transport_do_iteration (connection->transport,
01216 flags, timeout_milliseconds);
01217 }
01218
01219 _dbus_connection_release_io_path (connection);
01220 }
01221
01222 HAVE_LOCK_CHECK (connection);
01223
01224 _dbus_verbose ("end\n");
01225 }
01226
01236 DBusConnection*
01237 _dbus_connection_new_for_transport (DBusTransport *transport)
01238 {
01239 DBusConnection *connection;
01240 DBusWatchList *watch_list;
01241 DBusTimeoutList *timeout_list;
01242 DBusHashTable *pending_replies;
01243 DBusList *disconnect_link;
01244 DBusMessage *disconnect_message;
01245 DBusCounter *outgoing_counter;
01246 DBusObjectTree *objects;
01247
01248 watch_list = NULL;
01249 connection = NULL;
01250 pending_replies = NULL;
01251 timeout_list = NULL;
01252 disconnect_link = NULL;
01253 disconnect_message = NULL;
01254 outgoing_counter = NULL;
01255 objects = NULL;
01256
01257 watch_list = _dbus_watch_list_new ();
01258 if (watch_list == NULL)
01259 goto error;
01260
01261 timeout_list = _dbus_timeout_list_new ();
01262 if (timeout_list == NULL)
01263 goto error;
01264
01265 pending_replies =
01266 _dbus_hash_table_new (DBUS_HASH_INT,
01267 NULL,
01268 (DBusFreeFunction)free_pending_call_on_hash_removal);
01269 if (pending_replies == NULL)
01270 goto error;
01271
01272 connection = dbus_new0 (DBusConnection, 1);
01273 if (connection == NULL)
01274 goto error;
01275
01276 _dbus_mutex_new_at_location (&connection->mutex);
01277 if (connection->mutex == NULL)
01278 goto error;
01279
01280 _dbus_mutex_new_at_location (&connection->io_path_mutex);
01281 if (connection->io_path_mutex == NULL)
01282 goto error;
01283
01284 _dbus_mutex_new_at_location (&connection->dispatch_mutex);
01285 if (connection->dispatch_mutex == NULL)
01286 goto error;
01287
01288 _dbus_condvar_new_at_location (&connection->dispatch_cond);
01289 if (connection->dispatch_cond == NULL)
01290 goto error;
01291
01292 _dbus_condvar_new_at_location (&connection->io_path_cond);
01293 if (connection->io_path_cond == NULL)
01294 goto error;
01295
01296 _dbus_mutex_new_at_location (&connection->slot_mutex);
01297 if (connection->slot_mutex == NULL)
01298 goto error;
01299
01300 disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL,
01301 DBUS_INTERFACE_LOCAL,
01302 "Disconnected");
01303
01304 if (disconnect_message == NULL)
01305 goto error;
01306
01307 disconnect_link = _dbus_list_alloc_link (disconnect_message);
01308 if (disconnect_link == NULL)
01309 goto error;
01310
01311 outgoing_counter = _dbus_counter_new ();
01312 if (outgoing_counter == NULL)
01313 goto error;
01314
01315 objects = _dbus_object_tree_new (connection);
01316 if (objects == NULL)
01317 goto error;
01318
01319 if (_dbus_modify_sigpipe)
01320 _dbus_disable_sigpipe ();
01321
01322
01323 _dbus_atomic_inc (&connection->refcount);
01324 connection->transport = transport;
01325 connection->watches = watch_list;
01326 connection->timeouts = timeout_list;
01327 connection->pending_replies = pending_replies;
01328 connection->outgoing_counter = outgoing_counter;
01329 connection->filter_list = NULL;
01330 connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE;
01331 connection->objects = objects;
01332 connection->exit_on_disconnect = FALSE;
01333 connection->shareable = FALSE;
01334 connection->route_peer_messages = FALSE;
01335 connection->disconnected_message_arrived = FALSE;
01336 connection->disconnected_message_processed = FALSE;
01337
01338 #ifndef DBUS_DISABLE_CHECKS
01339 connection->generation = _dbus_current_generation;
01340 #endif
01341
01342 _dbus_data_slot_list_init (&connection->slot_list);
01343
01344 connection->client_serial = 1;
01345
01346 connection->disconnect_message_link = disconnect_link;
01347
01348 CONNECTION_LOCK (connection);
01349
01350 if (!_dbus_transport_set_connection (transport, connection))
01351 {
01352 CONNECTION_UNLOCK (connection);
01353
01354 goto error;
01355 }
01356
01357 _dbus_transport_ref (transport);
01358
01359 CONNECTION_UNLOCK (connection);
01360
01361 return connection;
01362
01363 error:
01364 if (disconnect_message != NULL)
01365 dbus_message_unref (disconnect_message);
01366
01367 if (disconnect_link != NULL)
01368 _dbus_list_free_link (disconnect_link);
01369
01370 if (connection != NULL)
01371 {
01372 _dbus_condvar_free_at_location (&connection->io_path_cond);
01373 _dbus_condvar_free_at_location (&connection->dispatch_cond);
01374 _dbus_mutex_free_at_location (&connection->mutex);
01375 _dbus_mutex_free_at_location (&connection->io_path_mutex);
01376 _dbus_mutex_free_at_location (&connection->dispatch_mutex);
01377 _dbus_mutex_free_at_location (&connection->slot_mutex);
01378 dbus_free (connection);
01379 }
01380 if (pending_replies)
01381 _dbus_hash_table_unref (pending_replies);
01382
01383 if (watch_list)
01384 _dbus_watch_list_free (watch_list);
01385
01386 if (timeout_list)
01387 _dbus_timeout_list_free (timeout_list);
01388
01389 if (outgoing_counter)
01390 _dbus_counter_unref (outgoing_counter);
01391
01392 if (objects)
01393 _dbus_object_tree_unref (objects);
01394
01395 return NULL;
01396 }
01397
01405 DBusConnection *
01406 _dbus_connection_ref_unlocked (DBusConnection *connection)
01407 {
01408 _dbus_assert (connection != NULL);
01409 _dbus_assert (connection->generation == _dbus_current_generation);
01410
01411 HAVE_LOCK_CHECK (connection);
01412
01413 _dbus_atomic_inc (&connection->refcount);
01414
01415 return connection;
01416 }
01417
01424 void
01425 _dbus_connection_unref_unlocked (DBusConnection *connection)
01426 {
01427 dbus_bool_t last_unref;
01428
01429 HAVE_LOCK_CHECK (connection);
01430
01431 _dbus_assert (connection != NULL);
01432
01433 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
01434
01435 if (last_unref)
01436 _dbus_connection_last_unref (connection);
01437 }
01438
01439 static dbus_uint32_t
01440 _dbus_connection_get_next_client_serial (DBusConnection *connection)
01441 {
01442 dbus_uint32_t serial;
01443
01444 serial = connection->client_serial++;
01445
01446 if (connection->client_serial == 0)
01447 connection->client_serial = 1;
01448
01449 return serial;
01450 }
01451
01465 dbus_bool_t
01466 _dbus_connection_handle_watch (DBusWatch *watch,
01467 unsigned int condition,
01468 void *data)
01469 {
01470 DBusConnection *connection;
01471 dbus_bool_t retval;
01472 DBusDispatchStatus status;
01473
01474 connection = data;
01475
01476 _dbus_verbose ("start\n");
01477
01478 CONNECTION_LOCK (connection);
01479
01480 if (!_dbus_connection_acquire_io_path (connection, 1))
01481 {
01482
01483 CONNECTION_UNLOCK (connection);
01484 return TRUE;
01485 }
01486
01487 HAVE_LOCK_CHECK (connection);
01488 retval = _dbus_transport_handle_watch (connection->transport,
01489 watch, condition);
01490
01491 _dbus_connection_release_io_path (connection);
01492
01493 HAVE_LOCK_CHECK (connection);
01494
01495 _dbus_verbose ("middle\n");
01496
01497 status = _dbus_connection_get_dispatch_status_unlocked (connection);
01498
01499
01500 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01501
01502 _dbus_verbose ("end\n");
01503
01504 return retval;
01505 }
01506
01507 _DBUS_DEFINE_GLOBAL_LOCK (shared_connections);
01508 static DBusHashTable *shared_connections = NULL;
01509 static DBusList *shared_connections_no_guid = NULL;
01510
01511 static void
01512 close_connection_on_shutdown (DBusConnection *connection)
01513 {
01514 DBusMessage *message;
01515
01516 dbus_connection_ref (connection);
01517 _dbus_connection_close_possibly_shared (connection);
01518
01519
01520 while ((message = dbus_connection_pop_message (connection)))
01521 {
01522 dbus_message_unref (message);
01523 }
01524 dbus_connection_unref (connection);
01525 }
01526
01527 static void
01528 shared_connections_shutdown (void *data)
01529 {
01530 int n_entries;
01531
01532 _DBUS_LOCK (shared_connections);
01533
01534
01535 while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0)
01536 {
01537 DBusConnection *connection;
01538 DBusHashIter iter;
01539
01540 _dbus_hash_iter_init (shared_connections, &iter);
01541 _dbus_hash_iter_next (&iter);
01542
01543 connection = _dbus_hash_iter_get_value (&iter);
01544
01545 _DBUS_UNLOCK (shared_connections);
01546 close_connection_on_shutdown (connection);
01547 _DBUS_LOCK (shared_connections);
01548
01549
01550 _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) < n_entries);
01551 }
01552
01553 _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) == 0);
01554
01555 _dbus_hash_table_unref (shared_connections);
01556 shared_connections = NULL;
01557
01558 if (shared_connections_no_guid != NULL)
01559 {
01560 DBusConnection *connection;
01561 connection = _dbus_list_pop_first (&shared_connections_no_guid);
01562 while (connection != NULL)
01563 {
01564 _DBUS_UNLOCK (shared_connections);
01565 close_connection_on_shutdown (connection);
01566 _DBUS_LOCK (shared_connections);
01567 connection = _dbus_list_pop_first (&shared_connections_no_guid);
01568 }
01569 }
01570
01571 shared_connections_no_guid = NULL;
01572
01573 _DBUS_UNLOCK (shared_connections);
01574 }
01575
01576 static dbus_bool_t
01577 connection_lookup_shared (DBusAddressEntry *entry,
01578 DBusConnection **result)
01579 {
01580 _dbus_verbose ("checking for existing connection\n");
01581
01582 *result = NULL;
01583
01584 _DBUS_LOCK (shared_connections);
01585
01586 if (shared_connections == NULL)
01587 {
01588 _dbus_verbose ("creating shared_connections hash table\n");
01589
01590 shared_connections = _dbus_hash_table_new (DBUS_HASH_STRING,
01591 dbus_free,
01592 NULL);
01593 if (shared_connections == NULL)
01594 {
01595 _DBUS_UNLOCK (shared_connections);
01596 return FALSE;
01597 }
01598
01599 if (!_dbus_register_shutdown_func (shared_connections_shutdown, NULL))
01600 {
01601 _dbus_hash_table_unref (shared_connections);
01602 shared_connections = NULL;
01603 _DBUS_UNLOCK (shared_connections);
01604 return FALSE;
01605 }
01606
01607 _dbus_verbose (" successfully created shared_connections\n");
01608
01609 _DBUS_UNLOCK (shared_connections);
01610 return TRUE;
01611 }
01612 else
01613 {
01614 const char *guid;
01615
01616 guid = dbus_address_entry_get_value (entry, "guid");
01617
01618 if (guid != NULL)
01619 {
01620 DBusConnection *connection;
01621
01622 connection = _dbus_hash_table_lookup_string (shared_connections,
01623 guid);
01624
01625 if (connection)
01626 {
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641 CONNECTION_LOCK (connection);
01642 if (_dbus_connection_get_is_connected_unlocked (connection))
01643 {
01644 _dbus_connection_ref_unlocked (connection);
01645 *result = connection;
01646 _dbus_verbose ("looked up existing connection to server guid %s\n",
01647 guid);
01648 }
01649 else
01650 {
01651 _dbus_verbose ("looked up existing connection to server guid %s but it was disconnected so ignoring it\n",
01652 guid);
01653 }
01654 CONNECTION_UNLOCK (connection);
01655 }
01656 }
01657
01658 _DBUS_UNLOCK (shared_connections);
01659 return TRUE;
01660 }
01661 }
01662
01663 static dbus_bool_t
01664 connection_record_shared_unlocked (DBusConnection *connection,
01665 const char *guid)
01666 {
01667 char *guid_key;
01668 char *guid_in_connection;
01669
01670 HAVE_LOCK_CHECK (connection);
01671 _dbus_assert (connection->server_guid == NULL);
01672 _dbus_assert (connection->shareable);
01673
01674
01675
01676
01677
01678 _dbus_connection_ref_unlocked (connection);
01679
01680 if (guid == NULL)
01681 {
01682 _DBUS_LOCK (shared_connections);
01683
01684 if (!_dbus_list_prepend (&shared_connections_no_guid, connection))
01685 {
01686 _DBUS_UNLOCK (shared_connections);
01687 return FALSE;
01688 }
01689
01690 _DBUS_UNLOCK (shared_connections);
01691 return TRUE;
01692 }
01693
01694
01695
01696
01697
01698
01699 guid_key = _dbus_strdup (guid);
01700 if (guid_key == NULL)
01701 return FALSE;
01702
01703 guid_in_connection = _dbus_strdup (guid);
01704 if (guid_in_connection == NULL)
01705 {
01706 dbus_free (guid_key);
01707 return FALSE;
01708 }
01709
01710 _DBUS_LOCK (shared_connections);
01711 _dbus_assert (shared_connections != NULL);
01712
01713 if (!_dbus_hash_table_insert_string (shared_connections,
01714 guid_key, connection))
01715 {
01716 dbus_free (guid_key);
01717 dbus_free (guid_in_connection);
01718 _DBUS_UNLOCK (shared_connections);
01719 return FALSE;
01720 }
01721
01722 connection->server_guid = guid_in_connection;
01723
01724 _dbus_verbose ("stored connection to %s to be shared\n",
01725 connection->server_guid);
01726
01727 _DBUS_UNLOCK (shared_connections);
01728
01729 _dbus_assert (connection->server_guid != NULL);
01730
01731 return TRUE;
01732 }
01733
01734 static void
01735 connection_forget_shared_unlocked (DBusConnection *connection)
01736 {
01737 HAVE_LOCK_CHECK (connection);
01738
01739 if (!connection->shareable)
01740 return;
01741
01742 _DBUS_LOCK (shared_connections);
01743
01744 if (connection->server_guid != NULL)
01745 {
01746 _dbus_verbose ("dropping connection to %s out of the shared table\n",
01747 connection->server_guid);
01748
01749 if (!_dbus_hash_table_remove_string (shared_connections,
01750 connection->server_guid))
01751 _dbus_assert_not_reached ("connection was not in the shared table");
01752
01753 dbus_free (connection->server_guid);
01754 connection->server_guid = NULL;
01755 }
01756 else
01757 {
01758 _dbus_list_remove (&shared_connections_no_guid, connection);
01759 }
01760
01761 _DBUS_UNLOCK (shared_connections);
01762
01763
01764 _dbus_connection_unref_unlocked (connection);
01765 }
01766
01767 static DBusConnection*
01768 connection_try_from_address_entry (DBusAddressEntry *entry,
01769 DBusError *error)
01770 {
01771 DBusTransport *transport;
01772 DBusConnection *connection;
01773
01774 transport = _dbus_transport_open (entry, error);
01775
01776 if (transport == NULL)
01777 {
01778 _DBUS_ASSERT_ERROR_IS_SET (error);
01779 return NULL;
01780 }
01781
01782 connection = _dbus_connection_new_for_transport (transport);
01783
01784 _dbus_transport_unref (transport);
01785
01786 if (connection == NULL)
01787 {
01788 _DBUS_SET_OOM (error);
01789 return NULL;
01790 }
01791
01792 #ifndef DBUS_DISABLE_CHECKS
01793 _dbus_assert (!connection->have_connection_lock);
01794 #endif
01795 return connection;
01796 }
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810 static DBusConnection*
01811 _dbus_connection_open_internal (const char *address,
01812 dbus_bool_t shared,
01813 DBusError *error)
01814 {
01815 DBusConnection *connection;
01816 DBusAddressEntry **entries;
01817 DBusError tmp_error = DBUS_ERROR_INIT;
01818 DBusError first_error = DBUS_ERROR_INIT;
01819 int len, i;
01820
01821 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01822
01823 _dbus_verbose ("opening %s connection to: %s\n",
01824 shared ? "shared" : "private", address);
01825
01826 if (!dbus_parse_address (address, &entries, &len, error))
01827 return NULL;
01828
01829 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01830
01831 connection = NULL;
01832
01833 for (i = 0; i < len; i++)
01834 {
01835 if (shared)
01836 {
01837 if (!connection_lookup_shared (entries[i], &connection))
01838 _DBUS_SET_OOM (&tmp_error);
01839 }
01840
01841 if (connection == NULL)
01842 {
01843 connection = connection_try_from_address_entry (entries[i],
01844 &tmp_error);
01845
01846 if (connection != NULL && shared)
01847 {
01848 const char *guid;
01849
01850 connection->shareable = TRUE;
01851
01852
01853 guid = dbus_address_entry_get_value (entries[i], "guid");
01854
01855 CONNECTION_LOCK (connection);
01856
01857 if (!connection_record_shared_unlocked (connection, guid))
01858 {
01859 _DBUS_SET_OOM (&tmp_error);
01860 _dbus_connection_close_possibly_shared_and_unlock (connection);
01861 dbus_connection_unref (connection);
01862 connection = NULL;
01863 }
01864 else
01865 CONNECTION_UNLOCK (connection);
01866 }
01867 }
01868
01869 if (connection)
01870 break;
01871
01872 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
01873
01874 if (i == 0)
01875 dbus_move_error (&tmp_error, &first_error);
01876 else
01877 dbus_error_free (&tmp_error);
01878 }
01879
01880 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01881 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
01882
01883 if (connection == NULL)
01884 {
01885 _DBUS_ASSERT_ERROR_IS_SET (&first_error);
01886 dbus_move_error (&first_error, error);
01887 }
01888 else
01889 dbus_error_free (&first_error);
01890
01891 dbus_address_entries_free (entries);
01892 return connection;
01893 }
01894
01903 void
01904 _dbus_connection_close_possibly_shared (DBusConnection *connection)
01905 {
01906 _dbus_assert (connection != NULL);
01907 _dbus_assert (connection->generation == _dbus_current_generation);
01908
01909 CONNECTION_LOCK (connection);
01910 _dbus_connection_close_possibly_shared_and_unlock (connection);
01911 }
01912
01913 static DBusPreallocatedSend*
01914 _dbus_connection_preallocate_send_unlocked (DBusConnection *connection)
01915 {
01916 DBusPreallocatedSend *preallocated;
01917
01918 HAVE_LOCK_CHECK (connection);
01919
01920 _dbus_assert (connection != NULL);
01921
01922 preallocated = dbus_new (DBusPreallocatedSend, 1);
01923 if (preallocated == NULL)
01924 return NULL;
01925
01926 if (connection->link_cache != NULL)
01927 {
01928 preallocated->queue_link =
01929 _dbus_list_pop_first_link (&connection->link_cache);
01930 preallocated->queue_link->data = NULL;
01931 }
01932 else
01933 {
01934 preallocated->queue_link = _dbus_list_alloc_link (NULL);
01935 if (preallocated->queue_link == NULL)
01936 goto failed_0;
01937 }
01938
01939 if (connection->link_cache != NULL)
01940 {
01941 preallocated->counter_link =
01942 _dbus_list_pop_first_link (&connection->link_cache);
01943 preallocated->counter_link->data = connection->outgoing_counter;
01944 }
01945 else
01946 {
01947 preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter);
01948 if (preallocated->counter_link == NULL)
01949 goto failed_1;
01950 }
01951
01952 _dbus_counter_ref (preallocated->counter_link->data);
01953
01954 preallocated->connection = connection;
01955
01956 return preallocated;
01957
01958 failed_1:
01959 _dbus_list_free_link (preallocated->queue_link);
01960 failed_0:
01961 dbus_free (preallocated);
01962
01963 return NULL;
01964 }
01965
01966
01967 static void
01968 _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *connection,
01969 DBusPreallocatedSend *preallocated,
01970 DBusMessage *message,
01971 dbus_uint32_t *client_serial)
01972 {
01973 dbus_uint32_t serial;
01974
01975 preallocated->queue_link->data = message;
01976 _dbus_list_prepend_link (&connection->outgoing_messages,
01977 preallocated->queue_link);
01978
01979 _dbus_message_add_counter_link (message,
01980 preallocated->counter_link);
01981
01982 dbus_free (preallocated);
01983 preallocated = NULL;
01984
01985 dbus_message_ref (message);
01986
01987 connection->n_outgoing += 1;
01988
01989 _dbus_verbose ("Message %p (%s %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
01990 message,
01991 dbus_message_type_to_string (dbus_message_get_type (message)),
01992 dbus_message_get_path (message) ?
01993 dbus_message_get_path (message) :
01994 "no path",
01995 dbus_message_get_interface (message) ?
01996 dbus_message_get_interface (message) :
01997 "no interface",
01998 dbus_message_get_member (message) ?
01999 dbus_message_get_member (message) :
02000 "no member",
02001 dbus_message_get_signature (message),
02002 dbus_message_get_destination (message) ?
02003 dbus_message_get_destination (message) :
02004 "null",
02005 connection,
02006 connection->n_outgoing);
02007
02008 if (dbus_message_get_serial (message) == 0)
02009 {
02010 serial = _dbus_connection_get_next_client_serial (connection);
02011 dbus_message_set_serial (message, serial);
02012 if (client_serial)
02013 *client_serial = serial;
02014 }
02015 else
02016 {
02017 if (client_serial)
02018 *client_serial = dbus_message_get_serial (message);
02019 }
02020
02021 _dbus_verbose ("Message %p serial is %u\n",
02022 message, dbus_message_get_serial (message));
02023
02024 dbus_message_lock (message);
02025
02026
02027
02028
02029 _dbus_connection_do_iteration_unlocked (connection,
02030 NULL,
02031 DBUS_ITERATION_DO_WRITING,
02032 -1);
02033
02034
02035 if (connection->n_outgoing > 0)
02036 _dbus_connection_wakeup_mainloop (connection);
02037 }
02038
02039 static void
02040 _dbus_connection_send_preallocated_and_unlock (DBusConnection *connection,
02041 DBusPreallocatedSend *preallocated,
02042 DBusMessage *message,
02043 dbus_uint32_t *client_serial)
02044 {
02045 DBusDispatchStatus status;
02046
02047 HAVE_LOCK_CHECK (connection);
02048
02049 _dbus_connection_send_preallocated_unlocked_no_update (connection,
02050 preallocated,
02051 message, client_serial);
02052
02053 _dbus_verbose ("middle\n");
02054 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02055
02056
02057 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02058 }
02059
02069 dbus_bool_t
02070 _dbus_connection_send_and_unlock (DBusConnection *connection,
02071 DBusMessage *message,
02072 dbus_uint32_t *client_serial)
02073 {
02074 DBusPreallocatedSend *preallocated;
02075
02076 _dbus_assert (connection != NULL);
02077 _dbus_assert (message != NULL);
02078
02079 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
02080 if (preallocated == NULL)
02081 {
02082 CONNECTION_UNLOCK (connection);
02083 return FALSE;
02084 }
02085
02086 _dbus_connection_send_preallocated_and_unlock (connection,
02087 preallocated,
02088 message,
02089 client_serial);
02090 return TRUE;
02091 }
02092
02117 void
02118 _dbus_connection_close_if_only_one_ref (DBusConnection *connection)
02119 {
02120 dbus_int32_t refcount;
02121
02122 CONNECTION_LOCK (connection);
02123
02124 refcount = _dbus_atomic_get (&connection->refcount);
02125
02126 _dbus_assert (refcount >= 1);
02127
02128 if (refcount == 1)
02129 _dbus_connection_close_possibly_shared_and_unlock (connection);
02130 else
02131 CONNECTION_UNLOCK (connection);
02132 }
02133
02134
02144 static void
02145 _dbus_memory_pause_based_on_timeout (int timeout_milliseconds)
02146 {
02147 if (timeout_milliseconds == -1)
02148 _dbus_sleep_milliseconds (1000);
02149 else if (timeout_milliseconds < 100)
02150 ;
02151 else if (timeout_milliseconds <= 1000)
02152 _dbus_sleep_milliseconds (timeout_milliseconds / 3);
02153 else
02154 _dbus_sleep_milliseconds (1000);
02155 }
02156
02157 static DBusMessage *
02158 generate_local_error_message (dbus_uint32_t serial,
02159 char *error_name,
02160 char *error_msg)
02161 {
02162 DBusMessage *message;
02163 message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
02164 if (!message)
02165 goto out;
02166
02167 if (!dbus_message_set_error_name (message, error_name))
02168 {
02169 dbus_message_unref (message);
02170 message = NULL;
02171 goto out;
02172 }
02173
02174 dbus_message_set_no_reply (message, TRUE);
02175
02176 if (!dbus_message_set_reply_serial (message,
02177 serial))
02178 {
02179 dbus_message_unref (message);
02180 message = NULL;
02181 goto out;
02182 }
02183
02184 if (error_msg != NULL)
02185 {
02186 DBusMessageIter iter;
02187
02188 dbus_message_iter_init_append (message, &iter);
02189 if (!dbus_message_iter_append_basic (&iter,
02190 DBUS_TYPE_STRING,
02191 &error_msg))
02192 {
02193 dbus_message_unref (message);
02194 message = NULL;
02195 goto out;
02196 }
02197 }
02198
02199 out:
02200 return message;
02201 }
02202
02203
02204
02205
02206 static dbus_bool_t
02207 _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection,
02208 dbus_uint32_t client_serial)
02209 {
02210 DBusList *link;
02211 HAVE_LOCK_CHECK (connection);
02212
02213 link = _dbus_list_get_first_link (&connection->incoming_messages);
02214
02215 while (link != NULL)
02216 {
02217 DBusMessage *reply = link->data;
02218
02219 if (dbus_message_get_reply_serial (reply) == client_serial)
02220 {
02221 _dbus_verbose ("%s reply to %d found in queue\n", _DBUS_FUNCTION_NAME, client_serial);
02222 return TRUE;
02223 }
02224 link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02225 }
02226
02227 return FALSE;
02228 }
02229
02230
02231
02232
02233 static DBusMessage*
02234 check_for_reply_unlocked (DBusConnection *connection,
02235 dbus_uint32_t client_serial)
02236 {
02237 DBusList *link;
02238
02239 HAVE_LOCK_CHECK (connection);
02240
02241 link = _dbus_list_get_first_link (&connection->incoming_messages);
02242
02243 while (link != NULL)
02244 {
02245 DBusMessage *reply = link->data;
02246
02247 if (dbus_message_get_reply_serial (reply) == client_serial)
02248 {
02249 _dbus_list_remove_link (&connection->incoming_messages, link);
02250 connection->n_incoming -= 1;
02251 return reply;
02252 }
02253 link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02254 }
02255
02256 return NULL;
02257 }
02258
02259 static void
02260 connection_timeout_and_complete_all_pending_calls_unlocked (DBusConnection *connection)
02261 {
02262
02263
02264
02265
02266
02267 while (_dbus_hash_table_get_n_entries (connection->pending_replies) > 0)
02268 {
02269 DBusPendingCall *pending;
02270 DBusHashIter iter;
02271
02272 _dbus_hash_iter_init (connection->pending_replies, &iter);
02273 _dbus_hash_iter_next (&iter);
02274
02275 pending = _dbus_hash_iter_get_value (&iter);
02276 _dbus_pending_call_ref_unlocked (pending);
02277
02278 _dbus_pending_call_queue_timeout_error_unlocked (pending,
02279 connection);
02280
02281 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
02282 _dbus_connection_remove_timeout_unlocked (connection,
02283 _dbus_pending_call_get_timeout_unlocked (pending));
02284 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
02285 _dbus_hash_iter_remove_entry (&iter);
02286
02287 _dbus_pending_call_unref_and_unlock (pending);
02288 CONNECTION_LOCK (connection);
02289 }
02290 HAVE_LOCK_CHECK (connection);
02291 }
02292
02293 static void
02294 complete_pending_call_and_unlock (DBusConnection *connection,
02295 DBusPendingCall *pending,
02296 DBusMessage *message)
02297 {
02298 _dbus_pending_call_set_reply_unlocked (pending, message);
02299 _dbus_pending_call_ref_unlocked (pending);
02300 _dbus_connection_detach_pending_call_and_unlock (connection, pending);
02301
02302
02303 _dbus_pending_call_complete (pending);
02304 dbus_pending_call_unref (pending);
02305 }
02306
02307 static dbus_bool_t
02308 check_for_reply_and_update_dispatch_unlocked (DBusConnection *connection,
02309 DBusPendingCall *pending)
02310 {
02311 DBusMessage *reply;
02312 DBusDispatchStatus status;
02313
02314 reply = check_for_reply_unlocked (connection,
02315 _dbus_pending_call_get_reply_serial_unlocked (pending));
02316 if (reply != NULL)
02317 {
02318 _dbus_verbose ("checked for reply\n");
02319
02320 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
02321
02322 complete_pending_call_and_unlock (connection, pending, reply);
02323 dbus_message_unref (reply);
02324
02325 CONNECTION_LOCK (connection);
02326 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02327 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02328 dbus_pending_call_unref (pending);
02329
02330 return TRUE;
02331 }
02332
02333 return FALSE;
02334 }
02335
02350 void
02351 _dbus_connection_block_pending_call (DBusPendingCall *pending)
02352 {
02353 long start_tv_sec, start_tv_usec;
02354 long tv_sec, tv_usec;
02355 DBusDispatchStatus status;
02356 DBusConnection *connection;
02357 dbus_uint32_t client_serial;
02358 DBusTimeout *timeout;
02359 int timeout_milliseconds, elapsed_milliseconds;
02360
02361 _dbus_assert (pending != NULL);
02362
02363 if (dbus_pending_call_get_completed (pending))
02364 return;
02365
02366 dbus_pending_call_ref (pending);
02367
02368 connection = _dbus_pending_call_get_connection_and_lock (pending);
02369
02370
02371 _dbus_connection_flush_unlocked (connection);
02372
02373 client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
02374
02375
02376
02377
02378
02379 timeout = _dbus_pending_call_get_timeout_unlocked (pending);
02380 _dbus_get_current_time (&start_tv_sec, &start_tv_usec);
02381 if (timeout)
02382 {
02383 timeout_milliseconds = dbus_timeout_get_interval (timeout);
02384
02385 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec\n",
02386 timeout_milliseconds,
02387 client_serial,
02388 start_tv_sec, start_tv_usec);
02389 }
02390 else
02391 {
02392 timeout_milliseconds = -1;
02393
02394 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block for reply serial %u\n", client_serial);
02395 }
02396
02397
02398
02399 if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02400 return;
02401
02402
02403
02404 _dbus_connection_do_iteration_unlocked (connection,
02405 pending,
02406 DBUS_ITERATION_DO_READING |
02407 DBUS_ITERATION_BLOCK,
02408 timeout_milliseconds);
02409
02410 recheck_status:
02411
02412 _dbus_verbose ("top of recheck\n");
02413
02414 HAVE_LOCK_CHECK (connection);
02415
02416
02417
02418 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02419
02420
02421
02422
02423 if (_dbus_pending_call_get_completed_unlocked (pending))
02424 {
02425 _dbus_verbose ("Pending call completed by dispatch\n");
02426 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02427 dbus_pending_call_unref (pending);
02428 return;
02429 }
02430
02431 if (status == DBUS_DISPATCH_DATA_REMAINS)
02432 {
02433 if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02434 return;
02435 }
02436
02437 _dbus_get_current_time (&tv_sec, &tv_usec);
02438 elapsed_milliseconds = (tv_sec - start_tv_sec) * 1000 +
02439 (tv_usec - start_tv_usec) / 1000;
02440
02441 if (!_dbus_connection_get_is_connected_unlocked (connection))
02442 {
02443 DBusMessage *error_msg;
02444
02445 error_msg = generate_local_error_message (client_serial,
02446 DBUS_ERROR_DISCONNECTED,
02447 "Connection was disconnected before a reply was received");
02448
02449
02450 complete_pending_call_and_unlock (connection, pending, error_msg);
02451 dbus_pending_call_unref (pending);
02452 return;
02453 }
02454 else if (connection->disconnect_message_link == NULL)
02455 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
02456 else if (timeout == NULL)
02457 {
02458 if (status == DBUS_DISPATCH_NEED_MEMORY)
02459 {
02460
02461
02462
02463
02464 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02465
02466 _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
02467 }
02468 else
02469 {
02470
02471 _dbus_connection_do_iteration_unlocked (connection,
02472 pending,
02473 DBUS_ITERATION_DO_READING |
02474 DBUS_ITERATION_BLOCK,
02475 timeout_milliseconds - elapsed_milliseconds);
02476 }
02477
02478 goto recheck_status;
02479 }
02480 else if (tv_sec < start_tv_sec)
02481 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
02482 else if (elapsed_milliseconds < timeout_milliseconds)
02483 {
02484 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds - elapsed_milliseconds);
02485
02486 if (status == DBUS_DISPATCH_NEED_MEMORY)
02487 {
02488
02489
02490
02491
02492 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02493
02494 _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
02495 }
02496 else
02497 {
02498
02499 _dbus_connection_do_iteration_unlocked (connection,
02500 NULL,
02501 DBUS_ITERATION_DO_READING |
02502 DBUS_ITERATION_BLOCK,
02503 timeout_milliseconds - elapsed_milliseconds);
02504 }
02505
02506 goto recheck_status;
02507 }
02508
02509 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %d milliseconds and got no reply\n",
02510 elapsed_milliseconds);
02511
02512 _dbus_assert (!_dbus_pending_call_get_completed_unlocked (pending));
02513
02514
02515 complete_pending_call_and_unlock (connection, pending, NULL);
02516
02517
02518 CONNECTION_LOCK (connection);
02519 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02520 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02521 dbus_pending_call_unref (pending);
02522 }
02523
02560 DBusConnection*
02561 dbus_connection_open (const char *address,
02562 DBusError *error)
02563 {
02564 DBusConnection *connection;
02565
02566 _dbus_return_val_if_fail (address != NULL, NULL);
02567 _dbus_return_val_if_error_is_set (error, NULL);
02568
02569 connection = _dbus_connection_open_internal (address,
02570 TRUE,
02571 error);
02572
02573 return connection;
02574 }
02575
02603 DBusConnection*
02604 dbus_connection_open_private (const char *address,
02605 DBusError *error)
02606 {
02607 DBusConnection *connection;
02608
02609 _dbus_return_val_if_fail (address != NULL, NULL);
02610 _dbus_return_val_if_error_is_set (error, NULL);
02611
02612 connection = _dbus_connection_open_internal (address,
02613 FALSE,
02614 error);
02615
02616 return connection;
02617 }
02618
02625 DBusConnection *
02626 dbus_connection_ref (DBusConnection *connection)
02627 {
02628 _dbus_return_val_if_fail (connection != NULL, NULL);
02629 _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
02630
02631 _dbus_atomic_inc (&connection->refcount);
02632
02633 return connection;
02634 }
02635
02636 static void
02637 free_outgoing_message (void *element,
02638 void *data)
02639 {
02640 DBusMessage *message = element;
02641 DBusConnection *connection = data;
02642
02643 _dbus_message_remove_counter (message,
02644 connection->outgoing_counter,
02645 NULL);
02646 dbus_message_unref (message);
02647 }
02648
02649
02650
02651
02652
02653 static void
02654 _dbus_connection_last_unref (DBusConnection *connection)
02655 {
02656 DBusList *link;
02657
02658 _dbus_verbose ("Finalizing connection %p\n", connection);
02659
02660 _dbus_assert (_dbus_atomic_get (&connection->refcount) == 0);
02661
02662
02663
02664
02665 _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
02666 _dbus_assert (connection->server_guid == NULL);
02667
02668
02669 _dbus_object_tree_free_all_unlocked (connection->objects);
02670
02671 dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
02672 dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
02673 dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
02674
02675 _dbus_watch_list_free (connection->watches);
02676 connection->watches = NULL;
02677
02678 _dbus_timeout_list_free (connection->timeouts);
02679 connection->timeouts = NULL;
02680
02681 _dbus_data_slot_list_free (&connection->slot_list);
02682
02683 link = _dbus_list_get_first_link (&connection->filter_list);
02684 while (link != NULL)
02685 {
02686 DBusMessageFilter *filter = link->data;
02687 DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
02688
02689 filter->function = NULL;
02690 _dbus_message_filter_unref (filter);
02691 link->data = NULL;
02692
02693 link = next;
02694 }
02695 _dbus_list_clear (&connection->filter_list);
02696
02697
02698
02699 _dbus_object_tree_unref (connection->objects);
02700
02701 _dbus_hash_table_unref (connection->pending_replies);
02702 connection->pending_replies = NULL;
02703
02704 _dbus_list_clear (&connection->filter_list);
02705
02706 _dbus_list_foreach (&connection->outgoing_messages,
02707 free_outgoing_message,
02708 connection);
02709 _dbus_list_clear (&connection->outgoing_messages);
02710
02711 _dbus_list_foreach (&connection->incoming_messages,
02712 (DBusForeachFunction) dbus_message_unref,
02713 NULL);
02714 _dbus_list_clear (&connection->incoming_messages);
02715
02716 _dbus_counter_unref (connection->outgoing_counter);
02717
02718 _dbus_transport_unref (connection->transport);
02719
02720 if (connection->disconnect_message_link)
02721 {
02722 DBusMessage *message = connection->disconnect_message_link->data;
02723 dbus_message_unref (message);
02724 _dbus_list_free_link (connection->disconnect_message_link);
02725 }
02726
02727 _dbus_list_clear (&connection->link_cache);
02728
02729 _dbus_condvar_free_at_location (&connection->dispatch_cond);
02730 _dbus_condvar_free_at_location (&connection->io_path_cond);
02731
02732 _dbus_mutex_free_at_location (&connection->io_path_mutex);
02733 _dbus_mutex_free_at_location (&connection->dispatch_mutex);
02734
02735 _dbus_mutex_free_at_location (&connection->slot_mutex);
02736
02737 _dbus_mutex_free_at_location (&connection->mutex);
02738
02739 dbus_free (connection);
02740 }
02741
02761 void
02762 dbus_connection_unref (DBusConnection *connection)
02763 {
02764 dbus_bool_t last_unref;
02765
02766 _dbus_return_if_fail (connection != NULL);
02767 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02768
02769 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
02770
02771 if (last_unref)
02772 {
02773 #ifndef DBUS_DISABLE_CHECKS
02774 if (_dbus_transport_get_is_connected (connection->transport))
02775 {
02776 _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",
02777 connection->shareable ?
02778 "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" :
02779 "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n");
02780 return;
02781 }
02782 #endif
02783 _dbus_connection_last_unref (connection);
02784 }
02785 }
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795
02796 static void
02797 _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection)
02798 {
02799 DBusDispatchStatus status;
02800
02801 HAVE_LOCK_CHECK (connection);
02802
02803 _dbus_verbose ("Disconnecting %p\n", connection);
02804
02805
02806
02807
02808
02809 _dbus_connection_ref_unlocked (connection);
02810
02811 _dbus_transport_disconnect (connection->transport);
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02823
02824
02825 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02826
02827
02828 dbus_connection_unref (connection);
02829 }
02830
02873 void
02874 dbus_connection_close (DBusConnection *connection)
02875 {
02876 _dbus_return_if_fail (connection != NULL);
02877 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02878
02879 CONNECTION_LOCK (connection);
02880
02881 #ifndef DBUS_DISABLE_CHECKS
02882 if (connection->shareable)
02883 {
02884 CONNECTION_UNLOCK (connection);
02885
02886 _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n");
02887 return;
02888 }
02889 #endif
02890
02891 _dbus_connection_close_possibly_shared_and_unlock (connection);
02892 }
02893
02894 static dbus_bool_t
02895 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
02896 {
02897 HAVE_LOCK_CHECK (connection);
02898 return _dbus_transport_get_is_connected (connection->transport);
02899 }
02900
02914 dbus_bool_t
02915 dbus_connection_get_is_connected (DBusConnection *connection)
02916 {
02917 dbus_bool_t res;
02918
02919 _dbus_return_val_if_fail (connection != NULL, FALSE);
02920
02921 CONNECTION_LOCK (connection);
02922 res = _dbus_connection_get_is_connected_unlocked (connection);
02923 CONNECTION_UNLOCK (connection);
02924
02925 return res;
02926 }
02927
02936 dbus_bool_t
02937 dbus_connection_get_is_authenticated (DBusConnection *connection)
02938 {
02939 dbus_bool_t res;
02940
02941 _dbus_return_val_if_fail (connection != NULL, FALSE);
02942
02943 CONNECTION_LOCK (connection);
02944 res = _dbus_transport_get_is_authenticated (connection->transport);
02945 CONNECTION_UNLOCK (connection);
02946
02947 return res;
02948 }
02949
02970 dbus_bool_t
02971 dbus_connection_get_is_anonymous (DBusConnection *connection)
02972 {
02973 dbus_bool_t res;
02974
02975 _dbus_return_val_if_fail (connection != NULL, FALSE);
02976
02977 CONNECTION_LOCK (connection);
02978 res = _dbus_transport_get_is_anonymous (connection->transport);
02979 CONNECTION_UNLOCK (connection);
02980
02981 return res;
02982 }
02983
03015 char*
03016 dbus_connection_get_server_id (DBusConnection *connection)
03017 {
03018 char *id;
03019
03020 _dbus_return_val_if_fail (connection != NULL, NULL);
03021
03022 CONNECTION_LOCK (connection);
03023 id = _dbus_strdup (_dbus_transport_get_server_id (connection->transport));
03024 CONNECTION_UNLOCK (connection);
03025
03026 return id;
03027 }
03028
03046 dbus_bool_t
03047 dbus_connection_can_send_type(DBusConnection *connection,
03048 int type)
03049 {
03050 _dbus_return_val_if_fail (connection != NULL, FALSE);
03051
03052 if (!_dbus_type_is_valid(type))
03053 return FALSE;
03054
03055 if (type != DBUS_TYPE_UNIX_FD)
03056 return TRUE;
03057
03058 #ifdef HAVE_UNIX_FD_PASSING
03059 {
03060 dbus_bool_t b;
03061
03062 CONNECTION_LOCK(connection);
03063 b = _dbus_transport_can_pass_unix_fd(connection->transport);
03064 CONNECTION_UNLOCK(connection);
03065
03066 return b;
03067 }
03068 #endif
03069
03070 return FALSE;
03071 }
03072
03086 void
03087 dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
03088 dbus_bool_t exit_on_disconnect)
03089 {
03090 _dbus_return_if_fail (connection != NULL);
03091
03092 CONNECTION_LOCK (connection);
03093 connection->exit_on_disconnect = exit_on_disconnect != FALSE;
03094 CONNECTION_UNLOCK (connection);
03095 }
03096
03106 DBusPreallocatedSend*
03107 dbus_connection_preallocate_send (DBusConnection *connection)
03108 {
03109 DBusPreallocatedSend *preallocated;
03110
03111 _dbus_return_val_if_fail (connection != NULL, NULL);
03112
03113 CONNECTION_LOCK (connection);
03114
03115 preallocated =
03116 _dbus_connection_preallocate_send_unlocked (connection);
03117
03118 CONNECTION_UNLOCK (connection);
03119
03120 return preallocated;
03121 }
03122
03132 void
03133 dbus_connection_free_preallocated_send (DBusConnection *connection,
03134 DBusPreallocatedSend *preallocated)
03135 {
03136 _dbus_return_if_fail (connection != NULL);
03137 _dbus_return_if_fail (preallocated != NULL);
03138 _dbus_return_if_fail (connection == preallocated->connection);
03139
03140 _dbus_list_free_link (preallocated->queue_link);
03141 _dbus_counter_unref (preallocated->counter_link->data);
03142 _dbus_list_free_link (preallocated->counter_link);
03143 dbus_free (preallocated);
03144 }
03145
03158 void
03159 dbus_connection_send_preallocated (DBusConnection *connection,
03160 DBusPreallocatedSend *preallocated,
03161 DBusMessage *message,
03162 dbus_uint32_t *client_serial)
03163 {
03164 _dbus_return_if_fail (connection != NULL);
03165 _dbus_return_if_fail (preallocated != NULL);
03166 _dbus_return_if_fail (message != NULL);
03167 _dbus_return_if_fail (preallocated->connection == connection);
03168 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
03169 dbus_message_get_member (message) != NULL);
03170 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
03171 (dbus_message_get_interface (message) != NULL &&
03172 dbus_message_get_member (message) != NULL));
03173
03174 CONNECTION_LOCK (connection);
03175
03176 #ifdef HAVE_UNIX_FD_PASSING
03177
03178 if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03179 message->n_unix_fds > 0)
03180 {
03181
03182
03183
03184 CONNECTION_UNLOCK (connection);
03185 return;
03186 }
03187
03188 #endif
03189
03190 _dbus_connection_send_preallocated_and_unlock (connection,
03191 preallocated,
03192 message, client_serial);
03193 }
03194
03195 static dbus_bool_t
03196 _dbus_connection_send_unlocked_no_update (DBusConnection *connection,
03197 DBusMessage *message,
03198 dbus_uint32_t *client_serial)
03199 {
03200 DBusPreallocatedSend *preallocated;
03201
03202 _dbus_assert (connection != NULL);
03203 _dbus_assert (message != NULL);
03204
03205 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
03206 if (preallocated == NULL)
03207 return FALSE;
03208
03209 _dbus_connection_send_preallocated_unlocked_no_update (connection,
03210 preallocated,
03211 message,
03212 client_serial);
03213 return TRUE;
03214 }
03215
03243 dbus_bool_t
03244 dbus_connection_send (DBusConnection *connection,
03245 DBusMessage *message,
03246 dbus_uint32_t *serial)
03247 {
03248 _dbus_return_val_if_fail (connection != NULL, FALSE);
03249 _dbus_return_val_if_fail (message != NULL, FALSE);
03250
03251 CONNECTION_LOCK (connection);
03252
03253 #ifdef HAVE_UNIX_FD_PASSING
03254
03255 if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03256 message->n_unix_fds > 0)
03257 {
03258
03259
03260
03261 CONNECTION_UNLOCK (connection);
03262 return FALSE;
03263 }
03264
03265 #endif
03266
03267 return _dbus_connection_send_and_unlock (connection,
03268 message,
03269 serial);
03270 }
03271
03272 static dbus_bool_t
03273 reply_handler_timeout (void *data)
03274 {
03275 DBusConnection *connection;
03276 DBusDispatchStatus status;
03277 DBusPendingCall *pending = data;
03278
03279 connection = _dbus_pending_call_get_connection_and_lock (pending);
03280
03281 _dbus_pending_call_queue_timeout_error_unlocked (pending,
03282 connection);
03283 _dbus_connection_remove_timeout_unlocked (connection,
03284 _dbus_pending_call_get_timeout_unlocked (pending));
03285 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
03286
03287 _dbus_verbose ("middle\n");
03288 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03289
03290
03291 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03292
03293 return TRUE;
03294 }
03295
03338 dbus_bool_t
03339 dbus_connection_send_with_reply (DBusConnection *connection,
03340 DBusMessage *message,
03341 DBusPendingCall **pending_return,
03342 int timeout_milliseconds)
03343 {
03344 DBusPendingCall *pending;
03345 dbus_int32_t serial = -1;
03346 DBusDispatchStatus status;
03347
03348 _dbus_return_val_if_fail (connection != NULL, FALSE);
03349 _dbus_return_val_if_fail (message != NULL, FALSE);
03350 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03351
03352 if (pending_return)
03353 *pending_return = NULL;
03354
03355 CONNECTION_LOCK (connection);
03356
03357 #ifdef HAVE_UNIX_FD_PASSING
03358
03359 if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03360 message->n_unix_fds > 0)
03361 {
03362
03363
03364
03365
03366 CONNECTION_UNLOCK (connection);
03367 return TRUE;
03368 }
03369
03370 #endif
03371
03372 if (!_dbus_connection_get_is_connected_unlocked (connection))
03373 {
03374 CONNECTION_UNLOCK (connection);
03375
03376 return TRUE;
03377 }
03378
03379 pending = _dbus_pending_call_new_unlocked (connection,
03380 timeout_milliseconds,
03381 reply_handler_timeout);
03382
03383 if (pending == NULL)
03384 {
03385 CONNECTION_UNLOCK (connection);
03386 return FALSE;
03387 }
03388
03389
03390 serial = dbus_message_get_serial (message);
03391 if (serial == 0)
03392 {
03393 serial = _dbus_connection_get_next_client_serial (connection);
03394 dbus_message_set_serial (message, serial);
03395 }
03396
03397 if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
03398 goto error;
03399
03400
03401
03402
03403
03404 if (!_dbus_connection_attach_pending_call_unlocked (connection,
03405 pending))
03406 goto error;
03407
03408 if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
03409 {
03410 _dbus_connection_detach_pending_call_and_unlock (connection,
03411 pending);
03412 goto error_unlocked;
03413 }
03414
03415 if (pending_return)
03416 *pending_return = pending;
03417 else
03418 {
03419 _dbus_connection_detach_pending_call_unlocked (connection, pending);
03420
03421
03422
03423 }
03424
03425 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03426
03427
03428 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03429
03430 if (pending_return == NULL)
03431 dbus_pending_call_unref (pending);
03432
03433 return TRUE;
03434
03435 error:
03436 CONNECTION_UNLOCK (connection);
03437 error_unlocked:
03438 dbus_pending_call_unref (pending);
03439 return FALSE;
03440 }
03441
03474 DBusMessage*
03475 dbus_connection_send_with_reply_and_block (DBusConnection *connection,
03476 DBusMessage *message,
03477 int timeout_milliseconds,
03478 DBusError *error)
03479 {
03480 DBusMessage *reply;
03481 DBusPendingCall *pending;
03482
03483 _dbus_return_val_if_fail (connection != NULL, NULL);
03484 _dbus_return_val_if_fail (message != NULL, NULL);
03485 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL);
03486 _dbus_return_val_if_error_is_set (error, NULL);
03487
03488 #ifdef HAVE_UNIX_FD_PASSING
03489
03490 CONNECTION_LOCK (connection);
03491 if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03492 message->n_unix_fds > 0)
03493 {
03494 CONNECTION_UNLOCK (connection);
03495 dbus_set_error(error, DBUS_ERROR_FAILED, "Cannot send file descriptors on this connection.");
03496 return NULL;
03497 }
03498 CONNECTION_UNLOCK (connection);
03499
03500 #endif
03501
03502 if (!dbus_connection_send_with_reply (connection, message,
03503 &pending, timeout_milliseconds))
03504 {
03505 _DBUS_SET_OOM (error);
03506 return NULL;
03507 }
03508
03509 if (pending == NULL)
03510 {
03511 dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Connection is closed");
03512 return NULL;
03513 }
03514
03515 dbus_pending_call_block (pending);
03516
03517 reply = dbus_pending_call_steal_reply (pending);
03518 dbus_pending_call_unref (pending);
03519
03520
03521
03522
03523 _dbus_assert (reply != NULL);
03524
03525 if (dbus_set_error_from_message (error, reply))
03526 {
03527 dbus_message_unref (reply);
03528 return NULL;
03529 }
03530 else
03531 return reply;
03532 }
03533
03542 static DBusDispatchStatus
03543 _dbus_connection_flush_unlocked (DBusConnection *connection)
03544 {
03545
03546
03547
03548
03549
03550 DBusDispatchStatus status;
03551
03552 HAVE_LOCK_CHECK (connection);
03553
03554 while (connection->n_outgoing > 0 &&
03555 _dbus_connection_get_is_connected_unlocked (connection))
03556 {
03557 _dbus_verbose ("doing iteration in\n");
03558 HAVE_LOCK_CHECK (connection);
03559 _dbus_connection_do_iteration_unlocked (connection,
03560 NULL,
03561 DBUS_ITERATION_DO_READING |
03562 DBUS_ITERATION_DO_WRITING |
03563 DBUS_ITERATION_BLOCK,
03564 -1);
03565 }
03566
03567 HAVE_LOCK_CHECK (connection);
03568 _dbus_verbose ("middle\n");
03569 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03570
03571 HAVE_LOCK_CHECK (connection);
03572 return status;
03573 }
03574
03580 void
03581 dbus_connection_flush (DBusConnection *connection)
03582 {
03583
03584
03585
03586
03587
03588 DBusDispatchStatus status;
03589
03590 _dbus_return_if_fail (connection != NULL);
03591
03592 CONNECTION_LOCK (connection);
03593
03594 status = _dbus_connection_flush_unlocked (connection);
03595
03596 HAVE_LOCK_CHECK (connection);
03597
03598 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03599
03600 _dbus_verbose ("end\n");
03601 }
03602
03613 static dbus_bool_t
03614 _dbus_connection_read_write_dispatch (DBusConnection *connection,
03615 int timeout_milliseconds,
03616 dbus_bool_t dispatch)
03617 {
03618 DBusDispatchStatus dstatus;
03619 dbus_bool_t progress_possible;
03620
03621
03622
03623
03624
03625 dbus_connection_ref (connection);
03626 dstatus = dbus_connection_get_dispatch_status (connection);
03627
03628 if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
03629 {
03630 _dbus_verbose ("doing dispatch\n");
03631 dbus_connection_dispatch (connection);
03632 CONNECTION_LOCK (connection);
03633 }
03634 else if (dstatus == DBUS_DISPATCH_NEED_MEMORY)
03635 {
03636 _dbus_verbose ("pausing for memory\n");
03637 _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
03638 CONNECTION_LOCK (connection);
03639 }
03640 else
03641 {
03642 CONNECTION_LOCK (connection);
03643 if (_dbus_connection_get_is_connected_unlocked (connection))
03644 {
03645 _dbus_verbose ("doing iteration\n");
03646 _dbus_connection_do_iteration_unlocked (connection,
03647 NULL,
03648 DBUS_ITERATION_DO_READING |
03649 DBUS_ITERATION_DO_WRITING |
03650 DBUS_ITERATION_BLOCK,
03651 timeout_milliseconds);
03652 }
03653 }
03654
03655 HAVE_LOCK_CHECK (connection);
03656
03657
03658
03659
03660 if (dispatch)
03661 progress_possible = connection->n_incoming != 0 ||
03662 connection->disconnect_message_link != NULL;
03663 else
03664 progress_possible = _dbus_connection_get_is_connected_unlocked (connection);
03665
03666 CONNECTION_UNLOCK (connection);
03667
03668 dbus_connection_unref (connection);
03669
03670 return progress_possible;
03671 }
03672
03673
03708 dbus_bool_t
03709 dbus_connection_read_write_dispatch (DBusConnection *connection,
03710 int timeout_milliseconds)
03711 {
03712 _dbus_return_val_if_fail (connection != NULL, FALSE);
03713 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03714 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE);
03715 }
03716
03740 dbus_bool_t
03741 dbus_connection_read_write (DBusConnection *connection,
03742 int timeout_milliseconds)
03743 {
03744 _dbus_return_val_if_fail (connection != NULL, FALSE);
03745 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03746 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE);
03747 }
03748
03749
03750
03751
03752
03753
03754 static void
03755 check_disconnected_message_arrived_unlocked (DBusConnection *connection,
03756 DBusMessage *head_of_queue)
03757 {
03758 HAVE_LOCK_CHECK (connection);
03759
03760
03761 if (connection->disconnect_message_link == NULL &&
03762 dbus_message_is_signal (head_of_queue,
03763 DBUS_INTERFACE_LOCAL,
03764 "Disconnected"))
03765 {
03766 connection->disconnected_message_arrived = TRUE;
03767 }
03768 }
03769
03789 DBusMessage*
03790 dbus_connection_borrow_message (DBusConnection *connection)
03791 {
03792 DBusDispatchStatus status;
03793 DBusMessage *message;
03794
03795 _dbus_return_val_if_fail (connection != NULL, NULL);
03796
03797 _dbus_verbose ("start\n");
03798
03799
03800
03801
03802 status = dbus_connection_get_dispatch_status (connection);
03803 if (status != DBUS_DISPATCH_DATA_REMAINS)
03804 return NULL;
03805
03806 CONNECTION_LOCK (connection);
03807
03808 _dbus_connection_acquire_dispatch (connection);
03809
03810
03811 _dbus_assert (connection->message_borrowed == NULL);
03812
03813 connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
03814
03815 message = connection->message_borrowed;
03816
03817 check_disconnected_message_arrived_unlocked (connection, message);
03818
03819
03820 if (message == NULL)
03821 _dbus_connection_release_dispatch (connection);
03822
03823 CONNECTION_UNLOCK (connection);
03824
03825
03826
03827 return message;
03828 }
03829
03838 void
03839 dbus_connection_return_message (DBusConnection *connection,
03840 DBusMessage *message)
03841 {
03842 DBusDispatchStatus status;
03843
03844 _dbus_return_if_fail (connection != NULL);
03845 _dbus_return_if_fail (message != NULL);
03846 _dbus_return_if_fail (message == connection->message_borrowed);
03847 _dbus_return_if_fail (connection->dispatch_acquired);
03848
03849 CONNECTION_LOCK (connection);
03850
03851 _dbus_assert (message == connection->message_borrowed);
03852
03853 connection->message_borrowed = NULL;
03854
03855 _dbus_connection_release_dispatch (connection);
03856
03857 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03858 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03859 }
03860
03870 void
03871 dbus_connection_steal_borrowed_message (DBusConnection *connection,
03872 DBusMessage *message)
03873 {
03874 DBusMessage *pop_message;
03875 DBusDispatchStatus status;
03876
03877 _dbus_return_if_fail (connection != NULL);
03878 _dbus_return_if_fail (message != NULL);
03879 _dbus_return_if_fail (message == connection->message_borrowed);
03880 _dbus_return_if_fail (connection->dispatch_acquired);
03881
03882 CONNECTION_LOCK (connection);
03883
03884 _dbus_assert (message == connection->message_borrowed);
03885
03886 pop_message = _dbus_list_pop_first (&connection->incoming_messages);
03887 _dbus_assert (message == pop_message);
03888
03889 connection->n_incoming -= 1;
03890
03891 _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
03892 message, connection->n_incoming);
03893
03894 connection->message_borrowed = NULL;
03895
03896 _dbus_connection_release_dispatch (connection);
03897
03898 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03899 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03900 }
03901
03902
03903
03904
03905 static DBusList*
03906 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
03907 {
03908 HAVE_LOCK_CHECK (connection);
03909
03910 _dbus_assert (connection->message_borrowed == NULL);
03911
03912 if (connection->n_incoming > 0)
03913 {
03914 DBusList *link;
03915
03916 link = _dbus_list_pop_first_link (&connection->incoming_messages);
03917 connection->n_incoming -= 1;
03918
03919 _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from incoming queue %p, %d incoming\n",
03920 link->data,
03921 dbus_message_type_to_string (dbus_message_get_type (link->data)),
03922 dbus_message_get_path (link->data) ?
03923 dbus_message_get_path (link->data) :
03924 "no path",
03925 dbus_message_get_interface (link->data) ?
03926 dbus_message_get_interface (link->data) :
03927 "no interface",
03928 dbus_message_get_member (link->data) ?
03929 dbus_message_get_member (link->data) :
03930 "no member",
03931 dbus_message_get_signature (link->data),
03932 connection, connection->n_incoming);
03933
03934 check_disconnected_message_arrived_unlocked (connection, link->data);
03935
03936 return link;
03937 }
03938 else
03939 return NULL;
03940 }
03941
03942
03943
03944
03945 static DBusMessage*
03946 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
03947 {
03948 DBusList *link;
03949
03950 HAVE_LOCK_CHECK (connection);
03951
03952 link = _dbus_connection_pop_message_link_unlocked (connection);
03953
03954 if (link != NULL)
03955 {
03956 DBusMessage *message;
03957
03958 message = link->data;
03959
03960 _dbus_list_free_link (link);
03961
03962 return message;
03963 }
03964 else
03965 return NULL;
03966 }
03967
03968 static void
03969 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
03970 DBusList *message_link)
03971 {
03972 HAVE_LOCK_CHECK (connection);
03973
03974 _dbus_assert (message_link != NULL);
03975
03976 _dbus_assert (connection->message_borrowed == NULL);
03977
03978 _dbus_assert (connection->dispatch_acquired);
03979
03980 _dbus_list_prepend_link (&connection->incoming_messages,
03981 message_link);
03982 connection->n_incoming += 1;
03983
03984 _dbus_verbose ("Message %p (%s %s %s '%s') put back into queue %p, %d incoming\n",
03985 message_link->data,
03986 dbus_message_type_to_string (dbus_message_get_type (message_link->data)),
03987 dbus_message_get_interface (message_link->data) ?
03988 dbus_message_get_interface (message_link->data) :
03989 "no interface",
03990 dbus_message_get_member (message_link->data) ?
03991 dbus_message_get_member (message_link->data) :
03992 "no member",
03993 dbus_message_get_signature (message_link->data),
03994 connection, connection->n_incoming);
03995 }
03996
04016 DBusMessage*
04017 dbus_connection_pop_message (DBusConnection *connection)
04018 {
04019 DBusMessage *message;
04020 DBusDispatchStatus status;
04021
04022 _dbus_verbose ("start\n");
04023
04024
04025
04026
04027 status = dbus_connection_get_dispatch_status (connection);
04028 if (status != DBUS_DISPATCH_DATA_REMAINS)
04029 return NULL;
04030
04031 CONNECTION_LOCK (connection);
04032 _dbus_connection_acquire_dispatch (connection);
04033 HAVE_LOCK_CHECK (connection);
04034
04035 message = _dbus_connection_pop_message_unlocked (connection);
04036
04037 _dbus_verbose ("Returning popped message %p\n", message);
04038
04039 _dbus_connection_release_dispatch (connection);
04040
04041 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04042 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04043
04044 return message;
04045 }
04046
04054 static void
04055 _dbus_connection_acquire_dispatch (DBusConnection *connection)
04056 {
04057 HAVE_LOCK_CHECK (connection);
04058
04059 _dbus_connection_ref_unlocked (connection);
04060 CONNECTION_UNLOCK (connection);
04061
04062 _dbus_verbose ("locking dispatch_mutex\n");
04063 _dbus_mutex_lock (connection->dispatch_mutex);
04064
04065 while (connection->dispatch_acquired)
04066 {
04067 _dbus_verbose ("waiting for dispatch to be acquirable\n");
04068 _dbus_condvar_wait (connection->dispatch_cond,
04069 connection->dispatch_mutex);
04070 }
04071
04072 _dbus_assert (!connection->dispatch_acquired);
04073
04074 connection->dispatch_acquired = TRUE;
04075
04076 _dbus_verbose ("unlocking dispatch_mutex\n");
04077 _dbus_mutex_unlock (connection->dispatch_mutex);
04078
04079 CONNECTION_LOCK (connection);
04080 _dbus_connection_unref_unlocked (connection);
04081 }
04082
04090 static void
04091 _dbus_connection_release_dispatch (DBusConnection *connection)
04092 {
04093 HAVE_LOCK_CHECK (connection);
04094
04095 _dbus_verbose ("locking dispatch_mutex\n");
04096 _dbus_mutex_lock (connection->dispatch_mutex);
04097
04098 _dbus_assert (connection->dispatch_acquired);
04099
04100 connection->dispatch_acquired = FALSE;
04101 _dbus_condvar_wake_one (connection->dispatch_cond);
04102
04103 _dbus_verbose ("unlocking dispatch_mutex\n");
04104 _dbus_mutex_unlock (connection->dispatch_mutex);
04105 }
04106
04107 static void
04108 _dbus_connection_failed_pop (DBusConnection *connection,
04109 DBusList *message_link)
04110 {
04111 _dbus_list_prepend_link (&connection->incoming_messages,
04112 message_link);
04113 connection->n_incoming += 1;
04114 }
04115
04116
04117 static void
04118 notify_disconnected_unlocked (DBusConnection *connection)
04119 {
04120 HAVE_LOCK_CHECK (connection);
04121
04122
04123
04124
04125
04126
04127
04128 _dbus_bus_notify_shared_connection_disconnected_unlocked (connection);
04129
04130
04131
04132
04133
04134 if (connection->n_outgoing > 0)
04135 {
04136 DBusList *link;
04137
04138 _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
04139 connection->n_outgoing);
04140
04141 while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
04142 {
04143 _dbus_connection_message_sent (connection, link->data);
04144 }
04145 }
04146 }
04147
04148
04149 static DBusDispatchStatus
04150 notify_disconnected_and_dispatch_complete_unlocked (DBusConnection *connection)
04151 {
04152 HAVE_LOCK_CHECK (connection);
04153
04154 if (connection->disconnect_message_link != NULL)
04155 {
04156 _dbus_verbose ("Sending disconnect message\n");
04157
04158
04159
04160
04161 connection_timeout_and_complete_all_pending_calls_unlocked (connection);
04162
04163
04164
04165
04166 _dbus_connection_queue_synthesized_message_link (connection,
04167 connection->disconnect_message_link);
04168 connection->disconnect_message_link = NULL;
04169
04170 return DBUS_DISPATCH_DATA_REMAINS;
04171 }
04172
04173 return DBUS_DISPATCH_COMPLETE;
04174 }
04175
04176 static DBusDispatchStatus
04177 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
04178 {
04179 HAVE_LOCK_CHECK (connection);
04180
04181 if (connection->n_incoming > 0)
04182 return DBUS_DISPATCH_DATA_REMAINS;
04183 else if (!_dbus_transport_queue_messages (connection->transport))
04184 return DBUS_DISPATCH_NEED_MEMORY;
04185 else
04186 {
04187 DBusDispatchStatus status;
04188 dbus_bool_t is_connected;
04189
04190 status = _dbus_transport_get_dispatch_status (connection->transport);
04191 is_connected = _dbus_transport_get_is_connected (connection->transport);
04192
04193 _dbus_verbose ("dispatch status = %s is_connected = %d\n",
04194 DISPATCH_STATUS_NAME (status), is_connected);
04195
04196 if (!is_connected)
04197 {
04198
04199
04200
04201
04202
04203
04204 notify_disconnected_unlocked (connection);
04205
04206
04207
04208
04209
04210
04211 if (status == DBUS_DISPATCH_COMPLETE)
04212 status = notify_disconnected_and_dispatch_complete_unlocked (connection);
04213 }
04214
04215 if (status != DBUS_DISPATCH_COMPLETE)
04216 return status;
04217 else if (connection->n_incoming > 0)
04218 return DBUS_DISPATCH_DATA_REMAINS;
04219 else
04220 return DBUS_DISPATCH_COMPLETE;
04221 }
04222 }
04223
04224 static void
04225 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
04226 DBusDispatchStatus new_status)
04227 {
04228 dbus_bool_t changed;
04229 DBusDispatchStatusFunction function;
04230 void *data;
04231
04232 HAVE_LOCK_CHECK (connection);
04233
04234 _dbus_connection_ref_unlocked (connection);
04235
04236 changed = new_status != connection->last_dispatch_status;
04237
04238 connection->last_dispatch_status = new_status;
04239
04240 function = connection->dispatch_status_function;
04241 data = connection->dispatch_status_data;
04242
04243 if (connection->disconnected_message_arrived &&
04244 !connection->disconnected_message_processed)
04245 {
04246 connection->disconnected_message_processed = TRUE;
04247
04248
04249
04250
04251
04252 connection_forget_shared_unlocked (connection);
04253
04254 if (connection->exit_on_disconnect)
04255 {
04256 CONNECTION_UNLOCK (connection);
04257
04258 _dbus_verbose ("Exiting on Disconnected signal\n");
04259 _dbus_exit (1);
04260 _dbus_assert_not_reached ("Call to exit() returned");
04261 }
04262 }
04263
04264
04265 CONNECTION_UNLOCK (connection);
04266
04267 if (changed && function)
04268 {
04269 _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
04270 connection, new_status,
04271 DISPATCH_STATUS_NAME (new_status));
04272 (* function) (connection, new_status, data);
04273 }
04274
04275 dbus_connection_unref (connection);
04276 }
04277
04303 DBusDispatchStatus
04304 dbus_connection_get_dispatch_status (DBusConnection *connection)
04305 {
04306 DBusDispatchStatus status;
04307
04308 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04309
04310 _dbus_verbose ("start\n");
04311
04312 CONNECTION_LOCK (connection);
04313
04314 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04315
04316 CONNECTION_UNLOCK (connection);
04317
04318 return status;
04319 }
04320
04324 static DBusHandlerResult
04325 _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
04326 DBusMessage *message)
04327 {
04328 if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
04329 {
04330
04331 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04332 }
04333 else if (dbus_message_is_method_call (message,
04334 DBUS_INTERFACE_PEER,
04335 "Ping"))
04336 {
04337 DBusMessage *ret;
04338 dbus_bool_t sent;
04339
04340 ret = dbus_message_new_method_return (message);
04341 if (ret == NULL)
04342 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04343
04344 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04345
04346 dbus_message_unref (ret);
04347
04348 if (!sent)
04349 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04350
04351 return DBUS_HANDLER_RESULT_HANDLED;
04352 }
04353 else if (dbus_message_is_method_call (message,
04354 DBUS_INTERFACE_PEER,
04355 "GetMachineId"))
04356 {
04357 DBusMessage *ret;
04358 dbus_bool_t sent;
04359 DBusString uuid;
04360
04361 ret = dbus_message_new_method_return (message);
04362 if (ret == NULL)
04363 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04364
04365 sent = FALSE;
04366 _dbus_string_init (&uuid);
04367 if (_dbus_get_local_machine_uuid_encoded (&uuid))
04368 {
04369 const char *v_STRING = _dbus_string_get_const_data (&uuid);
04370 if (dbus_message_append_args (ret,
04371 DBUS_TYPE_STRING, &v_STRING,
04372 DBUS_TYPE_INVALID))
04373 {
04374 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04375 }
04376 }
04377 _dbus_string_free (&uuid);
04378
04379 dbus_message_unref (ret);
04380
04381 if (!sent)
04382 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04383
04384 return DBUS_HANDLER_RESULT_HANDLED;
04385 }
04386 else if (dbus_message_has_interface (message, DBUS_INTERFACE_PEER))
04387 {
04388
04389
04390
04391
04392
04393 DBusMessage *ret;
04394 dbus_bool_t sent;
04395
04396 ret = dbus_message_new_error (message,
04397 DBUS_ERROR_UNKNOWN_METHOD,
04398 "Unknown method invoked on org.freedesktop.DBus.Peer interface");
04399 if (ret == NULL)
04400 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04401
04402 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04403
04404 dbus_message_unref (ret);
04405
04406 if (!sent)
04407 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04408
04409 return DBUS_HANDLER_RESULT_HANDLED;
04410 }
04411 else
04412 {
04413 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04414 }
04415 }
04416
04423 static DBusHandlerResult
04424 _dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection,
04425 DBusMessage *message)
04426 {
04427
04428
04429
04430 return _dbus_connection_peer_filter_unlocked_no_update (connection, message);
04431 }
04432
04475 DBusDispatchStatus
04476 dbus_connection_dispatch (DBusConnection *connection)
04477 {
04478 DBusMessage *message;
04479 DBusList *link, *filter_list_copy, *message_link;
04480 DBusHandlerResult result;
04481 DBusPendingCall *pending;
04482 dbus_int32_t reply_serial;
04483 DBusDispatchStatus status;
04484
04485 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04486
04487 _dbus_verbose ("\n");
04488
04489 CONNECTION_LOCK (connection);
04490 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04491 if (status != DBUS_DISPATCH_DATA_REMAINS)
04492 {
04493
04494 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04495 return status;
04496 }
04497
04498
04499
04500
04501 _dbus_connection_ref_unlocked (connection);
04502
04503 _dbus_connection_acquire_dispatch (connection);
04504 HAVE_LOCK_CHECK (connection);
04505
04506 message_link = _dbus_connection_pop_message_link_unlocked (connection);
04507 if (message_link == NULL)
04508 {
04509
04510
04511 _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
04512
04513 _dbus_connection_release_dispatch (connection);
04514
04515 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04516
04517 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04518
04519 dbus_connection_unref (connection);
04520
04521 return status;
04522 }
04523
04524 message = message_link->data;
04525
04526 _dbus_verbose (" dispatching message %p (%s %s %s '%s')\n",
04527 message,
04528 dbus_message_type_to_string (dbus_message_get_type (message)),
04529 dbus_message_get_interface (message) ?
04530 dbus_message_get_interface (message) :
04531 "no interface",
04532 dbus_message_get_member (message) ?
04533 dbus_message_get_member (message) :
04534 "no member",
04535 dbus_message_get_signature (message));
04536
04537 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04538
04539
04540
04541
04542
04543
04544
04545
04546 reply_serial = dbus_message_get_reply_serial (message);
04547 pending = _dbus_hash_table_lookup_int (connection->pending_replies,
04548 reply_serial);
04549 if (pending)
04550 {
04551 _dbus_verbose ("Dispatching a pending reply\n");
04552 complete_pending_call_and_unlock (connection, pending, message);
04553 pending = NULL;
04554
04555 CONNECTION_LOCK (connection);
04556 _dbus_verbose ("pending call completed in dispatch\n");
04557 result = DBUS_HANDLER_RESULT_HANDLED;
04558 goto out;
04559 }
04560
04561 result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message);
04562 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04563 goto out;
04564
04565 if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
04566 {
04567 _dbus_connection_release_dispatch (connection);
04568 HAVE_LOCK_CHECK (connection);
04569
04570 _dbus_connection_failed_pop (connection, message_link);
04571
04572
04573 _dbus_connection_update_dispatch_status_and_unlock (connection,
04574 DBUS_DISPATCH_NEED_MEMORY);
04575 dbus_connection_unref (connection);
04576
04577 return DBUS_DISPATCH_NEED_MEMORY;
04578 }
04579
04580 _dbus_list_foreach (&filter_list_copy,
04581 (DBusForeachFunction)_dbus_message_filter_ref,
04582 NULL);
04583
04584
04585
04586
04587 CONNECTION_UNLOCK (connection);
04588
04589 link = _dbus_list_get_first_link (&filter_list_copy);
04590 while (link != NULL)
04591 {
04592 DBusMessageFilter *filter = link->data;
04593 DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
04594
04595 if (filter->function == NULL)
04596 {
04597 _dbus_verbose (" filter was removed in a callback function\n");
04598 link = next;
04599 continue;
04600 }
04601
04602 _dbus_verbose (" running filter on message %p\n", message);
04603 result = (* filter->function) (connection, message, filter->user_data);
04604
04605 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04606 break;
04607
04608 link = next;
04609 }
04610
04611 _dbus_list_foreach (&filter_list_copy,
04612 (DBusForeachFunction)_dbus_message_filter_unref,
04613 NULL);
04614 _dbus_list_clear (&filter_list_copy);
04615
04616 CONNECTION_LOCK (connection);
04617
04618 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04619 {
04620 _dbus_verbose ("No memory\n");
04621 goto out;
04622 }
04623 else if (result == DBUS_HANDLER_RESULT_HANDLED)
04624 {
04625 _dbus_verbose ("filter handled message in dispatch\n");
04626 goto out;
04627 }
04628
04629
04630
04631
04632 _dbus_verbose (" running object path dispatch on message %p (%s %s %s '%s')\n",
04633 message,
04634 dbus_message_type_to_string (dbus_message_get_type (message)),
04635 dbus_message_get_interface (message) ?
04636 dbus_message_get_interface (message) :
04637 "no interface",
04638 dbus_message_get_member (message) ?
04639 dbus_message_get_member (message) :
04640 "no member",
04641 dbus_message_get_signature (message));
04642
04643 HAVE_LOCK_CHECK (connection);
04644 result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
04645 message);
04646
04647 CONNECTION_LOCK (connection);
04648
04649 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04650 {
04651 _dbus_verbose ("object tree handled message in dispatch\n");
04652 goto out;
04653 }
04654
04655 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
04656 {
04657 DBusMessage *reply;
04658 DBusString str;
04659 DBusPreallocatedSend *preallocated;
04660
04661 _dbus_verbose (" sending error %s\n",
04662 DBUS_ERROR_UNKNOWN_METHOD);
04663
04664 if (!_dbus_string_init (&str))
04665 {
04666 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04667 _dbus_verbose ("no memory for error string in dispatch\n");
04668 goto out;
04669 }
04670
04671 if (!_dbus_string_append_printf (&str,
04672 "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
04673 dbus_message_get_member (message),
04674 dbus_message_get_signature (message),
04675 dbus_message_get_interface (message)))
04676 {
04677 _dbus_string_free (&str);
04678 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04679 _dbus_verbose ("no memory for error string in dispatch\n");
04680 goto out;
04681 }
04682
04683 reply = dbus_message_new_error (message,
04684 DBUS_ERROR_UNKNOWN_METHOD,
04685 _dbus_string_get_const_data (&str));
04686 _dbus_string_free (&str);
04687
04688 if (reply == NULL)
04689 {
04690 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04691 _dbus_verbose ("no memory for error reply in dispatch\n");
04692 goto out;
04693 }
04694
04695 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
04696
04697 if (preallocated == NULL)
04698 {
04699 dbus_message_unref (reply);
04700 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04701 _dbus_verbose ("no memory for error send in dispatch\n");
04702 goto out;
04703 }
04704
04705 _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
04706 reply, NULL);
04707
04708 dbus_message_unref (reply);
04709
04710 result = DBUS_HANDLER_RESULT_HANDLED;
04711 }
04712
04713 _dbus_verbose (" done dispatching %p (%s %s %s '%s') on connection %p\n", message,
04714 dbus_message_type_to_string (dbus_message_get_type (message)),
04715 dbus_message_get_interface (message) ?
04716 dbus_message_get_interface (message) :
04717 "no interface",
04718 dbus_message_get_member (message) ?
04719 dbus_message_get_member (message) :
04720 "no member",
04721 dbus_message_get_signature (message),
04722 connection);
04723
04724 out:
04725 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04726 {
04727 _dbus_verbose ("out of memory\n");
04728
04729
04730
04731
04732
04733 _dbus_connection_putback_message_link_unlocked (connection,
04734 message_link);
04735 }
04736 else
04737 {
04738 _dbus_verbose (" ... done dispatching\n");
04739
04740 _dbus_list_free_link (message_link);
04741 dbus_message_unref (message);
04742
04743
04744 }
04745
04746 _dbus_connection_release_dispatch (connection);
04747 HAVE_LOCK_CHECK (connection);
04748
04749 _dbus_verbose ("before final status update\n");
04750 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04751
04752
04753 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04754
04755 dbus_connection_unref (connection);
04756
04757 return status;
04758 }
04759
04821 dbus_bool_t
04822 dbus_connection_set_watch_functions (DBusConnection *connection,
04823 DBusAddWatchFunction add_function,
04824 DBusRemoveWatchFunction remove_function,
04825 DBusWatchToggledFunction toggled_function,
04826 void *data,
04827 DBusFreeFunction free_data_function)
04828 {
04829 dbus_bool_t retval;
04830
04831 _dbus_return_val_if_fail (connection != NULL, FALSE);
04832
04833 CONNECTION_LOCK (connection);
04834
04835 retval = _dbus_watch_list_set_functions (connection->watches,
04836 add_function, remove_function,
04837 toggled_function,
04838 data, free_data_function);
04839
04840 CONNECTION_UNLOCK (connection);
04841
04842 return retval;
04843 }
04844
04884 dbus_bool_t
04885 dbus_connection_set_timeout_functions (DBusConnection *connection,
04886 DBusAddTimeoutFunction add_function,
04887 DBusRemoveTimeoutFunction remove_function,
04888 DBusTimeoutToggledFunction toggled_function,
04889 void *data,
04890 DBusFreeFunction free_data_function)
04891 {
04892 dbus_bool_t retval;
04893
04894 _dbus_return_val_if_fail (connection != NULL, FALSE);
04895
04896 CONNECTION_LOCK (connection);
04897
04898 retval = _dbus_timeout_list_set_functions (connection->timeouts,
04899 add_function, remove_function,
04900 toggled_function,
04901 data, free_data_function);
04902
04903 CONNECTION_UNLOCK (connection);
04904
04905 return retval;
04906 }
04907
04922 void
04923 dbus_connection_set_wakeup_main_function (DBusConnection *connection,
04924 DBusWakeupMainFunction wakeup_main_function,
04925 void *data,
04926 DBusFreeFunction free_data_function)
04927 {
04928 void *old_data;
04929 DBusFreeFunction old_free_data;
04930
04931 _dbus_return_if_fail (connection != NULL);
04932
04933 CONNECTION_LOCK (connection);
04934 old_data = connection->wakeup_main_data;
04935 old_free_data = connection->free_wakeup_main_data;
04936
04937 connection->wakeup_main_function = wakeup_main_function;
04938 connection->wakeup_main_data = data;
04939 connection->free_wakeup_main_data = free_data_function;
04940
04941 CONNECTION_UNLOCK (connection);
04942
04943
04944 if (old_free_data)
04945 (*old_free_data) (old_data);
04946 }
04947
04968 void
04969 dbus_connection_set_dispatch_status_function (DBusConnection *connection,
04970 DBusDispatchStatusFunction function,
04971 void *data,
04972 DBusFreeFunction free_data_function)
04973 {
04974 void *old_data;
04975 DBusFreeFunction old_free_data;
04976
04977 _dbus_return_if_fail (connection != NULL);
04978
04979 CONNECTION_LOCK (connection);
04980 old_data = connection->dispatch_status_data;
04981 old_free_data = connection->free_dispatch_status_data;
04982
04983 connection->dispatch_status_function = function;
04984 connection->dispatch_status_data = data;
04985 connection->free_dispatch_status_data = free_data_function;
04986
04987 CONNECTION_UNLOCK (connection);
04988
04989
04990 if (old_free_data)
04991 (*old_free_data) (old_data);
04992 }
04993
05013 dbus_bool_t
05014 dbus_connection_get_unix_fd (DBusConnection *connection,
05015 int *fd)
05016 {
05017 _dbus_return_val_if_fail (connection != NULL, FALSE);
05018 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
05019
05020 #ifdef DBUS_WIN
05021
05022 return FALSE;
05023 #endif
05024
05025 return dbus_connection_get_socket(connection, fd);
05026 }
05027
05043 dbus_bool_t
05044 dbus_connection_get_socket(DBusConnection *connection,
05045 int *fd)
05046 {
05047 dbus_bool_t retval;
05048
05049 _dbus_return_val_if_fail (connection != NULL, FALSE);
05050 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
05051
05052 CONNECTION_LOCK (connection);
05053
05054 retval = _dbus_transport_get_socket_fd (connection->transport,
05055 fd);
05056
05057 CONNECTION_UNLOCK (connection);
05058
05059 return retval;
05060 }
05061
05062
05085 dbus_bool_t
05086 dbus_connection_get_unix_user (DBusConnection *connection,
05087 unsigned long *uid)
05088 {
05089 dbus_bool_t result;
05090
05091 _dbus_return_val_if_fail (connection != NULL, FALSE);
05092 _dbus_return_val_if_fail (uid != NULL, FALSE);
05093
05094 CONNECTION_LOCK (connection);
05095
05096 if (!_dbus_transport_get_is_authenticated (connection->transport))
05097 result = FALSE;
05098 else
05099 result = _dbus_transport_get_unix_user (connection->transport,
05100 uid);
05101
05102 #ifdef DBUS_WIN
05103 _dbus_assert (!result);
05104 #endif
05105
05106 CONNECTION_UNLOCK (connection);
05107
05108 return result;
05109 }
05110
05121 dbus_bool_t
05122 dbus_connection_get_unix_process_id (DBusConnection *connection,
05123 unsigned long *pid)
05124 {
05125 dbus_bool_t result;
05126
05127 _dbus_return_val_if_fail (connection != NULL, FALSE);
05128 _dbus_return_val_if_fail (pid != NULL, FALSE);
05129
05130 CONNECTION_LOCK (connection);
05131
05132 if (!_dbus_transport_get_is_authenticated (connection->transport))
05133 result = FALSE;
05134 else
05135 result = _dbus_transport_get_unix_process_id (connection->transport,
05136 pid);
05137
05138 CONNECTION_UNLOCK (connection);
05139
05140 return result;
05141 }
05142
05153 dbus_bool_t
05154 dbus_connection_get_adt_audit_session_data (DBusConnection *connection,
05155 void **data,
05156 dbus_int32_t *data_size)
05157 {
05158 dbus_bool_t result;
05159
05160 _dbus_return_val_if_fail (connection != NULL, FALSE);
05161 _dbus_return_val_if_fail (data != NULL, FALSE);
05162 _dbus_return_val_if_fail (data_size != NULL, FALSE);
05163
05164 CONNECTION_LOCK (connection);
05165
05166 if (!_dbus_transport_get_is_authenticated (connection->transport))
05167 result = FALSE;
05168 else
05169 result = _dbus_transport_get_adt_audit_session_data (connection->transport,
05170 data,
05171 data_size);
05172 CONNECTION_UNLOCK (connection);
05173
05174 return result;
05175 }
05176
05199 void
05200 dbus_connection_set_unix_user_function (DBusConnection *connection,
05201 DBusAllowUnixUserFunction function,
05202 void *data,
05203 DBusFreeFunction free_data_function)
05204 {
05205 void *old_data = NULL;
05206 DBusFreeFunction old_free_function = NULL;
05207
05208 _dbus_return_if_fail (connection != NULL);
05209
05210 CONNECTION_LOCK (connection);
05211 _dbus_transport_set_unix_user_function (connection->transport,
05212 function, data, free_data_function,
05213 &old_data, &old_free_function);
05214 CONNECTION_UNLOCK (connection);
05215
05216 if (old_free_function != NULL)
05217 (* old_free_function) (old_data);
05218 }
05219
05251 dbus_bool_t
05252 dbus_connection_get_windows_user (DBusConnection *connection,
05253 char **windows_sid_p)
05254 {
05255 dbus_bool_t result;
05256
05257 _dbus_return_val_if_fail (connection != NULL, FALSE);
05258 _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
05259
05260 CONNECTION_LOCK (connection);
05261
05262 if (!_dbus_transport_get_is_authenticated (connection->transport))
05263 result = FALSE;
05264 else
05265 result = _dbus_transport_get_windows_user (connection->transport,
05266 windows_sid_p);
05267
05268 #ifdef DBUS_UNIX
05269 _dbus_assert (!result);
05270 #endif
05271
05272 CONNECTION_UNLOCK (connection);
05273
05274 return result;
05275 }
05276
05298 void
05299 dbus_connection_set_windows_user_function (DBusConnection *connection,
05300 DBusAllowWindowsUserFunction function,
05301 void *data,
05302 DBusFreeFunction free_data_function)
05303 {
05304 void *old_data = NULL;
05305 DBusFreeFunction old_free_function = NULL;
05306
05307 _dbus_return_if_fail (connection != NULL);
05308
05309 CONNECTION_LOCK (connection);
05310 _dbus_transport_set_windows_user_function (connection->transport,
05311 function, data, free_data_function,
05312 &old_data, &old_free_function);
05313 CONNECTION_UNLOCK (connection);
05314
05315 if (old_free_function != NULL)
05316 (* old_free_function) (old_data);
05317 }
05318
05345 void
05346 dbus_connection_set_allow_anonymous (DBusConnection *connection,
05347 dbus_bool_t value)
05348 {
05349 _dbus_return_if_fail (connection != NULL);
05350
05351 CONNECTION_LOCK (connection);
05352 _dbus_transport_set_allow_anonymous (connection->transport, value);
05353 CONNECTION_UNLOCK (connection);
05354 }
05355
05373 void
05374 dbus_connection_set_route_peer_messages (DBusConnection *connection,
05375 dbus_bool_t value)
05376 {
05377 _dbus_return_if_fail (connection != NULL);
05378
05379 CONNECTION_LOCK (connection);
05380 connection->route_peer_messages = TRUE;
05381 CONNECTION_UNLOCK (connection);
05382 }
05383
05405 dbus_bool_t
05406 dbus_connection_add_filter (DBusConnection *connection,
05407 DBusHandleMessageFunction function,
05408 void *user_data,
05409 DBusFreeFunction free_data_function)
05410 {
05411 DBusMessageFilter *filter;
05412
05413 _dbus_return_val_if_fail (connection != NULL, FALSE);
05414 _dbus_return_val_if_fail (function != NULL, FALSE);
05415
05416 filter = dbus_new0 (DBusMessageFilter, 1);
05417 if (filter == NULL)
05418 return FALSE;
05419
05420 _dbus_atomic_inc (&filter->refcount);
05421
05422 CONNECTION_LOCK (connection);
05423
05424 if (!_dbus_list_append (&connection->filter_list,
05425 filter))
05426 {
05427 _dbus_message_filter_unref (filter);
05428 CONNECTION_UNLOCK (connection);
05429 return FALSE;
05430 }
05431
05432
05433
05434
05435
05436
05437 filter->function = function;
05438 filter->user_data = user_data;
05439 filter->free_user_data_function = free_data_function;
05440
05441 CONNECTION_UNLOCK (connection);
05442 return TRUE;
05443 }
05444
05457 void
05458 dbus_connection_remove_filter (DBusConnection *connection,
05459 DBusHandleMessageFunction function,
05460 void *user_data)
05461 {
05462 DBusList *link;
05463 DBusMessageFilter *filter;
05464
05465 _dbus_return_if_fail (connection != NULL);
05466 _dbus_return_if_fail (function != NULL);
05467
05468 CONNECTION_LOCK (connection);
05469
05470 filter = NULL;
05471
05472 link = _dbus_list_get_last_link (&connection->filter_list);
05473 while (link != NULL)
05474 {
05475 filter = link->data;
05476
05477 if (filter->function == function &&
05478 filter->user_data == user_data)
05479 {
05480 _dbus_list_remove_link (&connection->filter_list, link);
05481 filter->function = NULL;
05482
05483 break;
05484 }
05485
05486 link = _dbus_list_get_prev_link (&connection->filter_list, link);
05487 filter = NULL;
05488 }
05489
05490 CONNECTION_UNLOCK (connection);
05491
05492 #ifndef DBUS_DISABLE_CHECKS
05493 if (filter == NULL)
05494 {
05495 _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
05496 function, user_data);
05497 return;
05498 }
05499 #endif
05500
05501
05502 if (filter->free_user_data_function)
05503 (* filter->free_user_data_function) (filter->user_data);
05504
05505 filter->free_user_data_function = NULL;
05506 filter->user_data = NULL;
05507
05508 _dbus_message_filter_unref (filter);
05509 }
05510
05523 dbus_bool_t
05524 dbus_connection_try_register_object_path (DBusConnection *connection,
05525 const char *path,
05526 const DBusObjectPathVTable *vtable,
05527 void *user_data,
05528 DBusError *error)
05529 {
05530 char **decomposed_path;
05531 dbus_bool_t retval;
05532
05533 _dbus_return_val_if_fail (connection != NULL, FALSE);
05534 _dbus_return_val_if_fail (path != NULL, FALSE);
05535 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05536 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05537
05538 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05539 return FALSE;
05540
05541 CONNECTION_LOCK (connection);
05542
05543 retval = _dbus_object_tree_register (connection->objects,
05544 FALSE,
05545 (const char **) decomposed_path, vtable,
05546 user_data, error);
05547
05548 CONNECTION_UNLOCK (connection);
05549
05550 dbus_free_string_array (decomposed_path);
05551
05552 return retval;
05553 }
05554
05570 dbus_bool_t
05571 dbus_connection_register_object_path (DBusConnection *connection,
05572 const char *path,
05573 const DBusObjectPathVTable *vtable,
05574 void *user_data)
05575 {
05576 char **decomposed_path;
05577 dbus_bool_t retval;
05578 DBusError error = DBUS_ERROR_INIT;
05579
05580 _dbus_return_val_if_fail (connection != NULL, FALSE);
05581 _dbus_return_val_if_fail (path != NULL, FALSE);
05582 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05583 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05584
05585 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05586 return FALSE;
05587
05588 CONNECTION_LOCK (connection);
05589
05590 retval = _dbus_object_tree_register (connection->objects,
05591 FALSE,
05592 (const char **) decomposed_path, vtable,
05593 user_data, &error);
05594
05595 CONNECTION_UNLOCK (connection);
05596
05597 dbus_free_string_array (decomposed_path);
05598
05599 if (dbus_error_has_name (&error, DBUS_ERROR_OBJECT_PATH_IN_USE))
05600 {
05601 _dbus_warn ("%s\n", error.message);
05602 dbus_error_free (&error);
05603 return FALSE;
05604 }
05605
05606 return retval;
05607 }
05608
05623 dbus_bool_t
05624 dbus_connection_try_register_fallback (DBusConnection *connection,
05625 const char *path,
05626 const DBusObjectPathVTable *vtable,
05627 void *user_data,
05628 DBusError *error)
05629 {
05630 char **decomposed_path;
05631 dbus_bool_t retval;
05632
05633 _dbus_return_val_if_fail (connection != NULL, FALSE);
05634 _dbus_return_val_if_fail (path != NULL, FALSE);
05635 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05636 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05637
05638 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05639 return FALSE;
05640
05641 CONNECTION_LOCK (connection);
05642
05643 retval = _dbus_object_tree_register (connection->objects,
05644 TRUE,
05645 (const char **) decomposed_path, vtable,
05646 user_data, error);
05647
05648 CONNECTION_UNLOCK (connection);
05649
05650 dbus_free_string_array (decomposed_path);
05651
05652 return retval;
05653 }
05654
05672 dbus_bool_t
05673 dbus_connection_register_fallback (DBusConnection *connection,
05674 const char *path,
05675 const DBusObjectPathVTable *vtable,
05676 void *user_data)
05677 {
05678 char **decomposed_path;
05679 dbus_bool_t retval;
05680 DBusError error = DBUS_ERROR_INIT;
05681
05682 _dbus_return_val_if_fail (connection != NULL, FALSE);
05683 _dbus_return_val_if_fail (path != NULL, FALSE);
05684 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05685 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05686
05687 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05688 return FALSE;
05689
05690 CONNECTION_LOCK (connection);
05691
05692 retval = _dbus_object_tree_register (connection->objects,
05693 TRUE,
05694 (const char **) decomposed_path, vtable,
05695 user_data, &error);
05696
05697 CONNECTION_UNLOCK (connection);
05698
05699 dbus_free_string_array (decomposed_path);
05700
05701 if (dbus_error_has_name (&error, DBUS_ERROR_OBJECT_PATH_IN_USE))
05702 {
05703 _dbus_warn ("%s\n", error.message);
05704 dbus_error_free (&error);
05705 return FALSE;
05706 }
05707
05708 return retval;
05709 }
05710
05720 dbus_bool_t
05721 dbus_connection_unregister_object_path (DBusConnection *connection,
05722 const char *path)
05723 {
05724 char **decomposed_path;
05725
05726 _dbus_return_val_if_fail (connection != NULL, FALSE);
05727 _dbus_return_val_if_fail (path != NULL, FALSE);
05728 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05729
05730 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05731 return FALSE;
05732
05733 CONNECTION_LOCK (connection);
05734
05735 _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
05736
05737 dbus_free_string_array (decomposed_path);
05738
05739 return TRUE;
05740 }
05741
05752 dbus_bool_t
05753 dbus_connection_get_object_path_data (DBusConnection *connection,
05754 const char *path,
05755 void **data_p)
05756 {
05757 char **decomposed_path;
05758
05759 _dbus_return_val_if_fail (connection != NULL, FALSE);
05760 _dbus_return_val_if_fail (path != NULL, FALSE);
05761 _dbus_return_val_if_fail (data_p != NULL, FALSE);
05762
05763 *data_p = NULL;
05764
05765 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05766 return FALSE;
05767
05768 CONNECTION_LOCK (connection);
05769
05770 *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path);
05771
05772 CONNECTION_UNLOCK (connection);
05773
05774 dbus_free_string_array (decomposed_path);
05775
05776 return TRUE;
05777 }
05778
05789 dbus_bool_t
05790 dbus_connection_list_registered (DBusConnection *connection,
05791 const char *parent_path,
05792 char ***child_entries)
05793 {
05794 char **decomposed_path;
05795 dbus_bool_t retval;
05796 _dbus_return_val_if_fail (connection != NULL, FALSE);
05797 _dbus_return_val_if_fail (parent_path != NULL, FALSE);
05798 _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
05799 _dbus_return_val_if_fail (child_entries != NULL, FALSE);
05800
05801 if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
05802 return FALSE;
05803
05804 CONNECTION_LOCK (connection);
05805
05806 retval = _dbus_object_tree_list_registered_and_unlock (connection->objects,
05807 (const char **) decomposed_path,
05808 child_entries);
05809 dbus_free_string_array (decomposed_path);
05810
05811 return retval;
05812 }
05813
05814 static DBusDataSlotAllocator slot_allocator;
05815 _DBUS_DEFINE_GLOBAL_LOCK (connection_slots);
05816
05831 dbus_bool_t
05832 dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
05833 {
05834 return _dbus_data_slot_allocator_alloc (&slot_allocator,
05835 &_DBUS_LOCK_NAME (connection_slots),
05836 slot_p);
05837 }
05838
05850 void
05851 dbus_connection_free_data_slot (dbus_int32_t *slot_p)
05852 {
05853 _dbus_return_if_fail (*slot_p >= 0);
05854
05855 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
05856 }
05857
05880 dbus_bool_t
05881 dbus_connection_set_data (DBusConnection *connection,
05882 dbus_int32_t slot,
05883 void *data,
05884 DBusFreeFunction free_data_func)
05885 {
05886 DBusFreeFunction old_free_func;
05887 void *old_data;
05888 dbus_bool_t retval;
05889
05890 _dbus_return_val_if_fail (connection != NULL, FALSE);
05891 _dbus_return_val_if_fail (slot >= 0, FALSE);
05892
05893 SLOTS_LOCK (connection);
05894
05895 retval = _dbus_data_slot_list_set (&slot_allocator,
05896 &connection->slot_list,
05897 slot, data, free_data_func,
05898 &old_free_func, &old_data);
05899
05900 SLOTS_UNLOCK (connection);
05901
05902 if (retval)
05903 {
05904
05905 if (old_free_func)
05906 (* old_free_func) (old_data);
05907 }
05908
05909 return retval;
05910 }
05911
05929 void*
05930 dbus_connection_get_data (DBusConnection *connection,
05931 dbus_int32_t slot)
05932 {
05933 void *res;
05934
05935 _dbus_return_val_if_fail (connection != NULL, NULL);
05936
05937 SLOTS_LOCK (connection);
05938
05939 res = _dbus_data_slot_list_get (&slot_allocator,
05940 &connection->slot_list,
05941 slot);
05942
05943 SLOTS_UNLOCK (connection);
05944
05945 return res;
05946 }
05947
05954 void
05955 dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
05956 {
05957 _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
05958 }
05959
05968 void
05969 dbus_connection_set_max_message_size (DBusConnection *connection,
05970 long size)
05971 {
05972 _dbus_return_if_fail (connection != NULL);
05973
05974 CONNECTION_LOCK (connection);
05975 _dbus_transport_set_max_message_size (connection->transport,
05976 size);
05977 CONNECTION_UNLOCK (connection);
05978 }
05979
05986 long
05987 dbus_connection_get_max_message_size (DBusConnection *connection)
05988 {
05989 long res;
05990
05991 _dbus_return_val_if_fail (connection != NULL, 0);
05992
05993 CONNECTION_LOCK (connection);
05994 res = _dbus_transport_get_max_message_size (connection->transport);
05995 CONNECTION_UNLOCK (connection);
05996 return res;
05997 }
05998
06007 void
06008 dbus_connection_set_max_message_unix_fds (DBusConnection *connection,
06009 long n)
06010 {
06011 _dbus_return_if_fail (connection != NULL);
06012
06013 CONNECTION_LOCK (connection);
06014 _dbus_transport_set_max_message_unix_fds (connection->transport,
06015 n);
06016 CONNECTION_UNLOCK (connection);
06017 }
06018
06025 long
06026 dbus_connection_get_max_message_unix_fds (DBusConnection *connection)
06027 {
06028 long res;
06029
06030 _dbus_return_val_if_fail (connection != NULL, 0);
06031
06032 CONNECTION_LOCK (connection);
06033 res = _dbus_transport_get_max_message_unix_fds (connection->transport);
06034 CONNECTION_UNLOCK (connection);
06035 return res;
06036 }
06037
06063 void
06064 dbus_connection_set_max_received_size (DBusConnection *connection,
06065 long size)
06066 {
06067 _dbus_return_if_fail (connection != NULL);
06068
06069 CONNECTION_LOCK (connection);
06070 _dbus_transport_set_max_received_size (connection->transport,
06071 size);
06072 CONNECTION_UNLOCK (connection);
06073 }
06074
06081 long
06082 dbus_connection_get_max_received_size (DBusConnection *connection)
06083 {
06084 long res;
06085
06086 _dbus_return_val_if_fail (connection != NULL, 0);
06087
06088 CONNECTION_LOCK (connection);
06089 res = _dbus_transport_get_max_received_size (connection->transport);
06090 CONNECTION_UNLOCK (connection);
06091 return res;
06092 }
06093
06105 void
06106 dbus_connection_set_max_received_unix_fds (DBusConnection *connection,
06107 long n)
06108 {
06109 _dbus_return_if_fail (connection != NULL);
06110
06111 CONNECTION_LOCK (connection);
06112 _dbus_transport_set_max_received_unix_fds (connection->transport,
06113 n);
06114 CONNECTION_UNLOCK (connection);
06115 }
06116
06123 long
06124 dbus_connection_get_max_received_unix_fds (DBusConnection *connection)
06125 {
06126 long res;
06127
06128 _dbus_return_val_if_fail (connection != NULL, 0);
06129
06130 CONNECTION_LOCK (connection);
06131 res = _dbus_transport_get_max_received_unix_fds (connection->transport);
06132 CONNECTION_UNLOCK (connection);
06133 return res;
06134 }
06135
06146 long
06147 dbus_connection_get_outgoing_size (DBusConnection *connection)
06148 {
06149 long res;
06150
06151 _dbus_return_val_if_fail (connection != NULL, 0);
06152
06153 CONNECTION_LOCK (connection);
06154 res = _dbus_counter_get_size_value (connection->outgoing_counter);
06155 CONNECTION_UNLOCK (connection);
06156 return res;
06157 }
06158
06166 long
06167 dbus_connection_get_outgoing_unix_fds (DBusConnection *connection)
06168 {
06169 long res;
06170
06171 _dbus_return_val_if_fail (connection != NULL, 0);
06172
06173 CONNECTION_LOCK (connection);
06174 res = _dbus_counter_get_unix_fd_value (connection->outgoing_counter);
06175 CONNECTION_UNLOCK (connection);
06176 return res;
06177 }
06178