00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config.h>
00025 #include "dbus-shared.h"
00026 #include "dbus-connection.h"
00027 #include "dbus-list.h"
00028 #include "dbus-timeout.h"
00029 #include "dbus-transport.h"
00030 #include "dbus-watch.h"
00031 #include "dbus-connection-internal.h"
00032 #include "dbus-pending-call-internal.h"
00033 #include "dbus-list.h"
00034 #include "dbus-hash.h"
00035 #include "dbus-message-internal.h"
00036 #include "dbus-message-private.h"
00037 #include "dbus-threads.h"
00038 #include "dbus-protocol.h"
00039 #include "dbus-dataslot.h"
00040 #include "dbus-string.h"
00041 #include "dbus-signature.h"
00042 #include "dbus-pending-call.h"
00043 #include "dbus-object-tree.h"
00044 #include "dbus-threads-internal.h"
00045 #include "dbus-bus.h"
00046 #include "dbus-marshal-basic.h"
00047
00048 #ifdef DBUS_DISABLE_CHECKS
00049 #define TOOK_LOCK_CHECK(connection)
00050 #define RELEASING_LOCK_CHECK(connection)
00051 #define HAVE_LOCK_CHECK(connection)
00052 #else
00053 #define TOOK_LOCK_CHECK(connection) do { \
00054 _dbus_assert (!(connection)->have_connection_lock); \
00055 (connection)->have_connection_lock = TRUE; \
00056 } while (0)
00057 #define RELEASING_LOCK_CHECK(connection) do { \
00058 _dbus_assert ((connection)->have_connection_lock); \
00059 (connection)->have_connection_lock = FALSE; \
00060 } while (0)
00061 #define HAVE_LOCK_CHECK(connection) _dbus_assert ((connection)->have_connection_lock)
00062
00063 #endif
00064
00065 #define TRACE_LOCKS 1
00066
00067 #define CONNECTION_LOCK(connection) do { \
00068 if (TRACE_LOCKS) { _dbus_verbose ("LOCK\n"); } \
00069 _dbus_rmutex_lock ((connection)->mutex); \
00070 TOOK_LOCK_CHECK (connection); \
00071 } while (0)
00072
00073 #define CONNECTION_UNLOCK(connection) _dbus_connection_unlock (connection)
00074
00075 #define SLOTS_LOCK(connection) do { \
00076 _dbus_rmutex_lock ((connection)->slot_mutex); \
00077 } while (0)
00078
00079 #define SLOTS_UNLOCK(connection) do { \
00080 _dbus_rmutex_unlock ((connection)->slot_mutex); \
00081 } while (0)
00082
00083 #define DISPATCH_STATUS_NAME(s) \
00084 ((s) == DBUS_DISPATCH_COMPLETE ? "complete" : \
00085 (s) == DBUS_DISPATCH_DATA_REMAINS ? "data remains" : \
00086 (s) == DBUS_DISPATCH_NEED_MEMORY ? "need memory" : \
00087 "???")
00088
00206 static void
00207 _dbus_connection_trace_ref (DBusConnection *connection,
00208 int old_refcount,
00209 int new_refcount,
00210 const char *why)
00211 {
00212 #ifdef DBUS_ENABLE_VERBOSE_MODE
00213 static int enabled = -1;
00214
00215 _dbus_trace_ref ("DBusConnection", connection, old_refcount, new_refcount,
00216 why, "DBUS_CONNECTION_TRACE", &enabled);
00217 #endif
00218 }
00219
00223 typedef struct DBusMessageFilter DBusMessageFilter;
00224
00228 struct DBusMessageFilter
00229 {
00230 DBusAtomic refcount;
00231 DBusHandleMessageFunction function;
00232 void *user_data;
00233 DBusFreeFunction free_user_data_function;
00234 };
00235
00236
00240 struct DBusPreallocatedSend
00241 {
00242 DBusConnection *connection;
00243 DBusList *queue_link;
00244 DBusList *counter_link;
00245 };
00246
00247 #if HAVE_DECL_MSG_NOSIGNAL
00248 static dbus_bool_t _dbus_modify_sigpipe = FALSE;
00249 #else
00250 static dbus_bool_t _dbus_modify_sigpipe = TRUE;
00251 #endif
00252
00256 struct DBusConnection
00257 {
00258 DBusAtomic refcount;
00260 DBusRMutex *mutex;
00262 DBusCMutex *dispatch_mutex;
00263 DBusCondVar *dispatch_cond;
00264 DBusCMutex *io_path_mutex;
00265 DBusCondVar *io_path_cond;
00267 DBusList *outgoing_messages;
00268 DBusList *incoming_messages;
00269 DBusList *expired_messages;
00271 DBusMessage *message_borrowed;
00275 int n_outgoing;
00276 int n_incoming;
00278 DBusCounter *outgoing_counter;
00280 DBusTransport *transport;
00281 DBusWatchList *watches;
00282 DBusTimeoutList *timeouts;
00284 DBusList *filter_list;
00286 DBusRMutex *slot_mutex;
00287 DBusDataSlotList slot_list;
00289 DBusHashTable *pending_replies;
00291 dbus_uint32_t client_serial;
00292 DBusList *disconnect_message_link;
00294 DBusWakeupMainFunction wakeup_main_function;
00295 void *wakeup_main_data;
00296 DBusFreeFunction free_wakeup_main_data;
00298 DBusDispatchStatusFunction dispatch_status_function;
00299 void *dispatch_status_data;
00300 DBusFreeFunction free_dispatch_status_data;
00302 DBusDispatchStatus last_dispatch_status;
00304 DBusObjectTree *objects;
00306 char *server_guid;
00308
00309
00310
00311
00312 dbus_bool_t dispatch_acquired;
00313 dbus_bool_t io_path_acquired;
00315 unsigned int shareable : 1;
00317 unsigned int exit_on_disconnect : 1;
00319 unsigned int route_peer_messages : 1;
00321 unsigned int disconnected_message_arrived : 1;
00325 unsigned int disconnected_message_processed : 1;
00329 #ifndef DBUS_DISABLE_CHECKS
00330 unsigned int have_connection_lock : 1;
00331 #endif
00332
00333 #if defined(DBUS_ENABLE_CHECKS) || defined(DBUS_ENABLE_ASSERT)
00334 int generation;
00335 #endif
00336 };
00337
00338 static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection);
00339 static void _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
00340 DBusDispatchStatus new_status);
00341 static void _dbus_connection_last_unref (DBusConnection *connection);
00342 static void _dbus_connection_acquire_dispatch (DBusConnection *connection);
00343 static void _dbus_connection_release_dispatch (DBusConnection *connection);
00344 static DBusDispatchStatus _dbus_connection_flush_unlocked (DBusConnection *connection);
00345 static void _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection);
00346 static dbus_bool_t _dbus_connection_get_is_connected_unlocked (DBusConnection *connection);
00347 static dbus_bool_t _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection,
00348 dbus_uint32_t client_serial);
00349
00350 static DBusMessageFilter *
00351 _dbus_message_filter_ref (DBusMessageFilter *filter)
00352 {
00353 #ifdef DBUS_DISABLE_ASSERT
00354 _dbus_atomic_inc (&filter->refcount);
00355 #else
00356 dbus_int32_t old_value;
00357
00358 old_value = _dbus_atomic_inc (&filter->refcount);
00359 _dbus_assert (old_value > 0);
00360 #endif
00361
00362 return filter;
00363 }
00364
00365 static void
00366 _dbus_message_filter_unref (DBusMessageFilter *filter)
00367 {
00368 dbus_int32_t old_value;
00369
00370 old_value = _dbus_atomic_dec (&filter->refcount);
00371 _dbus_assert (old_value > 0);
00372
00373 if (old_value == 1)
00374 {
00375 if (filter->free_user_data_function)
00376 (* filter->free_user_data_function) (filter->user_data);
00377
00378 dbus_free (filter);
00379 }
00380 }
00381
00387 void
00388 _dbus_connection_lock (DBusConnection *connection)
00389 {
00390 CONNECTION_LOCK (connection);
00391 }
00392
00398 void
00399 _dbus_connection_unlock (DBusConnection *connection)
00400 {
00401 DBusList *expired_messages;
00402 DBusList *iter;
00403
00404 if (TRACE_LOCKS)
00405 {
00406 _dbus_verbose ("UNLOCK\n");
00407 }
00408
00409
00410
00411 expired_messages = connection->expired_messages;
00412 connection->expired_messages = NULL;
00413
00414 RELEASING_LOCK_CHECK (connection);
00415 _dbus_rmutex_unlock (connection->mutex);
00416
00417 for (iter = _dbus_list_pop_first_link (&expired_messages);
00418 iter != NULL;
00419 iter = _dbus_list_pop_first_link (&expired_messages))
00420 {
00421 DBusMessage *message = iter->data;
00422
00423 dbus_message_unref (message);
00424 _dbus_list_free_link (iter);
00425 }
00426 }
00427
00435 static void
00436 _dbus_connection_wakeup_mainloop (DBusConnection *connection)
00437 {
00438 if (connection->wakeup_main_function)
00439 (*connection->wakeup_main_function) (connection->wakeup_main_data);
00440 }
00441
00442 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
00443
00455 void
00456 _dbus_connection_test_get_locks (DBusConnection *connection,
00457 DBusMutex **mutex_loc,
00458 DBusMutex **dispatch_mutex_loc,
00459 DBusMutex **io_path_mutex_loc,
00460 DBusCondVar **dispatch_cond_loc,
00461 DBusCondVar **io_path_cond_loc)
00462 {
00463 *mutex_loc = (DBusMutex *) connection->mutex;
00464 *dispatch_mutex_loc = (DBusMutex *) connection->dispatch_mutex;
00465 *io_path_mutex_loc = (DBusMutex *) connection->io_path_mutex;
00466 *dispatch_cond_loc = connection->dispatch_cond;
00467 *io_path_cond_loc = connection->io_path_cond;
00468 }
00469 #endif
00470
00479 void
00480 _dbus_connection_queue_received_message_link (DBusConnection *connection,
00481 DBusList *link)
00482 {
00483 DBusPendingCall *pending;
00484 dbus_uint32_t reply_serial;
00485 DBusMessage *message;
00486
00487 _dbus_assert (_dbus_transport_peek_is_authenticated (connection->transport));
00488
00489 _dbus_list_append_link (&connection->incoming_messages,
00490 link);
00491 message = link->data;
00492
00493
00494 reply_serial = dbus_message_get_reply_serial (message);
00495 if (reply_serial != 0)
00496 {
00497 pending = _dbus_hash_table_lookup_int (connection->pending_replies,
00498 reply_serial);
00499 if (pending != NULL)
00500 {
00501 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00502 _dbus_connection_remove_timeout_unlocked (connection,
00503 _dbus_pending_call_get_timeout_unlocked (pending));
00504
00505 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00506 }
00507 }
00508
00509
00510
00511 connection->n_incoming += 1;
00512
00513 _dbus_connection_wakeup_mainloop (connection);
00514
00515 _dbus_verbose ("Message %p (%s %s %s %s '%s' reply to %u) added to incoming queue %p, %d incoming\n",
00516 message,
00517 dbus_message_type_to_string (dbus_message_get_type (message)),
00518 dbus_message_get_path (message) ?
00519 dbus_message_get_path (message) :
00520 "no path",
00521 dbus_message_get_interface (message) ?
00522 dbus_message_get_interface (message) :
00523 "no interface",
00524 dbus_message_get_member (message) ?
00525 dbus_message_get_member (message) :
00526 "no member",
00527 dbus_message_get_signature (message),
00528 dbus_message_get_reply_serial (message),
00529 connection,
00530 connection->n_incoming);
00531
00532 _dbus_message_trace_ref (message, -1, -1,
00533 "_dbus_conection_queue_received_message_link");
00534 }
00535
00544 void
00545 _dbus_connection_queue_synthesized_message_link (DBusConnection *connection,
00546 DBusList *link)
00547 {
00548 HAVE_LOCK_CHECK (connection);
00549
00550 _dbus_list_append_link (&connection->incoming_messages, link);
00551
00552 connection->n_incoming += 1;
00553
00554 _dbus_connection_wakeup_mainloop (connection);
00555
00556 _dbus_message_trace_ref (link->data, -1, -1,
00557 "_dbus_connection_queue_synthesized_message_link");
00558
00559 _dbus_verbose ("Synthesized message %p added to incoming queue %p, %d incoming\n",
00560 link->data, connection, connection->n_incoming);
00561 }
00562
00563
00571 dbus_bool_t
00572 _dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection)
00573 {
00574 HAVE_LOCK_CHECK (connection);
00575 return connection->outgoing_messages != NULL;
00576 }
00577
00587 dbus_bool_t
00588 dbus_connection_has_messages_to_send (DBusConnection *connection)
00589 {
00590 dbus_bool_t v;
00591
00592 _dbus_return_val_if_fail (connection != NULL, FALSE);
00593
00594 CONNECTION_LOCK (connection);
00595 v = _dbus_connection_has_messages_to_send_unlocked (connection);
00596 CONNECTION_UNLOCK (connection);
00597
00598 return v;
00599 }
00600
00608 DBusMessage*
00609 _dbus_connection_get_message_to_send (DBusConnection *connection)
00610 {
00611 HAVE_LOCK_CHECK (connection);
00612
00613 return _dbus_list_get_last (&connection->outgoing_messages);
00614 }
00615
00624 void
00625 _dbus_connection_message_sent_unlocked (DBusConnection *connection,
00626 DBusMessage *message)
00627 {
00628 DBusList *link;
00629
00630 HAVE_LOCK_CHECK (connection);
00631
00632
00633
00634
00635
00636
00637 link = _dbus_list_get_last_link (&connection->outgoing_messages);
00638 _dbus_assert (link != NULL);
00639 _dbus_assert (link->data == message);
00640
00641 _dbus_list_unlink (&connection->outgoing_messages,
00642 link);
00643 _dbus_list_prepend_link (&connection->expired_messages, link);
00644
00645 connection->n_outgoing -= 1;
00646
00647 _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from outgoing queue %p, %d left to send\n",
00648 message,
00649 dbus_message_type_to_string (dbus_message_get_type (message)),
00650 dbus_message_get_path (message) ?
00651 dbus_message_get_path (message) :
00652 "no path",
00653 dbus_message_get_interface (message) ?
00654 dbus_message_get_interface (message) :
00655 "no interface",
00656 dbus_message_get_member (message) ?
00657 dbus_message_get_member (message) :
00658 "no member",
00659 dbus_message_get_signature (message),
00660 connection, connection->n_outgoing);
00661
00662
00663
00664 _dbus_message_remove_counter (message, connection->outgoing_counter);
00665
00666
00667 }
00668
00670 typedef dbus_bool_t (* DBusWatchAddFunction) (DBusWatchList *list,
00671 DBusWatch *watch);
00673 typedef void (* DBusWatchRemoveFunction) (DBusWatchList *list,
00674 DBusWatch *watch);
00676 typedef void (* DBusWatchToggleFunction) (DBusWatchList *list,
00677 DBusWatch *watch,
00678 dbus_bool_t enabled);
00679
00680 static dbus_bool_t
00681 protected_change_watch (DBusConnection *connection,
00682 DBusWatch *watch,
00683 DBusWatchAddFunction add_function,
00684 DBusWatchRemoveFunction remove_function,
00685 DBusWatchToggleFunction toggle_function,
00686 dbus_bool_t enabled)
00687 {
00688 dbus_bool_t retval;
00689
00690 HAVE_LOCK_CHECK (connection);
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710 if (connection->watches)
00711 {
00712 if (add_function)
00713 retval = (* add_function) (connection->watches, watch);
00714 else if (remove_function)
00715 {
00716 retval = TRUE;
00717 (* remove_function) (connection->watches, watch);
00718 }
00719 else
00720 {
00721 retval = TRUE;
00722 (* toggle_function) (connection->watches, watch, enabled);
00723 }
00724 return retval;
00725 }
00726 else
00727 return FALSE;
00728 }
00729
00730
00742 dbus_bool_t
00743 _dbus_connection_add_watch_unlocked (DBusConnection *connection,
00744 DBusWatch *watch)
00745 {
00746 return protected_change_watch (connection, watch,
00747 _dbus_watch_list_add_watch,
00748 NULL, NULL, FALSE);
00749 }
00750
00760 void
00761 _dbus_connection_remove_watch_unlocked (DBusConnection *connection,
00762 DBusWatch *watch)
00763 {
00764 protected_change_watch (connection, watch,
00765 NULL,
00766 _dbus_watch_list_remove_watch,
00767 NULL, FALSE);
00768 }
00769
00780 void
00781 _dbus_connection_toggle_watch_unlocked (DBusConnection *connection,
00782 DBusWatch *watch,
00783 dbus_bool_t enabled)
00784 {
00785 _dbus_assert (watch != NULL);
00786
00787 protected_change_watch (connection, watch,
00788 NULL, NULL,
00789 _dbus_watch_list_toggle_watch,
00790 enabled);
00791 }
00792
00794 typedef dbus_bool_t (* DBusTimeoutAddFunction) (DBusTimeoutList *list,
00795 DBusTimeout *timeout);
00797 typedef void (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list,
00798 DBusTimeout *timeout);
00800 typedef void (* DBusTimeoutToggleFunction) (DBusTimeoutList *list,
00801 DBusTimeout *timeout,
00802 dbus_bool_t enabled);
00803
00804 static dbus_bool_t
00805 protected_change_timeout (DBusConnection *connection,
00806 DBusTimeout *timeout,
00807 DBusTimeoutAddFunction add_function,
00808 DBusTimeoutRemoveFunction remove_function,
00809 DBusTimeoutToggleFunction toggle_function,
00810 dbus_bool_t enabled)
00811 {
00812 dbus_bool_t retval;
00813
00814 HAVE_LOCK_CHECK (connection);
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834 if (connection->timeouts)
00835 {
00836 if (add_function)
00837 retval = (* add_function) (connection->timeouts, timeout);
00838 else if (remove_function)
00839 {
00840 retval = TRUE;
00841 (* remove_function) (connection->timeouts, timeout);
00842 }
00843 else
00844 {
00845 retval = TRUE;
00846 (* toggle_function) (connection->timeouts, timeout, enabled);
00847 }
00848 return retval;
00849 }
00850 else
00851 return FALSE;
00852 }
00853
00866 dbus_bool_t
00867 _dbus_connection_add_timeout_unlocked (DBusConnection *connection,
00868 DBusTimeout *timeout)
00869 {
00870 return protected_change_timeout (connection, timeout,
00871 _dbus_timeout_list_add_timeout,
00872 NULL, NULL, FALSE);
00873 }
00874
00884 void
00885 _dbus_connection_remove_timeout_unlocked (DBusConnection *connection,
00886 DBusTimeout *timeout)
00887 {
00888 protected_change_timeout (connection, timeout,
00889 NULL,
00890 _dbus_timeout_list_remove_timeout,
00891 NULL, FALSE);
00892 }
00893
00904 void
00905 _dbus_connection_toggle_timeout_unlocked (DBusConnection *connection,
00906 DBusTimeout *timeout,
00907 dbus_bool_t enabled)
00908 {
00909 protected_change_timeout (connection, timeout,
00910 NULL, NULL,
00911 _dbus_timeout_list_toggle_timeout,
00912 enabled);
00913 }
00914
00915 static dbus_bool_t
00916 _dbus_connection_attach_pending_call_unlocked (DBusConnection *connection,
00917 DBusPendingCall *pending)
00918 {
00919 dbus_uint32_t reply_serial;
00920 DBusTimeout *timeout;
00921
00922 HAVE_LOCK_CHECK (connection);
00923
00924 reply_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
00925
00926 _dbus_assert (reply_serial != 0);
00927
00928 timeout = _dbus_pending_call_get_timeout_unlocked (pending);
00929
00930 if (timeout)
00931 {
00932 if (!_dbus_connection_add_timeout_unlocked (connection, timeout))
00933 return FALSE;
00934
00935 if (!_dbus_hash_table_insert_int (connection->pending_replies,
00936 reply_serial,
00937 pending))
00938 {
00939 _dbus_connection_remove_timeout_unlocked (connection, timeout);
00940
00941 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00942 HAVE_LOCK_CHECK (connection);
00943 return FALSE;
00944 }
00945
00946 _dbus_pending_call_set_timeout_added_unlocked (pending, TRUE);
00947 }
00948 else
00949 {
00950 if (!_dbus_hash_table_insert_int (connection->pending_replies,
00951 reply_serial,
00952 pending))
00953 {
00954 HAVE_LOCK_CHECK (connection);
00955 return FALSE;
00956 }
00957 }
00958
00959 _dbus_pending_call_ref_unlocked (pending);
00960
00961 HAVE_LOCK_CHECK (connection);
00962
00963 return TRUE;
00964 }
00965
00966 static void
00967 free_pending_call_on_hash_removal (void *data)
00968 {
00969 DBusPendingCall *pending;
00970 DBusConnection *connection;
00971
00972 if (data == NULL)
00973 return;
00974
00975 pending = data;
00976
00977 connection = _dbus_pending_call_get_connection_unlocked (pending);
00978
00979 HAVE_LOCK_CHECK (connection);
00980
00981 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00982 {
00983 _dbus_connection_remove_timeout_unlocked (connection,
00984 _dbus_pending_call_get_timeout_unlocked (pending));
00985
00986 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00987 }
00988
00989
00990
00991
00992
00993
00994 _dbus_connection_ref_unlocked (connection);
00995 _dbus_pending_call_unref_and_unlock (pending);
00996 CONNECTION_LOCK (connection);
00997 _dbus_connection_unref_unlocked (connection);
00998 }
00999
01000 static void
01001 _dbus_connection_detach_pending_call_unlocked (DBusConnection *connection,
01002 DBusPendingCall *pending)
01003 {
01004
01005
01006
01007 _dbus_hash_table_remove_int (connection->pending_replies,
01008 _dbus_pending_call_get_reply_serial_unlocked (pending));
01009 }
01010
01011 static void
01012 _dbus_connection_detach_pending_call_and_unlock (DBusConnection *connection,
01013 DBusPendingCall *pending)
01014 {
01015
01016
01017
01018
01019
01020
01021
01022 _dbus_pending_call_ref_unlocked (pending);
01023 _dbus_hash_table_remove_int (connection->pending_replies,
01024 _dbus_pending_call_get_reply_serial_unlocked (pending));
01025
01026 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
01027 _dbus_connection_remove_timeout_unlocked (connection,
01028 _dbus_pending_call_get_timeout_unlocked (pending));
01029
01030 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
01031
01032 _dbus_pending_call_unref_and_unlock (pending);
01033 }
01034
01043 void
01044 _dbus_connection_remove_pending_call (DBusConnection *connection,
01045 DBusPendingCall *pending)
01046 {
01047 CONNECTION_LOCK (connection);
01048 _dbus_connection_detach_pending_call_and_unlock (connection, pending);
01049 }
01050
01060 static dbus_bool_t
01061 _dbus_connection_acquire_io_path (DBusConnection *connection,
01062 int timeout_milliseconds)
01063 {
01064 dbus_bool_t we_acquired;
01065
01066 HAVE_LOCK_CHECK (connection);
01067
01068
01069 _dbus_connection_ref_unlocked (connection);
01070
01071
01072 CONNECTION_UNLOCK (connection);
01073
01074 _dbus_verbose ("locking io_path_mutex\n");
01075 _dbus_cmutex_lock (connection->io_path_mutex);
01076
01077 _dbus_verbose ("start connection->io_path_acquired = %d timeout = %d\n",
01078 connection->io_path_acquired, timeout_milliseconds);
01079
01080 we_acquired = FALSE;
01081
01082 if (connection->io_path_acquired)
01083 {
01084 if (timeout_milliseconds != -1)
01085 {
01086 _dbus_verbose ("waiting %d for IO path to be acquirable\n",
01087 timeout_milliseconds);
01088
01089 if (!_dbus_condvar_wait_timeout (connection->io_path_cond,
01090 connection->io_path_mutex,
01091 timeout_milliseconds))
01092 {
01093
01094
01095
01096
01097
01098
01099
01100
01101 }
01102 }
01103 else
01104 {
01105 while (connection->io_path_acquired)
01106 {
01107 _dbus_verbose ("waiting for IO path to be acquirable\n");
01108 _dbus_condvar_wait (connection->io_path_cond,
01109 connection->io_path_mutex);
01110 }
01111 }
01112 }
01113
01114 if (!connection->io_path_acquired)
01115 {
01116 we_acquired = TRUE;
01117 connection->io_path_acquired = TRUE;
01118 }
01119
01120 _dbus_verbose ("end connection->io_path_acquired = %d we_acquired = %d\n",
01121 connection->io_path_acquired, we_acquired);
01122
01123 _dbus_verbose ("unlocking io_path_mutex\n");
01124 _dbus_cmutex_unlock (connection->io_path_mutex);
01125
01126 CONNECTION_LOCK (connection);
01127
01128 HAVE_LOCK_CHECK (connection);
01129
01130 _dbus_connection_unref_unlocked (connection);
01131
01132 return we_acquired;
01133 }
01134
01142 static void
01143 _dbus_connection_release_io_path (DBusConnection *connection)
01144 {
01145 HAVE_LOCK_CHECK (connection);
01146
01147 _dbus_verbose ("locking io_path_mutex\n");
01148 _dbus_cmutex_lock (connection->io_path_mutex);
01149
01150 _dbus_assert (connection->io_path_acquired);
01151
01152 _dbus_verbose ("start connection->io_path_acquired = %d\n",
01153 connection->io_path_acquired);
01154
01155 connection->io_path_acquired = FALSE;
01156 _dbus_condvar_wake_one (connection->io_path_cond);
01157
01158 _dbus_verbose ("unlocking io_path_mutex\n");
01159 _dbus_cmutex_unlock (connection->io_path_mutex);
01160 }
01161
01197 void
01198 _dbus_connection_do_iteration_unlocked (DBusConnection *connection,
01199 DBusPendingCall *pending,
01200 unsigned int flags,
01201 int timeout_milliseconds)
01202 {
01203 _dbus_verbose ("start\n");
01204
01205 HAVE_LOCK_CHECK (connection);
01206
01207 if (connection->n_outgoing == 0)
01208 flags &= ~DBUS_ITERATION_DO_WRITING;
01209
01210 if (_dbus_connection_acquire_io_path (connection,
01211 (flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0))
01212 {
01213 HAVE_LOCK_CHECK (connection);
01214
01215 if ( (pending != NULL) && _dbus_pending_call_get_completed_unlocked(pending))
01216 {
01217 _dbus_verbose ("pending call completed while acquiring I/O path");
01218 }
01219 else if ( (pending != NULL) &&
01220 _dbus_connection_peek_for_reply_unlocked (connection,
01221 _dbus_pending_call_get_reply_serial_unlocked (pending)))
01222 {
01223 _dbus_verbose ("pending call completed while acquiring I/O path (reply found in queue)");
01224 }
01225 else
01226 {
01227 _dbus_transport_do_iteration (connection->transport,
01228 flags, timeout_milliseconds);
01229 }
01230
01231 _dbus_connection_release_io_path (connection);
01232 }
01233
01234 HAVE_LOCK_CHECK (connection);
01235
01236 _dbus_verbose ("end\n");
01237 }
01238
01248 DBusConnection*
01249 _dbus_connection_new_for_transport (DBusTransport *transport)
01250 {
01251 DBusConnection *connection;
01252 DBusWatchList *watch_list;
01253 DBusTimeoutList *timeout_list;
01254 DBusHashTable *pending_replies;
01255 DBusList *disconnect_link;
01256 DBusMessage *disconnect_message;
01257 DBusCounter *outgoing_counter;
01258 DBusObjectTree *objects;
01259
01260 watch_list = NULL;
01261 connection = NULL;
01262 pending_replies = NULL;
01263 timeout_list = NULL;
01264 disconnect_link = NULL;
01265 disconnect_message = NULL;
01266 outgoing_counter = NULL;
01267 objects = NULL;
01268
01269 watch_list = _dbus_watch_list_new ();
01270 if (watch_list == NULL)
01271 goto error;
01272
01273 timeout_list = _dbus_timeout_list_new ();
01274 if (timeout_list == NULL)
01275 goto error;
01276
01277 pending_replies =
01278 _dbus_hash_table_new (DBUS_HASH_INT,
01279 NULL,
01280 (DBusFreeFunction)free_pending_call_on_hash_removal);
01281 if (pending_replies == NULL)
01282 goto error;
01283
01284 connection = dbus_new0 (DBusConnection, 1);
01285 if (connection == NULL)
01286 goto error;
01287
01288 _dbus_rmutex_new_at_location (&connection->mutex);
01289 if (connection->mutex == NULL)
01290 goto error;
01291
01292 _dbus_cmutex_new_at_location (&connection->io_path_mutex);
01293 if (connection->io_path_mutex == NULL)
01294 goto error;
01295
01296 _dbus_cmutex_new_at_location (&connection->dispatch_mutex);
01297 if (connection->dispatch_mutex == NULL)
01298 goto error;
01299
01300 _dbus_condvar_new_at_location (&connection->dispatch_cond);
01301 if (connection->dispatch_cond == NULL)
01302 goto error;
01303
01304 _dbus_condvar_new_at_location (&connection->io_path_cond);
01305 if (connection->io_path_cond == NULL)
01306 goto error;
01307
01308 _dbus_rmutex_new_at_location (&connection->slot_mutex);
01309 if (connection->slot_mutex == NULL)
01310 goto error;
01311
01312 disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL,
01313 DBUS_INTERFACE_LOCAL,
01314 "Disconnected");
01315
01316 if (disconnect_message == NULL)
01317 goto error;
01318
01319 disconnect_link = _dbus_list_alloc_link (disconnect_message);
01320 if (disconnect_link == NULL)
01321 goto error;
01322
01323 outgoing_counter = _dbus_counter_new ();
01324 if (outgoing_counter == NULL)
01325 goto error;
01326
01327 objects = _dbus_object_tree_new (connection);
01328 if (objects == NULL)
01329 goto error;
01330
01331 if (_dbus_modify_sigpipe)
01332 _dbus_disable_sigpipe ();
01333
01334
01335 _dbus_atomic_inc (&connection->refcount);
01336 connection->transport = transport;
01337 connection->watches = watch_list;
01338 connection->timeouts = timeout_list;
01339 connection->pending_replies = pending_replies;
01340 connection->outgoing_counter = outgoing_counter;
01341 connection->filter_list = NULL;
01342 connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE;
01343 connection->objects = objects;
01344 connection->exit_on_disconnect = FALSE;
01345 connection->shareable = FALSE;
01346 connection->route_peer_messages = FALSE;
01347 connection->disconnected_message_arrived = FALSE;
01348 connection->disconnected_message_processed = FALSE;
01349
01350 #if defined(DBUS_ENABLE_CHECKS) || defined(DBUS_ENABLE_ASSERT)
01351 connection->generation = _dbus_current_generation;
01352 #endif
01353
01354 _dbus_data_slot_list_init (&connection->slot_list);
01355
01356 connection->client_serial = 1;
01357
01358 connection->disconnect_message_link = disconnect_link;
01359
01360 CONNECTION_LOCK (connection);
01361
01362 if (!_dbus_transport_set_connection (transport, connection))
01363 {
01364 CONNECTION_UNLOCK (connection);
01365
01366 goto error;
01367 }
01368
01369 _dbus_transport_ref (transport);
01370
01371 CONNECTION_UNLOCK (connection);
01372
01373 _dbus_connection_trace_ref (connection, 0, 1, "new_for_transport");
01374 return connection;
01375
01376 error:
01377 if (disconnect_message != NULL)
01378 dbus_message_unref (disconnect_message);
01379
01380 if (disconnect_link != NULL)
01381 _dbus_list_free_link (disconnect_link);
01382
01383 if (connection != NULL)
01384 {
01385 _dbus_condvar_free_at_location (&connection->io_path_cond);
01386 _dbus_condvar_free_at_location (&connection->dispatch_cond);
01387 _dbus_rmutex_free_at_location (&connection->mutex);
01388 _dbus_cmutex_free_at_location (&connection->io_path_mutex);
01389 _dbus_cmutex_free_at_location (&connection->dispatch_mutex);
01390 _dbus_rmutex_free_at_location (&connection->slot_mutex);
01391 dbus_free (connection);
01392 }
01393 if (pending_replies)
01394 _dbus_hash_table_unref (pending_replies);
01395
01396 if (watch_list)
01397 _dbus_watch_list_free (watch_list);
01398
01399 if (timeout_list)
01400 _dbus_timeout_list_free (timeout_list);
01401
01402 if (outgoing_counter)
01403 _dbus_counter_unref (outgoing_counter);
01404
01405 if (objects)
01406 _dbus_object_tree_unref (objects);
01407
01408 return NULL;
01409 }
01410
01418 DBusConnection *
01419 _dbus_connection_ref_unlocked (DBusConnection *connection)
01420 {
01421 dbus_int32_t old_refcount;
01422
01423 _dbus_assert (connection != NULL);
01424 _dbus_assert (connection->generation == _dbus_current_generation);
01425
01426 HAVE_LOCK_CHECK (connection);
01427
01428 old_refcount = _dbus_atomic_inc (&connection->refcount);
01429 _dbus_connection_trace_ref (connection, old_refcount, old_refcount + 1,
01430 "ref_unlocked");
01431
01432 return connection;
01433 }
01434
01441 void
01442 _dbus_connection_unref_unlocked (DBusConnection *connection)
01443 {
01444 dbus_int32_t old_refcount;
01445
01446 HAVE_LOCK_CHECK (connection);
01447
01448 _dbus_assert (connection != NULL);
01449
01450 old_refcount = _dbus_atomic_dec (&connection->refcount);
01451
01452 _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1,
01453 "unref_unlocked");
01454
01455 if (old_refcount == 1)
01456 _dbus_connection_last_unref (connection);
01457 }
01458
01459 static dbus_uint32_t
01460 _dbus_connection_get_next_client_serial (DBusConnection *connection)
01461 {
01462 dbus_uint32_t serial;
01463
01464 serial = connection->client_serial++;
01465
01466 if (connection->client_serial == 0)
01467 connection->client_serial = 1;
01468
01469 return serial;
01470 }
01471
01485 dbus_bool_t
01486 _dbus_connection_handle_watch (DBusWatch *watch,
01487 unsigned int condition,
01488 void *data)
01489 {
01490 DBusConnection *connection;
01491 dbus_bool_t retval;
01492 DBusDispatchStatus status;
01493
01494 connection = data;
01495
01496 _dbus_verbose ("start\n");
01497
01498 CONNECTION_LOCK (connection);
01499
01500 if (!_dbus_connection_acquire_io_path (connection, 1))
01501 {
01502
01503 CONNECTION_UNLOCK (connection);
01504 return TRUE;
01505 }
01506
01507 HAVE_LOCK_CHECK (connection);
01508 retval = _dbus_transport_handle_watch (connection->transport,
01509 watch, condition);
01510
01511 _dbus_connection_release_io_path (connection);
01512
01513 HAVE_LOCK_CHECK (connection);
01514
01515 _dbus_verbose ("middle\n");
01516
01517 status = _dbus_connection_get_dispatch_status_unlocked (connection);
01518
01519
01520 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01521
01522 _dbus_verbose ("end\n");
01523
01524 return retval;
01525 }
01526
01527
01528 static DBusHashTable *shared_connections = NULL;
01529 static DBusList *shared_connections_no_guid = NULL;
01530
01531 static void
01532 close_connection_on_shutdown (DBusConnection *connection)
01533 {
01534 DBusMessage *message;
01535
01536 dbus_connection_ref (connection);
01537 _dbus_connection_close_possibly_shared (connection);
01538
01539
01540 while ((message = dbus_connection_pop_message (connection)))
01541 {
01542 dbus_message_unref (message);
01543 }
01544 dbus_connection_unref (connection);
01545 }
01546
01547 static void
01548 shared_connections_shutdown (void *data)
01549 {
01550 int n_entries;
01551
01552 if (!_DBUS_LOCK (shared_connections))
01553 {
01554
01555
01556 return;
01557 }
01558
01559
01560 while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0)
01561 {
01562 DBusConnection *connection;
01563 DBusHashIter iter;
01564
01565 _dbus_hash_iter_init (shared_connections, &iter);
01566 _dbus_hash_iter_next (&iter);
01567
01568 connection = _dbus_hash_iter_get_value (&iter);
01569
01570 _DBUS_UNLOCK (shared_connections);
01571 close_connection_on_shutdown (connection);
01572 if (!_DBUS_LOCK (shared_connections))
01573 _dbus_assert_not_reached ("global locks were already initialized");
01574
01575
01576 _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) < n_entries);
01577 }
01578
01579 _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) == 0);
01580
01581 _dbus_hash_table_unref (shared_connections);
01582 shared_connections = NULL;
01583
01584 if (shared_connections_no_guid != NULL)
01585 {
01586 DBusConnection *connection;
01587 connection = _dbus_list_pop_first (&shared_connections_no_guid);
01588 while (connection != NULL)
01589 {
01590 _DBUS_UNLOCK (shared_connections);
01591 close_connection_on_shutdown (connection);
01592 if (!_DBUS_LOCK (shared_connections))
01593 _dbus_assert_not_reached ("global locks were already initialized");
01594 connection = _dbus_list_pop_first (&shared_connections_no_guid);
01595 }
01596 }
01597
01598 shared_connections_no_guid = NULL;
01599
01600 _DBUS_UNLOCK (shared_connections);
01601 }
01602
01603 static dbus_bool_t
01604 connection_lookup_shared (DBusAddressEntry *entry,
01605 DBusConnection **result)
01606 {
01607 _dbus_verbose ("checking for existing connection\n");
01608
01609 *result = NULL;
01610
01611 if (!_DBUS_LOCK (shared_connections))
01612 {
01613
01614
01615 return FALSE;
01616 }
01617
01618 if (shared_connections == NULL)
01619 {
01620 _dbus_verbose ("creating shared_connections hash table\n");
01621
01622 shared_connections = _dbus_hash_table_new (DBUS_HASH_STRING,
01623 dbus_free,
01624 NULL);
01625 if (shared_connections == NULL)
01626 {
01627 _DBUS_UNLOCK (shared_connections);
01628 return FALSE;
01629 }
01630
01631 if (!_dbus_register_shutdown_func (shared_connections_shutdown, NULL))
01632 {
01633 _dbus_hash_table_unref (shared_connections);
01634 shared_connections = NULL;
01635 _DBUS_UNLOCK (shared_connections);
01636 return FALSE;
01637 }
01638
01639 _dbus_verbose (" successfully created shared_connections\n");
01640
01641 _DBUS_UNLOCK (shared_connections);
01642 return TRUE;
01643 }
01644 else
01645 {
01646 const char *guid;
01647
01648 guid = dbus_address_entry_get_value (entry, "guid");
01649
01650 if (guid != NULL)
01651 {
01652 DBusConnection *connection;
01653
01654 connection = _dbus_hash_table_lookup_string (shared_connections,
01655 guid);
01656
01657 if (connection)
01658 {
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673 CONNECTION_LOCK (connection);
01674 if (_dbus_connection_get_is_connected_unlocked (connection))
01675 {
01676 _dbus_connection_ref_unlocked (connection);
01677 *result = connection;
01678 _dbus_verbose ("looked up existing connection to server guid %s\n",
01679 guid);
01680 }
01681 else
01682 {
01683 _dbus_verbose ("looked up existing connection to server guid %s but it was disconnected so ignoring it\n",
01684 guid);
01685 }
01686 CONNECTION_UNLOCK (connection);
01687 }
01688 }
01689
01690 _DBUS_UNLOCK (shared_connections);
01691 return TRUE;
01692 }
01693 }
01694
01695 static dbus_bool_t
01696 connection_record_shared_unlocked (DBusConnection *connection,
01697 const char *guid)
01698 {
01699 char *guid_key;
01700 char *guid_in_connection;
01701
01702 HAVE_LOCK_CHECK (connection);
01703 _dbus_assert (connection->server_guid == NULL);
01704 _dbus_assert (connection->shareable);
01705
01706
01707
01708
01709
01710 _dbus_connection_ref_unlocked (connection);
01711
01712 if (guid == NULL)
01713 {
01714 if (!_DBUS_LOCK (shared_connections))
01715 return FALSE;
01716
01717 if (!_dbus_list_prepend (&shared_connections_no_guid, connection))
01718 {
01719 _DBUS_UNLOCK (shared_connections);
01720 return FALSE;
01721 }
01722
01723 _DBUS_UNLOCK (shared_connections);
01724 return TRUE;
01725 }
01726
01727
01728
01729
01730
01731
01732 guid_key = _dbus_strdup (guid);
01733 if (guid_key == NULL)
01734 return FALSE;
01735
01736 guid_in_connection = _dbus_strdup (guid);
01737 if (guid_in_connection == NULL)
01738 {
01739 dbus_free (guid_key);
01740 return FALSE;
01741 }
01742
01743 if (!_DBUS_LOCK (shared_connections))
01744 {
01745 dbus_free (guid_in_connection);
01746 dbus_free (guid_key);
01747 return FALSE;
01748 }
01749
01750 _dbus_assert (shared_connections != NULL);
01751
01752 if (!_dbus_hash_table_insert_string (shared_connections,
01753 guid_key, connection))
01754 {
01755 dbus_free (guid_key);
01756 dbus_free (guid_in_connection);
01757 _DBUS_UNLOCK (shared_connections);
01758 return FALSE;
01759 }
01760
01761 connection->server_guid = guid_in_connection;
01762
01763 _dbus_verbose ("stored connection to %s to be shared\n",
01764 connection->server_guid);
01765
01766 _DBUS_UNLOCK (shared_connections);
01767
01768 _dbus_assert (connection->server_guid != NULL);
01769
01770 return TRUE;
01771 }
01772
01773 static void
01774 connection_forget_shared_unlocked (DBusConnection *connection)
01775 {
01776 HAVE_LOCK_CHECK (connection);
01777
01778 if (!connection->shareable)
01779 return;
01780
01781 if (!_DBUS_LOCK (shared_connections))
01782 {
01783
01784
01785 return;
01786 }
01787
01788 if (connection->server_guid != NULL)
01789 {
01790 _dbus_verbose ("dropping connection to %s out of the shared table\n",
01791 connection->server_guid);
01792
01793 if (!_dbus_hash_table_remove_string (shared_connections,
01794 connection->server_guid))
01795 _dbus_assert_not_reached ("connection was not in the shared table");
01796
01797 dbus_free (connection->server_guid);
01798 connection->server_guid = NULL;
01799 }
01800 else
01801 {
01802 _dbus_list_remove (&shared_connections_no_guid, connection);
01803 }
01804
01805 _DBUS_UNLOCK (shared_connections);
01806
01807
01808 _dbus_connection_unref_unlocked (connection);
01809 }
01810
01811 static DBusConnection*
01812 connection_try_from_address_entry (DBusAddressEntry *entry,
01813 DBusError *error)
01814 {
01815 DBusTransport *transport;
01816 DBusConnection *connection;
01817
01818 transport = _dbus_transport_open (entry, error);
01819
01820 if (transport == NULL)
01821 {
01822 _DBUS_ASSERT_ERROR_IS_SET (error);
01823 return NULL;
01824 }
01825
01826 connection = _dbus_connection_new_for_transport (transport);
01827
01828 _dbus_transport_unref (transport);
01829
01830 if (connection == NULL)
01831 {
01832 _DBUS_SET_OOM (error);
01833 return NULL;
01834 }
01835
01836 #ifndef DBUS_DISABLE_CHECKS
01837 _dbus_assert (!connection->have_connection_lock);
01838 #endif
01839 return connection;
01840 }
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854 static DBusConnection*
01855 _dbus_connection_open_internal (const char *address,
01856 dbus_bool_t shared,
01857 DBusError *error)
01858 {
01859 DBusConnection *connection;
01860 DBusAddressEntry **entries;
01861 DBusError tmp_error = DBUS_ERROR_INIT;
01862 DBusError first_error = DBUS_ERROR_INIT;
01863 int len, i;
01864
01865 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01866
01867 _dbus_verbose ("opening %s connection to: %s\n",
01868 shared ? "shared" : "private", address);
01869
01870 if (!dbus_parse_address (address, &entries, &len, error))
01871 return NULL;
01872
01873 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01874
01875 connection = NULL;
01876
01877 for (i = 0; i < len; i++)
01878 {
01879 if (shared)
01880 {
01881 if (!connection_lookup_shared (entries[i], &connection))
01882 _DBUS_SET_OOM (&tmp_error);
01883 }
01884
01885 if (connection == NULL)
01886 {
01887 connection = connection_try_from_address_entry (entries[i],
01888 &tmp_error);
01889
01890 if (connection != NULL && shared)
01891 {
01892 const char *guid;
01893
01894 connection->shareable = TRUE;
01895
01896
01897 guid = dbus_address_entry_get_value (entries[i], "guid");
01898
01899 CONNECTION_LOCK (connection);
01900
01901 if (!connection_record_shared_unlocked (connection, guid))
01902 {
01903 _DBUS_SET_OOM (&tmp_error);
01904 _dbus_connection_close_possibly_shared_and_unlock (connection);
01905 dbus_connection_unref (connection);
01906 connection = NULL;
01907 }
01908 else
01909 CONNECTION_UNLOCK (connection);
01910 }
01911 }
01912
01913 if (connection)
01914 break;
01915
01916 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
01917
01918 if (i == 0)
01919 dbus_move_error (&tmp_error, &first_error);
01920 else
01921 dbus_error_free (&tmp_error);
01922 }
01923
01924 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01925 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
01926
01927 if (connection == NULL)
01928 {
01929 _DBUS_ASSERT_ERROR_IS_SET (&first_error);
01930 dbus_move_error (&first_error, error);
01931 }
01932 else
01933 dbus_error_free (&first_error);
01934
01935 dbus_address_entries_free (entries);
01936 return connection;
01937 }
01938
01947 void
01948 _dbus_connection_close_possibly_shared (DBusConnection *connection)
01949 {
01950 _dbus_assert (connection != NULL);
01951 _dbus_assert (connection->generation == _dbus_current_generation);
01952
01953 CONNECTION_LOCK (connection);
01954 _dbus_connection_close_possibly_shared_and_unlock (connection);
01955 }
01956
01957 static DBusPreallocatedSend*
01958 _dbus_connection_preallocate_send_unlocked (DBusConnection *connection)
01959 {
01960 DBusPreallocatedSend *preallocated;
01961
01962 HAVE_LOCK_CHECK (connection);
01963
01964 _dbus_assert (connection != NULL);
01965
01966 preallocated = dbus_new (DBusPreallocatedSend, 1);
01967 if (preallocated == NULL)
01968 return NULL;
01969
01970 preallocated->queue_link = _dbus_list_alloc_link (NULL);
01971 if (preallocated->queue_link == NULL)
01972 goto failed_0;
01973
01974 preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter);
01975 if (preallocated->counter_link == NULL)
01976 goto failed_1;
01977
01978 _dbus_counter_ref (preallocated->counter_link->data);
01979
01980 preallocated->connection = connection;
01981
01982 return preallocated;
01983
01984 failed_1:
01985 _dbus_list_free_link (preallocated->queue_link);
01986 failed_0:
01987 dbus_free (preallocated);
01988
01989 return NULL;
01990 }
01991
01992
01993 static void
01994 _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *connection,
01995 DBusPreallocatedSend *preallocated,
01996 DBusMessage *message,
01997 dbus_uint32_t *client_serial)
01998 {
01999 dbus_uint32_t serial;
02000
02001 preallocated->queue_link->data = message;
02002 _dbus_list_prepend_link (&connection->outgoing_messages,
02003 preallocated->queue_link);
02004
02005
02006
02007 _dbus_message_add_counter_link (message,
02008 preallocated->counter_link);
02009
02010 dbus_free (preallocated);
02011 preallocated = NULL;
02012
02013 dbus_message_ref (message);
02014
02015 connection->n_outgoing += 1;
02016
02017 _dbus_verbose ("Message %p (%s %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
02018 message,
02019 dbus_message_type_to_string (dbus_message_get_type (message)),
02020 dbus_message_get_path (message) ?
02021 dbus_message_get_path (message) :
02022 "no path",
02023 dbus_message_get_interface (message) ?
02024 dbus_message_get_interface (message) :
02025 "no interface",
02026 dbus_message_get_member (message) ?
02027 dbus_message_get_member (message) :
02028 "no member",
02029 dbus_message_get_signature (message),
02030 dbus_message_get_destination (message) ?
02031 dbus_message_get_destination (message) :
02032 "null",
02033 connection,
02034 connection->n_outgoing);
02035
02036 if (dbus_message_get_serial (message) == 0)
02037 {
02038 serial = _dbus_connection_get_next_client_serial (connection);
02039 dbus_message_set_serial (message, serial);
02040 if (client_serial)
02041 *client_serial = serial;
02042 }
02043 else
02044 {
02045 if (client_serial)
02046 *client_serial = dbus_message_get_serial (message);
02047 }
02048
02049 _dbus_verbose ("Message %p serial is %u\n",
02050 message, dbus_message_get_serial (message));
02051
02052 dbus_message_lock (message);
02053
02054
02055
02056
02057 _dbus_connection_do_iteration_unlocked (connection,
02058 NULL,
02059 DBUS_ITERATION_DO_WRITING,
02060 -1);
02061
02062
02063 if (connection->n_outgoing > 0)
02064 _dbus_connection_wakeup_mainloop (connection);
02065 }
02066
02067 static void
02068 _dbus_connection_send_preallocated_and_unlock (DBusConnection *connection,
02069 DBusPreallocatedSend *preallocated,
02070 DBusMessage *message,
02071 dbus_uint32_t *client_serial)
02072 {
02073 DBusDispatchStatus status;
02074
02075 HAVE_LOCK_CHECK (connection);
02076
02077 _dbus_connection_send_preallocated_unlocked_no_update (connection,
02078 preallocated,
02079 message, client_serial);
02080
02081 _dbus_verbose ("middle\n");
02082 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02083
02084
02085 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02086 }
02087
02097 dbus_bool_t
02098 _dbus_connection_send_and_unlock (DBusConnection *connection,
02099 DBusMessage *message,
02100 dbus_uint32_t *client_serial)
02101 {
02102 DBusPreallocatedSend *preallocated;
02103
02104 _dbus_assert (connection != NULL);
02105 _dbus_assert (message != NULL);
02106
02107 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
02108 if (preallocated == NULL)
02109 {
02110 CONNECTION_UNLOCK (connection);
02111 return FALSE;
02112 }
02113
02114 _dbus_connection_send_preallocated_and_unlock (connection,
02115 preallocated,
02116 message,
02117 client_serial);
02118 return TRUE;
02119 }
02120
02145 void
02146 _dbus_connection_close_if_only_one_ref (DBusConnection *connection)
02147 {
02148 dbus_int32_t refcount;
02149
02150 CONNECTION_LOCK (connection);
02151
02152 refcount = _dbus_atomic_get (&connection->refcount);
02153
02154 _dbus_assert (refcount >= 1);
02155
02156 if (refcount == 1)
02157 _dbus_connection_close_possibly_shared_and_unlock (connection);
02158 else
02159 CONNECTION_UNLOCK (connection);
02160 }
02161
02162
02172 static void
02173 _dbus_memory_pause_based_on_timeout (int timeout_milliseconds)
02174 {
02175 if (timeout_milliseconds == -1)
02176 _dbus_sleep_milliseconds (1000);
02177 else if (timeout_milliseconds < 100)
02178 ;
02179 else if (timeout_milliseconds <= 1000)
02180 _dbus_sleep_milliseconds (timeout_milliseconds / 3);
02181 else
02182 _dbus_sleep_milliseconds (1000);
02183 }
02184
02185 static DBusMessage *
02186 generate_local_error_message (dbus_uint32_t serial,
02187 char *error_name,
02188 char *error_msg)
02189 {
02190 DBusMessage *message;
02191 message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
02192 if (!message)
02193 goto out;
02194
02195 if (!dbus_message_set_error_name (message, error_name))
02196 {
02197 dbus_message_unref (message);
02198 message = NULL;
02199 goto out;
02200 }
02201
02202 dbus_message_set_no_reply (message, TRUE);
02203
02204 if (!dbus_message_set_reply_serial (message,
02205 serial))
02206 {
02207 dbus_message_unref (message);
02208 message = NULL;
02209 goto out;
02210 }
02211
02212 if (error_msg != NULL)
02213 {
02214 DBusMessageIter iter;
02215
02216 dbus_message_iter_init_append (message, &iter);
02217 if (!dbus_message_iter_append_basic (&iter,
02218 DBUS_TYPE_STRING,
02219 &error_msg))
02220 {
02221 dbus_message_unref (message);
02222 message = NULL;
02223 goto out;
02224 }
02225 }
02226
02227 out:
02228 return message;
02229 }
02230
02231
02232
02233
02234 static dbus_bool_t
02235 _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection,
02236 dbus_uint32_t client_serial)
02237 {
02238 DBusList *link;
02239 HAVE_LOCK_CHECK (connection);
02240
02241 link = _dbus_list_get_first_link (&connection->incoming_messages);
02242
02243 while (link != NULL)
02244 {
02245 DBusMessage *reply = link->data;
02246
02247 if (dbus_message_get_reply_serial (reply) == client_serial)
02248 {
02249 _dbus_verbose ("%s reply to %d found in queue\n", _DBUS_FUNCTION_NAME, client_serial);
02250 return TRUE;
02251 }
02252 link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02253 }
02254
02255 return FALSE;
02256 }
02257
02258
02259
02260
02261 static DBusMessage*
02262 check_for_reply_unlocked (DBusConnection *connection,
02263 dbus_uint32_t client_serial)
02264 {
02265 DBusList *link;
02266
02267 HAVE_LOCK_CHECK (connection);
02268
02269 link = _dbus_list_get_first_link (&connection->incoming_messages);
02270
02271 while (link != NULL)
02272 {
02273 DBusMessage *reply = link->data;
02274
02275 if (dbus_message_get_reply_serial (reply) == client_serial)
02276 {
02277 _dbus_list_remove_link (&connection->incoming_messages, link);
02278 connection->n_incoming -= 1;
02279 return reply;
02280 }
02281 link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02282 }
02283
02284 return NULL;
02285 }
02286
02287 static void
02288 connection_timeout_and_complete_all_pending_calls_unlocked (DBusConnection *connection)
02289 {
02290
02291
02292
02293
02294
02295 while (_dbus_hash_table_get_n_entries (connection->pending_replies) > 0)
02296 {
02297 DBusPendingCall *pending;
02298 DBusHashIter iter;
02299
02300 _dbus_hash_iter_init (connection->pending_replies, &iter);
02301 _dbus_hash_iter_next (&iter);
02302
02303 pending = _dbus_hash_iter_get_value (&iter);
02304 _dbus_pending_call_ref_unlocked (pending);
02305
02306 _dbus_pending_call_queue_timeout_error_unlocked (pending,
02307 connection);
02308
02309 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
02310 _dbus_connection_remove_timeout_unlocked (connection,
02311 _dbus_pending_call_get_timeout_unlocked (pending));
02312 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
02313 _dbus_hash_iter_remove_entry (&iter);
02314
02315 _dbus_pending_call_unref_and_unlock (pending);
02316 CONNECTION_LOCK (connection);
02317 }
02318 HAVE_LOCK_CHECK (connection);
02319 }
02320
02321 static void
02322 complete_pending_call_and_unlock (DBusConnection *connection,
02323 DBusPendingCall *pending,
02324 DBusMessage *message)
02325 {
02326 _dbus_pending_call_set_reply_unlocked (pending, message);
02327 _dbus_pending_call_ref_unlocked (pending);
02328 _dbus_connection_detach_pending_call_and_unlock (connection, pending);
02329
02330
02331 _dbus_pending_call_complete (pending);
02332 dbus_pending_call_unref (pending);
02333 }
02334
02335 static dbus_bool_t
02336 check_for_reply_and_update_dispatch_unlocked (DBusConnection *connection,
02337 DBusPendingCall *pending)
02338 {
02339 DBusMessage *reply;
02340 DBusDispatchStatus status;
02341
02342 reply = check_for_reply_unlocked (connection,
02343 _dbus_pending_call_get_reply_serial_unlocked (pending));
02344 if (reply != NULL)
02345 {
02346 _dbus_verbose ("checked for reply\n");
02347
02348 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
02349
02350 complete_pending_call_and_unlock (connection, pending, reply);
02351 dbus_message_unref (reply);
02352
02353 CONNECTION_LOCK (connection);
02354 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02355 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02356 dbus_pending_call_unref (pending);
02357
02358 return TRUE;
02359 }
02360
02361 return FALSE;
02362 }
02363
02378 void
02379 _dbus_connection_block_pending_call (DBusPendingCall *pending)
02380 {
02381 long start_tv_sec, start_tv_usec;
02382 long tv_sec, tv_usec;
02383 DBusDispatchStatus status;
02384 DBusConnection *connection;
02385 dbus_uint32_t client_serial;
02386 DBusTimeout *timeout;
02387 int timeout_milliseconds, elapsed_milliseconds;
02388
02389 _dbus_assert (pending != NULL);
02390
02391 if (dbus_pending_call_get_completed (pending))
02392 return;
02393
02394 dbus_pending_call_ref (pending);
02395
02396 connection = _dbus_pending_call_get_connection_and_lock (pending);
02397
02398
02399 _dbus_connection_flush_unlocked (connection);
02400
02401 client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
02402
02403
02404
02405
02406
02407 timeout = _dbus_pending_call_get_timeout_unlocked (pending);
02408 _dbus_get_monotonic_time (&start_tv_sec, &start_tv_usec);
02409 if (timeout)
02410 {
02411 timeout_milliseconds = dbus_timeout_get_interval (timeout);
02412
02413 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec\n",
02414 timeout_milliseconds,
02415 client_serial,
02416 start_tv_sec, start_tv_usec);
02417 }
02418 else
02419 {
02420 timeout_milliseconds = -1;
02421
02422 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block for reply serial %u\n", client_serial);
02423 }
02424
02425
02426
02427 if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02428 return;
02429
02430
02431
02432 _dbus_connection_do_iteration_unlocked (connection,
02433 pending,
02434 DBUS_ITERATION_DO_READING |
02435 DBUS_ITERATION_BLOCK,
02436 timeout_milliseconds);
02437
02438 recheck_status:
02439
02440 _dbus_verbose ("top of recheck\n");
02441
02442 HAVE_LOCK_CHECK (connection);
02443
02444
02445
02446 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02447
02448
02449
02450
02451 if (_dbus_pending_call_get_completed_unlocked (pending))
02452 {
02453 _dbus_verbose ("Pending call completed by dispatch\n");
02454 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02455 dbus_pending_call_unref (pending);
02456 return;
02457 }
02458
02459 if (status == DBUS_DISPATCH_DATA_REMAINS)
02460 {
02461 if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02462 return;
02463 }
02464
02465 _dbus_get_monotonic_time (&tv_sec, &tv_usec);
02466 elapsed_milliseconds = (tv_sec - start_tv_sec) * 1000 +
02467 (tv_usec - start_tv_usec) / 1000;
02468
02469 if (!_dbus_connection_get_is_connected_unlocked (connection))
02470 {
02471 DBusMessage *error_msg;
02472
02473 error_msg = generate_local_error_message (client_serial,
02474 DBUS_ERROR_DISCONNECTED,
02475 "Connection was disconnected before a reply was received");
02476
02477
02478 complete_pending_call_and_unlock (connection, pending, error_msg);
02479 if (error_msg != NULL)
02480 dbus_message_unref (error_msg);
02481 dbus_pending_call_unref (pending);
02482 return;
02483 }
02484 else if (connection->disconnect_message_link == NULL)
02485 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
02486 else if (timeout == NULL)
02487 {
02488 if (status == DBUS_DISPATCH_NEED_MEMORY)
02489 {
02490
02491
02492
02493
02494 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02495
02496 _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
02497 }
02498 else
02499 {
02500
02501 _dbus_connection_do_iteration_unlocked (connection,
02502 pending,
02503 DBUS_ITERATION_DO_READING |
02504 DBUS_ITERATION_BLOCK,
02505 timeout_milliseconds - elapsed_milliseconds);
02506 }
02507
02508 goto recheck_status;
02509 }
02510 else if (tv_sec < start_tv_sec)
02511 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
02512 else if (elapsed_milliseconds < timeout_milliseconds)
02513 {
02514 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds - elapsed_milliseconds);
02515
02516 if (status == DBUS_DISPATCH_NEED_MEMORY)
02517 {
02518
02519
02520
02521
02522 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02523
02524 _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
02525 }
02526 else
02527 {
02528
02529 _dbus_connection_do_iteration_unlocked (connection,
02530 NULL,
02531 DBUS_ITERATION_DO_READING |
02532 DBUS_ITERATION_BLOCK,
02533 timeout_milliseconds - elapsed_milliseconds);
02534 }
02535
02536 goto recheck_status;
02537 }
02538
02539 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %d milliseconds and got no reply\n",
02540 elapsed_milliseconds);
02541
02542 _dbus_assert (!_dbus_pending_call_get_completed_unlocked (pending));
02543
02544
02545 complete_pending_call_and_unlock (connection, pending, NULL);
02546
02547
02548 CONNECTION_LOCK (connection);
02549 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02550 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02551 dbus_pending_call_unref (pending);
02552 }
02553
02559 int
02560 _dbus_connection_get_pending_fds_count (DBusConnection *connection)
02561 {
02562 return _dbus_transport_get_pending_fds_count (connection->transport);
02563 }
02564
02572 void
02573 _dbus_connection_set_pending_fds_function (DBusConnection *connection,
02574 DBusPendingFdsChangeFunction callback,
02575 void *data)
02576 {
02577 _dbus_transport_set_pending_fds_function (connection->transport,
02578 callback, data);
02579 }
02580
02617 DBusConnection*
02618 dbus_connection_open (const char *address,
02619 DBusError *error)
02620 {
02621 DBusConnection *connection;
02622
02623 _dbus_return_val_if_fail (address != NULL, NULL);
02624 _dbus_return_val_if_error_is_set (error, NULL);
02625
02626 connection = _dbus_connection_open_internal (address,
02627 TRUE,
02628 error);
02629
02630 return connection;
02631 }
02632
02660 DBusConnection*
02661 dbus_connection_open_private (const char *address,
02662 DBusError *error)
02663 {
02664 DBusConnection *connection;
02665
02666 _dbus_return_val_if_fail (address != NULL, NULL);
02667 _dbus_return_val_if_error_is_set (error, NULL);
02668
02669 connection = _dbus_connection_open_internal (address,
02670 FALSE,
02671 error);
02672
02673 return connection;
02674 }
02675
02682 DBusConnection *
02683 dbus_connection_ref (DBusConnection *connection)
02684 {
02685 dbus_int32_t old_refcount;
02686
02687 _dbus_return_val_if_fail (connection != NULL, NULL);
02688 _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
02689 old_refcount = _dbus_atomic_inc (&connection->refcount);
02690 _dbus_connection_trace_ref (connection, old_refcount, old_refcount + 1,
02691 "ref");
02692
02693 return connection;
02694 }
02695
02696 static void
02697 free_outgoing_message (void *element,
02698 void *data)
02699 {
02700 DBusMessage *message = element;
02701 DBusConnection *connection = data;
02702
02703 _dbus_message_remove_counter (message, connection->outgoing_counter);
02704 dbus_message_unref (message);
02705 }
02706
02707
02708
02709
02710
02711 static void
02712 _dbus_connection_last_unref (DBusConnection *connection)
02713 {
02714 DBusList *link;
02715
02716 _dbus_verbose ("Finalizing connection %p\n", connection);
02717
02718 _dbus_assert (_dbus_atomic_get (&connection->refcount) == 0);
02719
02720
02721
02722
02723 _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
02724 _dbus_assert (connection->server_guid == NULL);
02725
02726
02727 _dbus_object_tree_free_all_unlocked (connection->objects);
02728
02729 dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
02730 dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
02731 dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
02732 dbus_connection_set_windows_user_function (connection, NULL, NULL, NULL);
02733
02734 _dbus_watch_list_free (connection->watches);
02735 connection->watches = NULL;
02736
02737 _dbus_timeout_list_free (connection->timeouts);
02738 connection->timeouts = NULL;
02739
02740 _dbus_data_slot_list_free (&connection->slot_list);
02741
02742 link = _dbus_list_get_first_link (&connection->filter_list);
02743 while (link != NULL)
02744 {
02745 DBusMessageFilter *filter = link->data;
02746 DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
02747
02748 filter->function = NULL;
02749 _dbus_message_filter_unref (filter);
02750 link->data = NULL;
02751
02752 link = next;
02753 }
02754 _dbus_list_clear (&connection->filter_list);
02755
02756
02757
02758 _dbus_object_tree_unref (connection->objects);
02759
02760 _dbus_hash_table_unref (connection->pending_replies);
02761 connection->pending_replies = NULL;
02762
02763 _dbus_list_clear (&connection->filter_list);
02764
02765 _dbus_list_foreach (&connection->outgoing_messages,
02766 free_outgoing_message,
02767 connection);
02768 _dbus_list_clear (&connection->outgoing_messages);
02769
02770 _dbus_list_foreach (&connection->incoming_messages,
02771 (DBusForeachFunction) dbus_message_unref,
02772 NULL);
02773 _dbus_list_clear (&connection->incoming_messages);
02774
02775 _dbus_counter_unref (connection->outgoing_counter);
02776
02777 _dbus_transport_unref (connection->transport);
02778
02779 if (connection->disconnect_message_link)
02780 {
02781 DBusMessage *message = connection->disconnect_message_link->data;
02782 dbus_message_unref (message);
02783 _dbus_list_free_link (connection->disconnect_message_link);
02784 }
02785
02786 _dbus_condvar_free_at_location (&connection->dispatch_cond);
02787 _dbus_condvar_free_at_location (&connection->io_path_cond);
02788
02789 _dbus_cmutex_free_at_location (&connection->io_path_mutex);
02790 _dbus_cmutex_free_at_location (&connection->dispatch_mutex);
02791
02792 _dbus_rmutex_free_at_location (&connection->slot_mutex);
02793
02794 _dbus_rmutex_free_at_location (&connection->mutex);
02795
02796 dbus_free (connection);
02797 }
02798
02818 void
02819 dbus_connection_unref (DBusConnection *connection)
02820 {
02821 dbus_int32_t old_refcount;
02822
02823 _dbus_return_if_fail (connection != NULL);
02824 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02825
02826 old_refcount = _dbus_atomic_dec (&connection->refcount);
02827
02828 _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1,
02829 "unref");
02830
02831 if (old_refcount == 1)
02832 {
02833 #ifndef DBUS_DISABLE_CHECKS
02834 if (_dbus_transport_get_is_connected (connection->transport))
02835 {
02836 _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",
02837 connection->shareable ?
02838 "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" :
02839 "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n");
02840 return;
02841 }
02842 #endif
02843 _dbus_connection_last_unref (connection);
02844 }
02845 }
02846
02847
02848
02849
02850
02851
02852
02853
02854
02855
02856 static void
02857 _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection)
02858 {
02859 DBusDispatchStatus status;
02860
02861 HAVE_LOCK_CHECK (connection);
02862
02863 _dbus_verbose ("Disconnecting %p\n", connection);
02864
02865
02866
02867
02868
02869 _dbus_connection_ref_unlocked (connection);
02870
02871 _dbus_transport_disconnect (connection->transport);
02872
02873
02874
02875
02876
02877
02878
02879
02880
02881
02882 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02883
02884
02885 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02886
02887
02888 dbus_connection_unref (connection);
02889 }
02890
02933 void
02934 dbus_connection_close (DBusConnection *connection)
02935 {
02936 _dbus_return_if_fail (connection != NULL);
02937 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02938
02939 CONNECTION_LOCK (connection);
02940
02941 #ifndef DBUS_DISABLE_CHECKS
02942 if (connection->shareable)
02943 {
02944 CONNECTION_UNLOCK (connection);
02945
02946 _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n");
02947 return;
02948 }
02949 #endif
02950
02951 _dbus_connection_close_possibly_shared_and_unlock (connection);
02952 }
02953
02954 static dbus_bool_t
02955 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
02956 {
02957 HAVE_LOCK_CHECK (connection);
02958 return _dbus_transport_get_is_connected (connection->transport);
02959 }
02960
02974 dbus_bool_t
02975 dbus_connection_get_is_connected (DBusConnection *connection)
02976 {
02977 dbus_bool_t res;
02978
02979 _dbus_return_val_if_fail (connection != NULL, FALSE);
02980
02981 CONNECTION_LOCK (connection);
02982 res = _dbus_connection_get_is_connected_unlocked (connection);
02983 CONNECTION_UNLOCK (connection);
02984
02985 return res;
02986 }
02987
02996 dbus_bool_t
02997 dbus_connection_get_is_authenticated (DBusConnection *connection)
02998 {
02999 dbus_bool_t res;
03000
03001 _dbus_return_val_if_fail (connection != NULL, FALSE);
03002
03003 CONNECTION_LOCK (connection);
03004 res = _dbus_transport_try_to_authenticate (connection->transport);
03005 CONNECTION_UNLOCK (connection);
03006
03007 return res;
03008 }
03009
03030 dbus_bool_t
03031 dbus_connection_get_is_anonymous (DBusConnection *connection)
03032 {
03033 dbus_bool_t res;
03034
03035 _dbus_return_val_if_fail (connection != NULL, FALSE);
03036
03037 CONNECTION_LOCK (connection);
03038 res = _dbus_transport_get_is_anonymous (connection->transport);
03039 CONNECTION_UNLOCK (connection);
03040
03041 return res;
03042 }
03043
03075 char*
03076 dbus_connection_get_server_id (DBusConnection *connection)
03077 {
03078 char *id;
03079
03080 _dbus_return_val_if_fail (connection != NULL, NULL);
03081
03082 CONNECTION_LOCK (connection);
03083 id = _dbus_strdup (_dbus_transport_get_server_id (connection->transport));
03084 CONNECTION_UNLOCK (connection);
03085
03086 return id;
03087 }
03088
03106 dbus_bool_t
03107 dbus_connection_can_send_type(DBusConnection *connection,
03108 int type)
03109 {
03110 _dbus_return_val_if_fail (connection != NULL, FALSE);
03111
03112 if (!dbus_type_is_valid (type))
03113 return FALSE;
03114
03115 if (type != DBUS_TYPE_UNIX_FD)
03116 return TRUE;
03117
03118 #ifdef HAVE_UNIX_FD_PASSING
03119 {
03120 dbus_bool_t b;
03121
03122 CONNECTION_LOCK(connection);
03123 b = _dbus_transport_can_pass_unix_fd(connection->transport);
03124 CONNECTION_UNLOCK(connection);
03125
03126 return b;
03127 }
03128 #endif
03129
03130 return FALSE;
03131 }
03132
03146 void
03147 dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
03148 dbus_bool_t exit_on_disconnect)
03149 {
03150 _dbus_return_if_fail (connection != NULL);
03151
03152 CONNECTION_LOCK (connection);
03153 connection->exit_on_disconnect = exit_on_disconnect != FALSE;
03154 CONNECTION_UNLOCK (connection);
03155 }
03156
03166 DBusPreallocatedSend*
03167 dbus_connection_preallocate_send (DBusConnection *connection)
03168 {
03169 DBusPreallocatedSend *preallocated;
03170
03171 _dbus_return_val_if_fail (connection != NULL, NULL);
03172
03173 CONNECTION_LOCK (connection);
03174
03175 preallocated =
03176 _dbus_connection_preallocate_send_unlocked (connection);
03177
03178 CONNECTION_UNLOCK (connection);
03179
03180 return preallocated;
03181 }
03182
03192 void
03193 dbus_connection_free_preallocated_send (DBusConnection *connection,
03194 DBusPreallocatedSend *preallocated)
03195 {
03196 _dbus_return_if_fail (connection != NULL);
03197 _dbus_return_if_fail (preallocated != NULL);
03198 _dbus_return_if_fail (connection == preallocated->connection);
03199
03200 _dbus_list_free_link (preallocated->queue_link);
03201 _dbus_counter_unref (preallocated->counter_link->data);
03202 _dbus_list_free_link (preallocated->counter_link);
03203 dbus_free (preallocated);
03204 }
03205
03218 void
03219 dbus_connection_send_preallocated (DBusConnection *connection,
03220 DBusPreallocatedSend *preallocated,
03221 DBusMessage *message,
03222 dbus_uint32_t *client_serial)
03223 {
03224 _dbus_return_if_fail (connection != NULL);
03225 _dbus_return_if_fail (preallocated != NULL);
03226 _dbus_return_if_fail (message != NULL);
03227 _dbus_return_if_fail (preallocated->connection == connection);
03228 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
03229 dbus_message_get_member (message) != NULL);
03230 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
03231 (dbus_message_get_interface (message) != NULL &&
03232 dbus_message_get_member (message) != NULL));
03233
03234 CONNECTION_LOCK (connection);
03235
03236 #ifdef HAVE_UNIX_FD_PASSING
03237
03238 if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03239 message->n_unix_fds > 0)
03240 {
03241
03242
03243
03244 CONNECTION_UNLOCK (connection);
03245 return;
03246 }
03247
03248 #endif
03249
03250 _dbus_connection_send_preallocated_and_unlock (connection,
03251 preallocated,
03252 message, client_serial);
03253 }
03254
03255 static dbus_bool_t
03256 _dbus_connection_send_unlocked_no_update (DBusConnection *connection,
03257 DBusMessage *message,
03258 dbus_uint32_t *client_serial)
03259 {
03260 DBusPreallocatedSend *preallocated;
03261
03262 _dbus_assert (connection != NULL);
03263 _dbus_assert (message != NULL);
03264
03265 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
03266 if (preallocated == NULL)
03267 return FALSE;
03268
03269 _dbus_connection_send_preallocated_unlocked_no_update (connection,
03270 preallocated,
03271 message,
03272 client_serial);
03273 return TRUE;
03274 }
03275
03303 dbus_bool_t
03304 dbus_connection_send (DBusConnection *connection,
03305 DBusMessage *message,
03306 dbus_uint32_t *serial)
03307 {
03308 _dbus_return_val_if_fail (connection != NULL, FALSE);
03309 _dbus_return_val_if_fail (message != NULL, FALSE);
03310
03311 CONNECTION_LOCK (connection);
03312
03313 #ifdef HAVE_UNIX_FD_PASSING
03314
03315 if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03316 message->n_unix_fds > 0)
03317 {
03318
03319
03320
03321 CONNECTION_UNLOCK (connection);
03322 return FALSE;
03323 }
03324
03325 #endif
03326
03327 return _dbus_connection_send_and_unlock (connection,
03328 message,
03329 serial);
03330 }
03331
03332 static dbus_bool_t
03333 reply_handler_timeout (void *data)
03334 {
03335 DBusConnection *connection;
03336 DBusDispatchStatus status;
03337 DBusPendingCall *pending = data;
03338
03339 connection = _dbus_pending_call_get_connection_and_lock (pending);
03340 _dbus_connection_ref_unlocked (connection);
03341
03342 _dbus_pending_call_queue_timeout_error_unlocked (pending,
03343 connection);
03344 _dbus_connection_remove_timeout_unlocked (connection,
03345 _dbus_pending_call_get_timeout_unlocked (pending));
03346 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
03347
03348 _dbus_verbose ("middle\n");
03349 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03350
03351
03352 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03353 dbus_connection_unref (connection);
03354
03355 return TRUE;
03356 }
03357
03400 dbus_bool_t
03401 dbus_connection_send_with_reply (DBusConnection *connection,
03402 DBusMessage *message,
03403 DBusPendingCall **pending_return,
03404 int timeout_milliseconds)
03405 {
03406 DBusPendingCall *pending;
03407 dbus_int32_t serial = -1;
03408 DBusDispatchStatus status;
03409
03410 _dbus_return_val_if_fail (connection != NULL, FALSE);
03411 _dbus_return_val_if_fail (message != NULL, FALSE);
03412 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03413
03414 if (pending_return)
03415 *pending_return = NULL;
03416
03417 CONNECTION_LOCK (connection);
03418
03419 #ifdef HAVE_UNIX_FD_PASSING
03420
03421 if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03422 message->n_unix_fds > 0)
03423 {
03424
03425
03426
03427
03428 CONNECTION_UNLOCK (connection);
03429 return TRUE;
03430 }
03431
03432 #endif
03433
03434 if (!_dbus_connection_get_is_connected_unlocked (connection))
03435 {
03436 CONNECTION_UNLOCK (connection);
03437
03438 return TRUE;
03439 }
03440
03441 pending = _dbus_pending_call_new_unlocked (connection,
03442 timeout_milliseconds,
03443 reply_handler_timeout);
03444
03445 if (pending == NULL)
03446 {
03447 CONNECTION_UNLOCK (connection);
03448 return FALSE;
03449 }
03450
03451
03452 serial = dbus_message_get_serial (message);
03453 if (serial == 0)
03454 {
03455 serial = _dbus_connection_get_next_client_serial (connection);
03456 dbus_message_set_serial (message, serial);
03457 }
03458
03459 if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
03460 goto error;
03461
03462
03463
03464
03465
03466 if (!_dbus_connection_attach_pending_call_unlocked (connection,
03467 pending))
03468 goto error;
03469
03470 if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
03471 {
03472 _dbus_connection_detach_pending_call_and_unlock (connection,
03473 pending);
03474 goto error_unlocked;
03475 }
03476
03477 if (pending_return)
03478 *pending_return = pending;
03479 else
03480 {
03481 _dbus_connection_detach_pending_call_unlocked (connection, pending);
03482
03483
03484
03485 }
03486
03487 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03488
03489
03490 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03491
03492 if (pending_return == NULL)
03493 dbus_pending_call_unref (pending);
03494
03495 return TRUE;
03496
03497 error:
03498 CONNECTION_UNLOCK (connection);
03499 error_unlocked:
03500 dbus_pending_call_unref (pending);
03501 return FALSE;
03502 }
03503
03536 DBusMessage*
03537 dbus_connection_send_with_reply_and_block (DBusConnection *connection,
03538 DBusMessage *message,
03539 int timeout_milliseconds,
03540 DBusError *error)
03541 {
03542 DBusMessage *reply;
03543 DBusPendingCall *pending;
03544
03545 _dbus_return_val_if_fail (connection != NULL, NULL);
03546 _dbus_return_val_if_fail (message != NULL, NULL);
03547 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL);
03548 _dbus_return_val_if_error_is_set (error, NULL);
03549
03550 #ifdef HAVE_UNIX_FD_PASSING
03551
03552 CONNECTION_LOCK (connection);
03553 if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03554 message->n_unix_fds > 0)
03555 {
03556 CONNECTION_UNLOCK (connection);
03557 dbus_set_error(error, DBUS_ERROR_FAILED, "Cannot send file descriptors on this connection.");
03558 return NULL;
03559 }
03560 CONNECTION_UNLOCK (connection);
03561
03562 #endif
03563
03564 if (!dbus_connection_send_with_reply (connection, message,
03565 &pending, timeout_milliseconds))
03566 {
03567 _DBUS_SET_OOM (error);
03568 return NULL;
03569 }
03570
03571 if (pending == NULL)
03572 {
03573 dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Connection is closed");
03574 return NULL;
03575 }
03576
03577 dbus_pending_call_block (pending);
03578
03579 reply = dbus_pending_call_steal_reply (pending);
03580 dbus_pending_call_unref (pending);
03581
03582
03583
03584
03585 _dbus_assert (reply != NULL);
03586
03587 if (dbus_set_error_from_message (error, reply))
03588 {
03589 dbus_message_unref (reply);
03590 return NULL;
03591 }
03592 else
03593 return reply;
03594 }
03595
03604 static DBusDispatchStatus
03605 _dbus_connection_flush_unlocked (DBusConnection *connection)
03606 {
03607
03608
03609
03610
03611
03612 DBusDispatchStatus status;
03613
03614 HAVE_LOCK_CHECK (connection);
03615
03616 while (connection->n_outgoing > 0 &&
03617 _dbus_connection_get_is_connected_unlocked (connection))
03618 {
03619 _dbus_verbose ("doing iteration in\n");
03620 HAVE_LOCK_CHECK (connection);
03621 _dbus_connection_do_iteration_unlocked (connection,
03622 NULL,
03623 DBUS_ITERATION_DO_READING |
03624 DBUS_ITERATION_DO_WRITING |
03625 DBUS_ITERATION_BLOCK,
03626 -1);
03627 }
03628
03629 HAVE_LOCK_CHECK (connection);
03630 _dbus_verbose ("middle\n");
03631 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03632
03633 HAVE_LOCK_CHECK (connection);
03634 return status;
03635 }
03636
03642 void
03643 dbus_connection_flush (DBusConnection *connection)
03644 {
03645
03646
03647
03648
03649
03650 DBusDispatchStatus status;
03651
03652 _dbus_return_if_fail (connection != NULL);
03653
03654 CONNECTION_LOCK (connection);
03655
03656 status = _dbus_connection_flush_unlocked (connection);
03657
03658 HAVE_LOCK_CHECK (connection);
03659
03660 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03661
03662 _dbus_verbose ("end\n");
03663 }
03664
03675 static dbus_bool_t
03676 _dbus_connection_read_write_dispatch (DBusConnection *connection,
03677 int timeout_milliseconds,
03678 dbus_bool_t dispatch)
03679 {
03680 DBusDispatchStatus dstatus;
03681 dbus_bool_t progress_possible;
03682
03683
03684
03685
03686
03687 dbus_connection_ref (connection);
03688 dstatus = dbus_connection_get_dispatch_status (connection);
03689
03690 if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
03691 {
03692 _dbus_verbose ("doing dispatch\n");
03693 dbus_connection_dispatch (connection);
03694 CONNECTION_LOCK (connection);
03695 }
03696 else if (dstatus == DBUS_DISPATCH_NEED_MEMORY)
03697 {
03698 _dbus_verbose ("pausing for memory\n");
03699 _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
03700 CONNECTION_LOCK (connection);
03701 }
03702 else
03703 {
03704 CONNECTION_LOCK (connection);
03705 if (_dbus_connection_get_is_connected_unlocked (connection))
03706 {
03707 _dbus_verbose ("doing iteration\n");
03708 _dbus_connection_do_iteration_unlocked (connection,
03709 NULL,
03710 DBUS_ITERATION_DO_READING |
03711 DBUS_ITERATION_DO_WRITING |
03712 DBUS_ITERATION_BLOCK,
03713 timeout_milliseconds);
03714 }
03715 }
03716
03717 HAVE_LOCK_CHECK (connection);
03718
03719
03720
03721
03722 if (dispatch)
03723 progress_possible = connection->n_incoming != 0 ||
03724 connection->disconnect_message_link != NULL;
03725 else
03726 progress_possible = _dbus_connection_get_is_connected_unlocked (connection);
03727
03728 CONNECTION_UNLOCK (connection);
03729
03730 dbus_connection_unref (connection);
03731
03732 return progress_possible;
03733 }
03734
03735
03770 dbus_bool_t
03771 dbus_connection_read_write_dispatch (DBusConnection *connection,
03772 int timeout_milliseconds)
03773 {
03774 _dbus_return_val_if_fail (connection != NULL, FALSE);
03775 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03776 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE);
03777 }
03778
03802 dbus_bool_t
03803 dbus_connection_read_write (DBusConnection *connection,
03804 int timeout_milliseconds)
03805 {
03806 _dbus_return_val_if_fail (connection != NULL, FALSE);
03807 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03808 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE);
03809 }
03810
03811
03812
03813
03814
03815
03816 static void
03817 check_disconnected_message_arrived_unlocked (DBusConnection *connection,
03818 DBusMessage *head_of_queue)
03819 {
03820 HAVE_LOCK_CHECK (connection);
03821
03822
03823 if (connection->disconnect_message_link == NULL &&
03824 dbus_message_is_signal (head_of_queue,
03825 DBUS_INTERFACE_LOCAL,
03826 "Disconnected"))
03827 {
03828 connection->disconnected_message_arrived = TRUE;
03829 }
03830 }
03831
03851 DBusMessage*
03852 dbus_connection_borrow_message (DBusConnection *connection)
03853 {
03854 DBusDispatchStatus status;
03855 DBusMessage *message;
03856
03857 _dbus_return_val_if_fail (connection != NULL, NULL);
03858
03859 _dbus_verbose ("start\n");
03860
03861
03862
03863
03864 status = dbus_connection_get_dispatch_status (connection);
03865 if (status != DBUS_DISPATCH_DATA_REMAINS)
03866 return NULL;
03867
03868 CONNECTION_LOCK (connection);
03869
03870 _dbus_connection_acquire_dispatch (connection);
03871
03872
03873 _dbus_assert (connection->message_borrowed == NULL);
03874
03875 connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
03876
03877 message = connection->message_borrowed;
03878
03879 check_disconnected_message_arrived_unlocked (connection, message);
03880
03881
03882 if (message == NULL)
03883 _dbus_connection_release_dispatch (connection);
03884
03885 CONNECTION_UNLOCK (connection);
03886
03887 _dbus_message_trace_ref (message, -1, -1, "dbus_connection_borrow_message");
03888
03889
03890
03891 return message;
03892 }
03893
03902 void
03903 dbus_connection_return_message (DBusConnection *connection,
03904 DBusMessage *message)
03905 {
03906 DBusDispatchStatus status;
03907
03908 _dbus_return_if_fail (connection != NULL);
03909 _dbus_return_if_fail (message != NULL);
03910 _dbus_return_if_fail (message == connection->message_borrowed);
03911 _dbus_return_if_fail (connection->dispatch_acquired);
03912
03913 CONNECTION_LOCK (connection);
03914
03915 _dbus_assert (message == connection->message_borrowed);
03916
03917 connection->message_borrowed = NULL;
03918
03919 _dbus_connection_release_dispatch (connection);
03920
03921 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03922 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03923
03924 _dbus_message_trace_ref (message, -1, -1, "dbus_connection_return_message");
03925 }
03926
03936 void
03937 dbus_connection_steal_borrowed_message (DBusConnection *connection,
03938 DBusMessage *message)
03939 {
03940 DBusMessage *pop_message;
03941 DBusDispatchStatus status;
03942
03943 _dbus_return_if_fail (connection != NULL);
03944 _dbus_return_if_fail (message != NULL);
03945 _dbus_return_if_fail (message == connection->message_borrowed);
03946 _dbus_return_if_fail (connection->dispatch_acquired);
03947
03948 CONNECTION_LOCK (connection);
03949
03950 _dbus_assert (message == connection->message_borrowed);
03951
03952 pop_message = _dbus_list_pop_first (&connection->incoming_messages);
03953 _dbus_assert (message == pop_message);
03954 (void) pop_message;
03955
03956 connection->n_incoming -= 1;
03957
03958 _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
03959 message, connection->n_incoming);
03960
03961 connection->message_borrowed = NULL;
03962
03963 _dbus_connection_release_dispatch (connection);
03964
03965 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03966 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03967 _dbus_message_trace_ref (message, -1, -1,
03968 "dbus_connection_steal_borrowed_message");
03969 }
03970
03971
03972
03973
03974 static DBusList*
03975 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
03976 {
03977 HAVE_LOCK_CHECK (connection);
03978
03979 _dbus_assert (connection->message_borrowed == NULL);
03980
03981 if (connection->n_incoming > 0)
03982 {
03983 DBusList *link;
03984
03985 link = _dbus_list_pop_first_link (&connection->incoming_messages);
03986 connection->n_incoming -= 1;
03987
03988 _dbus_verbose ("Message %p (%s %s %s %s sig:'%s' serial:%u) removed from incoming queue %p, %d incoming\n",
03989 link->data,
03990 dbus_message_type_to_string (dbus_message_get_type (link->data)),
03991 dbus_message_get_path (link->data) ?
03992 dbus_message_get_path (link->data) :
03993 "no path",
03994 dbus_message_get_interface (link->data) ?
03995 dbus_message_get_interface (link->data) :
03996 "no interface",
03997 dbus_message_get_member (link->data) ?
03998 dbus_message_get_member (link->data) :
03999 "no member",
04000 dbus_message_get_signature (link->data),
04001 dbus_message_get_serial (link->data),
04002 connection, connection->n_incoming);
04003
04004 _dbus_message_trace_ref (link->data, -1, -1,
04005 "_dbus_connection_pop_message_link_unlocked");
04006
04007 check_disconnected_message_arrived_unlocked (connection, link->data);
04008
04009 return link;
04010 }
04011 else
04012 return NULL;
04013 }
04014
04015
04016
04017
04018 static DBusMessage*
04019 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
04020 {
04021 DBusList *link;
04022
04023 HAVE_LOCK_CHECK (connection);
04024
04025 link = _dbus_connection_pop_message_link_unlocked (connection);
04026
04027 if (link != NULL)
04028 {
04029 DBusMessage *message;
04030
04031 message = link->data;
04032
04033 _dbus_list_free_link (link);
04034
04035 return message;
04036 }
04037 else
04038 return NULL;
04039 }
04040
04041 static void
04042 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
04043 DBusList *message_link)
04044 {
04045 HAVE_LOCK_CHECK (connection);
04046
04047 _dbus_assert (message_link != NULL);
04048
04049 _dbus_assert (connection->message_borrowed == NULL);
04050
04051 _dbus_assert (connection->dispatch_acquired);
04052
04053 _dbus_list_prepend_link (&connection->incoming_messages,
04054 message_link);
04055 connection->n_incoming += 1;
04056
04057 _dbus_verbose ("Message %p (%s %s %s '%s') put back into queue %p, %d incoming\n",
04058 message_link->data,
04059 dbus_message_type_to_string (dbus_message_get_type (message_link->data)),
04060 dbus_message_get_interface (message_link->data) ?
04061 dbus_message_get_interface (message_link->data) :
04062 "no interface",
04063 dbus_message_get_member (message_link->data) ?
04064 dbus_message_get_member (message_link->data) :
04065 "no member",
04066 dbus_message_get_signature (message_link->data),
04067 connection, connection->n_incoming);
04068
04069 _dbus_message_trace_ref (message_link->data, -1, -1,
04070 "_dbus_connection_putback_message_link_unlocked");
04071 }
04072
04092 DBusMessage*
04093 dbus_connection_pop_message (DBusConnection *connection)
04094 {
04095 DBusMessage *message;
04096 DBusDispatchStatus status;
04097
04098 _dbus_verbose ("start\n");
04099
04100
04101
04102
04103 status = dbus_connection_get_dispatch_status (connection);
04104 if (status != DBUS_DISPATCH_DATA_REMAINS)
04105 return NULL;
04106
04107 CONNECTION_LOCK (connection);
04108 _dbus_connection_acquire_dispatch (connection);
04109 HAVE_LOCK_CHECK (connection);
04110
04111 message = _dbus_connection_pop_message_unlocked (connection);
04112
04113 _dbus_verbose ("Returning popped message %p\n", message);
04114
04115 _dbus_connection_release_dispatch (connection);
04116
04117 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04118 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04119
04120 return message;
04121 }
04122
04130 static void
04131 _dbus_connection_acquire_dispatch (DBusConnection *connection)
04132 {
04133 HAVE_LOCK_CHECK (connection);
04134
04135 _dbus_connection_ref_unlocked (connection);
04136 CONNECTION_UNLOCK (connection);
04137
04138 _dbus_verbose ("locking dispatch_mutex\n");
04139 _dbus_cmutex_lock (connection->dispatch_mutex);
04140
04141 while (connection->dispatch_acquired)
04142 {
04143 _dbus_verbose ("waiting for dispatch to be acquirable\n");
04144 _dbus_condvar_wait (connection->dispatch_cond,
04145 connection->dispatch_mutex);
04146 }
04147
04148 _dbus_assert (!connection->dispatch_acquired);
04149
04150 connection->dispatch_acquired = TRUE;
04151
04152 _dbus_verbose ("unlocking dispatch_mutex\n");
04153 _dbus_cmutex_unlock (connection->dispatch_mutex);
04154
04155 CONNECTION_LOCK (connection);
04156 _dbus_connection_unref_unlocked (connection);
04157 }
04158
04166 static void
04167 _dbus_connection_release_dispatch (DBusConnection *connection)
04168 {
04169 HAVE_LOCK_CHECK (connection);
04170
04171 _dbus_verbose ("locking dispatch_mutex\n");
04172 _dbus_cmutex_lock (connection->dispatch_mutex);
04173
04174 _dbus_assert (connection->dispatch_acquired);
04175
04176 connection->dispatch_acquired = FALSE;
04177 _dbus_condvar_wake_one (connection->dispatch_cond);
04178
04179 _dbus_verbose ("unlocking dispatch_mutex\n");
04180 _dbus_cmutex_unlock (connection->dispatch_mutex);
04181 }
04182
04183 static void
04184 _dbus_connection_failed_pop (DBusConnection *connection,
04185 DBusList *message_link)
04186 {
04187 _dbus_list_prepend_link (&connection->incoming_messages,
04188 message_link);
04189 connection->n_incoming += 1;
04190 }
04191
04192
04193 static void
04194 notify_disconnected_unlocked (DBusConnection *connection)
04195 {
04196 HAVE_LOCK_CHECK (connection);
04197
04198
04199
04200
04201
04202
04203
04204 _dbus_bus_notify_shared_connection_disconnected_unlocked (connection);
04205
04206
04207
04208
04209
04210 if (connection->n_outgoing > 0)
04211 {
04212 DBusList *link;
04213
04214 _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
04215 connection->n_outgoing);
04216
04217 while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
04218 {
04219 _dbus_connection_message_sent_unlocked (connection, link->data);
04220 }
04221 }
04222 }
04223
04224
04225 static DBusDispatchStatus
04226 notify_disconnected_and_dispatch_complete_unlocked (DBusConnection *connection)
04227 {
04228 HAVE_LOCK_CHECK (connection);
04229
04230 if (connection->disconnect_message_link != NULL)
04231 {
04232 _dbus_verbose ("Sending disconnect message\n");
04233
04234
04235
04236
04237 connection_timeout_and_complete_all_pending_calls_unlocked (connection);
04238
04239
04240
04241
04242 _dbus_connection_queue_synthesized_message_link (connection,
04243 connection->disconnect_message_link);
04244 connection->disconnect_message_link = NULL;
04245
04246 return DBUS_DISPATCH_DATA_REMAINS;
04247 }
04248
04249 return DBUS_DISPATCH_COMPLETE;
04250 }
04251
04252 static DBusDispatchStatus
04253 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
04254 {
04255 HAVE_LOCK_CHECK (connection);
04256
04257 if (connection->n_incoming > 0)
04258 return DBUS_DISPATCH_DATA_REMAINS;
04259 else if (!_dbus_transport_queue_messages (connection->transport))
04260 return DBUS_DISPATCH_NEED_MEMORY;
04261 else
04262 {
04263 DBusDispatchStatus status;
04264 dbus_bool_t is_connected;
04265
04266 status = _dbus_transport_get_dispatch_status (connection->transport);
04267 is_connected = _dbus_transport_get_is_connected (connection->transport);
04268
04269 _dbus_verbose ("dispatch status = %s is_connected = %d\n",
04270 DISPATCH_STATUS_NAME (status), is_connected);
04271
04272 if (!is_connected)
04273 {
04274
04275
04276
04277
04278
04279
04280 notify_disconnected_unlocked (connection);
04281
04282
04283
04284
04285
04286
04287 if (status == DBUS_DISPATCH_COMPLETE)
04288 status = notify_disconnected_and_dispatch_complete_unlocked (connection);
04289 }
04290
04291 if (status != DBUS_DISPATCH_COMPLETE)
04292 return status;
04293 else if (connection->n_incoming > 0)
04294 return DBUS_DISPATCH_DATA_REMAINS;
04295 else
04296 return DBUS_DISPATCH_COMPLETE;
04297 }
04298 }
04299
04300 static void
04301 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
04302 DBusDispatchStatus new_status)
04303 {
04304 dbus_bool_t changed;
04305 DBusDispatchStatusFunction function;
04306 void *data;
04307
04308 HAVE_LOCK_CHECK (connection);
04309
04310 _dbus_connection_ref_unlocked (connection);
04311
04312 changed = new_status != connection->last_dispatch_status;
04313
04314 connection->last_dispatch_status = new_status;
04315
04316 function = connection->dispatch_status_function;
04317 data = connection->dispatch_status_data;
04318
04319 if (connection->disconnected_message_arrived &&
04320 !connection->disconnected_message_processed)
04321 {
04322 connection->disconnected_message_processed = TRUE;
04323
04324
04325
04326
04327
04328 connection_forget_shared_unlocked (connection);
04329
04330 if (connection->exit_on_disconnect)
04331 {
04332 CONNECTION_UNLOCK (connection);
04333
04334 _dbus_verbose ("Exiting on Disconnected signal\n");
04335 _dbus_exit (1);
04336 _dbus_assert_not_reached ("Call to exit() returned");
04337 }
04338 }
04339
04340
04341 CONNECTION_UNLOCK (connection);
04342
04343 if (changed && function)
04344 {
04345 _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
04346 connection, new_status,
04347 DISPATCH_STATUS_NAME (new_status));
04348 (* function) (connection, new_status, data);
04349 }
04350
04351 dbus_connection_unref (connection);
04352 }
04353
04379 DBusDispatchStatus
04380 dbus_connection_get_dispatch_status (DBusConnection *connection)
04381 {
04382 DBusDispatchStatus status;
04383
04384 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04385
04386 _dbus_verbose ("start\n");
04387
04388 CONNECTION_LOCK (connection);
04389
04390 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04391
04392 CONNECTION_UNLOCK (connection);
04393
04394 return status;
04395 }
04396
04400 static DBusHandlerResult
04401 _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
04402 DBusMessage *message)
04403 {
04404 dbus_bool_t sent = FALSE;
04405 DBusMessage *ret = NULL;
04406 DBusList *expire_link;
04407
04408 if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
04409 {
04410
04411 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04412 }
04413
04414 if (!dbus_message_has_interface (message, DBUS_INTERFACE_PEER))
04415 {
04416 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04417 }
04418
04419
04420
04421 expire_link = _dbus_list_alloc_link (NULL);
04422
04423 if (!expire_link)
04424 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04425
04426 if (dbus_message_is_method_call (message,
04427 DBUS_INTERFACE_PEER,
04428 "Ping"))
04429 {
04430 ret = dbus_message_new_method_return (message);
04431 if (ret == NULL)
04432 goto out;
04433
04434 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04435 }
04436 else if (dbus_message_is_method_call (message,
04437 DBUS_INTERFACE_PEER,
04438 "GetMachineId"))
04439 {
04440 DBusString uuid;
04441 DBusError error = DBUS_ERROR_INIT;
04442
04443 if (!_dbus_string_init (&uuid))
04444 goto out;
04445
04446 if (_dbus_get_local_machine_uuid_encoded (&uuid, &error))
04447 {
04448 const char *v_STRING;
04449
04450 ret = dbus_message_new_method_return (message);
04451
04452 if (ret == NULL)
04453 {
04454 _dbus_string_free (&uuid);
04455 goto out;
04456 }
04457
04458 v_STRING = _dbus_string_get_const_data (&uuid);
04459 if (dbus_message_append_args (ret,
04460 DBUS_TYPE_STRING, &v_STRING,
04461 DBUS_TYPE_INVALID))
04462 {
04463 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04464 }
04465 }
04466 else if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
04467 {
04468 dbus_error_free (&error);
04469 goto out;
04470 }
04471 else
04472 {
04473 ret = dbus_message_new_error (message, error.name, error.message);
04474 dbus_error_free (&error);
04475
04476 if (ret == NULL)
04477 goto out;
04478
04479 sent = _dbus_connection_send_unlocked_no_update (connection, ret,
04480 NULL);
04481 }
04482
04483 _dbus_string_free (&uuid);
04484 }
04485 else
04486 {
04487
04488
04489
04490
04491 ret = dbus_message_new_error (message,
04492 DBUS_ERROR_UNKNOWN_METHOD,
04493 "Unknown method invoked on org.freedesktop.DBus.Peer interface");
04494 if (ret == NULL)
04495 goto out;
04496
04497 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04498 }
04499
04500 out:
04501 if (ret == NULL)
04502 {
04503 _dbus_list_free_link (expire_link);
04504 }
04505 else
04506 {
04507
04508 expire_link->data = ret;
04509 _dbus_list_prepend_link (&connection->expired_messages, expire_link);
04510 }
04511
04512 if (!sent)
04513 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04514
04515 return DBUS_HANDLER_RESULT_HANDLED;
04516 }
04517
04524 static DBusHandlerResult
04525 _dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection,
04526 DBusMessage *message)
04527 {
04528
04529
04530
04531 return _dbus_connection_peer_filter_unlocked_no_update (connection, message);
04532 }
04533
04576 DBusDispatchStatus
04577 dbus_connection_dispatch (DBusConnection *connection)
04578 {
04579 DBusMessage *message;
04580 DBusList *link, *filter_list_copy, *message_link;
04581 DBusHandlerResult result;
04582 DBusPendingCall *pending;
04583 dbus_int32_t reply_serial;
04584 DBusDispatchStatus status;
04585 dbus_bool_t found_object;
04586
04587 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04588
04589 _dbus_verbose ("\n");
04590
04591 CONNECTION_LOCK (connection);
04592 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04593 if (status != DBUS_DISPATCH_DATA_REMAINS)
04594 {
04595
04596 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04597 return status;
04598 }
04599
04600
04601
04602
04603 _dbus_connection_ref_unlocked (connection);
04604
04605 _dbus_connection_acquire_dispatch (connection);
04606 HAVE_LOCK_CHECK (connection);
04607
04608 message_link = _dbus_connection_pop_message_link_unlocked (connection);
04609 if (message_link == NULL)
04610 {
04611
04612
04613 _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
04614
04615 _dbus_connection_release_dispatch (connection);
04616
04617 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04618
04619 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04620
04621 dbus_connection_unref (connection);
04622
04623 return status;
04624 }
04625
04626 message = message_link->data;
04627
04628 _dbus_verbose (" dispatching message %p (%s %s %s '%s')\n",
04629 message,
04630 dbus_message_type_to_string (dbus_message_get_type (message)),
04631 dbus_message_get_interface (message) ?
04632 dbus_message_get_interface (message) :
04633 "no interface",
04634 dbus_message_get_member (message) ?
04635 dbus_message_get_member (message) :
04636 "no member",
04637 dbus_message_get_signature (message));
04638
04639 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04640
04641
04642
04643
04644
04645
04646
04647
04648 reply_serial = dbus_message_get_reply_serial (message);
04649 pending = _dbus_hash_table_lookup_int (connection->pending_replies,
04650 reply_serial);
04651 if (pending)
04652 {
04653 _dbus_verbose ("Dispatching a pending reply\n");
04654 complete_pending_call_and_unlock (connection, pending, message);
04655 pending = NULL;
04656
04657 CONNECTION_LOCK (connection);
04658 _dbus_verbose ("pending call completed in dispatch\n");
04659 result = DBUS_HANDLER_RESULT_HANDLED;
04660 goto out;
04661 }
04662
04663 result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message);
04664 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04665 goto out;
04666
04667 if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
04668 {
04669 _dbus_connection_release_dispatch (connection);
04670 HAVE_LOCK_CHECK (connection);
04671
04672 _dbus_connection_failed_pop (connection, message_link);
04673
04674
04675 _dbus_connection_update_dispatch_status_and_unlock (connection,
04676 DBUS_DISPATCH_NEED_MEMORY);
04677 dbus_connection_unref (connection);
04678
04679 return DBUS_DISPATCH_NEED_MEMORY;
04680 }
04681
04682 _dbus_list_foreach (&filter_list_copy,
04683 (DBusForeachFunction)_dbus_message_filter_ref,
04684 NULL);
04685
04686
04687
04688
04689 CONNECTION_UNLOCK (connection);
04690
04691 link = _dbus_list_get_first_link (&filter_list_copy);
04692 while (link != NULL)
04693 {
04694 DBusMessageFilter *filter = link->data;
04695 DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
04696
04697 if (filter->function == NULL)
04698 {
04699 _dbus_verbose (" filter was removed in a callback function\n");
04700 link = next;
04701 continue;
04702 }
04703
04704 _dbus_verbose (" running filter on message %p\n", message);
04705 result = (* filter->function) (connection, message, filter->user_data);
04706
04707 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04708 break;
04709
04710 link = next;
04711 }
04712
04713 _dbus_list_foreach (&filter_list_copy,
04714 (DBusForeachFunction)_dbus_message_filter_unref,
04715 NULL);
04716 _dbus_list_clear (&filter_list_copy);
04717
04718 CONNECTION_LOCK (connection);
04719
04720 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04721 {
04722 _dbus_verbose ("No memory\n");
04723 goto out;
04724 }
04725 else if (result == DBUS_HANDLER_RESULT_HANDLED)
04726 {
04727 _dbus_verbose ("filter handled message in dispatch\n");
04728 goto out;
04729 }
04730
04731
04732
04733
04734 _dbus_verbose (" running object path dispatch on message %p (%s %s %s '%s')\n",
04735 message,
04736 dbus_message_type_to_string (dbus_message_get_type (message)),
04737 dbus_message_get_interface (message) ?
04738 dbus_message_get_interface (message) :
04739 "no interface",
04740 dbus_message_get_member (message) ?
04741 dbus_message_get_member (message) :
04742 "no member",
04743 dbus_message_get_signature (message));
04744
04745 HAVE_LOCK_CHECK (connection);
04746 result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
04747 message,
04748 &found_object);
04749
04750 CONNECTION_LOCK (connection);
04751
04752 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04753 {
04754 _dbus_verbose ("object tree handled message in dispatch\n");
04755 goto out;
04756 }
04757
04758 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
04759 {
04760 DBusMessage *reply;
04761 DBusString str;
04762 DBusPreallocatedSend *preallocated;
04763 DBusList *expire_link;
04764
04765 _dbus_verbose (" sending error %s\n",
04766 DBUS_ERROR_UNKNOWN_METHOD);
04767
04768 if (!_dbus_string_init (&str))
04769 {
04770 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04771 _dbus_verbose ("no memory for error string in dispatch\n");
04772 goto out;
04773 }
04774
04775 if (!_dbus_string_append_printf (&str,
04776 "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
04777 dbus_message_get_member (message),
04778 dbus_message_get_signature (message),
04779 dbus_message_get_interface (message)))
04780 {
04781 _dbus_string_free (&str);
04782 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04783 _dbus_verbose ("no memory for error string in dispatch\n");
04784 goto out;
04785 }
04786
04787 reply = dbus_message_new_error (message,
04788 found_object ? DBUS_ERROR_UNKNOWN_METHOD : DBUS_ERROR_UNKNOWN_OBJECT,
04789 _dbus_string_get_const_data (&str));
04790 _dbus_string_free (&str);
04791
04792 if (reply == NULL)
04793 {
04794 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04795 _dbus_verbose ("no memory for error reply in dispatch\n");
04796 goto out;
04797 }
04798
04799 expire_link = _dbus_list_alloc_link (reply);
04800
04801 if (expire_link == NULL)
04802 {
04803 dbus_message_unref (reply);
04804 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04805 _dbus_verbose ("no memory for error send in dispatch\n");
04806 goto out;
04807 }
04808
04809 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
04810
04811 if (preallocated == NULL)
04812 {
04813 _dbus_list_free_link (expire_link);
04814
04815
04816 dbus_message_unref (reply);
04817 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04818 _dbus_verbose ("no memory for error send in dispatch\n");
04819 goto out;
04820 }
04821
04822 _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
04823 reply, NULL);
04824
04825 _dbus_list_prepend_link (&connection->expired_messages, expire_link);
04826
04827 result = DBUS_HANDLER_RESULT_HANDLED;
04828 }
04829
04830 _dbus_verbose (" done dispatching %p (%s %s %s '%s') on connection %p\n", message,
04831 dbus_message_type_to_string (dbus_message_get_type (message)),
04832 dbus_message_get_interface (message) ?
04833 dbus_message_get_interface (message) :
04834 "no interface",
04835 dbus_message_get_member (message) ?
04836 dbus_message_get_member (message) :
04837 "no member",
04838 dbus_message_get_signature (message),
04839 connection);
04840
04841 out:
04842 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04843 {
04844 _dbus_verbose ("out of memory\n");
04845
04846
04847
04848
04849
04850 _dbus_connection_putback_message_link_unlocked (connection,
04851 message_link);
04852
04853 message_link = NULL;
04854 message = NULL;
04855 }
04856 else
04857 {
04858 _dbus_verbose (" ... done dispatching\n");
04859 }
04860
04861 _dbus_connection_release_dispatch (connection);
04862 HAVE_LOCK_CHECK (connection);
04863
04864 if (message != NULL)
04865 {
04866
04867
04868
04869
04870
04871
04872
04873 CONNECTION_UNLOCK (connection);
04874 dbus_message_unref (message);
04875 CONNECTION_LOCK (connection);
04876 }
04877
04878 if (message_link != NULL)
04879 _dbus_list_free_link (message_link);
04880
04881 _dbus_verbose ("before final status update\n");
04882 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04883
04884
04885 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04886
04887 dbus_connection_unref (connection);
04888
04889 return status;
04890 }
04891
04953 dbus_bool_t
04954 dbus_connection_set_watch_functions (DBusConnection *connection,
04955 DBusAddWatchFunction add_function,
04956 DBusRemoveWatchFunction remove_function,
04957 DBusWatchToggledFunction toggled_function,
04958 void *data,
04959 DBusFreeFunction free_data_function)
04960 {
04961 dbus_bool_t retval;
04962
04963 _dbus_return_val_if_fail (connection != NULL, FALSE);
04964
04965 CONNECTION_LOCK (connection);
04966
04967 retval = _dbus_watch_list_set_functions (connection->watches,
04968 add_function, remove_function,
04969 toggled_function,
04970 data, free_data_function);
04971
04972 CONNECTION_UNLOCK (connection);
04973
04974 return retval;
04975 }
04976
05016 dbus_bool_t
05017 dbus_connection_set_timeout_functions (DBusConnection *connection,
05018 DBusAddTimeoutFunction add_function,
05019 DBusRemoveTimeoutFunction remove_function,
05020 DBusTimeoutToggledFunction toggled_function,
05021 void *data,
05022 DBusFreeFunction free_data_function)
05023 {
05024 dbus_bool_t retval;
05025
05026 _dbus_return_val_if_fail (connection != NULL, FALSE);
05027
05028 CONNECTION_LOCK (connection);
05029
05030 retval = _dbus_timeout_list_set_functions (connection->timeouts,
05031 add_function, remove_function,
05032 toggled_function,
05033 data, free_data_function);
05034
05035 CONNECTION_UNLOCK (connection);
05036
05037 return retval;
05038 }
05039
05054 void
05055 dbus_connection_set_wakeup_main_function (DBusConnection *connection,
05056 DBusWakeupMainFunction wakeup_main_function,
05057 void *data,
05058 DBusFreeFunction free_data_function)
05059 {
05060 void *old_data;
05061 DBusFreeFunction old_free_data;
05062
05063 _dbus_return_if_fail (connection != NULL);
05064
05065 CONNECTION_LOCK (connection);
05066 old_data = connection->wakeup_main_data;
05067 old_free_data = connection->free_wakeup_main_data;
05068
05069 connection->wakeup_main_function = wakeup_main_function;
05070 connection->wakeup_main_data = data;
05071 connection->free_wakeup_main_data = free_data_function;
05072
05073 CONNECTION_UNLOCK (connection);
05074
05075
05076 if (old_free_data)
05077 (*old_free_data) (old_data);
05078 }
05079
05100 void
05101 dbus_connection_set_dispatch_status_function (DBusConnection *connection,
05102 DBusDispatchStatusFunction function,
05103 void *data,
05104 DBusFreeFunction free_data_function)
05105 {
05106 void *old_data;
05107 DBusFreeFunction old_free_data;
05108
05109 _dbus_return_if_fail (connection != NULL);
05110
05111 CONNECTION_LOCK (connection);
05112 old_data = connection->dispatch_status_data;
05113 old_free_data = connection->free_dispatch_status_data;
05114
05115 connection->dispatch_status_function = function;
05116 connection->dispatch_status_data = data;
05117 connection->free_dispatch_status_data = free_data_function;
05118
05119 CONNECTION_UNLOCK (connection);
05120
05121
05122 if (old_free_data)
05123 (*old_free_data) (old_data);
05124 }
05125
05145 dbus_bool_t
05146 dbus_connection_get_unix_fd (DBusConnection *connection,
05147 int *fd)
05148 {
05149 _dbus_return_val_if_fail (connection != NULL, FALSE);
05150 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
05151
05152 #ifdef DBUS_WIN
05153
05154 return FALSE;
05155 #endif
05156
05157 return dbus_connection_get_socket(connection, fd);
05158 }
05159
05175 dbus_bool_t
05176 dbus_connection_get_socket(DBusConnection *connection,
05177 int *fd)
05178 {
05179 dbus_bool_t retval;
05180 DBusSocket s = DBUS_SOCKET_INIT;
05181
05182 _dbus_return_val_if_fail (connection != NULL, FALSE);
05183 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
05184
05185 CONNECTION_LOCK (connection);
05186
05187 retval = _dbus_transport_get_socket_fd (connection->transport, &s);
05188
05189 if (retval)
05190 {
05191 *fd = _dbus_socket_get_int (s);
05192 }
05193
05194 CONNECTION_UNLOCK (connection);
05195
05196 return retval;
05197 }
05198
05199
05222 dbus_bool_t
05223 dbus_connection_get_unix_user (DBusConnection *connection,
05224 unsigned long *uid)
05225 {
05226 dbus_bool_t result;
05227
05228 _dbus_return_val_if_fail (connection != NULL, FALSE);
05229 _dbus_return_val_if_fail (uid != NULL, FALSE);
05230
05231 CONNECTION_LOCK (connection);
05232
05233 if (!_dbus_transport_try_to_authenticate (connection->transport))
05234 result = FALSE;
05235 else
05236 result = _dbus_transport_get_unix_user (connection->transport,
05237 uid);
05238
05239 #ifdef DBUS_WIN
05240 _dbus_assert (!result);
05241 #endif
05242
05243 CONNECTION_UNLOCK (connection);
05244
05245 return result;
05246 }
05247
05258 dbus_bool_t
05259 dbus_connection_get_unix_process_id (DBusConnection *connection,
05260 unsigned long *pid)
05261 {
05262 dbus_bool_t result;
05263
05264 _dbus_return_val_if_fail (connection != NULL, FALSE);
05265 _dbus_return_val_if_fail (pid != NULL, FALSE);
05266
05267 CONNECTION_LOCK (connection);
05268
05269 if (!_dbus_transport_try_to_authenticate (connection->transport))
05270 result = FALSE;
05271 else
05272 result = _dbus_transport_get_unix_process_id (connection->transport,
05273 pid);
05274
05275 CONNECTION_UNLOCK (connection);
05276
05277 return result;
05278 }
05279
05291 dbus_bool_t
05292 dbus_connection_get_adt_audit_session_data (DBusConnection *connection,
05293 void **data,
05294 dbus_int32_t *data_size)
05295 {
05296 dbus_bool_t result;
05297
05298 _dbus_return_val_if_fail (connection != NULL, FALSE);
05299 _dbus_return_val_if_fail (data != NULL, FALSE);
05300 _dbus_return_val_if_fail (data_size != NULL, FALSE);
05301
05302 CONNECTION_LOCK (connection);
05303
05304 if (!_dbus_transport_try_to_authenticate (connection->transport))
05305 result = FALSE;
05306 else
05307 result = _dbus_transport_get_adt_audit_session_data (connection->transport,
05308 data,
05309 data_size);
05310 CONNECTION_UNLOCK (connection);
05311
05312 return result;
05313 }
05314
05337 void
05338 dbus_connection_set_unix_user_function (DBusConnection *connection,
05339 DBusAllowUnixUserFunction function,
05340 void *data,
05341 DBusFreeFunction free_data_function)
05342 {
05343 void *old_data = NULL;
05344 DBusFreeFunction old_free_function = NULL;
05345
05346 _dbus_return_if_fail (connection != NULL);
05347
05348 CONNECTION_LOCK (connection);
05349 _dbus_transport_set_unix_user_function (connection->transport,
05350 function, data, free_data_function,
05351 &old_data, &old_free_function);
05352 CONNECTION_UNLOCK (connection);
05353
05354 if (old_free_function != NULL)
05355 (* old_free_function) (old_data);
05356 }
05357
05358
05359 dbus_bool_t
05360 _dbus_connection_get_linux_security_label (DBusConnection *connection,
05361 char **label_p)
05362 {
05363 dbus_bool_t result;
05364
05365 _dbus_assert (connection != NULL);
05366 _dbus_assert (label_p != NULL);
05367
05368 CONNECTION_LOCK (connection);
05369
05370 if (!_dbus_transport_try_to_authenticate (connection->transport))
05371 result = FALSE;
05372 else
05373 result = _dbus_transport_get_linux_security_label (connection->transport,
05374 label_p);
05375 #ifndef __linux__
05376 _dbus_assert (!result);
05377 #endif
05378
05379 CONNECTION_UNLOCK (connection);
05380
05381 return result;
05382 }
05383
05415 dbus_bool_t
05416 dbus_connection_get_windows_user (DBusConnection *connection,
05417 char **windows_sid_p)
05418 {
05419 dbus_bool_t result;
05420
05421 _dbus_return_val_if_fail (connection != NULL, FALSE);
05422 _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
05423
05424 CONNECTION_LOCK (connection);
05425
05426 if (!_dbus_transport_try_to_authenticate (connection->transport))
05427 result = FALSE;
05428 else
05429 result = _dbus_transport_get_windows_user (connection->transport,
05430 windows_sid_p);
05431
05432 #ifdef DBUS_UNIX
05433 _dbus_assert (!result);
05434 #endif
05435
05436 CONNECTION_UNLOCK (connection);
05437
05438 return result;
05439 }
05440
05462 void
05463 dbus_connection_set_windows_user_function (DBusConnection *connection,
05464 DBusAllowWindowsUserFunction function,
05465 void *data,
05466 DBusFreeFunction free_data_function)
05467 {
05468 void *old_data = NULL;
05469 DBusFreeFunction old_free_function = NULL;
05470
05471 _dbus_return_if_fail (connection != NULL);
05472
05473 CONNECTION_LOCK (connection);
05474 _dbus_transport_set_windows_user_function (connection->transport,
05475 function, data, free_data_function,
05476 &old_data, &old_free_function);
05477 CONNECTION_UNLOCK (connection);
05478
05479 if (old_free_function != NULL)
05480 (* old_free_function) (old_data);
05481 }
05482
05509 void
05510 dbus_connection_set_allow_anonymous (DBusConnection *connection,
05511 dbus_bool_t value)
05512 {
05513 _dbus_return_if_fail (connection != NULL);
05514
05515 CONNECTION_LOCK (connection);
05516 _dbus_transport_set_allow_anonymous (connection->transport, value);
05517 CONNECTION_UNLOCK (connection);
05518 }
05519
05537 void
05538 dbus_connection_set_route_peer_messages (DBusConnection *connection,
05539 dbus_bool_t value)
05540 {
05541 _dbus_return_if_fail (connection != NULL);
05542
05543 CONNECTION_LOCK (connection);
05544 connection->route_peer_messages = value;
05545 CONNECTION_UNLOCK (connection);
05546 }
05547
05569 dbus_bool_t
05570 dbus_connection_add_filter (DBusConnection *connection,
05571 DBusHandleMessageFunction function,
05572 void *user_data,
05573 DBusFreeFunction free_data_function)
05574 {
05575 DBusMessageFilter *filter;
05576
05577 _dbus_return_val_if_fail (connection != NULL, FALSE);
05578 _dbus_return_val_if_fail (function != NULL, FALSE);
05579
05580 filter = dbus_new0 (DBusMessageFilter, 1);
05581 if (filter == NULL)
05582 return FALSE;
05583
05584 _dbus_atomic_inc (&filter->refcount);
05585
05586 CONNECTION_LOCK (connection);
05587
05588 if (!_dbus_list_append (&connection->filter_list,
05589 filter))
05590 {
05591 _dbus_message_filter_unref (filter);
05592 CONNECTION_UNLOCK (connection);
05593 return FALSE;
05594 }
05595
05596
05597
05598
05599
05600
05601 filter->function = function;
05602 filter->user_data = user_data;
05603 filter->free_user_data_function = free_data_function;
05604
05605 CONNECTION_UNLOCK (connection);
05606 return TRUE;
05607 }
05608
05621 void
05622 dbus_connection_remove_filter (DBusConnection *connection,
05623 DBusHandleMessageFunction function,
05624 void *user_data)
05625 {
05626 DBusList *link;
05627 DBusMessageFilter *filter;
05628
05629 _dbus_return_if_fail (connection != NULL);
05630 _dbus_return_if_fail (function != NULL);
05631
05632 CONNECTION_LOCK (connection);
05633
05634 filter = NULL;
05635
05636 link = _dbus_list_get_last_link (&connection->filter_list);
05637 while (link != NULL)
05638 {
05639 filter = link->data;
05640
05641 if (filter->function == function &&
05642 filter->user_data == user_data)
05643 {
05644 _dbus_list_remove_link (&connection->filter_list, link);
05645 filter->function = NULL;
05646
05647 break;
05648 }
05649
05650 link = _dbus_list_get_prev_link (&connection->filter_list, link);
05651 filter = NULL;
05652 }
05653
05654 CONNECTION_UNLOCK (connection);
05655
05656 #ifndef DBUS_DISABLE_CHECKS
05657 if (filter == NULL)
05658 {
05659 _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
05660 function, user_data);
05661 return;
05662 }
05663 #endif
05664
05665
05666 if (filter->free_user_data_function)
05667 (* filter->free_user_data_function) (filter->user_data);
05668
05669 filter->free_user_data_function = NULL;
05670 filter->user_data = NULL;
05671
05672 _dbus_message_filter_unref (filter);
05673 }
05674
05690 static dbus_bool_t
05691 _dbus_connection_register_object_path (DBusConnection *connection,
05692 dbus_bool_t fallback,
05693 const char *path,
05694 const DBusObjectPathVTable *vtable,
05695 void *user_data,
05696 DBusError *error)
05697 {
05698 char **decomposed_path;
05699 dbus_bool_t retval;
05700
05701 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05702 return FALSE;
05703
05704 CONNECTION_LOCK (connection);
05705
05706 retval = _dbus_object_tree_register (connection->objects,
05707 fallback,
05708 (const char **) decomposed_path, vtable,
05709 user_data, error);
05710
05711 CONNECTION_UNLOCK (connection);
05712
05713 dbus_free_string_array (decomposed_path);
05714
05715 return retval;
05716 }
05717
05730 dbus_bool_t
05731 dbus_connection_try_register_object_path (DBusConnection *connection,
05732 const char *path,
05733 const DBusObjectPathVTable *vtable,
05734 void *user_data,
05735 DBusError *error)
05736 {
05737 _dbus_return_val_if_fail (connection != NULL, FALSE);
05738 _dbus_return_val_if_fail (path != NULL, FALSE);
05739 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05740 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05741
05742 return _dbus_connection_register_object_path (connection, FALSE, path, vtable, user_data, error);
05743 }
05744
05760 dbus_bool_t
05761 dbus_connection_register_object_path (DBusConnection *connection,
05762 const char *path,
05763 const DBusObjectPathVTable *vtable,
05764 void *user_data)
05765 {
05766 dbus_bool_t retval;
05767 DBusError error = DBUS_ERROR_INIT;
05768
05769 _dbus_return_val_if_fail (connection != NULL, FALSE);
05770 _dbus_return_val_if_fail (path != NULL, FALSE);
05771 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05772 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05773
05774 retval = _dbus_connection_register_object_path (connection, FALSE, path, vtable, user_data, &error);
05775
05776 if (dbus_error_has_name (&error, DBUS_ERROR_OBJECT_PATH_IN_USE))
05777 {
05778 _dbus_warn ("%s\n", error.message);
05779 dbus_error_free (&error);
05780 return FALSE;
05781 }
05782
05783 return retval;
05784 }
05785
05800 dbus_bool_t
05801 dbus_connection_try_register_fallback (DBusConnection *connection,
05802 const char *path,
05803 const DBusObjectPathVTable *vtable,
05804 void *user_data,
05805 DBusError *error)
05806 {
05807 _dbus_return_val_if_fail (connection != NULL, FALSE);
05808 _dbus_return_val_if_fail (path != NULL, FALSE);
05809 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05810 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05811
05812 return _dbus_connection_register_object_path (connection, TRUE, path, vtable, user_data, error);
05813 }
05814
05832 dbus_bool_t
05833 dbus_connection_register_fallback (DBusConnection *connection,
05834 const char *path,
05835 const DBusObjectPathVTable *vtable,
05836 void *user_data)
05837 {
05838 dbus_bool_t retval;
05839 DBusError error = DBUS_ERROR_INIT;
05840
05841 _dbus_return_val_if_fail (connection != NULL, FALSE);
05842 _dbus_return_val_if_fail (path != NULL, FALSE);
05843 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05844 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05845
05846 retval = _dbus_connection_register_object_path (connection, TRUE, path, vtable, user_data, &error);
05847
05848 if (dbus_error_has_name (&error, DBUS_ERROR_OBJECT_PATH_IN_USE))
05849 {
05850 _dbus_warn ("%s\n", error.message);
05851 dbus_error_free (&error);
05852 return FALSE;
05853 }
05854
05855 return retval;
05856 }
05857
05867 dbus_bool_t
05868 dbus_connection_unregister_object_path (DBusConnection *connection,
05869 const char *path)
05870 {
05871 char **decomposed_path;
05872
05873 _dbus_return_val_if_fail (connection != NULL, FALSE);
05874 _dbus_return_val_if_fail (path != NULL, FALSE);
05875 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05876
05877 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05878 return FALSE;
05879
05880 CONNECTION_LOCK (connection);
05881
05882 _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
05883
05884 dbus_free_string_array (decomposed_path);
05885
05886 return TRUE;
05887 }
05888
05899 dbus_bool_t
05900 dbus_connection_get_object_path_data (DBusConnection *connection,
05901 const char *path,
05902 void **data_p)
05903 {
05904 char **decomposed_path;
05905
05906 _dbus_return_val_if_fail (connection != NULL, FALSE);
05907 _dbus_return_val_if_fail (path != NULL, FALSE);
05908 _dbus_return_val_if_fail (data_p != NULL, FALSE);
05909
05910 *data_p = NULL;
05911
05912 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05913 return FALSE;
05914
05915 CONNECTION_LOCK (connection);
05916
05917 *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path);
05918
05919 CONNECTION_UNLOCK (connection);
05920
05921 dbus_free_string_array (decomposed_path);
05922
05923 return TRUE;
05924 }
05925
05936 dbus_bool_t
05937 dbus_connection_list_registered (DBusConnection *connection,
05938 const char *parent_path,
05939 char ***child_entries)
05940 {
05941 char **decomposed_path;
05942 dbus_bool_t retval;
05943 _dbus_return_val_if_fail (connection != NULL, FALSE);
05944 _dbus_return_val_if_fail (parent_path != NULL, FALSE);
05945 _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
05946 _dbus_return_val_if_fail (child_entries != NULL, FALSE);
05947
05948 if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
05949 return FALSE;
05950
05951 CONNECTION_LOCK (connection);
05952
05953 retval = _dbus_object_tree_list_registered_and_unlock (connection->objects,
05954 (const char **) decomposed_path,
05955 child_entries);
05956 dbus_free_string_array (decomposed_path);
05957
05958 return retval;
05959 }
05960
05961 static DBusDataSlotAllocator slot_allocator =
05962 _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (connection_slots));
05963
05978 dbus_bool_t
05979 dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
05980 {
05981 return _dbus_data_slot_allocator_alloc (&slot_allocator,
05982 slot_p);
05983 }
05984
05996 void
05997 dbus_connection_free_data_slot (dbus_int32_t *slot_p)
05998 {
05999 _dbus_return_if_fail (*slot_p >= 0);
06000
06001 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
06002 }
06003
06026 dbus_bool_t
06027 dbus_connection_set_data (DBusConnection *connection,
06028 dbus_int32_t slot,
06029 void *data,
06030 DBusFreeFunction free_data_func)
06031 {
06032 DBusFreeFunction old_free_func;
06033 void *old_data;
06034 dbus_bool_t retval;
06035
06036 _dbus_return_val_if_fail (connection != NULL, FALSE);
06037 _dbus_return_val_if_fail (slot >= 0, FALSE);
06038
06039 SLOTS_LOCK (connection);
06040
06041 retval = _dbus_data_slot_list_set (&slot_allocator,
06042 &connection->slot_list,
06043 slot, data, free_data_func,
06044 &old_free_func, &old_data);
06045
06046 SLOTS_UNLOCK (connection);
06047
06048 if (retval)
06049 {
06050
06051 if (old_free_func)
06052 (* old_free_func) (old_data);
06053 }
06054
06055 return retval;
06056 }
06057
06075 void*
06076 dbus_connection_get_data (DBusConnection *connection,
06077 dbus_int32_t slot)
06078 {
06079 void *res;
06080
06081 _dbus_return_val_if_fail (connection != NULL, NULL);
06082 _dbus_return_val_if_fail (slot >= 0, NULL);
06083
06084 SLOTS_LOCK (connection);
06085
06086 res = _dbus_data_slot_list_get (&slot_allocator,
06087 &connection->slot_list,
06088 slot);
06089
06090 SLOTS_UNLOCK (connection);
06091
06092 return res;
06093 }
06094
06101 void
06102 dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
06103 {
06104 _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
06105 }
06106
06115 void
06116 dbus_connection_set_max_message_size (DBusConnection *connection,
06117 long size)
06118 {
06119 _dbus_return_if_fail (connection != NULL);
06120
06121 CONNECTION_LOCK (connection);
06122 _dbus_transport_set_max_message_size (connection->transport,
06123 size);
06124 CONNECTION_UNLOCK (connection);
06125 }
06126
06133 long
06134 dbus_connection_get_max_message_size (DBusConnection *connection)
06135 {
06136 long res;
06137
06138 _dbus_return_val_if_fail (connection != NULL, 0);
06139
06140 CONNECTION_LOCK (connection);
06141 res = _dbus_transport_get_max_message_size (connection->transport);
06142 CONNECTION_UNLOCK (connection);
06143 return res;
06144 }
06145
06154 void
06155 dbus_connection_set_max_message_unix_fds (DBusConnection *connection,
06156 long n)
06157 {
06158 _dbus_return_if_fail (connection != NULL);
06159
06160 CONNECTION_LOCK (connection);
06161 _dbus_transport_set_max_message_unix_fds (connection->transport,
06162 n);
06163 CONNECTION_UNLOCK (connection);
06164 }
06165
06172 long
06173 dbus_connection_get_max_message_unix_fds (DBusConnection *connection)
06174 {
06175 long res;
06176
06177 _dbus_return_val_if_fail (connection != NULL, 0);
06178
06179 CONNECTION_LOCK (connection);
06180 res = _dbus_transport_get_max_message_unix_fds (connection->transport);
06181 CONNECTION_UNLOCK (connection);
06182 return res;
06183 }
06184
06210 void
06211 dbus_connection_set_max_received_size (DBusConnection *connection,
06212 long size)
06213 {
06214 _dbus_return_if_fail (connection != NULL);
06215
06216 CONNECTION_LOCK (connection);
06217 _dbus_transport_set_max_received_size (connection->transport,
06218 size);
06219 CONNECTION_UNLOCK (connection);
06220 }
06221
06228 long
06229 dbus_connection_get_max_received_size (DBusConnection *connection)
06230 {
06231 long res;
06232
06233 _dbus_return_val_if_fail (connection != NULL, 0);
06234
06235 CONNECTION_LOCK (connection);
06236 res = _dbus_transport_get_max_received_size (connection->transport);
06237 CONNECTION_UNLOCK (connection);
06238 return res;
06239 }
06240
06252 void
06253 dbus_connection_set_max_received_unix_fds (DBusConnection *connection,
06254 long n)
06255 {
06256 _dbus_return_if_fail (connection != NULL);
06257
06258 CONNECTION_LOCK (connection);
06259 _dbus_transport_set_max_received_unix_fds (connection->transport,
06260 n);
06261 CONNECTION_UNLOCK (connection);
06262 }
06263
06270 long
06271 dbus_connection_get_max_received_unix_fds (DBusConnection *connection)
06272 {
06273 long res;
06274
06275 _dbus_return_val_if_fail (connection != NULL, 0);
06276
06277 CONNECTION_LOCK (connection);
06278 res = _dbus_transport_get_max_received_unix_fds (connection->transport);
06279 CONNECTION_UNLOCK (connection);
06280 return res;
06281 }
06282
06293 long
06294 dbus_connection_get_outgoing_size (DBusConnection *connection)
06295 {
06296 long res;
06297
06298 _dbus_return_val_if_fail (connection != NULL, 0);
06299
06300 CONNECTION_LOCK (connection);
06301 res = _dbus_counter_get_size_value (connection->outgoing_counter);
06302 CONNECTION_UNLOCK (connection);
06303 return res;
06304 }
06305
06306 #ifdef DBUS_ENABLE_STATS
06307 void
06308 _dbus_connection_get_stats (DBusConnection *connection,
06309 dbus_uint32_t *in_messages,
06310 dbus_uint32_t *in_bytes,
06311 dbus_uint32_t *in_fds,
06312 dbus_uint32_t *in_peak_bytes,
06313 dbus_uint32_t *in_peak_fds,
06314 dbus_uint32_t *out_messages,
06315 dbus_uint32_t *out_bytes,
06316 dbus_uint32_t *out_fds,
06317 dbus_uint32_t *out_peak_bytes,
06318 dbus_uint32_t *out_peak_fds)
06319 {
06320 CONNECTION_LOCK (connection);
06321
06322 if (in_messages != NULL)
06323 *in_messages = connection->n_incoming;
06324
06325 _dbus_transport_get_stats (connection->transport,
06326 in_bytes, in_fds, in_peak_bytes, in_peak_fds);
06327
06328 if (out_messages != NULL)
06329 *out_messages = connection->n_outgoing;
06330
06331 if (out_bytes != NULL)
06332 *out_bytes = _dbus_counter_get_size_value (connection->outgoing_counter);
06333
06334 if (out_fds != NULL)
06335 *out_fds = _dbus_counter_get_unix_fd_value (connection->outgoing_counter);
06336
06337 if (out_peak_bytes != NULL)
06338 *out_peak_bytes = _dbus_counter_get_peak_size_value (connection->outgoing_counter);
06339
06340 if (out_peak_fds != NULL)
06341 *out_peak_fds = _dbus_counter_get_peak_unix_fd_value (connection->outgoing_counter);
06342
06343 CONNECTION_UNLOCK (connection);
06344 }
06345 #endif
06346
06354 long
06355 dbus_connection_get_outgoing_unix_fds (DBusConnection *connection)
06356 {
06357 long res;
06358
06359 _dbus_return_val_if_fail (connection != NULL, 0);
06360
06361 CONNECTION_LOCK (connection);
06362 res = _dbus_counter_get_unix_fd_value (connection->outgoing_counter);
06363 CONNECTION_UNLOCK (connection);
06364 return res;
06365 }
06366
06367 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
06368
06374 const char*
06375 _dbus_connection_get_address (DBusConnection *connection)
06376 {
06377 return _dbus_transport_get_address (connection->transport);
06378 }
06379 #endif
06380