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