00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config.h>
00025 #include "dbus-shared.h"
00026 #include "dbus-connection.h"
00027 #include "dbus-list.h"
00028 #include "dbus-timeout.h"
00029 #include "dbus-transport.h"
00030 #include "dbus-watch.h"
00031 #include "dbus-connection-internal.h"
00032 #include "dbus-pending-call-internal.h"
00033 #include "dbus-list.h"
00034 #include "dbus-hash.h"
00035 #include "dbus-message-internal.h"
00036 #include "dbus-threads.h"
00037 #include "dbus-protocol.h"
00038 #include "dbus-dataslot.h"
00039 #include "dbus-string.h"
00040 #include "dbus-pending-call.h"
00041 #include "dbus-object-tree.h"
00042 #include "dbus-threads-internal.h"
00043 #include "dbus-bus.h"
00044
00045 #ifdef DBUS_DISABLE_CHECKS
00046 #define TOOK_LOCK_CHECK(connection)
00047 #define RELEASING_LOCK_CHECK(connection)
00048 #define HAVE_LOCK_CHECK(connection)
00049 #else
00050 #define TOOK_LOCK_CHECK(connection) do { \
00051 _dbus_assert (!(connection)->have_connection_lock); \
00052 (connection)->have_connection_lock = TRUE; \
00053 } while (0)
00054 #define RELEASING_LOCK_CHECK(connection) do { \
00055 _dbus_assert ((connection)->have_connection_lock); \
00056 (connection)->have_connection_lock = FALSE; \
00057 } while (0)
00058 #define HAVE_LOCK_CHECK(connection) _dbus_assert ((connection)->have_connection_lock)
00059
00060 #endif
00061
00062 #define TRACE_LOCKS 1
00063
00064 #define CONNECTION_LOCK(connection) do { \
00065 if (TRACE_LOCKS) { _dbus_verbose (" LOCK: %s\n", _DBUS_FUNCTION_NAME); } \
00066 _dbus_mutex_lock ((connection)->mutex); \
00067 TOOK_LOCK_CHECK (connection); \
00068 } while (0)
00069
00070 #define CONNECTION_UNLOCK(connection) do { \
00071 if (TRACE_LOCKS) { _dbus_verbose (" UNLOCK: %s\n", _DBUS_FUNCTION_NAME); } \
00072 RELEASING_LOCK_CHECK (connection); \
00073 _dbus_mutex_unlock ((connection)->mutex); \
00074 } while (0)
00075
00076 #define DISPATCH_STATUS_NAME(s) \
00077 ((s) == DBUS_DISPATCH_COMPLETE ? "complete" : \
00078 (s) == DBUS_DISPATCH_DATA_REMAINS ? "data remains" : \
00079 (s) == DBUS_DISPATCH_NEED_MEMORY ? "need memory" : \
00080 "???")
00081
00202 typedef struct DBusMessageFilter DBusMessageFilter;
00203
00207 struct DBusMessageFilter
00208 {
00209 DBusAtomic refcount;
00210 DBusHandleMessageFunction function;
00211 void *user_data;
00212 DBusFreeFunction free_user_data_function;
00213 };
00214
00215
00219 struct DBusPreallocatedSend
00220 {
00221 DBusConnection *connection;
00222 DBusList *queue_link;
00223 DBusList *counter_link;
00224 };
00225
00226 static dbus_bool_t _dbus_modify_sigpipe = TRUE;
00227
00231 struct DBusConnection
00232 {
00233 DBusAtomic refcount;
00235 DBusMutex *mutex;
00237 DBusMutex *dispatch_mutex;
00238 DBusCondVar *dispatch_cond;
00239 DBusMutex *io_path_mutex;
00240 DBusCondVar *io_path_cond;
00242 DBusList *outgoing_messages;
00243 DBusList *incoming_messages;
00245 DBusMessage *message_borrowed;
00249 int n_outgoing;
00250 int n_incoming;
00252 DBusCounter *outgoing_counter;
00254 DBusTransport *transport;
00255 DBusWatchList *watches;
00256 DBusTimeoutList *timeouts;
00258 DBusList *filter_list;
00260 DBusDataSlotList slot_list;
00262 DBusHashTable *pending_replies;
00264 dbus_uint32_t client_serial;
00265 DBusList *disconnect_message_link;
00267 DBusWakeupMainFunction wakeup_main_function;
00268 void *wakeup_main_data;
00269 DBusFreeFunction free_wakeup_main_data;
00271 DBusDispatchStatusFunction dispatch_status_function;
00272 void *dispatch_status_data;
00273 DBusFreeFunction free_dispatch_status_data;
00275 DBusDispatchStatus last_dispatch_status;
00277 DBusList *link_cache;
00280 DBusObjectTree *objects;
00282 char *server_guid;
00284
00285
00286
00287
00288 dbus_bool_t dispatch_acquired;
00289 dbus_bool_t io_path_acquired;
00291 unsigned int shareable : 1;
00293 unsigned int exit_on_disconnect : 1;
00295 unsigned int route_peer_messages : 1;
00297 unsigned int disconnected_message_arrived : 1;
00301 unsigned int disconnected_message_processed : 1;
00305 #ifndef DBUS_DISABLE_CHECKS
00306 unsigned int have_connection_lock : 1;
00307 #endif
00308
00309 #ifndef DBUS_DISABLE_CHECKS
00310 int generation;
00311 #endif
00312 };
00313
00314 static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection);
00315 static void _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
00316 DBusDispatchStatus new_status);
00317 static void _dbus_connection_last_unref (DBusConnection *connection);
00318 static void _dbus_connection_acquire_dispatch (DBusConnection *connection);
00319 static void _dbus_connection_release_dispatch (DBusConnection *connection);
00320 static DBusDispatchStatus _dbus_connection_flush_unlocked (DBusConnection *connection);
00321 static void _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection);
00322 static dbus_bool_t _dbus_connection_get_is_connected_unlocked (DBusConnection *connection);
00323 static dbus_bool_t _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection,
00324 dbus_uint32_t client_serial);
00325
00326 static DBusMessageFilter *
00327 _dbus_message_filter_ref (DBusMessageFilter *filter)
00328 {
00329 _dbus_assert (filter->refcount.value > 0);
00330 _dbus_atomic_inc (&filter->refcount);
00331
00332 return filter;
00333 }
00334
00335 static void
00336 _dbus_message_filter_unref (DBusMessageFilter *filter)
00337 {
00338 _dbus_assert (filter->refcount.value > 0);
00339
00340 if (_dbus_atomic_dec (&filter->refcount) == 1)
00341 {
00342 if (filter->free_user_data_function)
00343 (* filter->free_user_data_function) (filter->user_data);
00344
00345 dbus_free (filter);
00346 }
00347 }
00348
00354 void
00355 _dbus_connection_lock (DBusConnection *connection)
00356 {
00357 CONNECTION_LOCK (connection);
00358 }
00359
00365 void
00366 _dbus_connection_unlock (DBusConnection *connection)
00367 {
00368 CONNECTION_UNLOCK (connection);
00369 }
00370
00378 static void
00379 _dbus_connection_wakeup_mainloop (DBusConnection *connection)
00380 {
00381 if (connection->wakeup_main_function)
00382 (*connection->wakeup_main_function) (connection->wakeup_main_data);
00383 }
00384
00385 #ifdef DBUS_BUILD_TESTS
00386
00396 dbus_bool_t
00397 _dbus_connection_queue_received_message (DBusConnection *connection,
00398 DBusMessage *message)
00399 {
00400 DBusList *link;
00401
00402 link = _dbus_list_alloc_link (message);
00403 if (link == NULL)
00404 return FALSE;
00405
00406 dbus_message_ref (message);
00407 _dbus_connection_queue_received_message_link (connection, link);
00408
00409 return TRUE;
00410 }
00411
00424 void
00425 _dbus_connection_test_get_locks (DBusConnection *connection,
00426 DBusMutex **mutex_loc,
00427 DBusMutex **dispatch_mutex_loc,
00428 DBusMutex **io_path_mutex_loc,
00429 DBusCondVar **dispatch_cond_loc,
00430 DBusCondVar **io_path_cond_loc)
00431 {
00432 *mutex_loc = connection->mutex;
00433 *dispatch_mutex_loc = connection->dispatch_mutex;
00434 *io_path_mutex_loc = connection->io_path_mutex;
00435 *dispatch_cond_loc = connection->dispatch_cond;
00436 *io_path_cond_loc = connection->io_path_cond;
00437 }
00438 #endif
00439
00448 void
00449 _dbus_connection_queue_received_message_link (DBusConnection *connection,
00450 DBusList *link)
00451 {
00452 DBusPendingCall *pending;
00453 dbus_uint32_t reply_serial;
00454 DBusMessage *message;
00455
00456 _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport));
00457
00458 _dbus_list_append_link (&connection->incoming_messages,
00459 link);
00460 message = link->data;
00461
00462
00463 reply_serial = dbus_message_get_reply_serial (message);
00464 if (reply_serial != 0)
00465 {
00466 pending = _dbus_hash_table_lookup_int (connection->pending_replies,
00467 reply_serial);
00468 if (pending != NULL)
00469 {
00470 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00471 _dbus_connection_remove_timeout_unlocked (connection,
00472 _dbus_pending_call_get_timeout_unlocked (pending));
00473
00474 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00475 }
00476 }
00477
00478
00479
00480 connection->n_incoming += 1;
00481
00482 _dbus_connection_wakeup_mainloop (connection);
00483
00484 _dbus_verbose ("Message %p (%d %s %s %s '%s' reply to %u) added to incoming queue %p, %d incoming\n",
00485 message,
00486 dbus_message_get_type (message),
00487 dbus_message_get_path (message) ?
00488 dbus_message_get_path (message) :
00489 "no path",
00490 dbus_message_get_interface (message) ?
00491 dbus_message_get_interface (message) :
00492 "no interface",
00493 dbus_message_get_member (message) ?
00494 dbus_message_get_member (message) :
00495 "no member",
00496 dbus_message_get_signature (message),
00497 dbus_message_get_reply_serial (message),
00498 connection,
00499 connection->n_incoming);}
00500
00509 void
00510 _dbus_connection_queue_synthesized_message_link (DBusConnection *connection,
00511 DBusList *link)
00512 {
00513 HAVE_LOCK_CHECK (connection);
00514
00515 _dbus_list_append_link (&connection->incoming_messages, link);
00516
00517 connection->n_incoming += 1;
00518
00519 _dbus_connection_wakeup_mainloop (connection);
00520
00521 _dbus_verbose ("Synthesized message %p added to incoming queue %p, %d incoming\n",
00522 link->data, connection, connection->n_incoming);
00523 }
00524
00525
00533 dbus_bool_t
00534 _dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection)
00535 {
00536 HAVE_LOCK_CHECK (connection);
00537 return connection->outgoing_messages != NULL;
00538 }
00539
00549 dbus_bool_t
00550 dbus_connection_has_messages_to_send (DBusConnection *connection)
00551 {
00552 dbus_bool_t v;
00553
00554 _dbus_return_val_if_fail (connection != NULL, FALSE);
00555
00556 CONNECTION_LOCK (connection);
00557 v = _dbus_connection_has_messages_to_send_unlocked (connection);
00558 CONNECTION_UNLOCK (connection);
00559
00560 return v;
00561 }
00562
00570 DBusMessage*
00571 _dbus_connection_get_message_to_send (DBusConnection *connection)
00572 {
00573 HAVE_LOCK_CHECK (connection);
00574
00575 return _dbus_list_get_last (&connection->outgoing_messages);
00576 }
00577
00586 void
00587 _dbus_connection_message_sent (DBusConnection *connection,
00588 DBusMessage *message)
00589 {
00590 DBusList *link;
00591
00592 HAVE_LOCK_CHECK (connection);
00593
00594
00595
00596
00597
00598
00599 link = _dbus_list_get_last_link (&connection->outgoing_messages);
00600 _dbus_assert (link != NULL);
00601 _dbus_assert (link->data == message);
00602
00603
00604 _dbus_list_unlink (&connection->outgoing_messages,
00605 link);
00606 _dbus_list_prepend_link (&connection->link_cache, link);
00607
00608 connection->n_outgoing -= 1;
00609
00610 _dbus_verbose ("Message %p (%d %s %s %s '%s') removed from outgoing queue %p, %d left to send\n",
00611 message,
00612 dbus_message_get_type (message),
00613 dbus_message_get_path (message) ?
00614 dbus_message_get_path (message) :
00615 "no path",
00616 dbus_message_get_interface (message) ?
00617 dbus_message_get_interface (message) :
00618 "no interface",
00619 dbus_message_get_member (message) ?
00620 dbus_message_get_member (message) :
00621 "no member",
00622 dbus_message_get_signature (message),
00623 connection, connection->n_outgoing);
00624
00625
00626 _dbus_message_remove_size_counter (message, connection->outgoing_counter,
00627 &link);
00628 _dbus_list_prepend_link (&connection->link_cache, link);
00629
00630 dbus_message_unref (message);
00631 }
00632
00634 typedef dbus_bool_t (* DBusWatchAddFunction) (DBusWatchList *list,
00635 DBusWatch *watch);
00637 typedef void (* DBusWatchRemoveFunction) (DBusWatchList *list,
00638 DBusWatch *watch);
00640 typedef void (* DBusWatchToggleFunction) (DBusWatchList *list,
00641 DBusWatch *watch,
00642 dbus_bool_t enabled);
00643
00644 static dbus_bool_t
00645 protected_change_watch (DBusConnection *connection,
00646 DBusWatch *watch,
00647 DBusWatchAddFunction add_function,
00648 DBusWatchRemoveFunction remove_function,
00649 DBusWatchToggleFunction toggle_function,
00650 dbus_bool_t enabled)
00651 {
00652 DBusWatchList *watches;
00653 dbus_bool_t retval;
00654
00655 HAVE_LOCK_CHECK (connection);
00656
00657
00658
00659
00660
00661 watches = connection->watches;
00662 if (watches)
00663 {
00664 connection->watches = NULL;
00665 _dbus_connection_ref_unlocked (connection);
00666 CONNECTION_UNLOCK (connection);
00667
00668 if (add_function)
00669 retval = (* add_function) (watches, watch);
00670 else if (remove_function)
00671 {
00672 retval = TRUE;
00673 (* remove_function) (watches, watch);
00674 }
00675 else
00676 {
00677 retval = TRUE;
00678 (* toggle_function) (watches, watch, enabled);
00679 }
00680
00681 CONNECTION_LOCK (connection);
00682 connection->watches = watches;
00683 _dbus_connection_unref_unlocked (connection);
00684
00685 return retval;
00686 }
00687 else
00688 return FALSE;
00689 }
00690
00691
00703 dbus_bool_t
00704 _dbus_connection_add_watch_unlocked (DBusConnection *connection,
00705 DBusWatch *watch)
00706 {
00707 return protected_change_watch (connection, watch,
00708 _dbus_watch_list_add_watch,
00709 NULL, NULL, FALSE);
00710 }
00711
00721 void
00722 _dbus_connection_remove_watch_unlocked (DBusConnection *connection,
00723 DBusWatch *watch)
00724 {
00725 protected_change_watch (connection, watch,
00726 NULL,
00727 _dbus_watch_list_remove_watch,
00728 NULL, FALSE);
00729 }
00730
00741 void
00742 _dbus_connection_toggle_watch_unlocked (DBusConnection *connection,
00743 DBusWatch *watch,
00744 dbus_bool_t enabled)
00745 {
00746 _dbus_assert (watch != NULL);
00747
00748 protected_change_watch (connection, watch,
00749 NULL, NULL,
00750 _dbus_watch_list_toggle_watch,
00751 enabled);
00752 }
00753
00755 typedef dbus_bool_t (* DBusTimeoutAddFunction) (DBusTimeoutList *list,
00756 DBusTimeout *timeout);
00758 typedef void (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list,
00759 DBusTimeout *timeout);
00761 typedef void (* DBusTimeoutToggleFunction) (DBusTimeoutList *list,
00762 DBusTimeout *timeout,
00763 dbus_bool_t enabled);
00764
00765 static dbus_bool_t
00766 protected_change_timeout (DBusConnection *connection,
00767 DBusTimeout *timeout,
00768 DBusTimeoutAddFunction add_function,
00769 DBusTimeoutRemoveFunction remove_function,
00770 DBusTimeoutToggleFunction toggle_function,
00771 dbus_bool_t enabled)
00772 {
00773 DBusTimeoutList *timeouts;
00774 dbus_bool_t retval;
00775
00776 HAVE_LOCK_CHECK (connection);
00777
00778
00779
00780
00781
00782 retry:
00783 timeouts = connection->timeouts;
00784 if (timeouts)
00785 {
00786 connection->timeouts = NULL;
00787 _dbus_connection_ref_unlocked (connection);
00788 CONNECTION_UNLOCK (connection);
00789
00790 if (add_function)
00791 retval = (* add_function) (timeouts, timeout);
00792 else if (remove_function)
00793 {
00794 retval = TRUE;
00795 (* remove_function) (timeouts, timeout);
00796 }
00797 else
00798 {
00799 retval = TRUE;
00800 (* toggle_function) (timeouts, timeout, enabled);
00801 }
00802
00803 CONNECTION_LOCK (connection);
00804 connection->timeouts = timeouts;
00805 _dbus_connection_unref_unlocked (connection);
00806
00807 return retval;
00808 }
00809 else
00810 {
00811 CONNECTION_UNLOCK (connection);
00812 usleep(1000);
00813 CONNECTION_LOCK (connection);
00814 goto retry;
00815 }
00816 }
00817
00830 dbus_bool_t
00831 _dbus_connection_add_timeout_unlocked (DBusConnection *connection,
00832 DBusTimeout *timeout)
00833 {
00834 return protected_change_timeout (connection, timeout,
00835 _dbus_timeout_list_add_timeout,
00836 NULL, NULL, FALSE);
00837 }
00838
00848 void
00849 _dbus_connection_remove_timeout_unlocked (DBusConnection *connection,
00850 DBusTimeout *timeout)
00851 {
00852 protected_change_timeout (connection, timeout,
00853 NULL,
00854 _dbus_timeout_list_remove_timeout,
00855 NULL, FALSE);
00856 }
00857
00868 void
00869 _dbus_connection_toggle_timeout_unlocked (DBusConnection *connection,
00870 DBusTimeout *timeout,
00871 dbus_bool_t enabled)
00872 {
00873 protected_change_timeout (connection, timeout,
00874 NULL, NULL,
00875 _dbus_timeout_list_toggle_timeout,
00876 enabled);
00877 }
00878
00879 static dbus_bool_t
00880 _dbus_connection_attach_pending_call_unlocked (DBusConnection *connection,
00881 DBusPendingCall *pending)
00882 {
00883 dbus_uint32_t reply_serial;
00884 DBusTimeout *timeout;
00885
00886 HAVE_LOCK_CHECK (connection);
00887
00888 reply_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
00889
00890 _dbus_assert (reply_serial != 0);
00891
00892 timeout = _dbus_pending_call_get_timeout_unlocked (pending);
00893
00894 if (timeout)
00895 {
00896 if (!_dbus_connection_add_timeout_unlocked (connection, timeout))
00897 return FALSE;
00898
00899 if (!_dbus_hash_table_insert_int (connection->pending_replies,
00900 reply_serial,
00901 pending))
00902 {
00903 _dbus_connection_remove_timeout_unlocked (connection, timeout);
00904
00905 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00906 HAVE_LOCK_CHECK (connection);
00907 return FALSE;
00908 }
00909
00910 _dbus_pending_call_set_timeout_added_unlocked (pending, TRUE);
00911 }
00912 else
00913 {
00914 if (!_dbus_hash_table_insert_int (connection->pending_replies,
00915 reply_serial,
00916 pending))
00917 {
00918 HAVE_LOCK_CHECK (connection);
00919 return FALSE;
00920 }
00921 }
00922
00923 _dbus_pending_call_ref_unlocked (pending);
00924
00925 HAVE_LOCK_CHECK (connection);
00926
00927 return TRUE;
00928 }
00929
00930 static void
00931 free_pending_call_on_hash_removal (void *data)
00932 {
00933 DBusPendingCall *pending;
00934 DBusConnection *connection;
00935
00936 if (data == NULL)
00937 return;
00938
00939 pending = data;
00940
00941 connection = _dbus_pending_call_get_connection_unlocked (pending);
00942
00943 HAVE_LOCK_CHECK (connection);
00944
00945 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00946 {
00947 _dbus_connection_remove_timeout_unlocked (connection,
00948 _dbus_pending_call_get_timeout_unlocked (pending));
00949
00950 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00951 }
00952
00953
00954
00955
00956
00957
00958 _dbus_connection_ref_unlocked (connection);
00959 _dbus_pending_call_unref_and_unlock (pending);
00960 CONNECTION_LOCK (connection);
00961 _dbus_connection_unref_unlocked (connection);
00962 }
00963
00964 static void
00965 _dbus_connection_detach_pending_call_unlocked (DBusConnection *connection,
00966 DBusPendingCall *pending)
00967 {
00968
00969
00970
00971 _dbus_hash_table_remove_int (connection->pending_replies,
00972 _dbus_pending_call_get_reply_serial_unlocked (pending));
00973 }
00974
00975 static void
00976 _dbus_connection_detach_pending_call_and_unlock (DBusConnection *connection,
00977 DBusPendingCall *pending)
00978 {
00979
00980
00981
00982
00983
00984
00985
00986 _dbus_pending_call_ref_unlocked (pending);
00987 _dbus_hash_table_remove_int (connection->pending_replies,
00988 _dbus_pending_call_get_reply_serial_unlocked (pending));
00989
00990 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
00991 _dbus_connection_remove_timeout_unlocked (connection,
00992 _dbus_pending_call_get_timeout_unlocked (pending));
00993
00994 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
00995
00996 _dbus_pending_call_unref_and_unlock (pending);
00997 }
00998
01007 void
01008 _dbus_connection_remove_pending_call (DBusConnection *connection,
01009 DBusPendingCall *pending)
01010 {
01011 CONNECTION_LOCK (connection);
01012 _dbus_connection_detach_pending_call_and_unlock (connection, pending);
01013 }
01014
01024 static dbus_bool_t
01025 _dbus_connection_acquire_io_path (DBusConnection *connection,
01026 int timeout_milliseconds)
01027 {
01028 dbus_bool_t we_acquired;
01029
01030 HAVE_LOCK_CHECK (connection);
01031
01032
01033 _dbus_connection_ref_unlocked (connection);
01034
01035
01036 CONNECTION_UNLOCK (connection);
01037
01038 _dbus_verbose ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME);
01039 _dbus_mutex_lock (connection->io_path_mutex);
01040
01041 _dbus_verbose ("%s start connection->io_path_acquired = %d timeout = %d\n",
01042 _DBUS_FUNCTION_NAME, connection->io_path_acquired, timeout_milliseconds);
01043
01044 we_acquired = FALSE;
01045
01046 if (connection->io_path_acquired)
01047 {
01048 if (timeout_milliseconds != -1)
01049 {
01050 _dbus_verbose ("%s waiting %d for IO path to be acquirable\n",
01051 _DBUS_FUNCTION_NAME, timeout_milliseconds);
01052
01053 if (!_dbus_condvar_wait_timeout (connection->io_path_cond,
01054 connection->io_path_mutex,
01055 timeout_milliseconds))
01056 {
01057
01058
01059
01060
01061
01062
01063
01064
01065 }
01066 }
01067 else
01068 {
01069 while (connection->io_path_acquired)
01070 {
01071 _dbus_verbose ("%s waiting for IO path to be acquirable\n", _DBUS_FUNCTION_NAME);
01072 _dbus_condvar_wait (connection->io_path_cond,
01073 connection->io_path_mutex);
01074 }
01075 }
01076 }
01077
01078 if (!connection->io_path_acquired)
01079 {
01080 we_acquired = TRUE;
01081 connection->io_path_acquired = TRUE;
01082 }
01083
01084 _dbus_verbose ("%s end connection->io_path_acquired = %d we_acquired = %d\n",
01085 _DBUS_FUNCTION_NAME, connection->io_path_acquired, we_acquired);
01086
01087 _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME);
01088 _dbus_mutex_unlock (connection->io_path_mutex);
01089
01090 CONNECTION_LOCK (connection);
01091
01092 HAVE_LOCK_CHECK (connection);
01093
01094 _dbus_connection_unref_unlocked (connection);
01095
01096 return we_acquired;
01097 }
01098
01106 static void
01107 _dbus_connection_release_io_path (DBusConnection *connection)
01108 {
01109 HAVE_LOCK_CHECK (connection);
01110
01111 _dbus_verbose ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME);
01112 _dbus_mutex_lock (connection->io_path_mutex);
01113
01114 _dbus_assert (connection->io_path_acquired);
01115
01116 _dbus_verbose ("%s start connection->io_path_acquired = %d\n",
01117 _DBUS_FUNCTION_NAME, connection->io_path_acquired);
01118
01119 connection->io_path_acquired = FALSE;
01120 _dbus_condvar_wake_one (connection->io_path_cond);
01121
01122 _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME);
01123 _dbus_mutex_unlock (connection->io_path_mutex);
01124 }
01125
01161 void
01162 _dbus_connection_do_iteration_unlocked (DBusConnection *connection,
01163 DBusPendingCall *pending,
01164 unsigned int flags,
01165 int timeout_milliseconds)
01166 {
01167 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
01168
01169 HAVE_LOCK_CHECK (connection);
01170
01171 if (connection->n_outgoing == 0)
01172 flags &= ~DBUS_ITERATION_DO_WRITING;
01173
01174 if (_dbus_connection_acquire_io_path (connection,
01175 (flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0))
01176 {
01177 HAVE_LOCK_CHECK (connection);
01178
01179 if ( (pending != NULL) && _dbus_pending_call_get_completed_unlocked(pending))
01180 {
01181 _dbus_verbose ("pending call completed while acquiring I/O path");
01182 }
01183 else if ( (pending != NULL) &&
01184 _dbus_connection_peek_for_reply_unlocked (connection,
01185 _dbus_pending_call_get_reply_serial_unlocked (pending)))
01186 {
01187 _dbus_verbose ("pending call completed while acquiring I/O path (reply found in queue)");
01188 }
01189 else
01190 {
01191 _dbus_transport_do_iteration (connection->transport,
01192 flags, timeout_milliseconds);
01193 }
01194
01195 _dbus_connection_release_io_path (connection);
01196 }
01197
01198 HAVE_LOCK_CHECK (connection);
01199
01200 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
01201 }
01202
01212 DBusConnection*
01213 _dbus_connection_new_for_transport (DBusTransport *transport)
01214 {
01215 DBusConnection *connection;
01216 DBusWatchList *watch_list;
01217 DBusTimeoutList *timeout_list;
01218 DBusHashTable *pending_replies;
01219 DBusList *disconnect_link;
01220 DBusMessage *disconnect_message;
01221 DBusCounter *outgoing_counter;
01222 DBusObjectTree *objects;
01223
01224 watch_list = NULL;
01225 connection = NULL;
01226 pending_replies = NULL;
01227 timeout_list = NULL;
01228 disconnect_link = NULL;
01229 disconnect_message = NULL;
01230 outgoing_counter = NULL;
01231 objects = NULL;
01232
01233 watch_list = _dbus_watch_list_new ();
01234 if (watch_list == NULL)
01235 goto error;
01236
01237 timeout_list = _dbus_timeout_list_new ();
01238 if (timeout_list == NULL)
01239 goto error;
01240
01241 pending_replies =
01242 _dbus_hash_table_new (DBUS_HASH_INT,
01243 NULL,
01244 (DBusFreeFunction)free_pending_call_on_hash_removal);
01245 if (pending_replies == NULL)
01246 goto error;
01247
01248 connection = dbus_new0 (DBusConnection, 1);
01249 if (connection == NULL)
01250 goto error;
01251
01252 _dbus_mutex_new_at_location (&connection->mutex);
01253 if (connection->mutex == NULL)
01254 goto error;
01255
01256 _dbus_mutex_new_at_location (&connection->io_path_mutex);
01257 if (connection->io_path_mutex == NULL)
01258 goto error;
01259
01260 _dbus_mutex_new_at_location (&connection->dispatch_mutex);
01261 if (connection->dispatch_mutex == NULL)
01262 goto error;
01263
01264 _dbus_condvar_new_at_location (&connection->dispatch_cond);
01265 if (connection->dispatch_cond == NULL)
01266 goto error;
01267
01268 _dbus_condvar_new_at_location (&connection->io_path_cond);
01269 if (connection->io_path_cond == NULL)
01270 goto error;
01271
01272 disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL,
01273 DBUS_INTERFACE_LOCAL,
01274 "Disconnected");
01275
01276 if (disconnect_message == NULL)
01277 goto error;
01278
01279 disconnect_link = _dbus_list_alloc_link (disconnect_message);
01280 if (disconnect_link == NULL)
01281 goto error;
01282
01283 outgoing_counter = _dbus_counter_new ();
01284 if (outgoing_counter == NULL)
01285 goto error;
01286
01287 objects = _dbus_object_tree_new (connection);
01288 if (objects == NULL)
01289 goto error;
01290
01291 if (_dbus_modify_sigpipe)
01292 _dbus_disable_sigpipe ();
01293
01294 connection->refcount.value = 1;
01295 connection->transport = transport;
01296 connection->watches = watch_list;
01297 connection->timeouts = timeout_list;
01298 connection->pending_replies = pending_replies;
01299 connection->outgoing_counter = outgoing_counter;
01300 connection->filter_list = NULL;
01301 connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE;
01302 connection->objects = objects;
01303 connection->exit_on_disconnect = FALSE;
01304 connection->shareable = FALSE;
01305 connection->route_peer_messages = FALSE;
01306 connection->disconnected_message_arrived = FALSE;
01307 connection->disconnected_message_processed = FALSE;
01308
01309 #ifndef DBUS_DISABLE_CHECKS
01310 connection->generation = _dbus_current_generation;
01311 #endif
01312
01313 _dbus_data_slot_list_init (&connection->slot_list);
01314
01315 connection->client_serial = 1;
01316
01317 connection->disconnect_message_link = disconnect_link;
01318
01319 CONNECTION_LOCK (connection);
01320
01321 if (!_dbus_transport_set_connection (transport, connection))
01322 {
01323 CONNECTION_UNLOCK (connection);
01324
01325 goto error;
01326 }
01327
01328 _dbus_transport_ref (transport);
01329
01330 CONNECTION_UNLOCK (connection);
01331
01332 return connection;
01333
01334 error:
01335 if (disconnect_message != NULL)
01336 dbus_message_unref (disconnect_message);
01337
01338 if (disconnect_link != NULL)
01339 _dbus_list_free_link (disconnect_link);
01340
01341 if (connection != NULL)
01342 {
01343 _dbus_condvar_free_at_location (&connection->io_path_cond);
01344 _dbus_condvar_free_at_location (&connection->dispatch_cond);
01345 _dbus_mutex_free_at_location (&connection->mutex);
01346 _dbus_mutex_free_at_location (&connection->io_path_mutex);
01347 _dbus_mutex_free_at_location (&connection->dispatch_mutex);
01348 dbus_free (connection);
01349 }
01350 if (pending_replies)
01351 _dbus_hash_table_unref (pending_replies);
01352
01353 if (watch_list)
01354 _dbus_watch_list_free (watch_list);
01355
01356 if (timeout_list)
01357 _dbus_timeout_list_free (timeout_list);
01358
01359 if (outgoing_counter)
01360 _dbus_counter_unref (outgoing_counter);
01361
01362 if (objects)
01363 _dbus_object_tree_unref (objects);
01364
01365 return NULL;
01366 }
01367
01375 DBusConnection *
01376 _dbus_connection_ref_unlocked (DBusConnection *connection)
01377 {
01378 _dbus_assert (connection != NULL);
01379 _dbus_assert (connection->generation == _dbus_current_generation);
01380
01381 HAVE_LOCK_CHECK (connection);
01382
01383 #ifdef DBUS_HAVE_ATOMIC_INT
01384 _dbus_atomic_inc (&connection->refcount);
01385 #else
01386 _dbus_assert (connection->refcount.value > 0);
01387 connection->refcount.value += 1;
01388 #endif
01389
01390 return connection;
01391 }
01392
01399 void
01400 _dbus_connection_unref_unlocked (DBusConnection *connection)
01401 {
01402 dbus_bool_t last_unref;
01403
01404 HAVE_LOCK_CHECK (connection);
01405
01406 _dbus_assert (connection != NULL);
01407
01408
01409
01410
01411
01412 #ifdef DBUS_HAVE_ATOMIC_INT
01413 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
01414 #else
01415 _dbus_assert (connection->refcount.value > 0);
01416
01417 connection->refcount.value -= 1;
01418 last_unref = (connection->refcount.value == 0);
01419 #if 0
01420 printf ("unref_unlocked() connection %p count = %d\n", connection, connection->refcount.value);
01421 #endif
01422 #endif
01423
01424 if (last_unref)
01425 _dbus_connection_last_unref (connection);
01426 }
01427
01428 static dbus_uint32_t
01429 _dbus_connection_get_next_client_serial (DBusConnection *connection)
01430 {
01431 dbus_uint32_t serial;
01432
01433 serial = connection->client_serial++;
01434
01435 if (connection->client_serial == 0)
01436 connection->client_serial = 1;
01437
01438 return serial;
01439 }
01440
01454 dbus_bool_t
01455 _dbus_connection_handle_watch (DBusWatch *watch,
01456 unsigned int condition,
01457 void *data)
01458 {
01459 DBusConnection *connection;
01460 dbus_bool_t retval;
01461 DBusDispatchStatus status;
01462
01463 connection = data;
01464
01465 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
01466
01467 CONNECTION_LOCK (connection);
01468 _dbus_connection_acquire_io_path (connection, -1);
01469 HAVE_LOCK_CHECK (connection);
01470 retval = _dbus_transport_handle_watch (connection->transport,
01471 watch, condition);
01472
01473 _dbus_connection_release_io_path (connection);
01474
01475 HAVE_LOCK_CHECK (connection);
01476
01477 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
01478
01479 status = _dbus_connection_get_dispatch_status_unlocked (connection);
01480
01481
01482 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01483
01484 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
01485
01486 return retval;
01487 }
01488
01489 _DBUS_DEFINE_GLOBAL_LOCK (shared_connections);
01490 static DBusHashTable *shared_connections = NULL;
01491 static DBusList *shared_connections_no_guid = NULL;
01492
01493 static void
01494 close_connection_on_shutdown (DBusConnection *connection)
01495 {
01496 DBusMessage *message;
01497
01498 dbus_connection_ref (connection);
01499 _dbus_connection_close_possibly_shared (connection);
01500
01501
01502 while ((message = dbus_connection_pop_message (connection)))
01503 {
01504 dbus_message_unref (message);
01505 }
01506 dbus_connection_unref (connection);
01507 }
01508
01509 static void
01510 shared_connections_shutdown (void *data)
01511 {
01512 int n_entries;
01513
01514 _DBUS_LOCK (shared_connections);
01515
01516
01517 while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0)
01518 {
01519 DBusConnection *connection;
01520 DBusHashIter iter;
01521
01522 _dbus_hash_iter_init (shared_connections, &iter);
01523 _dbus_hash_iter_next (&iter);
01524
01525 connection = _dbus_hash_iter_get_value (&iter);
01526
01527 _DBUS_UNLOCK (shared_connections);
01528 close_connection_on_shutdown (connection);
01529 _DBUS_LOCK (shared_connections);
01530
01531
01532 _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) < n_entries);
01533 }
01534
01535 _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) == 0);
01536
01537 _dbus_hash_table_unref (shared_connections);
01538 shared_connections = NULL;
01539
01540 if (shared_connections_no_guid != NULL)
01541 {
01542 DBusConnection *connection;
01543 connection = _dbus_list_pop_first (&shared_connections_no_guid);
01544 while (connection != NULL)
01545 {
01546 _DBUS_UNLOCK (shared_connections);
01547 close_connection_on_shutdown (connection);
01548 _DBUS_LOCK (shared_connections);
01549 connection = _dbus_list_pop_first (&shared_connections_no_guid);
01550 }
01551 }
01552
01553 shared_connections_no_guid = NULL;
01554
01555 _DBUS_UNLOCK (shared_connections);
01556 }
01557
01558 static dbus_bool_t
01559 connection_lookup_shared (DBusAddressEntry *entry,
01560 DBusConnection **result)
01561 {
01562 _dbus_verbose ("checking for existing connection\n");
01563
01564 *result = NULL;
01565
01566 _DBUS_LOCK (shared_connections);
01567
01568 if (shared_connections == NULL)
01569 {
01570 _dbus_verbose ("creating shared_connections hash table\n");
01571
01572 shared_connections = _dbus_hash_table_new (DBUS_HASH_STRING,
01573 dbus_free,
01574 NULL);
01575 if (shared_connections == NULL)
01576 {
01577 _DBUS_UNLOCK (shared_connections);
01578 return FALSE;
01579 }
01580
01581 if (!_dbus_register_shutdown_func (shared_connections_shutdown, NULL))
01582 {
01583 _dbus_hash_table_unref (shared_connections);
01584 shared_connections = NULL;
01585 _DBUS_UNLOCK (shared_connections);
01586 return FALSE;
01587 }
01588
01589 _dbus_verbose (" successfully created shared_connections\n");
01590
01591 _DBUS_UNLOCK (shared_connections);
01592 return TRUE;
01593 }
01594 else
01595 {
01596 const char *guid;
01597
01598 guid = dbus_address_entry_get_value (entry, "guid");
01599
01600 if (guid != NULL)
01601 {
01602 DBusConnection *connection;
01603
01604 connection = _dbus_hash_table_lookup_string (shared_connections,
01605 guid);
01606
01607 if (connection)
01608 {
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623 CONNECTION_LOCK (connection);
01624 if (_dbus_connection_get_is_connected_unlocked (connection))
01625 {
01626 _dbus_connection_ref_unlocked (connection);
01627 *result = connection;
01628 _dbus_verbose ("looked up existing connection to server guid %s\n",
01629 guid);
01630 }
01631 else
01632 {
01633 _dbus_verbose ("looked up existing connection to server guid %s but it was disconnected so ignoring it\n",
01634 guid);
01635 }
01636 CONNECTION_UNLOCK (connection);
01637 }
01638 }
01639
01640 _DBUS_UNLOCK (shared_connections);
01641 return TRUE;
01642 }
01643 }
01644
01645 static dbus_bool_t
01646 connection_record_shared_unlocked (DBusConnection *connection,
01647 const char *guid)
01648 {
01649 char *guid_key;
01650 char *guid_in_connection;
01651
01652 HAVE_LOCK_CHECK (connection);
01653 _dbus_assert (connection->server_guid == NULL);
01654 _dbus_assert (connection->shareable);
01655
01656
01657
01658
01659
01660 _dbus_connection_ref_unlocked (connection);
01661
01662 if (guid == NULL)
01663 {
01664 _DBUS_LOCK (shared_connections);
01665
01666 if (!_dbus_list_prepend (&shared_connections_no_guid, connection))
01667 {
01668 _DBUS_UNLOCK (shared_connections);
01669 return FALSE;
01670 }
01671
01672 _DBUS_UNLOCK (shared_connections);
01673 return TRUE;
01674 }
01675
01676
01677
01678
01679
01680
01681 guid_key = _dbus_strdup (guid);
01682 if (guid_key == NULL)
01683 return FALSE;
01684
01685 guid_in_connection = _dbus_strdup (guid);
01686 if (guid_in_connection == NULL)
01687 {
01688 dbus_free (guid_key);
01689 return FALSE;
01690 }
01691
01692 _DBUS_LOCK (shared_connections);
01693 _dbus_assert (shared_connections != NULL);
01694
01695 if (!_dbus_hash_table_insert_string (shared_connections,
01696 guid_key, connection))
01697 {
01698 dbus_free (guid_key);
01699 dbus_free (guid_in_connection);
01700 _DBUS_UNLOCK (shared_connections);
01701 return FALSE;
01702 }
01703
01704 connection->server_guid = guid_in_connection;
01705
01706 _dbus_verbose ("stored connection to %s to be shared\n",
01707 connection->server_guid);
01708
01709 _DBUS_UNLOCK (shared_connections);
01710
01711 _dbus_assert (connection->server_guid != NULL);
01712
01713 return TRUE;
01714 }
01715
01716 static void
01717 connection_forget_shared_unlocked (DBusConnection *connection)
01718 {
01719 HAVE_LOCK_CHECK (connection);
01720
01721 if (!connection->shareable)
01722 return;
01723
01724 _DBUS_LOCK (shared_connections);
01725
01726 if (connection->server_guid != NULL)
01727 {
01728 _dbus_verbose ("dropping connection to %s out of the shared table\n",
01729 connection->server_guid);
01730
01731 if (!_dbus_hash_table_remove_string (shared_connections,
01732 connection->server_guid))
01733 _dbus_assert_not_reached ("connection was not in the shared table");
01734
01735 dbus_free (connection->server_guid);
01736 connection->server_guid = NULL;
01737 }
01738 else
01739 {
01740 _dbus_list_remove (&shared_connections_no_guid, connection);
01741 }
01742
01743 _DBUS_UNLOCK (shared_connections);
01744
01745
01746 _dbus_connection_unref_unlocked (connection);
01747 }
01748
01749 static DBusConnection*
01750 connection_try_from_address_entry (DBusAddressEntry *entry,
01751 DBusError *error)
01752 {
01753 DBusTransport *transport;
01754 DBusConnection *connection;
01755
01756 transport = _dbus_transport_open (entry, error);
01757
01758 if (transport == NULL)
01759 {
01760 _DBUS_ASSERT_ERROR_IS_SET (error);
01761 return NULL;
01762 }
01763
01764 connection = _dbus_connection_new_for_transport (transport);
01765
01766 _dbus_transport_unref (transport);
01767
01768 if (connection == NULL)
01769 {
01770 _DBUS_SET_OOM (error);
01771 return NULL;
01772 }
01773
01774 #ifndef DBUS_DISABLE_CHECKS
01775 _dbus_assert (!connection->have_connection_lock);
01776 #endif
01777 return connection;
01778 }
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792 static DBusConnection*
01793 _dbus_connection_open_internal (const char *address,
01794 dbus_bool_t shared,
01795 DBusError *error)
01796 {
01797 DBusConnection *connection;
01798 DBusAddressEntry **entries;
01799 DBusError tmp_error = DBUS_ERROR_INIT;
01800 DBusError first_error = DBUS_ERROR_INIT;
01801 int len, i;
01802
01803 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01804
01805 _dbus_verbose ("opening %s connection to: %s\n",
01806 shared ? "shared" : "private", address);
01807
01808 if (!dbus_parse_address (address, &entries, &len, error))
01809 return NULL;
01810
01811 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01812
01813 connection = NULL;
01814
01815 for (i = 0; i < len; i++)
01816 {
01817 if (shared)
01818 {
01819 if (!connection_lookup_shared (entries[i], &connection))
01820 _DBUS_SET_OOM (&tmp_error);
01821 }
01822
01823 if (connection == NULL)
01824 {
01825 connection = connection_try_from_address_entry (entries[i],
01826 &tmp_error);
01827
01828 if (connection != NULL && shared)
01829 {
01830 const char *guid;
01831
01832 connection->shareable = TRUE;
01833
01834
01835 guid = dbus_address_entry_get_value (entries[i], "guid");
01836
01837 CONNECTION_LOCK (connection);
01838
01839 if (!connection_record_shared_unlocked (connection, guid))
01840 {
01841 _DBUS_SET_OOM (&tmp_error);
01842 _dbus_connection_close_possibly_shared_and_unlock (connection);
01843 dbus_connection_unref (connection);
01844 connection = NULL;
01845 }
01846 else
01847 CONNECTION_UNLOCK (connection);
01848 }
01849 }
01850
01851 if (connection)
01852 break;
01853
01854 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
01855
01856 if (i == 0)
01857 dbus_move_error (&tmp_error, &first_error);
01858 else
01859 dbus_error_free (&tmp_error);
01860 }
01861
01862 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
01863 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
01864
01865 if (connection == NULL)
01866 {
01867 _DBUS_ASSERT_ERROR_IS_SET (&first_error);
01868 dbus_move_error (&first_error, error);
01869 }
01870 else
01871 dbus_error_free (&first_error);
01872
01873 dbus_address_entries_free (entries);
01874 return connection;
01875 }
01876
01885 void
01886 _dbus_connection_close_possibly_shared (DBusConnection *connection)
01887 {
01888 _dbus_assert (connection != NULL);
01889 _dbus_assert (connection->generation == _dbus_current_generation);
01890
01891 CONNECTION_LOCK (connection);
01892 _dbus_connection_close_possibly_shared_and_unlock (connection);
01893 }
01894
01895 static DBusPreallocatedSend*
01896 _dbus_connection_preallocate_send_unlocked (DBusConnection *connection)
01897 {
01898 DBusPreallocatedSend *preallocated;
01899
01900 HAVE_LOCK_CHECK (connection);
01901
01902 _dbus_assert (connection != NULL);
01903
01904 preallocated = dbus_new (DBusPreallocatedSend, 1);
01905 if (preallocated == NULL)
01906 return NULL;
01907
01908 if (connection->link_cache != NULL)
01909 {
01910 preallocated->queue_link =
01911 _dbus_list_pop_first_link (&connection->link_cache);
01912 preallocated->queue_link->data = NULL;
01913 }
01914 else
01915 {
01916 preallocated->queue_link = _dbus_list_alloc_link (NULL);
01917 if (preallocated->queue_link == NULL)
01918 goto failed_0;
01919 }
01920
01921 if (connection->link_cache != NULL)
01922 {
01923 preallocated->counter_link =
01924 _dbus_list_pop_first_link (&connection->link_cache);
01925 preallocated->counter_link->data = connection->outgoing_counter;
01926 }
01927 else
01928 {
01929 preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter);
01930 if (preallocated->counter_link == NULL)
01931 goto failed_1;
01932 }
01933
01934 _dbus_counter_ref (preallocated->counter_link->data);
01935
01936 preallocated->connection = connection;
01937
01938 return preallocated;
01939
01940 failed_1:
01941 _dbus_list_free_link (preallocated->queue_link);
01942 failed_0:
01943 dbus_free (preallocated);
01944
01945 return NULL;
01946 }
01947
01948
01949 static void
01950 _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *connection,
01951 DBusPreallocatedSend *preallocated,
01952 DBusMessage *message,
01953 dbus_uint32_t *client_serial)
01954 {
01955 dbus_uint32_t serial;
01956 const char *sig;
01957
01958 preallocated->queue_link->data = message;
01959 _dbus_list_prepend_link (&connection->outgoing_messages,
01960 preallocated->queue_link);
01961
01962 _dbus_message_add_size_counter_link (message,
01963 preallocated->counter_link);
01964
01965 dbus_free (preallocated);
01966 preallocated = NULL;
01967
01968 dbus_message_ref (message);
01969
01970 connection->n_outgoing += 1;
01971
01972 sig = dbus_message_get_signature (message);
01973
01974 _dbus_verbose ("Message %p (%d %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
01975 message,
01976 dbus_message_get_type (message),
01977 dbus_message_get_path (message) ?
01978 dbus_message_get_path (message) :
01979 "no path",
01980 dbus_message_get_interface (message) ?
01981 dbus_message_get_interface (message) :
01982 "no interface",
01983 dbus_message_get_member (message) ?
01984 dbus_message_get_member (message) :
01985 "no member",
01986 sig,
01987 dbus_message_get_destination (message) ?
01988 dbus_message_get_destination (message) :
01989 "null",
01990 connection,
01991 connection->n_outgoing);
01992
01993 if (dbus_message_get_serial (message) == 0)
01994 {
01995 serial = _dbus_connection_get_next_client_serial (connection);
01996 dbus_message_set_serial (message, serial);
01997 if (client_serial)
01998 *client_serial = serial;
01999 }
02000 else
02001 {
02002 if (client_serial)
02003 *client_serial = dbus_message_get_serial (message);
02004 }
02005
02006 _dbus_verbose ("Message %p serial is %u\n",
02007 message, dbus_message_get_serial (message));
02008
02009 dbus_message_lock (message);
02010
02011
02012
02013
02014 _dbus_connection_do_iteration_unlocked (connection,
02015 NULL,
02016 DBUS_ITERATION_DO_WRITING,
02017 -1);
02018
02019
02020 if (connection->n_outgoing > 0)
02021 _dbus_connection_wakeup_mainloop (connection);
02022 }
02023
02024 static void
02025 _dbus_connection_send_preallocated_and_unlock (DBusConnection *connection,
02026 DBusPreallocatedSend *preallocated,
02027 DBusMessage *message,
02028 dbus_uint32_t *client_serial)
02029 {
02030 DBusDispatchStatus status;
02031
02032 HAVE_LOCK_CHECK (connection);
02033
02034 _dbus_connection_send_preallocated_unlocked_no_update (connection,
02035 preallocated,
02036 message, client_serial);
02037
02038 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
02039 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02040
02041
02042 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02043 }
02044
02054 dbus_bool_t
02055 _dbus_connection_send_and_unlock (DBusConnection *connection,
02056 DBusMessage *message,
02057 dbus_uint32_t *client_serial)
02058 {
02059 DBusPreallocatedSend *preallocated;
02060
02061 _dbus_assert (connection != NULL);
02062 _dbus_assert (message != NULL);
02063
02064 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
02065 if (preallocated == NULL)
02066 {
02067 CONNECTION_UNLOCK (connection);
02068 return FALSE;
02069 }
02070
02071 _dbus_connection_send_preallocated_and_unlock (connection,
02072 preallocated,
02073 message,
02074 client_serial);
02075 return TRUE;
02076 }
02077
02102 void
02103 _dbus_connection_close_if_only_one_ref (DBusConnection *connection)
02104 {
02105 CONNECTION_LOCK (connection);
02106
02107 _dbus_assert (connection->refcount.value > 0);
02108
02109 if (connection->refcount.value == 1)
02110 _dbus_connection_close_possibly_shared_and_unlock (connection);
02111 else
02112 CONNECTION_UNLOCK (connection);
02113 }
02114
02115
02125 static void
02126 _dbus_memory_pause_based_on_timeout (int timeout_milliseconds)
02127 {
02128 if (timeout_milliseconds == -1)
02129 _dbus_sleep_milliseconds (1000);
02130 else if (timeout_milliseconds < 100)
02131 ;
02132 else if (timeout_milliseconds <= 1000)
02133 _dbus_sleep_milliseconds (timeout_milliseconds / 3);
02134 else
02135 _dbus_sleep_milliseconds (1000);
02136 }
02137
02138 static DBusMessage *
02139 generate_local_error_message (dbus_uint32_t serial,
02140 char *error_name,
02141 char *error_msg)
02142 {
02143 DBusMessage *message;
02144 message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
02145 if (!message)
02146 goto out;
02147
02148 if (!dbus_message_set_error_name (message, error_name))
02149 {
02150 dbus_message_unref (message);
02151 message = NULL;
02152 goto out;
02153 }
02154
02155 dbus_message_set_no_reply (message, TRUE);
02156
02157 if (!dbus_message_set_reply_serial (message,
02158 serial))
02159 {
02160 dbus_message_unref (message);
02161 message = NULL;
02162 goto out;
02163 }
02164
02165 if (error_msg != NULL)
02166 {
02167 DBusMessageIter iter;
02168
02169 dbus_message_iter_init_append (message, &iter);
02170 if (!dbus_message_iter_append_basic (&iter,
02171 DBUS_TYPE_STRING,
02172 &error_msg))
02173 {
02174 dbus_message_unref (message);
02175 message = NULL;
02176 goto out;
02177 }
02178 }
02179
02180 out:
02181 return message;
02182 }
02183
02184
02185
02186
02187 static dbus_bool_t
02188 _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection,
02189 dbus_uint32_t client_serial)
02190 {
02191 DBusList *link;
02192 HAVE_LOCK_CHECK (connection);
02193
02194 link = _dbus_list_get_first_link (&connection->incoming_messages);
02195
02196 while (link != NULL)
02197 {
02198 DBusMessage *reply = link->data;
02199
02200 if (dbus_message_get_reply_serial (reply) == client_serial)
02201 {
02202 _dbus_verbose ("%s reply to %d found in queue\n", _DBUS_FUNCTION_NAME, client_serial);
02203 return TRUE;
02204 }
02205 link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02206 }
02207
02208 return FALSE;
02209 }
02210
02211
02212
02213
02214 static DBusMessage*
02215 check_for_reply_unlocked (DBusConnection *connection,
02216 dbus_uint32_t client_serial)
02217 {
02218 DBusList *link;
02219
02220 HAVE_LOCK_CHECK (connection);
02221
02222 link = _dbus_list_get_first_link (&connection->incoming_messages);
02223
02224 while (link != NULL)
02225 {
02226 DBusMessage *reply = link->data;
02227
02228 if (dbus_message_get_reply_serial (reply) == client_serial)
02229 {
02230 _dbus_list_remove_link (&connection->incoming_messages, link);
02231 connection->n_incoming -= 1;
02232 return reply;
02233 }
02234 link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02235 }
02236
02237 return NULL;
02238 }
02239
02240 static void
02241 connection_timeout_and_complete_all_pending_calls_unlocked (DBusConnection *connection)
02242 {
02243
02244
02245
02246
02247
02248 while (_dbus_hash_table_get_n_entries (connection->pending_replies) > 0)
02249 {
02250 DBusPendingCall *pending;
02251 DBusHashIter iter;
02252
02253 _dbus_hash_iter_init (connection->pending_replies, &iter);
02254 _dbus_hash_iter_next (&iter);
02255
02256 pending = _dbus_hash_iter_get_value (&iter);
02257 _dbus_pending_call_ref_unlocked (pending);
02258
02259 _dbus_pending_call_queue_timeout_error_unlocked (pending,
02260 connection);
02261
02262 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
02263 _dbus_connection_remove_timeout_unlocked (connection,
02264 _dbus_pending_call_get_timeout_unlocked (pending));
02265 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
02266 _dbus_hash_iter_remove_entry (&iter);
02267
02268 _dbus_pending_call_unref_and_unlock (pending);
02269 CONNECTION_LOCK (connection);
02270 }
02271 HAVE_LOCK_CHECK (connection);
02272 }
02273
02274 static void
02275 complete_pending_call_and_unlock (DBusConnection *connection,
02276 DBusPendingCall *pending,
02277 DBusMessage *message)
02278 {
02279 _dbus_pending_call_set_reply_unlocked (pending, message);
02280 _dbus_pending_call_ref_unlocked (pending);
02281 _dbus_connection_detach_pending_call_and_unlock (connection, pending);
02282
02283
02284 _dbus_pending_call_complete (pending);
02285 dbus_pending_call_unref (pending);
02286 }
02287
02288 static dbus_bool_t
02289 check_for_reply_and_update_dispatch_unlocked (DBusConnection *connection,
02290 DBusPendingCall *pending)
02291 {
02292 DBusMessage *reply;
02293 DBusDispatchStatus status;
02294
02295 reply = check_for_reply_unlocked (connection,
02296 _dbus_pending_call_get_reply_serial_unlocked (pending));
02297 if (reply != NULL)
02298 {
02299 _dbus_verbose ("%s checked for reply\n", _DBUS_FUNCTION_NAME);
02300
02301 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
02302
02303 complete_pending_call_and_unlock (connection, pending, reply);
02304 dbus_message_unref (reply);
02305
02306 CONNECTION_LOCK (connection);
02307 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02308 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02309 dbus_pending_call_unref (pending);
02310
02311 return TRUE;
02312 }
02313
02314 return FALSE;
02315 }
02316
02331 void
02332 _dbus_connection_block_pending_call (DBusPendingCall *pending)
02333 {
02334 long start_tv_sec, start_tv_usec;
02335 long tv_sec, tv_usec;
02336 DBusDispatchStatus status;
02337 DBusConnection *connection;
02338 dbus_uint32_t client_serial;
02339 DBusTimeout *timeout;
02340 int timeout_milliseconds, elapsed_milliseconds;
02341
02342 _dbus_assert (pending != NULL);
02343
02344 if (dbus_pending_call_get_completed (pending))
02345 return;
02346
02347 dbus_pending_call_ref (pending);
02348
02349 connection = _dbus_pending_call_get_connection_and_lock (pending);
02350
02351
02352 _dbus_connection_flush_unlocked (connection);
02353
02354 client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
02355
02356
02357
02358
02359
02360 timeout = _dbus_pending_call_get_timeout_unlocked (pending);
02361 if (timeout)
02362 {
02363 timeout_milliseconds = dbus_timeout_get_interval (timeout);
02364 _dbus_get_current_time (&start_tv_sec, &start_tv_usec);
02365
02366 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec\n",
02367 timeout_milliseconds,
02368 client_serial,
02369 start_tv_sec, start_tv_usec);
02370 }
02371 else
02372 {
02373 timeout_milliseconds = -1;
02374
02375 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block for reply serial %u\n", client_serial);
02376 }
02377
02378
02379
02380 if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02381 return;
02382
02383
02384
02385 _dbus_connection_do_iteration_unlocked (connection,
02386 pending,
02387 DBUS_ITERATION_DO_READING |
02388 DBUS_ITERATION_BLOCK,
02389 timeout_milliseconds);
02390
02391 recheck_status:
02392
02393 _dbus_verbose ("%s top of recheck\n", _DBUS_FUNCTION_NAME);
02394
02395 HAVE_LOCK_CHECK (connection);
02396
02397
02398
02399 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02400
02401
02402
02403
02404 if (_dbus_pending_call_get_completed_unlocked (pending))
02405 {
02406 _dbus_verbose ("Pending call completed by dispatch in %s\n", _DBUS_FUNCTION_NAME);
02407 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02408 dbus_pending_call_unref (pending);
02409 return;
02410 }
02411
02412 if (status == DBUS_DISPATCH_DATA_REMAINS)
02413 {
02414 if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
02415 return;
02416 }
02417
02418 _dbus_get_current_time (&tv_sec, &tv_usec);
02419 elapsed_milliseconds = (tv_sec - start_tv_sec) * 1000 +
02420 (tv_usec - start_tv_usec) / 1000;
02421
02422 if (!_dbus_connection_get_is_connected_unlocked (connection))
02423 {
02424 DBusMessage *error_msg;
02425
02426 error_msg = generate_local_error_message (client_serial,
02427 DBUS_ERROR_DISCONNECTED,
02428 "Connection was disconnected before a reply was received");
02429
02430
02431 complete_pending_call_and_unlock (connection, pending, error_msg);
02432 dbus_pending_call_unref (pending);
02433 return;
02434 }
02435 else if (connection->disconnect_message_link == NULL)
02436 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
02437 else if (timeout == NULL)
02438 {
02439 if (status == DBUS_DISPATCH_NEED_MEMORY)
02440 {
02441
02442
02443
02444
02445 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02446
02447 _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
02448 }
02449 else
02450 {
02451
02452 _dbus_connection_do_iteration_unlocked (connection,
02453 pending,
02454 DBUS_ITERATION_DO_READING |
02455 DBUS_ITERATION_BLOCK,
02456 timeout_milliseconds);
02457 }
02458
02459 goto recheck_status;
02460 }
02461 else if (tv_sec < start_tv_sec)
02462 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
02463 else if (elapsed_milliseconds < timeout_milliseconds)
02464 {
02465 timeout_milliseconds -= elapsed_milliseconds;
02466 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds);
02467 _dbus_assert (timeout_milliseconds >= 0);
02468
02469 if (status == DBUS_DISPATCH_NEED_MEMORY)
02470 {
02471
02472
02473
02474
02475 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02476
02477 _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
02478 }
02479 else
02480 {
02481
02482 _dbus_connection_do_iteration_unlocked (connection,
02483 NULL,
02484 DBUS_ITERATION_DO_READING |
02485 DBUS_ITERATION_BLOCK,
02486 timeout_milliseconds);
02487 }
02488
02489 goto recheck_status;
02490 }
02491
02492 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %ld milliseconds and got no reply\n",
02493 (tv_sec - start_tv_sec) * 1000 + (tv_usec - start_tv_usec) / 1000);
02494
02495 _dbus_assert (!_dbus_pending_call_get_completed_unlocked (pending));
02496
02497
02498 complete_pending_call_and_unlock (connection, pending, NULL);
02499
02500
02501 CONNECTION_LOCK (connection);
02502 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02503 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02504 dbus_pending_call_unref (pending);
02505 }
02506
02543 DBusConnection*
02544 dbus_connection_open (const char *address,
02545 DBusError *error)
02546 {
02547 DBusConnection *connection;
02548
02549 _dbus_return_val_if_fail (address != NULL, NULL);
02550 _dbus_return_val_if_error_is_set (error, NULL);
02551
02552 connection = _dbus_connection_open_internal (address,
02553 TRUE,
02554 error);
02555
02556 return connection;
02557 }
02558
02586 DBusConnection*
02587 dbus_connection_open_private (const char *address,
02588 DBusError *error)
02589 {
02590 DBusConnection *connection;
02591
02592 _dbus_return_val_if_fail (address != NULL, NULL);
02593 _dbus_return_val_if_error_is_set (error, NULL);
02594
02595 connection = _dbus_connection_open_internal (address,
02596 FALSE,
02597 error);
02598
02599 return connection;
02600 }
02601
02608 DBusConnection *
02609 dbus_connection_ref (DBusConnection *connection)
02610 {
02611 _dbus_return_val_if_fail (connection != NULL, NULL);
02612 _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
02613
02614
02615
02616
02617
02618 #ifdef DBUS_HAVE_ATOMIC_INT
02619 _dbus_atomic_inc (&connection->refcount);
02620 #else
02621 CONNECTION_LOCK (connection);
02622 _dbus_assert (connection->refcount.value > 0);
02623
02624 connection->refcount.value += 1;
02625 CONNECTION_UNLOCK (connection);
02626 #endif
02627
02628 return connection;
02629 }
02630
02631 static void
02632 free_outgoing_message (void *element,
02633 void *data)
02634 {
02635 DBusMessage *message = element;
02636 DBusConnection *connection = data;
02637
02638 _dbus_message_remove_size_counter (message,
02639 connection->outgoing_counter,
02640 NULL);
02641 dbus_message_unref (message);
02642 }
02643
02644
02645
02646
02647
02648 static void
02649 _dbus_connection_last_unref (DBusConnection *connection)
02650 {
02651 DBusList *link;
02652
02653 _dbus_verbose ("Finalizing connection %p\n", connection);
02654
02655 _dbus_assert (connection->refcount.value == 0);
02656
02657
02658
02659
02660 _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
02661 _dbus_assert (connection->server_guid == NULL);
02662
02663
02664 _dbus_object_tree_free_all_unlocked (connection->objects);
02665
02666 dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
02667 dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
02668 dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
02669
02670 _dbus_watch_list_free (connection->watches);
02671 connection->watches = NULL;
02672
02673 _dbus_timeout_list_free (connection->timeouts);
02674 connection->timeouts = NULL;
02675
02676 _dbus_data_slot_list_free (&connection->slot_list);
02677
02678 link = _dbus_list_get_first_link (&connection->filter_list);
02679 while (link != NULL)
02680 {
02681 DBusMessageFilter *filter = link->data;
02682 DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
02683
02684 filter->function = NULL;
02685 _dbus_message_filter_unref (filter);
02686 link->data = NULL;
02687
02688 link = next;
02689 }
02690 _dbus_list_clear (&connection->filter_list);
02691
02692
02693
02694 _dbus_object_tree_unref (connection->objects);
02695
02696 _dbus_hash_table_unref (connection->pending_replies);
02697 connection->pending_replies = NULL;
02698
02699 _dbus_list_clear (&connection->filter_list);
02700
02701 _dbus_list_foreach (&connection->outgoing_messages,
02702 free_outgoing_message,
02703 connection);
02704 _dbus_list_clear (&connection->outgoing_messages);
02705
02706 _dbus_list_foreach (&connection->incoming_messages,
02707 (DBusForeachFunction) dbus_message_unref,
02708 NULL);
02709 _dbus_list_clear (&connection->incoming_messages);
02710
02711 _dbus_counter_unref (connection->outgoing_counter);
02712
02713 _dbus_transport_unref (connection->transport);
02714
02715 if (connection->disconnect_message_link)
02716 {
02717 DBusMessage *message = connection->disconnect_message_link->data;
02718 dbus_message_unref (message);
02719 _dbus_list_free_link (connection->disconnect_message_link);
02720 }
02721
02722 _dbus_list_clear (&connection->link_cache);
02723
02724 _dbus_condvar_free_at_location (&connection->dispatch_cond);
02725 _dbus_condvar_free_at_location (&connection->io_path_cond);
02726
02727 _dbus_mutex_free_at_location (&connection->io_path_mutex);
02728 _dbus_mutex_free_at_location (&connection->dispatch_mutex);
02729
02730 _dbus_mutex_free_at_location (&connection->mutex);
02731
02732 dbus_free (connection);
02733 }
02734
02754 void
02755 dbus_connection_unref (DBusConnection *connection)
02756 {
02757 dbus_bool_t last_unref;
02758
02759 _dbus_return_if_fail (connection != NULL);
02760 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02761
02762
02763
02764
02765
02766 #ifdef DBUS_HAVE_ATOMIC_INT
02767 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
02768 #else
02769 CONNECTION_LOCK (connection);
02770
02771 _dbus_assert (connection->refcount.value > 0);
02772
02773 connection->refcount.value -= 1;
02774 last_unref = (connection->refcount.value == 0);
02775
02776 #if 0
02777 printf ("unref() connection %p count = %d\n", connection, connection->refcount.value);
02778 #endif
02779
02780 CONNECTION_UNLOCK (connection);
02781 #endif
02782
02783 if (last_unref)
02784 {
02785 #ifndef DBUS_DISABLE_CHECKS
02786 if (_dbus_transport_get_is_connected (connection->transport))
02787 {
02788 _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",
02789 connection->shareable ?
02790 "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" :
02791 "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n");
02792 return;
02793 }
02794 #endif
02795 _dbus_connection_last_unref (connection);
02796 }
02797 }
02798
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808 static void
02809 _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection)
02810 {
02811 DBusDispatchStatus status;
02812
02813 HAVE_LOCK_CHECK (connection);
02814
02815 _dbus_verbose ("Disconnecting %p\n", connection);
02816
02817
02818
02819
02820
02821 _dbus_connection_ref_unlocked (connection);
02822
02823 _dbus_transport_disconnect (connection->transport);
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02835
02836
02837 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02838
02839
02840 dbus_connection_unref (connection);
02841 }
02842
02885 void
02886 dbus_connection_close (DBusConnection *connection)
02887 {
02888 _dbus_return_if_fail (connection != NULL);
02889 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
02890
02891 CONNECTION_LOCK (connection);
02892
02893 #ifndef DBUS_DISABLE_CHECKS
02894 if (connection->shareable)
02895 {
02896 CONNECTION_UNLOCK (connection);
02897
02898 _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n");
02899 return;
02900 }
02901 #endif
02902
02903 _dbus_connection_close_possibly_shared_and_unlock (connection);
02904 }
02905
02906 static dbus_bool_t
02907 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
02908 {
02909 HAVE_LOCK_CHECK (connection);
02910 return _dbus_transport_get_is_connected (connection->transport);
02911 }
02912
02926 dbus_bool_t
02927 dbus_connection_get_is_connected (DBusConnection *connection)
02928 {
02929 dbus_bool_t res;
02930
02931 _dbus_return_val_if_fail (connection != NULL, FALSE);
02932
02933 CONNECTION_LOCK (connection);
02934 res = _dbus_connection_get_is_connected_unlocked (connection);
02935 CONNECTION_UNLOCK (connection);
02936
02937 return res;
02938 }
02939
02948 dbus_bool_t
02949 dbus_connection_get_is_authenticated (DBusConnection *connection)
02950 {
02951 dbus_bool_t res;
02952
02953 _dbus_return_val_if_fail (connection != NULL, FALSE);
02954
02955 CONNECTION_LOCK (connection);
02956 res = _dbus_transport_get_is_authenticated (connection->transport);
02957 CONNECTION_UNLOCK (connection);
02958
02959 return res;
02960 }
02961
02982 dbus_bool_t
02983 dbus_connection_get_is_anonymous (DBusConnection *connection)
02984 {
02985 dbus_bool_t res;
02986
02987 _dbus_return_val_if_fail (connection != NULL, FALSE);
02988
02989 CONNECTION_LOCK (connection);
02990 res = _dbus_transport_get_is_anonymous (connection->transport);
02991 CONNECTION_UNLOCK (connection);
02992
02993 return res;
02994 }
02995
03027 char*
03028 dbus_connection_get_server_id (DBusConnection *connection)
03029 {
03030 char *id;
03031
03032 _dbus_return_val_if_fail (connection != NULL, NULL);
03033
03034 CONNECTION_LOCK (connection);
03035 id = _dbus_strdup (_dbus_transport_get_server_id (connection->transport));
03036 CONNECTION_UNLOCK (connection);
03037
03038 return id;
03039 }
03040
03054 void
03055 dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
03056 dbus_bool_t exit_on_disconnect)
03057 {
03058 _dbus_return_if_fail (connection != NULL);
03059
03060 CONNECTION_LOCK (connection);
03061 connection->exit_on_disconnect = exit_on_disconnect != FALSE;
03062 CONNECTION_UNLOCK (connection);
03063 }
03064
03074 DBusPreallocatedSend*
03075 dbus_connection_preallocate_send (DBusConnection *connection)
03076 {
03077 DBusPreallocatedSend *preallocated;
03078
03079 _dbus_return_val_if_fail (connection != NULL, NULL);
03080
03081 CONNECTION_LOCK (connection);
03082
03083 preallocated =
03084 _dbus_connection_preallocate_send_unlocked (connection);
03085
03086 CONNECTION_UNLOCK (connection);
03087
03088 return preallocated;
03089 }
03090
03100 void
03101 dbus_connection_free_preallocated_send (DBusConnection *connection,
03102 DBusPreallocatedSend *preallocated)
03103 {
03104 _dbus_return_if_fail (connection != NULL);
03105 _dbus_return_if_fail (preallocated != NULL);
03106 _dbus_return_if_fail (connection == preallocated->connection);
03107
03108 _dbus_list_free_link (preallocated->queue_link);
03109 _dbus_counter_unref (preallocated->counter_link->data);
03110 _dbus_list_free_link (preallocated->counter_link);
03111 dbus_free (preallocated);
03112 }
03113
03126 void
03127 dbus_connection_send_preallocated (DBusConnection *connection,
03128 DBusPreallocatedSend *preallocated,
03129 DBusMessage *message,
03130 dbus_uint32_t *client_serial)
03131 {
03132 _dbus_return_if_fail (connection != NULL);
03133 _dbus_return_if_fail (preallocated != NULL);
03134 _dbus_return_if_fail (message != NULL);
03135 _dbus_return_if_fail (preallocated->connection == connection);
03136 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
03137 dbus_message_get_member (message) != NULL);
03138 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
03139 (dbus_message_get_interface (message) != NULL &&
03140 dbus_message_get_member (message) != NULL));
03141
03142 CONNECTION_LOCK (connection);
03143 _dbus_connection_send_preallocated_and_unlock (connection,
03144 preallocated,
03145 message, client_serial);
03146 }
03147
03148 static dbus_bool_t
03149 _dbus_connection_send_unlocked_no_update (DBusConnection *connection,
03150 DBusMessage *message,
03151 dbus_uint32_t *client_serial)
03152 {
03153 DBusPreallocatedSend *preallocated;
03154
03155 _dbus_assert (connection != NULL);
03156 _dbus_assert (message != NULL);
03157
03158 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
03159 if (preallocated == NULL)
03160 return FALSE;
03161
03162 _dbus_connection_send_preallocated_unlocked_no_update (connection,
03163 preallocated,
03164 message,
03165 client_serial);
03166 return TRUE;
03167 }
03168
03196 dbus_bool_t
03197 dbus_connection_send (DBusConnection *connection,
03198 DBusMessage *message,
03199 dbus_uint32_t *serial)
03200 {
03201 _dbus_return_val_if_fail (connection != NULL, FALSE);
03202 _dbus_return_val_if_fail (message != NULL, FALSE);
03203
03204 CONNECTION_LOCK (connection);
03205
03206 return _dbus_connection_send_and_unlock (connection,
03207 message,
03208 serial);
03209 }
03210
03211 static dbus_bool_t
03212 reply_handler_timeout (void *data)
03213 {
03214 DBusConnection *connection;
03215 DBusDispatchStatus status;
03216 DBusPendingCall *pending = data;
03217
03218 connection = _dbus_pending_call_get_connection_and_lock (pending);
03219
03220 _dbus_pending_call_queue_timeout_error_unlocked (pending,
03221 connection);
03222 _dbus_connection_remove_timeout_unlocked (connection,
03223 _dbus_pending_call_get_timeout_unlocked (pending));
03224 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
03225
03226 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
03227 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03228
03229
03230 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03231
03232 return TRUE;
03233 }
03234
03270 dbus_bool_t
03271 dbus_connection_send_with_reply (DBusConnection *connection,
03272 DBusMessage *message,
03273 DBusPendingCall **pending_return,
03274 int timeout_milliseconds)
03275 {
03276 DBusPendingCall *pending;
03277 dbus_int32_t serial = -1;
03278 DBusDispatchStatus status;
03279
03280 _dbus_return_val_if_fail (connection != NULL, FALSE);
03281 _dbus_return_val_if_fail (message != NULL, FALSE);
03282 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03283
03284 if (pending_return)
03285 *pending_return = NULL;
03286
03287 CONNECTION_LOCK (connection);
03288
03289 if (!_dbus_connection_get_is_connected_unlocked (connection))
03290 {
03291 CONNECTION_UNLOCK (connection);
03292
03293 return TRUE;
03294 }
03295
03296 pending = _dbus_pending_call_new_unlocked (connection,
03297 timeout_milliseconds,
03298 reply_handler_timeout);
03299
03300 if (pending == NULL)
03301 {
03302 CONNECTION_UNLOCK (connection);
03303 return FALSE;
03304 }
03305
03306
03307 serial = dbus_message_get_serial (message);
03308 if (serial == 0)
03309 {
03310 serial = _dbus_connection_get_next_client_serial (connection);
03311 dbus_message_set_serial (message, serial);
03312 }
03313
03314 if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
03315 goto error;
03316
03317
03318
03319
03320
03321 if (!_dbus_connection_attach_pending_call_unlocked (connection,
03322 pending))
03323 goto error;
03324
03325 if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
03326 {
03327 _dbus_connection_detach_pending_call_and_unlock (connection,
03328 pending);
03329 goto error_unlocked;
03330 }
03331
03332 if (pending_return)
03333 *pending_return = pending;
03334 else
03335 {
03336 _dbus_connection_detach_pending_call_unlocked (connection, pending);
03337
03338
03339
03340 }
03341
03342 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03343
03344
03345 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03346
03347 if (pending_return == NULL)
03348 dbus_pending_call_unref (pending);
03349
03350 return TRUE;
03351
03352 error:
03353 CONNECTION_UNLOCK (connection);
03354 error_unlocked:
03355 dbus_pending_call_unref (pending);
03356 return FALSE;
03357 }
03358
03389 DBusMessage*
03390 dbus_connection_send_with_reply_and_block (DBusConnection *connection,
03391 DBusMessage *message,
03392 int timeout_milliseconds,
03393 DBusError *error)
03394 {
03395 DBusMessage *reply;
03396 DBusPendingCall *pending;
03397
03398 _dbus_return_val_if_fail (connection != NULL, NULL);
03399 _dbus_return_val_if_fail (message != NULL, NULL);
03400 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL);
03401 _dbus_return_val_if_error_is_set (error, NULL);
03402
03403 if (!dbus_connection_send_with_reply (connection, message,
03404 &pending, timeout_milliseconds))
03405 {
03406 _DBUS_SET_OOM (error);
03407 return NULL;
03408 }
03409
03410 if (pending == NULL)
03411 {
03412 dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Connection is closed");
03413 return NULL;
03414 }
03415
03416 dbus_pending_call_block (pending);
03417
03418 reply = dbus_pending_call_steal_reply (pending);
03419 dbus_pending_call_unref (pending);
03420
03421
03422
03423
03424 _dbus_assert (reply != NULL);
03425
03426 if (dbus_set_error_from_message (error, reply))
03427 {
03428 dbus_message_unref (reply);
03429 return NULL;
03430 }
03431 else
03432 return reply;
03433 }
03434
03443 static DBusDispatchStatus
03444 _dbus_connection_flush_unlocked (DBusConnection *connection)
03445 {
03446
03447
03448
03449
03450
03451 DBusDispatchStatus status;
03452
03453 HAVE_LOCK_CHECK (connection);
03454
03455 while (connection->n_outgoing > 0 &&
03456 _dbus_connection_get_is_connected_unlocked (connection))
03457 {
03458 _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME);
03459 HAVE_LOCK_CHECK (connection);
03460 _dbus_connection_do_iteration_unlocked (connection,
03461 NULL,
03462 DBUS_ITERATION_DO_READING |
03463 DBUS_ITERATION_DO_WRITING |
03464 DBUS_ITERATION_BLOCK,
03465 -1);
03466 }
03467
03468 HAVE_LOCK_CHECK (connection);
03469 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
03470 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03471
03472 HAVE_LOCK_CHECK (connection);
03473 return status;
03474 }
03475
03481 void
03482 dbus_connection_flush (DBusConnection *connection)
03483 {
03484
03485
03486
03487
03488
03489 DBusDispatchStatus status;
03490
03491 _dbus_return_if_fail (connection != NULL);
03492
03493 CONNECTION_LOCK (connection);
03494
03495 status = _dbus_connection_flush_unlocked (connection);
03496
03497 HAVE_LOCK_CHECK (connection);
03498
03499 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03500
03501 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
03502 }
03503
03514 static dbus_bool_t
03515 _dbus_connection_read_write_dispatch (DBusConnection *connection,
03516 int timeout_milliseconds,
03517 dbus_bool_t dispatch)
03518 {
03519 DBusDispatchStatus dstatus;
03520 dbus_bool_t progress_possible;
03521
03522
03523
03524
03525
03526 dbus_connection_ref (connection);
03527 dstatus = dbus_connection_get_dispatch_status (connection);
03528
03529 if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
03530 {
03531 _dbus_verbose ("doing dispatch in %s\n", _DBUS_FUNCTION_NAME);
03532 dbus_connection_dispatch (connection);
03533 CONNECTION_LOCK (connection);
03534 }
03535 else if (dstatus == DBUS_DISPATCH_NEED_MEMORY)
03536 {
03537 _dbus_verbose ("pausing for memory in %s\n", _DBUS_FUNCTION_NAME);
03538 _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
03539 CONNECTION_LOCK (connection);
03540 }
03541 else
03542 {
03543 CONNECTION_LOCK (connection);
03544 if (_dbus_connection_get_is_connected_unlocked (connection))
03545 {
03546 _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME);
03547 _dbus_connection_do_iteration_unlocked (connection,
03548 NULL,
03549 DBUS_ITERATION_DO_READING |
03550 DBUS_ITERATION_DO_WRITING |
03551 DBUS_ITERATION_BLOCK,
03552 timeout_milliseconds);
03553 }
03554 }
03555
03556 HAVE_LOCK_CHECK (connection);
03557
03558
03559
03560
03561 if (dispatch)
03562 progress_possible = connection->n_incoming != 0 ||
03563 connection->disconnect_message_link != NULL;
03564 else
03565 progress_possible = _dbus_connection_get_is_connected_unlocked (connection);
03566
03567 CONNECTION_UNLOCK (connection);
03568
03569 dbus_connection_unref (connection);
03570
03571 return progress_possible;
03572 }
03573
03574
03609 dbus_bool_t
03610 dbus_connection_read_write_dispatch (DBusConnection *connection,
03611 int timeout_milliseconds)
03612 {
03613 _dbus_return_val_if_fail (connection != NULL, FALSE);
03614 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03615 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE);
03616 }
03617
03641 dbus_bool_t
03642 dbus_connection_read_write (DBusConnection *connection,
03643 int timeout_milliseconds)
03644 {
03645 _dbus_return_val_if_fail (connection != NULL, FALSE);
03646 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
03647 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE);
03648 }
03649
03650
03651
03652
03653
03654
03655 static void
03656 check_disconnected_message_arrived_unlocked (DBusConnection *connection,
03657 DBusMessage *head_of_queue)
03658 {
03659 HAVE_LOCK_CHECK (connection);
03660
03661
03662 if (connection->disconnect_message_link == NULL &&
03663 dbus_message_is_signal (head_of_queue,
03664 DBUS_INTERFACE_LOCAL,
03665 "Disconnected"))
03666 {
03667 connection->disconnected_message_arrived = TRUE;
03668 }
03669 }
03670
03690 DBusMessage*
03691 dbus_connection_borrow_message (DBusConnection *connection)
03692 {
03693 DBusDispatchStatus status;
03694 DBusMessage *message;
03695
03696 _dbus_return_val_if_fail (connection != NULL, NULL);
03697
03698 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
03699
03700
03701
03702
03703 status = dbus_connection_get_dispatch_status (connection);
03704 if (status != DBUS_DISPATCH_DATA_REMAINS)
03705 return NULL;
03706
03707 CONNECTION_LOCK (connection);
03708
03709 _dbus_connection_acquire_dispatch (connection);
03710
03711
03712 _dbus_assert (connection->message_borrowed == NULL);
03713
03714 connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
03715
03716 message = connection->message_borrowed;
03717
03718 check_disconnected_message_arrived_unlocked (connection, message);
03719
03720
03721 if (message == NULL)
03722 _dbus_connection_release_dispatch (connection);
03723
03724 CONNECTION_UNLOCK (connection);
03725
03726
03727
03728 return message;
03729 }
03730
03739 void
03740 dbus_connection_return_message (DBusConnection *connection,
03741 DBusMessage *message)
03742 {
03743 DBusDispatchStatus status;
03744
03745 _dbus_return_if_fail (connection != NULL);
03746 _dbus_return_if_fail (message != NULL);
03747 _dbus_return_if_fail (message == connection->message_borrowed);
03748 _dbus_return_if_fail (connection->dispatch_acquired);
03749
03750 CONNECTION_LOCK (connection);
03751
03752 _dbus_assert (message == connection->message_borrowed);
03753
03754 connection->message_borrowed = NULL;
03755
03756 _dbus_connection_release_dispatch (connection);
03757
03758 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03759 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03760 }
03761
03771 void
03772 dbus_connection_steal_borrowed_message (DBusConnection *connection,
03773 DBusMessage *message)
03774 {
03775 DBusMessage *pop_message;
03776 DBusDispatchStatus status;
03777
03778 _dbus_return_if_fail (connection != NULL);
03779 _dbus_return_if_fail (message != NULL);
03780 _dbus_return_if_fail (message == connection->message_borrowed);
03781 _dbus_return_if_fail (connection->dispatch_acquired);
03782
03783 CONNECTION_LOCK (connection);
03784
03785 _dbus_assert (message == connection->message_borrowed);
03786
03787 pop_message = _dbus_list_pop_first (&connection->incoming_messages);
03788 _dbus_assert (message == pop_message);
03789
03790 connection->n_incoming -= 1;
03791
03792 _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
03793 message, connection->n_incoming);
03794
03795 connection->message_borrowed = NULL;
03796
03797 _dbus_connection_release_dispatch (connection);
03798
03799 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03800 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03801 }
03802
03803
03804
03805
03806 static DBusList*
03807 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
03808 {
03809 HAVE_LOCK_CHECK (connection);
03810
03811 _dbus_assert (connection->message_borrowed == NULL);
03812
03813 if (connection->n_incoming > 0)
03814 {
03815 DBusList *link;
03816
03817 link = _dbus_list_pop_first_link (&connection->incoming_messages);
03818 connection->n_incoming -= 1;
03819
03820 _dbus_verbose ("Message %p (%d %s %s %s '%s') removed from incoming queue %p, %d incoming\n",
03821 link->data,
03822 dbus_message_get_type (link->data),
03823 dbus_message_get_path (link->data) ?
03824 dbus_message_get_path (link->data) :
03825 "no path",
03826 dbus_message_get_interface (link->data) ?
03827 dbus_message_get_interface (link->data) :
03828 "no interface",
03829 dbus_message_get_member (link->data) ?
03830 dbus_message_get_member (link->data) :
03831 "no member",
03832 dbus_message_get_signature (link->data),
03833 connection, connection->n_incoming);
03834
03835 check_disconnected_message_arrived_unlocked (connection, link->data);
03836
03837 return link;
03838 }
03839 else
03840 return NULL;
03841 }
03842
03843
03844
03845
03846 static DBusMessage*
03847 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
03848 {
03849 DBusList *link;
03850
03851 HAVE_LOCK_CHECK (connection);
03852
03853 link = _dbus_connection_pop_message_link_unlocked (connection);
03854
03855 if (link != NULL)
03856 {
03857 DBusMessage *message;
03858
03859 message = link->data;
03860
03861 _dbus_list_free_link (link);
03862
03863 return message;
03864 }
03865 else
03866 return NULL;
03867 }
03868
03869 static void
03870 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
03871 DBusList *message_link)
03872 {
03873 HAVE_LOCK_CHECK (connection);
03874
03875 _dbus_assert (message_link != NULL);
03876
03877 _dbus_assert (connection->message_borrowed == NULL);
03878
03879 _dbus_assert (connection->dispatch_acquired);
03880
03881 _dbus_list_prepend_link (&connection->incoming_messages,
03882 message_link);
03883 connection->n_incoming += 1;
03884
03885 _dbus_verbose ("Message %p (%d %s %s '%s') put back into queue %p, %d incoming\n",
03886 message_link->data,
03887 dbus_message_get_type (message_link->data),
03888 dbus_message_get_interface (message_link->data) ?
03889 dbus_message_get_interface (message_link->data) :
03890 "no interface",
03891 dbus_message_get_member (message_link->data) ?
03892 dbus_message_get_member (message_link->data) :
03893 "no member",
03894 dbus_message_get_signature (message_link->data),
03895 connection, connection->n_incoming);
03896 }
03897
03917 DBusMessage*
03918 dbus_connection_pop_message (DBusConnection *connection)
03919 {
03920 DBusMessage *message;
03921 DBusDispatchStatus status;
03922
03923 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
03924
03925
03926
03927
03928 status = dbus_connection_get_dispatch_status (connection);
03929 if (status != DBUS_DISPATCH_DATA_REMAINS)
03930 return NULL;
03931
03932 CONNECTION_LOCK (connection);
03933 _dbus_connection_acquire_dispatch (connection);
03934 HAVE_LOCK_CHECK (connection);
03935
03936 message = _dbus_connection_pop_message_unlocked (connection);
03937
03938 _dbus_verbose ("Returning popped message %p\n", message);
03939
03940 _dbus_connection_release_dispatch (connection);
03941
03942 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03943 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03944
03945 return message;
03946 }
03947
03955 static void
03956 _dbus_connection_acquire_dispatch (DBusConnection *connection)
03957 {
03958 HAVE_LOCK_CHECK (connection);
03959
03960 _dbus_connection_ref_unlocked (connection);
03961 CONNECTION_UNLOCK (connection);
03962
03963 _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03964 _dbus_mutex_lock (connection->dispatch_mutex);
03965
03966 while (connection->dispatch_acquired)
03967 {
03968 _dbus_verbose ("%s waiting for dispatch to be acquirable\n", _DBUS_FUNCTION_NAME);
03969 _dbus_condvar_wait (connection->dispatch_cond,
03970 connection->dispatch_mutex);
03971 }
03972
03973 _dbus_assert (!connection->dispatch_acquired);
03974
03975 connection->dispatch_acquired = TRUE;
03976
03977 _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03978 _dbus_mutex_unlock (connection->dispatch_mutex);
03979
03980 CONNECTION_LOCK (connection);
03981 _dbus_connection_unref_unlocked (connection);
03982 }
03983
03991 static void
03992 _dbus_connection_release_dispatch (DBusConnection *connection)
03993 {
03994 HAVE_LOCK_CHECK (connection);
03995
03996 _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
03997 _dbus_mutex_lock (connection->dispatch_mutex);
03998
03999 _dbus_assert (connection->dispatch_acquired);
04000
04001 connection->dispatch_acquired = FALSE;
04002 _dbus_condvar_wake_one (connection->dispatch_cond);
04003
04004 _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
04005 _dbus_mutex_unlock (connection->dispatch_mutex);
04006 }
04007
04008 static void
04009 _dbus_connection_failed_pop (DBusConnection *connection,
04010 DBusList *message_link)
04011 {
04012 _dbus_list_prepend_link (&connection->incoming_messages,
04013 message_link);
04014 connection->n_incoming += 1;
04015 }
04016
04017
04018 static void
04019 notify_disconnected_unlocked (DBusConnection *connection)
04020 {
04021 HAVE_LOCK_CHECK (connection);
04022
04023
04024
04025
04026
04027
04028
04029 _dbus_bus_notify_shared_connection_disconnected_unlocked (connection);
04030
04031
04032
04033
04034
04035 if (connection->n_outgoing > 0)
04036 {
04037 DBusList *link;
04038
04039 _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
04040 connection->n_outgoing);
04041
04042 while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
04043 {
04044 _dbus_connection_message_sent (connection, link->data);
04045 }
04046 }
04047 }
04048
04049
04050 static DBusDispatchStatus
04051 notify_disconnected_and_dispatch_complete_unlocked (DBusConnection *connection)
04052 {
04053 HAVE_LOCK_CHECK (connection);
04054
04055 if (connection->disconnect_message_link != NULL)
04056 {
04057 _dbus_verbose ("Sending disconnect message from %s\n",
04058 _DBUS_FUNCTION_NAME);
04059
04060
04061
04062
04063 connection_timeout_and_complete_all_pending_calls_unlocked (connection);
04064
04065
04066
04067
04068 _dbus_connection_queue_synthesized_message_link (connection,
04069 connection->disconnect_message_link);
04070 connection->disconnect_message_link = NULL;
04071
04072 return DBUS_DISPATCH_DATA_REMAINS;
04073 }
04074
04075 return DBUS_DISPATCH_COMPLETE;
04076 }
04077
04078 static DBusDispatchStatus
04079 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
04080 {
04081 HAVE_LOCK_CHECK (connection);
04082
04083 if (connection->n_incoming > 0)
04084 return DBUS_DISPATCH_DATA_REMAINS;
04085 else if (!_dbus_transport_queue_messages (connection->transport))
04086 return DBUS_DISPATCH_NEED_MEMORY;
04087 else
04088 {
04089 DBusDispatchStatus status;
04090 dbus_bool_t is_connected;
04091
04092 status = _dbus_transport_get_dispatch_status (connection->transport);
04093 is_connected = _dbus_transport_get_is_connected (connection->transport);
04094
04095 _dbus_verbose ("dispatch status = %s is_connected = %d\n",
04096 DISPATCH_STATUS_NAME (status), is_connected);
04097
04098 if (!is_connected)
04099 {
04100
04101
04102
04103
04104
04105
04106 notify_disconnected_unlocked (connection);
04107
04108
04109
04110
04111
04112
04113 if (status == DBUS_DISPATCH_COMPLETE)
04114 status = notify_disconnected_and_dispatch_complete_unlocked (connection);
04115 }
04116
04117 if (status != DBUS_DISPATCH_COMPLETE)
04118 return status;
04119 else if (connection->n_incoming > 0)
04120 return DBUS_DISPATCH_DATA_REMAINS;
04121 else
04122 return DBUS_DISPATCH_COMPLETE;
04123 }
04124 }
04125
04126 static void
04127 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
04128 DBusDispatchStatus new_status)
04129 {
04130 dbus_bool_t changed;
04131 DBusDispatchStatusFunction function;
04132 void *data;
04133
04134 HAVE_LOCK_CHECK (connection);
04135
04136 _dbus_connection_ref_unlocked (connection);
04137
04138 changed = new_status != connection->last_dispatch_status;
04139
04140 connection->last_dispatch_status = new_status;
04141
04142 function = connection->dispatch_status_function;
04143 data = connection->dispatch_status_data;
04144
04145 if (connection->disconnected_message_arrived &&
04146 !connection->disconnected_message_processed)
04147 {
04148 connection->disconnected_message_processed = TRUE;
04149
04150
04151
04152
04153
04154 connection_forget_shared_unlocked (connection);
04155
04156 if (connection->exit_on_disconnect)
04157 {
04158 CONNECTION_UNLOCK (connection);
04159
04160 _dbus_verbose ("Exiting on Disconnected signal\n");
04161 _dbus_exit (1);
04162 _dbus_assert_not_reached ("Call to exit() returned");
04163 }
04164 }
04165
04166
04167 CONNECTION_UNLOCK (connection);
04168
04169 if (changed && function)
04170 {
04171 _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
04172 connection, new_status,
04173 DISPATCH_STATUS_NAME (new_status));
04174 (* function) (connection, new_status, data);
04175 }
04176
04177 dbus_connection_unref (connection);
04178 }
04179
04205 DBusDispatchStatus
04206 dbus_connection_get_dispatch_status (DBusConnection *connection)
04207 {
04208 DBusDispatchStatus status;
04209
04210 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04211
04212 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
04213
04214 CONNECTION_LOCK (connection);
04215
04216 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04217
04218 CONNECTION_UNLOCK (connection);
04219
04220 return status;
04221 }
04222
04226 static DBusHandlerResult
04227 _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
04228 DBusMessage *message)
04229 {
04230 if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
04231 {
04232
04233 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04234 }
04235 else if (dbus_message_is_method_call (message,
04236 DBUS_INTERFACE_PEER,
04237 "Ping"))
04238 {
04239 DBusMessage *ret;
04240 dbus_bool_t sent;
04241
04242 ret = dbus_message_new_method_return (message);
04243 if (ret == NULL)
04244 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04245
04246 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04247
04248 dbus_message_unref (ret);
04249
04250 if (!sent)
04251 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04252
04253 return DBUS_HANDLER_RESULT_HANDLED;
04254 }
04255 else if (dbus_message_is_method_call (message,
04256 DBUS_INTERFACE_PEER,
04257 "GetMachineId"))
04258 {
04259 DBusMessage *ret;
04260 dbus_bool_t sent;
04261 DBusString uuid;
04262
04263 ret = dbus_message_new_method_return (message);
04264 if (ret == NULL)
04265 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04266
04267 sent = FALSE;
04268 _dbus_string_init (&uuid);
04269 if (_dbus_get_local_machine_uuid_encoded (&uuid))
04270 {
04271 const char *v_STRING = _dbus_string_get_const_data (&uuid);
04272 if (dbus_message_append_args (ret,
04273 DBUS_TYPE_STRING, &v_STRING,
04274 DBUS_TYPE_INVALID))
04275 {
04276 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04277 }
04278 }
04279 _dbus_string_free (&uuid);
04280
04281 dbus_message_unref (ret);
04282
04283 if (!sent)
04284 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04285
04286 return DBUS_HANDLER_RESULT_HANDLED;
04287 }
04288 else if (dbus_message_has_interface (message, DBUS_INTERFACE_PEER))
04289 {
04290
04291
04292
04293
04294
04295 DBusMessage *ret;
04296 dbus_bool_t sent;
04297
04298 ret = dbus_message_new_error (message,
04299 DBUS_ERROR_UNKNOWN_METHOD,
04300 "Unknown method invoked on org.freedesktop.DBus.Peer interface");
04301 if (ret == NULL)
04302 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04303
04304 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
04305
04306 dbus_message_unref (ret);
04307
04308 if (!sent)
04309 return DBUS_HANDLER_RESULT_NEED_MEMORY;
04310
04311 return DBUS_HANDLER_RESULT_HANDLED;
04312 }
04313 else
04314 {
04315 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04316 }
04317 }
04318
04325 static DBusHandlerResult
04326 _dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection,
04327 DBusMessage *message)
04328 {
04329
04330
04331
04332 return _dbus_connection_peer_filter_unlocked_no_update (connection, message);
04333 }
04334
04377 DBusDispatchStatus
04378 dbus_connection_dispatch (DBusConnection *connection)
04379 {
04380 DBusMessage *message;
04381 DBusList *link, *filter_list_copy, *message_link;
04382 DBusHandlerResult result;
04383 DBusPendingCall *pending;
04384 dbus_int32_t reply_serial;
04385 DBusDispatchStatus status;
04386
04387 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
04388
04389 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
04390
04391 CONNECTION_LOCK (connection);
04392 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04393 if (status != DBUS_DISPATCH_DATA_REMAINS)
04394 {
04395
04396 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04397 return status;
04398 }
04399
04400
04401
04402
04403 _dbus_connection_ref_unlocked (connection);
04404
04405 _dbus_connection_acquire_dispatch (connection);
04406 HAVE_LOCK_CHECK (connection);
04407
04408 message_link = _dbus_connection_pop_message_link_unlocked (connection);
04409 if (message_link == NULL)
04410 {
04411
04412
04413 _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
04414
04415 _dbus_connection_release_dispatch (connection);
04416
04417 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04418
04419 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04420
04421 dbus_connection_unref (connection);
04422
04423 return status;
04424 }
04425
04426 message = message_link->data;
04427
04428 _dbus_verbose (" dispatching message %p (%d %s %s '%s')\n",
04429 message,
04430 dbus_message_get_type (message),
04431 dbus_message_get_interface (message) ?
04432 dbus_message_get_interface (message) :
04433 "no interface",
04434 dbus_message_get_member (message) ?
04435 dbus_message_get_member (message) :
04436 "no member",
04437 dbus_message_get_signature (message));
04438
04439 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
04440
04441
04442
04443
04444
04445
04446
04447
04448 reply_serial = dbus_message_get_reply_serial (message);
04449 pending = _dbus_hash_table_lookup_int (connection->pending_replies,
04450 reply_serial);
04451 if (pending)
04452 {
04453 _dbus_verbose ("Dispatching a pending reply\n");
04454 complete_pending_call_and_unlock (connection, pending, message);
04455 pending = NULL;
04456
04457 CONNECTION_LOCK (connection);
04458 _dbus_verbose ("pending call completed in dispatch\n");
04459 result = DBUS_HANDLER_RESULT_HANDLED;
04460 goto out;
04461 }
04462
04463 result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message);
04464 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04465 goto out;
04466
04467 if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
04468 {
04469 _dbus_connection_release_dispatch (connection);
04470 HAVE_LOCK_CHECK (connection);
04471
04472 _dbus_connection_failed_pop (connection, message_link);
04473
04474
04475 _dbus_connection_update_dispatch_status_and_unlock (connection,
04476 DBUS_DISPATCH_NEED_MEMORY);
04477
04478 if (pending)
04479 dbus_pending_call_unref (pending);
04480 dbus_connection_unref (connection);
04481
04482 return DBUS_DISPATCH_NEED_MEMORY;
04483 }
04484
04485 _dbus_list_foreach (&filter_list_copy,
04486 (DBusForeachFunction)_dbus_message_filter_ref,
04487 NULL);
04488
04489
04490
04491
04492 CONNECTION_UNLOCK (connection);
04493
04494 link = _dbus_list_get_first_link (&filter_list_copy);
04495 while (link != NULL)
04496 {
04497 DBusMessageFilter *filter = link->data;
04498 DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
04499
04500 if (filter->function == NULL)
04501 {
04502 _dbus_verbose (" filter was removed in a callback function\n");
04503 link = next;
04504 continue;
04505 }
04506
04507 _dbus_verbose (" running filter on message %p\n", message);
04508 result = (* filter->function) (connection, message, filter->user_data);
04509
04510 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04511 break;
04512
04513 link = next;
04514 }
04515
04516 _dbus_list_foreach (&filter_list_copy,
04517 (DBusForeachFunction)_dbus_message_filter_unref,
04518 NULL);
04519 _dbus_list_clear (&filter_list_copy);
04520
04521 CONNECTION_LOCK (connection);
04522
04523 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04524 {
04525 _dbus_verbose ("No memory in %s\n", _DBUS_FUNCTION_NAME);
04526 goto out;
04527 }
04528 else if (result == DBUS_HANDLER_RESULT_HANDLED)
04529 {
04530 _dbus_verbose ("filter handled message in dispatch\n");
04531 goto out;
04532 }
04533
04534
04535
04536
04537 _dbus_verbose (" running object path dispatch on message %p (%d %s %s '%s')\n",
04538 message,
04539 dbus_message_get_type (message),
04540 dbus_message_get_interface (message) ?
04541 dbus_message_get_interface (message) :
04542 "no interface",
04543 dbus_message_get_member (message) ?
04544 dbus_message_get_member (message) :
04545 "no member",
04546 dbus_message_get_signature (message));
04547
04548 HAVE_LOCK_CHECK (connection);
04549 result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
04550 message);
04551
04552 CONNECTION_LOCK (connection);
04553
04554 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
04555 {
04556 _dbus_verbose ("object tree handled message in dispatch\n");
04557 goto out;
04558 }
04559
04560 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
04561 {
04562 DBusMessage *reply;
04563 DBusString str;
04564 DBusPreallocatedSend *preallocated;
04565
04566 _dbus_verbose (" sending error %s\n",
04567 DBUS_ERROR_UNKNOWN_METHOD);
04568
04569 if (!_dbus_string_init (&str))
04570 {
04571 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04572 _dbus_verbose ("no memory for error string in dispatch\n");
04573 goto out;
04574 }
04575
04576 if (!_dbus_string_append_printf (&str,
04577 "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
04578 dbus_message_get_member (message),
04579 dbus_message_get_signature (message),
04580 dbus_message_get_interface (message)))
04581 {
04582 _dbus_string_free (&str);
04583 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04584 _dbus_verbose ("no memory for error string in dispatch\n");
04585 goto out;
04586 }
04587
04588 reply = dbus_message_new_error (message,
04589 DBUS_ERROR_UNKNOWN_METHOD,
04590 _dbus_string_get_const_data (&str));
04591 _dbus_string_free (&str);
04592
04593 if (reply == NULL)
04594 {
04595 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04596 _dbus_verbose ("no memory for error reply in dispatch\n");
04597 goto out;
04598 }
04599
04600 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
04601
04602 if (preallocated == NULL)
04603 {
04604 dbus_message_unref (reply);
04605 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
04606 _dbus_verbose ("no memory for error send in dispatch\n");
04607 goto out;
04608 }
04609
04610 _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
04611 reply, NULL);
04612
04613 dbus_message_unref (reply);
04614
04615 result = DBUS_HANDLER_RESULT_HANDLED;
04616 }
04617
04618 _dbus_verbose (" done dispatching %p (%d %s %s '%s') on connection %p\n", message,
04619 dbus_message_get_type (message),
04620 dbus_message_get_interface (message) ?
04621 dbus_message_get_interface (message) :
04622 "no interface",
04623 dbus_message_get_member (message) ?
04624 dbus_message_get_member (message) :
04625 "no member",
04626 dbus_message_get_signature (message),
04627 connection);
04628
04629 out:
04630 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
04631 {
04632 _dbus_verbose ("out of memory in %s\n", _DBUS_FUNCTION_NAME);
04633
04634
04635
04636
04637
04638 _dbus_connection_putback_message_link_unlocked (connection,
04639 message_link);
04640 }
04641 else
04642 {
04643 _dbus_verbose (" ... done dispatching in %s\n", _DBUS_FUNCTION_NAME);
04644
04645 _dbus_list_free_link (message_link);
04646 dbus_message_unref (message);
04647
04648
04649 }
04650
04651 _dbus_connection_release_dispatch (connection);
04652 HAVE_LOCK_CHECK (connection);
04653
04654 _dbus_verbose ("%s before final status update\n", _DBUS_FUNCTION_NAME);
04655 status = _dbus_connection_get_dispatch_status_unlocked (connection);
04656
04657
04658 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
04659
04660 dbus_connection_unref (connection);
04661
04662 return status;
04663 }
04664
04724 dbus_bool_t
04725 dbus_connection_set_watch_functions (DBusConnection *connection,
04726 DBusAddWatchFunction add_function,
04727 DBusRemoveWatchFunction remove_function,
04728 DBusWatchToggledFunction toggled_function,
04729 void *data,
04730 DBusFreeFunction free_data_function)
04731 {
04732 dbus_bool_t retval;
04733 DBusWatchList *watches;
04734
04735 _dbus_return_val_if_fail (connection != NULL, FALSE);
04736
04737 CONNECTION_LOCK (connection);
04738
04739 #ifndef DBUS_DISABLE_CHECKS
04740 if (connection->watches == NULL)
04741 {
04742 _dbus_warn_check_failed ("Re-entrant call to %s is not allowed\n",
04743 _DBUS_FUNCTION_NAME);
04744 return FALSE;
04745 }
04746 #endif
04747
04748
04749 _dbus_connection_ref_unlocked (connection);
04750
04751
04752
04753
04754
04755 watches = connection->watches;
04756 connection->watches = NULL;
04757 CONNECTION_UNLOCK (connection);
04758
04759 retval = _dbus_watch_list_set_functions (watches,
04760 add_function, remove_function,
04761 toggled_function,
04762 data, free_data_function);
04763 CONNECTION_LOCK (connection);
04764 connection->watches = watches;
04765
04766 CONNECTION_UNLOCK (connection);
04767
04768 dbus_connection_unref (connection);
04769
04770 return retval;
04771 }
04772
04806 dbus_bool_t
04807 dbus_connection_set_timeout_functions (DBusConnection *connection,
04808 DBusAddTimeoutFunction add_function,
04809 DBusRemoveTimeoutFunction remove_function,
04810 DBusTimeoutToggledFunction toggled_function,
04811 void *data,
04812 DBusFreeFunction free_data_function)
04813 {
04814 dbus_bool_t retval;
04815 DBusTimeoutList *timeouts;
04816
04817 _dbus_return_val_if_fail (connection != NULL, FALSE);
04818
04819 CONNECTION_LOCK (connection);
04820
04821 #ifndef DBUS_DISABLE_CHECKS
04822 if (connection->timeouts == NULL)
04823 {
04824 _dbus_warn_check_failed ("Re-entrant call to %s is not allowed\n",
04825 _DBUS_FUNCTION_NAME);
04826 return FALSE;
04827 }
04828 #endif
04829
04830
04831 _dbus_connection_ref_unlocked (connection);
04832
04833 timeouts = connection->timeouts;
04834 connection->timeouts = NULL;
04835 CONNECTION_UNLOCK (connection);
04836
04837 retval = _dbus_timeout_list_set_functions (timeouts,
04838 add_function, remove_function,
04839 toggled_function,
04840 data, free_data_function);
04841 CONNECTION_LOCK (connection);
04842 connection->timeouts = timeouts;
04843
04844 CONNECTION_UNLOCK (connection);
04845
04846 dbus_connection_unref (connection);
04847
04848 return retval;
04849 }
04850
04865 void
04866 dbus_connection_set_wakeup_main_function (DBusConnection *connection,
04867 DBusWakeupMainFunction wakeup_main_function,
04868 void *data,
04869 DBusFreeFunction free_data_function)
04870 {
04871 void *old_data;
04872 DBusFreeFunction old_free_data;
04873
04874 _dbus_return_if_fail (connection != NULL);
04875
04876 CONNECTION_LOCK (connection);
04877 old_data = connection->wakeup_main_data;
04878 old_free_data = connection->free_wakeup_main_data;
04879
04880 connection->wakeup_main_function = wakeup_main_function;
04881 connection->wakeup_main_data = data;
04882 connection->free_wakeup_main_data = free_data_function;
04883
04884 CONNECTION_UNLOCK (connection);
04885
04886
04887 if (old_free_data)
04888 (*old_free_data) (old_data);
04889 }
04890
04911 void
04912 dbus_connection_set_dispatch_status_function (DBusConnection *connection,
04913 DBusDispatchStatusFunction function,
04914 void *data,
04915 DBusFreeFunction free_data_function)
04916 {
04917 void *old_data;
04918 DBusFreeFunction old_free_data;
04919
04920 _dbus_return_if_fail (connection != NULL);
04921
04922 CONNECTION_LOCK (connection);
04923 old_data = connection->dispatch_status_data;
04924 old_free_data = connection->free_dispatch_status_data;
04925
04926 connection->dispatch_status_function = function;
04927 connection->dispatch_status_data = data;
04928 connection->free_dispatch_status_data = free_data_function;
04929
04930 CONNECTION_UNLOCK (connection);
04931
04932
04933 if (old_free_data)
04934 (*old_free_data) (old_data);
04935 }
04936
04956 dbus_bool_t
04957 dbus_connection_get_unix_fd (DBusConnection *connection,
04958 int *fd)
04959 {
04960 _dbus_return_val_if_fail (connection != NULL, FALSE);
04961 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
04962
04963 #ifdef DBUS_WIN
04964
04965 return FALSE;
04966 #endif
04967
04968 return dbus_connection_get_socket(connection, fd);
04969 }
04970
04986 dbus_bool_t
04987 dbus_connection_get_socket(DBusConnection *connection,
04988 int *fd)
04989 {
04990 dbus_bool_t retval;
04991
04992 _dbus_return_val_if_fail (connection != NULL, FALSE);
04993 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
04994
04995 CONNECTION_LOCK (connection);
04996
04997 retval = _dbus_transport_get_socket_fd (connection->transport,
04998 fd);
04999
05000 CONNECTION_UNLOCK (connection);
05001
05002 return retval;
05003 }
05004
05005
05028 dbus_bool_t
05029 dbus_connection_get_unix_user (DBusConnection *connection,
05030 unsigned long *uid)
05031 {
05032 dbus_bool_t result;
05033
05034 _dbus_return_val_if_fail (connection != NULL, FALSE);
05035 _dbus_return_val_if_fail (uid != NULL, FALSE);
05036
05037 CONNECTION_LOCK (connection);
05038
05039 if (!_dbus_transport_get_is_authenticated (connection->transport))
05040 result = FALSE;
05041 else
05042 result = _dbus_transport_get_unix_user (connection->transport,
05043 uid);
05044
05045 #ifdef DBUS_WIN
05046 _dbus_assert (!result);
05047 #endif
05048
05049 CONNECTION_UNLOCK (connection);
05050
05051 return result;
05052 }
05053
05064 dbus_bool_t
05065 dbus_connection_get_unix_process_id (DBusConnection *connection,
05066 unsigned long *pid)
05067 {
05068 dbus_bool_t result;
05069
05070 _dbus_return_val_if_fail (connection != NULL, FALSE);
05071 _dbus_return_val_if_fail (pid != NULL, FALSE);
05072
05073 CONNECTION_LOCK (connection);
05074
05075 if (!_dbus_transport_get_is_authenticated (connection->transport))
05076 result = FALSE;
05077 else
05078 result = _dbus_transport_get_unix_process_id (connection->transport,
05079 pid);
05080 #ifdef DBUS_WIN
05081 _dbus_assert (!result);
05082 #endif
05083
05084 CONNECTION_UNLOCK (connection);
05085
05086 return result;
05087 }
05088
05099 dbus_bool_t
05100 dbus_connection_get_adt_audit_session_data (DBusConnection *connection,
05101 void **data,
05102 dbus_int32_t *data_size)
05103 {
05104 dbus_bool_t result;
05105
05106 _dbus_return_val_if_fail (connection != NULL, FALSE);
05107 _dbus_return_val_if_fail (data != NULL, FALSE);
05108 _dbus_return_val_if_fail (data_size != NULL, FALSE);
05109
05110 CONNECTION_LOCK (connection);
05111
05112 if (!_dbus_transport_get_is_authenticated (connection->transport))
05113 result = FALSE;
05114 else
05115 result = _dbus_transport_get_adt_audit_session_data (connection->transport,
05116 data,
05117 data_size);
05118 CONNECTION_UNLOCK (connection);
05119
05120 return result;
05121 }
05122
05145 void
05146 dbus_connection_set_unix_user_function (DBusConnection *connection,
05147 DBusAllowUnixUserFunction function,
05148 void *data,
05149 DBusFreeFunction free_data_function)
05150 {
05151 void *old_data = NULL;
05152 DBusFreeFunction old_free_function = NULL;
05153
05154 _dbus_return_if_fail (connection != NULL);
05155
05156 CONNECTION_LOCK (connection);
05157 _dbus_transport_set_unix_user_function (connection->transport,
05158 function, data, free_data_function,
05159 &old_data, &old_free_function);
05160 CONNECTION_UNLOCK (connection);
05161
05162 if (old_free_function != NULL)
05163 (* old_free_function) (old_data);
05164 }
05165
05197 dbus_bool_t
05198 dbus_connection_get_windows_user (DBusConnection *connection,
05199 char **windows_sid_p)
05200 {
05201 dbus_bool_t result;
05202
05203 _dbus_return_val_if_fail (connection != NULL, FALSE);
05204 _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
05205
05206 CONNECTION_LOCK (connection);
05207
05208 if (!_dbus_transport_get_is_authenticated (connection->transport))
05209 result = FALSE;
05210 else
05211 result = _dbus_transport_get_windows_user (connection->transport,
05212 windows_sid_p);
05213
05214 #ifdef DBUS_UNIX
05215 _dbus_assert (!result);
05216 #endif
05217
05218 CONNECTION_UNLOCK (connection);
05219
05220 return result;
05221 }
05222
05244 void
05245 dbus_connection_set_windows_user_function (DBusConnection *connection,
05246 DBusAllowWindowsUserFunction function,
05247 void *data,
05248 DBusFreeFunction free_data_function)
05249 {
05250 void *old_data = NULL;
05251 DBusFreeFunction old_free_function = NULL;
05252
05253 _dbus_return_if_fail (connection != NULL);
05254
05255 CONNECTION_LOCK (connection);
05256 _dbus_transport_set_windows_user_function (connection->transport,
05257 function, data, free_data_function,
05258 &old_data, &old_free_function);
05259 CONNECTION_UNLOCK (connection);
05260
05261 if (old_free_function != NULL)
05262 (* old_free_function) (old_data);
05263 }
05264
05291 void
05292 dbus_connection_set_allow_anonymous (DBusConnection *connection,
05293 dbus_bool_t value)
05294 {
05295 _dbus_return_if_fail (connection != NULL);
05296
05297 CONNECTION_LOCK (connection);
05298 _dbus_transport_set_allow_anonymous (connection->transport, value);
05299 CONNECTION_UNLOCK (connection);
05300 }
05301
05319 void
05320 dbus_connection_set_route_peer_messages (DBusConnection *connection,
05321 dbus_bool_t value)
05322 {
05323 _dbus_return_if_fail (connection != NULL);
05324
05325 CONNECTION_LOCK (connection);
05326 connection->route_peer_messages = TRUE;
05327 CONNECTION_UNLOCK (connection);
05328 }
05329
05351 dbus_bool_t
05352 dbus_connection_add_filter (DBusConnection *connection,
05353 DBusHandleMessageFunction function,
05354 void *user_data,
05355 DBusFreeFunction free_data_function)
05356 {
05357 DBusMessageFilter *filter;
05358
05359 _dbus_return_val_if_fail (connection != NULL, FALSE);
05360 _dbus_return_val_if_fail (function != NULL, FALSE);
05361
05362 filter = dbus_new0 (DBusMessageFilter, 1);
05363 if (filter == NULL)
05364 return FALSE;
05365
05366 filter->refcount.value = 1;
05367
05368 CONNECTION_LOCK (connection);
05369
05370 if (!_dbus_list_append (&connection->filter_list,
05371 filter))
05372 {
05373 _dbus_message_filter_unref (filter);
05374 CONNECTION_UNLOCK (connection);
05375 return FALSE;
05376 }
05377
05378
05379
05380
05381
05382
05383 filter->function = function;
05384 filter->user_data = user_data;
05385 filter->free_user_data_function = free_data_function;
05386
05387 CONNECTION_UNLOCK (connection);
05388 return TRUE;
05389 }
05390
05403 void
05404 dbus_connection_remove_filter (DBusConnection *connection,
05405 DBusHandleMessageFunction function,
05406 void *user_data)
05407 {
05408 DBusList *link;
05409 DBusMessageFilter *filter;
05410
05411 _dbus_return_if_fail (connection != NULL);
05412 _dbus_return_if_fail (function != NULL);
05413
05414 CONNECTION_LOCK (connection);
05415
05416 filter = NULL;
05417
05418 link = _dbus_list_get_last_link (&connection->filter_list);
05419 while (link != NULL)
05420 {
05421 filter = link->data;
05422
05423 if (filter->function == function &&
05424 filter->user_data == user_data)
05425 {
05426 _dbus_list_remove_link (&connection->filter_list, link);
05427 filter->function = NULL;
05428
05429 break;
05430 }
05431
05432 link = _dbus_list_get_prev_link (&connection->filter_list, link);
05433 filter = NULL;
05434 }
05435
05436 CONNECTION_UNLOCK (connection);
05437
05438 #ifndef DBUS_DISABLE_CHECKS
05439 if (filter == NULL)
05440 {
05441 _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
05442 function, user_data);
05443 return;
05444 }
05445 #endif
05446
05447
05448 if (filter->free_user_data_function)
05449 (* filter->free_user_data_function) (filter->user_data);
05450
05451 filter->free_user_data_function = NULL;
05452 filter->user_data = NULL;
05453
05454 _dbus_message_filter_unref (filter);
05455 }
05456
05469 dbus_bool_t
05470 dbus_connection_try_register_object_path (DBusConnection *connection,
05471 const char *path,
05472 const DBusObjectPathVTable *vtable,
05473 void *user_data,
05474 DBusError *error)
05475 {
05476 char **decomposed_path;
05477 dbus_bool_t retval;
05478
05479 _dbus_return_val_if_fail (connection != NULL, FALSE);
05480 _dbus_return_val_if_fail (path != NULL, FALSE);
05481 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05482 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05483
05484 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05485 return FALSE;
05486
05487 CONNECTION_LOCK (connection);
05488
05489 retval = _dbus_object_tree_register (connection->objects,
05490 FALSE,
05491 (const char **) decomposed_path, vtable,
05492 user_data, error);
05493
05494 CONNECTION_UNLOCK (connection);
05495
05496 dbus_free_string_array (decomposed_path);
05497
05498 return retval;
05499 }
05500
05515 dbus_bool_t
05516 dbus_connection_register_object_path (DBusConnection *connection,
05517 const char *path,
05518 const DBusObjectPathVTable *vtable,
05519 void *user_data)
05520 {
05521 char **decomposed_path;
05522 dbus_bool_t retval;
05523 DBusError error = DBUS_ERROR_INIT;
05524
05525 _dbus_return_val_if_fail (connection != NULL, FALSE);
05526 _dbus_return_val_if_fail (path != NULL, FALSE);
05527 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05528 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05529
05530 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05531 return FALSE;
05532
05533 CONNECTION_LOCK (connection);
05534
05535 retval = _dbus_object_tree_register (connection->objects,
05536 FALSE,
05537 (const char **) decomposed_path, vtable,
05538 user_data, &error);
05539
05540 CONNECTION_UNLOCK (connection);
05541
05542 dbus_free_string_array (decomposed_path);
05543
05544 if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE))
05545 {
05546 _dbus_warn ("%s\n", error.message);
05547 dbus_error_free (&error);
05548 return FALSE;
05549 }
05550
05551 return retval;
05552 }
05553
05568 dbus_bool_t
05569 dbus_connection_try_register_fallback (DBusConnection *connection,
05570 const char *path,
05571 const DBusObjectPathVTable *vtable,
05572 void *user_data,
05573 DBusError *error)
05574 {
05575 char **decomposed_path;
05576 dbus_bool_t retval;
05577
05578 _dbus_return_val_if_fail (connection != NULL, FALSE);
05579 _dbus_return_val_if_fail (path != NULL, FALSE);
05580 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05581 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05582
05583 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05584 return FALSE;
05585
05586 CONNECTION_LOCK (connection);
05587
05588 retval = _dbus_object_tree_register (connection->objects,
05589 TRUE,
05590 (const char **) decomposed_path, vtable,
05591 user_data, error);
05592
05593 CONNECTION_UNLOCK (connection);
05594
05595 dbus_free_string_array (decomposed_path);
05596
05597 return retval;
05598 }
05599
05616 dbus_bool_t
05617 dbus_connection_register_fallback (DBusConnection *connection,
05618 const char *path,
05619 const DBusObjectPathVTable *vtable,
05620 void *user_data)
05621 {
05622 char **decomposed_path;
05623 dbus_bool_t retval;
05624 DBusError error = DBUS_ERROR_INIT;
05625
05626 _dbus_return_val_if_fail (connection != NULL, FALSE);
05627 _dbus_return_val_if_fail (path != NULL, FALSE);
05628 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05629 _dbus_return_val_if_fail (vtable != NULL, FALSE);
05630
05631 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05632 return FALSE;
05633
05634 CONNECTION_LOCK (connection);
05635
05636 retval = _dbus_object_tree_register (connection->objects,
05637 TRUE,
05638 (const char **) decomposed_path, vtable,
05639 user_data, &error);
05640
05641 CONNECTION_UNLOCK (connection);
05642
05643 dbus_free_string_array (decomposed_path);
05644
05645 if (dbus_error_has_name (&error, DBUS_ERROR_ADDRESS_IN_USE))
05646 {
05647 _dbus_warn ("%s\n", error.message);
05648 dbus_error_free (&error);
05649 return FALSE;
05650 }
05651
05652 return retval;
05653 }
05654
05664 dbus_bool_t
05665 dbus_connection_unregister_object_path (DBusConnection *connection,
05666 const char *path)
05667 {
05668 char **decomposed_path;
05669
05670 _dbus_return_val_if_fail (connection != NULL, FALSE);
05671 _dbus_return_val_if_fail (path != NULL, FALSE);
05672 _dbus_return_val_if_fail (path[0] == '/', FALSE);
05673
05674 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05675 return FALSE;
05676
05677 CONNECTION_LOCK (connection);
05678
05679 _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
05680
05681 dbus_free_string_array (decomposed_path);
05682
05683 return TRUE;
05684 }
05685
05696 dbus_bool_t
05697 dbus_connection_get_object_path_data (DBusConnection *connection,
05698 const char *path,
05699 void **data_p)
05700 {
05701 char **decomposed_path;
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 (data_p != NULL, FALSE);
05706
05707 *data_p = NULL;
05708
05709 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
05710 return FALSE;
05711
05712 CONNECTION_LOCK (connection);
05713
05714 *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path);
05715
05716 CONNECTION_UNLOCK (connection);
05717
05718 dbus_free_string_array (decomposed_path);
05719
05720 return TRUE;
05721 }
05722
05733 dbus_bool_t
05734 dbus_connection_list_registered (DBusConnection *connection,
05735 const char *parent_path,
05736 char ***child_entries)
05737 {
05738 char **decomposed_path;
05739 dbus_bool_t retval;
05740 _dbus_return_val_if_fail (connection != NULL, FALSE);
05741 _dbus_return_val_if_fail (parent_path != NULL, FALSE);
05742 _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
05743 _dbus_return_val_if_fail (child_entries != NULL, FALSE);
05744
05745 if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
05746 return FALSE;
05747
05748 CONNECTION_LOCK (connection);
05749
05750 retval = _dbus_object_tree_list_registered_and_unlock (connection->objects,
05751 (const char **) decomposed_path,
05752 child_entries);
05753 dbus_free_string_array (decomposed_path);
05754
05755 return retval;
05756 }
05757
05758 static DBusDataSlotAllocator slot_allocator;
05759 _DBUS_DEFINE_GLOBAL_LOCK (connection_slots);
05760
05775 dbus_bool_t
05776 dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
05777 {
05778 return _dbus_data_slot_allocator_alloc (&slot_allocator,
05779 &_DBUS_LOCK_NAME (connection_slots),
05780 slot_p);
05781 }
05782
05794 void
05795 dbus_connection_free_data_slot (dbus_int32_t *slot_p)
05796 {
05797 _dbus_return_if_fail (*slot_p >= 0);
05798
05799 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
05800 }
05801
05815 dbus_bool_t
05816 dbus_connection_set_data (DBusConnection *connection,
05817 dbus_int32_t slot,
05818 void *data,
05819 DBusFreeFunction free_data_func)
05820 {
05821 DBusFreeFunction old_free_func;
05822 void *old_data;
05823 dbus_bool_t retval;
05824
05825 _dbus_return_val_if_fail (connection != NULL, FALSE);
05826 _dbus_return_val_if_fail (slot >= 0, FALSE);
05827
05828 CONNECTION_LOCK (connection);
05829
05830 retval = _dbus_data_slot_list_set (&slot_allocator,
05831 &connection->slot_list,
05832 slot, data, free_data_func,
05833 &old_free_func, &old_data);
05834
05835 CONNECTION_UNLOCK (connection);
05836
05837 if (retval)
05838 {
05839
05840 if (old_free_func)
05841 (* old_free_func) (old_data);
05842 }
05843
05844 return retval;
05845 }
05846
05855 void*
05856 dbus_connection_get_data (DBusConnection *connection,
05857 dbus_int32_t slot)
05858 {
05859 void *res;
05860
05861 _dbus_return_val_if_fail (connection != NULL, NULL);
05862
05863 CONNECTION_LOCK (connection);
05864
05865 res = _dbus_data_slot_list_get (&slot_allocator,
05866 &connection->slot_list,
05867 slot);
05868
05869 CONNECTION_UNLOCK (connection);
05870
05871 return res;
05872 }
05873
05880 void
05881 dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
05882 {
05883 _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
05884 }
05885
05894 void
05895 dbus_connection_set_max_message_size (DBusConnection *connection,
05896 long size)
05897 {
05898 _dbus_return_if_fail (connection != NULL);
05899
05900 CONNECTION_LOCK (connection);
05901 _dbus_transport_set_max_message_size (connection->transport,
05902 size);
05903 CONNECTION_UNLOCK (connection);
05904 }
05905
05912 long
05913 dbus_connection_get_max_message_size (DBusConnection *connection)
05914 {
05915 long res;
05916
05917 _dbus_return_val_if_fail (connection != NULL, 0);
05918
05919 CONNECTION_LOCK (connection);
05920 res = _dbus_transport_get_max_message_size (connection->transport);
05921 CONNECTION_UNLOCK (connection);
05922 return res;
05923 }
05924
05950 void
05951 dbus_connection_set_max_received_size (DBusConnection *connection,
05952 long size)
05953 {
05954 _dbus_return_if_fail (connection != NULL);
05955
05956 CONNECTION_LOCK (connection);
05957 _dbus_transport_set_max_received_size (connection->transport,
05958 size);
05959 CONNECTION_UNLOCK (connection);
05960 }
05961
05968 long
05969 dbus_connection_get_max_received_size (DBusConnection *connection)
05970 {
05971 long res;
05972
05973 _dbus_return_val_if_fail (connection != NULL, 0);
05974
05975 CONNECTION_LOCK (connection);
05976 res = _dbus_transport_get_max_received_size (connection->transport);
05977 CONNECTION_UNLOCK (connection);
05978 return res;
05979 }
05980
05991 long
05992 dbus_connection_get_outgoing_size (DBusConnection *connection)
05993 {
05994 long res;
05995
05996 _dbus_return_val_if_fail (connection != NULL, 0);
05997
05998 CONNECTION_LOCK (connection);
05999 res = _dbus_counter_get_value (connection->outgoing_counter);
06000 CONNECTION_UNLOCK (connection);
06001 return res;
06002 }
06003