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 if (connection->server_guid != NULL)
01682 {
01683 _dbus_verbose ("dropping connection to %s out of the shared table\n",
01684 connection->server_guid);
01685
01686 _DBUS_LOCK (shared_connections);
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 _DBUS_UNLOCK (shared_connections);
01695 }
01696
01697
01698 _dbus_connection_unref_unlocked (connection);
01699 }
01700
01701 static DBusConnection*
01702 connection_try_from_address_entry (DBusAddressEntry *entry,
01703 DBusError *error)
01704 {
01705 DBusTransport *transport;
01706 DBusConnection *connection;
01707
01708 transport = _dbus_transport_open (entry, error);
01709
01710 if (transport == NULL)
01711 {
01712 _DBUS_ASSERT_ERROR_IS_SET (error);
01713 return NULL;
01714 }
01715
01716 connection = _dbus_connection_new_for_transport (transport);
01717
01718 _dbus_transport_unref (transport);
01719
01720 if (connection == NULL)
01721 {
01722 _DBUS_SET_OOM (error);
01723 return NULL;
01724 }
01725
01726 #ifndef DBUS_DISABLE_CHECKS
01727 _dbus_assert (!connection->have_connection_lock);
01728 #endif
01729 return connection;
01730 }
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744 static DBusConnection*
01745 _dbus_connection_open_internal (const char *address,
01746 dbus_bool_t shared,
01747 DBusError *error)
01748 {
01749 DBusConnection *connection;
01750 DBusAddressEntry **entries;
01751 DBusError tmp_error = DBUS_ERROR_INIT;
01752 DBusError first_error = DBUS_ERROR_INIT;
01753 int len, i;
01754
01755 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01756
01757 _dbus_verbose ("opening %s connection to: %s\n",
01758 shared ? "shared" : "private", address);
01759
01760 if (!dbus_parse_address (address, &entries, &len, error))
01761 return NULL;
01762
01763 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01764
01765 connection = NULL;
01766
01767 for (i = 0; i < len; i++)
01768 {
01769 if (shared)
01770 {
01771 if (!connection_lookup_shared (entries[i], &connection))
01772 _DBUS_SET_OOM (&tmp_error);
01773 }
01774
01775 if (connection == NULL)
01776 {
01777 connection = connection_try_from_address_entry (entries[i],
01778 &tmp_error);
01779
01780 if (connection != NULL && shared)
01781 {
01782 const char *guid;
01783
01784 connection->shareable = TRUE;
01785
01786
01787 guid = dbus_address_entry_get_value (entries[i], "guid");
01788
01789 CONNECTION_LOCK (connection);
01790
01791 if (!connection_record_shared_unlocked (connection, guid))
01792 {
01793 _DBUS_SET_OOM (&tmp_error);
01794 _dbus_connection_close_possibly_shared_and_unlock (connection);
01795 dbus_connection_unref (connection);
01796 connection = NULL;
01797 }
01798 else
01799 CONNECTION_UNLOCK (connection);
01800 }
01801 }
01802
01803 if (connection)
01804 break;
01805
01806 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
01807
01808 if (i == 0)
01809 dbus_move_error (&tmp_error, &first_error);
01810 else
01811 dbus_error_free (&tmp_error);
01812 }
01813
01814 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01815 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
01816
01817 if (connection == NULL)
01818 {
01819 _DBUS_ASSERT_ERROR_IS_SET (&first_error);
01820 dbus_move_error (&first_error, error);
01821 }
01822 else
01823 dbus_error_free (&first_error);
01824
01825 dbus_address_entries_free (entries);
01826 return connection;
01827 }
01828
01837 void
01838 _dbus_connection_close_possibly_shared (DBusConnection *connection)
01839 {
01840 _dbus_assert (connection != NULL);
01841 _dbus_assert (connection->generation == _dbus_current_generation);
01842
01843 CONNECTION_LOCK (connection);
01844 _dbus_connection_close_possibly_shared_and_unlock (connection);
01845 }
01846
01847 static DBusPreallocatedSend*
01848 _dbus_connection_preallocate_send_unlocked (DBusConnection *connection)
01849 {
01850 DBusPreallocatedSend *preallocated;
01851
01852 HAVE_LOCK_CHECK (connection);
01853
01854 _dbus_assert (connection != NULL);
01855
01856 preallocated = dbus_new (DBusPreallocatedSend, 1);
01857 if (preallocated == NULL)
01858 return NULL;
01859
01860 if (connection->link_cache != NULL)
01861 {
01862 preallocated->queue_link =
01863 _dbus_list_pop_first_link (&connection->link_cache);
01864 preallocated->queue_link->data = NULL;
01865 }
01866 else
01867 {
01868 preallocated->queue_link = _dbus_list_alloc_link (NULL);
01869 if (preallocated->queue_link == NULL)
01870 goto failed_0;
01871 }
01872
01873 if (connection->link_cache != NULL)
01874 {
01875 preallocated->counter_link =
01876 _dbus_list_pop_first_link (&connection->link_cache);
01877 preallocated->counter_link->data = connection->outgoing_counter;
01878 }
01879 else
01880 {
01881 preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter);
01882 if (preallocated->counter_link == NULL)
01883 goto failed_1;
01884 }
01885
01886 _dbus_counter_ref (preallocated->counter_link->data);
01887
01888 preallocated->connection = connection;
01889
01890 return preallocated;
01891
01892 failed_1:
01893 _dbus_list_free_link (preallocated->queue_link);
01894 failed_0:
01895 dbus_free (preallocated);
01896
01897 return NULL;
01898 }
01899
01900
01901 static void
01902 _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *connection,
01903 DBusPreallocatedSend *preallocated,
01904 DBusMessage *message,
01905 dbus_uint32_t *client_serial)
01906 {
01907 dbus_uint32_t serial;
01908 const char *sig;
01909
01910 preallocated->queue_link->data = message;
01911 _dbus_list_prepend_link (&connection->outgoing_messages,
01912 preallocated->queue_link);
01913
01914 _dbus_message_add_size_counter_link (message,
01915 preallocated->counter_link);
01916
01917 dbus_free (preallocated);
01918 preallocated = NULL;
01919
01920 dbus_message_ref (message);
01921
01922 connection->n_outgoing += 1;
01923
01924 sig = dbus_message_get_signature (message);
01925
01926 _dbus_verbose ("Message %p (%d %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
01927 message,
01928 dbus_message_get_type (message),
01929 dbus_message_get_path (message) ?
01930 dbus_message_get_path (message) :
01931 "no path",
01932 dbus_message_get_interface (message) ?
01933 dbus_message_get_interface (message) :
01934 "no interface",
01935 dbus_message_get_member (message) ?
01936 dbus_message_get_member (message) :
01937 "no member",
01938 sig,
01939 dbus_message_get_destination (message) ?
01940 dbus_message_get_destination (message) :
01941 "null",
01942 connection,
01943 connection->n_outgoing);
01944
01945 if (dbus_message_get_serial (message) == 0)
01946 {
01947 serial = _dbus_connection_get_next_client_serial (connection);
01948 _dbus_message_set_serial (message, serial);
01949 if (client_serial)
01950 *client_serial = serial;
01951 }
01952 else
01953 {
01954 if (client_serial)
01955 *client_serial = dbus_message_get_serial (message);
01956 }
01957
01958 _dbus_verbose ("Message %p serial is %u\n",
01959 message, dbus_message_get_serial (message));
01960
01961 _dbus_message_lock (message);
01962
01963
01964
01965
01966 _dbus_connection_do_iteration_unlocked (connection,
01967 DBUS_ITERATION_DO_WRITING,
01968 -1);
01969
01970
01971 if (connection->n_outgoing > 0)
01972 _dbus_connection_wakeup_mainloop (connection);
01973 }
01974
01975 static void
01976 _dbus_connection_send_preallocated_and_unlock (DBusConnection *connection,
01977 DBusPreallocatedSend *preallocated,
01978 DBusMessage *message,
01979 dbus_uint32_t *client_serial)
01980 {
01981 DBusDispatchStatus status;
01982
01983 HAVE_LOCK_CHECK (connection);
01984
01985 _dbus_connection_send_preallocated_unlocked_no_update (connection,
01986 preallocated,
01987 message, client_serial);
01988
01989 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
01990 status = _dbus_connection_get_dispatch_status_unlocked (connection);
01991
01992
01993 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01994 }
01995
02005 dbus_bool_t
02006 _dbus_connection_send_and_unlock (DBusConnection *connection,
02007 DBusMessage *message,
02008 dbus_uint32_t *client_serial)
02009 {
02010 DBusPreallocatedSend *preallocated;
02011
02012 _dbus_assert (connection != NULL);
02013 _dbus_assert (message != NULL);
02014
02015 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
02016 if (preallocated == NULL)
02017 {
02018 CONNECTION_UNLOCK (connection);
02019 return FALSE;
02020 }
02021
02022 _dbus_connection_send_preallocated_and_unlock (connection,
02023 preallocated,
02024 message,
02025 client_serial);
02026 return TRUE;
02027 }
02028
02053 void
02054 _dbus_connection_close_if_only_one_ref (DBusConnection *connection)
02055 {
02056 CONNECTION_LOCK (connection);
02057
02058 _dbus_assert (connection->refcount.value > 0);
02059
02060 if (connection->refcount.value == 1)
02061 _dbus_connection_close_possibly_shared_and_unlock (connection);
02062 else
02063 CONNECTION_UNLOCK (connection);
02064 }
02065
02066
02076 static void
02077 _dbus_memory_pause_based_on_timeout (int timeout_milliseconds)
02078 {
02079 if (timeout_milliseconds == -1)
02080 _dbus_sleep_milliseconds (1000);
02081 else if (timeout_milliseconds < 100)
02082 ;
02083 else if (timeout_milliseconds <= 1000)
02084 _dbus_sleep_milliseconds (timeout_milliseconds / 3);
02085 else
02086 _dbus_sleep_milliseconds (1000);
02087 }
02088
02089 static DBusMessage *
02090 generate_local_error_message (dbus_uint32_t serial,
02091 char *error_name,
02092 char *error_msg)
02093 {
02094 DBusMessage *message;
02095 message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
02096 if (!message)
02097 goto out;
02098
02099 if (!dbus_message_set_error_name (message, error_name))
02100 {
02101 dbus_message_unref (message);
02102 message = NULL;
02103 goto out;
02104 }
02105
02106 dbus_message_set_no_reply (message, TRUE);
02107
02108 if (!dbus_message_set_reply_serial (message,
02109 serial))
02110 {
02111 dbus_message_unref (message);
02112 message = NULL;
02113 goto out;
02114 }
02115
02116 if (error_msg != NULL)
02117 {
02118 DBusMessageIter iter;
02119
02120 dbus_message_iter_init_append (message, &iter);
02121 if (!dbus_message_iter_append_basic (&iter,
02122 DBUS_TYPE_STRING,
02123 &error_msg))
02124 {
02125 dbus_message_unref (message);
02126 message = NULL;
02127 goto out;
02128 }
02129 }
02130
02131 out:
02132 return message;
02133 }
02134
02135
02136
02137
02138
02139 static DBusMessage*
02140 check_for_reply_unlocked (DBusConnection *connection,
02141 dbus_uint32_t client_serial)
02142 {
02143 DBusList *link;
02144
02145 HAVE_LOCK_CHECK (connection);
02146
02147 link = _dbus_list_get_first_link (&connection->incoming_messages);
02148
02149 while (link != NULL)
02150 {
02151 DBusMessage *reply = link->data;
02152
02153 if (dbus_message_get_reply_serial (reply) == client_serial)
02154 {
02155 _dbus_list_remove_link (&connection->incoming_messages, link);
02156 connection->n_incoming -= 1;
02157 return reply;
02158 }
02159 link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02160 }
02161
02162 return NULL;
02163 }
02164
02165 static void
02166 connection_timeout_and_complete_all_pending_calls_unlocked (DBusConnection *connection)
02167 {
02168
02169
02170
02171
02172
02173 while (_dbus_hash_table_get_n_entries (connection->pending_replies) > 0)
02174 {
02175 DBusPendingCall *pending;
02176 DBusHashIter iter;
02177
02178 _dbus_hash_iter_init (connection->pending_replies, &iter);
02179 _dbus_hash_iter_next (&iter);
02180
02181 pending = _dbus_hash_iter_get_value (&iter);
02182 _dbus_pending_call_ref_unlocked (pending);
02183
02184 _dbus_pending_call_queue_timeout_error_unlocked (pending,
02185 connection);
02186 _dbus_connection_remove_timeout_unlocked (connection,
02187 _dbus_pending_call_get_timeout_unlocked (pending));
02188 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
02189 _dbus_hash_iter_remove_entry (&iter);
02190
02191 _dbus_pending_call_unref_and_unlock (pending);
02192 CONNECTION_LOCK (connection);
02193 }
02194 HAVE_LOCK_CHECK (connection);
02195 }
02196
02197 static void
02198 complete_pending_call_and_unlock (DBusConnection *connection,
02199 DBusPendingCall *pending,
02200 DBusMessage *message)
02201 {
02202 _dbus_pending_call_set_reply_unlocked (pending, message);
02203 _dbus_pending_call_ref_unlocked (pending);
02204 _dbus_connection_detach_pending_call_and_unlock (connection, pending);
02205
02206
02207 _dbus_pending_call_complete (pending);
02208 dbus_pending_call_unref (pending);
02209 }
02210
02211 static dbus_bool_t
02212 check_for_reply_and_update_dispatch_unlocked (DBusConnection *connection,
02213 DBusPendingCall *pending)
02214 {
02215 DBusMessage *reply;
02216 DBusDispatchStatus status;
02217
02218 reply = check_for_reply_unlocked (connection,
02219 _dbus_pending_call_get_reply_serial_unlocked (pending));
02220 if (reply != NULL)
02221 {
02222 _dbus_verbose ("%s checked for reply\n", _DBUS_FUNCTION_NAME);
02223
02224 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
02225
02226 complete_pending_call_and_unlock (connection, pending, reply);
02227 dbus_message_unref (reply);
02228
02229 CONNECTION_LOCK (connection);
02230 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02231 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02232 dbus_pending_call_unref (pending);
02233
02234 return TRUE;
02235 }
02236
02237 return FALSE;
02238 }
02239
02254 void
02255 _dbus_connection_block_pending_call (DBusPendingCall *pending)
02256 {
02257 long start_tv_sec, start_tv_usec;
02258 long end_tv_sec, end_tv_usec;
02259 long tv_sec, tv_usec;
02260 DBusDispatchStatus status;
02261 DBusConnection *connection;
02262 dbus_uint32_t client_serial;
02263 int timeout_milliseconds;
02264
02265 _dbus_assert (pending != NULL);
02266
02267 if (dbus_pending_call_get_completed (pending))
02268 return;
02269
02270 dbus_pending_call_ref (pending);
02271
02272 connection = _dbus_pending_call_get_connection_and_lock (pending);
02273
02274
02275 _dbus_connection_flush_unlocked (connection);
02276
02277 client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
02278
02279
02280
02281
02282
02283 timeout_milliseconds = dbus_timeout_get_interval (_dbus_pending_call_get_timeout_unlocked (pending));
02284
02285 _dbus_get_current_time (&start_tv_sec, &start_tv_usec);
02286 end_tv_sec = start_tv_sec + timeout_milliseconds / 1000;
02287 end_tv_usec = start_tv_usec + (timeout_milliseconds % 1000) * 1000;
02288 end_tv_sec += end_tv_usec / _DBUS_USEC_PER_SECOND;
02289 end_tv_usec = end_tv_usec % _DBUS_USEC_PER_SECOND;
02290
02291 _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",
02292 timeout_milliseconds,
02293 client_serial,
02294 start_tv_sec, start_tv_usec,
02295 end_tv_sec, end_tv_usec);
02296
02297
02298
02299 if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02300 return;
02301
02302
02303
02304 _dbus_connection_do_iteration_unlocked (connection,
02305 DBUS_ITERATION_DO_READING |
02306 DBUS_ITERATION_BLOCK,
02307 timeout_milliseconds);
02308
02309 recheck_status:
02310
02311 _dbus_verbose ("%s top of recheck\n", _DBUS_FUNCTION_NAME);
02312
02313 HAVE_LOCK_CHECK (connection);
02314
02315
02316
02317 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02318
02319
02320
02321
02322 if (_dbus_pending_call_get_completed_unlocked (pending))
02323 {
02324 _dbus_verbose ("Pending call completed by dispatch in %s\n", _DBUS_FUNCTION_NAME);
02325 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02326 dbus_pending_call_unref (pending);
02327 return;
02328 }
02329
02330 if (status == DBUS_DISPATCH_DATA_REMAINS)
02331 {
02332 if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02333 return;
02334 }
02335
02336 _dbus_get_current_time (&tv_sec, &tv_usec);
02337
02338 if (!_dbus_connection_get_is_connected_unlocked (connection))
02339 {
02340 DBusMessage *error_msg;
02341
02342 error_msg = generate_local_error_message (client_serial,
02343 DBUS_ERROR_DISCONNECTED,
02344 "Connection was disconnected before a reply was received");
02345
02346
02347 complete_pending_call_and_unlock (connection, pending, error_msg);
02348 dbus_pending_call_unref (pending);
02349 return;
02350 }
02351 else if (tv_sec < start_tv_sec)
02352 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
02353 else if (connection->disconnect_message_link == NULL)
02354 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
02355 else if (tv_sec < end_tv_sec ||
02356 (tv_sec == end_tv_sec && tv_usec < end_tv_usec))
02357 {
02358 timeout_milliseconds = (end_tv_sec - tv_sec) * 1000 +
02359 (end_tv_usec - tv_usec) / 1000;
02360 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds);
02361 _dbus_assert (timeout_milliseconds >= 0);
02362
02363 if (status == DBUS_DISPATCH_NEED_MEMORY)
02364 {
02365
02366
02367
02368
02369 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02370
02371 _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
02372 }
02373 else
02374 {
02375
02376 _dbus_connection_do_iteration_unlocked (connection,
02377 DBUS_ITERATION_DO_READING |
02378 DBUS_ITERATION_BLOCK,
02379 timeout_milliseconds);
02380 }
02381
02382 goto recheck_status;
02383 }
02384
02385 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %ld milliseconds and got no reply\n",
02386 (tv_sec - start_tv_sec) * 1000 + (tv_usec - start_tv_usec) / 1000);
02387
02388 _dbus_assert (!_dbus_pending_call_get_completed_unlocked (pending));
02389
02390
02391 complete_pending_call_and_unlock (connection, pending, NULL);
02392
02393
02394 CONNECTION_LOCK (connection);
02395 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02396 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02397 dbus_pending_call_unref (pending);
02398 }
02399
02436 DBusConnection*
02437 dbus_connection_open (const char *address,
02438 DBusError *error)
02439 {
02440 DBusConnection *connection;
02441
02442 _dbus_return_val_if_fail (address != NULL, NULL);
02443 _dbus_return_val_if_error_is_set (error, NULL);
02444
02445 connection = _dbus_connection_open_internal (address,
02446 TRUE,
02447 error);
02448
02449 return connection;
02450 }
02451
02479 DBusConnection*
02480 dbus_connection_open_private (const char *address,
02481 DBusError *error)
02482 {
02483 DBusConnection *connection;
02484
02485 _dbus_return_val_if_fail (address != NULL, NULL);
02486 _dbus_return_val_if_error_is_set (error, NULL);
02487
02488 connection = _dbus_connection_open_internal (address,
02489 FALSE,
02490 error);
02491
02492 return connection;
02493 }
02494
02501 DBusConnection *
02502 dbus_connection_ref (DBusConnection *connection)
02503 {
02504 _dbus_return_val_if_fail (connection != NULL, NULL);
02505 _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
02506
02507
02508
02509
02510
02511 #ifdef DBUS_HAVE_ATOMIC_INT
02512 _dbus_atomic_inc (&connection->refcount);
02513 #else
02514 CONNECTION_LOCK (connection);
02515 _dbus_assert (connection->refcount.value > 0);
02516
02517 connection->refcount.value += 1;
02518 CONNECTION_UNLOCK (connection);
02519 #endif
02520
02521 return connection;
02522 }
02523
02524 static void
02525 free_outgoing_message (void *element,
02526 void *data)
02527 {
02528 DBusMessage *message = element;
02529 DBusConnection *connection = data;
02530
02531 _dbus_message_remove_size_counter (message,
02532 connection->outgoing_counter,
02533 NULL);
02534 dbus_message_unref (message);
02535 }
02536
02537
02538
02539
02540
02541 static void
02542 _dbus_connection_last_unref (DBusConnection *connection)
02543 {
02544 DBusList *link;
02545
02546 _dbus_verbose ("Finalizing connection %p\n", connection);
02547
02548 _dbus_assert (connection->refcount.value == 0);
02549
02550
02551
02552
02553 _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
02554 _dbus_assert (connection->server_guid == NULL);
02555
02556
02557 _dbus_object_tree_free_all_unlocked (connection->objects);
02558
02559 dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
02560 dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
02561 dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
02562
02563 _dbus_watch_list_free (connection->watches);
02564 connection->watches = NULL;
02565
02566 _dbus_timeout_list_free (connection->timeouts);
02567 connection->timeouts = NULL;
02568
02569 _dbus_data_slot_list_free (&connection->slot_list);
02570
02571 link = _dbus_list_get_first_link (&connection->filter_list);
02572 while (link != NULL)
02573 {
02574 DBusMessageFilter *filter = link->data;
02575 DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
02576
02577 filter->function = NULL;
02578 _dbus_message_filter_unref (filter);
02579 link->data = NULL;
02580
02581 link = next;
02582 }
02583 _dbus_list_clear (&connection->filter_list);
02584
02585
02586
02587 _dbus_object_tree_unref (connection->objects);
02588
02589 _dbus_hash_table_unref (connection->pending_replies);
02590 connection->pending_replies = NULL;
02591
02592 _dbus_list_clear (&connection->filter_list);
02593
02594 _dbus_list_foreach (&connection->outgoing_messages,
02595 free_outgoing_message,
02596 connection);
02597 _dbus_list_clear (&connection->outgoing_messages);
02598
02599 _dbus_list_foreach (&connection->incoming_messages,
02600 (DBusForeachFunction) dbus_message_unref,
02601 NULL);
02602 _dbus_list_clear (&connection->incoming_messages);
02603
02604 _dbus_counter_unref (connection->outgoing_counter);
02605
02606 _dbus_transport_unref (connection->transport);
02607
02608 if (connection->disconnect_message_link)
02609 {
02610 DBusMessage *message = connection->disconnect_message_link->data;
02611 dbus_message_unref (message);
02612 _dbus_list_free_link (connection->disconnect_message_link);
02613 }
02614
02615 _dbus_list_clear (&connection->link_cache);
02616
02617 _dbus_condvar_free_at_location (&connection->dispatch_cond);
02618 _dbus_condvar_free_at_location (&connection->io_path_cond);
02619
02620 _dbus_mutex_free_at_location (&connection->io_path_mutex);
02621 _dbus_mutex_free_at_location (&connection->dispatch_mutex);
02622
02623 _dbus_mutex_free_at_location (&connection->mutex);
02624
02625 dbus_free (connection);
02626 }
02627
02647 void
02648 dbus_connection_unref (DBusConnection *connection)
02649 {
02650 dbus_bool_t last_unref;
02651
02652 _dbus_return_if_fail (connection != NULL);
02653 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02654
02655
02656
02657
02658
02659 #ifdef DBUS_HAVE_ATOMIC_INT
02660 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
02661 #else
02662 CONNECTION_LOCK (connection);
02663
02664 _dbus_assert (connection->refcount.value > 0);
02665
02666 connection->refcount.value -= 1;
02667 last_unref = (connection->refcount.value == 0);
02668
02669 #if 0
02670 printf ("unref() connection %p count = %d\n", connection, connection->refcount.value);
02671 #endif
02672
02673 CONNECTION_UNLOCK (connection);
02674 #endif
02675
02676 if (last_unref)
02677 {
02678 #ifndef DBUS_DISABLE_CHECKS
02679 if (_dbus_transport_get_is_connected (connection->transport))
02680 {
02681 _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",
02682 connection->shareable ?
02683 "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" :
02684 "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n");
02685 return;
02686 }
02687 #endif
02688 _dbus_connection_last_unref (connection);
02689 }
02690 }
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701 static void
02702 _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection)
02703 {
02704 DBusDispatchStatus status;
02705
02706 HAVE_LOCK_CHECK (connection);
02707
02708 _dbus_verbose ("Disconnecting %p\n", connection);
02709
02710
02711
02712
02713
02714 _dbus_connection_ref_unlocked (connection);
02715
02716 _dbus_transport_disconnect (connection->transport);
02717
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02728
02729
02730 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02731
02732
02733 dbus_connection_unref (connection);
02734 }
02735
02778 void
02779 dbus_connection_close (DBusConnection *connection)
02780 {
02781 _dbus_return_if_fail (connection != NULL);
02782 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02783
02784 CONNECTION_LOCK (connection);
02785
02786 #ifndef DBUS_DISABLE_CHECKS
02787 if (connection->shareable)
02788 {
02789 CONNECTION_UNLOCK (connection);
02790
02791 _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n");
02792 return;
02793 }
02794 #endif
02795
02796 _dbus_connection_close_possibly_shared_and_unlock (connection);
02797 }
02798
02799 static dbus_bool_t
02800 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
02801 {
02802 HAVE_LOCK_CHECK (connection);
02803 return _dbus_transport_get_is_connected (connection->transport);
02804 }
02805
02819 dbus_bool_t
02820 dbus_connection_get_is_connected (DBusConnection *connection)
02821 {
02822 dbus_bool_t res;
02823
02824 _dbus_return_val_if_fail (connection != NULL, FALSE);
02825
02826 CONNECTION_LOCK (connection);
02827 res = _dbus_connection_get_is_connected_unlocked (connection);
02828 CONNECTION_UNLOCK (connection);
02829
02830 return res;
02831 }
02832
02841 dbus_bool_t
02842 dbus_connection_get_is_authenticated (DBusConnection *connection)
02843 {
02844 dbus_bool_t res;
02845
02846 _dbus_return_val_if_fail (connection != NULL, FALSE);
02847
02848 CONNECTION_LOCK (connection);
02849 res = _dbus_transport_get_is_authenticated (connection->transport);
02850 CONNECTION_UNLOCK (connection);
02851
02852 return res;
02853 }
02854
02875 dbus_bool_t
02876 dbus_connection_get_is_anonymous (DBusConnection *connection)
02877 {
02878 dbus_bool_t res;
02879
02880 _dbus_return_val_if_fail (connection != NULL, FALSE);
02881
02882 CONNECTION_LOCK (connection);
02883 res = _dbus_transport_get_is_anonymous (connection->transport);
02884 CONNECTION_UNLOCK (connection);
02885
02886 return res;
02887 }
02888
02920 char*
02921 dbus_connection_get_server_id (DBusConnection *connection)
02922 {
02923 char *id;
02924
02925 _dbus_return_val_if_fail (connection != NULL, FALSE);
02926
02927 CONNECTION_LOCK (connection);
02928 id = _dbus_strdup (_dbus_transport_get_server_id (connection->transport));
02929 CONNECTION_UNLOCK (connection);
02930
02931 return id;
02932 }
02933
02947 void
02948 dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
02949 dbus_bool_t exit_on_disconnect)
02950 {
02951 _dbus_return_if_fail (connection != NULL);
02952
02953 CONNECTION_LOCK (connection);
02954 connection->exit_on_disconnect = exit_on_disconnect != FALSE;
02955 CONNECTION_UNLOCK (connection);
02956 }
02957
02967 DBusPreallocatedSend*
02968 dbus_connection_preallocate_send (DBusConnection *connection)
02969 {
02970 DBusPreallocatedSend *preallocated;
02971
02972 _dbus_return_val_if_fail (connection != NULL, NULL);
02973
02974 CONNECTION_LOCK (connection);
02975
02976 preallocated =
02977 _dbus_connection_preallocate_send_unlocked (connection);
02978
02979 CONNECTION_UNLOCK (connection);
02980
02981 return preallocated;
02982 }
02983
02993 void
02994 dbus_connection_free_preallocated_send (DBusConnection *connection,
02995 DBusPreallocatedSend *preallocated)
02996 {
02997 _dbus_return_if_fail (connection != NULL);
02998 _dbus_return_if_fail (preallocated != NULL);
02999 _dbus_return_if_fail (connection == preallocated->connection);
03000
03001 _dbus_list_free_link (preallocated->queue_link);
03002 _dbus_counter_unref (preallocated->counter_link->data);
03003 _dbus_list_free_link (preallocated->counter_link);
03004 dbus_free (preallocated);
03005 }
03006
03019 void
03020 dbus_connection_send_preallocated (DBusConnection *connection,
03021 DBusPreallocatedSend *preallocated,
03022 DBusMessage *message,
03023 dbus_uint32_t *client_serial)
03024 {
03025 _dbus_return_if_fail (connection != NULL);
03026 _dbus_return_if_fail (preallocated != NULL);
03027 _dbus_return_if_fail (message != NULL);
03028 _dbus_return_if_fail (preallocated->connection == connection);
03029 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
03030 dbus_message_get_member (message) != NULL);
03031 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
03032 (dbus_message_get_interface (message) != NULL &&
03033 dbus_message_get_member (message) != NULL));
03034
03035 CONNECTION_LOCK (connection);
03036 _dbus_connection_send_preallocated_and_unlock (connection,
03037 preallocated,
03038 message, client_serial);
03039 }
03040
03041 static dbus_bool_t
03042 _dbus_connection_send_unlocked_no_update (DBusConnection *connection,
03043 DBusMessage *message,
03044 dbus_uint32_t *client_serial)
03045 {
03046 DBusPreallocatedSend *preallocated;
03047
03048 _dbus_assert (connection != NULL);
03049 _dbus_assert (message != NULL);
03050
03051 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
03052 if (preallocated == NULL)
03053 return FALSE;
03054
03055 _dbus_connection_send_preallocated_unlocked_no_update (connection,
03056 preallocated,
03057 message,
03058 client_serial);
03059 return TRUE;
03060 }
03061
03089 dbus_bool_t
03090 dbus_connection_send (DBusConnection *connection,
03091 DBusMessage *message,
03092 dbus_uint32_t *serial)
03093 {
03094 _dbus_return_val_if_fail (connection != NULL, FALSE);
03095 _dbus_return_val_if_fail (message != NULL, FALSE);
03096
03097 CONNECTION_LOCK (connection);
03098
03099 return _dbus_connection_send_and_unlock (connection,
03100 message,
03101 serial);
03102 }
03103
03104 static dbus_bool_t
03105 reply_handler_timeout (void *data)
03106 {
03107 DBusConnection *connection;
03108 DBusDispatchStatus status;
03109 DBusPendingCall *pending = data;
03110
03111 connection = _dbus_pending_call_get_connection_and_lock (pending);
03112
03113 _dbus_pending_call_queue_timeout_error_unlocked (pending,
03114 connection);
03115 _dbus_connection_remove_timeout_unlocked (connection,
03116 _dbus_pending_call_get_timeout_unlocked (pending));
03117 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
03118
03119 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
03120 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03121
03122
03123 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03124
03125 return TRUE;
03126 }
03127
03165 dbus_bool_t
03166 dbus_connection_send_with_reply (DBusConnection *connection,
03167 DBusMessage *message,
03168 DBusPendingCall **pending_return,
03169 int timeout_milliseconds)
03170 {
03171 DBusPendingCall *pending;
03172 dbus_int32_t serial = -1;
03173 DBusDispatchStatus status;
03174
03175 _dbus_return_val_if_fail (connection != NULL, FALSE);
03176 _dbus_return_val_if_fail (message != NULL, FALSE);
03177 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03178
03179 if (pending_return)
03180 *pending_return = NULL;
03181
03182 CONNECTION_LOCK (connection);
03183
03184 if (!_dbus_connection_get_is_connected_unlocked (connection))
03185 {
03186 CONNECTION_UNLOCK (connection);
03187
03188 return TRUE;
03189 }
03190
03191 pending = _dbus_pending_call_new_unlocked (connection,
03192 timeout_milliseconds,
03193 reply_handler_timeout);
03194
03195 if (pending == NULL)
03196 {
03197 CONNECTION_UNLOCK (connection);
03198 return FALSE;
03199 }
03200
03201
03202 serial = dbus_message_get_serial (message);
03203 if (serial == 0)
03204 {
03205 serial = _dbus_connection_get_next_client_serial (connection);
03206 _dbus_message_set_serial (message, serial);
03207 }
03208
03209 if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
03210 goto error;
03211
03212
03213
03214
03215
03216 if (!_dbus_connection_attach_pending_call_unlocked (connection,
03217 pending))
03218 goto error;
03219
03220 if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
03221 {
03222 _dbus_connection_detach_pending_call_and_unlock (connection,
03223 pending);
03224 goto error_unlocked;
03225 }
03226
03227 if (pending_return)
03228 *pending_return = pending;
03229 else
03230 {
03231 _dbus_connection_detach_pending_call_unlocked (connection, pending);
03232
03233
03234
03235 }
03236
03237 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03238
03239
03240 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03241
03242 if (pending_return == NULL)
03243 dbus_pending_call_unref (pending);
03244
03245 return TRUE;
03246
03247 error:
03248 CONNECTION_UNLOCK (connection);
03249 error_unlocked:
03250 dbus_pending_call_unref (pending);
03251 return FALSE;
03252 }
03253
03284 DBusMessage*
03285 dbus_connection_send_with_reply_and_block (DBusConnection *connection,
03286 DBusMessage *message,
03287 int timeout_milliseconds,
03288 DBusError *error)
03289 {
03290 DBusMessage *reply;
03291 DBusPendingCall *pending;
03292
03293 _dbus_return_val_if_fail (connection != NULL, NULL);
03294 _dbus_return_val_if_fail (message != NULL, NULL);
03295 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL);
03296 _dbus_return_val_if_error_is_set (error, NULL);
03297
03298 if (!dbus_connection_send_with_reply (connection, message,
03299 &pending, timeout_milliseconds))
03300 {
03301 _DBUS_SET_OOM (error);
03302 return NULL;
03303 }
03304
03305 if (pending == NULL)
03306 {
03307 dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Connection is closed");
03308 return NULL;
03309 }
03310
03311 dbus_pending_call_block (pending);
03312
03313 reply = dbus_pending_call_steal_reply (pending);
03314 dbus_pending_call_unref (pending);
03315
03316
03317
03318
03319 _dbus_assert (reply != NULL);
03320
03321 if (dbus_set_error_from_message (error, reply))
03322 {
03323 dbus_message_unref (reply);
03324 return NULL;
03325 }
03326 else
03327 return reply;
03328 }
03329
03338 DBusDispatchStatus
03339 _dbus_connection_flush_unlocked (DBusConnection *connection)
03340 {
03341
03342
03343
03344
03345
03346 DBusDispatchStatus status;
03347
03348 HAVE_LOCK_CHECK (connection);
03349
03350 while (connection->n_outgoing > 0 &&
03351 _dbus_connection_get_is_connected_unlocked (connection))
03352 {
03353 _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME);
03354 HAVE_LOCK_CHECK (connection);
03355 _dbus_connection_do_iteration_unlocked (connection,
03356 DBUS_ITERATION_DO_READING |
03357 DBUS_ITERATION_DO_WRITING |
03358 DBUS_ITERATION_BLOCK,
03359 -1);
03360 }
03361
03362 HAVE_LOCK_CHECK (connection);
03363 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
03364 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03365
03366 HAVE_LOCK_CHECK (connection);
03367 return status;
03368 }
03369
03375 void
03376 dbus_connection_flush (DBusConnection *connection)
03377 {
03378
03379
03380
03381
03382
03383 DBusDispatchStatus status;
03384
03385 _dbus_return_if_fail (connection != NULL);
03386
03387 CONNECTION_LOCK (connection);
03388
03389 status = _dbus_connection_flush_unlocked (connection);
03390
03391 HAVE_LOCK_CHECK (connection);
03392
03393 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03394
03395 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
03396 }
03397
03408 static dbus_bool_t
03409 _dbus_connection_read_write_dispatch (DBusConnection *connection,
03410 int timeout_milliseconds,
03411 dbus_bool_t dispatch)
03412 {
03413 DBusDispatchStatus dstatus;
03414 dbus_bool_t no_progress_possible;
03415 dbus_bool_t progress_possible;
03416
03417 dstatus = dbus_connection_get_dispatch_status (connection);
03418
03419 if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
03420 {
03421 _dbus_verbose ("doing dispatch in %s\n", _DBUS_FUNCTION_NAME);
03422 dbus_connection_dispatch (connection);
03423 CONNECTION_LOCK (connection);
03424 }
03425 else if (dstatus == DBUS_DISPATCH_NEED_MEMORY)
03426 {
03427 _dbus_verbose ("pausing for memory in %s\n", _DBUS_FUNCTION_NAME);
03428 _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
03429 CONNECTION_LOCK (connection);
03430 }
03431 else
03432 {
03433 CONNECTION_LOCK (connection);
03434 if (_dbus_connection_get_is_connected_unlocked (connection))
03435 {
03436 _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME);
03437 _dbus_connection_do_iteration_unlocked (connection,
03438 DBUS_ITERATION_DO_READING |
03439 DBUS_ITERATION_DO_WRITING |
03440 DBUS_ITERATION_BLOCK,
03441 timeout_milliseconds);
03442 }
03443 }
03444
03445 HAVE_LOCK_CHECK (connection);
03446
03447
03448
03449
03450 if (dispatch)
03451 progress_possible = connection->n_incoming != 0 ||
03452 connection->disconnect_message_link != NULL;
03453 else
03454 progress_possible = _dbus_connection_get_is_connected_unlocked (connection);
03455
03456 CONNECTION_UNLOCK (connection);
03457 return progress_possible;
03458 }
03459
03460
03495 dbus_bool_t
03496 dbus_connection_read_write_dispatch (DBusConnection *connection,
03497 int timeout_milliseconds)
03498 {
03499 _dbus_return_val_if_fail (connection != NULL, FALSE);
03500 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03501 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE);
03502 }
03503
03527 dbus_bool_t
03528 dbus_connection_read_write (DBusConnection *connection,
03529 int timeout_milliseconds)
03530 {
03531 _dbus_return_val_if_fail (connection != NULL, FALSE);
03532 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03533 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE);
03534 }
03535
03536
03537
03538
03539
03540
03541 static void
03542 check_disconnected_message_arrived_unlocked (DBusConnection *connection,
03543 DBusMessage *head_of_queue)
03544 {
03545 HAVE_LOCK_CHECK (connection);
03546
03547
03548 if (connection->disconnect_message_link == NULL &&
03549 dbus_message_is_signal (head_of_queue,
03550 DBUS_INTERFACE_LOCAL,
03551 "Disconnected"))
03552 {
03553 connection->disconnected_message_arrived = TRUE;
03554 }
03555 }
03556
03576 DBusMessage*
03577 dbus_connection_borrow_message (DBusConnection *connection)
03578 {
03579 DBusDispatchStatus status;
03580 DBusMessage *message;
03581
03582 _dbus_return_val_if_fail (connection != NULL, NULL);
03583
03584 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
03585
03586
03587
03588
03589 status = dbus_connection_get_dispatch_status (connection);
03590 if (status != DBUS_DISPATCH_DATA_REMAINS)
03591 return NULL;
03592
03593 CONNECTION_LOCK (connection);
03594
03595 _dbus_connection_acquire_dispatch (connection);
03596
03597
03598 _dbus_assert (connection->message_borrowed == NULL);
03599
03600 connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
03601
03602 message = connection->message_borrowed;
03603
03604 check_disconnected_message_arrived_unlocked (connection, message);
03605
03606
03607 if (message == NULL)
03608 _dbus_connection_release_dispatch (connection);
03609
03610 CONNECTION_UNLOCK (connection);
03611
03612
03613
03614 return message;
03615 }
03616
03625 void
03626 dbus_connection_return_message (DBusConnection *connection,
03627 DBusMessage *message)
03628 {
03629 DBusDispatchStatus status;
03630
03631 _dbus_return_if_fail (connection != NULL);
03632 _dbus_return_if_fail (message != NULL);
03633 _dbus_return_if_fail (message == connection->message_borrowed);
03634 _dbus_return_if_fail (connection->dispatch_acquired);
03635
03636 CONNECTION_LOCK (connection);
03637
03638 _dbus_assert (message == connection->message_borrowed);
03639
03640 connection->message_borrowed = NULL;
03641
03642 _dbus_connection_release_dispatch (connection);
03643
03644 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03645 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03646 }
03647
03657 void
03658 dbus_connection_steal_borrowed_message (DBusConnection *connection,
03659 DBusMessage *message)
03660 {
03661 DBusMessage *pop_message;
03662 DBusDispatchStatus status;
03663
03664 _dbus_return_if_fail (connection != NULL);
03665 _dbus_return_if_fail (message != NULL);
03666 _dbus_return_if_fail (message == connection->message_borrowed);
03667 _dbus_return_if_fail (connection->dispatch_acquired);
03668
03669 CONNECTION_LOCK (connection);
03670
03671 _dbus_assert (message == connection->message_borrowed);
03672
03673 pop_message = _dbus_list_pop_first (&connection->incoming_messages);
03674 _dbus_assert (message == pop_message);
03675
03676 connection->n_incoming -= 1;
03677
03678 _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
03679 message, connection->n_incoming);
03680
03681 connection->message_borrowed = NULL;
03682
03683 _dbus_connection_release_dispatch (connection);
03684
03685 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03686 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03687 }
03688
03689
03690
03691
03692 static DBusList*
03693 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
03694 {
03695 HAVE_LOCK_CHECK (connection);
03696
03697 _dbus_assert (connection->message_borrowed == NULL);
03698
03699 if (connection->n_incoming > 0)
03700 {
03701 DBusList *link;
03702
03703 link = _dbus_list_pop_first_link (&connection->incoming_messages);
03704 connection->n_incoming -= 1;
03705
03706 _dbus_verbose ("Message %p (%d %s %s %s '%s') removed from incoming queue %p, %d incoming\n",
03707 link->data,
03708 dbus_message_get_type (link->data),
03709 dbus_message_get_path (link->data) ?
03710 dbus_message_get_path (link->data) :
03711 "no path",
03712 dbus_message_get_interface (link->data) ?
03713 dbus_message_get_interface (link->data) :
03714 "no interface",
03715 dbus_message_get_member (link->data) ?
03716 dbus_message_get_member (link->data) :
03717 "no member",
03718 dbus_message_get_signature (link->data),
03719 connection, connection->n_incoming);
03720
03721 check_disconnected_message_arrived_unlocked (connection, link->data);
03722
03723 return link;
03724 }
03725 else
03726 return NULL;
03727 }
03728
03729
03730
03731
03732 static DBusMessage*
03733 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
03734 {
03735 DBusList *link;
03736
03737 HAVE_LOCK_CHECK (connection);
03738
03739 link = _dbus_connection_pop_message_link_unlocked (connection);
03740
03741 if (link != NULL)
03742 {
03743 DBusMessage *message;
03744
03745 message = link->data;
03746
03747 _dbus_list_free_link (link);
03748
03749 return message;
03750 }
03751 else
03752 return NULL;
03753 }
03754
03755 static void
03756 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
03757 DBusList *message_link)
03758 {
03759 HAVE_LOCK_CHECK (connection);
03760
03761 _dbus_assert (message_link != NULL);
03762
03763 _dbus_assert (connection->message_borrowed == NULL);
03764
03765 _dbus_assert (connection->dispatch_acquired);
03766
03767 _dbus_list_prepend_link (&connection->incoming_messages,
03768 message_link);
03769 connection->n_incoming += 1;
03770
03771 _dbus_verbose ("Message %p (%d %s %s '%s') put back into queue %p, %d incoming\n",
03772 message_link->data,
03773 dbus_message_get_type (message_link->data),
03774 dbus_message_get_interface (message_link->data) ?
03775 dbus_message_get_interface (message_link->data) :
03776 "no interface",
03777 dbus_message_get_member (message_link->data) ?
03778 dbus_message_get_member (message_link->data) :
03779 "no member",
03780 dbus_message_get_signature (message_link->data),
03781 connection, connection->n_incoming);
03782 }
03783
03803 DBusMessage*
03804 dbus_connection_pop_message (DBusConnection *connection)
03805 {
03806 DBusMessage *message;
03807 DBusDispatchStatus status;
03808
03809 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
03810
03811
03812
03813
03814 status = dbus_connection_get_dispatch_status (connection);
03815 if (status != DBUS_DISPATCH_DATA_REMAINS)
03816 return NULL;
03817
03818 CONNECTION_LOCK (connection);
03819 _dbus_connection_acquire_dispatch (connection);
03820 HAVE_LOCK_CHECK (connection);
03821
03822 message = _dbus_connection_pop_message_unlocked (connection);
03823
03824 _dbus_verbose ("Returning popped message %p\n", message);
03825
03826 _dbus_connection_release_dispatch (connection);
03827
03828 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03829 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03830
03831 return message;
03832 }
03833
03841 static void
03842 _dbus_connection_acquire_dispatch (DBusConnection *connection)
03843 {
03844 HAVE_LOCK_CHECK (connection);
03845
03846 _dbus_connection_ref_unlocked (connection);
03847 CONNECTION_UNLOCK (connection);
03848
03849 _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03850 _dbus_mutex_lock (connection->dispatch_mutex);
03851
03852 while (connection->dispatch_acquired)
03853 {
03854 _dbus_verbose ("%s waiting for dispatch to be acquirable\n", _DBUS_FUNCTION_NAME);
03855 _dbus_condvar_wait (connection->dispatch_cond,
03856 connection->dispatch_mutex);
03857 }
03858
03859 _dbus_assert (!connection->dispatch_acquired);
03860
03861 connection->dispatch_acquired = TRUE;
03862
03863 _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03864 _dbus_mutex_unlock (connection->dispatch_mutex);
03865
03866 CONNECTION_LOCK (connection);
03867 _dbus_connection_unref_unlocked (connection);
03868 }
03869
03877 static void
03878 _dbus_connection_release_dispatch (DBusConnection *connection)
03879 {
03880 HAVE_LOCK_CHECK (connection);
03881
03882 _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03883 _dbus_mutex_lock (connection->dispatch_mutex);
03884
03885 _dbus_assert (connection->dispatch_acquired);
03886
03887 connection->dispatch_acquired = FALSE;
03888 _dbus_condvar_wake_one (connection->dispatch_cond);
03889
03890 _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03891 _dbus_mutex_unlock (connection->dispatch_mutex);
03892 }
03893
03894 static void
03895 _dbus_connection_failed_pop (DBusConnection *connection,
03896 DBusList *message_link)
03897 {
03898 _dbus_list_prepend_link (&connection->incoming_messages,
03899 message_link);
03900 connection->n_incoming += 1;
03901 }
03902
03903
03904 static void
03905 notify_disconnected_unlocked (DBusConnection *connection)
03906 {
03907 HAVE_LOCK_CHECK (connection);
03908
03909
03910
03911
03912
03913
03914
03915 _dbus_bus_notify_shared_connection_disconnected_unlocked (connection);
03916
03917
03918
03919
03920
03921 if (connection->n_outgoing > 0)
03922 {
03923 DBusList *link;
03924
03925 _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
03926 connection->n_outgoing);
03927
03928 while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
03929 {
03930 _dbus_connection_message_sent (connection, link->data);
03931 }
03932 }
03933 }
03934
03935
03936 static DBusDispatchStatus
03937 notify_disconnected_and_dispatch_complete_unlocked (DBusConnection *connection)
03938 {
03939 HAVE_LOCK_CHECK (connection);
03940
03941 if (connection->disconnect_message_link != NULL)
03942 {
03943 _dbus_verbose ("Sending disconnect message from %s\n",
03944 _DBUS_FUNCTION_NAME);
03945
03946
03947
03948
03949 connection_timeout_and_complete_all_pending_calls_unlocked (connection);
03950
03951
03952
03953
03954 _dbus_connection_queue_synthesized_message_link (connection,
03955 connection->disconnect_message_link);
03956 connection->disconnect_message_link = NULL;
03957
03958 return DBUS_DISPATCH_DATA_REMAINS;
03959 }
03960
03961 return DBUS_DISPATCH_COMPLETE;
03962 }
03963
03964 static DBusDispatchStatus
03965 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
03966 {
03967 HAVE_LOCK_CHECK (connection);
03968
03969 if (connection->n_incoming > 0)
03970 return DBUS_DISPATCH_DATA_REMAINS;
03971 else if (!_dbus_transport_queue_messages (connection->transport))
03972 return DBUS_DISPATCH_NEED_MEMORY;
03973 else
03974 {
03975 DBusDispatchStatus status;
03976 dbus_bool_t is_connected;
03977
03978 status = _dbus_transport_get_dispatch_status (connection->transport);
03979 is_connected = _dbus_transport_get_is_connected (connection->transport);
03980
03981 _dbus_verbose ("dispatch status = %s is_connected = %d\n",
03982 DISPATCH_STATUS_NAME (status), is_connected);
03983
03984 if (!is_connected)
03985 {
03986
03987
03988
03989
03990
03991
03992 notify_disconnected_unlocked (connection);
03993
03994
03995
03996
03997
03998
03999 if (status == DBUS_DISPATCH_COMPLETE)
04000 status = notify_disconnected_and_dispatch_complete_unlocked (connection);
04001 }
04002
04003 if (status != DBUS_DISPATCH_COMPLETE)
04004 return status;
04005 else if (connection->n_incoming > 0)
04006 return DBUS_DISPATCH_DATA_REMAINS;
04007 else
04008 return DBUS_DISPATCH_COMPLETE;
04009 }
04010 }
04011
04012 static void
04013 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
04014 DBusDispatchStatus new_status)
04015 {
04016 dbus_bool_t changed;
04017 DBusDispatchStatusFunction function;
04018 void *data;
04019
04020 HAVE_LOCK_CHECK (connection);
04021
04022 _dbus_connection_ref_unlocked (connection);
04023
04024 changed = new_status != connection->last_dispatch_status;
04025
04026 connection->last_dispatch_status = new_status;
04027
04028 function = connection->dispatch_status_function;
04029 data = connection->dispatch_status_data;
04030
04031 if (connection->disconnected_message_arrived &&
04032 !connection->disconnected_message_processed)
04033 {
04034 connection->disconnected_message_processed = TRUE;
04035
04036
04037
04038
04039
04040 connection_forget_shared_unlocked (connection);
04041
04042 if (connection->exit_on_disconnect)
04043 {
04044 CONNECTION_UNLOCK (connection);
04045
04046 _dbus_verbose ("Exiting on Disconnected signal\n");
04047 _dbus_exit (1);
04048 _dbus_assert_not_reached ("Call to exit() returned");
04049 }
04050 }
04051
04052
04053 CONNECTION_UNLOCK (connection);
04054
04055 if (changed && function)
04056 {
04057 _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
04058 connection, new_status,
04059 DISPATCH_STATUS_NAME (new_status));
04060 (* function) (connection, new_status, data);
04061 }
04062
04063 dbus_connection_unref (connection);
04064 }
04065
04091 DBusDispatchStatus
04092 dbus_connection_get_dispatch_status (DBusConnection *connection)
04093 {
04094 DBusDispatchStatus status;
04095
04096 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04097
04098 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
04099
04100 CONNECTION_LOCK (connection);
04101
04102 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04103
04104 CONNECTION_UNLOCK (connection);
04105
04106 return status;
04107 }
04108
04112 static DBusHandlerResult
04113 _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
04114 DBusMessage *message)
04115 {
04116 if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
04117 {
04118
04119 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04120 }
04121 else if (dbus_message_is_method_call (message,
04122 DBUS_INTERFACE_PEER,
04123 "Ping"))
04124 {
04125 DBusMessage *ret;
04126 dbus_bool_t sent;
04127
04128 ret = dbus_message_new_method_return (message);
04129 if (ret == NULL)
04130 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04131
04132 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04133
04134 dbus_message_unref (ret);
04135
04136 if (!sent)
04137 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04138
04139 return DBUS_HANDLER_RESULT_HANDLED;
04140 }
04141 else if (dbus_message_is_method_call (message,
04142 DBUS_INTERFACE_PEER,
04143 "GetMachineId"))
04144 {
04145 DBusMessage *ret;
04146 dbus_bool_t sent;
04147 DBusString uuid;
04148
04149 ret = dbus_message_new_method_return (message);
04150 if (ret == NULL)
04151 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04152
04153 sent = FALSE;
04154 _dbus_string_init (&uuid);
04155 if (_dbus_get_local_machine_uuid_encoded (&uuid))
04156 {
04157 const char *v_STRING = _dbus_string_get_const_data (&uuid);
04158 if (dbus_message_append_args (ret,
04159 DBUS_TYPE_STRING, &v_STRING,
04160 DBUS_TYPE_INVALID))
04161 {
04162 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04163 }
04164 }
04165 _dbus_string_free (&uuid);
04166
04167 dbus_message_unref (ret);
04168
04169 if (!sent)
04170 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04171
04172 return DBUS_HANDLER_RESULT_HANDLED;
04173 }
04174 else if (dbus_message_has_interface (message, DBUS_INTERFACE_PEER))
04175 {
04176
04177
04178
04179
04180
04181 DBusMessage *ret;
04182 dbus_bool_t sent;
04183
04184 ret = dbus_message_new_error (message,
04185 DBUS_ERROR_UNKNOWN_METHOD,
04186 "Unknown method invoked on org.freedesktop.DBus.Peer interface");
04187 if (ret == NULL)
04188 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04189
04190 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04191
04192 dbus_message_unref (ret);
04193
04194 if (!sent)
04195 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04196
04197 return DBUS_HANDLER_RESULT_HANDLED;
04198 }
04199 else
04200 {
04201 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04202 }
04203 }
04204
04211 static DBusHandlerResult
04212 _dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection,
04213 DBusMessage *message)
04214 {
04215
04216
04217
04218 return _dbus_connection_peer_filter_unlocked_no_update (connection, message);
04219 }
04220
04263 DBusDispatchStatus
04264 dbus_connection_dispatch (DBusConnection *connection)
04265 {
04266 DBusMessage *message;
04267 DBusList *link, *filter_list_copy, *message_link;
04268 DBusHandlerResult result;
04269 DBusPendingCall *pending;
04270 dbus_int32_t reply_serial;
04271 DBusDispatchStatus status;
04272
04273 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04274
04275 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
04276
04277 CONNECTION_LOCK (connection);
04278 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04279 if (status != DBUS_DISPATCH_DATA_REMAINS)
04280 {
04281
04282 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04283 return status;
04284 }
04285
04286
04287
04288
04289 _dbus_connection_ref_unlocked (connection);
04290
04291 _dbus_connection_acquire_dispatch (connection);
04292 HAVE_LOCK_CHECK (connection);
04293
04294 message_link = _dbus_connection_pop_message_link_unlocked (connection);
04295 if (message_link == NULL)
04296 {
04297
04298
04299 _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
04300
04301 _dbus_connection_release_dispatch (connection);
04302
04303 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04304
04305 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04306
04307 dbus_connection_unref (connection);
04308
04309 return status;
04310 }
04311
04312 message = message_link->data;
04313
04314 _dbus_verbose (" dispatching message %p (%d %s %s '%s')\n",
04315 message,
04316 dbus_message_get_type (message),
04317 dbus_message_get_interface (message) ?
04318 dbus_message_get_interface (message) :
04319 "no interface",
04320 dbus_message_get_member (message) ?
04321 dbus_message_get_member (message) :
04322 "no member",
04323 dbus_message_get_signature (message));
04324
04325 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04326
04327
04328
04329
04330
04331
04332
04333
04334 reply_serial = dbus_message_get_reply_serial (message);
04335 pending = _dbus_hash_table_lookup_int (connection->pending_replies,
04336 reply_serial);
04337 if (pending)
04338 {
04339 _dbus_verbose ("Dispatching a pending reply\n");
04340 complete_pending_call_and_unlock (connection, pending, message);
04341 pending = NULL;
04342
04343 CONNECTION_LOCK (connection);
04344 _dbus_verbose ("pending call completed in dispatch\n");
04345 result = DBUS_HANDLER_RESULT_HANDLED;
04346 goto out;
04347 }
04348
04349 result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message);
04350 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04351 goto out;
04352
04353 if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
04354 {
04355 _dbus_connection_release_dispatch (connection);
04356 HAVE_LOCK_CHECK (connection);
04357
04358 _dbus_connection_failed_pop (connection, message_link);
04359
04360
04361 _dbus_connection_update_dispatch_status_and_unlock (connection,
04362 DBUS_DISPATCH_NEED_MEMORY);
04363
04364 if (pending)
04365 dbus_pending_call_unref (pending);
04366 dbus_connection_unref (connection);
04367
04368 return DBUS_DISPATCH_NEED_MEMORY;
04369 }
04370
04371 _dbus_list_foreach (&filter_list_copy,
04372 (DBusForeachFunction)_dbus_message_filter_ref,
04373 NULL);
04374
04375
04376
04377
04378 CONNECTION_UNLOCK (connection);
04379
04380 link = _dbus_list_get_first_link (&filter_list_copy);
04381 while (link != NULL)
04382 {
04383 DBusMessageFilter *filter = link->data;
04384 DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
04385
04386 if (filter->function == NULL)
04387 {
04388 _dbus_verbose (" filter was removed in a callback function\n");
04389 link = next;
04390 continue;
04391 }
04392
04393 _dbus_verbose (" running filter on message %p\n", message);
04394 result = (* filter->function) (connection, message, filter->user_data);
04395
04396 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04397 break;
04398
04399 link = next;
04400 }
04401
04402 _dbus_list_foreach (&filter_list_copy,
04403 (DBusForeachFunction)_dbus_message_filter_unref,
04404 NULL);
04405 _dbus_list_clear (&filter_list_copy);
04406
04407 CONNECTION_LOCK (connection);
04408
04409 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04410 {
04411 _dbus_verbose ("No memory in %s\n", _DBUS_FUNCTION_NAME);
04412 goto out;
04413 }
04414 else if (result == DBUS_HANDLER_RESULT_HANDLED)
04415 {
04416 _dbus_verbose ("filter handled message in dispatch\n");
04417 goto out;
04418 }
04419
04420
04421
04422
04423 _dbus_verbose (" running object path dispatch on message %p (%d %s %s '%s')\n",
04424 message,
04425 dbus_message_get_type (message),
04426 dbus_message_get_interface (message) ?
04427 dbus_message_get_interface (message) :
04428 "no interface",
04429 dbus_message_get_member (message) ?
04430 dbus_message_get_member (message) :
04431 "no member",
04432 dbus_message_get_signature (message));
04433
04434 HAVE_LOCK_CHECK (connection);
04435 result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
04436 message);
04437
04438 CONNECTION_LOCK (connection);
04439
04440 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04441 {
04442 _dbus_verbose ("object tree handled message in dispatch\n");
04443 goto out;
04444 }
04445
04446 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
04447 {
04448 DBusMessage *reply;
04449 DBusString str;
04450 DBusPreallocatedSend *preallocated;
04451
04452 _dbus_verbose (" sending error %s\n",
04453 DBUS_ERROR_UNKNOWN_METHOD);
04454
04455 if (!_dbus_string_init (&str))
04456 {
04457 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04458 _dbus_verbose ("no memory for error string in dispatch\n");
04459 goto out;
04460 }
04461
04462 if (!_dbus_string_append_printf (&str,
04463 "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
04464 dbus_message_get_member (message),
04465 dbus_message_get_signature (message),
04466 dbus_message_get_interface (message)))
04467 {
04468 _dbus_string_free (&str);
04469 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04470 _dbus_verbose ("no memory for error string in dispatch\n");
04471 goto out;
04472 }
04473
04474 reply = dbus_message_new_error (message,
04475 DBUS_ERROR_UNKNOWN_METHOD,
04476 _dbus_string_get_const_data (&str));
04477 _dbus_string_free (&str);
04478
04479 if (reply == NULL)
04480 {
04481 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04482 _dbus_verbose ("no memory for error reply in dispatch\n");
04483 goto out;
04484 }
04485
04486 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
04487
04488 if (preallocated == NULL)
04489 {
04490 dbus_message_unref (reply);
04491 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04492 _dbus_verbose ("no memory for error send in dispatch\n");
04493 goto out;
04494 }
04495
04496 _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
04497 reply, NULL);
04498
04499 dbus_message_unref (reply);
04500
04501 result = DBUS_HANDLER_RESULT_HANDLED;
04502 }
04503
04504 _dbus_verbose (" done dispatching %p (%d %s %s '%s') on connection %p\n", message,
04505 dbus_message_get_type (message),
04506 dbus_message_get_interface (message) ?
04507 dbus_message_get_interface (message) :
04508 "no interface",
04509 dbus_message_get_member (message) ?
04510 dbus_message_get_member (message) :
04511 "no member",
04512 dbus_message_get_signature (message),
04513 connection);
04514
04515 out:
04516 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04517 {
04518 _dbus_verbose ("out of memory in %s\n", _DBUS_FUNCTION_NAME);
04519
04520
04521
04522
04523
04524 _dbus_connection_putback_message_link_unlocked (connection,
04525 message_link);
04526 }
04527 else
04528 {
04529 _dbus_verbose (" ... done dispatching in %s\n", _DBUS_FUNCTION_NAME);
04530
04531 _dbus_list_free_link (message_link);
04532 dbus_message_unref (message);
04533
04534
04535 }
04536
04537 _dbus_connection_release_dispatch (connection);
04538 HAVE_LOCK_CHECK (connection);
04539
04540 _dbus_verbose ("%s before final status update\n", _DBUS_FUNCTION_NAME);
04541 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04542
04543
04544 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04545
04546 dbus_connection_unref (connection);
04547
04548 return status;
04549 }
04550
04610 dbus_bool_t
04611 dbus_connection_set_watch_functions (DBusConnection *connection,
04612 DBusAddWatchFunction add_function,
04613 DBusRemoveWatchFunction remove_function,
04614 DBusWatchToggledFunction toggled_function,
04615 void *data,
04616 DBusFreeFunction free_data_function)
04617 {
04618 dbus_bool_t retval;
04619 DBusWatchList *watches;
04620
04621 _dbus_return_val_if_fail (connection != NULL, FALSE);
04622
04623 CONNECTION_LOCK (connection);
04624
04625 #ifndef DBUS_DISABLE_CHECKS
04626 if (connection->watches == NULL)
04627 {
04628 _dbus_warn_check_failed ("Re-entrant call to %s is not allowed\n",
04629 _DBUS_FUNCTION_NAME);
04630 return FALSE;
04631 }
04632 #endif
04633
04634
04635 _dbus_connection_ref_unlocked (connection);
04636
04637
04638
04639
04640
04641 watches = connection->watches;
04642 connection->watches = NULL;
04643 CONNECTION_UNLOCK (connection);
04644
04645 retval = _dbus_watch_list_set_functions (watches,
04646 add_function, remove_function,
04647 toggled_function,
04648 data, free_data_function);
04649 CONNECTION_LOCK (connection);
04650 connection->watches = watches;
04651
04652 CONNECTION_UNLOCK (connection);
04653
04654 dbus_connection_unref (connection);
04655
04656 return retval;
04657 }
04658
04692 dbus_bool_t
04693 dbus_connection_set_timeout_functions (DBusConnection *connection,
04694 DBusAddTimeoutFunction add_function,
04695 DBusRemoveTimeoutFunction remove_function,
04696 DBusTimeoutToggledFunction toggled_function,
04697 void *data,
04698 DBusFreeFunction free_data_function)
04699 {
04700 dbus_bool_t retval;
04701 DBusTimeoutList *timeouts;
04702
04703 _dbus_return_val_if_fail (connection != NULL, FALSE);
04704
04705 CONNECTION_LOCK (connection);
04706
04707 #ifndef DBUS_DISABLE_CHECKS
04708 if (connection->timeouts == NULL)
04709 {
04710 _dbus_warn_check_failed ("Re-entrant call to %s is not allowed\n",
04711 _DBUS_FUNCTION_NAME);
04712 return FALSE;
04713 }
04714 #endif
04715
04716
04717 _dbus_connection_ref_unlocked (connection);
04718
04719 timeouts = connection->timeouts;
04720 connection->timeouts = NULL;
04721 CONNECTION_UNLOCK (connection);
04722
04723 retval = _dbus_timeout_list_set_functions (timeouts,
04724 add_function, remove_function,
04725 toggled_function,
04726 data, free_data_function);
04727 CONNECTION_LOCK (connection);
04728 connection->timeouts = timeouts;
04729
04730 CONNECTION_UNLOCK (connection);
04731
04732 dbus_connection_unref (connection);
04733
04734 return retval;
04735 }
04736
04751 void
04752 dbus_connection_set_wakeup_main_function (DBusConnection *connection,
04753 DBusWakeupMainFunction wakeup_main_function,
04754 void *data,
04755 DBusFreeFunction free_data_function)
04756 {
04757 void *old_data;
04758 DBusFreeFunction old_free_data;
04759
04760 _dbus_return_if_fail (connection != NULL);
04761
04762 CONNECTION_LOCK (connection);
04763 old_data = connection->wakeup_main_data;
04764 old_free_data = connection->free_wakeup_main_data;
04765
04766 connection->wakeup_main_function = wakeup_main_function;
04767 connection->wakeup_main_data = data;
04768 connection->free_wakeup_main_data = free_data_function;
04769
04770 CONNECTION_UNLOCK (connection);
04771
04772
04773 if (old_free_data)
04774 (*old_free_data) (old_data);
04775 }
04776
04797 void
04798 dbus_connection_set_dispatch_status_function (DBusConnection *connection,
04799 DBusDispatchStatusFunction function,
04800 void *data,
04801 DBusFreeFunction free_data_function)
04802 {
04803 void *old_data;
04804 DBusFreeFunction old_free_data;
04805
04806 _dbus_return_if_fail (connection != NULL);
04807
04808 CONNECTION_LOCK (connection);
04809 old_data = connection->dispatch_status_data;
04810 old_free_data = connection->free_dispatch_status_data;
04811
04812 connection->dispatch_status_function = function;
04813 connection->dispatch_status_data = data;
04814 connection->free_dispatch_status_data = free_data_function;
04815
04816 CONNECTION_UNLOCK (connection);
04817
04818
04819 if (old_free_data)
04820 (*old_free_data) (old_data);
04821 }
04822
04842 dbus_bool_t
04843 dbus_connection_get_unix_fd (DBusConnection *connection,
04844 int *fd)
04845 {
04846 _dbus_return_val_if_fail (connection != NULL, FALSE);
04847 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
04848
04849 #ifdef DBUS_WIN
04850
04851 return FALSE;
04852 #endif
04853
04854 return dbus_connection_get_socket(connection, fd);
04855 }
04856
04872 dbus_bool_t
04873 dbus_connection_get_socket(DBusConnection *connection,
04874 int *fd)
04875 {
04876 dbus_bool_t retval;
04877
04878 _dbus_return_val_if_fail (connection != NULL, FALSE);
04879 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
04880
04881 CONNECTION_LOCK (connection);
04882
04883 retval = _dbus_transport_get_socket_fd (connection->transport,
04884 fd);
04885
04886 CONNECTION_UNLOCK (connection);
04887
04888 return retval;
04889 }
04890
04891
04914 dbus_bool_t
04915 dbus_connection_get_unix_user (DBusConnection *connection,
04916 unsigned long *uid)
04917 {
04918 dbus_bool_t result;
04919
04920 _dbus_return_val_if_fail (connection != NULL, FALSE);
04921 _dbus_return_val_if_fail (uid != NULL, FALSE);
04922
04923 CONNECTION_LOCK (connection);
04924
04925 if (!_dbus_transport_get_is_authenticated (connection->transport))
04926 result = FALSE;
04927 else
04928 result = _dbus_transport_get_unix_user (connection->transport,
04929 uid);
04930
04931 #ifdef DBUS_WIN
04932 _dbus_assert (!result);
04933 #endif
04934
04935 CONNECTION_UNLOCK (connection);
04936
04937 return result;
04938 }
04939
04950 dbus_bool_t
04951 dbus_connection_get_unix_process_id (DBusConnection *connection,
04952 unsigned long *pid)
04953 {
04954 dbus_bool_t result;
04955
04956 _dbus_return_val_if_fail (connection != NULL, FALSE);
04957 _dbus_return_val_if_fail (pid != NULL, FALSE);
04958
04959 CONNECTION_LOCK (connection);
04960
04961 if (!_dbus_transport_get_is_authenticated (connection->transport))
04962 result = FALSE;
04963 else
04964 result = _dbus_transport_get_unix_process_id (connection->transport,
04965 pid);
04966 #ifdef DBUS_WIN
04967 _dbus_assert (!result);
04968 #endif
04969
04970 CONNECTION_UNLOCK (connection);
04971
04972 return result;
04973 }
04974
04997 void
04998 dbus_connection_set_unix_user_function (DBusConnection *connection,
04999 DBusAllowUnixUserFunction function,
05000 void *data,
05001 DBusFreeFunction free_data_function)
05002 {
05003 void *old_data = NULL;
05004 DBusFreeFunction old_free_function = NULL;
05005
05006 _dbus_return_if_fail (connection != NULL);
05007
05008 CONNECTION_LOCK (connection);
05009 _dbus_transport_set_unix_user_function (connection->transport,
05010 function, data, free_data_function,
05011 &old_data, &old_free_function);
05012 CONNECTION_UNLOCK (connection);
05013
05014 if (old_free_function != NULL)
05015 (* old_free_function) (old_data);
05016 }
05017
05049 dbus_bool_t
05050 dbus_connection_get_windows_user (DBusConnection *connection,
05051 char **windows_sid_p)
05052 {
05053 dbus_bool_t result;
05054
05055 _dbus_return_val_if_fail (connection != NULL, FALSE);
05056 _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
05057
05058 CONNECTION_LOCK (connection);
05059
05060 if (!_dbus_transport_get_is_authenticated (connection->transport))
05061 result = FALSE;
05062 else
05063 result = _dbus_transport_get_windows_user (connection->transport,
05064 windows_sid_p);
05065
05066 #ifdef DBUS_UNIX
05067 _dbus_assert (!result);
05068 #endif
05069
05070 CONNECTION_UNLOCK (connection);
05071
05072 return result;
05073 }
05074
05096 void
05097 dbus_connection_set_windows_user_function (DBusConnection *connection,
05098 DBusAllowWindowsUserFunction function,
05099 void *data,
05100 DBusFreeFunction free_data_function)
05101 {
05102 void *old_data = NULL;
05103 DBusFreeFunction old_free_function = NULL;
05104
05105 _dbus_return_if_fail (connection != NULL);
05106
05107 CONNECTION_LOCK (connection);
05108 _dbus_transport_set_windows_user_function (connection->transport,
05109 function, data, free_data_function,
05110 &old_data, &old_free_function);
05111 CONNECTION_UNLOCK (connection);
05112
05113 if (old_free_function != NULL)
05114 (* old_free_function) (old_data);
05115 }
05116
05143 void
05144 dbus_connection_set_allow_anonymous (DBusConnection *connection,
05145 dbus_bool_t value)
05146 {
05147 _dbus_return_if_fail (connection != NULL);
05148
05149 CONNECTION_LOCK (connection);
05150 _dbus_transport_set_allow_anonymous (connection->transport, value);
05151 CONNECTION_UNLOCK (connection);
05152 }
05153
05171 void
05172 dbus_connection_set_route_peer_messages (DBusConnection *connection,
05173 dbus_bool_t value)
05174 {
05175 _dbus_return_if_fail (connection != NULL);
05176
05177 CONNECTION_LOCK (connection);
05178 connection->route_peer_messages = TRUE;
05179 CONNECTION_UNLOCK (connection);
05180 }
05181
05203 dbus_bool_t
05204 dbus_connection_add_filter (DBusConnection *connection,
05205 DBusHandleMessageFunction function,
05206 void *user_data,
05207 DBusFreeFunction free_data_function)
05208 {
05209 DBusMessageFilter *filter;
05210
05211 _dbus_return_val_if_fail (connection != NULL, FALSE);
05212 _dbus_return_val_if_fail (function != NULL, FALSE);
05213
05214 filter = dbus_new0 (DBusMessageFilter, 1);
05215 if (filter == NULL)
05216 return FALSE;
05217
05218 filter->refcount.value = 1;
05219
05220 CONNECTION_LOCK (connection);
05221
05222 if (!_dbus_list_append (&connection->filter_list,
05223 filter))
05224 {
05225 _dbus_message_filter_unref (filter);
05226 CONNECTION_UNLOCK (connection);
05227 return FALSE;
05228 }
05229
05230
05231
05232
05233
05234
05235 filter->function = function;
05236 filter->user_data = user_data;
05237 filter->free_user_data_function = free_data_function;
05238
05239 CONNECTION_UNLOCK (connection);
05240 return TRUE;
05241 }
05242
05255 void
05256 dbus_connection_remove_filter (DBusConnection *connection,
05257 DBusHandleMessageFunction function,
05258 void *user_data)
05259 {
05260 DBusList *link;
05261 DBusMessageFilter *filter;
05262
05263 _dbus_return_if_fail (connection != NULL);
05264 _dbus_return_if_fail (function != NULL);
05265
05266 CONNECTION_LOCK (connection);
05267
05268 filter = NULL;
05269
05270 link = _dbus_list_get_last_link (&connection->filter_list);
05271 while (link != NULL)
05272 {
05273 filter = link->data;
05274
05275 if (filter->function == function &&
05276 filter->user_data == user_data)
05277 {
05278 _dbus_list_remove_link (&connection->filter_list, link);
05279 filter->function = NULL;
05280
05281 break;
05282 }
05283
05284 link = _dbus_list_get_prev_link (&connection->filter_list, link);
05285 }
05286
05287 CONNECTION_UNLOCK (connection);
05288
05289 #ifndef DBUS_DISABLE_CHECKS
05290 if (filter == NULL)
05291 {
05292 _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
05293 function, user_data);
05294 return;
05295 }
05296 #endif
05297
05298
05299 if (filter->free_user_data_function)
05300 (* filter->free_user_data_function) (filter->user_data);
05301
05302 filter->free_user_data_function = NULL;
05303 filter->user_data = NULL;
05304
05305 _dbus_message_filter_unref (filter);
05306 }
05307
05320 dbus_bool_t
05321 dbus_connection_try_register_object_path (DBusConnection *connection,
05322 const char *path,
05323 const DBusObjectPathVTable *vtable,
05324 void *user_data,
05325 DBusError *error)
05326 {
05327 char **decomposed_path;
05328 dbus_bool_t retval;
05329
05330 _dbus_return_val_if_fail (connection != NULL, FALSE);
05331 _dbus_return_val_if_fail (path != NULL, FALSE);
05332 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05333 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05334
05335 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05336 return FALSE;
05337
05338 CONNECTION_LOCK (connection);
05339
05340 retval = _dbus_object_tree_register (connection->objects,
05341 FALSE,
05342 (const char **) decomposed_path, vtable,
05343 user_data, error);
05344
05345 CONNECTION_UNLOCK (connection);
05346
05347 dbus_free_string_array (decomposed_path);
05348
05349 return retval;
05350 }
05351
05366 dbus_bool_t
05367 dbus_connection_register_object_path (DBusConnection *connection,
05368 const char *path,
05369 const DBusObjectPathVTable *vtable,
05370 void *user_data)
05371 {
05372 char **decomposed_path;
05373 dbus_bool_t retval;
05374 DBusError error = DBUS_ERROR_INIT;
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 if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE))
05396 {
05397 _dbus_warn ("%s\n", error.message);
05398 dbus_error_free (&error);
05399 return FALSE;
05400 }
05401
05402 return retval;
05403 }
05404
05419 dbus_bool_t
05420 dbus_connection_try_register_fallback (DBusConnection *connection,
05421 const char *path,
05422 const DBusObjectPathVTable *vtable,
05423 void *user_data,
05424 DBusError *error)
05425 {
05426 char **decomposed_path;
05427 dbus_bool_t retval;
05428
05429 _dbus_return_val_if_fail (connection != NULL, FALSE);
05430 _dbus_return_val_if_fail (path != NULL, FALSE);
05431 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05432 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05433
05434 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05435 return FALSE;
05436
05437 CONNECTION_LOCK (connection);
05438
05439 retval = _dbus_object_tree_register (connection->objects,
05440 TRUE,
05441 (const char **) decomposed_path, vtable,
05442 user_data, error);
05443
05444 CONNECTION_UNLOCK (connection);
05445
05446 dbus_free_string_array (decomposed_path);
05447
05448 return retval;
05449 }
05450
05467 dbus_bool_t
05468 dbus_connection_register_fallback (DBusConnection *connection,
05469 const char *path,
05470 const DBusObjectPathVTable *vtable,
05471 void *user_data)
05472 {
05473 char **decomposed_path;
05474 dbus_bool_t retval;
05475 DBusError error = DBUS_ERROR_INIT;
05476
05477 _dbus_return_val_if_fail (connection != NULL, FALSE);
05478 _dbus_return_val_if_fail (path != NULL, FALSE);
05479 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05480 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05481
05482 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05483 return FALSE;
05484
05485 CONNECTION_LOCK (connection);
05486
05487 retval = _dbus_object_tree_register (connection->objects,
05488 TRUE,
05489 (const char **) decomposed_path, vtable,
05490 user_data, &error);
05491
05492 CONNECTION_UNLOCK (connection);
05493
05494 dbus_free_string_array (decomposed_path);
05495
05496 if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE))
05497 {
05498 _dbus_warn ("%s\n", error.message);
05499 dbus_error_free (&error);
05500 return FALSE;
05501 }
05502
05503 return retval;
05504 }
05505
05515 dbus_bool_t
05516 dbus_connection_unregister_object_path (DBusConnection *connection,
05517 const char *path)
05518 {
05519 char **decomposed_path;
05520
05521 _dbus_return_val_if_fail (connection != NULL, FALSE);
05522 _dbus_return_val_if_fail (path != NULL, FALSE);
05523 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05524
05525 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05526 return FALSE;
05527
05528 CONNECTION_LOCK (connection);
05529
05530 _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
05531
05532 dbus_free_string_array (decomposed_path);
05533
05534 return TRUE;
05535 }
05536
05547 dbus_bool_t
05548 dbus_connection_get_object_path_data (DBusConnection *connection,
05549 const char *path,
05550 void **data_p)
05551 {
05552 char **decomposed_path;
05553
05554 _dbus_return_val_if_fail (connection != NULL, FALSE);
05555 _dbus_return_val_if_fail (path != NULL, FALSE);
05556 _dbus_return_val_if_fail (data_p != NULL, FALSE);
05557
05558 *data_p = NULL;
05559
05560 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05561 return FALSE;
05562
05563 CONNECTION_LOCK (connection);
05564
05565 *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path);
05566
05567 CONNECTION_UNLOCK (connection);
05568
05569 dbus_free_string_array (decomposed_path);
05570
05571 return TRUE;
05572 }
05573
05584 dbus_bool_t
05585 dbus_connection_list_registered (DBusConnection *connection,
05586 const char *parent_path,
05587 char ***child_entries)
05588 {
05589 char **decomposed_path;
05590 dbus_bool_t retval;
05591 _dbus_return_val_if_fail (connection != NULL, FALSE);
05592 _dbus_return_val_if_fail (parent_path != NULL, FALSE);
05593 _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
05594 _dbus_return_val_if_fail (child_entries != NULL, FALSE);
05595
05596 if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
05597 return FALSE;
05598
05599 CONNECTION_LOCK (connection);
05600
05601 retval = _dbus_object_tree_list_registered_and_unlock (connection->objects,
05602 (const char **) decomposed_path,
05603 child_entries);
05604 dbus_free_string_array (decomposed_path);
05605
05606 return retval;
05607 }
05608
05609 static DBusDataSlotAllocator slot_allocator;
05610 _DBUS_DEFINE_GLOBAL_LOCK (connection_slots);
05611
05626 dbus_bool_t
05627 dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
05628 {
05629 return _dbus_data_slot_allocator_alloc (&slot_allocator,
05630 &_DBUS_LOCK_NAME (connection_slots),
05631 slot_p);
05632 }
05633
05645 void
05646 dbus_connection_free_data_slot (dbus_int32_t *slot_p)
05647 {
05648 _dbus_return_if_fail (*slot_p >= 0);
05649
05650 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
05651 }
05652
05666 dbus_bool_t
05667 dbus_connection_set_data (DBusConnection *connection,
05668 dbus_int32_t slot,
05669 void *data,
05670 DBusFreeFunction free_data_func)
05671 {
05672 DBusFreeFunction old_free_func;
05673 void *old_data;
05674 dbus_bool_t retval;
05675
05676 _dbus_return_val_if_fail (connection != NULL, FALSE);
05677 _dbus_return_val_if_fail (slot >= 0, FALSE);
05678
05679 CONNECTION_LOCK (connection);
05680
05681 retval = _dbus_data_slot_list_set (&slot_allocator,
05682 &connection->slot_list,
05683 slot, data, free_data_func,
05684 &old_free_func, &old_data);
05685
05686 CONNECTION_UNLOCK (connection);
05687
05688 if (retval)
05689 {
05690
05691 if (old_free_func)
05692 (* old_free_func) (old_data);
05693 }
05694
05695 return retval;
05696 }
05697
05706 void*
05707 dbus_connection_get_data (DBusConnection *connection,
05708 dbus_int32_t slot)
05709 {
05710 void *res;
05711
05712 _dbus_return_val_if_fail (connection != NULL, NULL);
05713
05714 CONNECTION_LOCK (connection);
05715
05716 res = _dbus_data_slot_list_get (&slot_allocator,
05717 &connection->slot_list,
05718 slot);
05719
05720 CONNECTION_UNLOCK (connection);
05721
05722 return res;
05723 }
05724
05731 void
05732 dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
05733 {
05734 _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
05735 }
05736
05745 void
05746 dbus_connection_set_max_message_size (DBusConnection *connection,
05747 long size)
05748 {
05749 _dbus_return_if_fail (connection != NULL);
05750
05751 CONNECTION_LOCK (connection);
05752 _dbus_transport_set_max_message_size (connection->transport,
05753 size);
05754 CONNECTION_UNLOCK (connection);
05755 }
05756
05763 long
05764 dbus_connection_get_max_message_size (DBusConnection *connection)
05765 {
05766 long res;
05767
05768 _dbus_return_val_if_fail (connection != NULL, 0);
05769
05770 CONNECTION_LOCK (connection);
05771 res = _dbus_transport_get_max_message_size (connection->transport);
05772 CONNECTION_UNLOCK (connection);
05773 return res;
05774 }
05775
05801 void
05802 dbus_connection_set_max_received_size (DBusConnection *connection,
05803 long size)
05804 {
05805 _dbus_return_if_fail (connection != NULL);
05806
05807 CONNECTION_LOCK (connection);
05808 _dbus_transport_set_max_received_size (connection->transport,
05809 size);
05810 CONNECTION_UNLOCK (connection);
05811 }
05812
05819 long
05820 dbus_connection_get_max_received_size (DBusConnection *connection)
05821 {
05822 long res;
05823
05824 _dbus_return_val_if_fail (connection != NULL, 0);
05825
05826 CONNECTION_LOCK (connection);
05827 res = _dbus_transport_get_max_received_size (connection->transport);
05828 CONNECTION_UNLOCK (connection);
05829 return res;
05830 }
05831
05842 long
05843 dbus_connection_get_outgoing_size (DBusConnection *connection)
05844 {
05845 long res;
05846
05847 _dbus_return_val_if_fail (connection != NULL, 0);
05848
05849 CONNECTION_LOCK (connection);
05850 res = _dbus_counter_get_value (connection->outgoing_counter);
05851 CONNECTION_UNLOCK (connection);
05852 return res;
05853 }
05854