00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config.h>
00025 #include "dbus-shared.h"
00026 #include "dbus-connection.h"
00027 #include "dbus-list.h"
00028 #include "dbus-timeout.h"
00029 #include "dbus-transport.h"
00030 #include "dbus-watch.h"
00031 #include "dbus-connection-internal.h"
00032 #include "dbus-pending-call-internal.h"
00033 #include "dbus-list.h"
00034 #include "dbus-hash.h"
00035 #include "dbus-message-internal.h"
00036 #include "dbus-message-private.h"
00037 #include "dbus-threads.h"
00038 #include "dbus-protocol.h"
00039 #include "dbus-dataslot.h"
00040 #include "dbus-string.h"
00041 #include "dbus-pending-call.h"
00042 #include "dbus-object-tree.h"
00043 #include "dbus-threads-internal.h"
00044 #include "dbus-bus.h"
00045 #include "dbus-marshal-basic.h"
00046
00047 #ifdef DBUS_DISABLE_CHECKS
00048 #define TOOK_LOCK_CHECK(connection)
00049 #define RELEASING_LOCK_CHECK(connection)
00050 #define HAVE_LOCK_CHECK(connection)
00051 #else
00052 #define TOOK_LOCK_CHECK(connection) do { \
00053 _dbus_assert (!(connection)->have_connection_lock); \
00054 (connection)->have_connection_lock = TRUE; \
00055 } while (0)
00056 #define RELEASING_LOCK_CHECK(connection) do { \
00057 _dbus_assert ((connection)->have_connection_lock); \
00058 (connection)->have_connection_lock = FALSE; \
00059 } while (0)
00060 #define HAVE_LOCK_CHECK(connection) _dbus_assert ((connection)->have_connection_lock)
00061
00062 #endif
00063
00064 #define TRACE_LOCKS 1
00065
00066 #define CONNECTION_LOCK(connection) do { \
00067 if (TRACE_LOCKS) { _dbus_verbose ("LOCK\n"); } \
00068 _dbus_mutex_lock ((connection)->mutex); \
00069 TOOK_LOCK_CHECK (connection); \
00070 } while (0)
00071
00072 #define CONNECTION_UNLOCK(connection) _dbus_connection_unlock (connection)
00073
00074 #define SLOTS_LOCK(connection) do { \
00075 _dbus_mutex_lock ((connection)->slot_mutex); \
00076 } while (0)
00077
00078 #define SLOTS_UNLOCK(connection) do { \
00079 _dbus_mutex_unlock ((connection)->slot_mutex); \
00080 } while (0)
00081
00082 #define DISPATCH_STATUS_NAME(s) \
00083 ((s) == DBUS_DISPATCH_COMPLETE ? "complete" : \
00084 (s) == DBUS_DISPATCH_DATA_REMAINS ? "data remains" : \
00085 (s) == DBUS_DISPATCH_NEED_MEMORY ? "need memory" : \
00086 "???")
00087
00208 typedef struct DBusMessageFilter DBusMessageFilter;
00209
00213 struct DBusMessageFilter
00214 {
00215 DBusAtomic refcount;
00216 DBusHandleMessageFunction function;
00217 void *user_data;
00218 DBusFreeFunction free_user_data_function;
00219 };
00220
00221
00225 struct DBusPreallocatedSend
00226 {
00227 DBusConnection *connection;
00228 DBusList *queue_link;
00229 DBusList *counter_link;
00230 };
00231
00232 #if HAVE_DECL_MSG_NOSIGNAL
00233 static dbus_bool_t _dbus_modify_sigpipe = FALSE;
00234 #else
00235 static dbus_bool_t _dbus_modify_sigpipe = TRUE;
00236 #endif
00237
00241 struct DBusConnection
00242 {
00243 DBusAtomic refcount;
00245 DBusMutex *mutex;
00247 DBusMutex *dispatch_mutex;
00248 DBusCondVar *dispatch_cond;
00249 DBusMutex *io_path_mutex;
00250 DBusCondVar *io_path_cond;
00252 DBusList *outgoing_messages;
00253 DBusList *incoming_messages;
00254 DBusList *expired_messages;
00256 DBusMessage *message_borrowed;
00260 int n_outgoing;
00261 int n_incoming;
00263 DBusCounter *outgoing_counter;
00265 DBusTransport *transport;
00266 DBusWatchList *watches;
00267 DBusTimeoutList *timeouts;
00269 DBusList *filter_list;
00271 DBusMutex *slot_mutex;
00272 DBusDataSlotList slot_list;
00274 DBusHashTable *pending_replies;
00276 dbus_uint32_t client_serial;
00277 DBusList *disconnect_message_link;
00279 DBusWakeupMainFunction wakeup_main_function;
00280 void *wakeup_main_data;
00281 DBusFreeFunction free_wakeup_main_data;
00283 DBusDispatchStatusFunction dispatch_status_function;
00284 void *dispatch_status_data;
00285 DBusFreeFunction free_dispatch_status_data;
00287 DBusDispatchStatus last_dispatch_status;
00289 DBusObjectTree *objects;
00291 char *server_guid;
00293
00294
00295
00296
00297 dbus_bool_t dispatch_acquired;
00298 dbus_bool_t io_path_acquired;
00300 unsigned int shareable : 1;
00302 unsigned int exit_on_disconnect : 1;
00304 unsigned int route_peer_messages : 1;
00306 unsigned int disconnected_message_arrived : 1;
00310 unsigned int disconnected_message_processed : 1;
00314 #ifndef DBUS_DISABLE_CHECKS
00315 unsigned int have_connection_lock : 1;
00316 #endif
00317
00318 #ifndef DBUS_DISABLE_CHECKS
00319 int generation;
00320 #endif
00321 };
00322
00323 static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection);
00324 static void _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
00325 DBusDispatchStatus new_status);
00326 static void _dbus_connection_last_unref (DBusConnection *connection);
00327 static void _dbus_connection_acquire_dispatch (DBusConnection *connection);
00328 static void _dbus_connection_release_dispatch (DBusConnection *connection);
00329 static DBusDispatchStatus _dbus_connection_flush_unlocked (DBusConnection *connection);
00330 static void _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection);
00331 static dbus_bool_t _dbus_connection_get_is_connected_unlocked (DBusConnection *connection);
00332 static dbus_bool_t _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection,
00333 dbus_uint32_t client_serial);
00334
00335 static DBusMessageFilter *
00336 _dbus_message_filter_ref (DBusMessageFilter *filter)
00337 {
00338 #ifdef DBUS_DISABLE_ASSERT
00339 _dbus_atomic_inc (&filter->refcount);
00340 #else
00341 dbus_int32_t old_value;
00342
00343 old_value = _dbus_atomic_inc (&filter->refcount);
00344 _dbus_assert (old_value > 0);
00345 #endif
00346
00347 return filter;
00348 }
00349
00350 static void
00351 _dbus_message_filter_unref (DBusMessageFilter *filter)
00352 {
00353 dbus_int32_t old_value;
00354
00355 old_value = _dbus_atomic_dec (&filter->refcount);
00356 _dbus_assert (old_value > 0);
00357
00358 if (old_value == 1)
00359 {
00360 if (filter->free_user_data_function)
00361 (* filter->free_user_data_function) (filter->user_data);
00362
00363 dbus_free (filter);
00364 }
00365 }
00366
00372 void
00373 _dbus_connection_lock (DBusConnection *connection)
00374 {
00375 CONNECTION_LOCK (connection);
00376 }
00377
00383 void
00384 _dbus_connection_unlock (DBusConnection *connection)
00385 {
00386 DBusList *expired_messages;
00387 DBusList *iter;
00388
00389 if (TRACE_LOCKS)
00390 {
00391 _dbus_verbose ("UNLOCK\n");
00392 }
00393
00394
00395
00396 expired_messages = connection->expired_messages;
00397 connection->expired_messages = NULL;
00398
00399 RELEASING_LOCK_CHECK (connection);
00400 _dbus_mutex_unlock (connection->mutex);
00401
00402 for (iter = _dbus_list_pop_first_link (&expired_messages);
00403 iter != NULL;
00404 iter = _dbus_list_pop_first_link (&expired_messages))
00405 {
00406 DBusMessage *message = iter->data;
00407
00408 dbus_message_unref (message);
00409 _dbus_list_free_link (iter);
00410 }
00411 }
00412
00420 static void
00421 _dbus_connection_wakeup_mainloop (DBusConnection *connection)
00422 {
00423 if (connection->wakeup_main_function)
00424 (*connection->wakeup_main_function) (connection->wakeup_main_data);
00425 }
00426
00427 #ifdef DBUS_BUILD_TESTS
00428
00438 dbus_bool_t
00439 _dbus_connection_queue_received_message (DBusConnection *connection,
00440 DBusMessage *message)
00441 {
00442 DBusList *link;
00443
00444 link = _dbus_list_alloc_link (message);
00445 if (link == NULL)
00446 return FALSE;
00447
00448 dbus_message_ref (message);
00449 _dbus_connection_queue_received_message_link (connection, link);
00450
00451 return TRUE;
00452 }
00453
00466 void
00467 _dbus_connection_test_get_locks (DBusConnection *connection,
00468 DBusMutex **mutex_loc,
00469 DBusMutex **dispatch_mutex_loc,
00470 DBusMutex **io_path_mutex_loc,
00471 DBusCondVar **dispatch_cond_loc,
00472 DBusCondVar **io_path_cond_loc)
00473 {
00474 *mutex_loc = connection->mutex;
00475 *dispatch_mutex_loc = connection->dispatch_mutex;
00476 *io_path_mutex_loc = connection->io_path_mutex;
00477 *dispatch_cond_loc = connection->dispatch_cond;
00478 *io_path_cond_loc = connection->io_path_cond;
00479 }
00480 #endif
00481
00490 void
00491 _dbus_connection_queue_received_message_link (DBusConnection *connection,
00492 DBusList *link)
00493 {
00494 DBusPendingCall *pending;
00495 dbus_uint32_t reply_serial;
00496 DBusMessage *message;
00497
00498 _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport));
00499
00500 _dbus_list_append_link (&connection->incoming_messages,
00501 link);
00502 message = link->data;
00503
00504
00505 reply_serial = dbus_message_get_reply_serial (message);
00506 if (reply_serial != 0)
00507 {
00508 pending = _dbus_hash_table_lookup_int (connection->pending_replies,
00509 reply_serial);
00510 if (pending != NULL)
00511 {
00512 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00513 _dbus_connection_remove_timeout_unlocked (connection,
00514 _dbus_pending_call_get_timeout_unlocked (pending));
00515
00516 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00517 }
00518 }
00519
00520
00521
00522 connection->n_incoming += 1;
00523
00524 _dbus_connection_wakeup_mainloop (connection);
00525
00526 _dbus_verbose ("Message %p (%s %s %s %s '%s' reply to %u) added to incoming queue %p, %d incoming\n",
00527 message,
00528 dbus_message_type_to_string (dbus_message_get_type (message)),
00529 dbus_message_get_path (message) ?
00530 dbus_message_get_path (message) :
00531 "no path",
00532 dbus_message_get_interface (message) ?
00533 dbus_message_get_interface (message) :
00534 "no interface",
00535 dbus_message_get_member (message) ?
00536 dbus_message_get_member (message) :
00537 "no member",
00538 dbus_message_get_signature (message),
00539 dbus_message_get_reply_serial (message),
00540 connection,
00541 connection->n_incoming);}
00542
00551 void
00552 _dbus_connection_queue_synthesized_message_link (DBusConnection *connection,
00553 DBusList *link)
00554 {
00555 HAVE_LOCK_CHECK (connection);
00556
00557 _dbus_list_append_link (&connection->incoming_messages, link);
00558
00559 connection->n_incoming += 1;
00560
00561 _dbus_connection_wakeup_mainloop (connection);
00562
00563 _dbus_verbose ("Synthesized message %p added to incoming queue %p, %d incoming\n",
00564 link->data, connection, connection->n_incoming);
00565 }
00566
00567
00575 dbus_bool_t
00576 _dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection)
00577 {
00578 HAVE_LOCK_CHECK (connection);
00579 return connection->outgoing_messages != NULL;
00580 }
00581
00591 dbus_bool_t
00592 dbus_connection_has_messages_to_send (DBusConnection *connection)
00593 {
00594 dbus_bool_t v;
00595
00596 _dbus_return_val_if_fail (connection != NULL, FALSE);
00597
00598 CONNECTION_LOCK (connection);
00599 v = _dbus_connection_has_messages_to_send_unlocked (connection);
00600 CONNECTION_UNLOCK (connection);
00601
00602 return v;
00603 }
00604
00612 DBusMessage*
00613 _dbus_connection_get_message_to_send (DBusConnection *connection)
00614 {
00615 HAVE_LOCK_CHECK (connection);
00616
00617 return _dbus_list_get_last (&connection->outgoing_messages);
00618 }
00619
00628 void
00629 _dbus_connection_message_sent_unlocked (DBusConnection *connection,
00630 DBusMessage *message)
00631 {
00632 DBusList *link;
00633
00634 HAVE_LOCK_CHECK (connection);
00635
00636
00637
00638
00639
00640
00641 link = _dbus_list_get_last_link (&connection->outgoing_messages);
00642 _dbus_assert (link != NULL);
00643 _dbus_assert (link->data == message);
00644
00645 _dbus_list_unlink (&connection->outgoing_messages,
00646 link);
00647 _dbus_list_prepend_link (&connection->expired_messages, link);
00648
00649 connection->n_outgoing -= 1;
00650
00651 _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from outgoing queue %p, %d left to send\n",
00652 message,
00653 dbus_message_type_to_string (dbus_message_get_type (message)),
00654 dbus_message_get_path (message) ?
00655 dbus_message_get_path (message) :
00656 "no path",
00657 dbus_message_get_interface (message) ?
00658 dbus_message_get_interface (message) :
00659 "no interface",
00660 dbus_message_get_member (message) ?
00661 dbus_message_get_member (message) :
00662 "no member",
00663 dbus_message_get_signature (message),
00664 connection, connection->n_outgoing);
00665
00666
00667
00668 _dbus_message_remove_counter (message, connection->outgoing_counter, NULL);
00669
00670
00671 }
00672
00674 typedef dbus_bool_t (* DBusWatchAddFunction) (DBusWatchList *list,
00675 DBusWatch *watch);
00677 typedef void (* DBusWatchRemoveFunction) (DBusWatchList *list,
00678 DBusWatch *watch);
00680 typedef void (* DBusWatchToggleFunction) (DBusWatchList *list,
00681 DBusWatch *watch,
00682 dbus_bool_t enabled);
00683
00684 static dbus_bool_t
00685 protected_change_watch (DBusConnection *connection,
00686 DBusWatch *watch,
00687 DBusWatchAddFunction add_function,
00688 DBusWatchRemoveFunction remove_function,
00689 DBusWatchToggleFunction toggle_function,
00690 dbus_bool_t enabled)
00691 {
00692 dbus_bool_t retval;
00693
00694 HAVE_LOCK_CHECK (connection);
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714 if (connection->watches)
00715 {
00716 if (add_function)
00717 retval = (* add_function) (connection->watches, watch);
00718 else if (remove_function)
00719 {
00720 retval = TRUE;
00721 (* remove_function) (connection->watches, watch);
00722 }
00723 else
00724 {
00725 retval = TRUE;
00726 (* toggle_function) (connection->watches, watch, enabled);
00727 }
00728 return retval;
00729 }
00730 else
00731 return FALSE;
00732 }
00733
00734
00746 dbus_bool_t
00747 _dbus_connection_add_watch_unlocked (DBusConnection *connection,
00748 DBusWatch *watch)
00749 {
00750 return protected_change_watch (connection, watch,
00751 _dbus_watch_list_add_watch,
00752 NULL, NULL, FALSE);
00753 }
00754
00764 void
00765 _dbus_connection_remove_watch_unlocked (DBusConnection *connection,
00766 DBusWatch *watch)
00767 {
00768 protected_change_watch (connection, watch,
00769 NULL,
00770 _dbus_watch_list_remove_watch,
00771 NULL, FALSE);
00772 }
00773
00784 void
00785 _dbus_connection_toggle_watch_unlocked (DBusConnection *connection,
00786 DBusWatch *watch,
00787 dbus_bool_t enabled)
00788 {
00789 _dbus_assert (watch != NULL);
00790
00791 protected_change_watch (connection, watch,
00792 NULL, NULL,
00793 _dbus_watch_list_toggle_watch,
00794 enabled);
00795 }
00796
00798 typedef dbus_bool_t (* DBusTimeoutAddFunction) (DBusTimeoutList *list,
00799 DBusTimeout *timeout);
00801 typedef void (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list,
00802 DBusTimeout *timeout);
00804 typedef void (* DBusTimeoutToggleFunction) (DBusTimeoutList *list,
00805 DBusTimeout *timeout,
00806 dbus_bool_t enabled);
00807
00808 static dbus_bool_t
00809 protected_change_timeout (DBusConnection *connection,
00810 DBusTimeout *timeout,
00811 DBusTimeoutAddFunction add_function,
00812 DBusTimeoutRemoveFunction remove_function,
00813 DBusTimeoutToggleFunction toggle_function,
00814 dbus_bool_t enabled)
00815 {
00816 dbus_bool_t retval;
00817
00818 HAVE_LOCK_CHECK (connection);
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838 if (connection->timeouts)
00839 {
00840 if (add_function)
00841 retval = (* add_function) (connection->timeouts, timeout);
00842 else if (remove_function)
00843 {
00844 retval = TRUE;
00845 (* remove_function) (connection->timeouts, timeout);
00846 }
00847 else
00848 {
00849 retval = TRUE;
00850 (* toggle_function) (connection->timeouts, timeout, enabled);
00851 }
00852 return retval;
00853 }
00854 else
00855 return FALSE;
00856 }
00857
00870 dbus_bool_t
00871 _dbus_connection_add_timeout_unlocked (DBusConnection *connection,
00872 DBusTimeout *timeout)
00873 {
00874 return protected_change_timeout (connection, timeout,
00875 _dbus_timeout_list_add_timeout,
00876 NULL, NULL, FALSE);
00877 }
00878
00888 void
00889 _dbus_connection_remove_timeout_unlocked (DBusConnection *connection,
00890 DBusTimeout *timeout)
00891 {
00892 protected_change_timeout (connection, timeout,
00893 NULL,
00894 _dbus_timeout_list_remove_timeout,
00895 NULL, FALSE);
00896 }
00897
00908 void
00909 _dbus_connection_toggle_timeout_unlocked (DBusConnection *connection,
00910 DBusTimeout *timeout,
00911 dbus_bool_t enabled)
00912 {
00913 protected_change_timeout (connection, timeout,
00914 NULL, NULL,
00915 _dbus_timeout_list_toggle_timeout,
00916 enabled);
00917 }
00918
00919 static dbus_bool_t
00920 _dbus_connection_attach_pending_call_unlocked (DBusConnection *connection,
00921 DBusPendingCall *pending)
00922 {
00923 dbus_uint32_t reply_serial;
00924 DBusTimeout *timeout;
00925
00926 HAVE_LOCK_CHECK (connection);
00927
00928 reply_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
00929
00930 _dbus_assert (reply_serial != 0);
00931
00932 timeout = _dbus_pending_call_get_timeout_unlocked (pending);
00933
00934 if (timeout)
00935 {
00936 if (!_dbus_connection_add_timeout_unlocked (connection, timeout))
00937 return FALSE;
00938
00939 if (!_dbus_hash_table_insert_int (connection->pending_replies,
00940 reply_serial,
00941 pending))
00942 {
00943 _dbus_connection_remove_timeout_unlocked (connection, timeout);
00944
00945 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00946 HAVE_LOCK_CHECK (connection);
00947 return FALSE;
00948 }
00949
00950 _dbus_pending_call_set_timeout_added_unlocked (pending, TRUE);
00951 }
00952 else
00953 {
00954 if (!_dbus_hash_table_insert_int (connection->pending_replies,
00955 reply_serial,
00956 pending))
00957 {
00958 HAVE_LOCK_CHECK (connection);
00959 return FALSE;
00960 }
00961 }
00962
00963 _dbus_pending_call_ref_unlocked (pending);
00964
00965 HAVE_LOCK_CHECK (connection);
00966
00967 return TRUE;
00968 }
00969
00970 static void
00971 free_pending_call_on_hash_removal (void *data)
00972 {
00973 DBusPendingCall *pending;
00974 DBusConnection *connection;
00975
00976 if (data == NULL)
00977 return;
00978
00979 pending = data;
00980
00981 connection = _dbus_pending_call_get_connection_unlocked (pending);
00982
00983 HAVE_LOCK_CHECK (connection);
00984
00985 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00986 {
00987 _dbus_connection_remove_timeout_unlocked (connection,
00988 _dbus_pending_call_get_timeout_unlocked (pending));
00989
00990 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00991 }
00992
00993
00994
00995
00996
00997
00998 _dbus_connection_ref_unlocked (connection);
00999 _dbus_pending_call_unref_and_unlock (pending);
01000 CONNECTION_LOCK (connection);
01001 _dbus_connection_unref_unlocked (connection);
01002 }
01003
01004 static void
01005 _dbus_connection_detach_pending_call_unlocked (DBusConnection *connection,
01006 DBusPendingCall *pending)
01007 {
01008
01009
01010
01011 _dbus_hash_table_remove_int (connection->pending_replies,
01012 _dbus_pending_call_get_reply_serial_unlocked (pending));
01013 }
01014
01015 static void
01016 _dbus_connection_detach_pending_call_and_unlock (DBusConnection *connection,
01017 DBusPendingCall *pending)
01018 {
01019
01020
01021
01022
01023
01024
01025
01026 _dbus_pending_call_ref_unlocked (pending);
01027 _dbus_hash_table_remove_int (connection->pending_replies,
01028 _dbus_pending_call_get_reply_serial_unlocked (pending));
01029
01030 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
01031 _dbus_connection_remove_timeout_unlocked (connection,
01032 _dbus_pending_call_get_timeout_unlocked (pending));
01033
01034 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
01035
01036 _dbus_pending_call_unref_and_unlock (pending);
01037 }
01038
01047 void
01048 _dbus_connection_remove_pending_call (DBusConnection *connection,
01049 DBusPendingCall *pending)
01050 {
01051 CONNECTION_LOCK (connection);
01052 _dbus_connection_detach_pending_call_and_unlock (connection, pending);
01053 }
01054
01064 static dbus_bool_t
01065 _dbus_connection_acquire_io_path (DBusConnection *connection,
01066 int timeout_milliseconds)
01067 {
01068 dbus_bool_t we_acquired;
01069
01070 HAVE_LOCK_CHECK (connection);
01071
01072
01073 _dbus_connection_ref_unlocked (connection);
01074
01075
01076 CONNECTION_UNLOCK (connection);
01077
01078 _dbus_verbose ("locking io_path_mutex\n");
01079 _dbus_mutex_lock (connection->io_path_mutex);
01080
01081 _dbus_verbose ("start connection->io_path_acquired = %d timeout = %d\n",
01082 connection->io_path_acquired, timeout_milliseconds);
01083
01084 we_acquired = FALSE;
01085
01086 if (connection->io_path_acquired)
01087 {
01088 if (timeout_milliseconds != -1)
01089 {
01090 _dbus_verbose ("waiting %d for IO path to be acquirable\n",
01091 timeout_milliseconds);
01092
01093 if (!_dbus_condvar_wait_timeout (connection->io_path_cond,
01094 connection->io_path_mutex,
01095 timeout_milliseconds))
01096 {
01097
01098
01099
01100
01101
01102
01103
01104
01105 }
01106 }
01107 else
01108 {
01109 while (connection->io_path_acquired)
01110 {
01111 _dbus_verbose ("waiting for IO path to be acquirable\n");
01112 _dbus_condvar_wait (connection->io_path_cond,
01113 connection->io_path_mutex);
01114 }
01115 }
01116 }
01117
01118 if (!connection->io_path_acquired)
01119 {
01120 we_acquired = TRUE;
01121 connection->io_path_acquired = TRUE;
01122 }
01123
01124 _dbus_verbose ("end connection->io_path_acquired = %d we_acquired = %d\n",
01125 connection->io_path_acquired, we_acquired);
01126
01127 _dbus_verbose ("unlocking io_path_mutex\n");
01128 _dbus_mutex_unlock (connection->io_path_mutex);
01129
01130 CONNECTION_LOCK (connection);
01131
01132 HAVE_LOCK_CHECK (connection);
01133
01134 _dbus_connection_unref_unlocked (connection);
01135
01136 return we_acquired;
01137 }
01138
01146 static void
01147 _dbus_connection_release_io_path (DBusConnection *connection)
01148 {
01149 HAVE_LOCK_CHECK (connection);
01150
01151 _dbus_verbose ("locking io_path_mutex\n");
01152 _dbus_mutex_lock (connection->io_path_mutex);
01153
01154 _dbus_assert (connection->io_path_acquired);
01155
01156 _dbus_verbose ("start connection->io_path_acquired = %d\n",
01157 connection->io_path_acquired);
01158
01159 connection->io_path_acquired = FALSE;
01160 _dbus_condvar_wake_one (connection->io_path_cond);
01161
01162 _dbus_verbose ("unlocking io_path_mutex\n");
01163 _dbus_mutex_unlock (connection->io_path_mutex);
01164 }
01165
01201 void
01202 _dbus_connection_do_iteration_unlocked (DBusConnection *connection,
01203 DBusPendingCall *pending,
01204 unsigned int flags,
01205 int timeout_milliseconds)
01206 {
01207 _dbus_verbose ("start\n");
01208
01209 HAVE_LOCK_CHECK (connection);
01210
01211 if (connection->n_outgoing == 0)
01212 flags &= ~DBUS_ITERATION_DO_WRITING;
01213
01214 if (_dbus_connection_acquire_io_path (connection,
01215 (flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0))
01216 {
01217 HAVE_LOCK_CHECK (connection);
01218
01219 if ( (pending != NULL) && _dbus_pending_call_get_completed_unlocked(pending))
01220 {
01221 _dbus_verbose ("pending call completed while acquiring I/O path");
01222 }
01223 else if ( (pending != NULL) &&
01224 _dbus_connection_peek_for_reply_unlocked (connection,
01225 _dbus_pending_call_get_reply_serial_unlocked (pending)))
01226 {
01227 _dbus_verbose ("pending call completed while acquiring I/O path (reply found in queue)");
01228 }
01229 else
01230 {
01231 _dbus_transport_do_iteration (connection->transport,
01232 flags, timeout_milliseconds);
01233 }
01234
01235 _dbus_connection_release_io_path (connection);
01236 }
01237
01238 HAVE_LOCK_CHECK (connection);
01239
01240 _dbus_verbose ("end\n");
01241 }
01242
01252 DBusConnection*
01253 _dbus_connection_new_for_transport (DBusTransport *transport)
01254 {
01255 DBusConnection *connection;
01256 DBusWatchList *watch_list;
01257 DBusTimeoutList *timeout_list;
01258 DBusHashTable *pending_replies;
01259 DBusList *disconnect_link;
01260 DBusMessage *disconnect_message;
01261 DBusCounter *outgoing_counter;
01262 DBusObjectTree *objects;
01263
01264 watch_list = NULL;
01265 connection = NULL;
01266 pending_replies = NULL;
01267 timeout_list = NULL;
01268 disconnect_link = NULL;
01269 disconnect_message = NULL;
01270 outgoing_counter = NULL;
01271 objects = NULL;
01272
01273 watch_list = _dbus_watch_list_new ();
01274 if (watch_list == NULL)
01275 goto error;
01276
01277 timeout_list = _dbus_timeout_list_new ();
01278 if (timeout_list == NULL)
01279 goto error;
01280
01281 pending_replies =
01282 _dbus_hash_table_new (DBUS_HASH_INT,
01283 NULL,
01284 (DBusFreeFunction)free_pending_call_on_hash_removal);
01285 if (pending_replies == NULL)
01286 goto error;
01287
01288 connection = dbus_new0 (DBusConnection, 1);
01289 if (connection == NULL)
01290 goto error;
01291
01292 _dbus_mutex_new_at_location (&connection->mutex);
01293 if (connection->mutex == NULL)
01294 goto error;
01295
01296 _dbus_mutex_new_at_location (&connection->io_path_mutex);
01297 if (connection->io_path_mutex == NULL)
01298 goto error;
01299
01300 _dbus_mutex_new_at_location (&connection->dispatch_mutex);
01301 if (connection->dispatch_mutex == NULL)
01302 goto error;
01303
01304 _dbus_condvar_new_at_location (&connection->dispatch_cond);
01305 if (connection->dispatch_cond == NULL)
01306 goto error;
01307
01308 _dbus_condvar_new_at_location (&connection->io_path_cond);
01309 if (connection->io_path_cond == NULL)
01310 goto error;
01311
01312 _dbus_mutex_new_at_location (&connection->slot_mutex);
01313 if (connection->slot_mutex == NULL)
01314 goto error;
01315
01316 disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL,
01317 DBUS_INTERFACE_LOCAL,
01318 "Disconnected");
01319
01320 if (disconnect_message == NULL)
01321 goto error;
01322
01323 disconnect_link = _dbus_list_alloc_link (disconnect_message);
01324 if (disconnect_link == NULL)
01325 goto error;
01326
01327 outgoing_counter = _dbus_counter_new ();
01328 if (outgoing_counter == NULL)
01329 goto error;
01330
01331 objects = _dbus_object_tree_new (connection);
01332 if (objects == NULL)
01333 goto error;
01334
01335 if (_dbus_modify_sigpipe)
01336 _dbus_disable_sigpipe ();
01337
01338
01339 _dbus_atomic_inc (&connection->refcount);
01340 connection->transport = transport;
01341 connection->watches = watch_list;
01342 connection->timeouts = timeout_list;
01343 connection->pending_replies = pending_replies;
01344 connection->outgoing_counter = outgoing_counter;
01345 connection->filter_list = NULL;
01346 connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE;
01347 connection->objects = objects;
01348 connection->exit_on_disconnect = FALSE;
01349 connection->shareable = FALSE;
01350 connection->route_peer_messages = FALSE;
01351 connection->disconnected_message_arrived = FALSE;
01352 connection->disconnected_message_processed = FALSE;
01353
01354 #ifndef DBUS_DISABLE_CHECKS
01355 connection->generation = _dbus_current_generation;
01356 #endif
01357
01358 _dbus_data_slot_list_init (&connection->slot_list);
01359
01360 connection->client_serial = 1;
01361
01362 connection->disconnect_message_link = disconnect_link;
01363
01364 CONNECTION_LOCK (connection);
01365
01366 if (!_dbus_transport_set_connection (transport, connection))
01367 {
01368 CONNECTION_UNLOCK (connection);
01369
01370 goto error;
01371 }
01372
01373 _dbus_transport_ref (transport);
01374
01375 CONNECTION_UNLOCK (connection);
01376
01377 return connection;
01378
01379 error:
01380 if (disconnect_message != NULL)
01381 dbus_message_unref (disconnect_message);
01382
01383 if (disconnect_link != NULL)
01384 _dbus_list_free_link (disconnect_link);
01385
01386 if (connection != NULL)
01387 {
01388 _dbus_condvar_free_at_location (&connection->io_path_cond);
01389 _dbus_condvar_free_at_location (&connection->dispatch_cond);
01390 _dbus_mutex_free_at_location (&connection->mutex);
01391 _dbus_mutex_free_at_location (&connection->io_path_mutex);
01392 _dbus_mutex_free_at_location (&connection->dispatch_mutex);
01393 _dbus_mutex_free_at_location (&connection->slot_mutex);
01394 dbus_free (connection);
01395 }
01396 if (pending_replies)
01397 _dbus_hash_table_unref (pending_replies);
01398
01399 if (watch_list)
01400 _dbus_watch_list_free (watch_list);
01401
01402 if (timeout_list)
01403 _dbus_timeout_list_free (timeout_list);
01404
01405 if (outgoing_counter)
01406 _dbus_counter_unref (outgoing_counter);
01407
01408 if (objects)
01409 _dbus_object_tree_unref (objects);
01410
01411 return NULL;
01412 }
01413
01421 DBusConnection *
01422 _dbus_connection_ref_unlocked (DBusConnection *connection)
01423 {
01424 _dbus_assert (connection != NULL);
01425 _dbus_assert (connection->generation == _dbus_current_generation);
01426
01427 HAVE_LOCK_CHECK (connection);
01428
01429 _dbus_atomic_inc (&connection->refcount);
01430
01431 return connection;
01432 }
01433
01440 void
01441 _dbus_connection_unref_unlocked (DBusConnection *connection)
01442 {
01443 dbus_bool_t last_unref;
01444
01445 HAVE_LOCK_CHECK (connection);
01446
01447 _dbus_assert (connection != NULL);
01448
01449 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
01450
01451 if (last_unref)
01452 _dbus_connection_last_unref (connection);
01453 }
01454
01455 static dbus_uint32_t
01456 _dbus_connection_get_next_client_serial (DBusConnection *connection)
01457 {
01458 dbus_uint32_t serial;
01459
01460 serial = connection->client_serial++;
01461
01462 if (connection->client_serial == 0)
01463 connection->client_serial = 1;
01464
01465 return serial;
01466 }
01467
01481 dbus_bool_t
01482 _dbus_connection_handle_watch (DBusWatch *watch,
01483 unsigned int condition,
01484 void *data)
01485 {
01486 DBusConnection *connection;
01487 dbus_bool_t retval;
01488 DBusDispatchStatus status;
01489
01490 connection = data;
01491
01492 _dbus_verbose ("start\n");
01493
01494 CONNECTION_LOCK (connection);
01495
01496 if (!_dbus_connection_acquire_io_path (connection, 1))
01497 {
01498
01499 CONNECTION_UNLOCK (connection);
01500 return TRUE;
01501 }
01502
01503 HAVE_LOCK_CHECK (connection);
01504 retval = _dbus_transport_handle_watch (connection->transport,
01505 watch, condition);
01506
01507 _dbus_connection_release_io_path (connection);
01508
01509 HAVE_LOCK_CHECK (connection);
01510
01511 _dbus_verbose ("middle\n");
01512
01513 status = _dbus_connection_get_dispatch_status_unlocked (connection);
01514
01515
01516 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01517
01518 _dbus_verbose ("end\n");
01519
01520 return retval;
01521 }
01522
01523 _DBUS_DEFINE_GLOBAL_LOCK (shared_connections);
01524 static DBusHashTable *shared_connections = NULL;
01525 static DBusList *shared_connections_no_guid = NULL;
01526
01527 static void
01528 close_connection_on_shutdown (DBusConnection *connection)
01529 {
01530 DBusMessage *message;
01531
01532 dbus_connection_ref (connection);
01533 _dbus_connection_close_possibly_shared (connection);
01534
01535
01536 while ((message = dbus_connection_pop_message (connection)))
01537 {
01538 dbus_message_unref (message);
01539 }
01540 dbus_connection_unref (connection);
01541 }
01542
01543 static void
01544 shared_connections_shutdown (void *data)
01545 {
01546 int n_entries;
01547
01548 _DBUS_LOCK (shared_connections);
01549
01550
01551 while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0)
01552 {
01553 DBusConnection *connection;
01554 DBusHashIter iter;
01555
01556 _dbus_hash_iter_init (shared_connections, &iter);
01557 _dbus_hash_iter_next (&iter);
01558
01559 connection = _dbus_hash_iter_get_value (&iter);
01560
01561 _DBUS_UNLOCK (shared_connections);
01562 close_connection_on_shutdown (connection);
01563 _DBUS_LOCK (shared_connections);
01564
01565
01566 _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) < n_entries);
01567 }
01568
01569 _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) == 0);
01570
01571 _dbus_hash_table_unref (shared_connections);
01572 shared_connections = NULL;
01573
01574 if (shared_connections_no_guid != NULL)
01575 {
01576 DBusConnection *connection;
01577 connection = _dbus_list_pop_first (&shared_connections_no_guid);
01578 while (connection != NULL)
01579 {
01580 _DBUS_UNLOCK (shared_connections);
01581 close_connection_on_shutdown (connection);
01582 _DBUS_LOCK (shared_connections);
01583 connection = _dbus_list_pop_first (&shared_connections_no_guid);
01584 }
01585 }
01586
01587 shared_connections_no_guid = NULL;
01588
01589 _DBUS_UNLOCK (shared_connections);
01590 }
01591
01592 static dbus_bool_t
01593 connection_lookup_shared (DBusAddressEntry *entry,
01594 DBusConnection **result)
01595 {
01596 _dbus_verbose ("checking for existing connection\n");
01597
01598 *result = NULL;
01599
01600 _DBUS_LOCK (shared_connections);
01601
01602 if (shared_connections == NULL)
01603 {
01604 _dbus_verbose ("creating shared_connections hash table\n");
01605
01606 shared_connections = _dbus_hash_table_new (DBUS_HASH_STRING,
01607 dbus_free,
01608 NULL);
01609 if (shared_connections == NULL)
01610 {
01611 _DBUS_UNLOCK (shared_connections);
01612 return FALSE;
01613 }
01614
01615 if (!_dbus_register_shutdown_func (shared_connections_shutdown, NULL))
01616 {
01617 _dbus_hash_table_unref (shared_connections);
01618 shared_connections = NULL;
01619 _DBUS_UNLOCK (shared_connections);
01620 return FALSE;
01621 }
01622
01623 _dbus_verbose (" successfully created shared_connections\n");
01624
01625 _DBUS_UNLOCK (shared_connections);
01626 return TRUE;
01627 }
01628 else
01629 {
01630 const char *guid;
01631
01632 guid = dbus_address_entry_get_value (entry, "guid");
01633
01634 if (guid != NULL)
01635 {
01636 DBusConnection *connection;
01637
01638 connection = _dbus_hash_table_lookup_string (shared_connections,
01639 guid);
01640
01641 if (connection)
01642 {
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657 CONNECTION_LOCK (connection);
01658 if (_dbus_connection_get_is_connected_unlocked (connection))
01659 {
01660 _dbus_connection_ref_unlocked (connection);
01661 *result = connection;
01662 _dbus_verbose ("looked up existing connection to server guid %s\n",
01663 guid);
01664 }
01665 else
01666 {
01667 _dbus_verbose ("looked up existing connection to server guid %s but it was disconnected so ignoring it\n",
01668 guid);
01669 }
01670 CONNECTION_UNLOCK (connection);
01671 }
01672 }
01673
01674 _DBUS_UNLOCK (shared_connections);
01675 return TRUE;
01676 }
01677 }
01678
01679 static dbus_bool_t
01680 connection_record_shared_unlocked (DBusConnection *connection,
01681 const char *guid)
01682 {
01683 char *guid_key;
01684 char *guid_in_connection;
01685
01686 HAVE_LOCK_CHECK (connection);
01687 _dbus_assert (connection->server_guid == NULL);
01688 _dbus_assert (connection->shareable);
01689
01690
01691
01692
01693
01694 _dbus_connection_ref_unlocked (connection);
01695
01696 if (guid == NULL)
01697 {
01698 _DBUS_LOCK (shared_connections);
01699
01700 if (!_dbus_list_prepend (&shared_connections_no_guid, connection))
01701 {
01702 _DBUS_UNLOCK (shared_connections);
01703 return FALSE;
01704 }
01705
01706 _DBUS_UNLOCK (shared_connections);
01707 return TRUE;
01708 }
01709
01710
01711
01712
01713
01714
01715 guid_key = _dbus_strdup (guid);
01716 if (guid_key == NULL)
01717 return FALSE;
01718
01719 guid_in_connection = _dbus_strdup (guid);
01720 if (guid_in_connection == NULL)
01721 {
01722 dbus_free (guid_key);
01723 return FALSE;
01724 }
01725
01726 _DBUS_LOCK (shared_connections);
01727 _dbus_assert (shared_connections != NULL);
01728
01729 if (!_dbus_hash_table_insert_string (shared_connections,
01730 guid_key, connection))
01731 {
01732 dbus_free (guid_key);
01733 dbus_free (guid_in_connection);
01734 _DBUS_UNLOCK (shared_connections);
01735 return FALSE;
01736 }
01737
01738 connection->server_guid = guid_in_connection;
01739
01740 _dbus_verbose ("stored connection to %s to be shared\n",
01741 connection->server_guid);
01742
01743 _DBUS_UNLOCK (shared_connections);
01744
01745 _dbus_assert (connection->server_guid != NULL);
01746
01747 return TRUE;
01748 }
01749
01750 static void
01751 connection_forget_shared_unlocked (DBusConnection *connection)
01752 {
01753 HAVE_LOCK_CHECK (connection);
01754
01755 if (!connection->shareable)
01756 return;
01757
01758 _DBUS_LOCK (shared_connections);
01759
01760 if (connection->server_guid != NULL)
01761 {
01762 _dbus_verbose ("dropping connection to %s out of the shared table\n",
01763 connection->server_guid);
01764
01765 if (!_dbus_hash_table_remove_string (shared_connections,
01766 connection->server_guid))
01767 _dbus_assert_not_reached ("connection was not in the shared table");
01768
01769 dbus_free (connection->server_guid);
01770 connection->server_guid = NULL;
01771 }
01772 else
01773 {
01774 _dbus_list_remove (&shared_connections_no_guid, connection);
01775 }
01776
01777 _DBUS_UNLOCK (shared_connections);
01778
01779
01780 _dbus_connection_unref_unlocked (connection);
01781 }
01782
01783 static DBusConnection*
01784 connection_try_from_address_entry (DBusAddressEntry *entry,
01785 DBusError *error)
01786 {
01787 DBusTransport *transport;
01788 DBusConnection *connection;
01789
01790 transport = _dbus_transport_open (entry, error);
01791
01792 if (transport == NULL)
01793 {
01794 _DBUS_ASSERT_ERROR_IS_SET (error);
01795 return NULL;
01796 }
01797
01798 connection = _dbus_connection_new_for_transport (transport);
01799
01800 _dbus_transport_unref (transport);
01801
01802 if (connection == NULL)
01803 {
01804 _DBUS_SET_OOM (error);
01805 return NULL;
01806 }
01807
01808 #ifndef DBUS_DISABLE_CHECKS
01809 _dbus_assert (!connection->have_connection_lock);
01810 #endif
01811 return connection;
01812 }
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825
01826 static DBusConnection*
01827 _dbus_connection_open_internal (const char *address,
01828 dbus_bool_t shared,
01829 DBusError *error)
01830 {
01831 DBusConnection *connection;
01832 DBusAddressEntry **entries;
01833 DBusError tmp_error = DBUS_ERROR_INIT;
01834 DBusError first_error = DBUS_ERROR_INIT;
01835 int len, i;
01836
01837 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01838
01839 _dbus_verbose ("opening %s connection to: %s\n",
01840 shared ? "shared" : "private", address);
01841
01842 if (!dbus_parse_address (address, &entries, &len, error))
01843 return NULL;
01844
01845 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01846
01847 connection = NULL;
01848
01849 for (i = 0; i < len; i++)
01850 {
01851 if (shared)
01852 {
01853 if (!connection_lookup_shared (entries[i], &connection))
01854 _DBUS_SET_OOM (&tmp_error);
01855 }
01856
01857 if (connection == NULL)
01858 {
01859 connection = connection_try_from_address_entry (entries[i],
01860 &tmp_error);
01861
01862 if (connection != NULL && shared)
01863 {
01864 const char *guid;
01865
01866 connection->shareable = TRUE;
01867
01868
01869 guid = dbus_address_entry_get_value (entries[i], "guid");
01870
01871 CONNECTION_LOCK (connection);
01872
01873 if (!connection_record_shared_unlocked (connection, guid))
01874 {
01875 _DBUS_SET_OOM (&tmp_error);
01876 _dbus_connection_close_possibly_shared_and_unlock (connection);
01877 dbus_connection_unref (connection);
01878 connection = NULL;
01879 }
01880 else
01881 CONNECTION_UNLOCK (connection);
01882 }
01883 }
01884
01885 if (connection)
01886 break;
01887
01888 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
01889
01890 if (i == 0)
01891 dbus_move_error (&tmp_error, &first_error);
01892 else
01893 dbus_error_free (&tmp_error);
01894 }
01895
01896 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01897 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
01898
01899 if (connection == NULL)
01900 {
01901 _DBUS_ASSERT_ERROR_IS_SET (&first_error);
01902 dbus_move_error (&first_error, error);
01903 }
01904 else
01905 dbus_error_free (&first_error);
01906
01907 dbus_address_entries_free (entries);
01908 return connection;
01909 }
01910
01919 void
01920 _dbus_connection_close_possibly_shared (DBusConnection *connection)
01921 {
01922 _dbus_assert (connection != NULL);
01923 _dbus_assert (connection->generation == _dbus_current_generation);
01924
01925 CONNECTION_LOCK (connection);
01926 _dbus_connection_close_possibly_shared_and_unlock (connection);
01927 }
01928
01929 static DBusPreallocatedSend*
01930 _dbus_connection_preallocate_send_unlocked (DBusConnection *connection)
01931 {
01932 DBusPreallocatedSend *preallocated;
01933
01934 HAVE_LOCK_CHECK (connection);
01935
01936 _dbus_assert (connection != NULL);
01937
01938 preallocated = dbus_new (DBusPreallocatedSend, 1);
01939 if (preallocated == NULL)
01940 return NULL;
01941
01942 preallocated->queue_link = _dbus_list_alloc_link (NULL);
01943 if (preallocated->queue_link == NULL)
01944 goto failed_0;
01945
01946 preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter);
01947 if (preallocated->counter_link == NULL)
01948 goto failed_1;
01949
01950 _dbus_counter_ref (preallocated->counter_link->data);
01951
01952 preallocated->connection = connection;
01953
01954 return preallocated;
01955
01956 failed_1:
01957 _dbus_list_free_link (preallocated->queue_link);
01958 failed_0:
01959 dbus_free (preallocated);
01960
01961 return NULL;
01962 }
01963
01964
01965 static void
01966 _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *connection,
01967 DBusPreallocatedSend *preallocated,
01968 DBusMessage *message,
01969 dbus_uint32_t *client_serial)
01970 {
01971 dbus_uint32_t serial;
01972
01973 preallocated->queue_link->data = message;
01974 _dbus_list_prepend_link (&connection->outgoing_messages,
01975 preallocated->queue_link);
01976
01977
01978
01979 _dbus_message_add_counter_link (message,
01980 preallocated->counter_link);
01981
01982 dbus_free (preallocated);
01983 preallocated = NULL;
01984
01985 dbus_message_ref (message);
01986
01987 connection->n_outgoing += 1;
01988
01989 _dbus_verbose ("Message %p (%s %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
01990 message,
01991 dbus_message_type_to_string (dbus_message_get_type (message)),
01992 dbus_message_get_path (message) ?
01993 dbus_message_get_path (message) :
01994 "no path",
01995 dbus_message_get_interface (message) ?
01996 dbus_message_get_interface (message) :
01997 "no interface",
01998 dbus_message_get_member (message) ?
01999 dbus_message_get_member (message) :
02000 "no member",
02001 dbus_message_get_signature (message),
02002 dbus_message_get_destination (message) ?
02003 dbus_message_get_destination (message) :
02004 "null",
02005 connection,
02006 connection->n_outgoing);
02007
02008 if (dbus_message_get_serial (message) == 0)
02009 {
02010 serial = _dbus_connection_get_next_client_serial (connection);
02011 dbus_message_set_serial (message, serial);
02012 if (client_serial)
02013 *client_serial = serial;
02014 }
02015 else
02016 {
02017 if (client_serial)
02018 *client_serial = dbus_message_get_serial (message);
02019 }
02020
02021 _dbus_verbose ("Message %p serial is %u\n",
02022 message, dbus_message_get_serial (message));
02023
02024 dbus_message_lock (message);
02025
02026
02027
02028
02029 _dbus_connection_do_iteration_unlocked (connection,
02030 NULL,
02031 DBUS_ITERATION_DO_WRITING,
02032 -1);
02033
02034
02035 if (connection->n_outgoing > 0)
02036 _dbus_connection_wakeup_mainloop (connection);
02037 }
02038
02039 static void
02040 _dbus_connection_send_preallocated_and_unlock (DBusConnection *connection,
02041 DBusPreallocatedSend *preallocated,
02042 DBusMessage *message,
02043 dbus_uint32_t *client_serial)
02044 {
02045 DBusDispatchStatus status;
02046
02047 HAVE_LOCK_CHECK (connection);
02048
02049 _dbus_connection_send_preallocated_unlocked_no_update (connection,
02050 preallocated,
02051 message, client_serial);
02052
02053 _dbus_verbose ("middle\n");
02054 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02055
02056
02057 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02058 }
02059
02069 dbus_bool_t
02070 _dbus_connection_send_and_unlock (DBusConnection *connection,
02071 DBusMessage *message,
02072 dbus_uint32_t *client_serial)
02073 {
02074 DBusPreallocatedSend *preallocated;
02075
02076 _dbus_assert (connection != NULL);
02077 _dbus_assert (message != NULL);
02078
02079 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
02080 if (preallocated == NULL)
02081 {
02082 CONNECTION_UNLOCK (connection);
02083 return FALSE;
02084 }
02085
02086 _dbus_connection_send_preallocated_and_unlock (connection,
02087 preallocated,
02088 message,
02089 client_serial);
02090 return TRUE;
02091 }
02092
02117 void
02118 _dbus_connection_close_if_only_one_ref (DBusConnection *connection)
02119 {
02120 dbus_int32_t refcount;
02121
02122 CONNECTION_LOCK (connection);
02123
02124 refcount = _dbus_atomic_get (&connection->refcount);
02125
02126 _dbus_assert (refcount >= 1);
02127
02128 if (refcount == 1)
02129 _dbus_connection_close_possibly_shared_and_unlock (connection);
02130 else
02131 CONNECTION_UNLOCK (connection);
02132 }
02133
02134
02144 static void
02145 _dbus_memory_pause_based_on_timeout (int timeout_milliseconds)
02146 {
02147 if (timeout_milliseconds == -1)
02148 _dbus_sleep_milliseconds (1000);
02149 else if (timeout_milliseconds < 100)
02150 ;
02151 else if (timeout_milliseconds <= 1000)
02152 _dbus_sleep_milliseconds (timeout_milliseconds / 3);
02153 else
02154 _dbus_sleep_milliseconds (1000);
02155 }
02156
02157 static DBusMessage *
02158 generate_local_error_message (dbus_uint32_t serial,
02159 char *error_name,
02160 char *error_msg)
02161 {
02162 DBusMessage *message;
02163 message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
02164 if (!message)
02165 goto out;
02166
02167 if (!dbus_message_set_error_name (message, error_name))
02168 {
02169 dbus_message_unref (message);
02170 message = NULL;
02171 goto out;
02172 }
02173
02174 dbus_message_set_no_reply (message, TRUE);
02175
02176 if (!dbus_message_set_reply_serial (message,
02177 serial))
02178 {
02179 dbus_message_unref (message);
02180 message = NULL;
02181 goto out;
02182 }
02183
02184 if (error_msg != NULL)
02185 {
02186 DBusMessageIter iter;
02187
02188 dbus_message_iter_init_append (message, &iter);
02189 if (!dbus_message_iter_append_basic (&iter,
02190 DBUS_TYPE_STRING,
02191 &error_msg))
02192 {
02193 dbus_message_unref (message);
02194 message = NULL;
02195 goto out;
02196 }
02197 }
02198
02199 out:
02200 return message;
02201 }
02202
02203
02204
02205
02206 static dbus_bool_t
02207 _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection,
02208 dbus_uint32_t client_serial)
02209 {
02210 DBusList *link;
02211 HAVE_LOCK_CHECK (connection);
02212
02213 link = _dbus_list_get_first_link (&connection->incoming_messages);
02214
02215 while (link != NULL)
02216 {
02217 DBusMessage *reply = link->data;
02218
02219 if (dbus_message_get_reply_serial (reply) == client_serial)
02220 {
02221 _dbus_verbose ("%s reply to %d found in queue\n", _DBUS_FUNCTION_NAME, client_serial);
02222 return TRUE;
02223 }
02224 link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02225 }
02226
02227 return FALSE;
02228 }
02229
02230
02231
02232
02233 static DBusMessage*
02234 check_for_reply_unlocked (DBusConnection *connection,
02235 dbus_uint32_t client_serial)
02236 {
02237 DBusList *link;
02238
02239 HAVE_LOCK_CHECK (connection);
02240
02241 link = _dbus_list_get_first_link (&connection->incoming_messages);
02242
02243 while (link != NULL)
02244 {
02245 DBusMessage *reply = link->data;
02246
02247 if (dbus_message_get_reply_serial (reply) == client_serial)
02248 {
02249 _dbus_list_remove_link (&connection->incoming_messages, link);
02250 connection->n_incoming -= 1;
02251 return reply;
02252 }
02253 link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02254 }
02255
02256 return NULL;
02257 }
02258
02259 static void
02260 connection_timeout_and_complete_all_pending_calls_unlocked (DBusConnection *connection)
02261 {
02262
02263
02264
02265
02266
02267 while (_dbus_hash_table_get_n_entries (connection->pending_replies) > 0)
02268 {
02269 DBusPendingCall *pending;
02270 DBusHashIter iter;
02271
02272 _dbus_hash_iter_init (connection->pending_replies, &iter);
02273 _dbus_hash_iter_next (&iter);
02274
02275 pending = _dbus_hash_iter_get_value (&iter);
02276 _dbus_pending_call_ref_unlocked (pending);
02277
02278 _dbus_pending_call_queue_timeout_error_unlocked (pending,
02279 connection);
02280
02281 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
02282 _dbus_connection_remove_timeout_unlocked (connection,
02283 _dbus_pending_call_get_timeout_unlocked (pending));
02284 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
02285 _dbus_hash_iter_remove_entry (&iter);
02286
02287 _dbus_pending_call_unref_and_unlock (pending);
02288 CONNECTION_LOCK (connection);
02289 }
02290 HAVE_LOCK_CHECK (connection);
02291 }
02292
02293 static void
02294 complete_pending_call_and_unlock (DBusConnection *connection,
02295 DBusPendingCall *pending,
02296 DBusMessage *message)
02297 {
02298 _dbus_pending_call_set_reply_unlocked (pending, message);
02299 _dbus_pending_call_ref_unlocked (pending);
02300 _dbus_connection_detach_pending_call_and_unlock (connection, pending);
02301
02302
02303 _dbus_pending_call_complete (pending);
02304 dbus_pending_call_unref (pending);
02305 }
02306
02307 static dbus_bool_t
02308 check_for_reply_and_update_dispatch_unlocked (DBusConnection *connection,
02309 DBusPendingCall *pending)
02310 {
02311 DBusMessage *reply;
02312 DBusDispatchStatus status;
02313
02314 reply = check_for_reply_unlocked (connection,
02315 _dbus_pending_call_get_reply_serial_unlocked (pending));
02316 if (reply != NULL)
02317 {
02318 _dbus_verbose ("checked for reply\n");
02319
02320 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
02321
02322 complete_pending_call_and_unlock (connection, pending, reply);
02323 dbus_message_unref (reply);
02324
02325 CONNECTION_LOCK (connection);
02326 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02327 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02328 dbus_pending_call_unref (pending);
02329
02330 return TRUE;
02331 }
02332
02333 return FALSE;
02334 }
02335
02350 void
02351 _dbus_connection_block_pending_call (DBusPendingCall *pending)
02352 {
02353 long start_tv_sec, start_tv_usec;
02354 long tv_sec, tv_usec;
02355 DBusDispatchStatus status;
02356 DBusConnection *connection;
02357 dbus_uint32_t client_serial;
02358 DBusTimeout *timeout;
02359 int timeout_milliseconds, elapsed_milliseconds;
02360
02361 _dbus_assert (pending != NULL);
02362
02363 if (dbus_pending_call_get_completed (pending))
02364 return;
02365
02366 dbus_pending_call_ref (pending);
02367
02368 connection = _dbus_pending_call_get_connection_and_lock (pending);
02369
02370
02371 _dbus_connection_flush_unlocked (connection);
02372
02373 client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
02374
02375
02376
02377
02378
02379 timeout = _dbus_pending_call_get_timeout_unlocked (pending);
02380 _dbus_get_current_time (&start_tv_sec, &start_tv_usec);
02381 if (timeout)
02382 {
02383 timeout_milliseconds = dbus_timeout_get_interval (timeout);
02384
02385 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec\n",
02386 timeout_milliseconds,
02387 client_serial,
02388 start_tv_sec, start_tv_usec);
02389 }
02390 else
02391 {
02392 timeout_milliseconds = -1;
02393
02394 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block for reply serial %u\n", client_serial);
02395 }
02396
02397
02398
02399 if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02400 return;
02401
02402
02403
02404 _dbus_connection_do_iteration_unlocked (connection,
02405 pending,
02406 DBUS_ITERATION_DO_READING |
02407 DBUS_ITERATION_BLOCK,
02408 timeout_milliseconds);
02409
02410 recheck_status:
02411
02412 _dbus_verbose ("top of recheck\n");
02413
02414 HAVE_LOCK_CHECK (connection);
02415
02416
02417
02418 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02419
02420
02421
02422
02423 if (_dbus_pending_call_get_completed_unlocked (pending))
02424 {
02425 _dbus_verbose ("Pending call completed by dispatch\n");
02426 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02427 dbus_pending_call_unref (pending);
02428 return;
02429 }
02430
02431 if (status == DBUS_DISPATCH_DATA_REMAINS)
02432 {
02433 if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02434 return;
02435 }
02436
02437 _dbus_get_current_time (&tv_sec, &tv_usec);
02438 elapsed_milliseconds = (tv_sec - start_tv_sec) * 1000 +
02439 (tv_usec - start_tv_usec) / 1000;
02440
02441 if (!_dbus_connection_get_is_connected_unlocked (connection))
02442 {
02443 DBusMessage *error_msg;
02444
02445 error_msg = generate_local_error_message (client_serial,
02446 DBUS_ERROR_DISCONNECTED,
02447 "Connection was disconnected before a reply was received");
02448
02449
02450 complete_pending_call_and_unlock (connection, pending, error_msg);
02451 dbus_pending_call_unref (pending);
02452 return;
02453 }
02454 else if (connection->disconnect_message_link == NULL)
02455 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
02456 else if (timeout == NULL)
02457 {
02458 if (status == DBUS_DISPATCH_NEED_MEMORY)
02459 {
02460
02461
02462
02463
02464 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02465
02466 _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
02467 }
02468 else
02469 {
02470
02471 _dbus_connection_do_iteration_unlocked (connection,
02472 pending,
02473 DBUS_ITERATION_DO_READING |
02474 DBUS_ITERATION_BLOCK,
02475 timeout_milliseconds - elapsed_milliseconds);
02476 }
02477
02478 goto recheck_status;
02479 }
02480 else if (tv_sec < start_tv_sec)
02481 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
02482 else if (elapsed_milliseconds < timeout_milliseconds)
02483 {
02484 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds - elapsed_milliseconds);
02485
02486 if (status == DBUS_DISPATCH_NEED_MEMORY)
02487 {
02488
02489
02490
02491
02492 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02493
02494 _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
02495 }
02496 else
02497 {
02498
02499 _dbus_connection_do_iteration_unlocked (connection,
02500 NULL,
02501 DBUS_ITERATION_DO_READING |
02502 DBUS_ITERATION_BLOCK,
02503 timeout_milliseconds - elapsed_milliseconds);
02504 }
02505
02506 goto recheck_status;
02507 }
02508
02509 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %d milliseconds and got no reply\n",
02510 elapsed_milliseconds);
02511
02512 _dbus_assert (!_dbus_pending_call_get_completed_unlocked (pending));
02513
02514
02515 complete_pending_call_and_unlock (connection, pending, NULL);
02516
02517
02518 CONNECTION_LOCK (connection);
02519 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02520 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02521 dbus_pending_call_unref (pending);
02522 }
02523
02560 DBusConnection*
02561 dbus_connection_open (const char *address,
02562 DBusError *error)
02563 {
02564 DBusConnection *connection;
02565
02566 _dbus_return_val_if_fail (address != NULL, NULL);
02567 _dbus_return_val_if_error_is_set (error, NULL);
02568
02569 connection = _dbus_connection_open_internal (address,
02570 TRUE,
02571 error);
02572
02573 return connection;
02574 }
02575
02603 DBusConnection*
02604 dbus_connection_open_private (const char *address,
02605 DBusError *error)
02606 {
02607 DBusConnection *connection;
02608
02609 _dbus_return_val_if_fail (address != NULL, NULL);
02610 _dbus_return_val_if_error_is_set (error, NULL);
02611
02612 connection = _dbus_connection_open_internal (address,
02613 FALSE,
02614 error);
02615
02616 return connection;
02617 }
02618
02625 DBusConnection *
02626 dbus_connection_ref (DBusConnection *connection)
02627 {
02628 _dbus_return_val_if_fail (connection != NULL, NULL);
02629 _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
02630
02631 _dbus_atomic_inc (&connection->refcount);
02632
02633 return connection;
02634 }
02635
02636 static void
02637 free_outgoing_message (void *element,
02638 void *data)
02639 {
02640 DBusMessage *message = element;
02641 DBusConnection *connection = data;
02642
02643 _dbus_message_remove_counter (message,
02644 connection->outgoing_counter,
02645 NULL);
02646 dbus_message_unref (message);
02647 }
02648
02649
02650
02651
02652
02653 static void
02654 _dbus_connection_last_unref (DBusConnection *connection)
02655 {
02656 DBusList *link;
02657
02658 _dbus_verbose ("Finalizing connection %p\n", connection);
02659
02660 _dbus_assert (_dbus_atomic_get (&connection->refcount) == 0);
02661
02662
02663
02664
02665 _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
02666 _dbus_assert (connection->server_guid == NULL);
02667
02668
02669 _dbus_object_tree_free_all_unlocked (connection->objects);
02670
02671 dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
02672 dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
02673 dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
02674
02675 _dbus_watch_list_free (connection->watches);
02676 connection->watches = NULL;
02677
02678 _dbus_timeout_list_free (connection->timeouts);
02679 connection->timeouts = NULL;
02680
02681 _dbus_data_slot_list_free (&connection->slot_list);
02682
02683 link = _dbus_list_get_first_link (&connection->filter_list);
02684 while (link != NULL)
02685 {
02686 DBusMessageFilter *filter = link->data;
02687 DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
02688
02689 filter->function = NULL;
02690 _dbus_message_filter_unref (filter);
02691 link->data = NULL;
02692
02693 link = next;
02694 }
02695 _dbus_list_clear (&connection->filter_list);
02696
02697
02698
02699 _dbus_object_tree_unref (connection->objects);
02700
02701 _dbus_hash_table_unref (connection->pending_replies);
02702 connection->pending_replies = NULL;
02703
02704 _dbus_list_clear (&connection->filter_list);
02705
02706 _dbus_list_foreach (&connection->outgoing_messages,
02707 free_outgoing_message,
02708 connection);
02709 _dbus_list_clear (&connection->outgoing_messages);
02710
02711 _dbus_list_foreach (&connection->incoming_messages,
02712 (DBusForeachFunction) dbus_message_unref,
02713 NULL);
02714 _dbus_list_clear (&connection->incoming_messages);
02715
02716 _dbus_counter_unref (connection->outgoing_counter);
02717
02718 _dbus_transport_unref (connection->transport);
02719
02720 if (connection->disconnect_message_link)
02721 {
02722 DBusMessage *message = connection->disconnect_message_link->data;
02723 dbus_message_unref (message);
02724 _dbus_list_free_link (connection->disconnect_message_link);
02725 }
02726
02727 _dbus_condvar_free_at_location (&connection->dispatch_cond);
02728 _dbus_condvar_free_at_location (&connection->io_path_cond);
02729
02730 _dbus_mutex_free_at_location (&connection->io_path_mutex);
02731 _dbus_mutex_free_at_location (&connection->dispatch_mutex);
02732
02733 _dbus_mutex_free_at_location (&connection->slot_mutex);
02734
02735 _dbus_mutex_free_at_location (&connection->mutex);
02736
02737 dbus_free (connection);
02738 }
02739
02759 void
02760 dbus_connection_unref (DBusConnection *connection)
02761 {
02762 dbus_bool_t last_unref;
02763
02764 _dbus_return_if_fail (connection != NULL);
02765 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02766
02767 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
02768
02769 if (last_unref)
02770 {
02771 #ifndef DBUS_DISABLE_CHECKS
02772 if (_dbus_transport_get_is_connected (connection->transport))
02773 {
02774 _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",
02775 connection->shareable ?
02776 "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" :
02777 "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n");
02778 return;
02779 }
02780 #endif
02781 _dbus_connection_last_unref (connection);
02782 }
02783 }
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794 static void
02795 _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection)
02796 {
02797 DBusDispatchStatus status;
02798
02799 HAVE_LOCK_CHECK (connection);
02800
02801 _dbus_verbose ("Disconnecting %p\n", connection);
02802
02803
02804
02805
02806
02807 _dbus_connection_ref_unlocked (connection);
02808
02809 _dbus_transport_disconnect (connection->transport);
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02821
02822
02823 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02824
02825
02826 dbus_connection_unref (connection);
02827 }
02828
02871 void
02872 dbus_connection_close (DBusConnection *connection)
02873 {
02874 _dbus_return_if_fail (connection != NULL);
02875 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02876
02877 CONNECTION_LOCK (connection);
02878
02879 #ifndef DBUS_DISABLE_CHECKS
02880 if (connection->shareable)
02881 {
02882 CONNECTION_UNLOCK (connection);
02883
02884 _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n");
02885 return;
02886 }
02887 #endif
02888
02889 _dbus_connection_close_possibly_shared_and_unlock (connection);
02890 }
02891
02892 static dbus_bool_t
02893 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
02894 {
02895 HAVE_LOCK_CHECK (connection);
02896 return _dbus_transport_get_is_connected (connection->transport);
02897 }
02898
02912 dbus_bool_t
02913 dbus_connection_get_is_connected (DBusConnection *connection)
02914 {
02915 dbus_bool_t res;
02916
02917 _dbus_return_val_if_fail (connection != NULL, FALSE);
02918
02919 CONNECTION_LOCK (connection);
02920 res = _dbus_connection_get_is_connected_unlocked (connection);
02921 CONNECTION_UNLOCK (connection);
02922
02923 return res;
02924 }
02925
02934 dbus_bool_t
02935 dbus_connection_get_is_authenticated (DBusConnection *connection)
02936 {
02937 dbus_bool_t res;
02938
02939 _dbus_return_val_if_fail (connection != NULL, FALSE);
02940
02941 CONNECTION_LOCK (connection);
02942 res = _dbus_transport_get_is_authenticated (connection->transport);
02943 CONNECTION_UNLOCK (connection);
02944
02945 return res;
02946 }
02947
02968 dbus_bool_t
02969 dbus_connection_get_is_anonymous (DBusConnection *connection)
02970 {
02971 dbus_bool_t res;
02972
02973 _dbus_return_val_if_fail (connection != NULL, FALSE);
02974
02975 CONNECTION_LOCK (connection);
02976 res = _dbus_transport_get_is_anonymous (connection->transport);
02977 CONNECTION_UNLOCK (connection);
02978
02979 return res;
02980 }
02981
03013 char*
03014 dbus_connection_get_server_id (DBusConnection *connection)
03015 {
03016 char *id;
03017
03018 _dbus_return_val_if_fail (connection != NULL, NULL);
03019
03020 CONNECTION_LOCK (connection);
03021 id = _dbus_strdup (_dbus_transport_get_server_id (connection->transport));
03022 CONNECTION_UNLOCK (connection);
03023
03024 return id;
03025 }
03026
03044 dbus_bool_t
03045 dbus_connection_can_send_type(DBusConnection *connection,
03046 int type)
03047 {
03048 _dbus_return_val_if_fail (connection != NULL, FALSE);
03049
03050 if (!_dbus_type_is_valid(type))
03051 return FALSE;
03052
03053 if (type != DBUS_TYPE_UNIX_FD)
03054 return TRUE;
03055
03056 #ifdef HAVE_UNIX_FD_PASSING
03057 {
03058 dbus_bool_t b;
03059
03060 CONNECTION_LOCK(connection);
03061 b = _dbus_transport_can_pass_unix_fd(connection->transport);
03062 CONNECTION_UNLOCK(connection);
03063
03064 return b;
03065 }
03066 #endif
03067
03068 return FALSE;
03069 }
03070
03084 void
03085 dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
03086 dbus_bool_t exit_on_disconnect)
03087 {
03088 _dbus_return_if_fail (connection != NULL);
03089
03090 CONNECTION_LOCK (connection);
03091 connection->exit_on_disconnect = exit_on_disconnect != FALSE;
03092 CONNECTION_UNLOCK (connection);
03093 }
03094
03104 DBusPreallocatedSend*
03105 dbus_connection_preallocate_send (DBusConnection *connection)
03106 {
03107 DBusPreallocatedSend *preallocated;
03108
03109 _dbus_return_val_if_fail (connection != NULL, NULL);
03110
03111 CONNECTION_LOCK (connection);
03112
03113 preallocated =
03114 _dbus_connection_preallocate_send_unlocked (connection);
03115
03116 CONNECTION_UNLOCK (connection);
03117
03118 return preallocated;
03119 }
03120
03130 void
03131 dbus_connection_free_preallocated_send (DBusConnection *connection,
03132 DBusPreallocatedSend *preallocated)
03133 {
03134 _dbus_return_if_fail (connection != NULL);
03135 _dbus_return_if_fail (preallocated != NULL);
03136 _dbus_return_if_fail (connection == preallocated->connection);
03137
03138 _dbus_list_free_link (preallocated->queue_link);
03139 _dbus_counter_unref (preallocated->counter_link->data);
03140 _dbus_list_free_link (preallocated->counter_link);
03141 dbus_free (preallocated);
03142 }
03143
03156 void
03157 dbus_connection_send_preallocated (DBusConnection *connection,
03158 DBusPreallocatedSend *preallocated,
03159 DBusMessage *message,
03160 dbus_uint32_t *client_serial)
03161 {
03162 _dbus_return_if_fail (connection != NULL);
03163 _dbus_return_if_fail (preallocated != NULL);
03164 _dbus_return_if_fail (message != NULL);
03165 _dbus_return_if_fail (preallocated->connection == connection);
03166 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
03167 dbus_message_get_member (message) != NULL);
03168 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
03169 (dbus_message_get_interface (message) != NULL &&
03170 dbus_message_get_member (message) != NULL));
03171
03172 CONNECTION_LOCK (connection);
03173
03174 #ifdef HAVE_UNIX_FD_PASSING
03175
03176 if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03177 message->n_unix_fds > 0)
03178 {
03179
03180
03181
03182 CONNECTION_UNLOCK (connection);
03183 return;
03184 }
03185
03186 #endif
03187
03188 _dbus_connection_send_preallocated_and_unlock (connection,
03189 preallocated,
03190 message, client_serial);
03191 }
03192
03193 static dbus_bool_t
03194 _dbus_connection_send_unlocked_no_update (DBusConnection *connection,
03195 DBusMessage *message,
03196 dbus_uint32_t *client_serial)
03197 {
03198 DBusPreallocatedSend *preallocated;
03199
03200 _dbus_assert (connection != NULL);
03201 _dbus_assert (message != NULL);
03202
03203 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
03204 if (preallocated == NULL)
03205 return FALSE;
03206
03207 _dbus_connection_send_preallocated_unlocked_no_update (connection,
03208 preallocated,
03209 message,
03210 client_serial);
03211 return TRUE;
03212 }
03213
03241 dbus_bool_t
03242 dbus_connection_send (DBusConnection *connection,
03243 DBusMessage *message,
03244 dbus_uint32_t *serial)
03245 {
03246 _dbus_return_val_if_fail (connection != NULL, FALSE);
03247 _dbus_return_val_if_fail (message != NULL, FALSE);
03248
03249 CONNECTION_LOCK (connection);
03250
03251 #ifdef HAVE_UNIX_FD_PASSING
03252
03253 if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03254 message->n_unix_fds > 0)
03255 {
03256
03257
03258
03259 CONNECTION_UNLOCK (connection);
03260 return FALSE;
03261 }
03262
03263 #endif
03264
03265 return _dbus_connection_send_and_unlock (connection,
03266 message,
03267 serial);
03268 }
03269
03270 static dbus_bool_t
03271 reply_handler_timeout (void *data)
03272 {
03273 DBusConnection *connection;
03274 DBusDispatchStatus status;
03275 DBusPendingCall *pending = data;
03276
03277 connection = _dbus_pending_call_get_connection_and_lock (pending);
03278 _dbus_connection_ref_unlocked (connection);
03279
03280 _dbus_pending_call_queue_timeout_error_unlocked (pending,
03281 connection);
03282 _dbus_connection_remove_timeout_unlocked (connection,
03283 _dbus_pending_call_get_timeout_unlocked (pending));
03284 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
03285
03286 _dbus_verbose ("middle\n");
03287 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03288
03289
03290 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03291 dbus_connection_unref (connection);
03292
03293 return TRUE;
03294 }
03295
03335 dbus_bool_t
03336 dbus_connection_send_with_reply (DBusConnection *connection,
03337 DBusMessage *message,
03338 DBusPendingCall **pending_return,
03339 int timeout_milliseconds)
03340 {
03341 DBusPendingCall *pending;
03342 dbus_int32_t serial = -1;
03343 DBusDispatchStatus status;
03344
03345 _dbus_return_val_if_fail (connection != NULL, FALSE);
03346 _dbus_return_val_if_fail (message != NULL, FALSE);
03347 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03348
03349 if (pending_return)
03350 *pending_return = NULL;
03351
03352 CONNECTION_LOCK (connection);
03353
03354 #ifdef HAVE_UNIX_FD_PASSING
03355
03356 if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03357 message->n_unix_fds > 0)
03358 {
03359
03360
03361
03362
03363 CONNECTION_UNLOCK (connection);
03364 return TRUE;
03365 }
03366
03367 #endif
03368
03369 if (!_dbus_connection_get_is_connected_unlocked (connection))
03370 {
03371 CONNECTION_UNLOCK (connection);
03372
03373 return TRUE;
03374 }
03375
03376 pending = _dbus_pending_call_new_unlocked (connection,
03377 timeout_milliseconds,
03378 reply_handler_timeout);
03379
03380 if (pending == NULL)
03381 {
03382 CONNECTION_UNLOCK (connection);
03383 return FALSE;
03384 }
03385
03386
03387 serial = dbus_message_get_serial (message);
03388 if (serial == 0)
03389 {
03390 serial = _dbus_connection_get_next_client_serial (connection);
03391 dbus_message_set_serial (message, serial);
03392 }
03393
03394 if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
03395 goto error;
03396
03397
03398
03399
03400
03401 if (!_dbus_connection_attach_pending_call_unlocked (connection,
03402 pending))
03403 goto error;
03404
03405 if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
03406 {
03407 _dbus_connection_detach_pending_call_and_unlock (connection,
03408 pending);
03409 goto error_unlocked;
03410 }
03411
03412 if (pending_return)
03413 *pending_return = pending;
03414 else
03415 {
03416 _dbus_connection_detach_pending_call_unlocked (connection, pending);
03417
03418
03419
03420 }
03421
03422 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03423
03424
03425 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03426
03427 if (pending_return == NULL)
03428 dbus_pending_call_unref (pending);
03429
03430 return TRUE;
03431
03432 error:
03433 CONNECTION_UNLOCK (connection);
03434 error_unlocked:
03435 dbus_pending_call_unref (pending);
03436 return FALSE;
03437 }
03438
03469 DBusMessage*
03470 dbus_connection_send_with_reply_and_block (DBusConnection *connection,
03471 DBusMessage *message,
03472 int timeout_milliseconds,
03473 DBusError *error)
03474 {
03475 DBusMessage *reply;
03476 DBusPendingCall *pending;
03477
03478 _dbus_return_val_if_fail (connection != NULL, NULL);
03479 _dbus_return_val_if_fail (message != NULL, NULL);
03480 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL);
03481 _dbus_return_val_if_error_is_set (error, NULL);
03482
03483 #ifdef HAVE_UNIX_FD_PASSING
03484
03485 CONNECTION_LOCK (connection);
03486 if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
03487 message->n_unix_fds > 0)
03488 {
03489 CONNECTION_UNLOCK (connection);
03490 dbus_set_error(error, DBUS_ERROR_FAILED, "Cannot send file descriptors on this connection.");
03491 return NULL;
03492 }
03493 CONNECTION_UNLOCK (connection);
03494
03495 #endif
03496
03497 if (!dbus_connection_send_with_reply (connection, message,
03498 &pending, timeout_milliseconds))
03499 {
03500 _DBUS_SET_OOM (error);
03501 return NULL;
03502 }
03503
03504 if (pending == NULL)
03505 {
03506 dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Connection is closed");
03507 return NULL;
03508 }
03509
03510 dbus_pending_call_block (pending);
03511
03512 reply = dbus_pending_call_steal_reply (pending);
03513 dbus_pending_call_unref (pending);
03514
03515
03516
03517
03518 _dbus_assert (reply != NULL);
03519
03520 if (dbus_set_error_from_message (error, reply))
03521 {
03522 dbus_message_unref (reply);
03523 return NULL;
03524 }
03525 else
03526 return reply;
03527 }
03528
03537 static DBusDispatchStatus
03538 _dbus_connection_flush_unlocked (DBusConnection *connection)
03539 {
03540
03541
03542
03543
03544
03545 DBusDispatchStatus status;
03546
03547 HAVE_LOCK_CHECK (connection);
03548
03549 while (connection->n_outgoing > 0 &&
03550 _dbus_connection_get_is_connected_unlocked (connection))
03551 {
03552 _dbus_verbose ("doing iteration in\n");
03553 HAVE_LOCK_CHECK (connection);
03554 _dbus_connection_do_iteration_unlocked (connection,
03555 NULL,
03556 DBUS_ITERATION_DO_READING |
03557 DBUS_ITERATION_DO_WRITING |
03558 DBUS_ITERATION_BLOCK,
03559 -1);
03560 }
03561
03562 HAVE_LOCK_CHECK (connection);
03563 _dbus_verbose ("middle\n");
03564 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03565
03566 HAVE_LOCK_CHECK (connection);
03567 return status;
03568 }
03569
03575 void
03576 dbus_connection_flush (DBusConnection *connection)
03577 {
03578
03579
03580
03581
03582
03583 DBusDispatchStatus status;
03584
03585 _dbus_return_if_fail (connection != NULL);
03586
03587 CONNECTION_LOCK (connection);
03588
03589 status = _dbus_connection_flush_unlocked (connection);
03590
03591 HAVE_LOCK_CHECK (connection);
03592
03593 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03594
03595 _dbus_verbose ("end\n");
03596 }
03597
03608 static dbus_bool_t
03609 _dbus_connection_read_write_dispatch (DBusConnection *connection,
03610 int timeout_milliseconds,
03611 dbus_bool_t dispatch)
03612 {
03613 DBusDispatchStatus dstatus;
03614 dbus_bool_t progress_possible;
03615
03616
03617
03618
03619
03620 dbus_connection_ref (connection);
03621 dstatus = dbus_connection_get_dispatch_status (connection);
03622
03623 if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
03624 {
03625 _dbus_verbose ("doing dispatch\n");
03626 dbus_connection_dispatch (connection);
03627 CONNECTION_LOCK (connection);
03628 }
03629 else if (dstatus == DBUS_DISPATCH_NEED_MEMORY)
03630 {
03631 _dbus_verbose ("pausing for memory\n");
03632 _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
03633 CONNECTION_LOCK (connection);
03634 }
03635 else
03636 {
03637 CONNECTION_LOCK (connection);
03638 if (_dbus_connection_get_is_connected_unlocked (connection))
03639 {
03640 _dbus_verbose ("doing iteration\n");
03641 _dbus_connection_do_iteration_unlocked (connection,
03642 NULL,
03643 DBUS_ITERATION_DO_READING |
03644 DBUS_ITERATION_DO_WRITING |
03645 DBUS_ITERATION_BLOCK,
03646 timeout_milliseconds);
03647 }
03648 }
03649
03650 HAVE_LOCK_CHECK (connection);
03651
03652
03653
03654
03655 if (dispatch)
03656 progress_possible = connection->n_incoming != 0 ||
03657 connection->disconnect_message_link != NULL;
03658 else
03659 progress_possible = _dbus_connection_get_is_connected_unlocked (connection);
03660
03661 CONNECTION_UNLOCK (connection);
03662
03663 dbus_connection_unref (connection);
03664
03665 return progress_possible;
03666 }
03667
03668
03703 dbus_bool_t
03704 dbus_connection_read_write_dispatch (DBusConnection *connection,
03705 int timeout_milliseconds)
03706 {
03707 _dbus_return_val_if_fail (connection != NULL, FALSE);
03708 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03709 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE);
03710 }
03711
03735 dbus_bool_t
03736 dbus_connection_read_write (DBusConnection *connection,
03737 int timeout_milliseconds)
03738 {
03739 _dbus_return_val_if_fail (connection != NULL, FALSE);
03740 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03741 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE);
03742 }
03743
03744
03745
03746
03747
03748
03749 static void
03750 check_disconnected_message_arrived_unlocked (DBusConnection *connection,
03751 DBusMessage *head_of_queue)
03752 {
03753 HAVE_LOCK_CHECK (connection);
03754
03755
03756 if (connection->disconnect_message_link == NULL &&
03757 dbus_message_is_signal (head_of_queue,
03758 DBUS_INTERFACE_LOCAL,
03759 "Disconnected"))
03760 {
03761 connection->disconnected_message_arrived = TRUE;
03762 }
03763 }
03764
03784 DBusMessage*
03785 dbus_connection_borrow_message (DBusConnection *connection)
03786 {
03787 DBusDispatchStatus status;
03788 DBusMessage *message;
03789
03790 _dbus_return_val_if_fail (connection != NULL, NULL);
03791
03792 _dbus_verbose ("start\n");
03793
03794
03795
03796
03797 status = dbus_connection_get_dispatch_status (connection);
03798 if (status != DBUS_DISPATCH_DATA_REMAINS)
03799 return NULL;
03800
03801 CONNECTION_LOCK (connection);
03802
03803 _dbus_connection_acquire_dispatch (connection);
03804
03805
03806 _dbus_assert (connection->message_borrowed == NULL);
03807
03808 connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
03809
03810 message = connection->message_borrowed;
03811
03812 check_disconnected_message_arrived_unlocked (connection, message);
03813
03814
03815 if (message == NULL)
03816 _dbus_connection_release_dispatch (connection);
03817
03818 CONNECTION_UNLOCK (connection);
03819
03820
03821
03822 return message;
03823 }
03824
03833 void
03834 dbus_connection_return_message (DBusConnection *connection,
03835 DBusMessage *message)
03836 {
03837 DBusDispatchStatus status;
03838
03839 _dbus_return_if_fail (connection != NULL);
03840 _dbus_return_if_fail (message != NULL);
03841 _dbus_return_if_fail (message == connection->message_borrowed);
03842 _dbus_return_if_fail (connection->dispatch_acquired);
03843
03844 CONNECTION_LOCK (connection);
03845
03846 _dbus_assert (message == connection->message_borrowed);
03847
03848 connection->message_borrowed = NULL;
03849
03850 _dbus_connection_release_dispatch (connection);
03851
03852 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03853 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03854 }
03855
03865 void
03866 dbus_connection_steal_borrowed_message (DBusConnection *connection,
03867 DBusMessage *message)
03868 {
03869 DBusMessage *pop_message;
03870 DBusDispatchStatus status;
03871
03872 _dbus_return_if_fail (connection != NULL);
03873 _dbus_return_if_fail (message != NULL);
03874 _dbus_return_if_fail (message == connection->message_borrowed);
03875 _dbus_return_if_fail (connection->dispatch_acquired);
03876
03877 CONNECTION_LOCK (connection);
03878
03879 _dbus_assert (message == connection->message_borrowed);
03880
03881 pop_message = _dbus_list_pop_first (&connection->incoming_messages);
03882 _dbus_assert (message == pop_message);
03883
03884 connection->n_incoming -= 1;
03885
03886 _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
03887 message, connection->n_incoming);
03888
03889 connection->message_borrowed = NULL;
03890
03891 _dbus_connection_release_dispatch (connection);
03892
03893 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03894 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03895 }
03896
03897
03898
03899
03900 static DBusList*
03901 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
03902 {
03903 HAVE_LOCK_CHECK (connection);
03904
03905 _dbus_assert (connection->message_borrowed == NULL);
03906
03907 if (connection->n_incoming > 0)
03908 {
03909 DBusList *link;
03910
03911 link = _dbus_list_pop_first_link (&connection->incoming_messages);
03912 connection->n_incoming -= 1;
03913
03914 _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from incoming queue %p, %d incoming\n",
03915 link->data,
03916 dbus_message_type_to_string (dbus_message_get_type (link->data)),
03917 dbus_message_get_path (link->data) ?
03918 dbus_message_get_path (link->data) :
03919 "no path",
03920 dbus_message_get_interface (link->data) ?
03921 dbus_message_get_interface (link->data) :
03922 "no interface",
03923 dbus_message_get_member (link->data) ?
03924 dbus_message_get_member (link->data) :
03925 "no member",
03926 dbus_message_get_signature (link->data),
03927 connection, connection->n_incoming);
03928
03929 check_disconnected_message_arrived_unlocked (connection, link->data);
03930
03931 return link;
03932 }
03933 else
03934 return NULL;
03935 }
03936
03937
03938
03939
03940 static DBusMessage*
03941 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
03942 {
03943 DBusList *link;
03944
03945 HAVE_LOCK_CHECK (connection);
03946
03947 link = _dbus_connection_pop_message_link_unlocked (connection);
03948
03949 if (link != NULL)
03950 {
03951 DBusMessage *message;
03952
03953 message = link->data;
03954
03955 _dbus_list_free_link (link);
03956
03957 return message;
03958 }
03959 else
03960 return NULL;
03961 }
03962
03963 static void
03964 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
03965 DBusList *message_link)
03966 {
03967 HAVE_LOCK_CHECK (connection);
03968
03969 _dbus_assert (message_link != NULL);
03970
03971 _dbus_assert (connection->message_borrowed == NULL);
03972
03973 _dbus_assert (connection->dispatch_acquired);
03974
03975 _dbus_list_prepend_link (&connection->incoming_messages,
03976 message_link);
03977 connection->n_incoming += 1;
03978
03979 _dbus_verbose ("Message %p (%s %s %s '%s') put back into queue %p, %d incoming\n",
03980 message_link->data,
03981 dbus_message_type_to_string (dbus_message_get_type (message_link->data)),
03982 dbus_message_get_interface (message_link->data) ?
03983 dbus_message_get_interface (message_link->data) :
03984 "no interface",
03985 dbus_message_get_member (message_link->data) ?
03986 dbus_message_get_member (message_link->data) :
03987 "no member",
03988 dbus_message_get_signature (message_link->data),
03989 connection, connection->n_incoming);
03990 }
03991
04011 DBusMessage*
04012 dbus_connection_pop_message (DBusConnection *connection)
04013 {
04014 DBusMessage *message;
04015 DBusDispatchStatus status;
04016
04017 _dbus_verbose ("start\n");
04018
04019
04020
04021
04022 status = dbus_connection_get_dispatch_status (connection);
04023 if (status != DBUS_DISPATCH_DATA_REMAINS)
04024 return NULL;
04025
04026 CONNECTION_LOCK (connection);
04027 _dbus_connection_acquire_dispatch (connection);
04028 HAVE_LOCK_CHECK (connection);
04029
04030 message = _dbus_connection_pop_message_unlocked (connection);
04031
04032 _dbus_verbose ("Returning popped message %p\n", message);
04033
04034 _dbus_connection_release_dispatch (connection);
04035
04036 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04037 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04038
04039 return message;
04040 }
04041
04049 static void
04050 _dbus_connection_acquire_dispatch (DBusConnection *connection)
04051 {
04052 HAVE_LOCK_CHECK (connection);
04053
04054 _dbus_connection_ref_unlocked (connection);
04055 CONNECTION_UNLOCK (connection);
04056
04057 _dbus_verbose ("locking dispatch_mutex\n");
04058 _dbus_mutex_lock (connection->dispatch_mutex);
04059
04060 while (connection->dispatch_acquired)
04061 {
04062 _dbus_verbose ("waiting for dispatch to be acquirable\n");
04063 _dbus_condvar_wait (connection->dispatch_cond,
04064 connection->dispatch_mutex);
04065 }
04066
04067 _dbus_assert (!connection->dispatch_acquired);
04068
04069 connection->dispatch_acquired = TRUE;
04070
04071 _dbus_verbose ("unlocking dispatch_mutex\n");
04072 _dbus_mutex_unlock (connection->dispatch_mutex);
04073
04074 CONNECTION_LOCK (connection);
04075 _dbus_connection_unref_unlocked (connection);
04076 }
04077
04085 static void
04086 _dbus_connection_release_dispatch (DBusConnection *connection)
04087 {
04088 HAVE_LOCK_CHECK (connection);
04089
04090 _dbus_verbose ("locking dispatch_mutex\n");
04091 _dbus_mutex_lock (connection->dispatch_mutex);
04092
04093 _dbus_assert (connection->dispatch_acquired);
04094
04095 connection->dispatch_acquired = FALSE;
04096 _dbus_condvar_wake_one (connection->dispatch_cond);
04097
04098 _dbus_verbose ("unlocking dispatch_mutex\n");
04099 _dbus_mutex_unlock (connection->dispatch_mutex);
04100 }
04101
04102 static void
04103 _dbus_connection_failed_pop (DBusConnection *connection,
04104 DBusList *message_link)
04105 {
04106 _dbus_list_prepend_link (&connection->incoming_messages,
04107 message_link);
04108 connection->n_incoming += 1;
04109 }
04110
04111
04112 static void
04113 notify_disconnected_unlocked (DBusConnection *connection)
04114 {
04115 HAVE_LOCK_CHECK (connection);
04116
04117
04118
04119
04120
04121
04122
04123 _dbus_bus_notify_shared_connection_disconnected_unlocked (connection);
04124
04125
04126
04127
04128
04129 if (connection->n_outgoing > 0)
04130 {
04131 DBusList *link;
04132
04133 _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
04134 connection->n_outgoing);
04135
04136 while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
04137 {
04138 _dbus_connection_message_sent_unlocked (connection, link->data);
04139 }
04140 }
04141 }
04142
04143
04144 static DBusDispatchStatus
04145 notify_disconnected_and_dispatch_complete_unlocked (DBusConnection *connection)
04146 {
04147 HAVE_LOCK_CHECK (connection);
04148
04149 if (connection->disconnect_message_link != NULL)
04150 {
04151 _dbus_verbose ("Sending disconnect message\n");
04152
04153
04154
04155
04156 connection_timeout_and_complete_all_pending_calls_unlocked (connection);
04157
04158
04159
04160
04161 _dbus_connection_queue_synthesized_message_link (connection,
04162 connection->disconnect_message_link);
04163 connection->disconnect_message_link = NULL;
04164
04165 return DBUS_DISPATCH_DATA_REMAINS;
04166 }
04167
04168 return DBUS_DISPATCH_COMPLETE;
04169 }
04170
04171 static DBusDispatchStatus
04172 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
04173 {
04174 HAVE_LOCK_CHECK (connection);
04175
04176 if (connection->n_incoming > 0)
04177 return DBUS_DISPATCH_DATA_REMAINS;
04178 else if (!_dbus_transport_queue_messages (connection->transport))
04179 return DBUS_DISPATCH_NEED_MEMORY;
04180 else
04181 {
04182 DBusDispatchStatus status;
04183 dbus_bool_t is_connected;
04184
04185 status = _dbus_transport_get_dispatch_status (connection->transport);
04186 is_connected = _dbus_transport_get_is_connected (connection->transport);
04187
04188 _dbus_verbose ("dispatch status = %s is_connected = %d\n",
04189 DISPATCH_STATUS_NAME (status), is_connected);
04190
04191 if (!is_connected)
04192 {
04193
04194
04195
04196
04197
04198
04199 notify_disconnected_unlocked (connection);
04200
04201
04202
04203
04204
04205
04206 if (status == DBUS_DISPATCH_COMPLETE)
04207 status = notify_disconnected_and_dispatch_complete_unlocked (connection);
04208 }
04209
04210 if (status != DBUS_DISPATCH_COMPLETE)
04211 return status;
04212 else if (connection->n_incoming > 0)
04213 return DBUS_DISPATCH_DATA_REMAINS;
04214 else
04215 return DBUS_DISPATCH_COMPLETE;
04216 }
04217 }
04218
04219 static void
04220 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
04221 DBusDispatchStatus new_status)
04222 {
04223 dbus_bool_t changed;
04224 DBusDispatchStatusFunction function;
04225 void *data;
04226
04227 HAVE_LOCK_CHECK (connection);
04228
04229 _dbus_connection_ref_unlocked (connection);
04230
04231 changed = new_status != connection->last_dispatch_status;
04232
04233 connection->last_dispatch_status = new_status;
04234
04235 function = connection->dispatch_status_function;
04236 data = connection->dispatch_status_data;
04237
04238 if (connection->disconnected_message_arrived &&
04239 !connection->disconnected_message_processed)
04240 {
04241 connection->disconnected_message_processed = TRUE;
04242
04243
04244
04245
04246
04247 connection_forget_shared_unlocked (connection);
04248
04249 if (connection->exit_on_disconnect)
04250 {
04251 CONNECTION_UNLOCK (connection);
04252
04253 _dbus_verbose ("Exiting on Disconnected signal\n");
04254 _dbus_exit (1);
04255 _dbus_assert_not_reached ("Call to exit() returned");
04256 }
04257 }
04258
04259
04260 CONNECTION_UNLOCK (connection);
04261
04262 if (changed && function)
04263 {
04264 _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
04265 connection, new_status,
04266 DISPATCH_STATUS_NAME (new_status));
04267 (* function) (connection, new_status, data);
04268 }
04269
04270 dbus_connection_unref (connection);
04271 }
04272
04298 DBusDispatchStatus
04299 dbus_connection_get_dispatch_status (DBusConnection *connection)
04300 {
04301 DBusDispatchStatus status;
04302
04303 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04304
04305 _dbus_verbose ("start\n");
04306
04307 CONNECTION_LOCK (connection);
04308
04309 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04310
04311 CONNECTION_UNLOCK (connection);
04312
04313 return status;
04314 }
04315
04319 static DBusHandlerResult
04320 _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
04321 DBusMessage *message)
04322 {
04323 dbus_bool_t sent = FALSE;
04324 DBusMessage *ret = NULL;
04325 DBusList *expire_link;
04326
04327 if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
04328 {
04329
04330 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04331 }
04332
04333 if (!dbus_message_has_interface (message, DBUS_INTERFACE_PEER))
04334 {
04335 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04336 }
04337
04338
04339
04340 expire_link = _dbus_list_alloc_link (NULL);
04341
04342 if (!expire_link)
04343 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04344
04345 if (dbus_message_is_method_call (message,
04346 DBUS_INTERFACE_PEER,
04347 "Ping"))
04348 {
04349 ret = dbus_message_new_method_return (message);
04350 if (ret == NULL)
04351 goto out;
04352
04353 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04354 }
04355 else if (dbus_message_is_method_call (message,
04356 DBUS_INTERFACE_PEER,
04357 "GetMachineId"))
04358 {
04359 DBusString uuid;
04360
04361 ret = dbus_message_new_method_return (message);
04362 if (ret == NULL)
04363 goto out;
04364
04365 _dbus_string_init (&uuid);
04366 if (_dbus_get_local_machine_uuid_encoded (&uuid))
04367 {
04368 const char *v_STRING = _dbus_string_get_const_data (&uuid);
04369 if (dbus_message_append_args (ret,
04370 DBUS_TYPE_STRING, &v_STRING,
04371 DBUS_TYPE_INVALID))
04372 {
04373 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04374 }
04375 }
04376 _dbus_string_free (&uuid);
04377 }
04378 else
04379 {
04380
04381
04382
04383
04384 ret = dbus_message_new_error (message,
04385 DBUS_ERROR_UNKNOWN_METHOD,
04386 "Unknown method invoked on org.freedesktop.DBus.Peer interface");
04387 if (ret == NULL)
04388 goto out;
04389
04390 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04391 }
04392
04393 out:
04394 if (ret == NULL)
04395 {
04396 _dbus_list_free_link (expire_link);
04397 }
04398 else
04399 {
04400
04401 expire_link->data = ret;
04402 _dbus_list_prepend_link (&connection->expired_messages, expire_link);
04403 }
04404
04405 if (!sent)
04406 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04407
04408 return DBUS_HANDLER_RESULT_HANDLED;
04409 }
04410
04417 static DBusHandlerResult
04418 _dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection,
04419 DBusMessage *message)
04420 {
04421
04422
04423
04424 return _dbus_connection_peer_filter_unlocked_no_update (connection, message);
04425 }
04426
04469 DBusDispatchStatus
04470 dbus_connection_dispatch (DBusConnection *connection)
04471 {
04472 DBusMessage *message;
04473 DBusList *link, *filter_list_copy, *message_link;
04474 DBusHandlerResult result;
04475 DBusPendingCall *pending;
04476 dbus_int32_t reply_serial;
04477 DBusDispatchStatus status;
04478
04479 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04480
04481 _dbus_verbose ("\n");
04482
04483 CONNECTION_LOCK (connection);
04484 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04485 if (status != DBUS_DISPATCH_DATA_REMAINS)
04486 {
04487
04488 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04489 return status;
04490 }
04491
04492
04493
04494
04495 _dbus_connection_ref_unlocked (connection);
04496
04497 _dbus_connection_acquire_dispatch (connection);
04498 HAVE_LOCK_CHECK (connection);
04499
04500 message_link = _dbus_connection_pop_message_link_unlocked (connection);
04501 if (message_link == NULL)
04502 {
04503
04504
04505 _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
04506
04507 _dbus_connection_release_dispatch (connection);
04508
04509 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04510
04511 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04512
04513 dbus_connection_unref (connection);
04514
04515 return status;
04516 }
04517
04518 message = message_link->data;
04519
04520 _dbus_verbose (" dispatching message %p (%s %s %s '%s')\n",
04521 message,
04522 dbus_message_type_to_string (dbus_message_get_type (message)),
04523 dbus_message_get_interface (message) ?
04524 dbus_message_get_interface (message) :
04525 "no interface",
04526 dbus_message_get_member (message) ?
04527 dbus_message_get_member (message) :
04528 "no member",
04529 dbus_message_get_signature (message));
04530
04531 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04532
04533
04534
04535
04536
04537
04538
04539
04540 reply_serial = dbus_message_get_reply_serial (message);
04541 pending = _dbus_hash_table_lookup_int (connection->pending_replies,
04542 reply_serial);
04543 if (pending)
04544 {
04545 _dbus_verbose ("Dispatching a pending reply\n");
04546 complete_pending_call_and_unlock (connection, pending, message);
04547 pending = NULL;
04548
04549 CONNECTION_LOCK (connection);
04550 _dbus_verbose ("pending call completed in dispatch\n");
04551 result = DBUS_HANDLER_RESULT_HANDLED;
04552 goto out;
04553 }
04554
04555 result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message);
04556 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04557 goto out;
04558
04559 if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
04560 {
04561 _dbus_connection_release_dispatch (connection);
04562 HAVE_LOCK_CHECK (connection);
04563
04564 _dbus_connection_failed_pop (connection, message_link);
04565
04566
04567 _dbus_connection_update_dispatch_status_and_unlock (connection,
04568 DBUS_DISPATCH_NEED_MEMORY);
04569 dbus_connection_unref (connection);
04570
04571 return DBUS_DISPATCH_NEED_MEMORY;
04572 }
04573
04574 _dbus_list_foreach (&filter_list_copy,
04575 (DBusForeachFunction)_dbus_message_filter_ref,
04576 NULL);
04577
04578
04579
04580
04581 CONNECTION_UNLOCK (connection);
04582
04583 link = _dbus_list_get_first_link (&filter_list_copy);
04584 while (link != NULL)
04585 {
04586 DBusMessageFilter *filter = link->data;
04587 DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
04588
04589 if (filter->function == NULL)
04590 {
04591 _dbus_verbose (" filter was removed in a callback function\n");
04592 link = next;
04593 continue;
04594 }
04595
04596 _dbus_verbose (" running filter on message %p\n", message);
04597 result = (* filter->function) (connection, message, filter->user_data);
04598
04599 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04600 break;
04601
04602 link = next;
04603 }
04604
04605 _dbus_list_foreach (&filter_list_copy,
04606 (DBusForeachFunction)_dbus_message_filter_unref,
04607 NULL);
04608 _dbus_list_clear (&filter_list_copy);
04609
04610 CONNECTION_LOCK (connection);
04611
04612 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04613 {
04614 _dbus_verbose ("No memory\n");
04615 goto out;
04616 }
04617 else if (result == DBUS_HANDLER_RESULT_HANDLED)
04618 {
04619 _dbus_verbose ("filter handled message in dispatch\n");
04620 goto out;
04621 }
04622
04623
04624
04625
04626 _dbus_verbose (" running object path dispatch on message %p (%s %s %s '%s')\n",
04627 message,
04628 dbus_message_type_to_string (dbus_message_get_type (message)),
04629 dbus_message_get_interface (message) ?
04630 dbus_message_get_interface (message) :
04631 "no interface",
04632 dbus_message_get_member (message) ?
04633 dbus_message_get_member (message) :
04634 "no member",
04635 dbus_message_get_signature (message));
04636
04637 HAVE_LOCK_CHECK (connection);
04638 result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
04639 message);
04640
04641 CONNECTION_LOCK (connection);
04642
04643 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04644 {
04645 _dbus_verbose ("object tree handled message in dispatch\n");
04646 goto out;
04647 }
04648
04649 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
04650 {
04651 DBusMessage *reply;
04652 DBusString str;
04653 DBusPreallocatedSend *preallocated;
04654 DBusList *expire_link;
04655
04656 _dbus_verbose (" sending error %s\n",
04657 DBUS_ERROR_UNKNOWN_METHOD);
04658
04659 if (!_dbus_string_init (&str))
04660 {
04661 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04662 _dbus_verbose ("no memory for error string in dispatch\n");
04663 goto out;
04664 }
04665
04666 if (!_dbus_string_append_printf (&str,
04667 "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
04668 dbus_message_get_member (message),
04669 dbus_message_get_signature (message),
04670 dbus_message_get_interface (message)))
04671 {
04672 _dbus_string_free (&str);
04673 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04674 _dbus_verbose ("no memory for error string in dispatch\n");
04675 goto out;
04676 }
04677
04678 reply = dbus_message_new_error (message,
04679 DBUS_ERROR_UNKNOWN_METHOD,
04680 _dbus_string_get_const_data (&str));
04681 _dbus_string_free (&str);
04682
04683 if (reply == NULL)
04684 {
04685 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04686 _dbus_verbose ("no memory for error reply in dispatch\n");
04687 goto out;
04688 }
04689
04690 expire_link = _dbus_list_alloc_link (reply);
04691
04692 if (expire_link == NULL)
04693 {
04694 dbus_message_unref (reply);
04695 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04696 _dbus_verbose ("no memory for error send in dispatch\n");
04697 goto out;
04698 }
04699
04700 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
04701
04702 if (preallocated == NULL)
04703 {
04704 _dbus_list_free_link (expire_link);
04705
04706
04707 dbus_message_unref (reply);
04708 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04709 _dbus_verbose ("no memory for error send in dispatch\n");
04710 goto out;
04711 }
04712
04713 _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
04714 reply, NULL);
04715
04716 _dbus_list_prepend_link (&connection->expired_messages, expire_link);
04717
04718 result = DBUS_HANDLER_RESULT_HANDLED;
04719 }
04720
04721 _dbus_verbose (" done dispatching %p (%s %s %s '%s') on connection %p\n", message,
04722 dbus_message_type_to_string (dbus_message_get_type (message)),
04723 dbus_message_get_interface (message) ?
04724 dbus_message_get_interface (message) :
04725 "no interface",
04726 dbus_message_get_member (message) ?
04727 dbus_message_get_member (message) :
04728 "no member",
04729 dbus_message_get_signature (message),
04730 connection);
04731
04732 out:
04733 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04734 {
04735 _dbus_verbose ("out of memory\n");
04736
04737
04738
04739
04740
04741 _dbus_connection_putback_message_link_unlocked (connection,
04742 message_link);
04743
04744 message_link = NULL;
04745 message = NULL;
04746 }
04747 else
04748 {
04749 _dbus_verbose (" ... done dispatching\n");
04750 }
04751
04752 _dbus_connection_release_dispatch (connection);
04753 HAVE_LOCK_CHECK (connection);
04754
04755 if (message != NULL)
04756 {
04757
04758
04759
04760
04761
04762
04763
04764 CONNECTION_UNLOCK (connection);
04765 dbus_message_unref (message);
04766 CONNECTION_LOCK (connection);
04767 }
04768
04769 if (message_link != NULL)
04770 _dbus_list_free_link (message_link);
04771
04772 _dbus_verbose ("before final status update\n");
04773 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04774
04775
04776 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04777
04778 dbus_connection_unref (connection);
04779
04780 return status;
04781 }
04782
04844 dbus_bool_t
04845 dbus_connection_set_watch_functions (DBusConnection *connection,
04846 DBusAddWatchFunction add_function,
04847 DBusRemoveWatchFunction remove_function,
04848 DBusWatchToggledFunction toggled_function,
04849 void *data,
04850 DBusFreeFunction free_data_function)
04851 {
04852 dbus_bool_t retval;
04853
04854 _dbus_return_val_if_fail (connection != NULL, FALSE);
04855
04856 CONNECTION_LOCK (connection);
04857
04858 retval = _dbus_watch_list_set_functions (connection->watches,
04859 add_function, remove_function,
04860 toggled_function,
04861 data, free_data_function);
04862
04863 CONNECTION_UNLOCK (connection);
04864
04865 return retval;
04866 }
04867
04907 dbus_bool_t
04908 dbus_connection_set_timeout_functions (DBusConnection *connection,
04909 DBusAddTimeoutFunction add_function,
04910 DBusRemoveTimeoutFunction remove_function,
04911 DBusTimeoutToggledFunction toggled_function,
04912 void *data,
04913 DBusFreeFunction free_data_function)
04914 {
04915 dbus_bool_t retval;
04916
04917 _dbus_return_val_if_fail (connection != NULL, FALSE);
04918
04919 CONNECTION_LOCK (connection);
04920
04921 retval = _dbus_timeout_list_set_functions (connection->timeouts,
04922 add_function, remove_function,
04923 toggled_function,
04924 data, free_data_function);
04925
04926 CONNECTION_UNLOCK (connection);
04927
04928 return retval;
04929 }
04930
04945 void
04946 dbus_connection_set_wakeup_main_function (DBusConnection *connection,
04947 DBusWakeupMainFunction wakeup_main_function,
04948 void *data,
04949 DBusFreeFunction free_data_function)
04950 {
04951 void *old_data;
04952 DBusFreeFunction old_free_data;
04953
04954 _dbus_return_if_fail (connection != NULL);
04955
04956 CONNECTION_LOCK (connection);
04957 old_data = connection->wakeup_main_data;
04958 old_free_data = connection->free_wakeup_main_data;
04959
04960 connection->wakeup_main_function = wakeup_main_function;
04961 connection->wakeup_main_data = data;
04962 connection->free_wakeup_main_data = free_data_function;
04963
04964 CONNECTION_UNLOCK (connection);
04965
04966
04967 if (old_free_data)
04968 (*old_free_data) (old_data);
04969 }
04970
04991 void
04992 dbus_connection_set_dispatch_status_function (DBusConnection *connection,
04993 DBusDispatchStatusFunction function,
04994 void *data,
04995 DBusFreeFunction free_data_function)
04996 {
04997 void *old_data;
04998 DBusFreeFunction old_free_data;
04999
05000 _dbus_return_if_fail (connection != NULL);
05001
05002 CONNECTION_LOCK (connection);
05003 old_data = connection->dispatch_status_data;
05004 old_free_data = connection->free_dispatch_status_data;
05005
05006 connection->dispatch_status_function = function;
05007 connection->dispatch_status_data = data;
05008 connection->free_dispatch_status_data = free_data_function;
05009
05010 CONNECTION_UNLOCK (connection);
05011
05012
05013 if (old_free_data)
05014 (*old_free_data) (old_data);
05015 }
05016
05036 dbus_bool_t
05037 dbus_connection_get_unix_fd (DBusConnection *connection,
05038 int *fd)
05039 {
05040 _dbus_return_val_if_fail (connection != NULL, FALSE);
05041 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
05042
05043 #ifdef DBUS_WIN
05044
05045 return FALSE;
05046 #endif
05047
05048 return dbus_connection_get_socket(connection, fd);
05049 }
05050
05066 dbus_bool_t
05067 dbus_connection_get_socket(DBusConnection *connection,
05068 int *fd)
05069 {
05070 dbus_bool_t retval;
05071
05072 _dbus_return_val_if_fail (connection != NULL, FALSE);
05073 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
05074
05075 CONNECTION_LOCK (connection);
05076
05077 retval = _dbus_transport_get_socket_fd (connection->transport,
05078 fd);
05079
05080 CONNECTION_UNLOCK (connection);
05081
05082 return retval;
05083 }
05084
05085
05108 dbus_bool_t
05109 dbus_connection_get_unix_user (DBusConnection *connection,
05110 unsigned long *uid)
05111 {
05112 dbus_bool_t result;
05113
05114 _dbus_return_val_if_fail (connection != NULL, FALSE);
05115 _dbus_return_val_if_fail (uid != NULL, FALSE);
05116
05117 CONNECTION_LOCK (connection);
05118
05119 if (!_dbus_transport_get_is_authenticated (connection->transport))
05120 result = FALSE;
05121 else
05122 result = _dbus_transport_get_unix_user (connection->transport,
05123 uid);
05124
05125 #ifdef DBUS_WIN
05126 _dbus_assert (!result);
05127 #endif
05128
05129 CONNECTION_UNLOCK (connection);
05130
05131 return result;
05132 }
05133
05144 dbus_bool_t
05145 dbus_connection_get_unix_process_id (DBusConnection *connection,
05146 unsigned long *pid)
05147 {
05148 dbus_bool_t result;
05149
05150 _dbus_return_val_if_fail (connection != NULL, FALSE);
05151 _dbus_return_val_if_fail (pid != NULL, FALSE);
05152
05153 CONNECTION_LOCK (connection);
05154
05155 if (!_dbus_transport_get_is_authenticated (connection->transport))
05156 result = FALSE;
05157 else
05158 result = _dbus_transport_get_unix_process_id (connection->transport,
05159 pid);
05160
05161 CONNECTION_UNLOCK (connection);
05162
05163 return result;
05164 }
05165
05176 dbus_bool_t
05177 dbus_connection_get_adt_audit_session_data (DBusConnection *connection,
05178 void **data,
05179 dbus_int32_t *data_size)
05180 {
05181 dbus_bool_t result;
05182
05183 _dbus_return_val_if_fail (connection != NULL, FALSE);
05184 _dbus_return_val_if_fail (data != NULL, FALSE);
05185 _dbus_return_val_if_fail (data_size != NULL, FALSE);
05186
05187 CONNECTION_LOCK (connection);
05188
05189 if (!_dbus_transport_get_is_authenticated (connection->transport))
05190 result = FALSE;
05191 else
05192 result = _dbus_transport_get_adt_audit_session_data (connection->transport,
05193 data,
05194 data_size);
05195 CONNECTION_UNLOCK (connection);
05196
05197 return result;
05198 }
05199
05222 void
05223 dbus_connection_set_unix_user_function (DBusConnection *connection,
05224 DBusAllowUnixUserFunction function,
05225 void *data,
05226 DBusFreeFunction free_data_function)
05227 {
05228 void *old_data = NULL;
05229 DBusFreeFunction old_free_function = NULL;
05230
05231 _dbus_return_if_fail (connection != NULL);
05232
05233 CONNECTION_LOCK (connection);
05234 _dbus_transport_set_unix_user_function (connection->transport,
05235 function, data, free_data_function,
05236 &old_data, &old_free_function);
05237 CONNECTION_UNLOCK (connection);
05238
05239 if (old_free_function != NULL)
05240 (* old_free_function) (old_data);
05241 }
05242
05274 dbus_bool_t
05275 dbus_connection_get_windows_user (DBusConnection *connection,
05276 char **windows_sid_p)
05277 {
05278 dbus_bool_t result;
05279
05280 _dbus_return_val_if_fail (connection != NULL, FALSE);
05281 _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
05282
05283 CONNECTION_LOCK (connection);
05284
05285 if (!_dbus_transport_get_is_authenticated (connection->transport))
05286 result = FALSE;
05287 else
05288 result = _dbus_transport_get_windows_user (connection->transport,
05289 windows_sid_p);
05290
05291 #ifdef DBUS_UNIX
05292 _dbus_assert (!result);
05293 #endif
05294
05295 CONNECTION_UNLOCK (connection);
05296
05297 return result;
05298 }
05299
05321 void
05322 dbus_connection_set_windows_user_function (DBusConnection *connection,
05323 DBusAllowWindowsUserFunction function,
05324 void *data,
05325 DBusFreeFunction free_data_function)
05326 {
05327 void *old_data = NULL;
05328 DBusFreeFunction old_free_function = NULL;
05329
05330 _dbus_return_if_fail (connection != NULL);
05331
05332 CONNECTION_LOCK (connection);
05333 _dbus_transport_set_windows_user_function (connection->transport,
05334 function, data, free_data_function,
05335 &old_data, &old_free_function);
05336 CONNECTION_UNLOCK (connection);
05337
05338 if (old_free_function != NULL)
05339 (* old_free_function) (old_data);
05340 }
05341
05368 void
05369 dbus_connection_set_allow_anonymous (DBusConnection *connection,
05370 dbus_bool_t value)
05371 {
05372 _dbus_return_if_fail (connection != NULL);
05373
05374 CONNECTION_LOCK (connection);
05375 _dbus_transport_set_allow_anonymous (connection->transport, value);
05376 CONNECTION_UNLOCK (connection);
05377 }
05378
05396 void
05397 dbus_connection_set_route_peer_messages (DBusConnection *connection,
05398 dbus_bool_t value)
05399 {
05400 _dbus_return_if_fail (connection != NULL);
05401
05402 CONNECTION_LOCK (connection);
05403 connection->route_peer_messages = TRUE;
05404 CONNECTION_UNLOCK (connection);
05405 }
05406
05428 dbus_bool_t
05429 dbus_connection_add_filter (DBusConnection *connection,
05430 DBusHandleMessageFunction function,
05431 void *user_data,
05432 DBusFreeFunction free_data_function)
05433 {
05434 DBusMessageFilter *filter;
05435
05436 _dbus_return_val_if_fail (connection != NULL, FALSE);
05437 _dbus_return_val_if_fail (function != NULL, FALSE);
05438
05439 filter = dbus_new0 (DBusMessageFilter, 1);
05440 if (filter == NULL)
05441 return FALSE;
05442
05443 _dbus_atomic_inc (&filter->refcount);
05444
05445 CONNECTION_LOCK (connection);
05446
05447 if (!_dbus_list_append (&connection->filter_list,
05448 filter))
05449 {
05450 _dbus_message_filter_unref (filter);
05451 CONNECTION_UNLOCK (connection);
05452 return FALSE;
05453 }
05454
05455
05456
05457
05458
05459
05460 filter->function = function;
05461 filter->user_data = user_data;
05462 filter->free_user_data_function = free_data_function;
05463
05464 CONNECTION_UNLOCK (connection);
05465 return TRUE;
05466 }
05467
05480 void
05481 dbus_connection_remove_filter (DBusConnection *connection,
05482 DBusHandleMessageFunction function,
05483 void *user_data)
05484 {
05485 DBusList *link;
05486 DBusMessageFilter *filter;
05487
05488 _dbus_return_if_fail (connection != NULL);
05489 _dbus_return_if_fail (function != NULL);
05490
05491 CONNECTION_LOCK (connection);
05492
05493 filter = NULL;
05494
05495 link = _dbus_list_get_last_link (&connection->filter_list);
05496 while (link != NULL)
05497 {
05498 filter = link->data;
05499
05500 if (filter->function == function &&
05501 filter->user_data == user_data)
05502 {
05503 _dbus_list_remove_link (&connection->filter_list, link);
05504 filter->function = NULL;
05505
05506 break;
05507 }
05508
05509 link = _dbus_list_get_prev_link (&connection->filter_list, link);
05510 filter = NULL;
05511 }
05512
05513 CONNECTION_UNLOCK (connection);
05514
05515 #ifndef DBUS_DISABLE_CHECKS
05516 if (filter == NULL)
05517 {
05518 _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
05519 function, user_data);
05520 return;
05521 }
05522 #endif
05523
05524
05525 if (filter->free_user_data_function)
05526 (* filter->free_user_data_function) (filter->user_data);
05527
05528 filter->free_user_data_function = NULL;
05529 filter->user_data = NULL;
05530
05531 _dbus_message_filter_unref (filter);
05532 }
05533
05546 dbus_bool_t
05547 dbus_connection_try_register_object_path (DBusConnection *connection,
05548 const char *path,
05549 const DBusObjectPathVTable *vtable,
05550 void *user_data,
05551 DBusError *error)
05552 {
05553 char **decomposed_path;
05554 dbus_bool_t retval;
05555
05556 _dbus_return_val_if_fail (connection != NULL, FALSE);
05557 _dbus_return_val_if_fail (path != NULL, FALSE);
05558 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05559 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05560
05561 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05562 return FALSE;
05563
05564 CONNECTION_LOCK (connection);
05565
05566 retval = _dbus_object_tree_register (connection->objects,
05567 FALSE,
05568 (const char **) decomposed_path, vtable,
05569 user_data, error);
05570
05571 CONNECTION_UNLOCK (connection);
05572
05573 dbus_free_string_array (decomposed_path);
05574
05575 return retval;
05576 }
05577
05592 dbus_bool_t
05593 dbus_connection_register_object_path (DBusConnection *connection,
05594 const char *path,
05595 const DBusObjectPathVTable *vtable,
05596 void *user_data)
05597 {
05598 char **decomposed_path;
05599 dbus_bool_t retval;
05600 DBusError error = DBUS_ERROR_INIT;
05601
05602 _dbus_return_val_if_fail (connection != NULL, FALSE);
05603 _dbus_return_val_if_fail (path != NULL, FALSE);
05604 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05605 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05606
05607 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05608 return FALSE;
05609
05610 CONNECTION_LOCK (connection);
05611
05612 retval = _dbus_object_tree_register (connection->objects,
05613 FALSE,
05614 (const char **) decomposed_path, vtable,
05615 user_data, &error);
05616
05617 CONNECTION_UNLOCK (connection);
05618
05619 dbus_free_string_array (decomposed_path);
05620
05621 if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE))
05622 {
05623 _dbus_warn ("%s\n", error.message);
05624 dbus_error_free (&error);
05625 return FALSE;
05626 }
05627
05628 return retval;
05629 }
05630
05645 dbus_bool_t
05646 dbus_connection_try_register_fallback (DBusConnection *connection,
05647 const char *path,
05648 const DBusObjectPathVTable *vtable,
05649 void *user_data,
05650 DBusError *error)
05651 {
05652 char **decomposed_path;
05653 dbus_bool_t retval;
05654
05655 _dbus_return_val_if_fail (connection != NULL, FALSE);
05656 _dbus_return_val_if_fail (path != NULL, FALSE);
05657 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05658 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05659
05660 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05661 return FALSE;
05662
05663 CONNECTION_LOCK (connection);
05664
05665 retval = _dbus_object_tree_register (connection->objects,
05666 TRUE,
05667 (const char **) decomposed_path, vtable,
05668 user_data, error);
05669
05670 CONNECTION_UNLOCK (connection);
05671
05672 dbus_free_string_array (decomposed_path);
05673
05674 return retval;
05675 }
05676
05693 dbus_bool_t
05694 dbus_connection_register_fallback (DBusConnection *connection,
05695 const char *path,
05696 const DBusObjectPathVTable *vtable,
05697 void *user_data)
05698 {
05699 char **decomposed_path;
05700 dbus_bool_t retval;
05701 DBusError error = DBUS_ERROR_INIT;
05702
05703 _dbus_return_val_if_fail (connection != NULL, FALSE);
05704 _dbus_return_val_if_fail (path != NULL, FALSE);
05705 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05706 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05707
05708 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05709 return FALSE;
05710
05711 CONNECTION_LOCK (connection);
05712
05713 retval = _dbus_object_tree_register (connection->objects,
05714 TRUE,
05715 (const char **) decomposed_path, vtable,
05716 user_data, &error);
05717
05718 CONNECTION_UNLOCK (connection);
05719
05720 dbus_free_string_array (decomposed_path);
05721
05722 if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE))
05723 {
05724 _dbus_warn ("%s\n", error.message);
05725 dbus_error_free (&error);
05726 return FALSE;
05727 }
05728
05729 return retval;
05730 }
05731
05741 dbus_bool_t
05742 dbus_connection_unregister_object_path (DBusConnection *connection,
05743 const char *path)
05744 {
05745 char **decomposed_path;
05746
05747 _dbus_return_val_if_fail (connection != NULL, FALSE);
05748 _dbus_return_val_if_fail (path != NULL, FALSE);
05749 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05750
05751 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05752 return FALSE;
05753
05754 CONNECTION_LOCK (connection);
05755
05756 _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
05757
05758 dbus_free_string_array (decomposed_path);
05759
05760 return TRUE;
05761 }
05762
05773 dbus_bool_t
05774 dbus_connection_get_object_path_data (DBusConnection *connection,
05775 const char *path,
05776 void **data_p)
05777 {
05778 char **decomposed_path;
05779
05780 _dbus_return_val_if_fail (connection != NULL, FALSE);
05781 _dbus_return_val_if_fail (path != NULL, FALSE);
05782 _dbus_return_val_if_fail (data_p != NULL, FALSE);
05783
05784 *data_p = NULL;
05785
05786 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05787 return FALSE;
05788
05789 CONNECTION_LOCK (connection);
05790
05791 *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path);
05792
05793 CONNECTION_UNLOCK (connection);
05794
05795 dbus_free_string_array (decomposed_path);
05796
05797 return TRUE;
05798 }
05799
05810 dbus_bool_t
05811 dbus_connection_list_registered (DBusConnection *connection,
05812 const char *parent_path,
05813 char ***child_entries)
05814 {
05815 char **decomposed_path;
05816 dbus_bool_t retval;
05817 _dbus_return_val_if_fail (connection != NULL, FALSE);
05818 _dbus_return_val_if_fail (parent_path != NULL, FALSE);
05819 _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
05820 _dbus_return_val_if_fail (child_entries != NULL, FALSE);
05821
05822 if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
05823 return FALSE;
05824
05825 CONNECTION_LOCK (connection);
05826
05827 retval = _dbus_object_tree_list_registered_and_unlock (connection->objects,
05828 (const char **) decomposed_path,
05829 child_entries);
05830 dbus_free_string_array (decomposed_path);
05831
05832 return retval;
05833 }
05834
05835 static DBusDataSlotAllocator slot_allocator;
05836 _DBUS_DEFINE_GLOBAL_LOCK (connection_slots);
05837
05852 dbus_bool_t
05853 dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
05854 {
05855 return _dbus_data_slot_allocator_alloc (&slot_allocator,
05856 &_DBUS_LOCK_NAME (connection_slots),
05857 slot_p);
05858 }
05859
05871 void
05872 dbus_connection_free_data_slot (dbus_int32_t *slot_p)
05873 {
05874 _dbus_return_if_fail (*slot_p >= 0);
05875
05876 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
05877 }
05878
05901 dbus_bool_t
05902 dbus_connection_set_data (DBusConnection *connection,
05903 dbus_int32_t slot,
05904 void *data,
05905 DBusFreeFunction free_data_func)
05906 {
05907 DBusFreeFunction old_free_func;
05908 void *old_data;
05909 dbus_bool_t retval;
05910
05911 _dbus_return_val_if_fail (connection != NULL, FALSE);
05912 _dbus_return_val_if_fail (slot >= 0, FALSE);
05913
05914 SLOTS_LOCK (connection);
05915
05916 retval = _dbus_data_slot_list_set (&slot_allocator,
05917 &connection->slot_list,
05918 slot, data, free_data_func,
05919 &old_free_func, &old_data);
05920
05921 SLOTS_UNLOCK (connection);
05922
05923 if (retval)
05924 {
05925
05926 if (old_free_func)
05927 (* old_free_func) (old_data);
05928 }
05929
05930 return retval;
05931 }
05932
05950 void*
05951 dbus_connection_get_data (DBusConnection *connection,
05952 dbus_int32_t slot)
05953 {
05954 void *res;
05955
05956 _dbus_return_val_if_fail (connection != NULL, NULL);
05957
05958 SLOTS_LOCK (connection);
05959
05960 res = _dbus_data_slot_list_get (&slot_allocator,
05961 &connection->slot_list,
05962 slot);
05963
05964 SLOTS_UNLOCK (connection);
05965
05966 return res;
05967 }
05968
05975 void
05976 dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
05977 {
05978 _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
05979 }
05980
05989 void
05990 dbus_connection_set_max_message_size (DBusConnection *connection,
05991 long size)
05992 {
05993 _dbus_return_if_fail (connection != NULL);
05994
05995 CONNECTION_LOCK (connection);
05996 _dbus_transport_set_max_message_size (connection->transport,
05997 size);
05998 CONNECTION_UNLOCK (connection);
05999 }
06000
06007 long
06008 dbus_connection_get_max_message_size (DBusConnection *connection)
06009 {
06010 long res;
06011
06012 _dbus_return_val_if_fail (connection != NULL, 0);
06013
06014 CONNECTION_LOCK (connection);
06015 res = _dbus_transport_get_max_message_size (connection->transport);
06016 CONNECTION_UNLOCK (connection);
06017 return res;
06018 }
06019
06028 void
06029 dbus_connection_set_max_message_unix_fds (DBusConnection *connection,
06030 long n)
06031 {
06032 _dbus_return_if_fail (connection != NULL);
06033
06034 CONNECTION_LOCK (connection);
06035 _dbus_transport_set_max_message_unix_fds (connection->transport,
06036 n);
06037 CONNECTION_UNLOCK (connection);
06038 }
06039
06046 long
06047 dbus_connection_get_max_message_unix_fds (DBusConnection *connection)
06048 {
06049 long res;
06050
06051 _dbus_return_val_if_fail (connection != NULL, 0);
06052
06053 CONNECTION_LOCK (connection);
06054 res = _dbus_transport_get_max_message_unix_fds (connection->transport);
06055 CONNECTION_UNLOCK (connection);
06056 return res;
06057 }
06058
06084 void
06085 dbus_connection_set_max_received_size (DBusConnection *connection,
06086 long size)
06087 {
06088 _dbus_return_if_fail (connection != NULL);
06089
06090 CONNECTION_LOCK (connection);
06091 _dbus_transport_set_max_received_size (connection->transport,
06092 size);
06093 CONNECTION_UNLOCK (connection);
06094 }
06095
06102 long
06103 dbus_connection_get_max_received_size (DBusConnection *connection)
06104 {
06105 long res;
06106
06107 _dbus_return_val_if_fail (connection != NULL, 0);
06108
06109 CONNECTION_LOCK (connection);
06110 res = _dbus_transport_get_max_received_size (connection->transport);
06111 CONNECTION_UNLOCK (connection);
06112 return res;
06113 }
06114
06126 void
06127 dbus_connection_set_max_received_unix_fds (DBusConnection *connection,
06128 long n)
06129 {
06130 _dbus_return_if_fail (connection != NULL);
06131
06132 CONNECTION_LOCK (connection);
06133 _dbus_transport_set_max_received_unix_fds (connection->transport,
06134 n);
06135 CONNECTION_UNLOCK (connection);
06136 }
06137
06144 long
06145 dbus_connection_get_max_received_unix_fds (DBusConnection *connection)
06146 {
06147 long res;
06148
06149 _dbus_return_val_if_fail (connection != NULL, 0);
06150
06151 CONNECTION_LOCK (connection);
06152 res = _dbus_transport_get_max_received_unix_fds (connection->transport);
06153 CONNECTION_UNLOCK (connection);
06154 return res;
06155 }
06156
06167 long
06168 dbus_connection_get_outgoing_size (DBusConnection *connection)
06169 {
06170 long res;
06171
06172 _dbus_return_val_if_fail (connection != NULL, 0);
06173
06174 CONNECTION_LOCK (connection);
06175 res = _dbus_counter_get_size_value (connection->outgoing_counter);
06176 CONNECTION_UNLOCK (connection);
06177 return res;
06178 }
06179
06187 long
06188 dbus_connection_get_outgoing_unix_fds (DBusConnection *connection)
06189 {
06190 long res;
06191
06192 _dbus_return_val_if_fail (connection != NULL, 0);
06193
06194 CONNECTION_LOCK (connection);
06195 res = _dbus_counter_get_unix_fd_value (connection->outgoing_counter);
06196 CONNECTION_UNLOCK (connection);
06197 return res;
06198 }
06199