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-connection.h"
00026 #include "dbus-list.h"
00027 #include "dbus-timeout.h"
00028 #include "dbus-transport.h"
00029 #include "dbus-watch.h"
00030 #include "dbus-connection-internal.h"
00031 #include "dbus-list.h"
00032 #include "dbus-hash.h"
00033 #include "dbus-message-internal.h"
00034 #include "dbus-threads.h"
00035 #include "dbus-protocol.h"
00036 #include "dbus-dataslot.h"
00037 #include "dbus-string.h"
00038 #include "dbus-pending-call.h"
00039 #include "dbus-object-tree.h"
00040
00041 #if 0
00042 #define CONNECTION_LOCK(connection) do { \
00043 _dbus_verbose (" LOCK: %s\n", _DBUS_FUNCTION_NAME); \
00044 dbus_mutex_lock ((connection)->mutex); \
00045 } while (0)
00046 #define CONNECTION_UNLOCK(connection) do { \
00047 _dbus_verbose (" UNLOCK: %s\n", _DBUS_FUNCTION_NAME); \
00048 dbus_mutex_unlock ((connection)->mutex); \
00049 } while (0)
00050 #else
00051 #define CONNECTION_LOCK(connection) dbus_mutex_lock ((connection)->mutex)
00052 #define CONNECTION_UNLOCK(connection) dbus_mutex_unlock ((connection)->mutex)
00053 #endif
00054
00132 typedef struct DBusMessageFilter DBusMessageFilter;
00133
00137 struct DBusMessageFilter
00138 {
00139 DBusAtomic refcount;
00140 DBusHandleMessageFunction function;
00141 void *user_data;
00142 DBusFreeFunction free_user_data_function;
00143 };
00144
00145
00149 struct DBusPreallocatedSend
00150 {
00151 DBusConnection *connection;
00152 DBusList *queue_link;
00153 DBusList *counter_link;
00154 };
00155
00156 static dbus_bool_t _dbus_modify_sigpipe = TRUE;
00157
00161 struct DBusConnection
00162 {
00163 DBusAtomic refcount;
00165 DBusMutex *mutex;
00167 dbus_bool_t dispatch_acquired;
00168 DBusCondVar *dispatch_cond;
00170 dbus_bool_t io_path_acquired;
00171 DBusCondVar *io_path_cond;
00173 DBusList *outgoing_messages;
00174 DBusList *incoming_messages;
00176 DBusMessage *message_borrowed;
00177 DBusCondVar *message_returned_cond;
00179 int n_outgoing;
00180 int n_incoming;
00182 DBusCounter *outgoing_counter;
00184 DBusTransport *transport;
00185 DBusWatchList *watches;
00186 DBusTimeoutList *timeouts;
00188 DBusList *filter_list;
00190 DBusDataSlotList slot_list;
00192 DBusHashTable *pending_replies;
00194 dbus_uint32_t client_serial;
00195 DBusList *disconnect_message_link;
00197 DBusWakeupMainFunction wakeup_main_function;
00198 void *wakeup_main_data;
00199 DBusFreeFunction free_wakeup_main_data;
00201 DBusDispatchStatusFunction dispatch_status_function;
00202 void *dispatch_status_data;
00203 DBusFreeFunction free_dispatch_status_data;
00205 DBusDispatchStatus last_dispatch_status;
00207 DBusList *link_cache;
00210 DBusObjectTree *objects;
00212 unsigned int exit_on_disconnect : 1;
00213 };
00214
00215 static void _dbus_connection_remove_timeout_locked (DBusConnection *connection,
00216 DBusTimeout *timeout);
00217 static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection);
00218 static void _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
00219 DBusDispatchStatus new_status);
00220 static void _dbus_connection_last_unref (DBusConnection *connection);
00221
00222 static DBusMessageFilter *
00223 _dbus_message_filter_ref (DBusMessageFilter *filter)
00224 {
00225 _dbus_assert (filter->refcount.value > 0);
00226 _dbus_atomic_inc (&filter->refcount);
00227
00228 return filter;
00229 }
00230
00231 static void
00232 _dbus_message_filter_unref (DBusMessageFilter *filter)
00233 {
00234 _dbus_assert (filter->refcount.value > 0);
00235
00236 if (_dbus_atomic_dec (&filter->refcount) == 1)
00237 {
00238 if (filter->free_user_data_function)
00239 (* filter->free_user_data_function) (filter->user_data);
00240
00241 dbus_free (filter);
00242 }
00243 }
00244
00250 void
00251 _dbus_connection_lock (DBusConnection *connection)
00252 {
00253 CONNECTION_LOCK (connection);
00254 }
00255
00261 void
00262 _dbus_connection_unlock (DBusConnection *connection)
00263 {
00264 CONNECTION_UNLOCK (connection);
00265 }
00266
00274 static void
00275 _dbus_connection_wakeup_mainloop (DBusConnection *connection)
00276 {
00277 if (connection->wakeup_main_function)
00278 (*connection->wakeup_main_function) (connection->wakeup_main_data);
00279 }
00280
00281 #ifdef DBUS_BUILD_TESTS
00282
00292 dbus_bool_t
00293 _dbus_connection_queue_received_message (DBusConnection *connection,
00294 DBusMessage *message)
00295 {
00296 DBusList *link;
00297
00298 link = _dbus_list_alloc_link (message);
00299 if (link == NULL)
00300 return FALSE;
00301
00302 dbus_message_ref (message);
00303 _dbus_connection_queue_received_message_link (connection, link);
00304
00305 return TRUE;
00306 }
00307 #endif
00308
00317 void
00318 _dbus_connection_queue_received_message_link (DBusConnection *connection,
00319 DBusList *link)
00320 {
00321 DBusPendingCall *pending;
00322 dbus_int32_t reply_serial;
00323 DBusMessage *message;
00324
00325 _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport));
00326
00327 _dbus_list_append_link (&connection->incoming_messages,
00328 link);
00329 message = link->data;
00330
00331
00332 reply_serial = dbus_message_get_reply_serial (message);
00333 if (reply_serial != -1)
00334 {
00335 pending = _dbus_hash_table_lookup_int (connection->pending_replies,
00336 reply_serial);
00337 if (pending != NULL)
00338 {
00339 if (pending->timeout_added)
00340 _dbus_connection_remove_timeout_locked (connection,
00341 pending->timeout);
00342
00343 pending->timeout_added = FALSE;
00344 }
00345 }
00346
00347 connection->n_incoming += 1;
00348
00349 _dbus_connection_wakeup_mainloop (connection);
00350
00351 _dbus_verbose ("Message %p (%d %s '%s') added to incoming queue %p, %d incoming\n",
00352 message,
00353 dbus_message_get_type (message),
00354 dbus_message_get_interface (message) ?
00355 dbus_message_get_interface (message) :
00356 "no interface",
00357 dbus_message_get_signature (message),
00358 connection,
00359 connection->n_incoming);
00360 }
00361
00372 static void
00373 _dbus_connection_queue_synthesized_message_link (DBusConnection *connection,
00374 DBusList *link)
00375 {
00376 _dbus_list_append_link (&connection->incoming_messages, link);
00377
00378 connection->n_incoming += 1;
00379
00380 _dbus_connection_wakeup_mainloop (connection);
00381
00382 _dbus_verbose ("Synthesized message %p added to incoming queue %p, %d incoming\n",
00383 link->data, connection, connection->n_incoming);
00384 }
00385
00386
00393 dbus_bool_t
00394 _dbus_connection_have_messages_to_send (DBusConnection *connection)
00395 {
00396 return connection->outgoing_messages != NULL;
00397 }
00398
00406 DBusMessage*
00407 _dbus_connection_get_message_to_send (DBusConnection *connection)
00408 {
00409 return _dbus_list_get_last (&connection->outgoing_messages);
00410 }
00411
00420 void
00421 _dbus_connection_message_sent (DBusConnection *connection,
00422 DBusMessage *message)
00423 {
00424 DBusList *link;
00425
00426 _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport));
00427
00428 link = _dbus_list_get_last_link (&connection->outgoing_messages);
00429 _dbus_assert (link != NULL);
00430 _dbus_assert (link->data == message);
00431
00432
00433 _dbus_list_unlink (&connection->outgoing_messages,
00434 link);
00435 _dbus_list_prepend_link (&connection->link_cache, link);
00436
00437 connection->n_outgoing -= 1;
00438
00439 _dbus_verbose ("Message %p (%d %s '%s') removed from outgoing queue %p, %d left to send\n",
00440 message,
00441 dbus_message_get_type (message),
00442 dbus_message_get_interface (message) ?
00443 dbus_message_get_interface (message) :
00444 "no interface",
00445 dbus_message_get_signature (message),
00446 connection, connection->n_outgoing);
00447
00448
00449 _dbus_message_remove_size_counter (message, connection->outgoing_counter,
00450 &link);
00451 _dbus_list_prepend_link (&connection->link_cache, link);
00452
00453 dbus_message_unref (message);
00454
00455 if (connection->n_outgoing == 0)
00456 _dbus_transport_messages_pending (connection->transport,
00457 connection->n_outgoing);
00458 }
00459
00470 dbus_bool_t
00471 _dbus_connection_add_watch (DBusConnection *connection,
00472 DBusWatch *watch)
00473 {
00474 if (connection->watches)
00475 return _dbus_watch_list_add_watch (connection->watches,
00476 watch);
00477 else
00478 return FALSE;
00479 }
00480
00489 void
00490 _dbus_connection_remove_watch (DBusConnection *connection,
00491 DBusWatch *watch)
00492 {
00493 if (connection->watches)
00494 _dbus_watch_list_remove_watch (connection->watches,
00495 watch);
00496 }
00497
00507 void
00508 _dbus_connection_toggle_watch (DBusConnection *connection,
00509 DBusWatch *watch,
00510 dbus_bool_t enabled)
00511 {
00512 if (connection->watches)
00513 _dbus_watch_list_toggle_watch (connection->watches,
00514 watch, enabled);
00515 }
00516
00528 dbus_bool_t
00529 _dbus_connection_add_timeout (DBusConnection *connection,
00530 DBusTimeout *timeout)
00531 {
00532 if (connection->timeouts)
00533 return _dbus_timeout_list_add_timeout (connection->timeouts,
00534 timeout);
00535 else
00536 return FALSE;
00537 }
00538
00547 void
00548 _dbus_connection_remove_timeout (DBusConnection *connection,
00549 DBusTimeout *timeout)
00550 {
00551 if (connection->timeouts)
00552 _dbus_timeout_list_remove_timeout (connection->timeouts,
00553 timeout);
00554 }
00555
00556 static void
00557 _dbus_connection_remove_timeout_locked (DBusConnection *connection,
00558 DBusTimeout *timeout)
00559 {
00560 CONNECTION_LOCK (connection);
00561 _dbus_connection_remove_timeout (connection, timeout);
00562 CONNECTION_UNLOCK (connection);
00563 }
00564
00574 void
00575 _dbus_connection_toggle_timeout (DBusConnection *connection,
00576 DBusTimeout *timeout,
00577 dbus_bool_t enabled)
00578 {
00579 if (connection->timeouts)
00580 _dbus_timeout_list_toggle_timeout (connection->timeouts,
00581 timeout, enabled);
00582 }
00583
00584 static dbus_bool_t
00585 _dbus_connection_attach_pending_call_unlocked (DBusConnection *connection,
00586 DBusPendingCall *pending)
00587 {
00588 _dbus_assert (pending->reply_serial != 0);
00589
00590 if (!_dbus_connection_add_timeout (connection, pending->timeout))
00591 return FALSE;
00592
00593 if (!_dbus_hash_table_insert_int (connection->pending_replies,
00594 pending->reply_serial,
00595 pending))
00596 {
00597 _dbus_connection_remove_timeout (connection, pending->timeout);
00598 return FALSE;
00599 }
00600
00601 pending->timeout_added = TRUE;
00602 pending->connection = connection;
00603
00604 dbus_pending_call_ref (pending);
00605
00606 return TRUE;
00607 }
00608
00609 static void
00610 free_pending_call_on_hash_removal (void *data)
00611 {
00612 DBusPendingCall *pending;
00613
00614 if (data == NULL)
00615 return;
00616
00617 pending = data;
00618
00619 if (pending->connection)
00620 {
00621 if (pending->timeout_added)
00622 {
00623 _dbus_connection_remove_timeout (pending->connection,
00624 pending->timeout);
00625 pending->timeout_added = FALSE;
00626 }
00627
00628 pending->connection = NULL;
00629
00630 dbus_pending_call_unref (pending);
00631 }
00632 }
00633
00634 static void
00635 _dbus_connection_detach_pending_call_and_unlock (DBusConnection *connection,
00636 DBusPendingCall *pending)
00637 {
00638
00639
00640
00641
00642 dbus_pending_call_ref (pending);
00643 _dbus_hash_table_remove_int (connection->pending_replies,
00644 pending->reply_serial);
00645 CONNECTION_UNLOCK (connection);
00646 dbus_pending_call_unref (pending);
00647 }
00648
00657 void
00658 _dbus_connection_remove_pending_call (DBusConnection *connection,
00659 DBusPendingCall *pending)
00660 {
00661 CONNECTION_LOCK (connection);
00662 _dbus_connection_detach_pending_call_and_unlock (connection, pending);
00663 }
00664
00673 void
00674 _dbus_pending_call_complete_and_unlock (DBusPendingCall *pending,
00675 DBusMessage *message)
00676 {
00677 if (message == NULL)
00678 {
00679 message = pending->timeout_link->data;
00680 _dbus_list_clear (&pending->timeout_link);
00681 }
00682 else
00683 dbus_message_ref (message);
00684
00685 _dbus_verbose (" handing message %p (%s) to pending call serial %u\n",
00686 message,
00687 dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN ?
00688 "method return" :
00689 dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR ?
00690 "error" : "other type",
00691 pending->reply_serial);
00692
00693 _dbus_assert (pending->reply == NULL);
00694 _dbus_assert (pending->reply_serial == dbus_message_get_reply_serial (message));
00695 pending->reply = message;
00696
00697 dbus_pending_call_ref (pending);
00698 _dbus_connection_detach_pending_call_and_unlock (pending->connection, pending);
00699
00700
00701 _dbus_pending_call_notify (pending);
00702 dbus_pending_call_unref (pending);
00703 }
00704
00714 static dbus_bool_t
00715 _dbus_connection_acquire_io_path (DBusConnection *connection,
00716 int timeout_milliseconds)
00717 {
00718 dbus_bool_t res = TRUE;
00719
00720 if (connection->io_path_acquired)
00721 {
00722 if (timeout_milliseconds != -1)
00723 res = dbus_condvar_wait_timeout (connection->io_path_cond,
00724 connection->mutex,
00725 timeout_milliseconds);
00726 else
00727 dbus_condvar_wait (connection->io_path_cond, connection->mutex);
00728 }
00729
00730 if (res)
00731 {
00732 _dbus_assert (!connection->io_path_acquired);
00733
00734 connection->io_path_acquired = TRUE;
00735 }
00736
00737 return res;
00738 }
00739
00747 static void
00748 _dbus_connection_release_io_path (DBusConnection *connection)
00749 {
00750 _dbus_assert (connection->io_path_acquired);
00751
00752 connection->io_path_acquired = FALSE;
00753 dbus_condvar_wake_one (connection->io_path_cond);
00754 }
00755
00756
00783 void
00784 _dbus_connection_do_iteration (DBusConnection *connection,
00785 unsigned int flags,
00786 int timeout_milliseconds)
00787 {
00788 if (connection->n_outgoing == 0)
00789 flags &= ~DBUS_ITERATION_DO_WRITING;
00790
00791 if (_dbus_connection_acquire_io_path (connection,
00792 (flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0))
00793 {
00794 _dbus_transport_do_iteration (connection->transport,
00795 flags, timeout_milliseconds);
00796 _dbus_connection_release_io_path (connection);
00797 }
00798 }
00799
00809 DBusConnection*
00810 _dbus_connection_new_for_transport (DBusTransport *transport)
00811 {
00812 DBusConnection *connection;
00813 DBusWatchList *watch_list;
00814 DBusTimeoutList *timeout_list;
00815 DBusHashTable *pending_replies;
00816 DBusMutex *mutex;
00817 DBusCondVar *message_returned_cond;
00818 DBusCondVar *dispatch_cond;
00819 DBusCondVar *io_path_cond;
00820 DBusList *disconnect_link;
00821 DBusMessage *disconnect_message;
00822 DBusCounter *outgoing_counter;
00823 DBusObjectTree *objects;
00824
00825 watch_list = NULL;
00826 connection = NULL;
00827 pending_replies = NULL;
00828 timeout_list = NULL;
00829 mutex = NULL;
00830 message_returned_cond = NULL;
00831 dispatch_cond = NULL;
00832 io_path_cond = NULL;
00833 disconnect_link = NULL;
00834 disconnect_message = NULL;
00835 outgoing_counter = NULL;
00836 objects = NULL;
00837
00838 watch_list = _dbus_watch_list_new ();
00839 if (watch_list == NULL)
00840 goto error;
00841
00842 timeout_list = _dbus_timeout_list_new ();
00843 if (timeout_list == NULL)
00844 goto error;
00845
00846 pending_replies =
00847 _dbus_hash_table_new (DBUS_HASH_INT,
00848 NULL,
00849 (DBusFreeFunction)free_pending_call_on_hash_removal);
00850 if (pending_replies == NULL)
00851 goto error;
00852
00853 connection = dbus_new0 (DBusConnection, 1);
00854 if (connection == NULL)
00855 goto error;
00856
00857 mutex = dbus_mutex_new ();
00858 if (mutex == NULL)
00859 goto error;
00860
00861 message_returned_cond = dbus_condvar_new ();
00862 if (message_returned_cond == NULL)
00863 goto error;
00864
00865 dispatch_cond = dbus_condvar_new ();
00866 if (dispatch_cond == NULL)
00867 goto error;
00868
00869 io_path_cond = dbus_condvar_new ();
00870 if (io_path_cond == NULL)
00871 goto error;
00872
00873 disconnect_message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_LOCAL,
00874 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
00875 "Disconnected");
00876
00877 if (disconnect_message == NULL)
00878 goto error;
00879
00880 disconnect_link = _dbus_list_alloc_link (disconnect_message);
00881 if (disconnect_link == NULL)
00882 goto error;
00883
00884 outgoing_counter = _dbus_counter_new ();
00885 if (outgoing_counter == NULL)
00886 goto error;
00887
00888 objects = _dbus_object_tree_new (connection);
00889 if (objects == NULL)
00890 goto error;
00891
00892 if (_dbus_modify_sigpipe)
00893 _dbus_disable_sigpipe ();
00894
00895 connection->refcount.value = 1;
00896 connection->mutex = mutex;
00897 connection->dispatch_cond = dispatch_cond;
00898 connection->io_path_cond = io_path_cond;
00899 connection->message_returned_cond = message_returned_cond;
00900 connection->transport = transport;
00901 connection->watches = watch_list;
00902 connection->timeouts = timeout_list;
00903 connection->pending_replies = pending_replies;
00904 connection->outgoing_counter = outgoing_counter;
00905 connection->filter_list = NULL;
00906 connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE;
00907 connection->objects = objects;
00908 connection->exit_on_disconnect = FALSE;
00909
00910 _dbus_data_slot_list_init (&connection->slot_list);
00911
00912 connection->client_serial = 1;
00913
00914 connection->disconnect_message_link = disconnect_link;
00915
00916 if (!_dbus_transport_set_connection (transport, connection))
00917 goto error;
00918
00919 _dbus_transport_ref (transport);
00920
00921 return connection;
00922
00923 error:
00924 if (disconnect_message != NULL)
00925 dbus_message_unref (disconnect_message);
00926
00927 if (disconnect_link != NULL)
00928 _dbus_list_free_link (disconnect_link);
00929
00930 if (io_path_cond != NULL)
00931 dbus_condvar_free (io_path_cond);
00932
00933 if (dispatch_cond != NULL)
00934 dbus_condvar_free (dispatch_cond);
00935
00936 if (message_returned_cond != NULL)
00937 dbus_condvar_free (message_returned_cond);
00938
00939 if (mutex != NULL)
00940 dbus_mutex_free (mutex);
00941
00942 if (connection != NULL)
00943 dbus_free (connection);
00944
00945 if (pending_replies)
00946 _dbus_hash_table_unref (pending_replies);
00947
00948 if (watch_list)
00949 _dbus_watch_list_free (watch_list);
00950
00951 if (timeout_list)
00952 _dbus_timeout_list_free (timeout_list);
00953
00954 if (outgoing_counter)
00955 _dbus_counter_unref (outgoing_counter);
00956
00957 if (objects)
00958 _dbus_object_tree_unref (objects);
00959
00960 return NULL;
00961 }
00962
00970 DBusConnection *
00971 _dbus_connection_ref_unlocked (DBusConnection *connection)
00972 {
00973 #ifdef DBUS_HAVE_ATOMIC_INT
00974 _dbus_atomic_inc (&connection->refcount);
00975 #else
00976 _dbus_assert (connection->refcount.value > 0);
00977 connection->refcount.value += 1;
00978 #endif
00979
00980 return connection;
00981 }
00982
00989 void
00990 _dbus_connection_unref_unlocked (DBusConnection *connection)
00991 {
00992 dbus_bool_t last_unref;
00993
00994 _dbus_return_if_fail (connection != NULL);
00995
00996
00997
00998
00999
01000 #ifdef DBUS_HAVE_ATOMIC_INT
01001 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
01002 #else
01003 _dbus_assert (connection->refcount.value > 0);
01004
01005 connection->refcount.value -= 1;
01006 last_unref = (connection->refcount.value == 0);
01007 #if 0
01008 printf ("unref_unlocked() connection %p count = %d\n", connection, connection->refcount.value);
01009 #endif
01010 #endif
01011
01012 if (last_unref)
01013 _dbus_connection_last_unref (connection);
01014 }
01015
01016 static dbus_uint32_t
01017 _dbus_connection_get_next_client_serial (DBusConnection *connection)
01018 {
01019 int serial;
01020
01021 serial = connection->client_serial++;
01022
01023 if (connection->client_serial < 0)
01024 connection->client_serial = 1;
01025
01026 return serial;
01027 }
01028
01042 dbus_bool_t
01043 _dbus_connection_handle_watch (DBusWatch *watch,
01044 unsigned int condition,
01045 void *data)
01046 {
01047 DBusConnection *connection;
01048 dbus_bool_t retval;
01049 DBusDispatchStatus status;
01050
01051 connection = data;
01052
01053 CONNECTION_LOCK (connection);
01054 _dbus_connection_acquire_io_path (connection, -1);
01055 retval = _dbus_transport_handle_watch (connection->transport,
01056 watch, condition);
01057 _dbus_connection_release_io_path (connection);
01058
01059 status = _dbus_connection_get_dispatch_status_unlocked (connection);
01060
01061
01062 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01063
01064 return retval;
01065 }
01066
01091 DBusConnection*
01092 dbus_connection_open (const char *address,
01093 DBusError *error)
01094 {
01095 DBusConnection *connection;
01096 DBusTransport *transport;
01097
01098 _dbus_return_val_if_fail (address != NULL, NULL);
01099 _dbus_return_val_if_error_is_set (error, NULL);
01100
01101 transport = _dbus_transport_open (address, error);
01102 if (transport == NULL)
01103 {
01104 _DBUS_ASSERT_ERROR_IS_SET (error);
01105 return NULL;
01106 }
01107
01108 connection = _dbus_connection_new_for_transport (transport);
01109
01110 _dbus_transport_unref (transport);
01111
01112 if (connection == NULL)
01113 {
01114 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
01115 return NULL;
01116 }
01117
01118 return connection;
01119 }
01120
01127 DBusConnection *
01128 dbus_connection_ref (DBusConnection *connection)
01129 {
01130 _dbus_return_val_if_fail (connection != NULL, NULL);
01131
01132
01133
01134
01135
01136 #ifdef DBUS_HAVE_ATOMIC_INT
01137 _dbus_atomic_inc (&connection->refcount);
01138 #else
01139 CONNECTION_LOCK (connection);
01140 _dbus_assert (connection->refcount.value > 0);
01141
01142 connection->refcount.value += 1;
01143 CONNECTION_UNLOCK (connection);
01144 #endif
01145
01146 return connection;
01147 }
01148
01149 static void
01150 free_outgoing_message (void *element,
01151 void *data)
01152 {
01153 DBusMessage *message = element;
01154 DBusConnection *connection = data;
01155
01156 _dbus_message_remove_size_counter (message,
01157 connection->outgoing_counter,
01158 NULL);
01159 dbus_message_unref (message);
01160 }
01161
01162
01163
01164
01165
01166 static void
01167 _dbus_connection_last_unref (DBusConnection *connection)
01168 {
01169 DBusList *link;
01170
01171 _dbus_verbose ("Finalizing connection %p\n", connection);
01172
01173 _dbus_assert (connection->refcount.value == 0);
01174
01175
01176
01177
01178 _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
01179
01180
01181 _dbus_object_tree_free_all_unlocked (connection->objects);
01182
01183 dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
01184 dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
01185 dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
01186
01187 _dbus_watch_list_free (connection->watches);
01188 connection->watches = NULL;
01189
01190 _dbus_timeout_list_free (connection->timeouts);
01191 connection->timeouts = NULL;
01192
01193 _dbus_data_slot_list_free (&connection->slot_list);
01194
01195 link = _dbus_list_get_first_link (&connection->filter_list);
01196 while (link != NULL)
01197 {
01198 DBusMessageFilter *filter = link->data;
01199 DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
01200
01201 filter->function = NULL;
01202 _dbus_message_filter_unref (filter);
01203 link->data = NULL;
01204
01205 link = next;
01206 }
01207 _dbus_list_clear (&connection->filter_list);
01208
01209
01210
01211 _dbus_object_tree_unref (connection->objects);
01212
01213 _dbus_hash_table_unref (connection->pending_replies);
01214 connection->pending_replies = NULL;
01215
01216 _dbus_list_clear (&connection->filter_list);
01217
01218 _dbus_list_foreach (&connection->outgoing_messages,
01219 free_outgoing_message,
01220 connection);
01221 _dbus_list_clear (&connection->outgoing_messages);
01222
01223 _dbus_list_foreach (&connection->incoming_messages,
01224 (DBusForeachFunction) dbus_message_unref,
01225 NULL);
01226 _dbus_list_clear (&connection->incoming_messages);
01227
01228 _dbus_counter_unref (connection->outgoing_counter);
01229
01230 _dbus_transport_unref (connection->transport);
01231
01232 if (connection->disconnect_message_link)
01233 {
01234 DBusMessage *message = connection->disconnect_message_link->data;
01235 dbus_message_unref (message);
01236 _dbus_list_free_link (connection->disconnect_message_link);
01237 }
01238
01239 _dbus_list_clear (&connection->link_cache);
01240
01241 dbus_condvar_free (connection->dispatch_cond);
01242 dbus_condvar_free (connection->io_path_cond);
01243 dbus_condvar_free (connection->message_returned_cond);
01244
01245 dbus_mutex_free (connection->mutex);
01246
01247 dbus_free (connection);
01248 }
01249
01261 void
01262 dbus_connection_unref (DBusConnection *connection)
01263 {
01264 dbus_bool_t last_unref;
01265
01266 _dbus_return_if_fail (connection != NULL);
01267
01268
01269
01270
01271
01272 #ifdef DBUS_HAVE_ATOMIC_INT
01273 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
01274 #else
01275 CONNECTION_LOCK (connection);
01276
01277 _dbus_assert (connection->refcount.value > 0);
01278
01279 connection->refcount.value -= 1;
01280 last_unref = (connection->refcount.value == 0);
01281
01282 #if 0
01283 printf ("unref() connection %p count = %d\n", connection, connection->refcount.value);
01284 #endif
01285
01286 CONNECTION_UNLOCK (connection);
01287 #endif
01288
01289 if (last_unref)
01290 _dbus_connection_last_unref (connection);
01291 }
01292
01306 void
01307 dbus_connection_disconnect (DBusConnection *connection)
01308 {
01309 DBusDispatchStatus status;
01310
01311 _dbus_return_if_fail (connection != NULL);
01312
01313 CONNECTION_LOCK (connection);
01314 _dbus_transport_disconnect (connection->transport);
01315
01316 status = _dbus_connection_get_dispatch_status_unlocked (connection);
01317
01318
01319 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01320 }
01321
01322 static dbus_bool_t
01323 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
01324 {
01325 return _dbus_transport_get_is_connected (connection->transport);
01326 }
01327
01338 dbus_bool_t
01339 dbus_connection_get_is_connected (DBusConnection *connection)
01340 {
01341 dbus_bool_t res;
01342
01343 _dbus_return_val_if_fail (connection != NULL, FALSE);
01344
01345 CONNECTION_LOCK (connection);
01346 res = _dbus_connection_get_is_connected_unlocked (connection);
01347 CONNECTION_UNLOCK (connection);
01348
01349 return res;
01350 }
01351
01360 dbus_bool_t
01361 dbus_connection_get_is_authenticated (DBusConnection *connection)
01362 {
01363 dbus_bool_t res;
01364
01365 _dbus_return_val_if_fail (connection != NULL, FALSE);
01366
01367 CONNECTION_LOCK (connection);
01368 res = _dbus_transport_get_is_authenticated (connection->transport);
01369 CONNECTION_UNLOCK (connection);
01370
01371 return res;
01372 }
01373
01387 void
01388 dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
01389 dbus_bool_t exit_on_disconnect)
01390 {
01391 _dbus_return_if_fail (connection != NULL);
01392
01393 CONNECTION_LOCK (connection);
01394 connection->exit_on_disconnect = exit_on_disconnect != FALSE;
01395 CONNECTION_UNLOCK (connection);
01396 }
01397
01398 static DBusPreallocatedSend*
01399 _dbus_connection_preallocate_send_unlocked (DBusConnection *connection)
01400 {
01401 DBusPreallocatedSend *preallocated;
01402
01403 _dbus_return_val_if_fail (connection != NULL, NULL);
01404
01405 preallocated = dbus_new (DBusPreallocatedSend, 1);
01406 if (preallocated == NULL)
01407 return NULL;
01408
01409 if (connection->link_cache != NULL)
01410 {
01411 preallocated->queue_link =
01412 _dbus_list_pop_first_link (&connection->link_cache);
01413 preallocated->queue_link->data = NULL;
01414 }
01415 else
01416 {
01417 preallocated->queue_link = _dbus_list_alloc_link (NULL);
01418 if (preallocated->queue_link == NULL)
01419 goto failed_0;
01420 }
01421
01422 if (connection->link_cache != NULL)
01423 {
01424 preallocated->counter_link =
01425 _dbus_list_pop_first_link (&connection->link_cache);
01426 preallocated->counter_link->data = connection->outgoing_counter;
01427 }
01428 else
01429 {
01430 preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter);
01431 if (preallocated->counter_link == NULL)
01432 goto failed_1;
01433 }
01434
01435 _dbus_counter_ref (preallocated->counter_link->data);
01436
01437 preallocated->connection = connection;
01438
01439 return preallocated;
01440
01441 failed_1:
01442 _dbus_list_free_link (preallocated->queue_link);
01443 failed_0:
01444 dbus_free (preallocated);
01445
01446 return NULL;
01447 }
01448
01458 DBusPreallocatedSend*
01459 dbus_connection_preallocate_send (DBusConnection *connection)
01460 {
01461 DBusPreallocatedSend *preallocated;
01462
01463 _dbus_return_val_if_fail (connection != NULL, NULL);
01464
01465 CONNECTION_LOCK (connection);
01466
01467 preallocated =
01468 _dbus_connection_preallocate_send_unlocked (connection);
01469
01470 CONNECTION_UNLOCK (connection);
01471
01472 return preallocated;
01473 }
01474
01484 void
01485 dbus_connection_free_preallocated_send (DBusConnection *connection,
01486 DBusPreallocatedSend *preallocated)
01487 {
01488 _dbus_return_if_fail (connection != NULL);
01489 _dbus_return_if_fail (preallocated != NULL);
01490 _dbus_return_if_fail (connection == preallocated->connection);
01491
01492 _dbus_list_free_link (preallocated->queue_link);
01493 _dbus_counter_unref (preallocated->counter_link->data);
01494 _dbus_list_free_link (preallocated->counter_link);
01495 dbus_free (preallocated);
01496 }
01497
01498 static void
01499 _dbus_connection_send_preallocated_unlocked (DBusConnection *connection,
01500 DBusPreallocatedSend *preallocated,
01501 DBusMessage *message,
01502 dbus_uint32_t *client_serial)
01503 {
01504 dbus_uint32_t serial;
01505
01506 preallocated->queue_link->data = message;
01507 _dbus_list_prepend_link (&connection->outgoing_messages,
01508 preallocated->queue_link);
01509
01510 _dbus_message_add_size_counter_link (message,
01511 preallocated->counter_link);
01512
01513 dbus_free (preallocated);
01514 preallocated = NULL;
01515
01516 dbus_message_ref (message);
01517
01518 connection->n_outgoing += 1;
01519
01520 _dbus_verbose ("Message %p (%d %s '%s') added to outgoing queue %p, %d pending to send\n",
01521 message,
01522 dbus_message_get_type (message),
01523 dbus_message_get_interface (message) ?
01524 dbus_message_get_interface (message) :
01525 "no interface",
01526 dbus_message_get_signature (message),
01527 connection,
01528 connection->n_outgoing);
01529
01530 if (dbus_message_get_serial (message) == 0)
01531 {
01532 serial = _dbus_connection_get_next_client_serial (connection);
01533 _dbus_message_set_serial (message, serial);
01534 if (client_serial)
01535 *client_serial = serial;
01536 }
01537 else
01538 {
01539 if (client_serial)
01540 *client_serial = dbus_message_get_serial (message);
01541 }
01542
01543 _dbus_message_lock (message);
01544
01545 if (connection->n_outgoing == 1)
01546 _dbus_transport_messages_pending (connection->transport,
01547 connection->n_outgoing);
01548
01549 _dbus_connection_wakeup_mainloop (connection);
01550 }
01551
01564 void
01565 dbus_connection_send_preallocated (DBusConnection *connection,
01566 DBusPreallocatedSend *preallocated,
01567 DBusMessage *message,
01568 dbus_uint32_t *client_serial)
01569 {
01570 _dbus_return_if_fail (connection != NULL);
01571 _dbus_return_if_fail (preallocated != NULL);
01572 _dbus_return_if_fail (message != NULL);
01573 _dbus_return_if_fail (preallocated->connection == connection);
01574 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
01575 (dbus_message_get_interface (message) != NULL &&
01576 dbus_message_get_member (message) != NULL));
01577 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
01578 (dbus_message_get_interface (message) != NULL &&
01579 dbus_message_get_member (message) != NULL));
01580
01581 CONNECTION_LOCK (connection);
01582 _dbus_connection_send_preallocated_unlocked (connection,
01583 preallocated,
01584 message, client_serial);
01585 CONNECTION_UNLOCK (connection);
01586 }
01587
01588 static dbus_bool_t
01589 _dbus_connection_send_unlocked (DBusConnection *connection,
01590 DBusMessage *message,
01591 dbus_uint32_t *client_serial)
01592 {
01593 DBusPreallocatedSend *preallocated;
01594
01595 _dbus_assert (connection != NULL);
01596 _dbus_assert (message != NULL);
01597
01598 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
01599 if (preallocated == NULL)
01600 return FALSE;
01601
01602
01603 _dbus_connection_send_preallocated_unlocked (connection,
01604 preallocated,
01605 message,
01606 client_serial);
01607 return TRUE;
01608 }
01609
01628 dbus_bool_t
01629 dbus_connection_send (DBusConnection *connection,
01630 DBusMessage *message,
01631 dbus_uint32_t *client_serial)
01632 {
01633 _dbus_return_val_if_fail (connection != NULL, FALSE);
01634 _dbus_return_val_if_fail (message != NULL, FALSE);
01635
01636 CONNECTION_LOCK (connection);
01637
01638 if (!_dbus_connection_send_unlocked (connection, message, client_serial))
01639 {
01640 CONNECTION_UNLOCK (connection);
01641 return FALSE;
01642 }
01643
01644 CONNECTION_UNLOCK (connection);
01645 return TRUE;
01646 }
01647
01648 static dbus_bool_t
01649 reply_handler_timeout (void *data)
01650 {
01651 DBusConnection *connection;
01652 DBusDispatchStatus status;
01653 DBusPendingCall *pending = data;
01654
01655 connection = pending->connection;
01656
01657 CONNECTION_LOCK (connection);
01658 if (pending->timeout_link)
01659 {
01660 _dbus_connection_queue_synthesized_message_link (connection,
01661 pending->timeout_link);
01662 pending->timeout_link = NULL;
01663 }
01664
01665 _dbus_connection_remove_timeout (connection,
01666 pending->timeout);
01667 pending->timeout_added = FALSE;
01668
01669 status = _dbus_connection_get_dispatch_status_unlocked (connection);
01670
01671
01672 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01673
01674 return TRUE;
01675 }
01676
01714 dbus_bool_t
01715 dbus_connection_send_with_reply (DBusConnection *connection,
01716 DBusMessage *message,
01717 DBusPendingCall **pending_return,
01718 int timeout_milliseconds)
01719 {
01720 DBusPendingCall *pending;
01721 DBusMessage *reply;
01722 DBusList *reply_link;
01723 dbus_int32_t serial = -1;
01724
01725 _dbus_return_val_if_fail (connection != NULL, FALSE);
01726 _dbus_return_val_if_fail (message != NULL, FALSE);
01727 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
01728
01729 if (pending_return)
01730 *pending_return = NULL;
01731
01732 pending = _dbus_pending_call_new (connection,
01733 timeout_milliseconds,
01734 reply_handler_timeout);
01735
01736 if (pending == NULL)
01737 return FALSE;
01738
01739 CONNECTION_LOCK (connection);
01740
01741
01742 if (dbus_message_get_serial (message) == 0)
01743 {
01744 serial = _dbus_connection_get_next_client_serial (connection);
01745 _dbus_message_set_serial (message, serial);
01746 }
01747
01748 pending->reply_serial = serial;
01749
01750 reply = dbus_message_new_error (message, DBUS_ERROR_NO_REPLY,
01751 "No reply within specified time");
01752 if (!reply)
01753 {
01754 CONNECTION_UNLOCK (connection);
01755 dbus_pending_call_unref (pending);
01756 return FALSE;
01757 }
01758
01759 reply_link = _dbus_list_alloc_link (reply);
01760 if (!reply)
01761 {
01762 CONNECTION_UNLOCK (connection);
01763 dbus_message_unref (reply);
01764 dbus_pending_call_unref (pending);
01765 return FALSE;
01766 }
01767
01768 pending->timeout_link = reply_link;
01769
01770
01771
01772
01773
01774 if (!_dbus_connection_attach_pending_call_unlocked (connection,
01775 pending))
01776 {
01777 CONNECTION_UNLOCK (connection);
01778 dbus_pending_call_unref (pending);
01779 return FALSE;
01780 }
01781
01782 if (!_dbus_connection_send_unlocked (connection, message, NULL))
01783 {
01784 _dbus_connection_detach_pending_call_and_unlock (connection,
01785 pending);
01786 return FALSE;
01787 }
01788
01789 if (pending_return)
01790 {
01791 dbus_pending_call_ref (pending);
01792 *pending_return = pending;
01793 }
01794
01795 CONNECTION_UNLOCK (connection);
01796
01797 return TRUE;
01798 }
01799
01800 static DBusMessage*
01801 check_for_reply_unlocked (DBusConnection *connection,
01802 dbus_uint32_t client_serial)
01803 {
01804 DBusList *link;
01805
01806 link = _dbus_list_get_first_link (&connection->incoming_messages);
01807
01808 while (link != NULL)
01809 {
01810 DBusMessage *reply = link->data;
01811
01812 if (dbus_message_get_reply_serial (reply) == client_serial)
01813 {
01814 _dbus_list_remove_link (&connection->incoming_messages, link);
01815 connection->n_incoming -= 1;
01816 dbus_message_ref (reply);
01817 return reply;
01818 }
01819 link = _dbus_list_get_next_link (&connection->incoming_messages, link);
01820 }
01821
01822 return NULL;
01823 }
01824
01842 DBusMessage*
01843 _dbus_connection_block_for_reply (DBusConnection *connection,
01844 dbus_uint32_t client_serial,
01845 int timeout_milliseconds)
01846 {
01847 long start_tv_sec, start_tv_usec;
01848 long end_tv_sec, end_tv_usec;
01849 long tv_sec, tv_usec;
01850 DBusDispatchStatus status;
01851
01852 _dbus_return_val_if_fail (connection != NULL, NULL);
01853 _dbus_return_val_if_fail (client_serial != 0, NULL);
01854 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
01855
01856 if (timeout_milliseconds == -1)
01857 timeout_milliseconds = _DBUS_DEFAULT_TIMEOUT_VALUE;
01858
01859
01860
01861
01862
01863 if (timeout_milliseconds > _DBUS_ONE_HOUR_IN_MILLISECONDS * 6)
01864 timeout_milliseconds = _DBUS_ONE_HOUR_IN_MILLISECONDS * 6;
01865
01866
01867 dbus_connection_flush (connection);
01868
01869 CONNECTION_LOCK (connection);
01870
01871 _dbus_get_current_time (&start_tv_sec, &start_tv_usec);
01872 end_tv_sec = start_tv_sec + timeout_milliseconds / 1000;
01873 end_tv_usec = start_tv_usec + (timeout_milliseconds % 1000) * 1000;
01874 end_tv_sec += end_tv_usec / _DBUS_USEC_PER_SECOND;
01875 end_tv_usec = end_tv_usec % _DBUS_USEC_PER_SECOND;
01876
01877 _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",
01878 timeout_milliseconds,
01879 client_serial,
01880 start_tv_sec, start_tv_usec,
01881 end_tv_sec, end_tv_usec);
01882
01883
01884
01885
01886
01887
01888 _dbus_connection_do_iteration (connection,
01889 DBUS_ITERATION_DO_READING |
01890 DBUS_ITERATION_BLOCK,
01891 timeout_milliseconds);
01892
01893 recheck_status:
01894
01895
01896 status = _dbus_connection_get_dispatch_status_unlocked (connection);
01897
01898 if (status == DBUS_DISPATCH_DATA_REMAINS)
01899 {
01900 DBusMessage *reply;
01901
01902 reply = check_for_reply_unlocked (connection, client_serial);
01903 if (reply != NULL)
01904 {
01905 status = _dbus_connection_get_dispatch_status_unlocked (connection);
01906
01907 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
01908
01909
01910 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01911
01912 return reply;
01913 }
01914 }
01915
01916 _dbus_get_current_time (&tv_sec, &tv_usec);
01917
01918 if (!_dbus_connection_get_is_connected_unlocked (connection))
01919 return NULL;
01920 else if (tv_sec < start_tv_sec)
01921 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
01922 else if (connection->disconnect_message_link == NULL)
01923 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
01924 else if (tv_sec < end_tv_sec ||
01925 (tv_sec == end_tv_sec && tv_usec < end_tv_usec))
01926 {
01927 timeout_milliseconds = (end_tv_sec - tv_sec) * 1000 +
01928 (end_tv_usec - tv_usec) / 1000;
01929 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds);
01930 _dbus_assert (timeout_milliseconds >= 0);
01931
01932 if (status == DBUS_DISPATCH_NEED_MEMORY)
01933 {
01934
01935
01936
01937
01938 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
01939
01940 if (timeout_milliseconds < 100)
01941 ;
01942 else if (timeout_milliseconds <= 1000)
01943 _dbus_sleep_milliseconds (timeout_milliseconds / 3);
01944 else
01945 _dbus_sleep_milliseconds (1000);
01946 }
01947 else
01948 {
01949
01950 _dbus_connection_do_iteration (connection,
01951 DBUS_ITERATION_DO_READING |
01952 DBUS_ITERATION_BLOCK,
01953 timeout_milliseconds);
01954 }
01955
01956 goto recheck_status;
01957 }
01958
01959 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %ld milliseconds and got no reply\n",
01960 (tv_sec - start_tv_sec) * 1000 + (tv_usec - start_tv_usec) / 1000);
01961
01962
01963 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
01964
01965 return NULL;
01966 }
01967
01990 DBusMessage *
01991 dbus_connection_send_with_reply_and_block (DBusConnection *connection,
01992 DBusMessage *message,
01993 int timeout_milliseconds,
01994 DBusError *error)
01995 {
01996 dbus_uint32_t client_serial;
01997 DBusMessage *reply;
01998
01999 _dbus_return_val_if_fail (connection != NULL, NULL);
02000 _dbus_return_val_if_fail (message != NULL, NULL);
02001 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
02002 _dbus_return_val_if_error_is_set (error, NULL);
02003
02004 if (!dbus_connection_send (connection, message, &client_serial))
02005 {
02006 _DBUS_SET_OOM (error);
02007 return NULL;
02008 }
02009
02010 reply = _dbus_connection_block_for_reply (connection,
02011 client_serial,
02012 timeout_milliseconds);
02013
02014 if (reply == NULL)
02015 {
02016 if (dbus_connection_get_is_connected (connection))
02017 dbus_set_error (error, DBUS_ERROR_NO_REPLY, "Message did not receive a reply");
02018 else
02019 dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Disconnected prior to receiving a reply");
02020
02021 return NULL;
02022 }
02023 else if (dbus_set_error_from_message (error, reply))
02024 {
02025 dbus_message_unref (reply);
02026 return NULL;
02027 }
02028 else
02029 return reply;
02030 }
02031
02037 void
02038 dbus_connection_flush (DBusConnection *connection)
02039 {
02040
02041
02042
02043
02044
02045 DBusDispatchStatus status;
02046
02047 _dbus_return_if_fail (connection != NULL);
02048
02049 CONNECTION_LOCK (connection);
02050 while (connection->n_outgoing > 0 &&
02051 _dbus_connection_get_is_connected_unlocked (connection))
02052 _dbus_connection_do_iteration (connection,
02053 DBUS_ITERATION_DO_READING |
02054 DBUS_ITERATION_DO_WRITING |
02055 DBUS_ITERATION_BLOCK,
02056 -1);
02057
02058 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02059
02060
02061 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02062 }
02063
02064
02065
02066
02067 static void
02068 _dbus_connection_wait_for_borrowed (DBusConnection *connection)
02069 {
02070 _dbus_assert (connection->message_borrowed != NULL);
02071
02072 while (connection->message_borrowed != NULL)
02073 dbus_condvar_wait (connection->message_returned_cond, connection->mutex);
02074 }
02075
02090 DBusMessage*
02091 dbus_connection_borrow_message (DBusConnection *connection)
02092 {
02093 DBusMessage *message;
02094 DBusDispatchStatus status;
02095
02096 _dbus_return_val_if_fail (connection != NULL, NULL);
02097
02098 _dbus_return_val_if_fail (!connection->dispatch_acquired, NULL);
02099
02100
02101
02102
02103 status = dbus_connection_get_dispatch_status (connection);
02104 if (status != DBUS_DISPATCH_DATA_REMAINS)
02105 return NULL;
02106
02107 CONNECTION_LOCK (connection);
02108
02109 if (connection->message_borrowed != NULL)
02110 _dbus_connection_wait_for_borrowed (connection);
02111
02112 message = _dbus_list_get_first (&connection->incoming_messages);
02113
02114 if (message)
02115 connection->message_borrowed = message;
02116
02117 CONNECTION_UNLOCK (connection);
02118 return message;
02119 }
02120
02128 void
02129 dbus_connection_return_message (DBusConnection *connection,
02130 DBusMessage *message)
02131 {
02132 _dbus_return_if_fail (connection != NULL);
02133 _dbus_return_if_fail (message != NULL);
02134
02135 _dbus_return_if_fail (!connection->dispatch_acquired);
02136
02137 CONNECTION_LOCK (connection);
02138
02139 _dbus_assert (message == connection->message_borrowed);
02140
02141 connection->message_borrowed = NULL;
02142 dbus_condvar_wake_all (connection->message_returned_cond);
02143
02144 CONNECTION_UNLOCK (connection);
02145 }
02146
02156 void
02157 dbus_connection_steal_borrowed_message (DBusConnection *connection,
02158 DBusMessage *message)
02159 {
02160 DBusMessage *pop_message;
02161
02162 _dbus_return_if_fail (connection != NULL);
02163 _dbus_return_if_fail (message != NULL);
02164
02165 _dbus_return_if_fail (!connection->dispatch_acquired);
02166
02167 CONNECTION_LOCK (connection);
02168
02169 _dbus_assert (message == connection->message_borrowed);
02170
02171 pop_message = _dbus_list_pop_first (&connection->incoming_messages);
02172 _dbus_assert (message == pop_message);
02173
02174 connection->n_incoming -= 1;
02175
02176 _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
02177 message, connection->n_incoming);
02178
02179 connection->message_borrowed = NULL;
02180 dbus_condvar_wake_all (connection->message_returned_cond);
02181
02182 CONNECTION_UNLOCK (connection);
02183 }
02184
02185
02186
02187
02188 static DBusList*
02189 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
02190 {
02191 if (connection->message_borrowed != NULL)
02192 _dbus_connection_wait_for_borrowed (connection);
02193
02194 if (connection->n_incoming > 0)
02195 {
02196 DBusList *link;
02197
02198 link = _dbus_list_pop_first_link (&connection->incoming_messages);
02199 connection->n_incoming -= 1;
02200
02201 _dbus_verbose ("Message %p (%d %s '%s') removed from incoming queue %p, %d incoming\n",
02202 link->data,
02203 dbus_message_get_type (link->data),
02204 dbus_message_get_interface (link->data) ?
02205 dbus_message_get_interface (link->data) :
02206 "no interface",
02207 dbus_message_get_signature (link->data),
02208 connection, connection->n_incoming);
02209
02210 return link;
02211 }
02212 else
02213 return NULL;
02214 }
02215
02216
02217
02218
02219 static DBusMessage*
02220 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
02221 {
02222 DBusList *link;
02223
02224 link = _dbus_connection_pop_message_link_unlocked (connection);
02225
02226 if (link != NULL)
02227 {
02228 DBusMessage *message;
02229
02230 message = link->data;
02231
02232 _dbus_list_free_link (link);
02233
02234 return message;
02235 }
02236 else
02237 return NULL;
02238 }
02239
02240 static void
02241 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
02242 DBusList *message_link)
02243 {
02244 _dbus_assert (message_link != NULL);
02245
02246 _dbus_assert (connection->message_borrowed == NULL);
02247
02248 _dbus_list_prepend_link (&connection->incoming_messages,
02249 message_link);
02250 connection->n_incoming += 1;
02251
02252 _dbus_verbose ("Message %p (%d %s '%s') put back into queue %p, %d incoming\n",
02253 message_link->data,
02254 dbus_message_get_type (message_link->data),
02255 dbus_message_get_interface (message_link->data) ?
02256 dbus_message_get_interface (message_link->data) :
02257 "no interface",
02258 dbus_message_get_signature (message_link->data),
02259 connection, connection->n_incoming);
02260 }
02261
02276 DBusMessage*
02277 dbus_connection_pop_message (DBusConnection *connection)
02278 {
02279 DBusMessage *message;
02280 DBusDispatchStatus status;
02281
02282
02283
02284
02285 status = dbus_connection_get_dispatch_status (connection);
02286 if (status != DBUS_DISPATCH_DATA_REMAINS)
02287 return NULL;
02288
02289 CONNECTION_LOCK (connection);
02290
02291 message = _dbus_connection_pop_message_unlocked (connection);
02292
02293 _dbus_verbose ("Returning popped message %p\n", message);
02294
02295 CONNECTION_UNLOCK (connection);
02296
02297 return message;
02298 }
02299
02308 static void
02309 _dbus_connection_acquire_dispatch (DBusConnection *connection)
02310 {
02311 if (connection->dispatch_acquired)
02312 dbus_condvar_wait (connection->dispatch_cond, connection->mutex);
02313 _dbus_assert (!connection->dispatch_acquired);
02314
02315 connection->dispatch_acquired = TRUE;
02316 }
02317
02325 static void
02326 _dbus_connection_release_dispatch (DBusConnection *connection)
02327 {
02328 _dbus_assert (connection->dispatch_acquired);
02329
02330 connection->dispatch_acquired = FALSE;
02331 dbus_condvar_wake_one (connection->dispatch_cond);
02332 }
02333
02334 static void
02335 _dbus_connection_failed_pop (DBusConnection *connection,
02336 DBusList *message_link)
02337 {
02338 _dbus_list_prepend_link (&connection->incoming_messages,
02339 message_link);
02340 connection->n_incoming += 1;
02341 }
02342
02343 static DBusDispatchStatus
02344 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
02345 {
02346 if (connection->n_incoming > 0)
02347 return DBUS_DISPATCH_DATA_REMAINS;
02348 else if (!_dbus_transport_queue_messages (connection->transport))
02349 return DBUS_DISPATCH_NEED_MEMORY;
02350 else
02351 {
02352 DBusDispatchStatus status;
02353
02354 status = _dbus_transport_get_dispatch_status (connection->transport);
02355
02356 if (status == DBUS_DISPATCH_COMPLETE &&
02357 connection->disconnect_message_link &&
02358 !_dbus_transport_get_is_connected (connection->transport))
02359 {
02360
02361
02362
02363 _dbus_connection_queue_synthesized_message_link (connection,
02364 connection->disconnect_message_link);
02365 connection->disconnect_message_link = NULL;
02366 }
02367
02368 if (status != DBUS_DISPATCH_COMPLETE)
02369 return status;
02370 else if (connection->n_incoming > 0)
02371 return DBUS_DISPATCH_DATA_REMAINS;
02372 else
02373 return DBUS_DISPATCH_COMPLETE;
02374 }
02375 }
02376
02377 static void
02378 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
02379 DBusDispatchStatus new_status)
02380 {
02381 dbus_bool_t changed;
02382 DBusDispatchStatusFunction function;
02383 void *data;
02384
02385
02386
02387 _dbus_connection_ref_unlocked (connection);
02388
02389 changed = new_status != connection->last_dispatch_status;
02390
02391 connection->last_dispatch_status = new_status;
02392
02393 function = connection->dispatch_status_function;
02394 data = connection->dispatch_status_data;
02395
02396
02397 CONNECTION_UNLOCK (connection);
02398
02399 if (changed && function)
02400 {
02401 _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
02402 connection, new_status,
02403 new_status == DBUS_DISPATCH_COMPLETE ? "complete" :
02404 new_status == DBUS_DISPATCH_DATA_REMAINS ? "data remains" :
02405 new_status == DBUS_DISPATCH_NEED_MEMORY ? "need memory" :
02406 "???");
02407 (* function) (connection, new_status, data);
02408 }
02409
02410 dbus_connection_unref (connection);
02411 }
02412
02421 DBusDispatchStatus
02422 dbus_connection_get_dispatch_status (DBusConnection *connection)
02423 {
02424 DBusDispatchStatus status;
02425
02426 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
02427
02428 CONNECTION_LOCK (connection);
02429
02430 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02431
02432 CONNECTION_UNLOCK (connection);
02433
02434 return status;
02435 }
02436
02464 DBusDispatchStatus
02465 dbus_connection_dispatch (DBusConnection *connection)
02466 {
02467 DBusMessage *message;
02468 DBusList *link, *filter_list_copy, *message_link;
02469 DBusHandlerResult result;
02470 DBusPendingCall *pending;
02471 dbus_int32_t reply_serial;
02472 DBusDispatchStatus status;
02473
02474 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
02475
02476 CONNECTION_LOCK (connection);
02477 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02478 if (status != DBUS_DISPATCH_DATA_REMAINS)
02479 {
02480
02481 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02482 return status;
02483 }
02484
02485
02486
02487
02488 _dbus_connection_ref_unlocked (connection);
02489
02490 _dbus_connection_acquire_dispatch (connection);
02491
02492
02493
02494
02495
02496
02497
02498 message_link = _dbus_connection_pop_message_link_unlocked (connection);
02499 if (message_link == NULL)
02500 {
02501
02502
02503 _dbus_connection_release_dispatch (connection);
02504
02505 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02506
02507 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02508
02509 dbus_connection_unref (connection);
02510
02511 return status;
02512 }
02513
02514 message = message_link->data;
02515
02516 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
02517
02518 reply_serial = dbus_message_get_reply_serial (message);
02519 pending = _dbus_hash_table_lookup_int (connection->pending_replies,
02520 reply_serial);
02521
02522 if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
02523 {
02524 _dbus_connection_release_dispatch (connection);
02525
02526 _dbus_connection_failed_pop (connection, message_link);
02527
02528
02529 _dbus_connection_update_dispatch_status_and_unlock (connection,
02530 DBUS_DISPATCH_NEED_MEMORY);
02531
02532 dbus_connection_unref (connection);
02533
02534 return DBUS_DISPATCH_NEED_MEMORY;
02535 }
02536
02537 _dbus_list_foreach (&filter_list_copy,
02538 (DBusForeachFunction)_dbus_message_filter_ref,
02539 NULL);
02540
02541
02542
02543
02544 CONNECTION_UNLOCK (connection);
02545
02546 link = _dbus_list_get_first_link (&filter_list_copy);
02547 while (link != NULL)
02548 {
02549 DBusMessageFilter *filter = link->data;
02550 DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
02551
02552 _dbus_verbose (" running filter on message %p\n", message);
02553 result = (* filter->function) (connection, message, filter->user_data);
02554
02555 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
02556 break;
02557
02558 link = next;
02559 }
02560
02561 _dbus_list_foreach (&filter_list_copy,
02562 (DBusForeachFunction)_dbus_message_filter_unref,
02563 NULL);
02564 _dbus_list_clear (&filter_list_copy);
02565
02566 CONNECTION_LOCK (connection);
02567
02568 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
02569 goto out;
02570
02571
02572 if (pending && result == DBUS_HANDLER_RESULT_HANDLED)
02573 {
02574
02575 if (pending->timeout_link)
02576 {
02577 _dbus_connection_queue_synthesized_message_link (connection,
02578 pending->timeout_link);
02579 pending->timeout_link = NULL;
02580 }
02581 else
02582 {
02583
02584 _dbus_warn ("The timeout error with reply serial %d was filtered, so the DBusPendingCall will never stop pending.\n", reply_serial);
02585 }
02586 }
02587
02588 if (result == DBUS_HANDLER_RESULT_HANDLED)
02589 goto out;
02590
02591 if (pending)
02592 {
02593 _dbus_pending_call_complete_and_unlock (pending, message);
02594
02595 pending = NULL;
02596
02597 CONNECTION_LOCK (connection);
02598 goto out;
02599 }
02600
02601
02602
02603
02604 _dbus_verbose (" running object path dispatch on message %p (%d %s '%s')\n",
02605 message,
02606 dbus_message_get_type (message),
02607 dbus_message_get_interface (message) ?
02608 dbus_message_get_interface (message) :
02609 "no interface",
02610 dbus_message_get_signature (message));
02611
02612 result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
02613 message);
02614
02615 CONNECTION_LOCK (connection);
02616
02617 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
02618 goto out;
02619
02620 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
02621 {
02622 DBusMessage *reply;
02623 DBusString str;
02624 DBusPreallocatedSend *preallocated;
02625
02626 _dbus_verbose (" sending error %s\n",
02627 DBUS_ERROR_UNKNOWN_METHOD);
02628
02629 if (!_dbus_string_init (&str))
02630 {
02631 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
02632 goto out;
02633 }
02634
02635 if (!_dbus_string_append_printf (&str,
02636 "Method \"%s\" on interface \"%s\" doesn't exist\n",
02637 dbus_message_get_member (message),
02638 dbus_message_get_interface (message)))
02639 {
02640 _dbus_string_free (&str);
02641 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
02642 goto out;
02643 }
02644
02645 reply = dbus_message_new_error (message,
02646 DBUS_ERROR_UNKNOWN_METHOD,
02647 _dbus_string_get_const_data (&str));
02648 _dbus_string_free (&str);
02649
02650 if (reply == NULL)
02651 {
02652 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
02653 goto out;
02654 }
02655
02656 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
02657
02658 if (preallocated == NULL)
02659 {
02660 dbus_message_unref (reply);
02661 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
02662 goto out;
02663 }
02664
02665 _dbus_connection_send_preallocated_unlocked (connection, preallocated,
02666 reply, NULL);
02667
02668 dbus_message_unref (reply);
02669
02670 result = DBUS_HANDLER_RESULT_HANDLED;
02671 }
02672
02673 _dbus_verbose (" done dispatching %p (%d %s '%s') on connection %p\n", message,
02674 dbus_message_get_type (message),
02675 dbus_message_get_interface (message) ?
02676 dbus_message_get_interface (message) :
02677 "no interface",
02678 dbus_message_get_signature (message),
02679 connection);
02680
02681 out:
02682 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
02683 {
02684 _dbus_verbose ("out of memory in %s\n", _DBUS_FUNCTION_NAME);
02685
02686
02687
02688
02689
02690 _dbus_connection_putback_message_link_unlocked (connection,
02691 message_link);
02692 }
02693 else
02694 {
02695 _dbus_verbose ("Done with message in %s\n", _DBUS_FUNCTION_NAME);
02696
02697 if (connection->exit_on_disconnect &&
02698 dbus_message_is_signal (message,
02699 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL,
02700 "Disconnected"))
02701 {
02702 _dbus_verbose ("Exiting on Disconnected signal\n");
02703 CONNECTION_UNLOCK (connection);
02704 _dbus_exit (1);
02705 _dbus_assert_not_reached ("Call to exit() returned");
02706 }
02707
02708 _dbus_list_free_link (message_link);
02709 dbus_message_unref (message);
02710
02711
02712 }
02713
02714 _dbus_connection_release_dispatch (connection);
02715
02716 status = _dbus_connection_get_dispatch_status_unlocked (connection);
02717
02718
02719 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
02720
02721 dbus_connection_unref (connection);
02722
02723 return status;
02724 }
02725
02784 dbus_bool_t
02785 dbus_connection_set_watch_functions (DBusConnection *connection,
02786 DBusAddWatchFunction add_function,
02787 DBusRemoveWatchFunction remove_function,
02788 DBusWatchToggledFunction toggled_function,
02789 void *data,
02790 DBusFreeFunction free_data_function)
02791 {
02792 dbus_bool_t retval;
02793
02794 _dbus_return_val_if_fail (connection != NULL, FALSE);
02795
02796 CONNECTION_LOCK (connection);
02797
02798 _dbus_connection_ref_unlocked (connection);
02799
02800
02801
02802
02803 retval = _dbus_watch_list_set_functions (connection->watches,
02804 add_function, remove_function,
02805 toggled_function,
02806 data, free_data_function);
02807
02808 CONNECTION_UNLOCK (connection);
02809
02810 dbus_connection_unref (connection);
02811
02812 return retval;
02813 }
02814
02848 dbus_bool_t
02849 dbus_connection_set_timeout_functions (DBusConnection *connection,
02850 DBusAddTimeoutFunction add_function,
02851 DBusRemoveTimeoutFunction remove_function,
02852 DBusTimeoutToggledFunction toggled_function,
02853 void *data,
02854 DBusFreeFunction free_data_function)
02855 {
02856 dbus_bool_t retval;
02857
02858 _dbus_return_val_if_fail (connection != NULL, FALSE);
02859
02860 CONNECTION_LOCK (connection);
02861
02862 _dbus_connection_ref_unlocked (connection);
02863
02864 retval = _dbus_timeout_list_set_functions (connection->timeouts,
02865 add_function, remove_function,
02866 toggled_function,
02867 data, free_data_function);
02868
02869 CONNECTION_UNLOCK (connection);
02870
02871 dbus_connection_unref (connection);
02872
02873 return retval;
02874 }
02875
02890 void
02891 dbus_connection_set_wakeup_main_function (DBusConnection *connection,
02892 DBusWakeupMainFunction wakeup_main_function,
02893 void *data,
02894 DBusFreeFunction free_data_function)
02895 {
02896 void *old_data;
02897 DBusFreeFunction old_free_data;
02898
02899 _dbus_return_if_fail (connection != NULL);
02900
02901 CONNECTION_LOCK (connection);
02902 old_data = connection->wakeup_main_data;
02903 old_free_data = connection->free_wakeup_main_data;
02904
02905 connection->wakeup_main_function = wakeup_main_function;
02906 connection->wakeup_main_data = data;
02907 connection->free_wakeup_main_data = free_data_function;
02908
02909 CONNECTION_UNLOCK (connection);
02910
02911
02912 if (old_free_data)
02913 (*old_free_data) (old_data);
02914 }
02915
02932 void
02933 dbus_connection_set_dispatch_status_function (DBusConnection *connection,
02934 DBusDispatchStatusFunction function,
02935 void *data,
02936 DBusFreeFunction free_data_function)
02937 {
02938 void *old_data;
02939 DBusFreeFunction old_free_data;
02940
02941 _dbus_return_if_fail (connection != NULL);
02942
02943 CONNECTION_LOCK (connection);
02944 old_data = connection->dispatch_status_data;
02945 old_free_data = connection->free_dispatch_status_data;
02946
02947 connection->dispatch_status_function = function;
02948 connection->dispatch_status_data = data;
02949 connection->free_dispatch_status_data = free_data_function;
02950
02951 CONNECTION_UNLOCK (connection);
02952
02953
02954 if (old_free_data)
02955 (*old_free_data) (old_data);
02956 }
02957
02969 dbus_bool_t
02970 dbus_connection_get_unix_user (DBusConnection *connection,
02971 unsigned long *uid)
02972 {
02973 dbus_bool_t result;
02974
02975 _dbus_return_val_if_fail (connection != NULL, FALSE);
02976 _dbus_return_val_if_fail (uid != NULL, FALSE);
02977
02978 CONNECTION_LOCK (connection);
02979
02980 if (!_dbus_transport_get_is_authenticated (connection->transport))
02981 result = FALSE;
02982 else
02983 result = _dbus_transport_get_unix_user (connection->transport,
02984 uid);
02985 CONNECTION_UNLOCK (connection);
02986
02987 return result;
02988 }
02989
03006 void
03007 dbus_connection_set_unix_user_function (DBusConnection *connection,
03008 DBusAllowUnixUserFunction function,
03009 void *data,
03010 DBusFreeFunction free_data_function)
03011 {
03012 void *old_data = NULL;
03013 DBusFreeFunction old_free_function = NULL;
03014
03015 _dbus_return_if_fail (connection != NULL);
03016
03017 CONNECTION_LOCK (connection);
03018 _dbus_transport_set_unix_user_function (connection->transport,
03019 function, data, free_data_function,
03020 &old_data, &old_free_function);
03021 CONNECTION_UNLOCK (connection);
03022
03023 if (old_free_function != NULL)
03024 (* old_free_function) (old_data);
03025 }
03026
03048 dbus_bool_t
03049 dbus_connection_add_filter (DBusConnection *connection,
03050 DBusHandleMessageFunction function,
03051 void *user_data,
03052 DBusFreeFunction free_data_function)
03053 {
03054 DBusMessageFilter *filter;
03055
03056 _dbus_return_val_if_fail (connection != NULL, FALSE);
03057 _dbus_return_val_if_fail (function != NULL, FALSE);
03058
03059 filter = dbus_new0 (DBusMessageFilter, 1);
03060 if (filter == NULL)
03061 return FALSE;
03062
03063 filter->refcount.value = 1;
03064
03065 CONNECTION_LOCK (connection);
03066
03067 if (!_dbus_list_append (&connection->filter_list,
03068 filter))
03069 {
03070 _dbus_message_filter_unref (filter);
03071 CONNECTION_UNLOCK (connection);
03072 return FALSE;
03073 }
03074
03075
03076
03077
03078
03079
03080 filter->function = function;
03081 filter->user_data = user_data;
03082 filter->free_user_data_function = free_data_function;
03083
03084 CONNECTION_UNLOCK (connection);
03085 return TRUE;
03086 }
03087
03100 void
03101 dbus_connection_remove_filter (DBusConnection *connection,
03102 DBusHandleMessageFunction function,
03103 void *user_data)
03104 {
03105 DBusList *link;
03106 DBusMessageFilter *filter;
03107
03108 _dbus_return_if_fail (connection != NULL);
03109 _dbus_return_if_fail (function != NULL);
03110
03111 CONNECTION_LOCK (connection);
03112
03113 filter = NULL;
03114
03115 link = _dbus_list_get_last_link (&connection->filter_list);
03116 while (link != NULL)
03117 {
03118 filter = link->data;
03119
03120 if (filter->function == function &&
03121 filter->user_data == user_data)
03122 {
03123 _dbus_list_remove_link (&connection->filter_list, link);
03124 filter->function = NULL;
03125
03126 break;
03127 }
03128
03129 link = _dbus_list_get_prev_link (&connection->filter_list, link);
03130 }
03131
03132 CONNECTION_UNLOCK (connection);
03133
03134 #ifndef DBUS_DISABLE_CHECKS
03135 if (filter == NULL)
03136 {
03137 _dbus_warn ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
03138 function, user_data);
03139 return;
03140 }
03141 #endif
03142
03143
03144 if (filter->free_user_data_function)
03145 (* filter->free_user_data_function) (filter->user_data);
03146
03147 filter->free_user_data_function = NULL;
03148 filter->user_data = NULL;
03149
03150 _dbus_message_filter_unref (filter);
03151 }
03152
03164 dbus_bool_t
03165 dbus_connection_register_object_path (DBusConnection *connection,
03166 const char **path,
03167 const DBusObjectPathVTable *vtable,
03168 void *user_data)
03169 {
03170 dbus_bool_t retval;
03171
03172 _dbus_return_val_if_fail (connection != NULL, FALSE);
03173 _dbus_return_val_if_fail (path != NULL, FALSE);
03174 _dbus_return_val_if_fail (path[0] != NULL, FALSE);
03175 _dbus_return_val_if_fail (vtable != NULL, FALSE);
03176
03177 CONNECTION_LOCK (connection);
03178
03179 retval = _dbus_object_tree_register (connection->objects,
03180 FALSE,
03181 path, vtable,
03182 user_data);
03183
03184 CONNECTION_UNLOCK (connection);
03185
03186 return retval;
03187 }
03188
03201 dbus_bool_t
03202 dbus_connection_register_fallback (DBusConnection *connection,
03203 const char **path,
03204 const DBusObjectPathVTable *vtable,
03205 void *user_data)
03206 {
03207 dbus_bool_t retval;
03208
03209 _dbus_return_val_if_fail (connection != NULL, FALSE);
03210 _dbus_return_val_if_fail (path != NULL, FALSE);
03211 _dbus_return_val_if_fail (path[0] != NULL, FALSE);
03212 _dbus_return_val_if_fail (vtable != NULL, FALSE);
03213
03214 CONNECTION_LOCK (connection);
03215
03216 retval = _dbus_object_tree_register (connection->objects,
03217 TRUE,
03218 path, vtable,
03219 user_data);
03220
03221 CONNECTION_UNLOCK (connection);
03222
03223 return retval;
03224 }
03225
03234 void
03235 dbus_connection_unregister_object_path (DBusConnection *connection,
03236 const char **path)
03237 {
03238 _dbus_return_if_fail (connection != NULL);
03239 _dbus_return_if_fail (path != NULL);
03240 _dbus_return_if_fail (path[0] != NULL);
03241
03242 CONNECTION_LOCK (connection);
03243
03244 return _dbus_object_tree_unregister_and_unlock (connection->objects,
03245 path);
03246 }
03247
03258 dbus_bool_t
03259 dbus_connection_list_registered (DBusConnection *connection,
03260 const char **parent_path,
03261 char ***child_entries)
03262 {
03263 _dbus_return_val_if_fail (connection != NULL, FALSE);
03264 _dbus_return_val_if_fail (parent_path != NULL, FALSE);
03265 _dbus_return_val_if_fail (child_entries != NULL, FALSE);
03266
03267 CONNECTION_LOCK (connection);
03268
03269 return _dbus_object_tree_list_registered_and_unlock (connection->objects,
03270 parent_path,
03271 child_entries);
03272 }
03273
03274 static DBusDataSlotAllocator slot_allocator;
03275 _DBUS_DEFINE_GLOBAL_LOCK (connection_slots);
03276
03291 dbus_bool_t
03292 dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
03293 {
03294 return _dbus_data_slot_allocator_alloc (&slot_allocator,
03295 _DBUS_LOCK_NAME (connection_slots),
03296 slot_p);
03297 }
03298
03310 void
03311 dbus_connection_free_data_slot (dbus_int32_t *slot_p)
03312 {
03313 _dbus_return_if_fail (*slot_p >= 0);
03314
03315 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
03316 }
03317
03331 dbus_bool_t
03332 dbus_connection_set_data (DBusConnection *connection,
03333 dbus_int32_t slot,
03334 void *data,
03335 DBusFreeFunction free_data_func)
03336 {
03337 DBusFreeFunction old_free_func;
03338 void *old_data;
03339 dbus_bool_t retval;
03340
03341 _dbus_return_val_if_fail (connection != NULL, FALSE);
03342 _dbus_return_val_if_fail (slot >= 0, FALSE);
03343
03344 CONNECTION_LOCK (connection);
03345
03346 retval = _dbus_data_slot_list_set (&slot_allocator,
03347 &connection->slot_list,
03348 slot, data, free_data_func,
03349 &old_free_func, &old_data);
03350
03351 CONNECTION_UNLOCK (connection);
03352
03353 if (retval)
03354 {
03355
03356 if (old_free_func)
03357 (* old_free_func) (old_data);
03358 }
03359
03360 return retval;
03361 }
03362
03371 void*
03372 dbus_connection_get_data (DBusConnection *connection,
03373 dbus_int32_t slot)
03374 {
03375 void *res;
03376
03377 _dbus_return_val_if_fail (connection != NULL, NULL);
03378
03379 CONNECTION_LOCK (connection);
03380
03381 res = _dbus_data_slot_list_get (&slot_allocator,
03382 &connection->slot_list,
03383 slot);
03384
03385 CONNECTION_UNLOCK (connection);
03386
03387 return res;
03388 }
03389
03396 void
03397 dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
03398 {
03399 _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
03400 }
03401
03410 void
03411 dbus_connection_set_max_message_size (DBusConnection *connection,
03412 long size)
03413 {
03414 _dbus_return_if_fail (connection != NULL);
03415
03416 CONNECTION_LOCK (connection);
03417 _dbus_transport_set_max_message_size (connection->transport,
03418 size);
03419 CONNECTION_UNLOCK (connection);
03420 }
03421
03428 long
03429 dbus_connection_get_max_message_size (DBusConnection *connection)
03430 {
03431 long res;
03432
03433 _dbus_return_val_if_fail (connection != NULL, 0);
03434
03435 CONNECTION_LOCK (connection);
03436 res = _dbus_transport_get_max_message_size (connection->transport);
03437 CONNECTION_UNLOCK (connection);
03438 return res;
03439 }
03440
03466 void
03467 dbus_connection_set_max_received_size (DBusConnection *connection,
03468 long size)
03469 {
03470 _dbus_return_if_fail (connection != NULL);
03471
03472 CONNECTION_LOCK (connection);
03473 _dbus_transport_set_max_received_size (connection->transport,
03474 size);
03475 CONNECTION_UNLOCK (connection);
03476 }
03477
03484 long
03485 dbus_connection_get_max_received_size (DBusConnection *connection)
03486 {
03487 long res;
03488
03489 _dbus_return_val_if_fail (connection != NULL, 0);
03490
03491 CONNECTION_LOCK (connection);
03492 res = _dbus_transport_get_max_received_size (connection->transport);
03493 CONNECTION_UNLOCK (connection);
03494 return res;
03495 }
03496
03507 long
03508 dbus_connection_get_outgoing_size (DBusConnection *connection)
03509 {
03510 long res;
03511
03512 _dbus_return_val_if_fail (connection != NULL, 0);
03513
03514 CONNECTION_LOCK (connection);
03515 res = _dbus_counter_get_value (connection->outgoing_counter);
03516 CONNECTION_UNLOCK (connection);
03517 return res;
03518 }
03519