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-list.h"
00033 #include "dbus-hash.h"
00034 #include "dbus-message-internal.h"
00035 #include "dbus-threads.h"
00036 #include "dbus-protocol.h"
00037 #include "dbus-dataslot.h"
00038 #include "dbus-string.h"
00039 #include "dbus-pending-call.h"
00040 #include "dbus-object-tree.h"
00041 #include "dbus-marshal.h"
00042
00043 #ifdef DBUS_DISABLE_CHECKS
00044 #define TOOK_LOCK_CHECK(connection)
00045 #define RELEASING_LOCK_CHECK(connection)
00046 #define HAVE_LOCK_CHECK(connection)
00047 #else
00048 #define TOOK_LOCK_CHECK(connection) do { \
00049 _dbus_assert (!(connection)->have_connection_lock); \
00050 (connection)->have_connection_lock = TRUE; \
00051 } while (0)
00052 #define RELEASING_LOCK_CHECK(connection) do { \
00053 _dbus_assert ((connection)->have_connection_lock); \
00054 (connection)->have_connection_lock = FALSE; \
00055 } while (0)
00056 #define HAVE_LOCK_CHECK(connection) _dbus_assert ((connection)->have_connection_lock)
00057
00058 #endif
00059
00060 #define TRACE_LOCKS 1
00061
00062 #define CONNECTION_LOCK(connection) do { \
00063 if (TRACE_LOCKS) { _dbus_verbose (" LOCK: %s\n", _DBUS_FUNCTION_NAME); } \
00064 dbus_mutex_lock ((connection)->mutex); \
00065 TOOK_LOCK_CHECK (connection); \
00066 } while (0)
00067
00068 #define CONNECTION_UNLOCK(connection) do { \
00069 if (TRACE_LOCKS) { _dbus_verbose (" UNLOCK: %s\n", _DBUS_FUNCTION_NAME); } \
00070 RELEASING_LOCK_CHECK (connection); \
00071 dbus_mutex_unlock ((connection)->mutex); \
00072 } while (0)
00073
00074 #define DISPATCH_STATUS_NAME(s) \
00075 ((s) == DBUS_DISPATCH_COMPLETE ? "complete" : \
00076 (s) == DBUS_DISPATCH_DATA_REMAINS ? "data remains" : \
00077 (s) == DBUS_DISPATCH_NEED_MEMORY ? "need memory" : \
00078 "???")
00079
00157 typedef struct DBusMessageFilter DBusMessageFilter;
00158
00162 struct DBusMessageFilter
00163 {
00164 DBusAtomic refcount;
00165 DBusHandleMessageFunction function;
00166 void *user_data;
00167 DBusFreeFunction free_user_data_function;
00168 };
00169
00170
00174 struct DBusPreallocatedSend
00175 {
00176 DBusConnection *connection;
00177 DBusList *queue_link;
00178 DBusList *counter_link;
00179 };
00180
00181 static dbus_bool_t _dbus_modify_sigpipe = TRUE;
00182
00186 struct DBusConnection
00187 {
00188 DBusAtomic refcount;
00190 DBusMutex *mutex;
00192 DBusMutex *dispatch_mutex;
00193 DBusCondVar *dispatch_cond;
00194 DBusMutex *io_path_mutex;
00195 DBusCondVar *io_path_cond;
00197 DBusList *outgoing_messages;
00198 DBusList *incoming_messages;
00200 DBusMessage *message_borrowed;
00204 int n_outgoing;
00205 int n_incoming;
00207 DBusCounter *outgoing_counter;
00209 DBusTransport *transport;
00210 DBusWatchList *watches;
00211 DBusTimeoutList *timeouts;
00213 DBusList *filter_list;
00215 DBusDataSlotList slot_list;
00217 DBusHashTable *pending_replies;
00219 dbus_uint32_t client_serial;
00220 DBusList *disconnect_message_link;
00222 DBusWakeupMainFunction wakeup_main_function;
00223 void *wakeup_main_data;
00224 DBusFreeFunction free_wakeup_main_data;
00226 DBusDispatchStatusFunction dispatch_status_function;
00227 void *dispatch_status_data;
00228 DBusFreeFunction free_dispatch_status_data;
00230 DBusDispatchStatus last_dispatch_status;
00232 DBusList *link_cache;
00235 DBusObjectTree *objects;
00237 unsigned int dispatch_acquired : 1;
00238 unsigned int io_path_acquired : 1;
00240 unsigned int exit_on_disconnect : 1;
00242 #ifndef DBUS_DISABLE_CHECKS
00243 unsigned int have_connection_lock : 1;
00244 #endif
00245
00246 #ifndef DBUS_DISABLE_CHECKS
00247 int generation;
00248 #endif
00249 };
00250
00251 static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection);
00252 static void _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
00253 DBusDispatchStatus new_status);
00254 static void _dbus_connection_last_unref (DBusConnection *connection);
00255 static void _dbus_connection_acquire_dispatch (DBusConnection *connection);
00256 static void _dbus_connection_release_dispatch (DBusConnection *connection);
00257
00258 static DBusMessageFilter *
00259 _dbus_message_filter_ref (DBusMessageFilter *filter)
00260 {
00261 _dbus_assert (filter->refcount.value > 0);
00262 _dbus_atomic_inc (&filter->refcount);
00263
00264 return filter;
00265 }
00266
00267 static void
00268 _dbus_message_filter_unref (DBusMessageFilter *filter)
00269 {
00270 _dbus_assert (filter->refcount.value > 0);
00271
00272 if (_dbus_atomic_dec (&filter->refcount) == 1)
00273 {
00274 if (filter->free_user_data_function)
00275 (* filter->free_user_data_function) (filter->user_data);
00276
00277 dbus_free (filter);
00278 }
00279 }
00280
00286 void
00287 _dbus_connection_lock (DBusConnection *connection)
00288 {
00289 CONNECTION_LOCK (connection);
00290 }
00291
00297 void
00298 _dbus_connection_unlock (DBusConnection *connection)
00299 {
00300 CONNECTION_UNLOCK (connection);
00301 }
00302
00310 static void
00311 _dbus_connection_wakeup_mainloop (DBusConnection *connection)
00312 {
00313 if (connection->wakeup_main_function)
00314 (*connection->wakeup_main_function) (connection->wakeup_main_data);
00315 }
00316
00317 #ifdef DBUS_BUILD_TESTS
00318
00328 dbus_bool_t
00329 _dbus_connection_queue_received_message (DBusConnection *connection,
00330 DBusMessage *message)
00331 {
00332 DBusList *link;
00333
00334 link = _dbus_list_alloc_link (message);
00335 if (link == NULL)
00336 return FALSE;
00337
00338 dbus_message_ref (message);
00339 _dbus_connection_queue_received_message_link (connection, link);
00340
00341 return TRUE;
00342 }
00343 #endif
00344
00353 void
00354 _dbus_connection_queue_received_message_link (DBusConnection *connection,
00355 DBusList *link)
00356 {
00357 DBusPendingCall *pending;
00358 dbus_int32_t reply_serial;
00359 DBusMessage *message;
00360
00361 _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport));
00362
00363 _dbus_list_append_link (&connection->incoming_messages,
00364 link);
00365 message = link->data;
00366
00367
00368 reply_serial = dbus_message_get_reply_serial (message);
00369 if (reply_serial != -1)
00370 {
00371 pending = _dbus_hash_table_lookup_int (connection->pending_replies,
00372 reply_serial);
00373 if (pending != NULL)
00374 {
00375 if (pending->timeout_added)
00376 _dbus_connection_remove_timeout (connection,
00377 pending->timeout);
00378
00379 pending->timeout_added = FALSE;
00380 }
00381 }
00382
00383 connection->n_incoming += 1;
00384
00385 _dbus_connection_wakeup_mainloop (connection);
00386
00387 _dbus_verbose ("Message %p (%d %s %s %s '%s' reply to %u) added to incoming queue %p, %d incoming\n",
00388 message,
00389 dbus_message_get_type (message),
00390 dbus_message_get_path (message),
00391 dbus_message_get_interface (message) ?
00392 dbus_message_get_interface (message) :
00393 "no interface",
00394 dbus_message_get_member (message) ?
00395 dbus_message_get_member (message) :
00396 "no member",
00397 dbus_message_get_signature (message),
00398 dbus_message_get_reply_serial (message),
00399 connection,
00400 connection->n_incoming);
00401 }
00402
00413 static void
00414 _dbus_connection_queue_synthesized_message_link (DBusConnection *connection,
00415 DBusList *link)
00416 {
00417 HAVE_LOCK_CHECK (connection);
00418
00419 _dbus_list_append_link (&connection->incoming_messages, link);
00420
00421 connection->n_incoming += 1;
00422
00423 _dbus_connection_wakeup_mainloop (connection);
00424
00425 _dbus_verbose ("Synthesized message %p added to incoming queue %p, %d incoming\n",
00426 link->data, connection, connection->n_incoming);
00427 }
00428
00429
00437 dbus_bool_t
00438 _dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection)
00439 {
00440 HAVE_LOCK_CHECK (connection);
00441 return connection->outgoing_messages != NULL;
00442 }
00443
00450 dbus_bool_t
00451 dbus_connection_has_messages_to_send (DBusConnection *connection)
00452 {
00453 dbus_bool_t v;
00454
00455 _dbus_return_val_if_fail (connection != NULL, FALSE);
00456
00457 CONNECTION_LOCK (connection);
00458 v = _dbus_connection_has_messages_to_send_unlocked (connection);
00459 CONNECTION_UNLOCK (connection);
00460
00461 return v;
00462 }
00463
00471 DBusMessage*
00472 _dbus_connection_get_message_to_send (DBusConnection *connection)
00473 {
00474 HAVE_LOCK_CHECK (connection);
00475
00476 return _dbus_list_get_last (&connection->outgoing_messages);
00477 }
00478
00487 void
00488 _dbus_connection_message_sent (DBusConnection *connection,
00489 DBusMessage *message)
00490 {
00491 DBusList *link;
00492
00493 HAVE_LOCK_CHECK (connection);
00494
00495
00496
00497
00498
00499
00500 link = _dbus_list_get_last_link (&connection->outgoing_messages);
00501 _dbus_assert (link != NULL);
00502 _dbus_assert (link->data == message);
00503
00504
00505 _dbus_list_unlink (&connection->outgoing_messages,
00506 link);
00507 _dbus_list_prepend_link (&connection->link_cache, link);
00508
00509 connection->n_outgoing -= 1;
00510
00511 _dbus_verbose ("Message %p (%d %s %s %s '%s') removed from outgoing queue %p, %d left to send\n",
00512 message,
00513 dbus_message_get_type (message),
00514 dbus_message_get_path (message),
00515 dbus_message_get_interface (message) ?
00516 dbus_message_get_interface (message) :
00517 "no interface",
00518 dbus_message_get_member (message) ?
00519 dbus_message_get_member (message) :
00520 "no member",
00521 dbus_message_get_signature (message),
00522 connection, connection->n_outgoing);
00523
00524
00525 _dbus_message_remove_size_counter (message, connection->outgoing_counter,
00526 &link);
00527 _dbus_list_prepend_link (&connection->link_cache, link);
00528
00529 dbus_message_unref (message);
00530 }
00531
00532 typedef dbus_bool_t (* DBusWatchAddFunction) (DBusWatchList *list,
00533 DBusWatch *watch);
00534 typedef void (* DBusWatchRemoveFunction) (DBusWatchList *list,
00535 DBusWatch *watch);
00536 typedef void (* DBusWatchToggleFunction) (DBusWatchList *list,
00537 DBusWatch *watch,
00538 dbus_bool_t enabled);
00539
00540 static dbus_bool_t
00541 protected_change_watch (DBusConnection *connection,
00542 DBusWatch *watch,
00543 DBusWatchAddFunction add_function,
00544 DBusWatchRemoveFunction remove_function,
00545 DBusWatchToggleFunction toggle_function,
00546 dbus_bool_t enabled)
00547 {
00548 DBusWatchList *watches;
00549 dbus_bool_t retval;
00550
00551 HAVE_LOCK_CHECK (connection);
00552
00553
00554
00555
00556
00557 watches = connection->watches;
00558 if (watches)
00559 {
00560 connection->watches = NULL;
00561 _dbus_connection_ref_unlocked (connection);
00562 CONNECTION_UNLOCK (connection);
00563
00564 if (add_function)
00565 retval = (* add_function) (watches, watch);
00566 else if (remove_function)
00567 {
00568 retval = TRUE;
00569 (* remove_function) (watches, watch);
00570 }
00571 else
00572 {
00573 retval = TRUE;
00574 (* toggle_function) (watches, watch, enabled);
00575 }
00576
00577 CONNECTION_LOCK (connection);
00578 connection->watches = watches;
00579 _dbus_connection_unref_unlocked (connection);
00580
00581 return retval;
00582 }
00583 else
00584 return FALSE;
00585 }
00586
00587
00598 dbus_bool_t
00599 _dbus_connection_add_watch (DBusConnection *connection,
00600 DBusWatch *watch)
00601 {
00602 return protected_change_watch (connection, watch,
00603 _dbus_watch_list_add_watch,
00604 NULL, NULL, FALSE);
00605 }
00606
00615 void
00616 _dbus_connection_remove_watch (DBusConnection *connection,
00617 DBusWatch *watch)
00618 {
00619 protected_change_watch (connection, watch,
00620 NULL,
00621 _dbus_watch_list_remove_watch,
00622 NULL, FALSE);
00623 }
00624
00635 void
00636 _dbus_connection_toggle_watch (DBusConnection *connection,
00637 DBusWatch *watch,
00638 dbus_bool_t enabled)
00639 {
00640 _dbus_assert (watch != NULL);
00641
00642 protected_change_watch (connection, watch,
00643 NULL, NULL,
00644 _dbus_watch_list_toggle_watch,
00645 enabled);
00646 }
00647
00648 typedef dbus_bool_t (* DBusTimeoutAddFunction) (DBusTimeoutList *list,
00649 DBusTimeout *timeout);
00650 typedef void (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list,
00651 DBusTimeout *timeout);
00652 typedef void (* DBusTimeoutToggleFunction) (DBusTimeoutList *list,
00653 DBusTimeout *timeout,
00654 dbus_bool_t enabled);
00655
00656 static dbus_bool_t
00657 protected_change_timeout (DBusConnection *connection,
00658 DBusTimeout *timeout,
00659 DBusTimeoutAddFunction add_function,
00660 DBusTimeoutRemoveFunction remove_function,
00661 DBusTimeoutToggleFunction toggle_function,
00662 dbus_bool_t enabled)
00663 {
00664 DBusTimeoutList *timeouts;
00665 dbus_bool_t retval;
00666
00667 HAVE_LOCK_CHECK (connection);
00668
00669
00670
00671
00672
00673 timeouts = connection->timeouts;
00674 if (timeouts)
00675 {
00676 connection->timeouts = NULL;
00677 _dbus_connection_ref_unlocked (connection);
00678 CONNECTION_UNLOCK (connection);
00679
00680 if (add_function)
00681 retval = (* add_function) (timeouts, timeout);
00682 else if (remove_function)
00683 {
00684 retval = TRUE;
00685 (* remove_function) (timeouts, timeout);
00686 }
00687 else
00688 {
00689 retval = TRUE;
00690 (* toggle_function) (timeouts, timeout, enabled);
00691 }
00692
00693 CONNECTION_LOCK (connection);
00694 connection->timeouts = timeouts;
00695 _dbus_connection_unref_unlocked (connection);
00696
00697 return retval;
00698 }
00699 else
00700 return FALSE;
00701 }
00702
00714 dbus_bool_t
00715 _dbus_connection_add_timeout (DBusConnection *connection,
00716 DBusTimeout *timeout)
00717 {
00718 return protected_change_timeout (connection, timeout,
00719 _dbus_timeout_list_add_timeout,
00720 NULL, NULL, FALSE);
00721 }
00722
00731 void
00732 _dbus_connection_remove_timeout (DBusConnection *connection,
00733 DBusTimeout *timeout)
00734 {
00735 protected_change_timeout (connection, timeout,
00736 NULL,
00737 _dbus_timeout_list_remove_timeout,
00738 NULL, FALSE);
00739 }
00740
00750 void
00751 _dbus_connection_toggle_timeout (DBusConnection *connection,
00752 DBusTimeout *timeout,
00753 dbus_bool_t enabled)
00754 {
00755 protected_change_timeout (connection, timeout,
00756 NULL, NULL,
00757 _dbus_timeout_list_toggle_timeout,
00758 enabled);
00759 }
00760
00761 static dbus_bool_t
00762 _dbus_connection_attach_pending_call_unlocked (DBusConnection *connection,
00763 DBusPendingCall *pending)
00764 {
00765 HAVE_LOCK_CHECK (connection);
00766
00767 _dbus_assert (pending->reply_serial != 0);
00768
00769 if (!_dbus_connection_add_timeout (connection, pending->timeout))
00770 return FALSE;
00771
00772 if (!_dbus_hash_table_insert_int (connection->pending_replies,
00773 pending->reply_serial,
00774 pending))
00775 {
00776 _dbus_connection_remove_timeout (connection, pending->timeout);
00777
00778 HAVE_LOCK_CHECK (connection);
00779 return FALSE;
00780 }
00781
00782 pending->timeout_added = TRUE;
00783 pending->connection = connection;
00784
00785 dbus_pending_call_ref (pending);
00786
00787 HAVE_LOCK_CHECK (connection);
00788
00789 return TRUE;
00790 }
00791
00792 static void
00793 free_pending_call_on_hash_removal (void *data)
00794 {
00795 DBusPendingCall *pending;
00796
00797 if (data == NULL)
00798 return;
00799
00800 pending = data;
00801
00802 if (pending->connection)
00803 {
00804 if (pending->timeout_added)
00805 {
00806 _dbus_connection_remove_timeout (pending->connection,
00807 pending->timeout);
00808 pending->timeout_added = FALSE;
00809 }
00810
00811 pending->connection = NULL;
00812
00813 dbus_pending_call_unref (pending);
00814 }
00815 }
00816
00817 static void
00818 _dbus_connection_detach_pending_call_unlocked (DBusConnection *connection,
00819 DBusPendingCall *pending)
00820 {
00821
00822
00823 dbus_pending_call_ref (pending);
00824 _dbus_hash_table_remove_int (connection->pending_replies,
00825 pending->reply_serial);
00826 _dbus_assert (pending->connection == NULL);
00827 dbus_pending_call_unref (pending);
00828 }
00829
00830 static void
00831 _dbus_connection_detach_pending_call_and_unlock (DBusConnection *connection,
00832 DBusPendingCall *pending)
00833 {
00834
00835
00836
00837
00838 dbus_pending_call_ref (pending);
00839 _dbus_hash_table_remove_int (connection->pending_replies,
00840 pending->reply_serial);
00841 _dbus_assert (pending->connection == NULL);
00842 CONNECTION_UNLOCK (connection);
00843 dbus_pending_call_unref (pending);
00844 }
00845
00854 void
00855 _dbus_connection_remove_pending_call (DBusConnection *connection,
00856 DBusPendingCall *pending)
00857 {
00858 CONNECTION_LOCK (connection);
00859 _dbus_connection_detach_pending_call_and_unlock (connection, pending);
00860 }
00861
00870 void
00871 _dbus_pending_call_complete_and_unlock (DBusPendingCall *pending,
00872 DBusMessage *message)
00873 {
00874 if (message == NULL)
00875 {
00876 message = pending->timeout_link->data;
00877 _dbus_list_clear (&pending->timeout_link);
00878 }
00879 else
00880 dbus_message_ref (message);
00881
00882 _dbus_verbose (" handing message %p (%s) to pending call serial %u\n",
00883 message,
00884 dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN ?
00885 "method return" :
00886 dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR ?
00887 "error" : "other type",
00888 pending->reply_serial);
00889
00890 _dbus_assert (pending->reply == NULL);
00891 _dbus_assert (pending->reply_serial == dbus_message_get_reply_serial (message));
00892 pending->reply = message;
00893
00894 dbus_pending_call_ref (pending);
00895 _dbus_connection_detach_pending_call_and_unlock (pending->connection, pending);
00896
00897
00898 _dbus_pending_call_notify (pending);
00899 dbus_pending_call_unref (pending);
00900 }
00901
00911 static dbus_bool_t
00912 _dbus_connection_acquire_io_path (DBusConnection *connection,
00913 int timeout_milliseconds)
00914 {
00915 dbus_bool_t we_acquired;
00916
00917 HAVE_LOCK_CHECK (connection);
00918
00919
00920 _dbus_connection_ref_unlocked (connection);
00921
00922
00923 CONNECTION_UNLOCK (connection);
00924
00925 _dbus_verbose ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME);
00926 dbus_mutex_lock (connection->io_path_mutex);
00927
00928 _dbus_verbose ("%s start connection->io_path_acquired = %d timeout = %d\n",
00929 _DBUS_FUNCTION_NAME, connection->io_path_acquired, timeout_milliseconds);
00930
00931 we_acquired = FALSE;
00932
00933 if (connection->io_path_acquired)
00934 {
00935 if (timeout_milliseconds != -1)
00936 {
00937 _dbus_verbose ("%s waiting %d for IO path to be acquirable\n",
00938 _DBUS_FUNCTION_NAME, timeout_milliseconds);
00939 dbus_condvar_wait_timeout (connection->io_path_cond,
00940 connection->io_path_mutex,
00941 timeout_milliseconds);
00942 }
00943 else
00944 {
00945 while (connection->io_path_acquired)
00946 {
00947 _dbus_verbose ("%s waiting for IO path to be acquirable\n", _DBUS_FUNCTION_NAME);
00948 dbus_condvar_wait (connection->io_path_cond, connection->io_path_mutex);
00949 }
00950 }
00951 }
00952
00953 if (!connection->io_path_acquired)
00954 {
00955 we_acquired = TRUE;
00956 connection->io_path_acquired = TRUE;
00957 }
00958
00959 _dbus_verbose ("%s end connection->io_path_acquired = %d we_acquired = %d\n",
00960 _DBUS_FUNCTION_NAME, connection->io_path_acquired, we_acquired);
00961
00962 _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME);
00963 dbus_mutex_unlock (connection->io_path_mutex);
00964
00965 CONNECTION_LOCK (connection);
00966
00967 HAVE_LOCK_CHECK (connection);
00968
00969 _dbus_connection_unref_unlocked (connection);
00970
00971 return we_acquired;
00972 }
00973
00981 static void
00982 _dbus_connection_release_io_path (DBusConnection *connection)
00983 {
00984 HAVE_LOCK_CHECK (connection);
00985
00986 _dbus_verbose ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME);
00987 dbus_mutex_lock (connection->io_path_mutex);
00988
00989 _dbus_assert (connection->io_path_acquired);
00990
00991 _dbus_verbose ("%s start connection->io_path_acquired = %d\n",
00992 _DBUS_FUNCTION_NAME, connection->io_path_acquired);
00993
00994 connection->io_path_acquired = FALSE;
00995 dbus_condvar_wake_one (connection->io_path_cond);
00996
00997 _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME);
00998 dbus_mutex_unlock (connection->io_path_mutex);
00999 }
01000
01029 void
01030 _dbus_connection_do_iteration_unlocked (DBusConnection *connection,
01031 unsigned int flags,
01032 int timeout_milliseconds)
01033 {
01034 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
01035
01036 HAVE_LOCK_CHECK (connection);
01037
01038 if (connection->n_outgoing == 0)
01039 flags &= ~DBUS_ITERATION_DO_WRITING;
01040
01041 if (_dbus_connection_acquire_io_path (connection,
01042 (flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0))
01043 {
01044 HAVE_LOCK_CHECK (connection);
01045
01046 _dbus_transport_do_iteration (connection->transport,
01047 flags, timeout_milliseconds);
01048 _dbus_connection_release_io_path (connection);
01049 }
01050
01051 HAVE_LOCK_CHECK (connection);
01052
01053 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
01054 }
01055
01065 DBusConnection*
01066 _dbus_connection_new_for_transport (DBusTransport *transport)
01067 {
01068 DBusConnection *connection;
01069 DBusWatchList *watch_list;
01070 DBusTimeoutList *timeout_list;
01071 DBusHashTable *pending_replies;
01072 DBusMutex *mutex;
01073 DBusMutex *io_path_mutex;
01074 DBusMutex *dispatch_mutex;
01075 DBusCondVar *message_returned_cond;
01076 DBusCondVar *dispatch_cond;
01077 DBusCondVar *io_path_cond;
01078 DBusList *disconnect_link;
01079 DBusMessage *disconnect_message;
01080 DBusCounter *outgoing_counter;
01081 DBusObjectTree *objects;
01082
01083 watch_list = NULL;
01084 connection = NULL;
01085 pending_replies = NULL;
01086 timeout_list = NULL;
01087 mutex = NULL;
01088 io_path_mutex = NULL;
01089 dispatch_mutex = NULL;
01090 message_returned_cond = NULL;
01091 dispatch_cond = NULL;
01092 io_path_cond = NULL;
01093 disconnect_link = NULL;
01094 disconnect_message = NULL;
01095 outgoing_counter = NULL;
01096 objects = NULL;
01097
01098 watch_list = _dbus_watch_list_new ();
01099 if (watch_list == NULL)
01100 goto error;
01101
01102 timeout_list = _dbus_timeout_list_new ();
01103 if (timeout_list == NULL)
01104 goto error;
01105
01106 pending_replies =
01107 _dbus_hash_table_new (DBUS_HASH_INT,
01108 NULL,
01109 (DBusFreeFunction)free_pending_call_on_hash_removal);
01110 if (pending_replies == NULL)
01111 goto error;
01112
01113 connection = dbus_new0 (DBusConnection, 1);
01114 if (connection == NULL)
01115 goto error;
01116
01117 mutex = dbus_mutex_new ();
01118 if (mutex == NULL)
01119 goto error;
01120
01121 io_path_mutex = dbus_mutex_new ();
01122 if (io_path_mutex == NULL)
01123 goto error;
01124
01125 dispatch_mutex = dbus_mutex_new ();
01126 if (dispatch_mutex == NULL)
01127 goto error;
01128
01129 message_returned_cond = dbus_condvar_new ();
01130 if (message_returned_cond == NULL)
01131 goto error;
01132
01133 dispatch_cond = dbus_condvar_new ();
01134 if (dispatch_cond == NULL)
01135 goto error;
01136
01137 io_path_cond = dbus_condvar_new ();
01138 if (io_path_cond == NULL)
01139 goto error;
01140
01141 disconnect_message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_LOCAL,
01142 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
01143 "Disconnected");
01144
01145 if (disconnect_message == NULL)
01146 goto error;
01147
01148 disconnect_link = _dbus_list_alloc_link (disconnect_message);
01149 if (disconnect_link == NULL)
01150 goto error;
01151
01152 outgoing_counter = _dbus_counter_new ();
01153 if (outgoing_counter == NULL)
01154 goto error;
01155
01156 objects = _dbus_object_tree_new (connection);
01157 if (objects == NULL)
01158 goto error;
01159
01160 if (_dbus_modify_sigpipe)
01161 _dbus_disable_sigpipe ();
01162
01163 connection->refcount.value = 1;
01164 connection->mutex = mutex;
01165 connection->dispatch_cond = dispatch_cond;
01166 connection->dispatch_mutex = dispatch_mutex;
01167 connection->io_path_cond = io_path_cond;
01168 connection->io_path_mutex = io_path_mutex;
01169 connection->transport = transport;
01170 connection->watches = watch_list;
01171 connection->timeouts = timeout_list;
01172 connection->pending_replies = pending_replies;
01173 connection->outgoing_counter = outgoing_counter;
01174 connection->filter_list = NULL;
01175 connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE;
01176 connection->objects = objects;
01177 connection->exit_on_disconnect = FALSE;
01178 #ifndef DBUS_DISABLE_CHECKS
01179 connection->generation = _dbus_current_generation;
01180 #endif
01181
01182 _dbus_data_slot_list_init (&connection->slot_list);
01183
01184 connection->client_serial = 1;
01185
01186 connection->disconnect_message_link = disconnect_link;
01187
01188 CONNECTION_LOCK (connection);
01189
01190 if (!_dbus_transport_set_connection (transport, connection))
01191 goto error;
01192
01193 _dbus_transport_ref (transport);
01194
01195 CONNECTION_UNLOCK (connection);
01196
01197 return connection;
01198
01199 error:
01200 if (disconnect_message != NULL)
01201 dbus_message_unref (disconnect_message);
01202
01203 if (disconnect_link != NULL)
01204 _dbus_list_free_link (disconnect_link);
01205
01206 if (io_path_cond != NULL)
01207 dbus_condvar_free (io_path_cond);
01208
01209 if (dispatch_cond != NULL)
01210 dbus_condvar_free (dispatch_cond);
01211
01212 if (message_returned_cond != NULL)
01213 dbus_condvar_free (message_returned_cond);
01214
01215 if (mutex != NULL)
01216 dbus_mutex_free (mutex);
01217
01218 if (io_path_mutex != NULL)
01219 dbus_mutex_free (io_path_mutex);
01220
01221 if (dispatch_mutex != NULL)
01222 dbus_mutex_free (dispatch_mutex);
01223
01224 if (connection != NULL)
01225 dbus_free (connection);
01226
01227 if (pending_replies)
01228 _dbus_hash_table_unref (pending_replies);
01229
01230 if (watch_list)
01231 _dbus_watch_list_free (watch_list);
01232
01233 if (timeout_list)
01234 _dbus_timeout_list_free (timeout_list);
01235
01236 if (outgoing_counter)
01237 _dbus_counter_unref (outgoing_counter);
01238
01239 if (objects)
01240 _dbus_object_tree_unref (objects);
01241
01242 return NULL;
01243 }
01244
01252 DBusConnection *
01253 _dbus_connection_ref_unlocked (DBusConnection *connection)
01254 {
01255 _dbus_assert (connection != NULL);
01256 _dbus_assert (connection->generation == _dbus_current_generation);
01257
01258 HAVE_LOCK_CHECK (connection);
01259
01260 #ifdef DBUS_HAVE_ATOMIC_INT
01261 _dbus_atomic_inc (&connection->refcount);
01262 #else
01263 _dbus_assert (connection->refcount.value > 0);
01264 connection->refcount.value += 1;
01265 #endif
01266
01267 return connection;
01268 }
01269
01276 void
01277 _dbus_connection_unref_unlocked (DBusConnection *connection)
01278 {
01279 dbus_bool_t last_unref;
01280
01281 HAVE_LOCK_CHECK (connection);
01282
01283 _dbus_assert (connection != NULL);
01284
01285
01286
01287
01288
01289 #ifdef DBUS_HAVE_ATOMIC_INT
01290 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
01291 #else
01292 _dbus_assert (connection->refcount.value > 0);
01293
01294 connection->refcount.value -= 1;
01295 last_unref = (connection->refcount.value == 0);
01296 #if 0
01297 printf ("unref_unlocked() connection %p count = %d\n", connection, connection->refcount.value);
01298 #endif
01299 #endif
01300
01301 if (last_unref)
01302 _dbus_connection_last_unref (connection);
01303 }
01304
01305 static dbus_uint32_t
01306 _dbus_connection_get_next_client_serial (DBusConnection *connection)
01307 {
01308 int serial;
01309
01310 serial = connection->client_serial++;
01311
01312 if (connection->client_serial < 0)
01313 connection->client_serial = 1;
01314
01315 return serial;
01316 }
01317
01331 dbus_bool_t
01332 _dbus_connection_handle_watch (DBusWatch *watch,
01333 unsigned int condition,
01334 void *data)
01335 {
01336 DBusConnection *connection;
01337 dbus_bool_t retval;
01338 DBusDispatchStatus status;
01339
01340 connection = data;
01341
01342 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
01343
01344 CONNECTION_LOCK (connection);
01345 _dbus_connection_acquire_io_path (connection, -1);
01346 HAVE_LOCK_CHECK (connection);
01347 retval = _dbus_transport_handle_watch (connection->transport,
01348 watch, condition);
01349
01350 _dbus_connection_release_io_path (connection);
01351
01352 HAVE_LOCK_CHECK (connection);
01353
01354 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
01355
01356 status = _dbus_connection_get_dispatch_status_unlocked (connection);
01357
01358
01359 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01360
01361 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
01362
01363 return retval;
01364 }
01365
01390 DBusConnection*
01391 dbus_connection_open (const char *address,
01392 DBusError *error)
01393 {
01394 DBusConnection *connection;
01395 DBusTransport *transport;
01396
01397 _dbus_return_val_if_fail (address != NULL, NULL);
01398 _dbus_return_val_if_error_is_set (error, NULL);
01399
01400 transport = _dbus_transport_open (address, error);
01401 if (transport == NULL)
01402 {
01403 _DBUS_ASSERT_ERROR_IS_SET (error);
01404 return NULL;
01405 }
01406
01407 connection = _dbus_connection_new_for_transport (transport);
01408
01409 _dbus_transport_unref (transport);
01410
01411 if (connection == NULL)
01412 {
01413 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01414 return NULL;
01415 }
01416
01417 #ifndef DBUS_DISABLE_CHECKS
01418 _dbus_assert (!connection->have_connection_lock);
01419 #endif
01420 return connection;
01421 }
01422
01429 DBusConnection *
01430 dbus_connection_ref (DBusConnection *connection)
01431 {
01432 _dbus_return_val_if_fail (connection != NULL, NULL);
01433 _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
01434
01435
01436
01437
01438
01439 #ifdef DBUS_HAVE_ATOMIC_INT
01440 _dbus_atomic_inc (&connection->refcount);
01441 #else
01442 CONNECTION_LOCK (connection);
01443 _dbus_assert (connection->refcount.value > 0);
01444
01445 connection->refcount.value += 1;
01446 CONNECTION_UNLOCK (connection);
01447 #endif
01448
01449 return connection;
01450 }
01451
01452 static void
01453 free_outgoing_message (void *element,
01454 void *data)
01455 {
01456 DBusMessage *message = element;
01457 DBusConnection *connection = data;
01458
01459 _dbus_message_remove_size_counter (message,
01460 connection->outgoing_counter,
01461 NULL);
01462 dbus_message_unref (message);
01463 }
01464
01465
01466
01467
01468
01469 static void
01470 _dbus_connection_last_unref (DBusConnection *connection)
01471 {
01472 DBusList *link;
01473
01474 _dbus_verbose ("Finalizing connection %p\n", connection);
01475
01476 _dbus_assert (connection->refcount.value == 0);
01477
01478
01479
01480
01481 _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
01482
01483
01484 _dbus_object_tree_free_all_unlocked (connection->objects);
01485
01486 dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
01487 dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
01488 dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
01489
01490 _dbus_watch_list_free (connection->watches);
01491 connection->watches = NULL;
01492
01493 _dbus_timeout_list_free (connection->timeouts);
01494 connection->timeouts = NULL;
01495
01496 _dbus_data_slot_list_free (&connection->slot_list);
01497
01498 link = _dbus_list_get_first_link (&connection->filter_list);
01499 while (link != NULL)
01500 {
01501 DBusMessageFilter *filter = link->data;
01502 DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
01503
01504 filter->function = NULL;
01505 _dbus_message_filter_unref (filter);
01506 link->data = NULL;
01507
01508 link = next;
01509 }
01510 _dbus_list_clear (&connection->filter_list);
01511
01512
01513
01514 _dbus_object_tree_unref (connection->objects);
01515
01516 _dbus_hash_table_unref (connection->pending_replies);
01517 connection->pending_replies = NULL;
01518
01519 _dbus_list_clear (&connection->filter_list);
01520
01521 _dbus_list_foreach (&connection->outgoing_messages,
01522 free_outgoing_message,
01523 connection);
01524 _dbus_list_clear (&connection->outgoing_messages);
01525
01526 _dbus_list_foreach (&connection->incoming_messages,
01527 (DBusForeachFunction) dbus_message_unref,
01528 NULL);
01529 _dbus_list_clear (&connection->incoming_messages);
01530
01531 _dbus_counter_unref (connection->outgoing_counter);
01532
01533 _dbus_transport_unref (connection->transport);
01534
01535 if (connection->disconnect_message_link)
01536 {
01537 DBusMessage *message = connection->disconnect_message_link->data;
01538 dbus_message_unref (message);
01539 _dbus_list_free_link (connection->disconnect_message_link);
01540 }
01541
01542 _dbus_list_clear (&connection->link_cache);
01543
01544 dbus_condvar_free (connection->dispatch_cond);
01545 dbus_condvar_free (connection->io_path_cond);
01546
01547 dbus_mutex_free (connection->io_path_mutex);
01548 dbus_mutex_free (connection->dispatch_mutex);
01549
01550 dbus_mutex_free (connection->mutex);
01551
01552 dbus_free (connection);
01553 }
01554
01566 void
01567 dbus_connection_unref (DBusConnection *connection)
01568 {
01569 dbus_bool_t last_unref;
01570
01571 _dbus_return_if_fail (connection != NULL);
01572 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
01573
01574
01575
01576
01577
01578 #ifdef DBUS_HAVE_ATOMIC_INT
01579 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
01580 #else
01581 CONNECTION_LOCK (connection);
01582
01583 _dbus_assert (connection->refcount.value > 0);
01584
01585 connection->refcount.value -= 1;
01586 last_unref = (connection->refcount.value == 0);
01587
01588 #if 0
01589 printf ("unref() connection %p count = %d\n", connection, connection->refcount.value);
01590 #endif
01591
01592 CONNECTION_UNLOCK (connection);
01593 #endif
01594
01595 if (last_unref)
01596 _dbus_connection_last_unref (connection);
01597 }
01598
01612 void
01613 dbus_connection_disconnect (DBusConnection *connection)
01614 {
01615 DBusDispatchStatus status;
01616
01617 _dbus_return_if_fail (connection != NULL);
01618 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
01619
01620 _dbus_verbose ("Disconnecting %p\n", connection);
01621
01622 CONNECTION_LOCK (connection);
01623 _dbus_transport_disconnect (connection->transport);
01624
01625 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
01626 status = _dbus_connection_get_dispatch_status_unlocked (connection);
01627
01628
01629 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01630 }
01631
01632 static dbus_bool_t
01633 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
01634 {
01635 HAVE_LOCK_CHECK (connection);
01636 return _dbus_transport_get_is_connected (connection->transport);
01637 }
01638
01649 dbus_bool_t
01650 dbus_connection_get_is_connected (DBusConnection *connection)
01651 {
01652 dbus_bool_t res;
01653
01654 _dbus_return_val_if_fail (connection != NULL, FALSE);
01655
01656 CONNECTION_LOCK (connection);
01657 res = _dbus_connection_get_is_connected_unlocked (connection);
01658 CONNECTION_UNLOCK (connection);
01659
01660 return res;
01661 }
01662
01671 dbus_bool_t
01672 dbus_connection_get_is_authenticated (DBusConnection *connection)
01673 {
01674 dbus_bool_t res;
01675
01676 _dbus_return_val_if_fail (connection != NULL, FALSE);
01677
01678 CONNECTION_LOCK (connection);
01679 res = _dbus_transport_get_is_authenticated (connection->transport);
01680 CONNECTION_UNLOCK (connection);
01681
01682 return res;
01683 }
01684
01698 void
01699 dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
01700 dbus_bool_t exit_on_disconnect)
01701 {
01702 _dbus_return_if_fail (connection != NULL);
01703
01704 CONNECTION_LOCK (connection);
01705 connection->exit_on_disconnect = exit_on_disconnect != FALSE;
01706 CONNECTION_UNLOCK (connection);
01707 }
01708
01709 static DBusPreallocatedSend*
01710 _dbus_connection_preallocate_send_unlocked (DBusConnection *connection)
01711 {
01712 DBusPreallocatedSend *preallocated;
01713
01714 HAVE_LOCK_CHECK (connection);
01715
01716 _dbus_assert (connection != NULL);
01717
01718 preallocated = dbus_new (DBusPreallocatedSend, 1);
01719 if (preallocated == NULL)
01720 return NULL;
01721
01722 if (connection->link_cache != NULL)
01723 {
01724 preallocated->queue_link =
01725 _dbus_list_pop_first_link (&connection->link_cache);
01726 preallocated->queue_link->data = NULL;
01727 }
01728 else
01729 {
01730 preallocated->queue_link = _dbus_list_alloc_link (NULL);
01731 if (preallocated->queue_link == NULL)
01732 goto failed_0;
01733 }
01734
01735 if (connection->link_cache != NULL)
01736 {
01737 preallocated->counter_link =
01738 _dbus_list_pop_first_link (&connection->link_cache);
01739 preallocated->counter_link->data = connection->outgoing_counter;
01740 }
01741 else
01742 {
01743 preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter);
01744 if (preallocated->counter_link == NULL)
01745 goto failed_1;
01746 }
01747
01748 _dbus_counter_ref (preallocated->counter_link->data);
01749
01750 preallocated->connection = connection;
01751
01752 return preallocated;
01753
01754 failed_1:
01755 _dbus_list_free_link (preallocated->queue_link);
01756 failed_0:
01757 dbus_free (preallocated);
01758
01759 return NULL;
01760 }
01761
01771 DBusPreallocatedSend*
01772 dbus_connection_preallocate_send (DBusConnection *connection)
01773 {
01774 DBusPreallocatedSend *preallocated;
01775
01776 _dbus_return_val_if_fail (connection != NULL, NULL);
01777
01778 CONNECTION_LOCK (connection);
01779
01780 preallocated =
01781 _dbus_connection_preallocate_send_unlocked (connection);
01782
01783 CONNECTION_UNLOCK (connection);
01784
01785 return preallocated;
01786 }
01787
01797 void
01798 dbus_connection_free_preallocated_send (DBusConnection *connection,
01799 DBusPreallocatedSend *preallocated)
01800 {
01801 _dbus_return_if_fail (connection != NULL);
01802 _dbus_return_if_fail (preallocated != NULL);
01803 _dbus_return_if_fail (connection == preallocated->connection);
01804
01805 _dbus_list_free_link (preallocated->queue_link);
01806 _dbus_counter_unref (preallocated->counter_link->data);
01807 _dbus_list_free_link (preallocated->counter_link);
01808 dbus_free (preallocated);
01809 }
01810
01811
01812 static void
01813 _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *connection,
01814 DBusPreallocatedSend *preallocated,
01815 DBusMessage *message,
01816 dbus_uint32_t *client_serial)
01817 {
01818 dbus_uint32_t serial;
01819 const char *sig;
01820
01821 preallocated->queue_link->data = message;
01822 _dbus_list_prepend_link (&connection->outgoing_messages,
01823 preallocated->queue_link);
01824
01825 _dbus_message_add_size_counter_link (message,
01826 preallocated->counter_link);
01827
01828 dbus_free (preallocated);
01829 preallocated = NULL;
01830
01831 dbus_message_ref (message);
01832
01833 connection->n_outgoing += 1;
01834
01835 sig = dbus_message_get_signature (message);
01836
01837 _dbus_verbose ("Message %p (%d %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
01838 message,
01839 dbus_message_get_type (message),
01840 dbus_message_get_path (message),
01841 dbus_message_get_interface (message) ?
01842 dbus_message_get_interface (message) :
01843 "no interface",
01844 dbus_message_get_member (message) ?
01845 dbus_message_get_member (message) :
01846 "no member",
01847 sig,
01848 dbus_message_get_destination (message) ?
01849 dbus_message_get_destination (message) :
01850 "null",
01851 connection,
01852 connection->n_outgoing);
01853
01854 if (dbus_message_get_serial (message) == 0)
01855 {
01856 serial = _dbus_connection_get_next_client_serial (connection);
01857 _dbus_message_set_serial (message, serial);
01858 if (client_serial)
01859 *client_serial = serial;
01860 }
01861 else
01862 {
01863 if (client_serial)
01864 *client_serial = dbus_message_get_serial (message);
01865 }
01866
01867 _dbus_verbose ("Message %p serial is %u\n",
01868 message, dbus_message_get_serial (message));
01869
01870 _dbus_message_lock (message);
01871
01872
01873
01874
01875 _dbus_connection_do_iteration_unlocked (connection,
01876 DBUS_ITERATION_DO_WRITING,
01877 -1);
01878
01879
01880 if (connection->n_outgoing > 0)
01881 _dbus_connection_wakeup_mainloop (connection);
01882 }
01883
01884 static void
01885 _dbus_connection_send_preallocated_and_unlock (DBusConnection *connection,
01886 DBusPreallocatedSend *preallocated,
01887 DBusMessage *message,
01888 dbus_uint32_t *client_serial)
01889 {
01890 DBusDispatchStatus status;
01891
01892 HAVE_LOCK_CHECK (connection);
01893
01894 _dbus_connection_send_preallocated_unlocked_no_update (connection,
01895 preallocated,
01896 message, client_serial);
01897
01898 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
01899 status = _dbus_connection_get_dispatch_status_unlocked (connection);
01900
01901
01902 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01903 }
01904
01917 void
01918 dbus_connection_send_preallocated (DBusConnection *connection,
01919 DBusPreallocatedSend *preallocated,
01920 DBusMessage *message,
01921 dbus_uint32_t *client_serial)
01922 {
01923 _dbus_return_if_fail (connection != NULL);
01924 _dbus_return_if_fail (preallocated != NULL);
01925 _dbus_return_if_fail (message != NULL);
01926 _dbus_return_if_fail (preallocated->connection == connection);
01927 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
01928 (dbus_message_get_interface (message) != NULL &&
01929 dbus_message_get_member (message) != NULL));
01930 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
01931 (dbus_message_get_interface (message) != NULL &&
01932 dbus_message_get_member (message) != NULL));
01933
01934 CONNECTION_LOCK (connection);
01935 _dbus_connection_send_preallocated_and_unlock (connection,
01936 preallocated,
01937 message, client_serial);
01938 }
01939
01940 static dbus_bool_t
01941 _dbus_connection_send_unlocked_no_update (DBusConnection *connection,
01942 DBusMessage *message,
01943 dbus_uint32_t *client_serial)
01944 {
01945 DBusPreallocatedSend *preallocated;
01946
01947 _dbus_assert (connection != NULL);
01948 _dbus_assert (message != NULL);
01949
01950 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
01951 if (preallocated == NULL)
01952 return FALSE;
01953
01954 _dbus_connection_send_preallocated_unlocked_no_update (connection,
01955 preallocated,
01956 message,
01957 client_serial);
01958 return TRUE;
01959 }
01960
01961 dbus_bool_t
01962 _dbus_connection_send_and_unlock (DBusConnection *connection,
01963 DBusMessage *message,
01964 dbus_uint32_t *client_serial)
01965 {
01966 DBusPreallocatedSend *preallocated;
01967
01968 _dbus_assert (connection != NULL);
01969 _dbus_assert (message != NULL);
01970
01971 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
01972 if (preallocated == NULL)
01973 {
01974 CONNECTION_UNLOCK (connection);
01975 return FALSE;
01976 }
01977
01978 _dbus_connection_send_preallocated_and_unlock (connection,
01979 preallocated,
01980 message,
01981 client_serial);
01982 return TRUE;
01983 }
01984
02003 dbus_bool_t
02004 dbus_connection_send (DBusConnection *connection,
02005 DBusMessage *message,
02006 dbus_uint32_t *client_serial)
02007 {
02008 _dbus_return_val_if_fail (connection != NULL, FALSE);
02009 _dbus_return_val_if_fail (message != NULL, FALSE);
02010
02011 CONNECTION_LOCK (connection);
02012
02013 return _dbus_connection_send_and_unlock (connection,
02014 message,
02015 client_serial);
02016 }
02017
02018 static dbus_bool_t
02019 reply_handler_timeout (void *data)
02020 {
02021 DBusConnection *connection;
02022 DBusDispatchStatus status;
02023 DBusPendingCall *pending = data;
02024
02025 connection = pending->connection;
02026
02027 CONNECTION_LOCK (connection);
02028 if (pending->timeout_link)
02029 {
02030 _dbus_connection_queue_synthesized_message_link (connection,
02031 pending->timeout_link);
02032 pending->timeout_link = NULL;
02033 }
02034
02035 _dbus_connection_remove_timeout (connection,
02036 pending->timeout);
02037 pending->timeout_added = FALSE;
02038
02039 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
02040 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02041
02042
02043 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02044
02045 return TRUE;
02046 }
02047
02085 dbus_bool_t
02086 dbus_connection_send_with_reply (DBusConnection *connection,
02087 DBusMessage *message,
02088 DBusPendingCall **pending_return,
02089 int timeout_milliseconds)
02090 {
02091 DBusPendingCall *pending;
02092 DBusMessage *reply;
02093 DBusList *reply_link;
02094 dbus_int32_t serial = -1;
02095 DBusDispatchStatus status;
02096
02097 _dbus_return_val_if_fail (connection != NULL, FALSE);
02098 _dbus_return_val_if_fail (message != NULL, FALSE);
02099 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
02100
02101 if (pending_return)
02102 *pending_return = NULL;
02103
02104 pending = _dbus_pending_call_new (connection,
02105 timeout_milliseconds,
02106 reply_handler_timeout);
02107
02108 if (pending == NULL)
02109 return FALSE;
02110
02111 CONNECTION_LOCK (connection);
02112
02113
02114 if (dbus_message_get_serial (message) == 0)
02115 {
02116 serial = _dbus_connection_get_next_client_serial (connection);
02117 _dbus_message_set_serial (message, serial);
02118 }
02119
02120 pending->reply_serial = serial;
02121
02122 reply = dbus_message_new_error (message, DBUS_ERROR_NO_REPLY,
02123 "No reply within specified time");
02124 if (reply == NULL)
02125 goto error;
02126
02127 reply_link = _dbus_list_alloc_link (reply);
02128 if (reply_link == NULL)
02129 {
02130 CONNECTION_UNLOCK (connection);
02131 dbus_message_unref (reply);
02132 goto error_unlocked;
02133 }
02134
02135 pending->timeout_link = reply_link;
02136
02137
02138
02139
02140
02141 if (!_dbus_connection_attach_pending_call_unlocked (connection,
02142 pending))
02143 goto error;
02144
02145 if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
02146 {
02147 _dbus_connection_detach_pending_call_and_unlock (connection,
02148 pending);
02149 goto error_unlocked;
02150 }
02151
02152 if (pending_return)
02153 *pending_return = pending;
02154 else
02155 {
02156 _dbus_connection_detach_pending_call_unlocked (connection, pending);
02157 dbus_pending_call_unref (pending);
02158 }
02159
02160 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
02161 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02162
02163
02164 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02165
02166 return TRUE;
02167
02168 error:
02169 CONNECTION_UNLOCK (connection);
02170 error_unlocked:
02171 dbus_pending_call_unref (pending);
02172 return FALSE;
02173 }
02174
02175
02176
02177
02178 static DBusMessage*
02179 check_for_reply_unlocked (DBusConnection *connection,
02180 dbus_uint32_t client_serial)
02181 {
02182 DBusList *link;
02183
02184 HAVE_LOCK_CHECK (connection);
02185
02186 link = _dbus_list_get_first_link (&connection->incoming_messages);
02187
02188 while (link != NULL)
02189 {
02190 DBusMessage *reply = link->data;
02191
02192 if (dbus_message_get_reply_serial (reply) == client_serial)
02193 {
02194 _dbus_list_remove_link (&connection->incoming_messages, link);
02195 connection->n_incoming -= 1;
02196 return reply;
02197 }
02198 link = _dbus_list_get_next_link (&connection->incoming_messages, link);
02199 }
02200
02201 return NULL;
02202 }
02203
02218 void
02219 _dbus_connection_block_pending_call (DBusPendingCall *pending)
02220 {
02221 long start_tv_sec, start_tv_usec;
02222 long end_tv_sec, end_tv_usec;
02223 long tv_sec, tv_usec;
02224 DBusDispatchStatus status;
02225 DBusConnection *connection;
02226 dbus_uint32_t client_serial;
02227 int timeout_milliseconds;
02228
02229 _dbus_assert (pending != NULL);
02230
02231 if (dbus_pending_call_get_completed (pending))
02232 return;
02233
02234 if (pending->connection == NULL)
02235 return;
02236
02237 dbus_pending_call_ref (pending);
02238
02239 connection = pending->connection;
02240 client_serial = pending->reply_serial;
02241
02242
02243
02244
02245
02246 timeout_milliseconds = dbus_timeout_get_interval (pending->timeout);
02247
02248
02249 dbus_connection_flush (connection);
02250
02251 CONNECTION_LOCK (connection);
02252
02253 _dbus_get_current_time (&start_tv_sec, &start_tv_usec);
02254 end_tv_sec = start_tv_sec + timeout_milliseconds / 1000;
02255 end_tv_usec = start_tv_usec + (timeout_milliseconds % 1000) * 1000;
02256 end_tv_sec += end_tv_usec / _DBUS_USEC_PER_SECOND;
02257 end_tv_usec = end_tv_usec % _DBUS_USEC_PER_SECOND;
02258
02259 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec to %ld sec %ld usec\n",
02260 timeout_milliseconds,
02261 client_serial,
02262 start_tv_sec, start_tv_usec,
02263 end_tv_sec, end_tv_usec);
02264
02265
02266
02267 _dbus_connection_do_iteration_unlocked (connection,
02268 DBUS_ITERATION_DO_READING |
02269 DBUS_ITERATION_BLOCK,
02270 timeout_milliseconds);
02271
02272 recheck_status:
02273
02274 _dbus_verbose ("%s top of recheck\n", _DBUS_FUNCTION_NAME);
02275
02276 HAVE_LOCK_CHECK (connection);
02277
02278
02279
02280 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02281
02282
02283
02284
02285 if (dbus_pending_call_get_completed (pending))
02286 {
02287 _dbus_verbose ("Pending call completed by dispatch in %s\n", _DBUS_FUNCTION_NAME);
02288 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02289 dbus_pending_call_unref (pending);
02290 return;
02291 }
02292
02293 if (status == DBUS_DISPATCH_DATA_REMAINS)
02294 {
02295 DBusMessage *reply;
02296
02297 reply = check_for_reply_unlocked (connection, client_serial);
02298 if (reply != NULL)
02299 {
02300 _dbus_verbose ("%s checked for reply\n", _DBUS_FUNCTION_NAME);
02301
02302 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
02303
02304 _dbus_pending_call_complete_and_unlock (pending, reply);
02305 dbus_message_unref (reply);
02306
02307 CONNECTION_LOCK (connection);
02308 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02309 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02310 dbus_pending_call_unref (pending);
02311
02312 return;
02313 }
02314 }
02315
02316 _dbus_get_current_time (&tv_sec, &tv_usec);
02317
02318 if (!_dbus_connection_get_is_connected_unlocked (connection))
02319 {
02320
02321
02322
02323
02324
02325 _dbus_pending_call_complete_and_unlock (pending, NULL);
02326 dbus_pending_call_unref (pending);
02327 return;
02328 }
02329 else if (tv_sec < start_tv_sec)
02330 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
02331 else if (connection->disconnect_message_link == NULL)
02332 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
02333 else if (tv_sec < end_tv_sec ||
02334 (tv_sec == end_tv_sec && tv_usec < end_tv_usec))
02335 {
02336 timeout_milliseconds = (end_tv_sec - tv_sec) * 1000 +
02337 (end_tv_usec - tv_usec) / 1000;
02338 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds);
02339 _dbus_assert (timeout_milliseconds >= 0);
02340
02341 if (status == DBUS_DISPATCH_NEED_MEMORY)
02342 {
02343
02344
02345
02346
02347 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
02348
02349 if (timeout_milliseconds < 100)
02350 ;
02351 else if (timeout_milliseconds <= 1000)
02352 _dbus_sleep_milliseconds (timeout_milliseconds / 3);
02353 else
02354 _dbus_sleep_milliseconds (1000);
02355 }
02356 else
02357 {
02358
02359 _dbus_connection_do_iteration_unlocked (connection,
02360 DBUS_ITERATION_DO_READING |
02361 DBUS_ITERATION_BLOCK,
02362 timeout_milliseconds);
02363 }
02364
02365 goto recheck_status;
02366 }
02367
02368 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %ld milliseconds and got no reply\n",
02369 (tv_sec - start_tv_sec) * 1000 + (tv_usec - start_tv_usec) / 1000);
02370
02371 _dbus_assert (!dbus_pending_call_get_completed (pending));
02372
02373
02374 _dbus_pending_call_complete_and_unlock (pending, NULL);
02375
02376
02377 CONNECTION_LOCK (connection);
02378 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02379 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02380 dbus_pending_call_unref (pending);
02381 }
02382
02405 DBusMessage*
02406 dbus_connection_send_with_reply_and_block (DBusConnection *connection,
02407 DBusMessage *message,
02408 int timeout_milliseconds,
02409 DBusError *error)
02410 {
02411 DBusMessage *reply;
02412 DBusPendingCall *pending;
02413
02414 _dbus_return_val_if_fail (connection != NULL, NULL);
02415 _dbus_return_val_if_fail (message != NULL, NULL);
02416 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
02417 _dbus_return_val_if_error_is_set (error, NULL);
02418
02419 if (!dbus_connection_send_with_reply (connection, message,
02420 &pending, timeout_milliseconds))
02421 {
02422 _DBUS_SET_OOM (error);
02423 return NULL;
02424 }
02425
02426 _dbus_assert (pending != NULL);
02427
02428 dbus_pending_call_block (pending);
02429
02430 reply = dbus_pending_call_steal_reply (pending);
02431 dbus_pending_call_unref (pending);
02432
02433
02434
02435
02436 _dbus_assert (reply != NULL);
02437
02438 if (dbus_set_error_from_message (error, reply))
02439 {
02440 dbus_message_unref (reply);
02441 return NULL;
02442 }
02443 else
02444 return reply;
02445 }
02446
02452 void
02453 dbus_connection_flush (DBusConnection *connection)
02454 {
02455
02456
02457
02458
02459
02460 DBusDispatchStatus status;
02461
02462 _dbus_return_if_fail (connection != NULL);
02463
02464 CONNECTION_LOCK (connection);
02465 while (connection->n_outgoing > 0 &&
02466 _dbus_connection_get_is_connected_unlocked (connection))
02467 {
02468 _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME);
02469 HAVE_LOCK_CHECK (connection);
02470 _dbus_connection_do_iteration_unlocked (connection,
02471 DBUS_ITERATION_DO_READING |
02472 DBUS_ITERATION_DO_WRITING |
02473 DBUS_ITERATION_BLOCK,
02474 -1);
02475 }
02476
02477 HAVE_LOCK_CHECK (connection);
02478 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME);
02479 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02480
02481 HAVE_LOCK_CHECK (connection);
02482
02483 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02484
02485 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME);
02486 }
02487
02507 DBusMessage*
02508 dbus_connection_borrow_message (DBusConnection *connection)
02509 {
02510 DBusDispatchStatus status;
02511 DBusMessage *message;
02512
02513 _dbus_return_val_if_fail (connection != NULL, NULL);
02514
02515 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
02516
02517
02518
02519
02520 status = dbus_connection_get_dispatch_status (connection);
02521 if (status != DBUS_DISPATCH_DATA_REMAINS)
02522 return NULL;
02523
02524 CONNECTION_LOCK (connection);
02525
02526 _dbus_connection_acquire_dispatch (connection);
02527
02528
02529 _dbus_assert (connection->message_borrowed == NULL);
02530
02531 connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
02532
02533 message = connection->message_borrowed;
02534
02535
02536 if (message == NULL)
02537 _dbus_connection_release_dispatch (connection);
02538
02539 CONNECTION_UNLOCK (connection);
02540
02541 return message;
02542 }
02543
02552 void
02553 dbus_connection_return_message (DBusConnection *connection,
02554 DBusMessage *message)
02555 {
02556 _dbus_return_if_fail (connection != NULL);
02557 _dbus_return_if_fail (message != NULL);
02558 _dbus_return_if_fail (message == connection->message_borrowed);
02559 _dbus_return_if_fail (connection->dispatch_acquired);
02560
02561 CONNECTION_LOCK (connection);
02562
02563 _dbus_assert (message == connection->message_borrowed);
02564
02565 connection->message_borrowed = NULL;
02566
02567 _dbus_connection_release_dispatch (connection);
02568
02569 CONNECTION_UNLOCK (connection);
02570 }
02571
02581 void
02582 dbus_connection_steal_borrowed_message (DBusConnection *connection,
02583 DBusMessage *message)
02584 {
02585 DBusMessage *pop_message;
02586
02587 _dbus_return_if_fail (connection != NULL);
02588 _dbus_return_if_fail (message != NULL);
02589 _dbus_return_if_fail (message == connection->message_borrowed);
02590 _dbus_return_if_fail (connection->dispatch_acquired);
02591
02592 CONNECTION_LOCK (connection);
02593
02594 _dbus_assert (message == connection->message_borrowed);
02595
02596 pop_message = _dbus_list_pop_first (&connection->incoming_messages);
02597 _dbus_assert (message == pop_message);
02598
02599 connection->n_incoming -= 1;
02600
02601 _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
02602 message, connection->n_incoming);
02603
02604 connection->message_borrowed = NULL;
02605
02606 _dbus_connection_release_dispatch (connection);
02607
02608 CONNECTION_UNLOCK (connection);
02609 }
02610
02611
02612
02613
02614 static DBusList*
02615 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
02616 {
02617 HAVE_LOCK_CHECK (connection);
02618
02619 _dbus_assert (connection->message_borrowed == NULL);
02620
02621 if (connection->n_incoming > 0)
02622 {
02623 DBusList *link;
02624
02625 link = _dbus_list_pop_first_link (&connection->incoming_messages);
02626 connection->n_incoming -= 1;
02627
02628 _dbus_verbose ("Message %p (%d %s %s %s '%s') removed from incoming queue %p, %d incoming\n",
02629 link->data,
02630 dbus_message_get_type (link->data),
02631 dbus_message_get_path (link->data),
02632 dbus_message_get_interface (link->data) ?
02633 dbus_message_get_interface (link->data) :
02634 "no interface",
02635 dbus_message_get_member (link->data) ?
02636 dbus_message_get_member (link->data) :
02637 "no member",
02638 dbus_message_get_signature (link->data),
02639 connection, connection->n_incoming);
02640
02641 return link;
02642 }
02643 else
02644 return NULL;
02645 }
02646
02647
02648
02649
02650 static DBusMessage*
02651 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
02652 {
02653 DBusList *link;
02654
02655 HAVE_LOCK_CHECK (connection);
02656
02657 link = _dbus_connection_pop_message_link_unlocked (connection);
02658
02659 if (link != NULL)
02660 {
02661 DBusMessage *message;
02662
02663 message = link->data;
02664
02665 _dbus_list_free_link (link);
02666
02667 return message;
02668 }
02669 else
02670 return NULL;
02671 }
02672
02673 static void
02674 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
02675 DBusList *message_link)
02676 {
02677 HAVE_LOCK_CHECK (connection);
02678
02679 _dbus_assert (message_link != NULL);
02680
02681 _dbus_assert (connection->message_borrowed == NULL);
02682
02683 _dbus_assert (connection->dispatch_acquired);
02684
02685 _dbus_list_prepend_link (&connection->incoming_messages,
02686 message_link);
02687 connection->n_incoming += 1;
02688
02689 _dbus_verbose ("Message %p (%d %s %s '%s') put back into queue %p, %d incoming\n",
02690 message_link->data,
02691 dbus_message_get_type (message_link->data),
02692 dbus_message_get_interface (message_link->data) ?
02693 dbus_message_get_interface (message_link->data) :
02694 "no interface",
02695 dbus_message_get_member (message_link->data) ?
02696 dbus_message_get_member (message_link->data) :
02697 "no member",
02698 dbus_message_get_signature (message_link->data),
02699 connection, connection->n_incoming);
02700 }
02701
02721 DBusMessage*
02722 dbus_connection_pop_message (DBusConnection *connection)
02723 {
02724 DBusMessage *message;
02725 DBusDispatchStatus status;
02726
02727 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
02728
02729
02730
02731
02732 status = dbus_connection_get_dispatch_status (connection);
02733 if (status != DBUS_DISPATCH_DATA_REMAINS)
02734 return NULL;
02735
02736 CONNECTION_LOCK (connection);
02737 _dbus_connection_acquire_dispatch (connection);
02738 HAVE_LOCK_CHECK (connection);
02739
02740 message = _dbus_connection_pop_message_unlocked (connection);
02741
02742 _dbus_verbose ("Returning popped message %p\n", message);
02743
02744 _dbus_connection_release_dispatch (connection);
02745 CONNECTION_UNLOCK (connection);
02746
02747 return message;
02748 }
02749
02757 static void
02758 _dbus_connection_acquire_dispatch (DBusConnection *connection)
02759 {
02760 HAVE_LOCK_CHECK (connection);
02761
02762 _dbus_connection_ref_unlocked (connection);
02763 CONNECTION_UNLOCK (connection);
02764
02765 _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
02766 dbus_mutex_lock (connection->dispatch_mutex);
02767
02768 while (connection->dispatch_acquired)
02769 {
02770 _dbus_verbose ("%s waiting for dispatch to be acquirable\n", _DBUS_FUNCTION_NAME);
02771 dbus_condvar_wait (connection->dispatch_cond, connection->dispatch_mutex);
02772 }
02773
02774 _dbus_assert (!connection->dispatch_acquired);
02775
02776 connection->dispatch_acquired = TRUE;
02777
02778 _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
02779 dbus_mutex_unlock (connection->dispatch_mutex);
02780
02781 CONNECTION_LOCK (connection);
02782 _dbus_connection_unref_unlocked (connection);
02783 }
02784
02792 static void
02793 _dbus_connection_release_dispatch (DBusConnection *connection)
02794 {
02795 HAVE_LOCK_CHECK (connection);
02796
02797 _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
02798 dbus_mutex_lock (connection->dispatch_mutex);
02799
02800 _dbus_assert (connection->dispatch_acquired);
02801
02802 connection->dispatch_acquired = FALSE;
02803 dbus_condvar_wake_one (connection->dispatch_cond);
02804
02805 _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME);
02806 dbus_mutex_unlock (connection->dispatch_mutex);
02807 }
02808
02809 static void
02810 _dbus_connection_failed_pop (DBusConnection *connection,
02811 DBusList *message_link)
02812 {
02813 _dbus_list_prepend_link (&connection->incoming_messages,
02814 message_link);
02815 connection->n_incoming += 1;
02816 }
02817
02818 static DBusDispatchStatus
02819 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
02820 {
02821 HAVE_LOCK_CHECK (connection);
02822
02823 if (connection->n_incoming > 0)
02824 return DBUS_DISPATCH_DATA_REMAINS;
02825 else if (!_dbus_transport_queue_messages (connection->transport))
02826 return DBUS_DISPATCH_NEED_MEMORY;
02827 else
02828 {
02829 DBusDispatchStatus status;
02830 dbus_bool_t is_connected;
02831
02832 status = _dbus_transport_get_dispatch_status (connection->transport);
02833 is_connected = _dbus_transport_get_is_connected (connection->transport);
02834
02835 _dbus_verbose ("dispatch status = %s is_connected = %d\n",
02836 DISPATCH_STATUS_NAME (status), is_connected);
02837
02838 if (!is_connected)
02839 {
02840 if (status == DBUS_DISPATCH_COMPLETE &&
02841 connection->disconnect_message_link)
02842 {
02843 _dbus_verbose ("Sending disconnect message from %s\n",
02844 _DBUS_FUNCTION_NAME);
02845
02846
02847
02848
02849 _dbus_connection_queue_synthesized_message_link (connection,
02850 connection->disconnect_message_link);
02851 connection->disconnect_message_link = NULL;
02852 }
02853
02854
02855
02856
02857
02858 if (connection->n_outgoing > 0)
02859 {
02860 DBusList *link;
02861
02862 _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
02863 connection->n_outgoing);
02864
02865 while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
02866 {
02867 _dbus_connection_message_sent (connection, link->data);
02868 }
02869 }
02870 }
02871
02872 if (status != DBUS_DISPATCH_COMPLETE)
02873 return status;
02874 else if (connection->n_incoming > 0)
02875 return DBUS_DISPATCH_DATA_REMAINS;
02876 else
02877 return DBUS_DISPATCH_COMPLETE;
02878 }
02879 }
02880
02881 static void
02882 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
02883 DBusDispatchStatus new_status)
02884 {
02885 dbus_bool_t changed;
02886 DBusDispatchStatusFunction function;
02887 void *data;
02888
02889 HAVE_LOCK_CHECK (connection);
02890
02891 _dbus_connection_ref_unlocked (connection);
02892
02893 changed = new_status != connection->last_dispatch_status;
02894
02895 connection->last_dispatch_status = new_status;
02896
02897 function = connection->dispatch_status_function;
02898 data = connection->dispatch_status_data;
02899
02900
02901 CONNECTION_UNLOCK (connection);
02902
02903 if (changed && function)
02904 {
02905 _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
02906 connection, new_status,
02907 DISPATCH_STATUS_NAME (new_status));
02908 (* function) (connection, new_status, data);
02909 }
02910
02911 dbus_connection_unref (connection);
02912 }
02913
02922 DBusDispatchStatus
02923 dbus_connection_get_dispatch_status (DBusConnection *connection)
02924 {
02925 DBusDispatchStatus status;
02926
02927 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
02928
02929 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME);
02930
02931 CONNECTION_LOCK (connection);
02932
02933 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02934
02935 CONNECTION_UNLOCK (connection);
02936
02937 return status;
02938 }
02939
02963 DBusDispatchStatus
02964 dbus_connection_dispatch (DBusConnection *connection)
02965 {
02966 DBusMessage *message;
02967 DBusList *link, *filter_list_copy, *message_link;
02968 DBusHandlerResult result;
02969 DBusPendingCall *pending;
02970 dbus_int32_t reply_serial;
02971 DBusDispatchStatus status;
02972
02973 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
02974
02975 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME);
02976
02977 CONNECTION_LOCK (connection);
02978 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02979 if (status != DBUS_DISPATCH_DATA_REMAINS)
02980 {
02981
02982 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02983 return status;
02984 }
02985
02986
02987
02988
02989 _dbus_connection_ref_unlocked (connection);
02990
02991 _dbus_connection_acquire_dispatch (connection);
02992 HAVE_LOCK_CHECK (connection);
02993
02994 message_link = _dbus_connection_pop_message_link_unlocked (connection);
02995 if (message_link == NULL)
02996 {
02997
02998
02999 _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
03000
03001 _dbus_connection_release_dispatch (connection);
03002
03003 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03004
03005 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03006
03007 dbus_connection_unref (connection);
03008
03009 return status;
03010 }
03011
03012 message = message_link->data;
03013
03014 _dbus_verbose (" dispatching message %p (%d %s %s '%s')\n",
03015 message,
03016 dbus_message_get_type (message),
03017 dbus_message_get_interface (message) ?
03018 dbus_message_get_interface (message) :
03019 "no interface",
03020 dbus_message_get_member (message) ?
03021 dbus_message_get_member (message) :
03022 "no member",
03023 dbus_message_get_signature (message));
03024
03025 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
03026
03027
03028
03029
03030
03031
03032
03033
03034 reply_serial = dbus_message_get_reply_serial (message);
03035 pending = _dbus_hash_table_lookup_int (connection->pending_replies,
03036 reply_serial);
03037 if (pending)
03038 {
03039 _dbus_verbose ("Dispatching a pending reply\n");
03040 _dbus_pending_call_complete_and_unlock (pending, message);
03041 pending = NULL;
03042
03043 CONNECTION_LOCK (connection);
03044 _dbus_verbose ("pending call completed in dispatch\n");
03045 result = DBUS_HANDLER_RESULT_HANDLED;
03046 goto out;
03047 }
03048
03049 if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
03050 {
03051 _dbus_connection_release_dispatch (connection);
03052 HAVE_LOCK_CHECK (connection);
03053
03054 _dbus_connection_failed_pop (connection, message_link);
03055
03056
03057 _dbus_connection_update_dispatch_status_and_unlock (connection,
03058 DBUS_DISPATCH_NEED_MEMORY);
03059
03060 if (pending)
03061 dbus_pending_call_unref (pending);
03062 dbus_connection_unref (connection);
03063
03064 return DBUS_DISPATCH_NEED_MEMORY;
03065 }
03066
03067 _dbus_list_foreach (&filter_list_copy,
03068 (DBusForeachFunction)_dbus_message_filter_ref,
03069 NULL);
03070
03071
03072
03073
03074 CONNECTION_UNLOCK (connection);
03075
03076 link = _dbus_list_get_first_link (&filter_list_copy);
03077 while (link != NULL)
03078 {
03079 DBusMessageFilter *filter = link->data;
03080 DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
03081
03082 _dbus_verbose (" running filter on message %p\n", message);
03083 result = (* filter->function) (connection, message, filter->user_data);
03084
03085 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
03086 break;
03087
03088 link = next;
03089 }
03090
03091 _dbus_list_foreach (&filter_list_copy,
03092 (DBusForeachFunction)_dbus_message_filter_unref,
03093 NULL);
03094 _dbus_list_clear (&filter_list_copy);
03095
03096 CONNECTION_LOCK (connection);
03097
03098 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
03099 {
03100 _dbus_verbose ("No memory in %s\n", _DBUS_FUNCTION_NAME);
03101 goto out;
03102 }
03103 else if (result == DBUS_HANDLER_RESULT_HANDLED)
03104 {
03105 _dbus_verbose ("filter handled message in dispatch\n");
03106 goto out;
03107 }
03108
03109
03110
03111
03112 _dbus_verbose (" running object path dispatch on message %p (%d %s %s '%s')\n",
03113 message,
03114 dbus_message_get_type (message),
03115 dbus_message_get_interface (message) ?
03116 dbus_message_get_interface (message) :
03117 "no interface",
03118 dbus_message_get_member (message) ?
03119 dbus_message_get_member (message) :
03120 "no member",
03121 dbus_message_get_signature (message));
03122
03123 HAVE_LOCK_CHECK (connection);
03124 result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
03125 message);
03126
03127 CONNECTION_LOCK (connection);
03128
03129 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
03130 {
03131 _dbus_verbose ("object tree handled message in dispatch\n");
03132 goto out;
03133 }
03134
03135 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
03136 {
03137 DBusMessage *reply;
03138 DBusString str;
03139 DBusPreallocatedSend *preallocated;
03140
03141 _dbus_verbose (" sending error %s\n",
03142 DBUS_ERROR_UNKNOWN_METHOD);
03143
03144 if (!_dbus_string_init (&str))
03145 {
03146 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
03147 _dbus_verbose ("no memory for error string in dispatch\n");
03148 goto out;
03149 }
03150
03151 if (!_dbus_string_append_printf (&str,
03152 "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
03153 dbus_message_get_member (message),
03154 dbus_message_get_signature (message),
03155 dbus_message_get_interface (message)))
03156 {
03157 _dbus_string_free (&str);
03158 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
03159 _dbus_verbose ("no memory for error string in dispatch\n");
03160 goto out;
03161 }
03162
03163 reply = dbus_message_new_error (message,
03164 DBUS_ERROR_UNKNOWN_METHOD,
03165 _dbus_string_get_const_data (&str));
03166 _dbus_string_free (&str);
03167
03168 if (reply == NULL)
03169 {
03170 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
03171 _dbus_verbose ("no memory for error reply in dispatch\n");
03172 goto out;
03173 }
03174
03175 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
03176
03177 if (preallocated == NULL)
03178 {
03179 dbus_message_unref (reply);
03180 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
03181 _dbus_verbose ("no memory for error send in dispatch\n");
03182 goto out;
03183 }
03184
03185 _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
03186 reply, NULL);
03187
03188 dbus_message_unref (reply);
03189
03190 result = DBUS_HANDLER_RESULT_HANDLED;
03191 }
03192
03193 _dbus_verbose (" done dispatching %p (%d %s %s '%s') on connection %p\n", message,
03194 dbus_message_get_type (message),
03195 dbus_message_get_interface (message) ?
03196 dbus_message_get_interface (message) :
03197 "no interface",
03198 dbus_message_get_member (message) ?
03199 dbus_message_get_member (message) :
03200 "no member",
03201 dbus_message_get_signature (message),
03202 connection);
03203
03204 out:
03205 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
03206 {
03207 _dbus_verbose ("out of memory in %s\n", _DBUS_FUNCTION_NAME);
03208
03209
03210
03211
03212
03213 _dbus_connection_putback_message_link_unlocked (connection,
03214 message_link);
03215 }
03216 else
03217 {
03218 _dbus_verbose (" ... done dispatching in %s\n", _DBUS_FUNCTION_NAME);
03219
03220 if (connection->exit_on_disconnect &&
03221 dbus_message_is_signal (message,
03222 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
03223 "Disconnected"))
03224 {
03225 _dbus_verbose ("Exiting on Disconnected signal\n");
03226 CONNECTION_UNLOCK (connection);
03227 _dbus_exit (1);
03228 _dbus_assert_not_reached ("Call to exit() returned");
03229 }
03230
03231 _dbus_list_free_link (message_link);
03232 dbus_message_unref (message);
03233
03234
03235 }
03236
03237 _dbus_connection_release_dispatch (connection);
03238 HAVE_LOCK_CHECK (connection);
03239
03240 _dbus_verbose ("%s before final status update\n", _DBUS_FUNCTION_NAME);
03241 status = _dbus_connection_get_dispatch_status_unlocked (connection);
03242
03243
03244 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
03245
03246 dbus_connection_unref (connection);
03247
03248 return status;
03249 }
03250
03309 dbus_bool_t
03310 dbus_connection_set_watch_functions (DBusConnection *connection,
03311 DBusAddWatchFunction add_function,
03312 DBusRemoveWatchFunction remove_function,
03313 DBusWatchToggledFunction toggled_function,
03314 void *data,
03315 DBusFreeFunction free_data_function)
03316 {
03317 dbus_bool_t retval;
03318 DBusWatchList *watches;
03319
03320 _dbus_return_val_if_fail (connection != NULL, FALSE);
03321
03322 CONNECTION_LOCK (connection);
03323
03324 #ifndef DBUS_DISABLE_CHECKS
03325 if (connection->watches == NULL)
03326 {
03327 _dbus_warn ("Re-entrant call to %s is not allowed\n",
03328 _DBUS_FUNCTION_NAME);
03329 return FALSE;
03330 }
03331 #endif
03332
03333
03334 _dbus_connection_ref_unlocked (connection);
03335
03336
03337
03338
03339
03340 watches = connection->watches;
03341 connection->watches = NULL;
03342 CONNECTION_UNLOCK (connection);
03343
03344 retval = _dbus_watch_list_set_functions (watches,
03345 add_function, remove_function,
03346 toggled_function,
03347 data, free_data_function);
03348 CONNECTION_LOCK (connection);
03349 connection->watches = watches;
03350
03351 CONNECTION_UNLOCK (connection);
03352
03353 dbus_connection_unref (connection);
03354
03355 return retval;
03356 }
03357
03391 dbus_bool_t
03392 dbus_connection_set_timeout_functions (DBusConnection *connection,
03393 DBusAddTimeoutFunction add_function,
03394 DBusRemoveTimeoutFunction remove_function,
03395 DBusTimeoutToggledFunction toggled_function,
03396 void *data,
03397 DBusFreeFunction free_data_function)
03398 {
03399 dbus_bool_t retval;
03400 DBusTimeoutList *timeouts;
03401
03402 _dbus_return_val_if_fail (connection != NULL, FALSE);
03403
03404 CONNECTION_LOCK (connection);
03405
03406 #ifndef DBUS_DISABLE_CHECKS
03407 if (connection->timeouts == NULL)
03408 {
03409 _dbus_warn ("Re-entrant call to %s is not allowed\n",
03410 _DBUS_FUNCTION_NAME);
03411 return FALSE;
03412 }
03413 #endif
03414
03415
03416 _dbus_connection_ref_unlocked (connection);
03417
03418 timeouts = connection->timeouts;
03419 connection->timeouts = NULL;
03420 CONNECTION_UNLOCK (connection);
03421
03422 retval = _dbus_timeout_list_set_functions (timeouts,
03423 add_function, remove_function,
03424 toggled_function,
03425 data, free_data_function);
03426 CONNECTION_LOCK (connection);
03427 connection->timeouts = timeouts;
03428
03429 CONNECTION_UNLOCK (connection);
03430
03431 dbus_connection_unref (connection);
03432
03433 return retval;
03434 }
03435
03450 void
03451 dbus_connection_set_wakeup_main_function (DBusConnection *connection,
03452 DBusWakeupMainFunction wakeup_main_function,
03453 void *data,
03454 DBusFreeFunction free_data_function)
03455 {
03456 void *old_data;
03457 DBusFreeFunction old_free_data;
03458
03459 _dbus_return_if_fail (connection != NULL);
03460
03461 CONNECTION_LOCK (connection);
03462 old_data = connection->wakeup_main_data;
03463 old_free_data = connection->free_wakeup_main_data;
03464
03465 connection->wakeup_main_function = wakeup_main_function;
03466 connection->wakeup_main_data = data;
03467 connection->free_wakeup_main_data = free_data_function;
03468
03469 CONNECTION_UNLOCK (connection);
03470
03471
03472 if (old_free_data)
03473 (*old_free_data) (old_data);
03474 }
03475
03492 void
03493 dbus_connection_set_dispatch_status_function (DBusConnection *connection,
03494 DBusDispatchStatusFunction function,
03495 void *data,
03496 DBusFreeFunction free_data_function)
03497 {
03498 void *old_data;
03499 DBusFreeFunction old_free_data;
03500
03501 _dbus_return_if_fail (connection != NULL);
03502
03503 CONNECTION_LOCK (connection);
03504 old_data = connection->dispatch_status_data;
03505 old_free_data = connection->free_dispatch_status_data;
03506
03507 connection->dispatch_status_function = function;
03508 connection->dispatch_status_data = data;
03509 connection->free_dispatch_status_data = free_data_function;
03510
03511 CONNECTION_UNLOCK (connection);
03512
03513
03514 if (old_free_data)
03515 (*old_free_data) (old_data);
03516 }
03517
03530 dbus_bool_t
03531 dbus_connection_get_unix_fd (DBusConnection *connection,
03532 int *fd)
03533 {
03534 dbus_bool_t retval;
03535
03536 _dbus_return_val_if_fail (connection != NULL, FALSE);
03537 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
03538
03539 CONNECTION_LOCK (connection);
03540
03541 retval = _dbus_transport_get_unix_fd (connection->transport,
03542 fd);
03543
03544 CONNECTION_UNLOCK (connection);
03545
03546 return retval;
03547 }
03548
03560 dbus_bool_t
03561 dbus_connection_get_unix_user (DBusConnection *connection,
03562 unsigned long *uid)
03563 {
03564 dbus_bool_t result;
03565
03566 _dbus_return_val_if_fail (connection != NULL, FALSE);
03567 _dbus_return_val_if_fail (uid != NULL, FALSE);
03568
03569 CONNECTION_LOCK (connection);
03570
03571 if (!_dbus_transport_get_is_authenticated (connection->transport))
03572 result = FALSE;
03573 else
03574 result = _dbus_transport_get_unix_user (connection->transport,
03575 uid);
03576 CONNECTION_UNLOCK (connection);
03577
03578 return result;
03579 }
03580
03591 dbus_bool_t
03592 dbus_connection_get_unix_process_id (DBusConnection *connection,
03593 unsigned long *pid)
03594 {
03595 dbus_bool_t result;
03596
03597 _dbus_return_val_if_fail (connection != NULL, FALSE);
03598 _dbus_return_val_if_fail (pid != NULL, FALSE);
03599
03600 CONNECTION_LOCK (connection);
03601
03602 if (!_dbus_transport_get_is_authenticated (connection->transport))
03603 result = FALSE;
03604 else
03605 result = _dbus_transport_get_unix_process_id (connection->transport,
03606 pid);
03607 CONNECTION_UNLOCK (connection);
03608
03609 return result;
03610 }
03611
03628 void
03629 dbus_connection_set_unix_user_function (DBusConnection *connection,
03630 DBusAllowUnixUserFunction function,
03631 void *data,
03632 DBusFreeFunction free_data_function)
03633 {
03634 void *old_data = NULL;
03635 DBusFreeFunction old_free_function = NULL;
03636
03637 _dbus_return_if_fail (connection != NULL);
03638
03639 CONNECTION_LOCK (connection);
03640 _dbus_transport_set_unix_user_function (connection->transport,
03641 function, data, free_data_function,
03642 &old_data, &old_free_function);
03643 CONNECTION_UNLOCK (connection);
03644
03645 if (old_free_function != NULL)
03646 (* old_free_function) (old_data);
03647 }
03648
03670 dbus_bool_t
03671 dbus_connection_add_filter (DBusConnection *connection,
03672 DBusHandleMessageFunction function,
03673 void *user_data,
03674 DBusFreeFunction free_data_function)
03675 {
03676 DBusMessageFilter *filter;
03677
03678 _dbus_return_val_if_fail (connection != NULL, FALSE);
03679 _dbus_return_val_if_fail (function != NULL, FALSE);
03680
03681 filter = dbus_new0 (DBusMessageFilter, 1);
03682 if (filter == NULL)
03683 return FALSE;
03684
03685 filter->refcount.value = 1;
03686
03687 CONNECTION_LOCK (connection);
03688
03689 if (!_dbus_list_append (&connection->filter_list,
03690 filter))
03691 {
03692 _dbus_message_filter_unref (filter);
03693 CONNECTION_UNLOCK (connection);
03694 return FALSE;
03695 }
03696
03697
03698
03699
03700
03701
03702 filter->function = function;
03703 filter->user_data = user_data;
03704 filter->free_user_data_function = free_data_function;
03705
03706 CONNECTION_UNLOCK (connection);
03707 return TRUE;
03708 }
03709
03722 void
03723 dbus_connection_remove_filter (DBusConnection *connection,
03724 DBusHandleMessageFunction function,
03725 void *user_data)
03726 {
03727 DBusList *link;
03728 DBusMessageFilter *filter;
03729
03730 _dbus_return_if_fail (connection != NULL);
03731 _dbus_return_if_fail (function != NULL);
03732
03733 CONNECTION_LOCK (connection);
03734
03735 filter = NULL;
03736
03737 link = _dbus_list_get_last_link (&connection->filter_list);
03738 while (link != NULL)
03739 {
03740 filter = link->data;
03741
03742 if (filter->function == function &&
03743 filter->user_data == user_data)
03744 {
03745 _dbus_list_remove_link (&connection->filter_list, link);
03746 filter->function = NULL;
03747
03748 break;
03749 }
03750
03751 link = _dbus_list_get_prev_link (&connection->filter_list, link);
03752 }
03753
03754 CONNECTION_UNLOCK (connection);
03755
03756 #ifndef DBUS_DISABLE_CHECKS
03757 if (filter == NULL)
03758 {
03759 _dbus_warn ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
03760 function, user_data);
03761 return;
03762 }
03763 #endif
03764
03765
03766 if (filter->free_user_data_function)
03767 (* filter->free_user_data_function) (filter->user_data);
03768
03769 filter->free_user_data_function = NULL;
03770 filter->user_data = NULL;
03771
03772 _dbus_message_filter_unref (filter);
03773 }
03774
03786 dbus_bool_t
03787 dbus_connection_register_object_path (DBusConnection *connection,
03788 const char *path,
03789 const DBusObjectPathVTable *vtable,
03790 void *user_data)
03791 {
03792 char **decomposed_path;
03793 dbus_bool_t retval;
03794
03795 _dbus_return_val_if_fail (connection != NULL, FALSE);
03796 _dbus_return_val_if_fail (path != NULL, FALSE);
03797 _dbus_return_val_if_fail (path[0] == '/', FALSE);
03798 _dbus_return_val_if_fail (vtable != NULL, FALSE);
03799
03800 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
03801 return FALSE;
03802
03803 CONNECTION_LOCK (connection);
03804
03805 retval = _dbus_object_tree_register (connection->objects,
03806 FALSE,
03807 (const char **) decomposed_path, vtable,
03808 user_data);
03809
03810 CONNECTION_UNLOCK (connection);
03811
03812 dbus_free_string_array (decomposed_path);
03813
03814 return retval;
03815 }
03816
03829 dbus_bool_t
03830 dbus_connection_register_fallback (DBusConnection *connection,
03831 const char *path,
03832 const DBusObjectPathVTable *vtable,
03833 void *user_data)
03834 {
03835 char **decomposed_path;
03836 dbus_bool_t retval;
03837
03838 _dbus_return_val_if_fail (connection != NULL, FALSE);
03839 _dbus_return_val_if_fail (path != NULL, FALSE);
03840 _dbus_return_val_if_fail (path[0] == '/', FALSE);
03841 _dbus_return_val_if_fail (vtable != NULL, FALSE);
03842
03843 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
03844 return FALSE;
03845
03846 CONNECTION_LOCK (connection);
03847
03848 retval = _dbus_object_tree_register (connection->objects,
03849 TRUE,
03850 (const char **) decomposed_path, vtable,
03851 user_data);
03852
03853 CONNECTION_UNLOCK (connection);
03854
03855 dbus_free_string_array (decomposed_path);
03856
03857 return retval;
03858 }
03859
03869 dbus_bool_t
03870 dbus_connection_unregister_object_path (DBusConnection *connection,
03871 const char *path)
03872 {
03873 char **decomposed_path;
03874
03875 _dbus_return_val_if_fail (connection != NULL, FALSE);
03876 _dbus_return_val_if_fail (path != NULL, FALSE);
03877 _dbus_return_val_if_fail (path[0] == '/', FALSE);
03878
03879 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
03880 return FALSE;
03881
03882 CONNECTION_LOCK (connection);
03883
03884 _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
03885
03886 dbus_free_string_array (decomposed_path);
03887
03888 return TRUE;
03889 }
03890
03901 dbus_bool_t
03902 dbus_connection_list_registered (DBusConnection *connection,
03903 const char *parent_path,
03904 char ***child_entries)
03905 {
03906 char **decomposed_path;
03907 dbus_bool_t retval;
03908 _dbus_return_val_if_fail (connection != NULL, FALSE);
03909 _dbus_return_val_if_fail (parent_path != NULL, FALSE);
03910 _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
03911 _dbus_return_val_if_fail (child_entries != NULL, FALSE);
03912
03913 if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
03914 return FALSE;
03915
03916 CONNECTION_LOCK (connection);
03917
03918 retval = _dbus_object_tree_list_registered_and_unlock (connection->objects,
03919 (const char **) decomposed_path,
03920 child_entries);
03921 dbus_free_string_array (decomposed_path);
03922
03923 return retval;
03924 }
03925
03926 static DBusDataSlotAllocator slot_allocator;
03927 _DBUS_DEFINE_GLOBAL_LOCK (connection_slots);
03928
03943 dbus_bool_t
03944 dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
03945 {
03946 return _dbus_data_slot_allocator_alloc (&slot_allocator,
03947 _DBUS_LOCK_NAME (connection_slots),
03948 slot_p);
03949 }
03950
03962 void
03963 dbus_connection_free_data_slot (dbus_int32_t *slot_p)
03964 {
03965 _dbus_return_if_fail (*slot_p >= 0);
03966
03967 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
03968 }
03969
03983 dbus_bool_t
03984 dbus_connection_set_data (DBusConnection *connection,
03985 dbus_int32_t slot,
03986 void *data,
03987 DBusFreeFunction free_data_func)
03988 {
03989 DBusFreeFunction old_free_func;
03990 void *old_data;
03991 dbus_bool_t retval;
03992
03993 _dbus_return_val_if_fail (connection != NULL, FALSE);
03994 _dbus_return_val_if_fail (slot >= 0, FALSE);
03995
03996 CONNECTION_LOCK (connection);
03997
03998 retval = _dbus_data_slot_list_set (&slot_allocator,
03999 &connection->slot_list,
04000 slot, data, free_data_func,
04001 &old_free_func, &old_data);
04002
04003 CONNECTION_UNLOCK (connection);
04004
04005 if (retval)
04006 {
04007
04008 if (old_free_func)
04009 (* old_free_func) (old_data);
04010 }
04011
04012 return retval;
04013 }
04014
04023 void*
04024 dbus_connection_get_data (DBusConnection *connection,
04025 dbus_int32_t slot)
04026 {
04027 void *res;
04028
04029 _dbus_return_val_if_fail (connection != NULL, NULL);
04030
04031 CONNECTION_LOCK (connection);
04032
04033 res = _dbus_data_slot_list_get (&slot_allocator,
04034 &connection->slot_list,
04035 slot);
04036
04037 CONNECTION_UNLOCK (connection);
04038
04039 return res;
04040 }
04041
04048 void
04049 dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
04050 {
04051 _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
04052 }
04053
04062 void
04063 dbus_connection_set_max_message_size (DBusConnection *connection,
04064 long size)
04065 {
04066 _dbus_return_if_fail (connection != NULL);
04067
04068 CONNECTION_LOCK (connection);
04069 _dbus_transport_set_max_message_size (connection->transport,
04070 size);
04071 CONNECTION_UNLOCK (connection);
04072 }
04073
04080 long
04081 dbus_connection_get_max_message_size (DBusConnection *connection)
04082 {
04083 long res;
04084
04085 _dbus_return_val_if_fail (connection != NULL, 0);
04086
04087 CONNECTION_LOCK (connection);
04088 res = _dbus_transport_get_max_message_size (connection->transport);
04089 CONNECTION_UNLOCK (connection);
04090 return res;
04091 }
04092
04118 void
04119 dbus_connection_set_max_received_size (DBusConnection *connection,
04120 long size)
04121 {
04122 _dbus_return_if_fail (connection != NULL);
04123
04124 CONNECTION_LOCK (connection);
04125 _dbus_transport_set_max_received_size (connection->transport,
04126 size);
04127 CONNECTION_UNLOCK (connection);
04128 }
04129
04136 long
04137 dbus_connection_get_max_received_size (DBusConnection *connection)
04138 {
04139 long res;
04140
04141 _dbus_return_val_if_fail (connection != NULL, 0);
04142
04143 CONNECTION_LOCK (connection);
04144 res = _dbus_transport_get_max_received_size (connection->transport);
04145 CONNECTION_UNLOCK (connection);
04146 return res;
04147 }
04148
04159 long
04160 dbus_connection_get_outgoing_size (DBusConnection *connection)
04161 {
04162 long res;
04163
04164 _dbus_return_val_if_fail (connection != NULL, 0);
04165
04166 CONNECTION_LOCK (connection);
04167 res = _dbus_counter_get_value (connection->outgoing_counter);
04168 CONNECTION_UNLOCK (connection);
04169 return res;
04170 }
04171