00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config.h>
00025 #include "dbus-shared.h"
00026 #include "dbus-connection.h"
00027 #include "dbus-list.h"
00028 #include "dbus-timeout.h"
00029 #include "dbus-transport.h"
00030 #include "dbus-watch.h"
00031 #include "dbus-connection-internal.h"
00032 #include "dbus-pending-call-internal.h"
00033 #include "dbus-list.h"
00034 #include "dbus-hash.h"
00035 #include "dbus-message-internal.h"
00036 #include "dbus-threads.h"
00037 #include "dbus-protocol.h"
00038 #include "dbus-dataslot.h"
00039 #include "dbus-string.h"
00040 #include "dbus-pending-call.h"
00041 #include "dbus-object-tree.h"
00042 #include "dbus-threads-internal.h"
00043 #include "dbus-bus.h"
00044
00045 #ifdef DBUS_DISABLE_CHECKS
00046 #define TOOK_LOCK_CHECK(connection)
00047 #define RELEASING_LOCK_CHECK(connection)
00048 #define HAVE_LOCK_CHECK(connection)
00049 #else
00050 #define TOOK_LOCK_CHECK(connection) do { \
00051 _dbus_assert (!(connection)->have_connection_lock); \
00052 (connection)->have_connection_lock = TRUE; \
00053 } while (0)
00054 #define RELEASING_LOCK_CHECK(connection) do { \
00055 _dbus_assert ((connection)->have_connection_lock); \
00056 (connection)->have_connection_lock = FALSE; \
00057 } while (0)
00058 #define HAVE_LOCK_CHECK(connection) _dbus_assert ((connection)->have_connection_lock)
00059
00060 #endif
00061
00062 #define TRACE_LOCKS 1
00063
00064 #define CONNECTION_LOCK(connection) do { \
00065 if (TRACE_LOCKS) { _dbus_verbose (" LOCK: %s\n", _DBUS_FUNCTION_NAME); } \
00066 _dbus_mutex_lock ((connection)->mutex); \
00067 TOOK_LOCK_CHECK (connection); \
00068 } while (0)
00069
00070 #define CONNECTION_UNLOCK(connection) do { \
00071 if (TRACE_LOCKS) { _dbus_verbose (" UNLOCK: %s\n", _DBUS_FUNCTION_NAME); } \
00072 RELEASING_LOCK_CHECK (connection); \
00073 _dbus_mutex_unlock ((connection)->mutex); \
00074 } while (0)
00075
00076 #define DISPATCH_STATUS_NAME(s) \
00077 ((s) == DBUS_DISPATCH_COMPLETE ? "complete" : \
00078 (s) == DBUS_DISPATCH_DATA_REMAINS ? "data remains" : \
00079 (s) == DBUS_DISPATCH_NEED_MEMORY ? "need memory" : \
00080 "???")
00081
00202 typedef struct DBusMessageFilter DBusMessageFilter;
00203
00207 struct DBusMessageFilter
00208 {
00209 DBusAtomic refcount;
00210 DBusHandleMessageFunction function;
00211 void *user_data;
00212 DBusFreeFunction free_user_data_function;
00213 };
00214
00215
00219 struct DBusPreallocatedSend
00220 {
00221 DBusConnection *connection;
00222 DBusList *queue_link;
00223 DBusList *counter_link;
00224 };
00225
00226 static dbus_bool_t _dbus_modify_sigpipe = TRUE;
00227
00231 struct DBusConnection
00232 {
00233 DBusAtomic refcount;
00235 DBusMutex *mutex;
00237 DBusMutex *dispatch_mutex;
00238 DBusCondVar *dispatch_cond;
00239 DBusMutex *io_path_mutex;
00240 DBusCondVar *io_path_cond;
00242 DBusList *outgoing_messages;
00243 DBusList *incoming_messages;
00245 DBusMessage *message_borrowed;
00249 int n_outgoing;
00250 int n_incoming;
00252 DBusCounter *outgoing_counter;
00254 DBusTransport *transport;
00255 DBusWatchList *watches;
00256 DBusTimeoutList *timeouts;
00258 DBusList *filter_list;
00260 DBusDataSlotList slot_list;
00262 DBusHashTable *pending_replies;
00264 dbus_uint32_t client_serial;
00265 DBusList *disconnect_message_link;
00267 DBusWakeupMainFunction wakeup_main_function;
00268 void *wakeup_main_data;
00269 DBusFreeFunction free_wakeup_main_data;
00271 DBusDispatchStatusFunction dispatch_status_function;
00272 void *dispatch_status_data;
00273 DBusFreeFunction free_dispatch_status_data;
00275 DBusDispatchStatus last_dispatch_status;
00277 DBusList *link_cache;
00280 DBusObjectTree *objects;
00282 char *server_guid;
00284
00285
00286
00287
00288 dbus_bool_t dispatch_acquired;
00289 dbus_bool_t io_path_acquired;
00291 unsigned int shareable : 1;
00293 unsigned int exit_on_disconnect : 1;
00295 unsigned int route_peer_messages : 1;
00297 unsigned int disconnected_message_arrived : 1;
00301 unsigned int disconnected_message_processed : 1;
00305 #ifndef DBUS_DISABLE_CHECKS
00306 unsigned int have_connection_lock : 1;
00307 #endif
00308
00309 #ifndef DBUS_DISABLE_CHECKS
00310 int generation;
00311 #endif
00312 };
00313
00314 static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection);
00315 static void _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
00316 DBusDispatchStatus new_status);
00317 static void _dbus_connection_last_unref (DBusConnection *connection);
00318 static void _dbus_connection_acquire_dispatch (DBusConnection *connection);
00319 static void _dbus_connection_release_dispatch (DBusConnection *connection);
00320 static DBusDispatchStatus _dbus_connection_flush_unlocked (DBusConnection *connection);
00321 static void _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection);
00322 static dbus_bool_t _dbus_connection_get_is_connected_unlocked (DBusConnection *connection);
00323
00324 static DBusMessageFilter *
00325 _dbus_message_filter_ref (DBusMessageFilter *filter)
00326 {
00327 _dbus_assert (filter->refcount.value > 0);
00328 _dbus_atomic_inc (&filter->refcount);
00329
00330 return filter;
00331 }
00332
00333 static void
00334 _dbus_message_filter_unref (DBusMessageFilter *filter)
00335 {
00336 _dbus_assert (filter->refcount.value > 0);
00337
00338 if (_dbus_atomic_dec (&filter->refcount) == 1)
00339 {
00340 if (filter->free_user_data_function)
00341 (* filter->free_user_data_function) (filter->user_data);
00342
00343 dbus_free (filter);
00344 }
00345 }
00346
00352 void
00353 _dbus_connection_lock (DBusConnection *connection)
00354 {
00355 CONNECTION_LOCK (connection);
00356 }
00357
00363 void
00364 _dbus_connection_unlock (DBusConnection *connection)
00365 {
00366 CONNECTION_UNLOCK (connection);
00367 }
00368
00376 static void
00377 _dbus_connection_wakeup_mainloop (DBusConnection *connection)
00378 {
00379 if (connection->wakeup_main_function)
00380 (*connection->wakeup_main_function) (connection->wakeup_main_data);
00381 }
00382
00383 #ifdef DBUS_BUILD_TESTS
00384
00394 dbus_bool_t
00395 _dbus_connection_queue_received_message (DBusConnection *connection,
00396 DBusMessage *message)
00397 {
00398 DBusList *link;
00399
00400 link = _dbus_list_alloc_link (message);
00401 if (link == NULL)
00402 return FALSE;
00403
00404 dbus_message_ref (message);
00405 _dbus_connection_queue_received_message_link (connection, link);
00406
00407 return TRUE;
00408 }
00409
00422 void
00423 _dbus_connection_test_get_locks (DBusConnection *connection,
00424 DBusMutex **mutex_loc,
00425 DBusMutex **dispatch_mutex_loc,
00426 DBusMutex **io_path_mutex_loc,
00427 DBusCondVar **dispatch_cond_loc,
00428 DBusCondVar **io_path_cond_loc)
00429 {
00430 *mutex_loc = connection->mutex;
00431 *dispatch_mutex_loc = connection->dispatch_mutex;
00432 *io_path_mutex_loc = connection->io_path_mutex;
00433 *dispatch_cond_loc = connection->dispatch_cond;
00434 *io_path_cond_loc = connection->io_path_cond;
00435 }
00436 #endif
00437
00446 void
00447 _dbus_connection_queue_received_message_link (DBusConnection *connection,
00448 DBusList *link)
00449 {
00450 DBusPendingCall *pending;
00451 dbus_int32_t reply_serial;
00452 DBusMessage *message;
00453
00454 _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport));
00455
00456 _dbus_list_append_link (&connection->incoming_messages,
00457 link);
00458 message = link->data;
00459
00460
00461 reply_serial = dbus_message_get_reply_serial (message);
00462 if (reply_serial != -1)
00463 {
00464 pending = _dbus_hash_table_lookup_int (connection->pending_replies,
00465 reply_serial);
00466 if (pending != NULL)
00467 {
00468 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00469 _dbus_connection_remove_timeout_unlocked (connection,
00470 _dbus_pending_call_get_timeout_unlocked (pending));
00471
00472 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00473 }
00474 }
00475
00476
00477
00478 connection->n_incoming += 1;
00479
00480 _dbus_connection_wakeup_mainloop (connection);
00481
00482 _dbus_verbose ("Message %p (%d %s %s %s '%s' reply to %u) added to incoming queue %p, %d incoming\n",
00483 message,
00484 dbus_message_get_type (message),
00485 dbus_message_get_path (message) ?
00486 dbus_message_get_path (message) :
00487 "no path",
00488 dbus_message_get_interface (message) ?
00489 dbus_message_get_interface (message) :
00490 "no interface",
00491 dbus_message_get_member (message) ?
00492 dbus_message_get_member (message) :
00493 "no member",
00494 dbus_message_get_signature (message),
00495 dbus_message_get_reply_serial (message),
00496 connection,
00497 connection->n_incoming);}
00498
00507 void
00508 _dbus_connection_queue_synthesized_message_link (DBusConnection *connection,
00509 DBusList *link)
00510 {
00511 HAVE_LOCK_CHECK (connection);
00512
00513 _dbus_list_append_link (&connection->incoming_messages, link);
00514
00515 connection->n_incoming += 1;
00516
00517 _dbus_connection_wakeup_mainloop (connection);
00518
00519 _dbus_verbose ("Synthesized message %p added to incoming queue %p, %d incoming\n",
00520 link->data, connection, connection->n_incoming);
00521 }
00522
00523
00531 dbus_bool_t
00532 _dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection)
00533 {
00534 HAVE_LOCK_CHECK (connection);
00535 return connection->outgoing_messages != NULL;
00536 }
00537
00547 dbus_bool_t
00548 dbus_connection_has_messages_to_send (DBusConnection *connection)
00549 {
00550 dbus_bool_t v;
00551
00552 _dbus_return_val_if_fail (connection != NULL, FALSE);
00553
00554 CONNECTION_LOCK (connection);
00555 v = _dbus_connection_has_messages_to_send_unlocked (connection);
00556 CONNECTION_UNLOCK (connection);
00557
00558 return v;
00559 }
00560
00568 DBusMessage*
00569 _dbus_connection_get_message_to_send (DBusConnection *connection)
00570 {
00571 HAVE_LOCK_CHECK (connection);
00572
00573 return _dbus_list_get_last (&connection->outgoing_messages);
00574 }
00575
00584 void
00585 _dbus_connection_message_sent (DBusConnection *connection,
00586 DBusMessage *message)
00587 {
00588 DBusList *link;
00589
00590 HAVE_LOCK_CHECK (connection);
00591
00592
00593
00594
00595
00596
00597 link = _dbus_list_get_last_link (&connection->outgoing_messages);
00598 _dbus_assert (link != NULL);
00599 _dbus_assert (link->data == message);
00600
00601
00602 _dbus_list_unlink (&connection->outgoing_messages,
00603 link);
00604 _dbus_list_prepend_link (&connection->link_cache, link);
00605
00606 connection->n_outgoing -= 1;
00607
00608 _dbus_verbose ("Message %p (%d %s %s %s '%s') removed from outgoing queue %p, %d left to send\n",
00609 message,
00610 dbus_message_get_type (message),
00611 dbus_message_get_path (message) ?
00612 dbus_message_get_path (message) :
00613 "no path",
00614 dbus_message_get_interface (message) ?
00615 dbus_message_get_interface (message) :
00616 "no interface",
00617 dbus_message_get_member (message) ?
00618 dbus_message_get_member (message) :
00619 "no member",
00620 dbus_message_get_signature (message),
00621 connection, connection->n_outgoing);
00622
00623
00624 _dbus_message_remove_size_counter (message, connection->outgoing_counter,
00625 &link);
00626 _dbus_list_prepend_link (&connection->link_cache, link);
00627
00628 dbus_message_unref (message);
00629 }
00630
00632 typedef dbus_bool_t (* DBusWatchAddFunction) (DBusWatchList *list,
00633 DBusWatch *watch);
00635 typedef void (* DBusWatchRemoveFunction) (DBusWatchList *list,
00636 DBusWatch *watch);
00638 typedef void (* DBusWatchToggleFunction) (DBusWatchList *list,
00639 DBusWatch *watch,
00640 dbus_bool_t enabled);
00641
00642 static dbus_bool_t
00643 protected_change_watch (DBusConnection *connection,
00644 DBusWatch *watch,
00645 DBusWatchAddFunction add_function,
00646 DBusWatchRemoveFunction remove_function,
00647 DBusWatchToggleFunction toggle_function,
00648 dbus_bool_t enabled)
00649 {
00650 DBusWatchList *watches;
00651 dbus_bool_t retval;
00652
00653 HAVE_LOCK_CHECK (connection);
00654
00655
00656
00657
00658
00659 watches = connection->watches;
00660 if (watches)
00661 {
00662 connection->watches = NULL;
00663 _dbus_connection_ref_unlocked (connection);
00664 CONNECTION_UNLOCK (connection);
00665
00666 if (add_function)
00667 retval = (* add_function) (watches, watch);
00668 else if (remove_function)
00669 {
00670 retval = TRUE;
00671 (* remove_function) (watches, watch);
00672 }
00673 else
00674 {
00675 retval = TRUE;
00676 (* toggle_function) (watches, watch, enabled);
00677 }
00678
00679 CONNECTION_LOCK (connection);
00680 connection->watches = watches;
00681 _dbus_connection_unref_unlocked (connection);
00682
00683 return retval;
00684 }
00685 else
00686 return FALSE;
00687 }
00688
00689
00701 dbus_bool_t
00702 _dbus_connection_add_watch_unlocked (DBusConnection *connection,
00703 DBusWatch *watch)
00704 {
00705 return protected_change_watch (connection, watch,
00706 _dbus_watch_list_add_watch,
00707 NULL, NULL, FALSE);
00708 }
00709
00719 void
00720 _dbus_connection_remove_watch_unlocked (DBusConnection *connection,
00721 DBusWatch *watch)
00722 {
00723 protected_change_watch (connection, watch,
00724 NULL,
00725 _dbus_watch_list_remove_watch,
00726 NULL, FALSE);
00727 }
00728
00739 void
00740 _dbus_connection_toggle_watch_unlocked (DBusConnection *connection,
00741 DBusWatch *watch,
00742 dbus_bool_t enabled)
00743 {
00744 _dbus_assert (watch != NULL);
00745
00746 protected_change_watch (connection, watch,
00747 NULL, NULL,
00748 _dbus_watch_list_toggle_watch,
00749 enabled);
00750 }
00751
00753 typedef dbus_bool_t (* DBusTimeoutAddFunction) (DBusTimeoutList *list,
00754 DBusTimeout *timeout);
00756 typedef void (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list,
00757 DBusTimeout *timeout);
00759 typedef void (* DBusTimeoutToggleFunction) (DBusTimeoutList *list,
00760 DBusTimeout *timeout,
00761 dbus_bool_t enabled);
00762
00763 static dbus_bool_t
00764 protected_change_timeout (DBusConnection *connection,
00765 DBusTimeout *timeout,
00766 DBusTimeoutAddFunction add_function,
00767 DBusTimeoutRemoveFunction remove_function,
00768 DBusTimeoutToggleFunction toggle_function,
00769 dbus_bool_t enabled)
00770 {
00771 DBusTimeoutList *timeouts;
00772 dbus_bool_t retval;
00773
00774 HAVE_LOCK_CHECK (connection);
00775
00776
00777
00778
00779
00780 timeouts = connection->timeouts;
00781 if (timeouts)
00782 {
00783 connection->timeouts = NULL;
00784 _dbus_connection_ref_unlocked (connection);
00785 CONNECTION_UNLOCK (connection);
00786
00787 if (add_function)
00788 retval = (* add_function) (timeouts, timeout);
00789 else if (remove_function)
00790 {
00791 retval = TRUE;
00792 (* remove_function) (timeouts, timeout);
00793 }
00794 else
00795 {
00796 retval = TRUE;
00797 (* toggle_function) (timeouts, timeout, enabled);
00798 }
00799
00800 CONNECTION_LOCK (connection);
00801 connection->timeouts = timeouts;
00802 _dbus_connection_unref_unlocked (connection);
00803
00804 return retval;
00805 }
00806 else
00807 return FALSE;
00808 }
00809
00822 dbus_bool_t
00823 _dbus_connection_add_timeout_unlocked (DBusConnection *connection,
00824 DBusTimeout *timeout)
00825 {
00826 return protected_change_timeout (connection, timeout,
00827 _dbus_timeout_list_add_timeout,
00828 NULL, NULL, FALSE);
00829 }
00830
00840 void
00841 _dbus_connection_remove_timeout_unlocked (DBusConnection *connection,
00842 DBusTimeout *timeout)
00843 {
00844 protected_change_timeout (connection, timeout,
00845 NULL,
00846 _dbus_timeout_list_remove_timeout,
00847 NULL, FALSE);
00848 }
00849
00860 void
00861 _dbus_connection_toggle_timeout_unlocked (DBusConnection *connection,
00862 DBusTimeout *timeout,
00863 dbus_bool_t enabled)
00864 {
00865 protected_change_timeout (connection, timeout,
00866 NULL, NULL,
00867 _dbus_timeout_list_toggle_timeout,
00868 enabled);
00869 }
00870
00871 static dbus_bool_t
00872 _dbus_connection_attach_pending_call_unlocked (DBusConnection *connection,
00873 DBusPendingCall *pending)
00874 {
00875 dbus_uint32_t reply_serial;
00876 DBusTimeout *timeout;
00877
00878 HAVE_LOCK_CHECK (connection);
00879
00880 reply_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
00881
00882 _dbus_assert (reply_serial != 0);
00883
00884 timeout = _dbus_pending_call_get_timeout_unlocked (pending);
00885
00886 if (!_dbus_connection_add_timeout_unlocked (connection, timeout))
00887 return FALSE;
00888
00889 if (!_dbus_hash_table_insert_int (connection->pending_replies,
00890 reply_serial,
00891 pending))
00892 {
00893 _dbus_connection_remove_timeout_unlocked (connection, timeout);
00894
00895 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00896 HAVE_LOCK_CHECK (connection);
00897 return FALSE;
00898 }
00899
00900 _dbus_pending_call_set_timeout_added_unlocked (pending, TRUE);
00901
00902 _dbus_pending_call_ref_unlocked (pending);
00903
00904 HAVE_LOCK_CHECK (connection);
00905
00906 return TRUE;
00907 }
00908
00909 static void
00910 free_pending_call_on_hash_removal (void *data)
00911 {
00912 DBusPendingCall *pending;
00913 DBusConnection *connection;
00914
00915 if (data == NULL)
00916 return;
00917
00918 pending = data;
00919
00920 connection = _dbus_pending_call_get_connection_unlocked (pending);
00921
00922 HAVE_LOCK_CHECK (connection);
00923
00924 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00925 {
00926 _dbus_connection_remove_timeout_unlocked (connection,
00927 _dbus_pending_call_get_timeout_unlocked (pending));
00928
00929 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00930 }
00931
00932
00933
00934
00935
00936
00937 _dbus_connection_ref_unlocked (connection);
00938 _dbus_pending_call_unref_and_unlock (pending);
00939 CONNECTION_LOCK (connection);
00940 _dbus_connection_unref_unlocked (connection);
00941 }
00942
00943 static void
00944 _dbus_connection_detach_pending_call_unlocked (DBusConnection *connection,
00945 DBusPendingCall *pending)
00946 {
00947
00948
00949
00950 _dbus_hash_table_remove_int (connection->pending_replies,
00951 _dbus_pending_call_get_reply_serial_unlocked (pending));
00952 }
00953
00954 static void
00955 _dbus_connection_detach_pending_call_and_unlock (DBusConnection *connection,
00956 DBusPendingCall *pending)
00957 {
00958
00959
00960
00961
00962
00963
00964
00965 _dbus_pending_call_ref_unlocked (pending);
00966 _dbus_hash_table_remove_int (connection->pending_replies,
00967 _dbus_pending_call_get_reply_serial_unlocked (pending));
00968
00969 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00970 _dbus_connection_remove_timeout_unlocked (connection,
00971 _dbus_pending_call_get_timeout_unlocked (pending));
00972
00973 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00974
00975 _dbus_pending_call_unref_and_unlock (pending);
00976 }
00977
00986 void
00987 _dbus_connection_remove_pending_call (DBusConnection *connection,
00988 DBusPendingCall *pending)
00989 {
00990 CONNECTION_LOCK (connection);
00991 _dbus_connection_detach_pending_call_and_unlock (connection, pending);
00992 }
00993
01003 static dbus_bool_t
01004 _dbus_connection_acquire_io_path (DBusConnection *connection,
01005 int timeout_milliseconds)
01006 {
01007 dbus_bool_t we_acquired;
01008
01009 HAVE_LOCK_CHECK (connection);
01010
01011
01012 _dbus_connection_ref_unlocked (connection);
01013
01014
01015 CONNECTION_UNLOCK (connection);
01016
01017 _dbus_verbose ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME);
01018 _dbus_mutex_lock (connection->io_path_mutex);
01019
01020 _dbus_verbose ("%s start connection->io_path_acquired = %d timeout = %d\n",
01021 _DBUS_FUNCTION_NAME, connection->io_path_acquired, timeout_milliseconds);
01022
01023 we_acquired = FALSE;
01024
01025 if (connection->io_path_acquired)
01026 {
01027 if (timeout_milliseconds != -1)
01028 {
01029 _dbus_verbose ("%s waiting %d for IO path to be acquirable\n",
01030 _DBUS_FUNCTION_NAME, timeout_milliseconds);
01031
01032 if (!_dbus_condvar_wait_timeout (connection->io_path_cond,
01033 connection->io_path_mutex,
01034 timeout_milliseconds))
01035 {
01036
01037
01038
01039
01040
01041
01042
01043
01044 }
01045 }
01046 else
01047 {
01048 while (connection->io_path_acquired)
01049 {
01050 _dbus_verbose ("%s waiting for IO path to be acquirable\n", _DBUS_FUNCTION_NAME);
01051 _dbus_condvar_wait (connection->io_path_cond,
01052 connection->io_path_mutex);
01053 }
01054 }
01055 }
01056
01057 if (!connection->io_path_acquired)
01058 {
01059 we_acquired = TRUE;
01060 connection->io_path_acquired = TRUE;
01061 }
01062
01063 _dbus_verbose ("%s end connection->io_path_acquired = %d we_acquired = %d\n",
01064 _DBUS_FUNCTION_NAME, connection->io_path_acquired, we_acquired);
01065
01066 _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME);
01067 _dbus_mutex_unlock (connection->io_path_mutex);
01068
01069 CONNECTION_LOCK (connection);
01070
01071 HAVE_LOCK_CHECK (connection);
01072
01073 _dbus_connection_unref_unlocked (connection);
01074
01075 return we_acquired;
01076 }
01077
01085 static void
01086 _dbus_connection_release_io_path (DBusConnection *connection)
01087 {
01088 HAVE_LOCK_CHECK (connection);
01089
01090 _dbus_verbose ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME);
01091 _dbus_mutex_lock (connection->io_path_mutex);
01092
01093 _dbus_assert (connection->io_path_acquired);
01094
01095 _dbus_verbose ("%s start connection->io_path_acquired = %d\n",
01096 _DBUS_FUNCTION_NAME, connection->io_path_acquired);
01097
01098 connection->io_path_acquired = FALSE;
01099 _dbus_condvar_wake_one (connection->io_path_cond);
01100
01101 _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME);
01102 _dbus_mutex_unlock (connection->io_path_mutex);
01103 }
01104
01133 void
01134 _dbus_connection_do_iteration_unlocked (DBusConnection *connection,
01135 unsigned int flags,
01136 int timeout_milliseconds)
01137 {
01138 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
01139
01140 HAVE_LOCK_CHECK (connection);
01141
01142 if (connection->n_outgoing == 0)
01143 flags &= ~DBUS_ITERATION_DO_WRITING;
01144
01145 if (_dbus_connection_acquire_io_path (connection,
01146 (flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0))
01147 {
01148 HAVE_LOCK_CHECK (connection);
01149
01150 _dbus_transport_do_iteration (connection->transport,
01151 flags, timeout_milliseconds);
01152 _dbus_connection_release_io_path (connection);
01153 }
01154
01155 HAVE_LOCK_CHECK (connection);
01156
01157 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
01158 }
01159
01169 DBusConnection*
01170 _dbus_connection_new_for_transport (DBusTransport *transport)
01171 {
01172 DBusConnection *connection;
01173 DBusWatchList *watch_list;
01174 DBusTimeoutList *timeout_list;
01175 DBusHashTable *pending_replies;
01176 DBusList *disconnect_link;
01177 DBusMessage *disconnect_message;
01178 DBusCounter *outgoing_counter;
01179 DBusObjectTree *objects;
01180
01181 watch_list = NULL;
01182 connection = NULL;
01183 pending_replies = NULL;
01184 timeout_list = NULL;
01185 disconnect_link = NULL;
01186 disconnect_message = NULL;
01187 outgoing_counter = NULL;
01188 objects = NULL;
01189
01190 watch_list = _dbus_watch_list_new ();
01191 if (watch_list == NULL)
01192 goto error;
01193
01194 timeout_list = _dbus_timeout_list_new ();
01195 if (timeout_list == NULL)
01196 goto error;
01197
01198 pending_replies =
01199 _dbus_hash_table_new (DBUS_HASH_INT,
01200 NULL,
01201 (DBusFreeFunction)free_pending_call_on_hash_removal);
01202 if (pending_replies == NULL)
01203 goto error;
01204
01205 connection = dbus_new0 (DBusConnection, 1);
01206 if (connection == NULL)
01207 goto error;
01208
01209 _dbus_mutex_new_at_location (&connection->mutex);
01210 if (connection->mutex == NULL)
01211 goto error;
01212
01213 _dbus_mutex_new_at_location (&connection->io_path_mutex);
01214 if (connection->io_path_mutex == NULL)
01215 goto error;
01216
01217 _dbus_mutex_new_at_location (&connection->dispatch_mutex);
01218 if (connection->dispatch_mutex == NULL)
01219 goto error;
01220
01221 _dbus_condvar_new_at_location (&connection->dispatch_cond);
01222 if (connection->dispatch_cond == NULL)
01223 goto error;
01224
01225 _dbus_condvar_new_at_location (&connection->io_path_cond);
01226 if (connection->io_path_cond == NULL)
01227 goto error;
01228
01229 disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL,
01230 DBUS_INTERFACE_LOCAL,
01231 "Disconnected");
01232
01233 if (disconnect_message == NULL)
01234 goto error;
01235
01236 disconnect_link = _dbus_list_alloc_link (disconnect_message);
01237 if (disconnect_link == NULL)
01238 goto error;
01239
01240 outgoing_counter = _dbus_counter_new ();
01241 if (outgoing_counter == NULL)
01242 goto error;
01243
01244 objects = _dbus_object_tree_new (connection);
01245 if (objects == NULL)
01246 goto error;
01247
01248 if (_dbus_modify_sigpipe)
01249 _dbus_disable_sigpipe ();
01250
01251 connection->refcount.value = 1;
01252 connection->transport = transport;
01253 connection->watches = watch_list;
01254 connection->timeouts = timeout_list;
01255 connection->pending_replies = pending_replies;
01256 connection->outgoing_counter = outgoing_counter;
01257 connection->filter_list = NULL;
01258 connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE;
01259 connection->objects = objects;
01260 connection->exit_on_disconnect = FALSE;
01261 connection->shareable = FALSE;
01262 connection->route_peer_messages = FALSE;
01263 connection->disconnected_message_arrived = FALSE;
01264 connection->disconnected_message_processed = FALSE;
01265
01266 #ifndef DBUS_DISABLE_CHECKS
01267 connection->generation = _dbus_current_generation;
01268 #endif
01269
01270 _dbus_data_slot_list_init (&connection->slot_list);
01271
01272 connection->client_serial = 1;
01273
01274 connection->disconnect_message_link = disconnect_link;
01275
01276 CONNECTION_LOCK (connection);
01277
01278 if (!_dbus_transport_set_connection (transport, connection))
01279 {
01280 CONNECTION_UNLOCK (connection);
01281
01282 goto error;
01283 }
01284
01285 _dbus_transport_ref (transport);
01286
01287 CONNECTION_UNLOCK (connection);
01288
01289 return connection;
01290
01291 error:
01292 if (disconnect_message != NULL)
01293 dbus_message_unref (disconnect_message);
01294
01295 if (disconnect_link != NULL)
01296 _dbus_list_free_link (disconnect_link);
01297
01298 if (connection != NULL)
01299 {
01300 _dbus_condvar_free_at_location (&connection->io_path_cond);
01301 _dbus_condvar_free_at_location (&connection->dispatch_cond);
01302 _dbus_mutex_free_at_location (&connection->mutex);
01303 _dbus_mutex_free_at_location (&connection->io_path_mutex);
01304 _dbus_mutex_free_at_location (&connection->dispatch_mutex);
01305 dbus_free (connection);
01306 }
01307 if (pending_replies)
01308 _dbus_hash_table_unref (pending_replies);
01309
01310 if (watch_list)
01311 _dbus_watch_list_free (watch_list);
01312
01313 if (timeout_list)
01314 _dbus_timeout_list_free (timeout_list);
01315
01316 if (outgoing_counter)
01317 _dbus_counter_unref (outgoing_counter);
01318
01319 if (objects)
01320 _dbus_object_tree_unref (objects);
01321
01322 return NULL;
01323 }
01324
01332 DBusConnection *
01333 _dbus_connection_ref_unlocked (DBusConnection *connection)
01334 {
01335 _dbus_assert (connection != NULL);
01336 _dbus_assert (connection->generation == _dbus_current_generation);
01337
01338 HAVE_LOCK_CHECK (connection);
01339
01340 #ifdef DBUS_HAVE_ATOMIC_INT
01341 _dbus_atomic_inc (&connection->refcount);
01342 #else
01343 _dbus_assert (connection->refcount.value > 0);
01344 connection->refcount.value += 1;
01345 #endif
01346
01347 return connection;
01348 }
01349
01356 void
01357 _dbus_connection_unref_unlocked (DBusConnection *connection)
01358 {
01359 dbus_bool_t last_unref;
01360
01361 HAVE_LOCK_CHECK (connection);
01362
01363 _dbus_assert (connection != NULL);
01364
01365
01366
01367
01368
01369 #ifdef DBUS_HAVE_ATOMIC_INT
01370 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
01371 #else
01372 _dbus_assert (connection->refcount.value > 0);
01373
01374 connection->refcount.value -= 1;
01375 last_unref = (connection->refcount.value == 0);
01376 #if 0
01377 printf ("unref_unlocked() connection %p count = %d\n", connection, connection->refcount.value);
01378 #endif
01379 #endif
01380
01381 if (last_unref)
01382 _dbus_connection_last_unref (connection);
01383 }
01384
01385 static dbus_uint32_t
01386 _dbus_connection_get_next_client_serial (DBusConnection *connection)
01387 {
01388 dbus_uint32_t serial;
01389
01390 serial = connection->client_serial++;
01391
01392 if (connection->client_serial == 0)
01393 connection->client_serial = 1;
01394
01395 return serial;
01396 }
01397
01411 dbus_bool_t
01412 _dbus_connection_handle_watch (DBusWatch *watch,
01413 unsigned int condition,
01414 void *data)
01415 {
01416 DBusConnection *connection;
01417 dbus_bool_t retval;
01418 DBusDispatchStatus status;
01419
01420 connection = data;
01421
01422 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
01423
01424 CONNECTION_LOCK (connection);
01425 _dbus_connection_acquire_io_path (connection, -1);
01426 HAVE_LOCK_CHECK (connection);
01427 retval = _dbus_transport_handle_watch (connection->transport,
01428 watch, condition);
01429
01430 _dbus_connection_release_io_path (connection);
01431
01432 HAVE_LOCK_CHECK (connection);
01433
01434 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
01435
01436 status = _dbus_connection_get_dispatch_status_unlocked (connection);
01437
01438
01439 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01440
01441 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
01442
01443 return retval;
01444 }
01445
01446 _DBUS_DEFINE_GLOBAL_LOCK (shared_connections);
01447 static DBusHashTable *shared_connections = NULL;
01448 static DBusList *shared_connections_no_guid = NULL;
01449
01450 static void
01451 close_connection_on_shutdown (DBusConnection *connection)
01452 {
01453 DBusMessage *message;
01454
01455 dbus_connection_ref (connection);
01456 _dbus_connection_close_possibly_shared (connection);
01457
01458
01459 while ((message = dbus_connection_pop_message (connection)))
01460 {
01461 dbus_message_unref (message);
01462 }
01463 dbus_connection_unref (connection);
01464 }
01465
01466 static void
01467 shared_connections_shutdown (void *data)
01468 {
01469 int n_entries;
01470
01471 _DBUS_LOCK (shared_connections);
01472
01473
01474 while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0)
01475 {
01476 DBusConnection *connection;
01477 DBusHashIter iter;
01478
01479 _dbus_hash_iter_init (shared_connections, &iter);
01480 _dbus_hash_iter_next (&iter);
01481
01482 connection = _dbus_hash_iter_get_value (&iter);
01483
01484 _DBUS_UNLOCK (shared_connections);
01485 close_connection_on_shutdown (connection);
01486 _DBUS_LOCK (shared_connections);
01487
01488
01489 _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) < n_entries);
01490 }
01491
01492 _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) == 0);
01493
01494 _dbus_hash_table_unref (shared_connections);
01495 shared_connections = NULL;
01496
01497 if (shared_connections_no_guid != NULL)
01498 {
01499 DBusConnection *connection;
01500 connection = _dbus_list_pop_first (&shared_connections_no_guid);
01501 while (connection != NULL)
01502 {
01503 _DBUS_UNLOCK (shared_connections);
01504 close_connection_on_shutdown (connection);
01505 _DBUS_LOCK (shared_connections);
01506 connection = _dbus_list_pop_first (&shared_connections_no_guid);
01507 }
01508 }
01509
01510 shared_connections_no_guid = NULL;
01511
01512 _DBUS_UNLOCK (shared_connections);
01513 }
01514
01515 static dbus_bool_t
01516 connection_lookup_shared (DBusAddressEntry *entry,
01517 DBusConnection **result)
01518 {
01519 _dbus_verbose ("checking for existing connection\n");
01520
01521 *result = NULL;
01522
01523 _DBUS_LOCK (shared_connections);
01524
01525 if (shared_connections == NULL)
01526 {
01527 _dbus_verbose ("creating shared_connections hash table\n");
01528
01529 shared_connections = _dbus_hash_table_new (DBUS_HASH_STRING,
01530 dbus_free,
01531 NULL);
01532 if (shared_connections == NULL)
01533 {
01534 _DBUS_UNLOCK (shared_connections);
01535 return FALSE;
01536 }
01537
01538 if (!_dbus_register_shutdown_func (shared_connections_shutdown, NULL))
01539 {
01540 _dbus_hash_table_unref (shared_connections);
01541 shared_connections = NULL;
01542 _DBUS_UNLOCK (shared_connections);
01543 return FALSE;
01544 }
01545
01546 _dbus_verbose (" successfully created shared_connections\n");
01547
01548 _DBUS_UNLOCK (shared_connections);
01549 return TRUE;
01550 }
01551 else
01552 {
01553 const char *guid;
01554
01555 guid = dbus_address_entry_get_value (entry, "guid");
01556
01557 if (guid != NULL)
01558 {
01559 DBusConnection *connection;
01560
01561 connection = _dbus_hash_table_lookup_string (shared_connections,
01562 guid);
01563
01564 if (connection)
01565 {
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580 CONNECTION_LOCK (connection);
01581 if (_dbus_connection_get_is_connected_unlocked (connection))
01582 {
01583 _dbus_connection_ref_unlocked (connection);
01584 *result = connection;
01585 _dbus_verbose ("looked up existing connection to server guid %s\n",
01586 guid);
01587 }
01588 else
01589 {
01590 _dbus_verbose ("looked up existing connection to server guid %s but it was disconnected so ignoring it\n",
01591 guid);
01592 }
01593 CONNECTION_UNLOCK (connection);
01594 }
01595 }
01596
01597 _DBUS_UNLOCK (shared_connections);
01598 return TRUE;
01599 }
01600 }
01601
01602 static dbus_bool_t
01603 connection_record_shared_unlocked (DBusConnection *connection,
01604 const char *guid)
01605 {
01606 char *guid_key;
01607 char *guid_in_connection;
01608
01609 HAVE_LOCK_CHECK (connection);
01610 _dbus_assert (connection->server_guid == NULL);
01611 _dbus_assert (connection->shareable);
01612
01613
01614
01615
01616
01617 _dbus_connection_ref_unlocked (connection);
01618
01619 if (guid == NULL)
01620 {
01621 _DBUS_LOCK (shared_connections);
01622
01623 if (!_dbus_list_prepend (&shared_connections_no_guid, connection))
01624 {
01625 _DBUS_UNLOCK (shared_connections);
01626 return FALSE;
01627 }
01628
01629 _DBUS_UNLOCK (shared_connections);
01630 return TRUE;
01631 }
01632
01633
01634
01635
01636
01637
01638 guid_key = _dbus_strdup (guid);
01639 if (guid_key == NULL)
01640 return FALSE;
01641
01642 guid_in_connection = _dbus_strdup (guid);
01643 if (guid_in_connection == NULL)
01644 {
01645 dbus_free (guid_key);
01646 return FALSE;
01647 }
01648
01649 _DBUS_LOCK (shared_connections);
01650 _dbus_assert (shared_connections != NULL);
01651
01652 if (!_dbus_hash_table_insert_string (shared_connections,
01653 guid_key, connection))
01654 {
01655 dbus_free (guid_key);
01656 dbus_free (guid_in_connection);
01657 _DBUS_UNLOCK (shared_connections);
01658 return FALSE;
01659 }
01660
01661 connection->server_guid = guid_in_connection;
01662
01663 _dbus_verbose ("stored connection to %s to be shared\n",
01664 connection->server_guid);
01665
01666 _DBUS_UNLOCK (shared_connections);
01667
01668 _dbus_assert (connection->server_guid != NULL);
01669
01670 return TRUE;
01671 }
01672
01673 static void
01674 connection_forget_shared_unlocked (DBusConnection *connection)
01675 {
01676 HAVE_LOCK_CHECK (connection);
01677
01678 if (!connection->shareable)
01679 return;
01680
01681 _DBUS_LOCK (shared_connections);
01682
01683 if (connection->server_guid != NULL)
01684 {
01685 _dbus_verbose ("dropping connection to %s out of the shared table\n",
01686 connection->server_guid);
01687
01688 if (!_dbus_hash_table_remove_string (shared_connections,
01689 connection->server_guid))
01690 _dbus_assert_not_reached ("connection was not in the shared table");
01691
01692 dbus_free (connection->server_guid);
01693 connection->server_guid = NULL;
01694 }
01695 else
01696 {
01697 _dbus_list_remove (&shared_connections_no_guid, connection);
01698 }
01699
01700 _DBUS_UNLOCK (shared_connections);
01701
01702
01703 _dbus_connection_unref_unlocked (connection);
01704 }
01705
01706 static DBusConnection*
01707 connection_try_from_address_entry (DBusAddressEntry *entry,
01708 DBusError *error)
01709 {
01710 DBusTransport *transport;
01711 DBusConnection *connection;
01712
01713 transport = _dbus_transport_open (entry, error);
01714
01715 if (transport == NULL)
01716 {
01717 _DBUS_ASSERT_ERROR_IS_SET (error);
01718 return NULL;
01719 }
01720
01721 connection = _dbus_connection_new_for_transport (transport);
01722
01723 _dbus_transport_unref (transport);
01724
01725 if (connection == NULL)
01726 {
01727 _DBUS_SET_OOM (error);
01728 return NULL;
01729 }
01730
01731 #ifndef DBUS_DISABLE_CHECKS
01732 _dbus_assert (!connection->have_connection_lock);
01733 #endif
01734 return connection;
01735 }
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749 static DBusConnection*
01750 _dbus_connection_open_internal (const char *address,
01751 dbus_bool_t shared,
01752 DBusError *error)
01753 {
01754 DBusConnection *connection;
01755 DBusAddressEntry **entries;
01756 DBusError tmp_error = DBUS_ERROR_INIT;
01757 DBusError first_error = DBUS_ERROR_INIT;
01758 int len, i;
01759
01760 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01761
01762 _dbus_verbose ("opening %s connection to: %s\n",
01763 shared ? "shared" : "private", address);
01764
01765 if (!dbus_parse_address (address, &entries, &len, error))
01766 return NULL;
01767
01768 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01769
01770 connection = NULL;
01771
01772 for (i = 0; i < len; i++)
01773 {
01774 if (shared)
01775 {
01776 if (!connection_lookup_shared (entries[i], &connection))
01777 _DBUS_SET_OOM (&tmp_error);
01778 }
01779
01780 if (connection == NULL)
01781 {
01782 connection = connection_try_from_address_entry (entries[i],
01783 &tmp_error);
01784
01785 if (connection != NULL && shared)
01786 {
01787 const char *guid;
01788
01789 connection->shareable = TRUE;
01790
01791
01792 guid = dbus_address_entry_get_value (entries[i], "guid");
01793
01794 CONNECTION_LOCK (connection);
01795
01796 if (!connection_record_shared_unlocked (connection, guid))
01797 {
01798 _DBUS_SET_OOM (&tmp_error);
01799 _dbus_connection_close_possibly_shared_and_unlock (connection);
01800 dbus_connection_unref (connection);
01801 connection = NULL;
01802 }
01803 else
01804 CONNECTION_UNLOCK (connection);
01805 }
01806 }
01807
01808 if (connection)
01809 break;
01810
01811 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
01812
01813 if (i == 0)
01814 dbus_move_error (&tmp_error, &first_error);
01815 else
01816 dbus_error_free (&tmp_error);
01817 }
01818
01819 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01820 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
01821
01822 if (connection == NULL)
01823 {
01824 _DBUS_ASSERT_ERROR_IS_SET (&first_error);
01825 dbus_move_error (&first_error, error);
01826 }
01827 else
01828 dbus_error_free (&first_error);
01829
01830 dbus_address_entries_free (entries);
01831 return connection;
01832 }
01833
01842 void
01843 _dbus_connection_close_possibly_shared (DBusConnection *connection)
01844 {
01845 _dbus_assert (connection != NULL);
01846 _dbus_assert (connection->generation == _dbus_current_generation);
01847
01848 CONNECTION_LOCK (connection);
01849 _dbus_connection_close_possibly_shared_and_unlock (connection);
01850 }
01851
01852 static DBusPreallocatedSend*
01853 _dbus_connection_preallocate_send_unlocked (DBusConnection *connection)
01854 {
01855 DBusPreallocatedSend *preallocated;
01856
01857 HAVE_LOCK_CHECK (connection);
01858
01859 _dbus_assert (connection != NULL);
01860
01861 preallocated = dbus_new (DBusPreallocatedSend, 1);
01862 if (preallocated == NULL)
01863 return NULL;
01864
01865 if (connection->link_cache != NULL)
01866 {
01867 preallocated->queue_link =
01868 _dbus_list_pop_first_link (&connection->link_cache);
01869 preallocated->queue_link->data = NULL;
01870 }
01871 else
01872 {
01873 preallocated->queue_link = _dbus_list_alloc_link (NULL);
01874 if (preallocated->queue_link == NULL)
01875 goto failed_0;
01876 }
01877
01878 if (connection->link_cache != NULL)
01879 {
01880 preallocated->counter_link =
01881 _dbus_list_pop_first_link (&connection->link_cache);
01882 preallocated->counter_link->data = connection->outgoing_counter;
01883 }
01884 else
01885 {
01886 preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter);
01887 if (preallocated->counter_link == NULL)
01888 goto failed_1;
01889 }
01890
01891 _dbus_counter_ref (preallocated->counter_link->data);
01892
01893 preallocated->connection = connection;
01894
01895 return preallocated;
01896
01897 failed_1:
01898 _dbus_list_free_link (preallocated->queue_link);
01899 failed_0:
01900 dbus_free (preallocated);
01901
01902 return NULL;
01903 }
01904
01905
01906 static void
01907 _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *connection,
01908 DBusPreallocatedSend *preallocated,
01909 DBusMessage *message,
01910 dbus_uint32_t *client_serial)
01911 {
01912 dbus_uint32_t serial;
01913 const char *sig;
01914
01915 preallocated->queue_link->data = message;
01916 _dbus_list_prepend_link (&connection->outgoing_messages,
01917 preallocated->queue_link);
01918
01919 _dbus_message_add_size_counter_link (message,
01920 preallocated->counter_link);
01921
01922 dbus_free (preallocated);
01923 preallocated = NULL;
01924
01925 dbus_message_ref (message);
01926
01927 connection->n_outgoing += 1;
01928
01929 sig = dbus_message_get_signature (message);
01930
01931 _dbus_verbose ("Message %p (%d %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
01932 message,
01933 dbus_message_get_type (message),
01934 dbus_message_get_path (message) ?
01935 dbus_message_get_path (message) :
01936 "no path",
01937 dbus_message_get_interface (message) ?
01938 dbus_message_get_interface (message) :
01939 "no interface",
01940 dbus_message_get_member (message) ?
01941 dbus_message_get_member (message) :
01942 "no member",
01943 sig,
01944 dbus_message_get_destination (message) ?
01945 dbus_message_get_destination (message) :
01946 "null",
01947 connection,
01948 connection->n_outgoing);
01949
01950 if (dbus_message_get_serial (message) == 0)
01951 {
01952 serial = _dbus_connection_get_next_client_serial (connection);
01953 _dbus_message_set_serial (message, serial);
01954 if (client_serial)
01955 *client_serial = serial;
01956 }
01957 else
01958 {
01959 if (client_serial)
01960 *client_serial = dbus_message_get_serial (message);
01961 }
01962
01963 _dbus_verbose ("Message %p serial is %u\n",
01964 message, dbus_message_get_serial (message));
01965
01966 _dbus_message_lock (message);
01967
01968
01969
01970
01971 _dbus_connection_do_iteration_unlocked (connection,
01972 DBUS_ITERATION_DO_WRITING,
01973 -1);
01974
01975
01976 if (connection->n_outgoing > 0)
01977 _dbus_connection_wakeup_mainloop (connection);
01978 }
01979
01980 static void
01981 _dbus_connection_send_preallocated_and_unlock (DBusConnection *connection,
01982 DBusPreallocatedSend *preallocated,
01983 DBusMessage *message,
01984 dbus_uint32_t *client_serial)
01985 {
01986 DBusDispatchStatus status;
01987
01988 HAVE_LOCK_CHECK (connection);
01989
01990 _dbus_connection_send_preallocated_unlocked_no_update (connection,
01991 preallocated,
01992 message, client_serial);
01993
01994 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
01995 status = _dbus_connection_get_dispatch_status_unlocked (connection);
01996
01997
01998 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01999 }
02000
02010 dbus_bool_t
02011 _dbus_connection_send_and_unlock (DBusConnection *connection,
02012 DBusMessage *message,
02013 dbus_uint32_t *client_serial)
02014 {
02015 DBusPreallocatedSend *preallocated;
02016
02017 _dbus_assert (connection != NULL);
02018 _dbus_assert (message != NULL);
02019
02020 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
02021 if (preallocated == NULL)
02022 {
02023 CONNECTION_UNLOCK (connection);
02024 return FALSE;
02025 }
02026
02027 _dbus_connection_send_preallocated_and_unlock (connection,
02028 preallocated,
02029 message,
02030 client_serial);
02031 return TRUE;
02032 }
02033
02058 void
02059 _dbus_connection_close_if_only_one_ref (DBusConnection *connection)
02060 {
02061 CONNECTION_LOCK (connection);
02062
02063 _dbus_assert (connection->refcount.value > 0);
02064
02065 if (connection->refcount.value == 1)
02066 _dbus_connection_close_possibly_shared_and_unlock (connection);
02067 else
02068 CONNECTION_UNLOCK (connection);
02069 }
02070
02071
02081 static void
02082 _dbus_memory_pause_based_on_timeout (int timeout_milliseconds)
02083 {
02084 if (timeout_milliseconds == -1)
02085 _dbus_sleep_milliseconds (1000);
02086 else if (timeout_milliseconds < 100)
02087 ;
02088 else if (timeout_milliseconds <= 1000)
02089 _dbus_sleep_milliseconds (timeout_milliseconds / 3);
02090 else
02091 _dbus_sleep_milliseconds (1000);
02092 }
02093
02094 static DBusMessage *
02095 generate_local_error_message (dbus_uint32_t serial,
02096 char *error_name,
02097 char *error_msg)
02098 {
02099 DBusMessage *message;
02100 message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
02101 if (!message)
02102 goto out;
02103
02104 if (!dbus_message_set_error_name (message, error_name))
02105 {
02106 dbus_message_unref (message);
02107 message = NULL;
02108 goto out;
02109 }
02110
02111 dbus_message_set_no_reply (message, TRUE);
02112
02113 if (!dbus_message_set_reply_serial (message,
02114 serial))
02115 {
02116 dbus_message_unref (message);
02117 message = NULL;
02118 goto out;
02119 }
02120
02121 if (error_msg != NULL)
02122 {
02123 DBusMessageIter iter;
02124
02125 dbus_message_iter_init_append (message, &iter);
02126 if (!dbus_message_iter_append_basic (&iter,
02127 DBUS_TYPE_STRING,
02128 &error_msg))
02129 {
02130 dbus_message_unref (message);
02131 message = NULL;
02132 goto out;
02133 }
02134 }
02135
02136 out:
02137 return message;
02138 }
02139
02140
02141
02142
02143
02144 static DBusMessage*
02145 check_for_reply_unlocked (DBusConnection *connection,
02146 dbus_uint32_t client_serial)
02147 {
02148 DBusList *link;
02149
02150 HAVE_LOCK_CHECK (connection);
02151
02152 link = _dbus_list_get_first_link (&connection->incoming_messages);
02153
02154 while (link != NULL)
02155 {
02156 DBusMessage *reply = link->data;
02157
02158 if (dbus_message_get_reply_serial (reply) == client_serial)
02159 {
02160 _dbus_list_remove_link (&connection->incoming_messages, link);
02161 connection->n_incoming -= 1;
02162 return reply;
02163 }
02164 link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02165 }
02166
02167 return NULL;
02168 }
02169
02170 static void
02171 connection_timeout_and_complete_all_pending_calls_unlocked (DBusConnection *connection)
02172 {
02173
02174
02175
02176
02177
02178 while (_dbus_hash_table_get_n_entries (connection->pending_replies) > 0)
02179 {
02180 DBusPendingCall *pending;
02181 DBusHashIter iter;
02182
02183 _dbus_hash_iter_init (connection->pending_replies, &iter);
02184 _dbus_hash_iter_next (&iter);
02185
02186 pending = _dbus_hash_iter_get_value (&iter);
02187 _dbus_pending_call_ref_unlocked (pending);
02188
02189 _dbus_pending_call_queue_timeout_error_unlocked (pending,
02190 connection);
02191 _dbus_connection_remove_timeout_unlocked (connection,
02192 _dbus_pending_call_get_timeout_unlocked (pending));
02193 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
02194 _dbus_hash_iter_remove_entry (&iter);
02195
02196 _dbus_pending_call_unref_and_unlock (pending);
02197 CONNECTION_LOCK (connection);
02198 }
02199 HAVE_LOCK_CHECK (connection);
02200 }
02201
02202 static void
02203 complete_pending_call_and_unlock (DBusConnection *connection,
02204 DBusPendingCall *pending,
02205 DBusMessage *message)
02206 {
02207 _dbus_pending_call_set_reply_unlocked (pending, message);
02208 _dbus_pending_call_ref_unlocked (pending);
02209 _dbus_connection_detach_pending_call_and_unlock (connection, pending);
02210
02211
02212 _dbus_pending_call_complete (pending);
02213 dbus_pending_call_unref (pending);
02214 }
02215
02216 static dbus_bool_t
02217 check_for_reply_and_update_dispatch_unlocked (DBusConnection *connection,
02218 DBusPendingCall *pending)
02219 {
02220 DBusMessage *reply;
02221 DBusDispatchStatus status;
02222
02223 reply = check_for_reply_unlocked (connection,
02224 _dbus_pending_call_get_reply_serial_unlocked (pending));
02225 if (reply != NULL)
02226 {
02227 _dbus_verbose ("%s checked for reply\n", _DBUS_FUNCTION_NAME);
02228
02229 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
02230
02231 complete_pending_call_and_unlock (connection, pending, reply);
02232 dbus_message_unref (reply);
02233
02234 CONNECTION_LOCK (connection);
02235 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02236 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02237 dbus_pending_call_unref (pending);
02238
02239 return TRUE;
02240 }
02241
02242 return FALSE;
02243 }
02244
02259 void
02260 _dbus_connection_block_pending_call (DBusPendingCall *pending)
02261 {
02262 long start_tv_sec, start_tv_usec;
02263 long end_tv_sec, end_tv_usec;
02264 long tv_sec, tv_usec;
02265 DBusDispatchStatus status;
02266 DBusConnection *connection;
02267 dbus_uint32_t client_serial;
02268 int timeout_milliseconds;
02269
02270 _dbus_assert (pending != NULL);
02271
02272 if (dbus_pending_call_get_completed (pending))
02273 return;
02274
02275 dbus_pending_call_ref (pending);
02276
02277 connection = _dbus_pending_call_get_connection_and_lock (pending);
02278
02279
02280 _dbus_connection_flush_unlocked (connection);
02281
02282 client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
02283
02284
02285
02286
02287
02288 timeout_milliseconds = dbus_timeout_get_interval (_dbus_pending_call_get_timeout_unlocked (pending));
02289
02290 _dbus_get_current_time (&start_tv_sec, &start_tv_usec);
02291 end_tv_sec = start_tv_sec + timeout_milliseconds / 1000;
02292 end_tv_usec = start_tv_usec + (timeout_milliseconds % 1000) * 1000;
02293 end_tv_sec += end_tv_usec / _DBUS_USEC_PER_SECOND;
02294 end_tv_usec = end_tv_usec % _DBUS_USEC_PER_SECOND;
02295
02296 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec to %ld sec %ld usec\n",
02297 timeout_milliseconds,
02298 client_serial,
02299 start_tv_sec, start_tv_usec,
02300 end_tv_sec, end_tv_usec);
02301
02302
02303
02304 if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02305 return;
02306
02307
02308
02309 _dbus_connection_do_iteration_unlocked (connection,
02310 DBUS_ITERATION_DO_READING |
02311 DBUS_ITERATION_BLOCK,
02312 timeout_milliseconds);
02313
02314 recheck_status:
02315
02316 _dbus_verbose ("%s top of recheck\n", _DBUS_FUNCTION_NAME);
02317
02318 HAVE_LOCK_CHECK (connection);
02319
02320
02321
02322 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02323
02324
02325
02326
02327 if (_dbus_pending_call_get_completed_unlocked (pending))
02328 {
02329 _dbus_verbose ("Pending call completed by dispatch in %s\n", _DBUS_FUNCTION_NAME);
02330 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02331 dbus_pending_call_unref (pending);
02332 return;
02333 }
02334
02335 if (status == DBUS_DISPATCH_DATA_REMAINS)
02336 {
02337 if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02338 return;
02339 }
02340
02341 _dbus_get_current_time (&tv_sec, &tv_usec);
02342
02343 if (!_dbus_connection_get_is_connected_unlocked (connection))
02344 {
02345 DBusMessage *error_msg;
02346
02347 error_msg = generate_local_error_message (client_serial,
02348 DBUS_ERROR_DISCONNECTED,
02349 "Connection was disconnected before a reply was received");
02350
02351
02352 complete_pending_call_and_unlock (connection, pending, error_msg);
02353 dbus_pending_call_unref (pending);
02354 return;
02355 }
02356 else if (tv_sec < start_tv_sec)
02357 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
02358 else if (connection->disconnect_message_link == NULL)
02359 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
02360 else if (tv_sec < end_tv_sec ||
02361 (tv_sec == end_tv_sec && tv_usec < end_tv_usec))
02362 {
02363 timeout_milliseconds = (end_tv_sec - tv_sec) * 1000 +
02364 (end_tv_usec - tv_usec) / 1000;
02365 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds);
02366 _dbus_assert (timeout_milliseconds >= 0);
02367
02368 if (status == DBUS_DISPATCH_NEED_MEMORY)
02369 {
02370
02371
02372
02373
02374 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02375
02376 _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
02377 }
02378 else
02379 {
02380
02381 _dbus_connection_do_iteration_unlocked (connection,
02382 DBUS_ITERATION_DO_READING |
02383 DBUS_ITERATION_BLOCK,
02384 timeout_milliseconds);
02385 }
02386
02387 goto recheck_status;
02388 }
02389
02390 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %ld milliseconds and got no reply\n",
02391 (tv_sec - start_tv_sec) * 1000 + (tv_usec - start_tv_usec) / 1000);
02392
02393 _dbus_assert (!_dbus_pending_call_get_completed_unlocked (pending));
02394
02395
02396 complete_pending_call_and_unlock (connection, pending, NULL);
02397
02398
02399 CONNECTION_LOCK (connection);
02400 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02401 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02402 dbus_pending_call_unref (pending);
02403 }
02404
02441 DBusConnection*
02442 dbus_connection_open (const char *address,
02443 DBusError *error)
02444 {
02445 DBusConnection *connection;
02446
02447 _dbus_return_val_if_fail (address != NULL, NULL);
02448 _dbus_return_val_if_error_is_set (error, NULL);
02449
02450 connection = _dbus_connection_open_internal (address,
02451 TRUE,
02452 error);
02453
02454 return connection;
02455 }
02456
02484 DBusConnection*
02485 dbus_connection_open_private (const char *address,
02486 DBusError *error)
02487 {
02488 DBusConnection *connection;
02489
02490 _dbus_return_val_if_fail (address != NULL, NULL);
02491 _dbus_return_val_if_error_is_set (error, NULL);
02492
02493 connection = _dbus_connection_open_internal (address,
02494 FALSE,
02495 error);
02496
02497 return connection;
02498 }
02499
02506 DBusConnection *
02507 dbus_connection_ref (DBusConnection *connection)
02508 {
02509 _dbus_return_val_if_fail (connection != NULL, NULL);
02510 _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
02511
02512
02513
02514
02515
02516 #ifdef DBUS_HAVE_ATOMIC_INT
02517 _dbus_atomic_inc (&connection->refcount);
02518 #else
02519 CONNECTION_LOCK (connection);
02520 _dbus_assert (connection->refcount.value > 0);
02521
02522 connection->refcount.value += 1;
02523 CONNECTION_UNLOCK (connection);
02524 #endif
02525
02526 return connection;
02527 }
02528
02529 static void
02530 free_outgoing_message (void *element,
02531 void *data)
02532 {
02533 DBusMessage *message = element;
02534 DBusConnection *connection = data;
02535
02536 _dbus_message_remove_size_counter (message,
02537 connection->outgoing_counter,
02538 NULL);
02539 dbus_message_unref (message);
02540 }
02541
02542
02543
02544
02545
02546 static void
02547 _dbus_connection_last_unref (DBusConnection *connection)
02548 {
02549 DBusList *link;
02550
02551 _dbus_verbose ("Finalizing connection %p\n", connection);
02552
02553 _dbus_assert (connection->refcount.value == 0);
02554
02555
02556
02557
02558 _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
02559 _dbus_assert (connection->server_guid == NULL);
02560
02561
02562 _dbus_object_tree_free_all_unlocked (connection->objects);
02563
02564 dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
02565 dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
02566 dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
02567
02568 _dbus_watch_list_free (connection->watches);
02569 connection->watches = NULL;
02570
02571 _dbus_timeout_list_free (connection->timeouts);
02572 connection->timeouts = NULL;
02573
02574 _dbus_data_slot_list_free (&connection->slot_list);
02575
02576 link = _dbus_list_get_first_link (&connection->filter_list);
02577 while (link != NULL)
02578 {
02579 DBusMessageFilter *filter = link->data;
02580 DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
02581
02582 filter->function = NULL;
02583 _dbus_message_filter_unref (filter);
02584 link->data = NULL;
02585
02586 link = next;
02587 }
02588 _dbus_list_clear (&connection->filter_list);
02589
02590
02591
02592 _dbus_object_tree_unref (connection->objects);
02593
02594 _dbus_hash_table_unref (connection->pending_replies);
02595 connection->pending_replies = NULL;
02596
02597 _dbus_list_clear (&connection->filter_list);
02598
02599 _dbus_list_foreach (&connection->outgoing_messages,
02600 free_outgoing_message,
02601 connection);
02602 _dbus_list_clear (&connection->outgoing_messages);
02603
02604 _dbus_list_foreach (&connection->incoming_messages,
02605 (DBusForeachFunction) dbus_message_unref,
02606 NULL);
02607 _dbus_list_clear (&connection->incoming_messages);
02608
02609 _dbus_counter_unref (connection->outgoing_counter);
02610
02611 _dbus_transport_unref (connection->transport);
02612
02613 if (connection->disconnect_message_link)
02614 {
02615 DBusMessage *message = connection->disconnect_message_link->data;
02616 dbus_message_unref (message);
02617 _dbus_list_free_link (connection->disconnect_message_link);
02618 }
02619
02620 _dbus_list_clear (&connection->link_cache);
02621
02622 _dbus_condvar_free_at_location (&connection->dispatch_cond);
02623 _dbus_condvar_free_at_location (&connection->io_path_cond);
02624
02625 _dbus_mutex_free_at_location (&connection->io_path_mutex);
02626 _dbus_mutex_free_at_location (&connection->dispatch_mutex);
02627
02628 _dbus_mutex_free_at_location (&connection->mutex);
02629
02630 dbus_free (connection);
02631 }
02632
02652 void
02653 dbus_connection_unref (DBusConnection *connection)
02654 {
02655 dbus_bool_t last_unref;
02656
02657 _dbus_return_if_fail (connection != NULL);
02658 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02659
02660
02661
02662
02663
02664 #ifdef DBUS_HAVE_ATOMIC_INT
02665 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
02666 #else
02667 CONNECTION_LOCK (connection);
02668
02669 _dbus_assert (connection->refcount.value > 0);
02670
02671 connection->refcount.value -= 1;
02672 last_unref = (connection->refcount.value == 0);
02673
02674 #if 0
02675 printf ("unref() connection %p count = %d\n", connection, connection->refcount.value);
02676 #endif
02677
02678 CONNECTION_UNLOCK (connection);
02679 #endif
02680
02681 if (last_unref)
02682 {
02683 #ifndef DBUS_DISABLE_CHECKS
02684 if (_dbus_transport_get_is_connected (connection->transport))
02685 {
02686 _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",
02687 connection->shareable ?
02688 "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" :
02689 "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n");
02690 return;
02691 }
02692 #endif
02693 _dbus_connection_last_unref (connection);
02694 }
02695 }
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706 static void
02707 _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection)
02708 {
02709 DBusDispatchStatus status;
02710
02711 HAVE_LOCK_CHECK (connection);
02712
02713 _dbus_verbose ("Disconnecting %p\n", connection);
02714
02715
02716
02717
02718
02719 _dbus_connection_ref_unlocked (connection);
02720
02721 _dbus_transport_disconnect (connection->transport);
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02733
02734
02735 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02736
02737
02738 dbus_connection_unref (connection);
02739 }
02740
02783 void
02784 dbus_connection_close (DBusConnection *connection)
02785 {
02786 _dbus_return_if_fail (connection != NULL);
02787 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02788
02789 CONNECTION_LOCK (connection);
02790
02791 #ifndef DBUS_DISABLE_CHECKS
02792 if (connection->shareable)
02793 {
02794 CONNECTION_UNLOCK (connection);
02795
02796 _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n");
02797 return;
02798 }
02799 #endif
02800
02801 _dbus_connection_close_possibly_shared_and_unlock (connection);
02802 }
02803
02804 static dbus_bool_t
02805 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
02806 {
02807 HAVE_LOCK_CHECK (connection);
02808 return _dbus_transport_get_is_connected (connection->transport);
02809 }
02810
02824 dbus_bool_t
02825 dbus_connection_get_is_connected (DBusConnection *connection)
02826 {
02827 dbus_bool_t res;
02828
02829 _dbus_return_val_if_fail (connection != NULL, FALSE);
02830
02831 CONNECTION_LOCK (connection);
02832 res = _dbus_connection_get_is_connected_unlocked (connection);
02833 CONNECTION_UNLOCK (connection);
02834
02835 return res;
02836 }
02837
02846 dbus_bool_t
02847 dbus_connection_get_is_authenticated (DBusConnection *connection)
02848 {
02849 dbus_bool_t res;
02850
02851 _dbus_return_val_if_fail (connection != NULL, FALSE);
02852
02853 CONNECTION_LOCK (connection);
02854 res = _dbus_transport_get_is_authenticated (connection->transport);
02855 CONNECTION_UNLOCK (connection);
02856
02857 return res;
02858 }
02859
02880 dbus_bool_t
02881 dbus_connection_get_is_anonymous (DBusConnection *connection)
02882 {
02883 dbus_bool_t res;
02884
02885 _dbus_return_val_if_fail (connection != NULL, FALSE);
02886
02887 CONNECTION_LOCK (connection);
02888 res = _dbus_transport_get_is_anonymous (connection->transport);
02889 CONNECTION_UNLOCK (connection);
02890
02891 return res;
02892 }
02893
02925 char*
02926 dbus_connection_get_server_id (DBusConnection *connection)
02927 {
02928 char *id;
02929
02930 _dbus_return_val_if_fail (connection != NULL, FALSE);
02931
02932 CONNECTION_LOCK (connection);
02933 id = _dbus_strdup (_dbus_transport_get_server_id (connection->transport));
02934 CONNECTION_UNLOCK (connection);
02935
02936 return id;
02937 }
02938
02952 void
02953 dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
02954 dbus_bool_t exit_on_disconnect)
02955 {
02956 _dbus_return_if_fail (connection != NULL);
02957
02958 CONNECTION_LOCK (connection);
02959 connection->exit_on_disconnect = exit_on_disconnect != FALSE;
02960 CONNECTION_UNLOCK (connection);
02961 }
02962
02972 DBusPreallocatedSend*
02973 dbus_connection_preallocate_send (DBusConnection *connection)
02974 {
02975 DBusPreallocatedSend *preallocated;
02976
02977 _dbus_return_val_if_fail (connection != NULL, NULL);
02978
02979 CONNECTION_LOCK (connection);
02980
02981 preallocated =
02982 _dbus_connection_preallocate_send_unlocked (connection);
02983
02984 CONNECTION_UNLOCK (connection);
02985
02986 return preallocated;
02987 }
02988
02998 void
02999 dbus_connection_free_preallocated_send (DBusConnection *connection,
03000 DBusPreallocatedSend *preallocated)
03001 {
03002 _dbus_return_if_fail (connection != NULL);
03003 _dbus_return_if_fail (preallocated != NULL);
03004 _dbus_return_if_fail (connection == preallocated->connection);
03005
03006 _dbus_list_free_link (preallocated->queue_link);
03007 _dbus_counter_unref (preallocated->counter_link->data);
03008 _dbus_list_free_link (preallocated->counter_link);
03009 dbus_free (preallocated);
03010 }
03011
03024 void
03025 dbus_connection_send_preallocated (DBusConnection *connection,
03026 DBusPreallocatedSend *preallocated,
03027 DBusMessage *message,
03028 dbus_uint32_t *client_serial)
03029 {
03030 _dbus_return_if_fail (connection != NULL);
03031 _dbus_return_if_fail (preallocated != NULL);
03032 _dbus_return_if_fail (message != NULL);
03033 _dbus_return_if_fail (preallocated->connection == connection);
03034 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
03035 dbus_message_get_member (message) != NULL);
03036 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
03037 (dbus_message_get_interface (message) != NULL &&
03038 dbus_message_get_member (message) != NULL));
03039
03040 CONNECTION_LOCK (connection);
03041 _dbus_connection_send_preallocated_and_unlock (connection,
03042 preallocated,
03043 message, client_serial);
03044 }
03045
03046 static dbus_bool_t
03047 _dbus_connection_send_unlocked_no_update (DBusConnection *connection,
03048 DBusMessage *message,
03049 dbus_uint32_t *client_serial)
03050 {
03051 DBusPreallocatedSend *preallocated;
03052
03053 _dbus_assert (connection != NULL);
03054 _dbus_assert (message != NULL);
03055
03056 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
03057 if (preallocated == NULL)
03058 return FALSE;
03059
03060 _dbus_connection_send_preallocated_unlocked_no_update (connection,
03061 preallocated,
03062 message,
03063 client_serial);
03064 return TRUE;
03065 }
03066
03094 dbus_bool_t
03095 dbus_connection_send (DBusConnection *connection,
03096 DBusMessage *message,
03097 dbus_uint32_t *serial)
03098 {
03099 _dbus_return_val_if_fail (connection != NULL, FALSE);
03100 _dbus_return_val_if_fail (message != NULL, FALSE);
03101
03102 CONNECTION_LOCK (connection);
03103
03104 return _dbus_connection_send_and_unlock (connection,
03105 message,
03106 serial);
03107 }
03108
03109 static dbus_bool_t
03110 reply_handler_timeout (void *data)
03111 {
03112 DBusConnection *connection;
03113 DBusDispatchStatus status;
03114 DBusPendingCall *pending = data;
03115
03116 connection = _dbus_pending_call_get_connection_and_lock (pending);
03117
03118 _dbus_pending_call_queue_timeout_error_unlocked (pending,
03119 connection);
03120 _dbus_connection_remove_timeout_unlocked (connection,
03121 _dbus_pending_call_get_timeout_unlocked (pending));
03122 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
03123
03124 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
03125 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03126
03127
03128 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03129
03130 return TRUE;
03131 }
03132
03170 dbus_bool_t
03171 dbus_connection_send_with_reply (DBusConnection *connection,
03172 DBusMessage *message,
03173 DBusPendingCall **pending_return,
03174 int timeout_milliseconds)
03175 {
03176 DBusPendingCall *pending;
03177 dbus_int32_t serial = -1;
03178 DBusDispatchStatus status;
03179
03180 _dbus_return_val_if_fail (connection != NULL, FALSE);
03181 _dbus_return_val_if_fail (message != NULL, FALSE);
03182 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03183
03184 if (pending_return)
03185 *pending_return = NULL;
03186
03187 CONNECTION_LOCK (connection);
03188
03189 if (!_dbus_connection_get_is_connected_unlocked (connection))
03190 {
03191 CONNECTION_UNLOCK (connection);
03192
03193 return TRUE;
03194 }
03195
03196 pending = _dbus_pending_call_new_unlocked (connection,
03197 timeout_milliseconds,
03198 reply_handler_timeout);
03199
03200 if (pending == NULL)
03201 {
03202 CONNECTION_UNLOCK (connection);
03203 return FALSE;
03204 }
03205
03206
03207 serial = dbus_message_get_serial (message);
03208 if (serial == 0)
03209 {
03210 serial = _dbus_connection_get_next_client_serial (connection);
03211 _dbus_message_set_serial (message, serial);
03212 }
03213
03214 if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
03215 goto error;
03216
03217
03218
03219
03220
03221 if (!_dbus_connection_attach_pending_call_unlocked (connection,
03222 pending))
03223 goto error;
03224
03225 if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
03226 {
03227 _dbus_connection_detach_pending_call_and_unlock (connection,
03228 pending);
03229 goto error_unlocked;
03230 }
03231
03232 if (pending_return)
03233 *pending_return = pending;
03234 else
03235 {
03236 _dbus_connection_detach_pending_call_unlocked (connection, pending);
03237
03238
03239
03240 }
03241
03242 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03243
03244
03245 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03246
03247 if (pending_return == NULL)
03248 dbus_pending_call_unref (pending);
03249
03250 return TRUE;
03251
03252 error:
03253 CONNECTION_UNLOCK (connection);
03254 error_unlocked:
03255 dbus_pending_call_unref (pending);
03256 return FALSE;
03257 }
03258
03289 DBusMessage*
03290 dbus_connection_send_with_reply_and_block (DBusConnection *connection,
03291 DBusMessage *message,
03292 int timeout_milliseconds,
03293 DBusError *error)
03294 {
03295 DBusMessage *reply;
03296 DBusPendingCall *pending;
03297
03298 _dbus_return_val_if_fail (connection != NULL, NULL);
03299 _dbus_return_val_if_fail (message != NULL, NULL);
03300 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL);
03301 _dbus_return_val_if_error_is_set (error, NULL);
03302
03303 if (!dbus_connection_send_with_reply (connection, message,
03304 &pending, timeout_milliseconds))
03305 {
03306 _DBUS_SET_OOM (error);
03307 return NULL;
03308 }
03309
03310 if (pending == NULL)
03311 {
03312 dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Connection is closed");
03313 return NULL;
03314 }
03315
03316 dbus_pending_call_block (pending);
03317
03318 reply = dbus_pending_call_steal_reply (pending);
03319 dbus_pending_call_unref (pending);
03320
03321
03322
03323
03324 _dbus_assert (reply != NULL);
03325
03326 if (dbus_set_error_from_message (error, reply))
03327 {
03328 dbus_message_unref (reply);
03329 return NULL;
03330 }
03331 else
03332 return reply;
03333 }
03334
03343 DBusDispatchStatus
03344 _dbus_connection_flush_unlocked (DBusConnection *connection)
03345 {
03346
03347
03348
03349
03350
03351 DBusDispatchStatus status;
03352
03353 HAVE_LOCK_CHECK (connection);
03354
03355 while (connection->n_outgoing > 0 &&
03356 _dbus_connection_get_is_connected_unlocked (connection))
03357 {
03358 _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME);
03359 HAVE_LOCK_CHECK (connection);
03360 _dbus_connection_do_iteration_unlocked (connection,
03361 DBUS_ITERATION_DO_READING |
03362 DBUS_ITERATION_DO_WRITING |
03363 DBUS_ITERATION_BLOCK,
03364 -1);
03365 }
03366
03367 HAVE_LOCK_CHECK (connection);
03368 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
03369 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03370
03371 HAVE_LOCK_CHECK (connection);
03372 return status;
03373 }
03374
03380 void
03381 dbus_connection_flush (DBusConnection *connection)
03382 {
03383
03384
03385
03386
03387
03388 DBusDispatchStatus status;
03389
03390 _dbus_return_if_fail (connection != NULL);
03391
03392 CONNECTION_LOCK (connection);
03393
03394 status = _dbus_connection_flush_unlocked (connection);
03395
03396 HAVE_LOCK_CHECK (connection);
03397
03398 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03399
03400 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
03401 }
03402
03413 static dbus_bool_t
03414 _dbus_connection_read_write_dispatch (DBusConnection *connection,
03415 int timeout_milliseconds,
03416 dbus_bool_t dispatch)
03417 {
03418 DBusDispatchStatus dstatus;
03419 dbus_bool_t progress_possible;
03420
03421
03422
03423
03424
03425 dbus_connection_ref (connection);
03426 dstatus = dbus_connection_get_dispatch_status (connection);
03427
03428 if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
03429 {
03430 _dbus_verbose ("doing dispatch in %s\n", _DBUS_FUNCTION_NAME);
03431 dbus_connection_dispatch (connection);
03432 CONNECTION_LOCK (connection);
03433 }
03434 else if (dstatus == DBUS_DISPATCH_NEED_MEMORY)
03435 {
03436 _dbus_verbose ("pausing for memory in %s\n", _DBUS_FUNCTION_NAME);
03437 _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
03438 CONNECTION_LOCK (connection);
03439 }
03440 else
03441 {
03442 CONNECTION_LOCK (connection);
03443 if (_dbus_connection_get_is_connected_unlocked (connection))
03444 {
03445 _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME);
03446 _dbus_connection_do_iteration_unlocked (connection,
03447 DBUS_ITERATION_DO_READING |
03448 DBUS_ITERATION_DO_WRITING |
03449 DBUS_ITERATION_BLOCK,
03450 timeout_milliseconds);
03451 }
03452 }
03453
03454 HAVE_LOCK_CHECK (connection);
03455
03456
03457
03458
03459 if (dispatch)
03460 progress_possible = connection->n_incoming != 0 ||
03461 connection->disconnect_message_link != NULL;
03462 else
03463 progress_possible = _dbus_connection_get_is_connected_unlocked (connection);
03464
03465 CONNECTION_UNLOCK (connection);
03466
03467 dbus_connection_unref (connection);
03468
03469 return progress_possible;
03470 }
03471
03472
03507 dbus_bool_t
03508 dbus_connection_read_write_dispatch (DBusConnection *connection,
03509 int timeout_milliseconds)
03510 {
03511 _dbus_return_val_if_fail (connection != NULL, FALSE);
03512 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03513 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE);
03514 }
03515
03539 dbus_bool_t
03540 dbus_connection_read_write (DBusConnection *connection,
03541 int timeout_milliseconds)
03542 {
03543 _dbus_return_val_if_fail (connection != NULL, FALSE);
03544 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03545 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE);
03546 }
03547
03548
03549
03550
03551
03552
03553 static void
03554 check_disconnected_message_arrived_unlocked (DBusConnection *connection,
03555 DBusMessage *head_of_queue)
03556 {
03557 HAVE_LOCK_CHECK (connection);
03558
03559
03560 if (connection->disconnect_message_link == NULL &&
03561 dbus_message_is_signal (head_of_queue,
03562 DBUS_INTERFACE_LOCAL,
03563 "Disconnected"))
03564 {
03565 connection->disconnected_message_arrived = TRUE;
03566 }
03567 }
03568
03588 DBusMessage*
03589 dbus_connection_borrow_message (DBusConnection *connection)
03590 {
03591 DBusDispatchStatus status;
03592 DBusMessage *message;
03593
03594 _dbus_return_val_if_fail (connection != NULL, NULL);
03595
03596 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
03597
03598
03599
03600
03601 status = dbus_connection_get_dispatch_status (connection);
03602 if (status != DBUS_DISPATCH_DATA_REMAINS)
03603 return NULL;
03604
03605 CONNECTION_LOCK (connection);
03606
03607 _dbus_connection_acquire_dispatch (connection);
03608
03609
03610 _dbus_assert (connection->message_borrowed == NULL);
03611
03612 connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
03613
03614 message = connection->message_borrowed;
03615
03616 check_disconnected_message_arrived_unlocked (connection, message);
03617
03618
03619 if (message == NULL)
03620 _dbus_connection_release_dispatch (connection);
03621
03622 CONNECTION_UNLOCK (connection);
03623
03624
03625
03626 return message;
03627 }
03628
03637 void
03638 dbus_connection_return_message (DBusConnection *connection,
03639 DBusMessage *message)
03640 {
03641 DBusDispatchStatus status;
03642
03643 _dbus_return_if_fail (connection != NULL);
03644 _dbus_return_if_fail (message != NULL);
03645 _dbus_return_if_fail (message == connection->message_borrowed);
03646 _dbus_return_if_fail (connection->dispatch_acquired);
03647
03648 CONNECTION_LOCK (connection);
03649
03650 _dbus_assert (message == connection->message_borrowed);
03651
03652 connection->message_borrowed = NULL;
03653
03654 _dbus_connection_release_dispatch (connection);
03655
03656 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03657 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03658 }
03659
03669 void
03670 dbus_connection_steal_borrowed_message (DBusConnection *connection,
03671 DBusMessage *message)
03672 {
03673 DBusMessage *pop_message;
03674 DBusDispatchStatus status;
03675
03676 _dbus_return_if_fail (connection != NULL);
03677 _dbus_return_if_fail (message != NULL);
03678 _dbus_return_if_fail (message == connection->message_borrowed);
03679 _dbus_return_if_fail (connection->dispatch_acquired);
03680
03681 CONNECTION_LOCK (connection);
03682
03683 _dbus_assert (message == connection->message_borrowed);
03684
03685 pop_message = _dbus_list_pop_first (&connection->incoming_messages);
03686 _dbus_assert (message == pop_message);
03687
03688 connection->n_incoming -= 1;
03689
03690 _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
03691 message, connection->n_incoming);
03692
03693 connection->message_borrowed = NULL;
03694
03695 _dbus_connection_release_dispatch (connection);
03696
03697 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03698 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03699 }
03700
03701
03702
03703
03704 static DBusList*
03705 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
03706 {
03707 HAVE_LOCK_CHECK (connection);
03708
03709 _dbus_assert (connection->message_borrowed == NULL);
03710
03711 if (connection->n_incoming > 0)
03712 {
03713 DBusList *link;
03714
03715 link = _dbus_list_pop_first_link (&connection->incoming_messages);
03716 connection->n_incoming -= 1;
03717
03718 _dbus_verbose ("Message %p (%d %s %s %s '%s') removed from incoming queue %p, %d incoming\n",
03719 link->data,
03720 dbus_message_get_type (link->data),
03721 dbus_message_get_path (link->data) ?
03722 dbus_message_get_path (link->data) :
03723 "no path",
03724 dbus_message_get_interface (link->data) ?
03725 dbus_message_get_interface (link->data) :
03726 "no interface",
03727 dbus_message_get_member (link->data) ?
03728 dbus_message_get_member (link->data) :
03729 "no member",
03730 dbus_message_get_signature (link->data),
03731 connection, connection->n_incoming);
03732
03733 check_disconnected_message_arrived_unlocked (connection, link->data);
03734
03735 return link;
03736 }
03737 else
03738 return NULL;
03739 }
03740
03741
03742
03743
03744 static DBusMessage*
03745 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
03746 {
03747 DBusList *link;
03748
03749 HAVE_LOCK_CHECK (connection);
03750
03751 link = _dbus_connection_pop_message_link_unlocked (connection);
03752
03753 if (link != NULL)
03754 {
03755 DBusMessage *message;
03756
03757 message = link->data;
03758
03759 _dbus_list_free_link (link);
03760
03761 return message;
03762 }
03763 else
03764 return NULL;
03765 }
03766
03767 static void
03768 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
03769 DBusList *message_link)
03770 {
03771 HAVE_LOCK_CHECK (connection);
03772
03773 _dbus_assert (message_link != NULL);
03774
03775 _dbus_assert (connection->message_borrowed == NULL);
03776
03777 _dbus_assert (connection->dispatch_acquired);
03778
03779 _dbus_list_prepend_link (&connection->incoming_messages,
03780 message_link);
03781 connection->n_incoming += 1;
03782
03783 _dbus_verbose ("Message %p (%d %s %s '%s') put back into queue %p, %d incoming\n",
03784 message_link->data,
03785 dbus_message_get_type (message_link->data),
03786 dbus_message_get_interface (message_link->data) ?
03787 dbus_message_get_interface (message_link->data) :
03788 "no interface",
03789 dbus_message_get_member (message_link->data) ?
03790 dbus_message_get_member (message_link->data) :
03791 "no member",
03792 dbus_message_get_signature (message_link->data),
03793 connection, connection->n_incoming);
03794 }
03795
03815 DBusMessage*
03816 dbus_connection_pop_message (DBusConnection *connection)
03817 {
03818 DBusMessage *message;
03819 DBusDispatchStatus status;
03820
03821 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
03822
03823
03824
03825
03826 status = dbus_connection_get_dispatch_status (connection);
03827 if (status != DBUS_DISPATCH_DATA_REMAINS)
03828 return NULL;
03829
03830 CONNECTION_LOCK (connection);
03831 _dbus_connection_acquire_dispatch (connection);
03832 HAVE_LOCK_CHECK (connection);
03833
03834 message = _dbus_connection_pop_message_unlocked (connection);
03835
03836 _dbus_verbose ("Returning popped message %p\n", message);
03837
03838 _dbus_connection_release_dispatch (connection);
03839
03840 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03841 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03842
03843 return message;
03844 }
03845
03853 static void
03854 _dbus_connection_acquire_dispatch (DBusConnection *connection)
03855 {
03856 HAVE_LOCK_CHECK (connection);
03857
03858 _dbus_connection_ref_unlocked (connection);
03859 CONNECTION_UNLOCK (connection);
03860
03861 _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03862 _dbus_mutex_lock (connection->dispatch_mutex);
03863
03864 while (connection->dispatch_acquired)
03865 {
03866 _dbus_verbose ("%s waiting for dispatch to be acquirable\n", _DBUS_FUNCTION_NAME);
03867 _dbus_condvar_wait (connection->dispatch_cond,
03868 connection->dispatch_mutex);
03869 }
03870
03871 _dbus_assert (!connection->dispatch_acquired);
03872
03873 connection->dispatch_acquired = TRUE;
03874
03875 _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03876 _dbus_mutex_unlock (connection->dispatch_mutex);
03877
03878 CONNECTION_LOCK (connection);
03879 _dbus_connection_unref_unlocked (connection);
03880 }
03881
03889 static void
03890 _dbus_connection_release_dispatch (DBusConnection *connection)
03891 {
03892 HAVE_LOCK_CHECK (connection);
03893
03894 _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03895 _dbus_mutex_lock (connection->dispatch_mutex);
03896
03897 _dbus_assert (connection->dispatch_acquired);
03898
03899 connection->dispatch_acquired = FALSE;
03900 _dbus_condvar_wake_one (connection->dispatch_cond);
03901
03902 _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03903 _dbus_mutex_unlock (connection->dispatch_mutex);
03904 }
03905
03906 static void
03907 _dbus_connection_failed_pop (DBusConnection *connection,
03908 DBusList *message_link)
03909 {
03910 _dbus_list_prepend_link (&connection->incoming_messages,
03911 message_link);
03912 connection->n_incoming += 1;
03913 }
03914
03915
03916 static void
03917 notify_disconnected_unlocked (DBusConnection *connection)
03918 {
03919 HAVE_LOCK_CHECK (connection);
03920
03921
03922
03923
03924
03925
03926
03927 _dbus_bus_notify_shared_connection_disconnected_unlocked (connection);
03928
03929
03930
03931
03932
03933 if (connection->n_outgoing > 0)
03934 {
03935 DBusList *link;
03936
03937 _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
03938 connection->n_outgoing);
03939
03940 while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
03941 {
03942 _dbus_connection_message_sent (connection, link->data);
03943 }
03944 }
03945 }
03946
03947
03948 static DBusDispatchStatus
03949 notify_disconnected_and_dispatch_complete_unlocked (DBusConnection *connection)
03950 {
03951 HAVE_LOCK_CHECK (connection);
03952
03953 if (connection->disconnect_message_link != NULL)
03954 {
03955 _dbus_verbose ("Sending disconnect message from %s\n",
03956 _DBUS_FUNCTION_NAME);
03957
03958
03959
03960
03961 connection_timeout_and_complete_all_pending_calls_unlocked (connection);
03962
03963
03964
03965
03966 _dbus_connection_queue_synthesized_message_link (connection,
03967 connection->disconnect_message_link);
03968 connection->disconnect_message_link = NULL;
03969
03970 return DBUS_DISPATCH_DATA_REMAINS;
03971 }
03972
03973 return DBUS_DISPATCH_COMPLETE;
03974 }
03975
03976 static DBusDispatchStatus
03977 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
03978 {
03979 HAVE_LOCK_CHECK (connection);
03980
03981 if (connection->n_incoming > 0)
03982 return DBUS_DISPATCH_DATA_REMAINS;
03983 else if (!_dbus_transport_queue_messages (connection->transport))
03984 return DBUS_DISPATCH_NEED_MEMORY;
03985 else
03986 {
03987 DBusDispatchStatus status;
03988 dbus_bool_t is_connected;
03989
03990 status = _dbus_transport_get_dispatch_status (connection->transport);
03991 is_connected = _dbus_transport_get_is_connected (connection->transport);
03992
03993 _dbus_verbose ("dispatch status = %s is_connected = %d\n",
03994 DISPATCH_STATUS_NAME (status), is_connected);
03995
03996 if (!is_connected)
03997 {
03998
03999
04000
04001
04002
04003
04004 notify_disconnected_unlocked (connection);
04005
04006
04007
04008
04009
04010
04011 if (status == DBUS_DISPATCH_COMPLETE)
04012 status = notify_disconnected_and_dispatch_complete_unlocked (connection);
04013 }
04014
04015 if (status != DBUS_DISPATCH_COMPLETE)
04016 return status;
04017 else if (connection->n_incoming > 0)
04018 return DBUS_DISPATCH_DATA_REMAINS;
04019 else
04020 return DBUS_DISPATCH_COMPLETE;
04021 }
04022 }
04023
04024 static void
04025 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
04026 DBusDispatchStatus new_status)
04027 {
04028 dbus_bool_t changed;
04029 DBusDispatchStatusFunction function;
04030 void *data;
04031
04032 HAVE_LOCK_CHECK (connection);
04033
04034 _dbus_connection_ref_unlocked (connection);
04035
04036 changed = new_status != connection->last_dispatch_status;
04037
04038 connection->last_dispatch_status = new_status;
04039
04040 function = connection->dispatch_status_function;
04041 data = connection->dispatch_status_data;
04042
04043 if (connection->disconnected_message_arrived &&
04044 !connection->disconnected_message_processed)
04045 {
04046 connection->disconnected_message_processed = TRUE;
04047
04048
04049
04050
04051
04052 connection_forget_shared_unlocked (connection);
04053
04054 if (connection->exit_on_disconnect)
04055 {
04056 CONNECTION_UNLOCK (connection);
04057
04058 _dbus_verbose ("Exiting on Disconnected signal\n");
04059 _dbus_exit (1);
04060 _dbus_assert_not_reached ("Call to exit() returned");
04061 }
04062 }
04063
04064
04065 CONNECTION_UNLOCK (connection);
04066
04067 if (changed && function)
04068 {
04069 _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
04070 connection, new_status,
04071 DISPATCH_STATUS_NAME (new_status));
04072 (* function) (connection, new_status, data);
04073 }
04074
04075 dbus_connection_unref (connection);
04076 }
04077
04103 DBusDispatchStatus
04104 dbus_connection_get_dispatch_status (DBusConnection *connection)
04105 {
04106 DBusDispatchStatus status;
04107
04108 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04109
04110 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
04111
04112 CONNECTION_LOCK (connection);
04113
04114 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04115
04116 CONNECTION_UNLOCK (connection);
04117
04118 return status;
04119 }
04120
04124 static DBusHandlerResult
04125 _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
04126 DBusMessage *message)
04127 {
04128 if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
04129 {
04130
04131 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04132 }
04133 else if (dbus_message_is_method_call (message,
04134 DBUS_INTERFACE_PEER,
04135 "Ping"))
04136 {
04137 DBusMessage *ret;
04138 dbus_bool_t sent;
04139
04140 ret = dbus_message_new_method_return (message);
04141 if (ret == NULL)
04142 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04143
04144 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04145
04146 dbus_message_unref (ret);
04147
04148 if (!sent)
04149 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04150
04151 return DBUS_HANDLER_RESULT_HANDLED;
04152 }
04153 else if (dbus_message_is_method_call (message,
04154 DBUS_INTERFACE_PEER,
04155 "GetMachineId"))
04156 {
04157 DBusMessage *ret;
04158 dbus_bool_t sent;
04159 DBusString uuid;
04160
04161 ret = dbus_message_new_method_return (message);
04162 if (ret == NULL)
04163 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04164
04165 sent = FALSE;
04166 _dbus_string_init (&uuid);
04167 if (_dbus_get_local_machine_uuid_encoded (&uuid))
04168 {
04169 const char *v_STRING = _dbus_string_get_const_data (&uuid);
04170 if (dbus_message_append_args (ret,
04171 DBUS_TYPE_STRING, &v_STRING,
04172 DBUS_TYPE_INVALID))
04173 {
04174 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04175 }
04176 }
04177 _dbus_string_free (&uuid);
04178
04179 dbus_message_unref (ret);
04180
04181 if (!sent)
04182 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04183
04184 return DBUS_HANDLER_RESULT_HANDLED;
04185 }
04186 else if (dbus_message_has_interface (message, DBUS_INTERFACE_PEER))
04187 {
04188
04189
04190
04191
04192
04193 DBusMessage *ret;
04194 dbus_bool_t sent;
04195
04196 ret = dbus_message_new_error (message,
04197 DBUS_ERROR_UNKNOWN_METHOD,
04198 "Unknown method invoked on org.freedesktop.DBus.Peer interface");
04199 if (ret == NULL)
04200 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04201
04202 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04203
04204 dbus_message_unref (ret);
04205
04206 if (!sent)
04207 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04208
04209 return DBUS_HANDLER_RESULT_HANDLED;
04210 }
04211 else
04212 {
04213 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04214 }
04215 }
04216
04223 static DBusHandlerResult
04224 _dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection,
04225 DBusMessage *message)
04226 {
04227
04228
04229
04230 return _dbus_connection_peer_filter_unlocked_no_update (connection, message);
04231 }
04232
04275 DBusDispatchStatus
04276 dbus_connection_dispatch (DBusConnection *connection)
04277 {
04278 DBusMessage *message;
04279 DBusList *link, *filter_list_copy, *message_link;
04280 DBusHandlerResult result;
04281 DBusPendingCall *pending;
04282 dbus_int32_t reply_serial;
04283 DBusDispatchStatus status;
04284
04285 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04286
04287 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
04288
04289 CONNECTION_LOCK (connection);
04290 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04291 if (status != DBUS_DISPATCH_DATA_REMAINS)
04292 {
04293
04294 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04295 return status;
04296 }
04297
04298
04299
04300
04301 _dbus_connection_ref_unlocked (connection);
04302
04303 _dbus_connection_acquire_dispatch (connection);
04304 HAVE_LOCK_CHECK (connection);
04305
04306 message_link = _dbus_connection_pop_message_link_unlocked (connection);
04307 if (message_link == NULL)
04308 {
04309
04310
04311 _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
04312
04313 _dbus_connection_release_dispatch (connection);
04314
04315 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04316
04317 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04318
04319 dbus_connection_unref (connection);
04320
04321 return status;
04322 }
04323
04324 message = message_link->data;
04325
04326 _dbus_verbose (" dispatching message %p (%d %s %s '%s')\n",
04327 message,
04328 dbus_message_get_type (message),
04329 dbus_message_get_interface (message) ?
04330 dbus_message_get_interface (message) :
04331 "no interface",
04332 dbus_message_get_member (message) ?
04333 dbus_message_get_member (message) :
04334 "no member",
04335 dbus_message_get_signature (message));
04336
04337 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04338
04339
04340
04341
04342
04343
04344
04345
04346 reply_serial = dbus_message_get_reply_serial (message);
04347 pending = _dbus_hash_table_lookup_int (connection->pending_replies,
04348 reply_serial);
04349 if (pending)
04350 {
04351 _dbus_verbose ("Dispatching a pending reply\n");
04352 complete_pending_call_and_unlock (connection, pending, message);
04353 pending = NULL;
04354
04355 CONNECTION_LOCK (connection);
04356 _dbus_verbose ("pending call completed in dispatch\n");
04357 result = DBUS_HANDLER_RESULT_HANDLED;
04358 goto out;
04359 }
04360
04361 result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message);
04362 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04363 goto out;
04364
04365 if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
04366 {
04367 _dbus_connection_release_dispatch (connection);
04368 HAVE_LOCK_CHECK (connection);
04369
04370 _dbus_connection_failed_pop (connection, message_link);
04371
04372
04373 _dbus_connection_update_dispatch_status_and_unlock (connection,
04374 DBUS_DISPATCH_NEED_MEMORY);
04375
04376 if (pending)
04377 dbus_pending_call_unref (pending);
04378 dbus_connection_unref (connection);
04379
04380 return DBUS_DISPATCH_NEED_MEMORY;
04381 }
04382
04383 _dbus_list_foreach (&filter_list_copy,
04384 (DBusForeachFunction)_dbus_message_filter_ref,
04385 NULL);
04386
04387
04388
04389
04390 CONNECTION_UNLOCK (connection);
04391
04392 link = _dbus_list_get_first_link (&filter_list_copy);
04393 while (link != NULL)
04394 {
04395 DBusMessageFilter *filter = link->data;
04396 DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
04397
04398 if (filter->function == NULL)
04399 {
04400 _dbus_verbose (" filter was removed in a callback function\n");
04401 link = next;
04402 continue;
04403 }
04404
04405 _dbus_verbose (" running filter on message %p\n", message);
04406 result = (* filter->function) (connection, message, filter->user_data);
04407
04408 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04409 break;
04410
04411 link = next;
04412 }
04413
04414 _dbus_list_foreach (&filter_list_copy,
04415 (DBusForeachFunction)_dbus_message_filter_unref,
04416 NULL);
04417 _dbus_list_clear (&filter_list_copy);
04418
04419 CONNECTION_LOCK (connection);
04420
04421 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04422 {
04423 _dbus_verbose ("No memory in %s\n", _DBUS_FUNCTION_NAME);
04424 goto out;
04425 }
04426 else if (result == DBUS_HANDLER_RESULT_HANDLED)
04427 {
04428 _dbus_verbose ("filter handled message in dispatch\n");
04429 goto out;
04430 }
04431
04432
04433
04434
04435 _dbus_verbose (" running object path dispatch on message %p (%d %s %s '%s')\n",
04436 message,
04437 dbus_message_get_type (message),
04438 dbus_message_get_interface (message) ?
04439 dbus_message_get_interface (message) :
04440 "no interface",
04441 dbus_message_get_member (message) ?
04442 dbus_message_get_member (message) :
04443 "no member",
04444 dbus_message_get_signature (message));
04445
04446 HAVE_LOCK_CHECK (connection);
04447 result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
04448 message);
04449
04450 CONNECTION_LOCK (connection);
04451
04452 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04453 {
04454 _dbus_verbose ("object tree handled message in dispatch\n");
04455 goto out;
04456 }
04457
04458 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
04459 {
04460 DBusMessage *reply;
04461 DBusString str;
04462 DBusPreallocatedSend *preallocated;
04463
04464 _dbus_verbose (" sending error %s\n",
04465 DBUS_ERROR_UNKNOWN_METHOD);
04466
04467 if (!_dbus_string_init (&str))
04468 {
04469 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04470 _dbus_verbose ("no memory for error string in dispatch\n");
04471 goto out;
04472 }
04473
04474 if (!_dbus_string_append_printf (&str,
04475 "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
04476 dbus_message_get_member (message),
04477 dbus_message_get_signature (message),
04478 dbus_message_get_interface (message)))
04479 {
04480 _dbus_string_free (&str);
04481 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04482 _dbus_verbose ("no memory for error string in dispatch\n");
04483 goto out;
04484 }
04485
04486 reply = dbus_message_new_error (message,
04487 DBUS_ERROR_UNKNOWN_METHOD,
04488 _dbus_string_get_const_data (&str));
04489 _dbus_string_free (&str);
04490
04491 if (reply == NULL)
04492 {
04493 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04494 _dbus_verbose ("no memory for error reply in dispatch\n");
04495 goto out;
04496 }
04497
04498 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
04499
04500 if (preallocated == NULL)
04501 {
04502 dbus_message_unref (reply);
04503 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04504 _dbus_verbose ("no memory for error send in dispatch\n");
04505 goto out;
04506 }
04507
04508 _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
04509 reply, NULL);
04510
04511 dbus_message_unref (reply);
04512
04513 result = DBUS_HANDLER_RESULT_HANDLED;
04514 }
04515
04516 _dbus_verbose (" done dispatching %p (%d %s %s '%s') on connection %p\n", message,
04517 dbus_message_get_type (message),
04518 dbus_message_get_interface (message) ?
04519 dbus_message_get_interface (message) :
04520 "no interface",
04521 dbus_message_get_member (message) ?
04522 dbus_message_get_member (message) :
04523 "no member",
04524 dbus_message_get_signature (message),
04525 connection);
04526
04527 out:
04528 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04529 {
04530 _dbus_verbose ("out of memory in %s\n", _DBUS_FUNCTION_NAME);
04531
04532
04533
04534
04535
04536 _dbus_connection_putback_message_link_unlocked (connection,
04537 message_link);
04538 }
04539 else
04540 {
04541 _dbus_verbose (" ... done dispatching in %s\n", _DBUS_FUNCTION_NAME);
04542
04543 _dbus_list_free_link (message_link);
04544 dbus_message_unref (message);
04545
04546
04547 }
04548
04549 _dbus_connection_release_dispatch (connection);
04550 HAVE_LOCK_CHECK (connection);
04551
04552 _dbus_verbose ("%s before final status update\n", _DBUS_FUNCTION_NAME);
04553 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04554
04555
04556 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04557
04558 dbus_connection_unref (connection);
04559
04560 return status;
04561 }
04562
04622 dbus_bool_t
04623 dbus_connection_set_watch_functions (DBusConnection *connection,
04624 DBusAddWatchFunction add_function,
04625 DBusRemoveWatchFunction remove_function,
04626 DBusWatchToggledFunction toggled_function,
04627 void *data,
04628 DBusFreeFunction free_data_function)
04629 {
04630 dbus_bool_t retval;
04631 DBusWatchList *watches;
04632
04633 _dbus_return_val_if_fail (connection != NULL, FALSE);
04634
04635 CONNECTION_LOCK (connection);
04636
04637 #ifndef DBUS_DISABLE_CHECKS
04638 if (connection->watches == NULL)
04639 {
04640 _dbus_warn_check_failed ("Re-entrant call to %s is not allowed\n",
04641 _DBUS_FUNCTION_NAME);
04642 return FALSE;
04643 }
04644 #endif
04645
04646
04647 _dbus_connection_ref_unlocked (connection);
04648
04649
04650
04651
04652
04653 watches = connection->watches;
04654 connection->watches = NULL;
04655 CONNECTION_UNLOCK (connection);
04656
04657 retval = _dbus_watch_list_set_functions (watches,
04658 add_function, remove_function,
04659 toggled_function,
04660 data, free_data_function);
04661 CONNECTION_LOCK (connection);
04662 connection->watches = watches;
04663
04664 CONNECTION_UNLOCK (connection);
04665
04666 dbus_connection_unref (connection);
04667
04668 return retval;
04669 }
04670
04704 dbus_bool_t
04705 dbus_connection_set_timeout_functions (DBusConnection *connection,
04706 DBusAddTimeoutFunction add_function,
04707 DBusRemoveTimeoutFunction remove_function,
04708 DBusTimeoutToggledFunction toggled_function,
04709 void *data,
04710 DBusFreeFunction free_data_function)
04711 {
04712 dbus_bool_t retval;
04713 DBusTimeoutList *timeouts;
04714
04715 _dbus_return_val_if_fail (connection != NULL, FALSE);
04716
04717 CONNECTION_LOCK (connection);
04718
04719 #ifndef DBUS_DISABLE_CHECKS
04720 if (connection->timeouts == NULL)
04721 {
04722 _dbus_warn_check_failed ("Re-entrant call to %s is not allowed\n",
04723 _DBUS_FUNCTION_NAME);
04724 return FALSE;
04725 }
04726 #endif
04727
04728
04729 _dbus_connection_ref_unlocked (connection);
04730
04731 timeouts = connection->timeouts;
04732 connection->timeouts = NULL;
04733 CONNECTION_UNLOCK (connection);
04734
04735 retval = _dbus_timeout_list_set_functions (timeouts,
04736 add_function, remove_function,
04737 toggled_function,
04738 data, free_data_function);
04739 CONNECTION_LOCK (connection);
04740 connection->timeouts = timeouts;
04741
04742 CONNECTION_UNLOCK (connection);
04743
04744 dbus_connection_unref (connection);
04745
04746 return retval;
04747 }
04748
04763 void
04764 dbus_connection_set_wakeup_main_function (DBusConnection *connection,
04765 DBusWakeupMainFunction wakeup_main_function,
04766 void *data,
04767 DBusFreeFunction free_data_function)
04768 {
04769 void *old_data;
04770 DBusFreeFunction old_free_data;
04771
04772 _dbus_return_if_fail (connection != NULL);
04773
04774 CONNECTION_LOCK (connection);
04775 old_data = connection->wakeup_main_data;
04776 old_free_data = connection->free_wakeup_main_data;
04777
04778 connection->wakeup_main_function = wakeup_main_function;
04779 connection->wakeup_main_data = data;
04780 connection->free_wakeup_main_data = free_data_function;
04781
04782 CONNECTION_UNLOCK (connection);
04783
04784
04785 if (old_free_data)
04786 (*old_free_data) (old_data);
04787 }
04788
04809 void
04810 dbus_connection_set_dispatch_status_function (DBusConnection *connection,
04811 DBusDispatchStatusFunction function,
04812 void *data,
04813 DBusFreeFunction free_data_function)
04814 {
04815 void *old_data;
04816 DBusFreeFunction old_free_data;
04817
04818 _dbus_return_if_fail (connection != NULL);
04819
04820 CONNECTION_LOCK (connection);
04821 old_data = connection->dispatch_status_data;
04822 old_free_data = connection->free_dispatch_status_data;
04823
04824 connection->dispatch_status_function = function;
04825 connection->dispatch_status_data = data;
04826 connection->free_dispatch_status_data = free_data_function;
04827
04828 CONNECTION_UNLOCK (connection);
04829
04830
04831 if (old_free_data)
04832 (*old_free_data) (old_data);
04833 }
04834
04854 dbus_bool_t
04855 dbus_connection_get_unix_fd (DBusConnection *connection,
04856 int *fd)
04857 {
04858 _dbus_return_val_if_fail (connection != NULL, FALSE);
04859 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
04860
04861 #ifdef DBUS_WIN
04862
04863 return FALSE;
04864 #endif
04865
04866 return dbus_connection_get_socket(connection, fd);
04867 }
04868
04884 dbus_bool_t
04885 dbus_connection_get_socket(DBusConnection *connection,
04886 int *fd)
04887 {
04888 dbus_bool_t retval;
04889
04890 _dbus_return_val_if_fail (connection != NULL, FALSE);
04891 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
04892
04893 CONNECTION_LOCK (connection);
04894
04895 retval = _dbus_transport_get_socket_fd (connection->transport,
04896 fd);
04897
04898 CONNECTION_UNLOCK (connection);
04899
04900 return retval;
04901 }
04902
04903
04926 dbus_bool_t
04927 dbus_connection_get_unix_user (DBusConnection *connection,
04928 unsigned long *uid)
04929 {
04930 dbus_bool_t result;
04931
04932 _dbus_return_val_if_fail (connection != NULL, FALSE);
04933 _dbus_return_val_if_fail (uid != NULL, FALSE);
04934
04935 CONNECTION_LOCK (connection);
04936
04937 if (!_dbus_transport_get_is_authenticated (connection->transport))
04938 result = FALSE;
04939 else
04940 result = _dbus_transport_get_unix_user (connection->transport,
04941 uid);
04942
04943 #ifdef DBUS_WIN
04944 _dbus_assert (!result);
04945 #endif
04946
04947 CONNECTION_UNLOCK (connection);
04948
04949 return result;
04950 }
04951
04962 dbus_bool_t
04963 dbus_connection_get_unix_process_id (DBusConnection *connection,
04964 unsigned long *pid)
04965 {
04966 dbus_bool_t result;
04967
04968 _dbus_return_val_if_fail (connection != NULL, FALSE);
04969 _dbus_return_val_if_fail (pid != NULL, FALSE);
04970
04971 CONNECTION_LOCK (connection);
04972
04973 if (!_dbus_transport_get_is_authenticated (connection->transport))
04974 result = FALSE;
04975 else
04976 result = _dbus_transport_get_unix_process_id (connection->transport,
04977 pid);
04978 #ifdef DBUS_WIN
04979 _dbus_assert (!result);
04980 #endif
04981
04982 CONNECTION_UNLOCK (connection);
04983
04984 return result;
04985 }
04986
04997 dbus_bool_t
04998 dbus_connection_get_adt_audit_session_data (DBusConnection *connection,
04999 void **data,
05000 dbus_int32_t *data_size)
05001 {
05002 dbus_bool_t result;
05003
05004 _dbus_return_val_if_fail (connection != NULL, FALSE);
05005 _dbus_return_val_if_fail (data != NULL, FALSE);
05006 _dbus_return_val_if_fail (data_size != NULL, FALSE);
05007
05008 CONNECTION_LOCK (connection);
05009
05010 if (!_dbus_transport_get_is_authenticated (connection->transport))
05011 result = FALSE;
05012 else
05013 result = _dbus_transport_get_adt_audit_session_data (connection->transport,
05014 data,
05015 data_size);
05016 CONNECTION_UNLOCK (connection);
05017
05018 return result;
05019 }
05020
05043 void
05044 dbus_connection_set_unix_user_function (DBusConnection *connection,
05045 DBusAllowUnixUserFunction function,
05046 void *data,
05047 DBusFreeFunction free_data_function)
05048 {
05049 void *old_data = NULL;
05050 DBusFreeFunction old_free_function = NULL;
05051
05052 _dbus_return_if_fail (connection != NULL);
05053
05054 CONNECTION_LOCK (connection);
05055 _dbus_transport_set_unix_user_function (connection->transport,
05056 function, data, free_data_function,
05057 &old_data, &old_free_function);
05058 CONNECTION_UNLOCK (connection);
05059
05060 if (old_free_function != NULL)
05061 (* old_free_function) (old_data);
05062 }
05063
05095 dbus_bool_t
05096 dbus_connection_get_windows_user (DBusConnection *connection,
05097 char **windows_sid_p)
05098 {
05099 dbus_bool_t result;
05100
05101 _dbus_return_val_if_fail (connection != NULL, FALSE);
05102 _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
05103
05104 CONNECTION_LOCK (connection);
05105
05106 if (!_dbus_transport_get_is_authenticated (connection->transport))
05107 result = FALSE;
05108 else
05109 result = _dbus_transport_get_windows_user (connection->transport,
05110 windows_sid_p);
05111
05112 #ifdef DBUS_UNIX
05113 _dbus_assert (!result);
05114 #endif
05115
05116 CONNECTION_UNLOCK (connection);
05117
05118 return result;
05119 }
05120
05142 void
05143 dbus_connection_set_windows_user_function (DBusConnection *connection,
05144 DBusAllowWindowsUserFunction function,
05145 void *data,
05146 DBusFreeFunction free_data_function)
05147 {
05148 void *old_data = NULL;
05149 DBusFreeFunction old_free_function = NULL;
05150
05151 _dbus_return_if_fail (connection != NULL);
05152
05153 CONNECTION_LOCK (connection);
05154 _dbus_transport_set_windows_user_function (connection->transport,
05155 function, data, free_data_function,
05156 &old_data, &old_free_function);
05157 CONNECTION_UNLOCK (connection);
05158
05159 if (old_free_function != NULL)
05160 (* old_free_function) (old_data);
05161 }
05162
05189 void
05190 dbus_connection_set_allow_anonymous (DBusConnection *connection,
05191 dbus_bool_t value)
05192 {
05193 _dbus_return_if_fail (connection != NULL);
05194
05195 CONNECTION_LOCK (connection);
05196 _dbus_transport_set_allow_anonymous (connection->transport, value);
05197 CONNECTION_UNLOCK (connection);
05198 }
05199
05217 void
05218 dbus_connection_set_route_peer_messages (DBusConnection *connection,
05219 dbus_bool_t value)
05220 {
05221 _dbus_return_if_fail (connection != NULL);
05222
05223 CONNECTION_LOCK (connection);
05224 connection->route_peer_messages = TRUE;
05225 CONNECTION_UNLOCK (connection);
05226 }
05227
05249 dbus_bool_t
05250 dbus_connection_add_filter (DBusConnection *connection,
05251 DBusHandleMessageFunction function,
05252 void *user_data,
05253 DBusFreeFunction free_data_function)
05254 {
05255 DBusMessageFilter *filter;
05256
05257 _dbus_return_val_if_fail (connection != NULL, FALSE);
05258 _dbus_return_val_if_fail (function != NULL, FALSE);
05259
05260 filter = dbus_new0 (DBusMessageFilter, 1);
05261 if (filter == NULL)
05262 return FALSE;
05263
05264 filter->refcount.value = 1;
05265
05266 CONNECTION_LOCK (connection);
05267
05268 if (!_dbus_list_append (&connection->filter_list,
05269 filter))
05270 {
05271 _dbus_message_filter_unref (filter);
05272 CONNECTION_UNLOCK (connection);
05273 return FALSE;
05274 }
05275
05276
05277
05278
05279
05280
05281 filter->function = function;
05282 filter->user_data = user_data;
05283 filter->free_user_data_function = free_data_function;
05284
05285 CONNECTION_UNLOCK (connection);
05286 return TRUE;
05287 }
05288
05301 void
05302 dbus_connection_remove_filter (DBusConnection *connection,
05303 DBusHandleMessageFunction function,
05304 void *user_data)
05305 {
05306 DBusList *link;
05307 DBusMessageFilter *filter;
05308
05309 _dbus_return_if_fail (connection != NULL);
05310 _dbus_return_if_fail (function != NULL);
05311
05312 CONNECTION_LOCK (connection);
05313
05314 filter = NULL;
05315
05316 link = _dbus_list_get_last_link (&connection->filter_list);
05317 while (link != NULL)
05318 {
05319 filter = link->data;
05320
05321 if (filter->function == function &&
05322 filter->user_data == user_data)
05323 {
05324 _dbus_list_remove_link (&connection->filter_list, link);
05325 filter->function = NULL;
05326
05327 break;
05328 }
05329
05330 link = _dbus_list_get_prev_link (&connection->filter_list, link);
05331 }
05332
05333 CONNECTION_UNLOCK (connection);
05334
05335 #ifndef DBUS_DISABLE_CHECKS
05336 if (filter == NULL)
05337 {
05338 _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
05339 function, user_data);
05340 return;
05341 }
05342 #endif
05343
05344
05345 if (filter->free_user_data_function)
05346 (* filter->free_user_data_function) (filter->user_data);
05347
05348 filter->free_user_data_function = NULL;
05349 filter->user_data = NULL;
05350
05351 _dbus_message_filter_unref (filter);
05352 }
05353
05366 dbus_bool_t
05367 dbus_connection_try_register_object_path (DBusConnection *connection,
05368 const char *path,
05369 const DBusObjectPathVTable *vtable,
05370 void *user_data,
05371 DBusError *error)
05372 {
05373 char **decomposed_path;
05374 dbus_bool_t retval;
05375
05376 _dbus_return_val_if_fail (connection != NULL, FALSE);
05377 _dbus_return_val_if_fail (path != NULL, FALSE);
05378 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05379 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05380
05381 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05382 return FALSE;
05383
05384 CONNECTION_LOCK (connection);
05385
05386 retval = _dbus_object_tree_register (connection->objects,
05387 FALSE,
05388 (const char **) decomposed_path, vtable,
05389 user_data, error);
05390
05391 CONNECTION_UNLOCK (connection);
05392
05393 dbus_free_string_array (decomposed_path);
05394
05395 return retval;
05396 }
05397
05412 dbus_bool_t
05413 dbus_connection_register_object_path (DBusConnection *connection,
05414 const char *path,
05415 const DBusObjectPathVTable *vtable,
05416 void *user_data)
05417 {
05418 char **decomposed_path;
05419 dbus_bool_t retval;
05420 DBusError error = DBUS_ERROR_INIT;
05421
05422 _dbus_return_val_if_fail (connection != NULL, FALSE);
05423 _dbus_return_val_if_fail (path != NULL, FALSE);
05424 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05425 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05426
05427 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05428 return FALSE;
05429
05430 CONNECTION_LOCK (connection);
05431
05432 retval = _dbus_object_tree_register (connection->objects,
05433 FALSE,
05434 (const char **) decomposed_path, vtable,
05435 user_data, &error);
05436
05437 CONNECTION_UNLOCK (connection);
05438
05439 dbus_free_string_array (decomposed_path);
05440
05441 if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE))
05442 {
05443 _dbus_warn ("%s\n", error.message);
05444 dbus_error_free (&error);
05445 return FALSE;
05446 }
05447
05448 return retval;
05449 }
05450
05465 dbus_bool_t
05466 dbus_connection_try_register_fallback (DBusConnection *connection,
05467 const char *path,
05468 const DBusObjectPathVTable *vtable,
05469 void *user_data,
05470 DBusError *error)
05471 {
05472 char **decomposed_path;
05473 dbus_bool_t retval;
05474
05475 _dbus_return_val_if_fail (connection != NULL, FALSE);
05476 _dbus_return_val_if_fail (path != NULL, FALSE);
05477 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05478 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05479
05480 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05481 return FALSE;
05482
05483 CONNECTION_LOCK (connection);
05484
05485 retval = _dbus_object_tree_register (connection->objects,
05486 TRUE,
05487 (const char **) decomposed_path, vtable,
05488 user_data, error);
05489
05490 CONNECTION_UNLOCK (connection);
05491
05492 dbus_free_string_array (decomposed_path);
05493
05494 return retval;
05495 }
05496
05513 dbus_bool_t
05514 dbus_connection_register_fallback (DBusConnection *connection,
05515 const char *path,
05516 const DBusObjectPathVTable *vtable,
05517 void *user_data)
05518 {
05519 char **decomposed_path;
05520 dbus_bool_t retval;
05521 DBusError error = DBUS_ERROR_INIT;
05522
05523 _dbus_return_val_if_fail (connection != NULL, FALSE);
05524 _dbus_return_val_if_fail (path != NULL, FALSE);
05525 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05526 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05527
05528 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05529 return FALSE;
05530
05531 CONNECTION_LOCK (connection);
05532
05533 retval = _dbus_object_tree_register (connection->objects,
05534 TRUE,
05535 (const char **) decomposed_path, vtable,
05536 user_data, &error);
05537
05538 CONNECTION_UNLOCK (connection);
05539
05540 dbus_free_string_array (decomposed_path);
05541
05542 if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE))
05543 {
05544 _dbus_warn ("%s\n", error.message);
05545 dbus_error_free (&error);
05546 return FALSE;
05547 }
05548
05549 return retval;
05550 }
05551
05561 dbus_bool_t
05562 dbus_connection_unregister_object_path (DBusConnection *connection,
05563 const char *path)
05564 {
05565 char **decomposed_path;
05566
05567 _dbus_return_val_if_fail (connection != NULL, FALSE);
05568 _dbus_return_val_if_fail (path != NULL, FALSE);
05569 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05570
05571 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05572 return FALSE;
05573
05574 CONNECTION_LOCK (connection);
05575
05576 _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
05577
05578 dbus_free_string_array (decomposed_path);
05579
05580 return TRUE;
05581 }
05582
05593 dbus_bool_t
05594 dbus_connection_get_object_path_data (DBusConnection *connection,
05595 const char *path,
05596 void **data_p)
05597 {
05598 char **decomposed_path;
05599
05600 _dbus_return_val_if_fail (connection != NULL, FALSE);
05601 _dbus_return_val_if_fail (path != NULL, FALSE);
05602 _dbus_return_val_if_fail (data_p != NULL, FALSE);
05603
05604 *data_p = NULL;
05605
05606 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05607 return FALSE;
05608
05609 CONNECTION_LOCK (connection);
05610
05611 *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path);
05612
05613 CONNECTION_UNLOCK (connection);
05614
05615 dbus_free_string_array (decomposed_path);
05616
05617 return TRUE;
05618 }
05619
05630 dbus_bool_t
05631 dbus_connection_list_registered (DBusConnection *connection,
05632 const char *parent_path,
05633 char ***child_entries)
05634 {
05635 char **decomposed_path;
05636 dbus_bool_t retval;
05637 _dbus_return_val_if_fail (connection != NULL, FALSE);
05638 _dbus_return_val_if_fail (parent_path != NULL, FALSE);
05639 _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
05640 _dbus_return_val_if_fail (child_entries != NULL, FALSE);
05641
05642 if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
05643 return FALSE;
05644
05645 CONNECTION_LOCK (connection);
05646
05647 retval = _dbus_object_tree_list_registered_and_unlock (connection->objects,
05648 (const char **) decomposed_path,
05649 child_entries);
05650 dbus_free_string_array (decomposed_path);
05651
05652 return retval;
05653 }
05654
05655 static DBusDataSlotAllocator slot_allocator;
05656 _DBUS_DEFINE_GLOBAL_LOCK (connection_slots);
05657
05672 dbus_bool_t
05673 dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
05674 {
05675 return _dbus_data_slot_allocator_alloc (&slot_allocator,
05676 &_DBUS_LOCK_NAME (connection_slots),
05677 slot_p);
05678 }
05679
05691 void
05692 dbus_connection_free_data_slot (dbus_int32_t *slot_p)
05693 {
05694 _dbus_return_if_fail (*slot_p >= 0);
05695
05696 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
05697 }
05698
05712 dbus_bool_t
05713 dbus_connection_set_data (DBusConnection *connection,
05714 dbus_int32_t slot,
05715 void *data,
05716 DBusFreeFunction free_data_func)
05717 {
05718 DBusFreeFunction old_free_func;
05719 void *old_data;
05720 dbus_bool_t retval;
05721
05722 _dbus_return_val_if_fail (connection != NULL, FALSE);
05723 _dbus_return_val_if_fail (slot >= 0, FALSE);
05724
05725 CONNECTION_LOCK (connection);
05726
05727 retval = _dbus_data_slot_list_set (&slot_allocator,
05728 &connection->slot_list,
05729 slot, data, free_data_func,
05730 &old_free_func, &old_data);
05731
05732 CONNECTION_UNLOCK (connection);
05733
05734 if (retval)
05735 {
05736
05737 if (old_free_func)
05738 (* old_free_func) (old_data);
05739 }
05740
05741 return retval;
05742 }
05743
05752 void*
05753 dbus_connection_get_data (DBusConnection *connection,
05754 dbus_int32_t slot)
05755 {
05756 void *res;
05757
05758 _dbus_return_val_if_fail (connection != NULL, NULL);
05759
05760 CONNECTION_LOCK (connection);
05761
05762 res = _dbus_data_slot_list_get (&slot_allocator,
05763 &connection->slot_list,
05764 slot);
05765
05766 CONNECTION_UNLOCK (connection);
05767
05768 return res;
05769 }
05770
05777 void
05778 dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
05779 {
05780 _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
05781 }
05782
05791 void
05792 dbus_connection_set_max_message_size (DBusConnection *connection,
05793 long size)
05794 {
05795 _dbus_return_if_fail (connection != NULL);
05796
05797 CONNECTION_LOCK (connection);
05798 _dbus_transport_set_max_message_size (connection->transport,
05799 size);
05800 CONNECTION_UNLOCK (connection);
05801 }
05802
05809 long
05810 dbus_connection_get_max_message_size (DBusConnection *connection)
05811 {
05812 long res;
05813
05814 _dbus_return_val_if_fail (connection != NULL, 0);
05815
05816 CONNECTION_LOCK (connection);
05817 res = _dbus_transport_get_max_message_size (connection->transport);
05818 CONNECTION_UNLOCK (connection);
05819 return res;
05820 }
05821
05847 void
05848 dbus_connection_set_max_received_size (DBusConnection *connection,
05849 long size)
05850 {
05851 _dbus_return_if_fail (connection != NULL);
05852
05853 CONNECTION_LOCK (connection);
05854 _dbus_transport_set_max_received_size (connection->transport,
05855 size);
05856 CONNECTION_UNLOCK (connection);
05857 }
05858
05865 long
05866 dbus_connection_get_max_received_size (DBusConnection *connection)
05867 {
05868 long res;
05869
05870 _dbus_return_val_if_fail (connection != NULL, 0);
05871
05872 CONNECTION_LOCK (connection);
05873 res = _dbus_transport_get_max_received_size (connection->transport);
05874 CONNECTION_UNLOCK (connection);
05875 return res;
05876 }
05877
05888 long
05889 dbus_connection_get_outgoing_size (DBusConnection *connection)
05890 {
05891 long res;
05892
05893 _dbus_return_val_if_fail (connection != NULL, 0);
05894
05895 CONNECTION_LOCK (connection);
05896 res = _dbus_counter_get_value (connection->outgoing_counter);
05897 CONNECTION_UNLOCK (connection);
05898 return res;
05899 }
05900