dbus-connection.c revision 1eae184450a585f10c8988613e0f7259e1d6066a
1/* -*- mode: C; c-file-style: "gnu" -*- */ 2/* dbus-connection.c DBusConnection object 3 * 4 * Copyright (C) 2002, 2003, 2004, 2005 Red Hat Inc. 5 * 6 * Licensed under the Academic Free License version 2.1 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * 22 */ 23 24#include <config.h> 25#include "dbus-shared.h" 26#include "dbus-connection.h" 27#include "dbus-list.h" 28#include "dbus-timeout.h" 29#include "dbus-transport.h" 30#include "dbus-watch.h" 31#include "dbus-connection-internal.h" 32#include "dbus-pending-call-internal.h" 33#include "dbus-list.h" 34#include "dbus-hash.h" 35#include "dbus-message-internal.h" 36#include "dbus-threads.h" 37#include "dbus-protocol.h" 38#include "dbus-dataslot.h" 39#include "dbus-string.h" 40#include "dbus-pending-call.h" 41#include "dbus-object-tree.h" 42#include "dbus-threads-internal.h" 43#include "dbus-bus.h" 44 45#ifdef DBUS_DISABLE_CHECKS 46#define TOOK_LOCK_CHECK(connection) 47#define RELEASING_LOCK_CHECK(connection) 48#define HAVE_LOCK_CHECK(connection) 49#else 50#define TOOK_LOCK_CHECK(connection) do { \ 51 _dbus_assert (!(connection)->have_connection_lock); \ 52 (connection)->have_connection_lock = TRUE; \ 53 } while (0) 54#define RELEASING_LOCK_CHECK(connection) do { \ 55 _dbus_assert ((connection)->have_connection_lock); \ 56 (connection)->have_connection_lock = FALSE; \ 57 } while (0) 58#define HAVE_LOCK_CHECK(connection) _dbus_assert ((connection)->have_connection_lock) 59/* A "DO_NOT_HAVE_LOCK_CHECK" is impossible since we need the lock to check the flag */ 60#endif 61 62#define TRACE_LOCKS 1 63 64#define CONNECTION_LOCK(connection) do { \ 65 if (TRACE_LOCKS) { _dbus_verbose (" LOCK: %s\n", _DBUS_FUNCTION_NAME); } \ 66 _dbus_mutex_lock ((connection)->mutex); \ 67 TOOK_LOCK_CHECK (connection); \ 68 } while (0) 69 70#define CONNECTION_UNLOCK(connection) do { \ 71 if (TRACE_LOCKS) { _dbus_verbose (" UNLOCK: %s\n", _DBUS_FUNCTION_NAME); } \ 72 RELEASING_LOCK_CHECK (connection); \ 73 _dbus_mutex_unlock ((connection)->mutex); \ 74 } while (0) 75 76#define DISPATCH_STATUS_NAME(s) \ 77 ((s) == DBUS_DISPATCH_COMPLETE ? "complete" : \ 78 (s) == DBUS_DISPATCH_DATA_REMAINS ? "data remains" : \ 79 (s) == DBUS_DISPATCH_NEED_MEMORY ? "need memory" : \ 80 "???") 81 82/** 83 * @defgroup DBusConnection DBusConnection 84 * @ingroup DBus 85 * @brief Connection to another application 86 * 87 * A DBusConnection represents a connection to another 88 * application. Messages can be sent and received via this connection. 89 * The other application may be a message bus; for convenience, the 90 * function dbus_bus_get() is provided to automatically open a 91 * connection to the well-known message buses. 92 * 93 * In brief a DBusConnection is a message queue associated with some 94 * message transport mechanism such as a socket. The connection 95 * maintains a queue of incoming messages and a queue of outgoing 96 * messages. 97 * 98 * Incoming messages are normally processed by calling 99 * dbus_connection_dispatch(). dbus_connection_dispatch() runs any 100 * handlers registered for the topmost message in the message queue, 101 * then discards the message, then returns. 102 * 103 * dbus_connection_get_dispatch_status() indicates whether 104 * messages are currently in the queue that need dispatching. 105 * dbus_connection_set_dispatch_status_function() allows 106 * you to set a function to be used to monitor the dispatch status. 107 * 108 * If you're using GLib or Qt add-on libraries for D-Bus, there are 109 * special convenience APIs in those libraries that hide 110 * all the details of dispatch and watch/timeout monitoring. 111 * For example, dbus_connection_setup_with_g_main(). 112 * 113 * If you aren't using these add-on libraries, you have to manually 114 * call dbus_connection_set_dispatch_status_function(), 115 * dbus_connection_set_watch_functions(), 116 * dbus_connection_set_timeout_functions() providing appropriate 117 * functions to integrate the connection with your application's main 118 * loop. 119 * 120 * When you use dbus_connection_send() or one of its variants to send 121 * a message, the message is added to the outgoing queue. It's 122 * actually written to the network later; either in 123 * dbus_watch_handle() invoked by your main loop, or in 124 * dbus_connection_flush() which blocks until it can write out the 125 * entire outgoing queue. The GLib/Qt add-on libraries again 126 * handle the details here for you by setting up watch functions. 127 * 128 * When a connection is disconnected, you are guaranteed to get a 129 * signal "Disconnected" from the interface 130 * #DBUS_INTERFACE_LOCAL, path 131 * #DBUS_PATH_LOCAL. 132 * 133 * You may not drop the last reference to a #DBusConnection 134 * until that connection has been disconnected. 135 * 136 * You may dispatch the unprocessed incoming message queue even if the 137 * connection is disconnected. However, "Disconnected" will always be 138 * the last message in the queue (obviously no messages are received 139 * after disconnection). 140 * 141 * #DBusConnection has thread locks and drops them when invoking user 142 * callbacks, so in general is transparently threadsafe. However, 143 * #DBusMessage does NOT have thread locks; you must not send the same 144 * message to multiple #DBusConnection that will be used from 145 * different threads. 146 */ 147 148/** 149 * @defgroup DBusConnectionInternals DBusConnection implementation details 150 * @ingroup DBusInternals 151 * @brief Implementation details of DBusConnection 152 * 153 * @{ 154 */ 155 156/** 157 * Internal struct representing a message filter function 158 */ 159typedef struct DBusMessageFilter DBusMessageFilter; 160 161/** 162 * Internal struct representing a message filter function 163 */ 164struct DBusMessageFilter 165{ 166 DBusAtomic refcount; /**< Reference count */ 167 DBusHandleMessageFunction function; /**< Function to call to filter */ 168 void *user_data; /**< User data for the function */ 169 DBusFreeFunction free_user_data_function; /**< Function to free the user data */ 170}; 171 172 173/** 174 * Internals of DBusPreallocatedSend 175 */ 176struct DBusPreallocatedSend 177{ 178 DBusConnection *connection; /**< Connection we'd send the message to */ 179 DBusList *queue_link; /**< Preallocated link in the queue */ 180 DBusList *counter_link; /**< Preallocated link in the resource counter */ 181}; 182 183static dbus_bool_t _dbus_modify_sigpipe = TRUE; 184 185/** 186 * Implementation details of DBusConnection. All fields are private. 187 */ 188struct DBusConnection 189{ 190 DBusAtomic refcount; /**< Reference count. */ 191 192 DBusMutex *mutex; /**< Lock on the entire DBusConnection */ 193 194 DBusMutex *dispatch_mutex; /**< Protects dispatch_acquired */ 195 DBusCondVar *dispatch_cond; /**< Notify when dispatch_acquired is available */ 196 DBusMutex *io_path_mutex; /**< Protects io_path_acquired */ 197 DBusCondVar *io_path_cond; /**< Notify when io_path_acquired is available */ 198 199 DBusList *outgoing_messages; /**< Queue of messages we need to send, send the end of the list first. */ 200 DBusList *incoming_messages; /**< Queue of messages we have received, end of the list received most recently. */ 201 202 DBusMessage *message_borrowed; /**< Filled in if the first incoming message has been borrowed; 203 * dispatch_acquired will be set by the borrower 204 */ 205 206 int n_outgoing; /**< Length of outgoing queue. */ 207 int n_incoming; /**< Length of incoming queue. */ 208 209 DBusCounter *outgoing_counter; /**< Counts size of outgoing messages. */ 210 211 DBusTransport *transport; /**< Object that sends/receives messages over network. */ 212 DBusWatchList *watches; /**< Stores active watches. */ 213 DBusTimeoutList *timeouts; /**< Stores active timeouts. */ 214 215 DBusList *filter_list; /**< List of filters. */ 216 217 DBusDataSlotList slot_list; /**< Data stored by allocated integer ID */ 218 219 DBusHashTable *pending_replies; /**< Hash of message serials to #DBusPendingCall. */ 220 221 dbus_uint32_t client_serial; /**< Client serial. Increments each time a message is sent */ 222 DBusList *disconnect_message_link; /**< Preallocated list node for queueing the disconnection message */ 223 224 DBusWakeupMainFunction wakeup_main_function; /**< Function to wake up the mainloop */ 225 void *wakeup_main_data; /**< Application data for wakeup_main_function */ 226 DBusFreeFunction free_wakeup_main_data; /**< free wakeup_main_data */ 227 228 DBusDispatchStatusFunction dispatch_status_function; /**< Function on dispatch status changes */ 229 void *dispatch_status_data; /**< Application data for dispatch_status_function */ 230 DBusFreeFunction free_dispatch_status_data; /**< free dispatch_status_data */ 231 232 DBusDispatchStatus last_dispatch_status; /**< The last dispatch status we reported to the application. */ 233 234 DBusList *link_cache; /**< A cache of linked list links to prevent contention 235 * for the global linked list mempool lock 236 */ 237 DBusObjectTree *objects; /**< Object path handlers registered with this connection */ 238 239 char *server_guid; /**< GUID of server if we are in shared_connections, #NULL if server GUID is unknown or connection is private */ 240 241 unsigned int shareable : 1; /**< #TRUE if connection can go in shared_connections once we know the GUID */ 242 243 unsigned int shared : 1; /** < #TRUE if connection is shared and we hold a ref to it */ 244 245 unsigned int dispatch_acquired : 1; /**< Someone has dispatch path (can drain incoming queue) */ 246 unsigned int io_path_acquired : 1; /**< Someone has transport io path (can use the transport to read/write messages) */ 247 248 unsigned int exit_on_disconnect : 1; /**< If #TRUE, exit after handling disconnect signal */ 249 250#ifndef DBUS_DISABLE_CHECKS 251 unsigned int have_connection_lock : 1; /**< Used to check locking */ 252#endif 253 254#ifndef DBUS_DISABLE_CHECKS 255 int generation; /**< _dbus_current_generation that should correspond to this connection */ 256#endif 257}; 258 259static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection); 260static void _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection, 261 DBusDispatchStatus new_status); 262static void _dbus_connection_last_unref (DBusConnection *connection); 263static void _dbus_connection_acquire_dispatch (DBusConnection *connection); 264static void _dbus_connection_release_dispatch (DBusConnection *connection); 265static DBusDispatchStatus _dbus_connection_flush_unlocked (DBusConnection *connection); 266 267static DBusMessageFilter * 268_dbus_message_filter_ref (DBusMessageFilter *filter) 269{ 270 _dbus_assert (filter->refcount.value > 0); 271 _dbus_atomic_inc (&filter->refcount); 272 273 return filter; 274} 275 276static void 277_dbus_message_filter_unref (DBusMessageFilter *filter) 278{ 279 _dbus_assert (filter->refcount.value > 0); 280 281 if (_dbus_atomic_dec (&filter->refcount) == 1) 282 { 283 if (filter->free_user_data_function) 284 (* filter->free_user_data_function) (filter->user_data); 285 286 dbus_free (filter); 287 } 288} 289 290/** 291 * Acquires the connection lock. 292 * 293 * @param connection the connection. 294 */ 295void 296_dbus_connection_lock (DBusConnection *connection) 297{ 298 CONNECTION_LOCK (connection); 299} 300 301/** 302 * Releases the connection lock. 303 * 304 * @param connection the connection. 305 */ 306void 307_dbus_connection_unlock (DBusConnection *connection) 308{ 309 CONNECTION_UNLOCK (connection); 310} 311 312/** 313 * Wakes up the main loop if it is sleeping 314 * Needed if we're e.g. queueing outgoing messages 315 * on a thread while the mainloop sleeps. 316 * 317 * @param connection the connection. 318 */ 319static void 320_dbus_connection_wakeup_mainloop (DBusConnection *connection) 321{ 322 if (connection->wakeup_main_function) 323 (*connection->wakeup_main_function) (connection->wakeup_main_data); 324} 325 326#ifdef DBUS_BUILD_TESTS 327/* For now this function isn't used */ 328/** 329 * Adds a message to the incoming message queue, returning #FALSE 330 * if there's insufficient memory to queue the message. 331 * Does not take over refcount of the message. 332 * 333 * @param connection the connection. 334 * @param message the message to queue. 335 * @returns #TRUE on success. 336 */ 337dbus_bool_t 338_dbus_connection_queue_received_message (DBusConnection *connection, 339 DBusMessage *message) 340{ 341 DBusList *link; 342 343 link = _dbus_list_alloc_link (message); 344 if (link == NULL) 345 return FALSE; 346 347 dbus_message_ref (message); 348 _dbus_connection_queue_received_message_link (connection, link); 349 350 return TRUE; 351} 352 353/** 354 * Gets the locks so we can examine them 355 * 356 * @param connection the connection. 357 * @param mutex_loc return for the location of the main mutex pointer 358 * @param dispatch_mutex_loc return location of the dispatch mutex pointer 359 * @param io_path_mutex_loc return location of the io_path mutex pointer 360 * @param dispatch_cond_loc return location of the dispatch conditional 361 * variable pointer 362 * @param io_path_cond_loc return location of the io_path conditional 363 * variable pointer 364 */ 365void 366_dbus_connection_test_get_locks (DBusConnection *conn, 367 DBusMutex **mutex_loc, 368 DBusMutex **dispatch_mutex_loc, 369 DBusMutex **io_path_mutex_loc, 370 DBusCondVar **dispatch_cond_loc, 371 DBusCondVar **io_path_cond_loc) 372{ 373 *mutex_loc = conn->mutex; 374 *dispatch_mutex_loc = conn->dispatch_mutex; 375 *io_path_mutex_loc = conn->io_path_mutex; 376 *dispatch_cond_loc = conn->dispatch_cond; 377 *io_path_cond_loc = conn->io_path_cond; 378} 379#endif 380 381/** 382 * Adds a message-containing list link to the incoming message queue, 383 * taking ownership of the link and the message's current refcount. 384 * Cannot fail due to lack of memory. 385 * 386 * @param connection the connection. 387 * @param link the message link to queue. 388 */ 389void 390_dbus_connection_queue_received_message_link (DBusConnection *connection, 391 DBusList *link) 392{ 393 DBusPendingCall *pending; 394 dbus_int32_t reply_serial; 395 DBusMessage *message; 396 397 _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport)); 398 399 _dbus_list_append_link (&connection->incoming_messages, 400 link); 401 message = link->data; 402 403 /* If this is a reply we're waiting on, remove timeout for it */ 404 reply_serial = dbus_message_get_reply_serial (message); 405 if (reply_serial != -1) 406 { 407 pending = _dbus_hash_table_lookup_int (connection->pending_replies, 408 reply_serial); 409 if (pending != NULL) 410 { 411 if (_dbus_pending_call_is_timeout_added_unlocked (pending)) 412 _dbus_connection_remove_timeout_unlocked (connection, 413 _dbus_pending_call_get_timeout_unlocked (pending)); 414 415 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE); 416 } 417 } 418 419 420 421 connection->n_incoming += 1; 422 423 _dbus_connection_wakeup_mainloop (connection); 424 425 _dbus_verbose ("Message %p (%d %s %s %s '%s' reply to %u) added to incoming queue %p, %d incoming\n", 426 message, 427 dbus_message_get_type (message), 428 dbus_message_get_path (message) ? 429 dbus_message_get_path (message) : 430 "no path", 431 dbus_message_get_interface (message) ? 432 dbus_message_get_interface (message) : 433 "no interface", 434 dbus_message_get_member (message) ? 435 dbus_message_get_member (message) : 436 "no member", 437 dbus_message_get_signature (message), 438 dbus_message_get_reply_serial (message), 439 connection, 440 connection->n_incoming);} 441 442/** 443 * Adds a link + message to the incoming message queue. 444 * Can't fail. Takes ownership of both link and message. 445 * 446 * @param connection the connection. 447 * @param link the list node and message to queue. 448 * 449 * @todo 1.0? This needs to wake up the mainloop if it is in 450 * a poll/select and this is a multithreaded app. 451 */ 452void 453_dbus_connection_queue_synthesized_message_link (DBusConnection *connection, 454 DBusList *link) 455{ 456 HAVE_LOCK_CHECK (connection); 457 458 _dbus_list_append_link (&connection->incoming_messages, link); 459 460 connection->n_incoming += 1; 461 462 _dbus_connection_wakeup_mainloop (connection); 463 464 _dbus_verbose ("Synthesized message %p added to incoming queue %p, %d incoming\n", 465 link->data, connection, connection->n_incoming); 466} 467 468 469/** 470 * Checks whether there are messages in the outgoing message queue. 471 * Called with connection lock held. 472 * 473 * @param connection the connection. 474 * @returns #TRUE if the outgoing queue is non-empty. 475 */ 476dbus_bool_t 477_dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection) 478{ 479 HAVE_LOCK_CHECK (connection); 480 return connection->outgoing_messages != NULL; 481} 482 483/** 484 * Checks whether there are messages in the outgoing message queue. 485 * 486 * @param connection the connection. 487 * @returns #TRUE if the outgoing queue is non-empty. 488 */ 489dbus_bool_t 490dbus_connection_has_messages_to_send (DBusConnection *connection) 491{ 492 dbus_bool_t v; 493 494 _dbus_return_val_if_fail (connection != NULL, FALSE); 495 496 CONNECTION_LOCK (connection); 497 v = _dbus_connection_has_messages_to_send_unlocked (connection); 498 CONNECTION_UNLOCK (connection); 499 500 return v; 501} 502 503/** 504 * Gets the next outgoing message. The message remains in the 505 * queue, and the caller does not own a reference to it. 506 * 507 * @param connection the connection. 508 * @returns the message to be sent. 509 */ 510DBusMessage* 511_dbus_connection_get_message_to_send (DBusConnection *connection) 512{ 513 HAVE_LOCK_CHECK (connection); 514 515 return _dbus_list_get_last (&connection->outgoing_messages); 516} 517 518/** 519 * Notifies the connection that a message has been sent, so the 520 * message can be removed from the outgoing queue. 521 * Called with the connection lock held. 522 * 523 * @param connection the connection. 524 * @param message the message that was sent. 525 */ 526void 527_dbus_connection_message_sent (DBusConnection *connection, 528 DBusMessage *message) 529{ 530 DBusList *link; 531 532 HAVE_LOCK_CHECK (connection); 533 534 /* This can be called before we even complete authentication, since 535 * it's called on disconnect to clean up the outgoing queue. 536 * It's also called as we successfully send each message. 537 */ 538 539 link = _dbus_list_get_last_link (&connection->outgoing_messages); 540 _dbus_assert (link != NULL); 541 _dbus_assert (link->data == message); 542 543 /* Save this link in the link cache */ 544 _dbus_list_unlink (&connection->outgoing_messages, 545 link); 546 _dbus_list_prepend_link (&connection->link_cache, link); 547 548 connection->n_outgoing -= 1; 549 550 _dbus_verbose ("Message %p (%d %s %s %s '%s') removed from outgoing queue %p, %d left to send\n", 551 message, 552 dbus_message_get_type (message), 553 dbus_message_get_path (message) ? 554 dbus_message_get_path (message) : 555 "no path", 556 dbus_message_get_interface (message) ? 557 dbus_message_get_interface (message) : 558 "no interface", 559 dbus_message_get_member (message) ? 560 dbus_message_get_member (message) : 561 "no member", 562 dbus_message_get_signature (message), 563 connection, connection->n_outgoing); 564 565 /* Save this link in the link cache also */ 566 _dbus_message_remove_size_counter (message, connection->outgoing_counter, 567 &link); 568 _dbus_list_prepend_link (&connection->link_cache, link); 569 570 dbus_message_unref (message); 571} 572 573typedef dbus_bool_t (* DBusWatchAddFunction) (DBusWatchList *list, 574 DBusWatch *watch); 575typedef void (* DBusWatchRemoveFunction) (DBusWatchList *list, 576 DBusWatch *watch); 577typedef void (* DBusWatchToggleFunction) (DBusWatchList *list, 578 DBusWatch *watch, 579 dbus_bool_t enabled); 580 581static dbus_bool_t 582protected_change_watch (DBusConnection *connection, 583 DBusWatch *watch, 584 DBusWatchAddFunction add_function, 585 DBusWatchRemoveFunction remove_function, 586 DBusWatchToggleFunction toggle_function, 587 dbus_bool_t enabled) 588{ 589 DBusWatchList *watches; 590 dbus_bool_t retval; 591 592 HAVE_LOCK_CHECK (connection); 593 594 /* This isn't really safe or reasonable; a better pattern is the "do everything, then 595 * drop lock and call out" one; but it has to be propagated up through all callers 596 */ 597 598 watches = connection->watches; 599 if (watches) 600 { 601 connection->watches = NULL; 602 _dbus_connection_ref_unlocked (connection); 603 CONNECTION_UNLOCK (connection); 604 605 if (add_function) 606 retval = (* add_function) (watches, watch); 607 else if (remove_function) 608 { 609 retval = TRUE; 610 (* remove_function) (watches, watch); 611 } 612 else 613 { 614 retval = TRUE; 615 (* toggle_function) (watches, watch, enabled); 616 } 617 618 CONNECTION_LOCK (connection); 619 connection->watches = watches; 620 _dbus_connection_unref_unlocked (connection); 621 622 return retval; 623 } 624 else 625 return FALSE; 626} 627 628 629/** 630 * Adds a watch using the connection's DBusAddWatchFunction if 631 * available. Otherwise records the watch to be added when said 632 * function is available. Also re-adds the watch if the 633 * DBusAddWatchFunction changes. May fail due to lack of memory. 634 * Connection lock should be held when calling this. 635 * 636 * @param connection the connection. 637 * @param watch the watch to add. 638 * @returns #TRUE on success. 639 */ 640dbus_bool_t 641_dbus_connection_add_watch_unlocked (DBusConnection *connection, 642 DBusWatch *watch) 643{ 644 return protected_change_watch (connection, watch, 645 _dbus_watch_list_add_watch, 646 NULL, NULL, FALSE); 647} 648 649/** 650 * Removes a watch using the connection's DBusRemoveWatchFunction 651 * if available. It's an error to call this function on a watch 652 * that was not previously added. 653 * Connection lock should be held when calling this. 654 * 655 * @param connection the connection. 656 * @param watch the watch to remove. 657 */ 658void 659_dbus_connection_remove_watch_unlocked (DBusConnection *connection, 660 DBusWatch *watch) 661{ 662 protected_change_watch (connection, watch, 663 NULL, 664 _dbus_watch_list_remove_watch, 665 NULL, FALSE); 666} 667 668/** 669 * Toggles a watch and notifies app via connection's 670 * DBusWatchToggledFunction if available. It's an error to call this 671 * function on a watch that was not previously added. 672 * Connection lock should be held when calling this. 673 * 674 * @param connection the connection. 675 * @param watch the watch to toggle. 676 * @param enabled whether to enable or disable 677 */ 678void 679_dbus_connection_toggle_watch_unlocked (DBusConnection *connection, 680 DBusWatch *watch, 681 dbus_bool_t enabled) 682{ 683 _dbus_assert (watch != NULL); 684 685 protected_change_watch (connection, watch, 686 NULL, NULL, 687 _dbus_watch_list_toggle_watch, 688 enabled); 689} 690 691typedef dbus_bool_t (* DBusTimeoutAddFunction) (DBusTimeoutList *list, 692 DBusTimeout *timeout); 693typedef void (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list, 694 DBusTimeout *timeout); 695typedef void (* DBusTimeoutToggleFunction) (DBusTimeoutList *list, 696 DBusTimeout *timeout, 697 dbus_bool_t enabled); 698 699static dbus_bool_t 700protected_change_timeout (DBusConnection *connection, 701 DBusTimeout *timeout, 702 DBusTimeoutAddFunction add_function, 703 DBusTimeoutRemoveFunction remove_function, 704 DBusTimeoutToggleFunction toggle_function, 705 dbus_bool_t enabled) 706{ 707 DBusTimeoutList *timeouts; 708 dbus_bool_t retval; 709 710 HAVE_LOCK_CHECK (connection); 711 712 /* This isn't really safe or reasonable; a better pattern is the "do everything, then 713 * drop lock and call out" one; but it has to be propagated up through all callers 714 */ 715 716 timeouts = connection->timeouts; 717 if (timeouts) 718 { 719 connection->timeouts = NULL; 720 _dbus_connection_ref_unlocked (connection); 721 CONNECTION_UNLOCK (connection); 722 723 if (add_function) 724 retval = (* add_function) (timeouts, timeout); 725 else if (remove_function) 726 { 727 retval = TRUE; 728 (* remove_function) (timeouts, timeout); 729 } 730 else 731 { 732 retval = TRUE; 733 (* toggle_function) (timeouts, timeout, enabled); 734 } 735 736 CONNECTION_LOCK (connection); 737 connection->timeouts = timeouts; 738 _dbus_connection_unref_unlocked (connection); 739 740 return retval; 741 } 742 else 743 return FALSE; 744} 745 746/** 747 * Adds a timeout using the connection's DBusAddTimeoutFunction if 748 * available. Otherwise records the timeout to be added when said 749 * function is available. Also re-adds the timeout if the 750 * DBusAddTimeoutFunction changes. May fail due to lack of memory. 751 * The timeout will fire repeatedly until removed. 752 * Connection lock should be held when calling this. 753 * 754 * @param connection the connection. 755 * @param timeout the timeout to add. 756 * @returns #TRUE on success. 757 */ 758dbus_bool_t 759_dbus_connection_add_timeout_unlocked (DBusConnection *connection, 760 DBusTimeout *timeout) 761{ 762 return protected_change_timeout (connection, timeout, 763 _dbus_timeout_list_add_timeout, 764 NULL, NULL, FALSE); 765} 766 767/** 768 * Removes a timeout using the connection's DBusRemoveTimeoutFunction 769 * if available. It's an error to call this function on a timeout 770 * that was not previously added. 771 * Connection lock should be held when calling this. 772 * 773 * @param connection the connection. 774 * @param timeout the timeout to remove. 775 */ 776void 777_dbus_connection_remove_timeout_unlocked (DBusConnection *connection, 778 DBusTimeout *timeout) 779{ 780 protected_change_timeout (connection, timeout, 781 NULL, 782 _dbus_timeout_list_remove_timeout, 783 NULL, FALSE); 784} 785 786/** 787 * Toggles a timeout and notifies app via connection's 788 * DBusTimeoutToggledFunction if available. It's an error to call this 789 * function on a timeout that was not previously added. 790 * Connection lock should be held when calling this. 791 * 792 * @param connection the connection. 793 * @param timeout the timeout to toggle. 794 * @param enabled whether to enable or disable 795 */ 796void 797_dbus_connection_toggle_timeout_unlocked (DBusConnection *connection, 798 DBusTimeout *timeout, 799 dbus_bool_t enabled) 800{ 801 protected_change_timeout (connection, timeout, 802 NULL, NULL, 803 _dbus_timeout_list_toggle_timeout, 804 enabled); 805} 806 807static dbus_bool_t 808_dbus_connection_attach_pending_call_unlocked (DBusConnection *connection, 809 DBusPendingCall *pending) 810{ 811 dbus_uint32_t reply_serial; 812 DBusTimeout *timeout; 813 814 HAVE_LOCK_CHECK (connection); 815 816 reply_serial = _dbus_pending_call_get_reply_serial_unlocked (pending); 817 818 _dbus_assert (reply_serial != 0); 819 820 timeout = _dbus_pending_call_get_timeout_unlocked (pending); 821 822 if (!_dbus_connection_add_timeout_unlocked (connection, timeout)) 823 return FALSE; 824 825 if (!_dbus_hash_table_insert_int (connection->pending_replies, 826 reply_serial, 827 pending)) 828 { 829 _dbus_connection_remove_timeout_unlocked (connection, timeout); 830 831 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE); 832 HAVE_LOCK_CHECK (connection); 833 return FALSE; 834 } 835 836 _dbus_pending_call_set_timeout_added_unlocked (pending, TRUE); 837 838 _dbus_pending_call_ref_unlocked (pending); 839 840 HAVE_LOCK_CHECK (connection); 841 842 return TRUE; 843} 844 845static void 846free_pending_call_on_hash_removal (void *data) 847{ 848 DBusPendingCall *pending; 849 DBusConnection *connection; 850 851 if (data == NULL) 852 return; 853 854 pending = data; 855 856 connection = _dbus_pending_call_get_connection_unlocked (pending); 857 858 HAVE_LOCK_CHECK (connection); 859 860 if (_dbus_pending_call_is_timeout_added_unlocked (pending)) 861 { 862 _dbus_connection_remove_timeout_unlocked (connection, 863 _dbus_pending_call_get_timeout_unlocked (pending)); 864 865 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE); 866 } 867 868 /* FIXME 1.0? this is sort of dangerous and undesirable to drop the lock 869 * here, but the pending call finalizer could in principle call out to 870 * application code so we pretty much have to... some larger code reorg 871 * might be needed. 872 */ 873 _dbus_connection_ref_unlocked (connection); 874 _dbus_pending_call_unref_and_unlock (pending); 875 CONNECTION_LOCK (connection); 876 _dbus_connection_unref_unlocked (connection); 877} 878 879static void 880_dbus_connection_detach_pending_call_unlocked (DBusConnection *connection, 881 DBusPendingCall *pending) 882{ 883 /* This ends up unlocking to call the pending call finalizer, which is unexpected to 884 * say the least. 885 */ 886 _dbus_hash_table_remove_int (connection->pending_replies, 887 _dbus_pending_call_get_reply_serial_unlocked (pending)); 888} 889 890static void 891_dbus_connection_detach_pending_call_and_unlock (DBusConnection *connection, 892 DBusPendingCall *pending) 893{ 894 /* The idea here is to avoid finalizing the pending call 895 * with the lock held, since there's a destroy notifier 896 * in pending call that goes out to application code. 897 * 898 * There's an extra unlock inside the hash table 899 * "free pending call" function FIXME... 900 */ 901 _dbus_pending_call_ref_unlocked (pending); 902 _dbus_hash_table_remove_int (connection->pending_replies, 903 _dbus_pending_call_get_reply_serial_unlocked (pending)); 904 _dbus_pending_call_unref_and_unlock (pending); 905} 906 907/** 908 * Removes a pending call from the connection, such that 909 * the pending reply will be ignored. May drop the last 910 * reference to the pending call. 911 * 912 * @param connection the connection 913 * @param pending the pending call 914 */ 915void 916_dbus_connection_remove_pending_call (DBusConnection *connection, 917 DBusPendingCall *pending) 918{ 919 CONNECTION_LOCK (connection); 920 _dbus_connection_detach_pending_call_and_unlock (connection, pending); 921} 922 923/** 924 * Acquire the transporter I/O path. This must be done before 925 * doing any I/O in the transporter. May sleep and drop the 926 * IO path mutex while waiting for the I/O path. 927 * 928 * @param connection the connection. 929 * @param timeout_milliseconds maximum blocking time, or -1 for no limit. 930 * @returns TRUE if the I/O path was acquired. 931 */ 932static dbus_bool_t 933_dbus_connection_acquire_io_path (DBusConnection *connection, 934 int timeout_milliseconds) 935{ 936 dbus_bool_t we_acquired; 937 938 HAVE_LOCK_CHECK (connection); 939 940 /* We don't want the connection to vanish */ 941 _dbus_connection_ref_unlocked (connection); 942 943 /* We will only touch io_path_acquired which is protected by our mutex */ 944 CONNECTION_UNLOCK (connection); 945 946 _dbus_verbose ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME); 947 _dbus_mutex_lock (connection->io_path_mutex); 948 949 _dbus_verbose ("%s start connection->io_path_acquired = %d timeout = %d\n", 950 _DBUS_FUNCTION_NAME, connection->io_path_acquired, timeout_milliseconds); 951 952 we_acquired = FALSE; 953 954 if (connection->io_path_acquired) 955 { 956 if (timeout_milliseconds != -1) 957 { 958 _dbus_verbose ("%s waiting %d for IO path to be acquirable\n", 959 _DBUS_FUNCTION_NAME, timeout_milliseconds); 960 _dbus_condvar_wait_timeout (connection->io_path_cond, 961 connection->io_path_mutex, 962 timeout_milliseconds); 963 } 964 else 965 { 966 while (connection->io_path_acquired) 967 { 968 _dbus_verbose ("%s waiting for IO path to be acquirable\n", _DBUS_FUNCTION_NAME); 969 _dbus_condvar_wait (connection->io_path_cond, 970 connection->io_path_mutex); 971 } 972 } 973 } 974 975 if (!connection->io_path_acquired) 976 { 977 we_acquired = TRUE; 978 connection->io_path_acquired = TRUE; 979 } 980 981 _dbus_verbose ("%s end connection->io_path_acquired = %d we_acquired = %d\n", 982 _DBUS_FUNCTION_NAME, connection->io_path_acquired, we_acquired); 983 984 _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME); 985 _dbus_mutex_unlock (connection->io_path_mutex); 986 987 CONNECTION_LOCK (connection); 988 989 HAVE_LOCK_CHECK (connection); 990 991 _dbus_connection_unref_unlocked (connection); 992 993 return we_acquired; 994} 995 996/** 997 * Release the I/O path when you're done with it. Only call 998 * after you've acquired the I/O. Wakes up at most one thread 999 * currently waiting to acquire the I/O path. 1000 * 1001 * @param connection the connection. 1002 */ 1003static void 1004_dbus_connection_release_io_path (DBusConnection *connection) 1005{ 1006 HAVE_LOCK_CHECK (connection); 1007 1008 _dbus_verbose ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME); 1009 _dbus_mutex_lock (connection->io_path_mutex); 1010 1011 _dbus_assert (connection->io_path_acquired); 1012 1013 _dbus_verbose ("%s start connection->io_path_acquired = %d\n", 1014 _DBUS_FUNCTION_NAME, connection->io_path_acquired); 1015 1016 connection->io_path_acquired = FALSE; 1017 _dbus_condvar_wake_one (connection->io_path_cond); 1018 1019 _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME); 1020 _dbus_mutex_unlock (connection->io_path_mutex); 1021} 1022 1023/** 1024 * Queues incoming messages and sends outgoing messages for this 1025 * connection, optionally blocking in the process. Each call to 1026 * _dbus_connection_do_iteration_unlocked() will call select() or poll() one 1027 * time and then read or write data if possible. 1028 * 1029 * The purpose of this function is to be able to flush outgoing 1030 * messages or queue up incoming messages without returning 1031 * control to the application and causing reentrancy weirdness. 1032 * 1033 * The flags parameter allows you to specify whether to 1034 * read incoming messages, write outgoing messages, or both, 1035 * and whether to block if no immediate action is possible. 1036 * 1037 * The timeout_milliseconds parameter does nothing unless the 1038 * iteration is blocking. 1039 * 1040 * If there are no outgoing messages and DBUS_ITERATION_DO_READING 1041 * wasn't specified, then it's impossible to block, even if 1042 * you specify DBUS_ITERATION_BLOCK; in that case the function 1043 * returns immediately. 1044 * 1045 * Called with connection lock held. 1046 * 1047 * @param connection the connection. 1048 * @param flags iteration flags. 1049 * @param timeout_milliseconds maximum blocking time, or -1 for no limit. 1050 */ 1051void 1052_dbus_connection_do_iteration_unlocked (DBusConnection *connection, 1053 unsigned int flags, 1054 int timeout_milliseconds) 1055{ 1056 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME); 1057 1058 HAVE_LOCK_CHECK (connection); 1059 1060 if (connection->n_outgoing == 0) 1061 flags &= ~DBUS_ITERATION_DO_WRITING; 1062 1063 if (_dbus_connection_acquire_io_path (connection, 1064 (flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0)) 1065 { 1066 HAVE_LOCK_CHECK (connection); 1067 1068 _dbus_transport_do_iteration (connection->transport, 1069 flags, timeout_milliseconds); 1070 _dbus_connection_release_io_path (connection); 1071 } 1072 1073 HAVE_LOCK_CHECK (connection); 1074 1075 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME); 1076} 1077 1078/** 1079 * Creates a new connection for the given transport. A transport 1080 * represents a message stream that uses some concrete mechanism, such 1081 * as UNIX domain sockets. May return #NULL if insufficient 1082 * memory exists to create the connection. 1083 * 1084 * @param transport the transport. 1085 * @returns the new connection, or #NULL on failure. 1086 */ 1087DBusConnection* 1088_dbus_connection_new_for_transport (DBusTransport *transport) 1089{ 1090 DBusConnection *connection; 1091 DBusWatchList *watch_list; 1092 DBusTimeoutList *timeout_list; 1093 DBusHashTable *pending_replies; 1094 DBusList *disconnect_link; 1095 DBusMessage *disconnect_message; 1096 DBusCounter *outgoing_counter; 1097 DBusObjectTree *objects; 1098 1099 watch_list = NULL; 1100 connection = NULL; 1101 pending_replies = NULL; 1102 timeout_list = NULL; 1103 disconnect_link = NULL; 1104 disconnect_message = NULL; 1105 outgoing_counter = NULL; 1106 objects = NULL; 1107 1108 watch_list = _dbus_watch_list_new (); 1109 if (watch_list == NULL) 1110 goto error; 1111 1112 timeout_list = _dbus_timeout_list_new (); 1113 if (timeout_list == NULL) 1114 goto error; 1115 1116 pending_replies = 1117 _dbus_hash_table_new (DBUS_HASH_INT, 1118 NULL, 1119 (DBusFreeFunction)free_pending_call_on_hash_removal); 1120 if (pending_replies == NULL) 1121 goto error; 1122 1123 connection = dbus_new0 (DBusConnection, 1); 1124 if (connection == NULL) 1125 goto error; 1126 1127 _dbus_mutex_new_at_location (&connection->mutex); 1128 if (connection->mutex == NULL) 1129 goto error; 1130 1131 _dbus_mutex_new_at_location (&connection->io_path_mutex); 1132 if (connection->io_path_mutex == NULL) 1133 goto error; 1134 1135 _dbus_mutex_new_at_location (&connection->dispatch_mutex); 1136 if (connection->dispatch_mutex == NULL) 1137 goto error; 1138 1139 _dbus_condvar_new_at_location (&connection->dispatch_cond); 1140 if (connection->dispatch_cond == NULL) 1141 goto error; 1142 1143 _dbus_condvar_new_at_location (&connection->io_path_cond); 1144 if (connection->io_path_cond == NULL) 1145 goto error; 1146 1147 disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL, 1148 DBUS_INTERFACE_LOCAL, 1149 "Disconnected"); 1150 1151 if (disconnect_message == NULL) 1152 goto error; 1153 1154 disconnect_link = _dbus_list_alloc_link (disconnect_message); 1155 if (disconnect_link == NULL) 1156 goto error; 1157 1158 outgoing_counter = _dbus_counter_new (); 1159 if (outgoing_counter == NULL) 1160 goto error; 1161 1162 objects = _dbus_object_tree_new (connection); 1163 if (objects == NULL) 1164 goto error; 1165 1166 if (_dbus_modify_sigpipe) 1167 _dbus_disable_sigpipe (); 1168 1169 connection->refcount.value = 1; 1170 connection->transport = transport; 1171 connection->watches = watch_list; 1172 connection->timeouts = timeout_list; 1173 connection->pending_replies = pending_replies; 1174 connection->outgoing_counter = outgoing_counter; 1175 connection->filter_list = NULL; 1176 connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE; /* so we're notified first time there's data */ 1177 connection->objects = objects; 1178 connection->exit_on_disconnect = FALSE; 1179 connection->shareable = FALSE; 1180#ifndef DBUS_DISABLE_CHECKS 1181 connection->generation = _dbus_current_generation; 1182#endif 1183 1184 _dbus_data_slot_list_init (&connection->slot_list); 1185 1186 connection->client_serial = 1; 1187 1188 connection->disconnect_message_link = disconnect_link; 1189 1190 CONNECTION_LOCK (connection); 1191 1192 if (!_dbus_transport_set_connection (transport, connection)) 1193 goto error; 1194 1195 _dbus_transport_ref (transport); 1196 1197 CONNECTION_UNLOCK (connection); 1198 1199 return connection; 1200 1201 error: 1202 if (disconnect_message != NULL) 1203 dbus_message_unref (disconnect_message); 1204 1205 if (disconnect_link != NULL) 1206 _dbus_list_free_link (disconnect_link); 1207 1208 if (connection != NULL) 1209 { 1210 _dbus_condvar_free_at_location (&connection->io_path_cond); 1211 _dbus_condvar_free_at_location (&connection->dispatch_cond); 1212 _dbus_mutex_free_at_location (&connection->mutex); 1213 _dbus_mutex_free_at_location (&connection->io_path_mutex); 1214 _dbus_mutex_free_at_location (&connection->dispatch_mutex); 1215 dbus_free (connection); 1216 } 1217 if (pending_replies) 1218 _dbus_hash_table_unref (pending_replies); 1219 1220 if (watch_list) 1221 _dbus_watch_list_free (watch_list); 1222 1223 if (timeout_list) 1224 _dbus_timeout_list_free (timeout_list); 1225 1226 if (outgoing_counter) 1227 _dbus_counter_unref (outgoing_counter); 1228 1229 if (objects) 1230 _dbus_object_tree_unref (objects); 1231 1232 return NULL; 1233} 1234 1235/** 1236 * Increments the reference count of a DBusConnection. 1237 * Requires that the caller already holds the connection lock. 1238 * 1239 * @param connection the connection. 1240 * @returns the connection. 1241 */ 1242DBusConnection * 1243_dbus_connection_ref_unlocked (DBusConnection *connection) 1244{ 1245 _dbus_assert (connection != NULL); 1246 _dbus_assert (connection->generation == _dbus_current_generation); 1247 1248 HAVE_LOCK_CHECK (connection); 1249 1250#ifdef DBUS_HAVE_ATOMIC_INT 1251 _dbus_atomic_inc (&connection->refcount); 1252#else 1253 _dbus_assert (connection->refcount.value > 0); 1254 connection->refcount.value += 1; 1255#endif 1256 1257 return connection; 1258} 1259 1260/** 1261 * Decrements the reference count of a DBusConnection. 1262 * Requires that the caller already holds the connection lock. 1263 * 1264 * @param connection the connection. 1265 */ 1266void 1267_dbus_connection_unref_unlocked (DBusConnection *connection) 1268{ 1269 dbus_bool_t last_unref; 1270 1271 HAVE_LOCK_CHECK (connection); 1272 1273 _dbus_assert (connection != NULL); 1274 1275 /* The connection lock is better than the global 1276 * lock in the atomic increment fallback 1277 */ 1278 1279#ifdef DBUS_HAVE_ATOMIC_INT 1280 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1); 1281#else 1282 _dbus_assert (connection->refcount.value > 0); 1283 1284 connection->refcount.value -= 1; 1285 last_unref = (connection->refcount.value == 0); 1286#if 0 1287 printf ("unref_unlocked() connection %p count = %d\n", connection, connection->refcount.value); 1288#endif 1289#endif 1290 1291 if (last_unref) 1292 _dbus_connection_last_unref (connection); 1293} 1294 1295static dbus_uint32_t 1296_dbus_connection_get_next_client_serial (DBusConnection *connection) 1297{ 1298 int serial; 1299 1300 serial = connection->client_serial++; 1301 1302 if (connection->client_serial < 0) 1303 connection->client_serial = 1; 1304 1305 return serial; 1306} 1307 1308/** 1309 * A callback for use with dbus_watch_new() to create a DBusWatch. 1310 * 1311 * @todo This is basically a hack - we could delete _dbus_transport_handle_watch() 1312 * and the virtual handle_watch in DBusTransport if we got rid of it. 1313 * The reason this is some work is threading, see the _dbus_connection_handle_watch() 1314 * implementation. 1315 * 1316 * @param watch the watch. 1317 * @param condition the current condition of the file descriptors being watched. 1318 * @param data must be a pointer to a #DBusConnection 1319 * @returns #FALSE if the IO condition may not have been fully handled due to lack of memory 1320 */ 1321dbus_bool_t 1322_dbus_connection_handle_watch (DBusWatch *watch, 1323 unsigned int condition, 1324 void *data) 1325{ 1326 DBusConnection *connection; 1327 dbus_bool_t retval; 1328 DBusDispatchStatus status; 1329 1330 connection = data; 1331 1332 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME); 1333 1334 CONNECTION_LOCK (connection); 1335 _dbus_connection_acquire_io_path (connection, -1); 1336 HAVE_LOCK_CHECK (connection); 1337 retval = _dbus_transport_handle_watch (connection->transport, 1338 watch, condition); 1339 1340 _dbus_connection_release_io_path (connection); 1341 1342 HAVE_LOCK_CHECK (connection); 1343 1344 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME); 1345 1346 status = _dbus_connection_get_dispatch_status_unlocked (connection); 1347 1348 /* this calls out to user code */ 1349 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 1350 1351 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME); 1352 1353 return retval; 1354} 1355 1356_DBUS_DEFINE_GLOBAL_LOCK (shared_connections); 1357static DBusHashTable *shared_connections = NULL; 1358 1359static void 1360shared_connections_shutdown (void *data) 1361{ 1362 _DBUS_LOCK (shared_connections); 1363 1364 _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) == 0); 1365 1366 _dbus_hash_table_unref (shared_connections); 1367 shared_connections = NULL; 1368 1369 _DBUS_UNLOCK (shared_connections); 1370} 1371 1372static dbus_bool_t 1373connection_lookup_shared (DBusAddressEntry *entry, 1374 DBusConnection **result) 1375{ 1376 _dbus_verbose ("checking for existing connection\n"); 1377 1378 *result = NULL; 1379 1380 _DBUS_LOCK (shared_connections); 1381 1382 if (shared_connections == NULL) 1383 { 1384 _dbus_verbose ("creating shared_connections hash table\n"); 1385 1386 shared_connections = _dbus_hash_table_new (DBUS_HASH_STRING, 1387 dbus_free, 1388 NULL); 1389 if (shared_connections == NULL) 1390 { 1391 _DBUS_UNLOCK (shared_connections); 1392 return FALSE; 1393 } 1394 1395 if (!_dbus_register_shutdown_func (shared_connections_shutdown, NULL)) 1396 { 1397 _dbus_hash_table_unref (shared_connections); 1398 shared_connections = NULL; 1399 _DBUS_UNLOCK (shared_connections); 1400 return FALSE; 1401 } 1402 1403 _dbus_verbose (" successfully created shared_connections\n"); 1404 1405 _DBUS_UNLOCK (shared_connections); 1406 return TRUE; /* no point looking up in the hash we just made */ 1407 } 1408 else 1409 { 1410 const char *guid; 1411 1412 guid = dbus_address_entry_get_value (entry, "guid"); 1413 1414 if (guid != NULL) 1415 { 1416 *result = _dbus_hash_table_lookup_string (shared_connections, 1417 guid); 1418 1419 if (*result) 1420 { 1421 /* The DBusConnection can't have been disconnected 1422 * between the lookup and this code, because the 1423 * disconnection will take the shared_connections lock to 1424 * remove the connection. It can't have been finalized 1425 * since you have to disconnect prior to finalize. 1426 * 1427 * Thus it's safe to ref the connection. 1428 */ 1429 dbus_connection_ref (*result); 1430 1431 _dbus_verbose ("looked up existing connection to server guid %s\n", 1432 guid); 1433 } 1434 } 1435 1436 _DBUS_UNLOCK (shared_connections); 1437 return TRUE; 1438 } 1439} 1440 1441static dbus_bool_t 1442connection_record_shared_unlocked (DBusConnection *connection, 1443 const char *guid) 1444{ 1445 char *guid_key; 1446 char *guid_in_connection; 1447 1448 /* A separate copy of the key is required in the hash table, because 1449 * we don't have a lock on the connection when we are doing a hash 1450 * lookup. 1451 */ 1452 1453 _dbus_assert (connection->server_guid == NULL); 1454 _dbus_assert (connection->shareable); 1455 1456 guid_key = _dbus_strdup (guid); 1457 if (guid_key == NULL) 1458 return FALSE; 1459 1460 guid_in_connection = _dbus_strdup (guid); 1461 if (guid_in_connection == NULL) 1462 { 1463 dbus_free (guid_key); 1464 return FALSE; 1465 } 1466 1467 _DBUS_LOCK (shared_connections); 1468 _dbus_assert (shared_connections != NULL); 1469 1470 if (!_dbus_hash_table_insert_string (shared_connections, 1471 guid_key, connection)) 1472 { 1473 dbus_free (guid_key); 1474 dbus_free (guid_in_connection); 1475 _DBUS_UNLOCK (shared_connections); 1476 return FALSE; 1477 } 1478 1479 connection->server_guid = guid_in_connection; 1480 connection->shared = TRUE; 1481 1482 /* get a hard ref on this connection */ 1483 dbus_connection_ref (connection); 1484 1485 _dbus_verbose ("stored connection to %s to be shared\n", 1486 connection->server_guid); 1487 1488 _DBUS_UNLOCK (shared_connections); 1489 1490 _dbus_assert (connection->server_guid != NULL); 1491 1492 return TRUE; 1493} 1494 1495static void 1496connection_forget_shared_unlocked (DBusConnection *connection) 1497{ 1498 HAVE_LOCK_CHECK (connection); 1499 1500 if (connection->server_guid == NULL) 1501 return; 1502 1503 _dbus_verbose ("dropping connection to %s out of the shared table\n", 1504 connection->server_guid); 1505 1506 _DBUS_LOCK (shared_connections); 1507 1508 if (!_dbus_hash_table_remove_string (shared_connections, 1509 connection->server_guid)) 1510 _dbus_assert_not_reached ("connection was not in the shared table"); 1511 1512 dbus_free (connection->server_guid); 1513 connection->server_guid = NULL; 1514 1515 /* remove the hash ref */ 1516 _dbus_connection_unref_unlocked (connection); 1517 _DBUS_UNLOCK (shared_connections); 1518} 1519 1520static DBusConnection* 1521connection_try_from_address_entry (DBusAddressEntry *entry, 1522 DBusError *error) 1523{ 1524 DBusTransport *transport; 1525 DBusConnection *connection; 1526 1527 transport = _dbus_transport_open (entry, error); 1528 1529 if (transport == NULL) 1530 { 1531 _DBUS_ASSERT_ERROR_IS_SET (error); 1532 return NULL; 1533 } 1534 1535 connection = _dbus_connection_new_for_transport (transport); 1536 1537 _dbus_transport_unref (transport); 1538 1539 if (connection == NULL) 1540 { 1541 _DBUS_SET_OOM (error); 1542 return NULL; 1543 } 1544 1545#ifndef DBUS_DISABLE_CHECKS 1546 _dbus_assert (!connection->have_connection_lock); 1547#endif 1548 return connection; 1549} 1550 1551/* 1552 * If the shared parameter is true, then any existing connection will 1553 * be used (and if a new connection is created, it will be available 1554 * for use by others). If the shared parameter is false, a new 1555 * connection will always be created, and the new connection will 1556 * never be returned to other callers. 1557 * 1558 * @param address the address 1559 * @param shared whether the connection is shared or private 1560 * @param error error return 1561 * @returns the connection or #NULL on error 1562 */ 1563static DBusConnection* 1564_dbus_connection_open_internal (const char *address, 1565 dbus_bool_t shared, 1566 DBusError *error) 1567{ 1568 DBusConnection *connection; 1569 DBusAddressEntry **entries; 1570 DBusError tmp_error; 1571 DBusError first_error; 1572 int len, i; 1573 1574 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1575 1576 _dbus_verbose ("opening %s connection to: %s\n", 1577 shared ? "shared" : "private", address); 1578 1579 if (!dbus_parse_address (address, &entries, &len, error)) 1580 return NULL; 1581 1582 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1583 1584 connection = NULL; 1585 1586 dbus_error_init (&tmp_error); 1587 dbus_error_init (&first_error); 1588 for (i = 0; i < len; i++) 1589 { 1590 if (shared) 1591 { 1592 if (!connection_lookup_shared (entries[i], &connection)) 1593 _DBUS_SET_OOM (&tmp_error); 1594 } 1595 1596 if (connection == NULL) 1597 { 1598 connection = connection_try_from_address_entry (entries[i], 1599 &tmp_error); 1600 1601 if (connection != NULL && shared) 1602 { 1603 const char *guid; 1604 1605 connection->shareable = TRUE; 1606 1607 guid = dbus_address_entry_get_value (entries[i], "guid"); 1608 1609 /* we don't have a connection lock but we know nobody 1610 * else has a handle to the connection 1611 */ 1612 1613 if (guid && 1614 !connection_record_shared_unlocked (connection, guid)) 1615 { 1616 _DBUS_SET_OOM (&tmp_error); 1617 _dbus_connection_close_internal (connection); 1618 dbus_connection_unref (connection); 1619 connection = NULL; 1620 } 1621 1622 /* but as of now the connection is possibly shared 1623 * since another thread could have pulled it from the table 1624 */ 1625 } 1626 } 1627 1628 if (connection) 1629 break; 1630 1631 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error); 1632 1633 if (i == 0) 1634 dbus_move_error (&tmp_error, &first_error); 1635 else 1636 dbus_error_free (&tmp_error); 1637 } 1638 1639 /* NOTE we don't have a lock on a possibly-shared connection object */ 1640 1641 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1642 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error); 1643 1644 if (connection == NULL) 1645 { 1646 _DBUS_ASSERT_ERROR_IS_SET (&first_error); 1647 dbus_move_error (&first_error, error); 1648 } 1649 else 1650 { 1651 dbus_error_free (&first_error); 1652 } 1653 1654 dbus_address_entries_free (entries); 1655 return connection; 1656} 1657 1658/** @} */ 1659 1660/** 1661 * @addtogroup DBusConnection 1662 * 1663 * @{ 1664 */ 1665 1666/** 1667 * Gets a connection to a remote address. If a connection to the given 1668 * address already exists, returns the existing connection with its 1669 * reference count incremented. Otherwise, returns a new connection 1670 * and saves the new connection for possible re-use if a future call 1671 * to dbus_connection_open() asks to connect to the same server. 1672 * 1673 * Use dbus_connection_open_private() to get a dedicated connection 1674 * not shared with other callers of dbus_connection_open(). 1675 * 1676 * If the open fails, the function returns #NULL, and provides a 1677 * reason for the failure in the error parameter. Pass #NULL for the 1678 * error parameter if you aren't interested in the reason for 1679 * failure. 1680 * 1681 * @param address the address. 1682 * @param error address where an error can be returned. 1683 * @returns new connection, or #NULL on failure. 1684 */ 1685DBusConnection* 1686dbus_connection_open (const char *address, 1687 DBusError *error) 1688{ 1689 DBusConnection *connection; 1690 1691 _dbus_return_val_if_fail (address != NULL, NULL); 1692 _dbus_return_val_if_error_is_set (error, NULL); 1693 1694 connection = _dbus_connection_open_internal (address, 1695 TRUE, 1696 error); 1697 1698 return connection; 1699} 1700 1701/** 1702 * Opens a new, dedicated connection to a remote address. Unlike 1703 * dbus_connection_open(), always creates a new connection. 1704 * This connection will not be saved or recycled by libdbus. 1705 * 1706 * If the open fails, the function returns #NULL, and provides a 1707 * reason for the failure in the error parameter. Pass #NULL for the 1708 * error parameter if you aren't interested in the reason for 1709 * failure. 1710 * 1711 * @param address the address. 1712 * @param error address where an error can be returned. 1713 * @returns new connection, or #NULL on failure. 1714 */ 1715DBusConnection* 1716dbus_connection_open_private (const char *address, 1717 DBusError *error) 1718{ 1719 DBusConnection *connection; 1720 1721 _dbus_return_val_if_fail (address != NULL, NULL); 1722 _dbus_return_val_if_error_is_set (error, NULL); 1723 1724 connection = _dbus_connection_open_internal (address, 1725 FALSE, 1726 error); 1727 1728 return connection; 1729} 1730 1731/** 1732 * Increments the reference count of a DBusConnection. 1733 * 1734 * @param connection the connection. 1735 * @returns the connection. 1736 */ 1737DBusConnection * 1738dbus_connection_ref (DBusConnection *connection) 1739{ 1740 _dbus_return_val_if_fail (connection != NULL, NULL); 1741 _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL); 1742 1743 /* The connection lock is better than the global 1744 * lock in the atomic increment fallback 1745 */ 1746 1747#ifdef DBUS_HAVE_ATOMIC_INT 1748 _dbus_atomic_inc (&connection->refcount); 1749#else 1750 CONNECTION_LOCK (connection); 1751 _dbus_assert (connection->refcount.value > 0); 1752 1753 connection->refcount.value += 1; 1754 CONNECTION_UNLOCK (connection); 1755#endif 1756 1757 return connection; 1758} 1759 1760static void 1761free_outgoing_message (void *element, 1762 void *data) 1763{ 1764 DBusMessage *message = element; 1765 DBusConnection *connection = data; 1766 1767 _dbus_message_remove_size_counter (message, 1768 connection->outgoing_counter, 1769 NULL); 1770 dbus_message_unref (message); 1771} 1772 1773/* This is run without the mutex held, but after the last reference 1774 * to the connection has been dropped we should have no thread-related 1775 * problems 1776 */ 1777static void 1778_dbus_connection_last_unref (DBusConnection *connection) 1779{ 1780 DBusList *link; 1781 1782 _dbus_verbose ("Finalizing connection %p\n", connection); 1783 1784 _dbus_assert (connection->refcount.value == 0); 1785 1786 /* You have to disconnect the connection before unref:ing it. Otherwise 1787 * you won't get the disconnected message. 1788 */ 1789 _dbus_assert (!_dbus_transport_get_is_connected (connection->transport)); 1790 _dbus_assert (connection->server_guid == NULL); 1791 1792 /* ---- We're going to call various application callbacks here, hope it doesn't break anything... */ 1793 _dbus_object_tree_free_all_unlocked (connection->objects); 1794 1795 dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL); 1796 dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL); 1797 dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL); 1798 1799 _dbus_watch_list_free (connection->watches); 1800 connection->watches = NULL; 1801 1802 _dbus_timeout_list_free (connection->timeouts); 1803 connection->timeouts = NULL; 1804 1805 _dbus_data_slot_list_free (&connection->slot_list); 1806 1807 link = _dbus_list_get_first_link (&connection->filter_list); 1808 while (link != NULL) 1809 { 1810 DBusMessageFilter *filter = link->data; 1811 DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link); 1812 1813 filter->function = NULL; 1814 _dbus_message_filter_unref (filter); /* calls app callback */ 1815 link->data = NULL; 1816 1817 link = next; 1818 } 1819 _dbus_list_clear (&connection->filter_list); 1820 1821 /* ---- Done with stuff that invokes application callbacks */ 1822 1823 _dbus_object_tree_unref (connection->objects); 1824 1825 _dbus_hash_table_unref (connection->pending_replies); 1826 connection->pending_replies = NULL; 1827 1828 _dbus_list_clear (&connection->filter_list); 1829 1830 _dbus_list_foreach (&connection->outgoing_messages, 1831 free_outgoing_message, 1832 connection); 1833 _dbus_list_clear (&connection->outgoing_messages); 1834 1835 _dbus_list_foreach (&connection->incoming_messages, 1836 (DBusForeachFunction) dbus_message_unref, 1837 NULL); 1838 _dbus_list_clear (&connection->incoming_messages); 1839 1840 _dbus_counter_unref (connection->outgoing_counter); 1841 1842 _dbus_transport_unref (connection->transport); 1843 1844 if (connection->disconnect_message_link) 1845 { 1846 DBusMessage *message = connection->disconnect_message_link->data; 1847 dbus_message_unref (message); 1848 _dbus_list_free_link (connection->disconnect_message_link); 1849 } 1850 1851 _dbus_list_clear (&connection->link_cache); 1852 1853 _dbus_condvar_free_at_location (&connection->dispatch_cond); 1854 _dbus_condvar_free_at_location (&connection->io_path_cond); 1855 1856 _dbus_mutex_free_at_location (&connection->io_path_mutex); 1857 _dbus_mutex_free_at_location (&connection->dispatch_mutex); 1858 1859 _dbus_mutex_free_at_location (&connection->mutex); 1860 1861 dbus_free (connection); 1862} 1863 1864/** 1865 * Decrements the reference count of a DBusConnection, and finalizes 1866 * it if the count reaches zero. It is a bug to drop the last reference 1867 * to a connection that has not been disconnected. 1868 * 1869 * @todo in practice it can be quite tricky to never unref a connection 1870 * that's still connected; maybe there's some way we could avoid 1871 * the requirement. 1872 * 1873 * @param connection the connection. 1874 */ 1875void 1876dbus_connection_unref (DBusConnection *connection) 1877{ 1878 dbus_bool_t last_unref; 1879 1880 _dbus_return_if_fail (connection != NULL); 1881 _dbus_return_if_fail (connection->generation == _dbus_current_generation); 1882 1883 /* The connection lock is better than the global 1884 * lock in the atomic increment fallback 1885 */ 1886 1887#ifdef DBUS_HAVE_ATOMIC_INT 1888 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1); 1889#else 1890 CONNECTION_LOCK (connection); 1891 1892 _dbus_assert (connection->refcount.value > 0); 1893 1894 connection->refcount.value -= 1; 1895 last_unref = (connection->refcount.value == 0); 1896 1897#if 0 1898 printf ("unref() connection %p count = %d\n", connection, connection->refcount.value); 1899#endif 1900 1901 CONNECTION_UNLOCK (connection); 1902#endif 1903 1904 if (last_unref) 1905 _dbus_connection_last_unref (connection); 1906} 1907 1908static void 1909_dbus_connection_close_internal_and_unlock (DBusConnection *connection) 1910{ 1911 DBusDispatchStatus status; 1912 1913 _dbus_verbose ("Disconnecting %p\n", connection); 1914 1915 _dbus_transport_disconnect (connection->transport); 1916 1917 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME); 1918 status = _dbus_connection_get_dispatch_status_unlocked (connection); 1919 1920 /* this calls out to user code */ 1921 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 1922} 1923 1924void 1925_dbus_connection_close_internal (DBusConnection *connection) 1926{ 1927 _dbus_assert (connection != NULL); 1928 _dbus_assert (connection->generation == _dbus_current_generation); 1929 1930 CONNECTION_LOCK (connection); 1931 _dbus_connection_close_internal_and_unlock (connection); 1932} 1933 1934/** 1935 * Closes the connection, so no further data can be sent or received. 1936 * Any further attempts to send data will result in errors. This 1937 * function does not affect the connection's reference count. It's 1938 * safe to disconnect a connection more than once; all calls after the 1939 * first do nothing. It's impossible to "reopen" a connection, a 1940 * new connection must be created. This function may result in a call 1941 * to the DBusDispatchStatusFunction set with 1942 * dbus_connection_set_dispatch_status_function(), as the disconnect 1943 * message it generates needs to be dispatched. 1944 * 1945 * If the connection is a shared connection we print out a warning that 1946 * you can not close shared connection and we return. Internal calls 1947 * should use _dbus_connection_close_internal() to close shared connections. 1948 * 1949 * @param connection the connection. 1950 */ 1951void 1952dbus_connection_close (DBusConnection *connection) 1953{ 1954 _dbus_return_if_fail (connection != NULL); 1955 _dbus_return_if_fail (connection->generation == _dbus_current_generation); 1956 1957 CONNECTION_LOCK (connection); 1958 1959 if (connection->shared) 1960 { 1961 CONNECTION_UNLOCK (connection); 1962 1963 _dbus_warn ("Applications can not close shared connections. Please fix this in your app. Ignoring close request and continuing."); 1964 return; 1965 } 1966 1967 _dbus_connection_close_internal_and_unlock (connection); 1968} 1969 1970static dbus_bool_t 1971_dbus_connection_get_is_connected_unlocked (DBusConnection *connection) 1972{ 1973 HAVE_LOCK_CHECK (connection); 1974 return _dbus_transport_get_is_connected (connection->transport); 1975} 1976 1977/** 1978 * Gets whether the connection is currently connected. All 1979 * connections are connected when they are opened. A connection may 1980 * become disconnected when the remote application closes its end, or 1981 * exits; a connection may also be disconnected with 1982 * dbus_connection_close(). 1983 * 1984 * @param connection the connection. 1985 * @returns #TRUE if the connection is still alive. 1986 */ 1987dbus_bool_t 1988dbus_connection_get_is_connected (DBusConnection *connection) 1989{ 1990 dbus_bool_t res; 1991 1992 _dbus_return_val_if_fail (connection != NULL, FALSE); 1993 1994 CONNECTION_LOCK (connection); 1995 res = _dbus_connection_get_is_connected_unlocked (connection); 1996 CONNECTION_UNLOCK (connection); 1997 1998 return res; 1999} 2000 2001/** 2002 * Gets whether the connection was authenticated. (Note that 2003 * if the connection was authenticated then disconnected, 2004 * this function still returns #TRUE) 2005 * 2006 * @param connection the connection 2007 * @returns #TRUE if the connection was ever authenticated 2008 */ 2009dbus_bool_t 2010dbus_connection_get_is_authenticated (DBusConnection *connection) 2011{ 2012 dbus_bool_t res; 2013 2014 _dbus_return_val_if_fail (connection != NULL, FALSE); 2015 2016 CONNECTION_LOCK (connection); 2017 res = _dbus_transport_get_is_authenticated (connection->transport); 2018 CONNECTION_UNLOCK (connection); 2019 2020 return res; 2021} 2022 2023/** 2024 * Set whether _exit() should be called when the connection receives a 2025 * disconnect signal. The call to _exit() comes after any handlers for 2026 * the disconnect signal run; handlers can cancel the exit by calling 2027 * this function. 2028 * 2029 * By default, exit_on_disconnect is #FALSE; but for message bus 2030 * connections returned from dbus_bus_get() it will be toggled on 2031 * by default. 2032 * 2033 * @param connection the connection 2034 * @param exit_on_disconnect #TRUE if _exit() should be called after a disconnect signal 2035 */ 2036void 2037dbus_connection_set_exit_on_disconnect (DBusConnection *connection, 2038 dbus_bool_t exit_on_disconnect) 2039{ 2040 _dbus_return_if_fail (connection != NULL); 2041 2042 CONNECTION_LOCK (connection); 2043 connection->exit_on_disconnect = exit_on_disconnect != FALSE; 2044 CONNECTION_UNLOCK (connection); 2045} 2046 2047static DBusPreallocatedSend* 2048_dbus_connection_preallocate_send_unlocked (DBusConnection *connection) 2049{ 2050 DBusPreallocatedSend *preallocated; 2051 2052 HAVE_LOCK_CHECK (connection); 2053 2054 _dbus_assert (connection != NULL); 2055 2056 preallocated = dbus_new (DBusPreallocatedSend, 1); 2057 if (preallocated == NULL) 2058 return NULL; 2059 2060 if (connection->link_cache != NULL) 2061 { 2062 preallocated->queue_link = 2063 _dbus_list_pop_first_link (&connection->link_cache); 2064 preallocated->queue_link->data = NULL; 2065 } 2066 else 2067 { 2068 preallocated->queue_link = _dbus_list_alloc_link (NULL); 2069 if (preallocated->queue_link == NULL) 2070 goto failed_0; 2071 } 2072 2073 if (connection->link_cache != NULL) 2074 { 2075 preallocated->counter_link = 2076 _dbus_list_pop_first_link (&connection->link_cache); 2077 preallocated->counter_link->data = connection->outgoing_counter; 2078 } 2079 else 2080 { 2081 preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter); 2082 if (preallocated->counter_link == NULL) 2083 goto failed_1; 2084 } 2085 2086 _dbus_counter_ref (preallocated->counter_link->data); 2087 2088 preallocated->connection = connection; 2089 2090 return preallocated; 2091 2092 failed_1: 2093 _dbus_list_free_link (preallocated->queue_link); 2094 failed_0: 2095 dbus_free (preallocated); 2096 2097 return NULL; 2098} 2099 2100/** 2101 * Preallocates resources needed to send a message, allowing the message 2102 * to be sent without the possibility of memory allocation failure. 2103 * Allows apps to create a future guarantee that they can send 2104 * a message regardless of memory shortages. 2105 * 2106 * @param connection the connection we're preallocating for. 2107 * @returns the preallocated resources, or #NULL 2108 */ 2109DBusPreallocatedSend* 2110dbus_connection_preallocate_send (DBusConnection *connection) 2111{ 2112 DBusPreallocatedSend *preallocated; 2113 2114 _dbus_return_val_if_fail (connection != NULL, NULL); 2115 2116 CONNECTION_LOCK (connection); 2117 2118 preallocated = 2119 _dbus_connection_preallocate_send_unlocked (connection); 2120 2121 CONNECTION_UNLOCK (connection); 2122 2123 return preallocated; 2124} 2125 2126/** 2127 * Frees preallocated message-sending resources from 2128 * dbus_connection_preallocate_send(). Should only 2129 * be called if the preallocated resources are not used 2130 * to send a message. 2131 * 2132 * @param connection the connection 2133 * @param preallocated the resources 2134 */ 2135void 2136dbus_connection_free_preallocated_send (DBusConnection *connection, 2137 DBusPreallocatedSend *preallocated) 2138{ 2139 _dbus_return_if_fail (connection != NULL); 2140 _dbus_return_if_fail (preallocated != NULL); 2141 _dbus_return_if_fail (connection == preallocated->connection); 2142 2143 _dbus_list_free_link (preallocated->queue_link); 2144 _dbus_counter_unref (preallocated->counter_link->data); 2145 _dbus_list_free_link (preallocated->counter_link); 2146 dbus_free (preallocated); 2147} 2148 2149/* Called with lock held, does not update dispatch status */ 2150static void 2151_dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *connection, 2152 DBusPreallocatedSend *preallocated, 2153 DBusMessage *message, 2154 dbus_uint32_t *client_serial) 2155{ 2156 dbus_uint32_t serial; 2157 const char *sig; 2158 2159 preallocated->queue_link->data = message; 2160 _dbus_list_prepend_link (&connection->outgoing_messages, 2161 preallocated->queue_link); 2162 2163 _dbus_message_add_size_counter_link (message, 2164 preallocated->counter_link); 2165 2166 dbus_free (preallocated); 2167 preallocated = NULL; 2168 2169 dbus_message_ref (message); 2170 2171 connection->n_outgoing += 1; 2172 2173 sig = dbus_message_get_signature (message); 2174 2175 _dbus_verbose ("Message %p (%d %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n", 2176 message, 2177 dbus_message_get_type (message), 2178 dbus_message_get_path (message) ? 2179 dbus_message_get_path (message) : 2180 "no path", 2181 dbus_message_get_interface (message) ? 2182 dbus_message_get_interface (message) : 2183 "no interface", 2184 dbus_message_get_member (message) ? 2185 dbus_message_get_member (message) : 2186 "no member", 2187 sig, 2188 dbus_message_get_destination (message) ? 2189 dbus_message_get_destination (message) : 2190 "null", 2191 connection, 2192 connection->n_outgoing); 2193 2194 if (dbus_message_get_serial (message) == 0) 2195 { 2196 serial = _dbus_connection_get_next_client_serial (connection); 2197 _dbus_message_set_serial (message, serial); 2198 if (client_serial) 2199 *client_serial = serial; 2200 } 2201 else 2202 { 2203 if (client_serial) 2204 *client_serial = dbus_message_get_serial (message); 2205 } 2206 2207 _dbus_verbose ("Message %p serial is %u\n", 2208 message, dbus_message_get_serial (message)); 2209 2210 _dbus_message_lock (message); 2211 2212 /* Now we need to run an iteration to hopefully just write the messages 2213 * out immediately, and otherwise get them queued up 2214 */ 2215 _dbus_connection_do_iteration_unlocked (connection, 2216 DBUS_ITERATION_DO_WRITING, 2217 -1); 2218 2219 /* If stuff is still queued up, be sure we wake up the main loop */ 2220 if (connection->n_outgoing > 0) 2221 _dbus_connection_wakeup_mainloop (connection); 2222} 2223 2224static void 2225_dbus_connection_send_preallocated_and_unlock (DBusConnection *connection, 2226 DBusPreallocatedSend *preallocated, 2227 DBusMessage *message, 2228 dbus_uint32_t *client_serial) 2229{ 2230 DBusDispatchStatus status; 2231 2232 HAVE_LOCK_CHECK (connection); 2233 2234 _dbus_connection_send_preallocated_unlocked_no_update (connection, 2235 preallocated, 2236 message, client_serial); 2237 2238 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME); 2239 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2240 2241 /* this calls out to user code */ 2242 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2243} 2244 2245/** 2246 * Sends a message using preallocated resources. This function cannot fail. 2247 * It works identically to dbus_connection_send() in other respects. 2248 * Preallocated resources comes from dbus_connection_preallocate_send(). 2249 * This function "consumes" the preallocated resources, they need not 2250 * be freed separately. 2251 * 2252 * @param connection the connection 2253 * @param preallocated the preallocated resources 2254 * @param message the message to send 2255 * @param client_serial return location for client serial assigned to the message 2256 */ 2257void 2258dbus_connection_send_preallocated (DBusConnection *connection, 2259 DBusPreallocatedSend *preallocated, 2260 DBusMessage *message, 2261 dbus_uint32_t *client_serial) 2262{ 2263 _dbus_return_if_fail (connection != NULL); 2264 _dbus_return_if_fail (preallocated != NULL); 2265 _dbus_return_if_fail (message != NULL); 2266 _dbus_return_if_fail (preallocated->connection == connection); 2267 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL || 2268 dbus_message_get_member (message) != NULL); 2269 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL || 2270 (dbus_message_get_interface (message) != NULL && 2271 dbus_message_get_member (message) != NULL)); 2272 2273 CONNECTION_LOCK (connection); 2274 _dbus_connection_send_preallocated_and_unlock (connection, 2275 preallocated, 2276 message, client_serial); 2277} 2278 2279static dbus_bool_t 2280_dbus_connection_send_unlocked_no_update (DBusConnection *connection, 2281 DBusMessage *message, 2282 dbus_uint32_t *client_serial) 2283{ 2284 DBusPreallocatedSend *preallocated; 2285 2286 _dbus_assert (connection != NULL); 2287 _dbus_assert (message != NULL); 2288 2289 preallocated = _dbus_connection_preallocate_send_unlocked (connection); 2290 if (preallocated == NULL) 2291 return FALSE; 2292 2293 _dbus_connection_send_preallocated_unlocked_no_update (connection, 2294 preallocated, 2295 message, 2296 client_serial); 2297 return TRUE; 2298} 2299 2300dbus_bool_t 2301_dbus_connection_send_and_unlock (DBusConnection *connection, 2302 DBusMessage *message, 2303 dbus_uint32_t *client_serial) 2304{ 2305 DBusPreallocatedSend *preallocated; 2306 2307 _dbus_assert (connection != NULL); 2308 _dbus_assert (message != NULL); 2309 2310 preallocated = _dbus_connection_preallocate_send_unlocked (connection); 2311 if (preallocated == NULL) 2312 { 2313 CONNECTION_UNLOCK (connection); 2314 return FALSE; 2315 } 2316 2317 _dbus_connection_send_preallocated_and_unlock (connection, 2318 preallocated, 2319 message, 2320 client_serial); 2321 return TRUE; 2322} 2323 2324/** 2325 * Adds a message to the outgoing message queue. Does not block to 2326 * write the message to the network; that happens asynchronously. To 2327 * force the message to be written, call dbus_connection_flush(). 2328 * Because this only queues the message, the only reason it can 2329 * fail is lack of memory. Even if the connection is disconnected, 2330 * no error will be returned. 2331 * 2332 * If the function fails due to lack of memory, it returns #FALSE. 2333 * The function will never fail for other reasons; even if the 2334 * connection is disconnected, you can queue an outgoing message, 2335 * though obviously it won't be sent. 2336 * 2337 * @param connection the connection. 2338 * @param message the message to write. 2339 * @param client_serial return location for client serial. 2340 * @returns #TRUE on success. 2341 */ 2342dbus_bool_t 2343dbus_connection_send (DBusConnection *connection, 2344 DBusMessage *message, 2345 dbus_uint32_t *client_serial) 2346{ 2347 _dbus_return_val_if_fail (connection != NULL, FALSE); 2348 _dbus_return_val_if_fail (message != NULL, FALSE); 2349 2350 CONNECTION_LOCK (connection); 2351 2352 return _dbus_connection_send_and_unlock (connection, 2353 message, 2354 client_serial); 2355} 2356 2357static dbus_bool_t 2358reply_handler_timeout (void *data) 2359{ 2360 DBusConnection *connection; 2361 DBusDispatchStatus status; 2362 DBusPendingCall *pending = data; 2363 2364 connection = _dbus_pending_call_get_connection_and_lock (pending); 2365 2366 _dbus_pending_call_queue_timeout_error_unlocked (pending, 2367 connection); 2368 _dbus_connection_remove_timeout_unlocked (connection, 2369 _dbus_pending_call_get_timeout_unlocked (pending)); 2370 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE); 2371 2372 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME); 2373 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2374 2375 /* Unlocks, and calls out to user code */ 2376 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2377 2378 return TRUE; 2379} 2380 2381/** 2382 * Queues a message to send, as with dbus_connection_send_message(), 2383 * but also returns a #DBusPendingCall used to receive a reply to the 2384 * message. If no reply is received in the given timeout_milliseconds, 2385 * this function expires the pending reply and generates a synthetic 2386 * error reply (generated in-process, not by the remote application) 2387 * indicating that a timeout occurred. 2388 * 2389 * A #DBusPendingCall will see a reply message after any filters, but 2390 * before any object instances or other handlers. A #DBusPendingCall 2391 * will always see exactly one reply message, unless it's cancelled 2392 * with dbus_pending_call_cancel(). 2393 * 2394 * If a filter filters out the reply before the handler sees it, the 2395 * reply is immediately timed out and a timeout error reply is 2396 * generated. If a filter removes the timeout error reply then the 2397 * #DBusPendingCall will get confused. Filtering the timeout error 2398 * is thus considered a bug and will print a warning. 2399 * 2400 * If #NULL is passed for the pending_return, the #DBusPendingCall 2401 * will still be generated internally, and used to track 2402 * the message reply timeout. This means a timeout error will 2403 * occur if no reply arrives, unlike with dbus_connection_send(). 2404 * 2405 * If -1 is passed for the timeout, a sane default timeout is used. -1 2406 * is typically the best value for the timeout for this reason, unless 2407 * you want a very short or very long timeout. There is no way to 2408 * avoid a timeout entirely, other than passing INT_MAX for the 2409 * timeout to postpone it indefinitely. 2410 * 2411 * @param connection the connection 2412 * @param message the message to send 2413 * @param pending_return return location for a #DBusPendingCall object, or #NULLif connection is disconnected 2414 * @param timeout_milliseconds timeout in milliseconds or -1 for default 2415 * @returns #FALSE if no memory, #TRUE otherwise. 2416 * 2417 */ 2418dbus_bool_t 2419dbus_connection_send_with_reply (DBusConnection *connection, 2420 DBusMessage *message, 2421 DBusPendingCall **pending_return, 2422 int timeout_milliseconds) 2423{ 2424 DBusPendingCall *pending; 2425 dbus_int32_t serial = -1; 2426 DBusDispatchStatus status; 2427 2428 _dbus_return_val_if_fail (connection != NULL, FALSE); 2429 _dbus_return_val_if_fail (message != NULL, FALSE); 2430 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE); 2431 2432 if (pending_return) 2433 *pending_return = NULL; 2434 2435 CONNECTION_LOCK (connection); 2436 2437 if (!_dbus_connection_get_is_connected_unlocked (connection)) 2438 { 2439 CONNECTION_UNLOCK (connection); 2440 2441 *pending_return = NULL; 2442 2443 return TRUE; 2444 } 2445 2446 pending = _dbus_pending_call_new_unlocked (connection, 2447 timeout_milliseconds, 2448 reply_handler_timeout); 2449 2450 if (pending == NULL) 2451 { 2452 CONNECTION_UNLOCK (connection); 2453 return FALSE; 2454 } 2455 2456 /* Assign a serial to the message */ 2457 serial = dbus_message_get_serial (message); 2458 if (serial == 0) 2459 { 2460 serial = _dbus_connection_get_next_client_serial (connection); 2461 _dbus_message_set_serial (message, serial); 2462 } 2463 2464 if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial)) 2465 goto error; 2466 2467 /* Insert the serial in the pending replies hash; 2468 * hash takes a refcount on DBusPendingCall. 2469 * Also, add the timeout. 2470 */ 2471 if (!_dbus_connection_attach_pending_call_unlocked (connection, 2472 pending)) 2473 goto error; 2474 2475 if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL)) 2476 { 2477 _dbus_connection_detach_pending_call_and_unlock (connection, 2478 pending); 2479 goto error_unlocked; 2480 } 2481 2482 if (pending_return) 2483 *pending_return = pending; /* hand off refcount */ 2484 else 2485 { 2486 _dbus_connection_detach_pending_call_unlocked (connection, pending); 2487 /* we still have a ref to the pending call in this case, we unref 2488 * after unlocking, below 2489 */ 2490 } 2491 2492 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2493 2494 /* this calls out to user code */ 2495 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2496 2497 if (pending_return == NULL) 2498 dbus_pending_call_unref (pending); 2499 2500 return TRUE; 2501 2502 error: 2503 CONNECTION_UNLOCK (connection); 2504 error_unlocked: 2505 dbus_pending_call_unref (pending); 2506 return FALSE; 2507} 2508 2509/* This is slightly strange since we can pop a message here without 2510 * the dispatch lock. 2511 */ 2512static DBusMessage* 2513check_for_reply_unlocked (DBusConnection *connection, 2514 dbus_uint32_t client_serial) 2515{ 2516 DBusList *link; 2517 2518 HAVE_LOCK_CHECK (connection); 2519 2520 link = _dbus_list_get_first_link (&connection->incoming_messages); 2521 2522 while (link != NULL) 2523 { 2524 DBusMessage *reply = link->data; 2525 2526 if (dbus_message_get_reply_serial (reply) == client_serial) 2527 { 2528 _dbus_list_remove_link (&connection->incoming_messages, link); 2529 connection->n_incoming -= 1; 2530 return reply; 2531 } 2532 link = _dbus_list_get_next_link (&connection->incoming_messages, link); 2533 } 2534 2535 return NULL; 2536} 2537 2538static void 2539connection_timeout_and_complete_all_pending_calls_unlocked (DBusConnection *connection) 2540{ 2541 /* We can't iterate over the hash in the normal way since we'll be 2542 * dropping the lock for each item. So we restart the 2543 * iter each time as we drain the hash table. 2544 */ 2545 2546 while (_dbus_hash_table_get_n_entries (connection->pending_replies) > 0) 2547 { 2548 DBusPendingCall *pending; 2549 DBusHashIter iter; 2550 2551 _dbus_hash_iter_init (connection->pending_replies, &iter); 2552 _dbus_hash_iter_next (&iter); 2553 2554 pending = (DBusPendingCall *) _dbus_hash_iter_get_value (&iter); 2555 _dbus_pending_call_ref_unlocked (pending); 2556 2557 _dbus_pending_call_queue_timeout_error_unlocked (pending, 2558 connection); 2559 _dbus_connection_remove_timeout_unlocked (connection, 2560 _dbus_pending_call_get_timeout_unlocked (pending)); 2561 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE); 2562 _dbus_hash_iter_remove_entry (&iter); 2563 2564 _dbus_pending_call_unref_and_unlock (pending); 2565 CONNECTION_LOCK (connection); 2566 } 2567 HAVE_LOCK_CHECK (connection); 2568} 2569 2570static void 2571complete_pending_call_and_unlock (DBusConnection *connection, 2572 DBusPendingCall *pending, 2573 DBusMessage *message) 2574{ 2575 _dbus_pending_call_set_reply_unlocked (pending, message); 2576 _dbus_pending_call_ref_unlocked (pending); /* in case there's no app with a ref held */ 2577 _dbus_connection_detach_pending_call_and_unlock (connection, pending); 2578 2579 /* Must be called unlocked since it invokes app callback */ 2580 _dbus_pending_call_complete (pending); 2581 dbus_pending_call_unref (pending); 2582} 2583 2584static dbus_bool_t 2585check_for_reply_and_update_dispatch_unlocked (DBusConnection *connection, 2586 DBusPendingCall *pending) 2587{ 2588 DBusMessage *reply; 2589 DBusDispatchStatus status; 2590 2591 reply = check_for_reply_unlocked (connection, 2592 _dbus_pending_call_get_reply_serial_unlocked (pending)); 2593 if (reply != NULL) 2594 { 2595 _dbus_verbose ("%s checked for reply\n", _DBUS_FUNCTION_NAME); 2596 2597 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n"); 2598 2599 complete_pending_call_and_unlock (connection, pending, reply); 2600 dbus_message_unref (reply); 2601 2602 CONNECTION_LOCK (connection); 2603 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2604 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2605 dbus_pending_call_unref (pending); 2606 2607 return TRUE; 2608 } 2609 2610 return FALSE; 2611} 2612 2613/** 2614 * When a function that blocks has been called with a timeout, and we 2615 * run out of memory, the time to wait for memory is based on the 2616 * timeout. If the caller was willing to block a long time we wait a 2617 * relatively long time for memory, if they were only willing to block 2618 * briefly then we retry for memory at a rapid rate. 2619 * 2620 * @timeout_milliseconds the timeout requested for blocking 2621 */ 2622static void 2623_dbus_memory_pause_based_on_timeout (int timeout_milliseconds) 2624{ 2625 if (timeout_milliseconds == -1) 2626 _dbus_sleep_milliseconds (1000); 2627 else if (timeout_milliseconds < 100) 2628 ; /* just busy loop */ 2629 else if (timeout_milliseconds <= 1000) 2630 _dbus_sleep_milliseconds (timeout_milliseconds / 3); 2631 else 2632 _dbus_sleep_milliseconds (1000); 2633} 2634 2635/** 2636 * Blocks until a pending call times out or gets a reply. 2637 * 2638 * Does not re-enter the main loop or run filter/path-registered 2639 * callbacks. The reply to the message will not be seen by 2640 * filter callbacks. 2641 * 2642 * Returns immediately if pending call already got a reply. 2643 * 2644 * @todo could use performance improvements (it keeps scanning 2645 * the whole message queue for example) 2646 * 2647 * @param pending the pending call we block for a reply on 2648 */ 2649void 2650_dbus_connection_block_pending_call (DBusPendingCall *pending) 2651{ 2652 long start_tv_sec, start_tv_usec; 2653 long end_tv_sec, end_tv_usec; 2654 long tv_sec, tv_usec; 2655 DBusDispatchStatus status; 2656 DBusConnection *connection; 2657 dbus_uint32_t client_serial; 2658 int timeout_milliseconds; 2659 2660 _dbus_assert (pending != NULL); 2661 2662 if (dbus_pending_call_get_completed (pending)) 2663 return; 2664 2665 dbus_pending_call_ref (pending); /* necessary because the call could be canceled */ 2666 2667 connection = _dbus_pending_call_get_connection_and_lock (pending); 2668 2669 /* Flush message queue - note, can affect dispatch status */ 2670 _dbus_connection_flush_unlocked (connection); 2671 2672 client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending); 2673 2674 /* note that timeout_milliseconds is limited to a smallish value 2675 * in _dbus_pending_call_new() so overflows aren't possible 2676 * below 2677 */ 2678 timeout_milliseconds = dbus_timeout_get_interval (_dbus_pending_call_get_timeout_unlocked (pending)); 2679 2680 _dbus_get_current_time (&start_tv_sec, &start_tv_usec); 2681 end_tv_sec = start_tv_sec + timeout_milliseconds / 1000; 2682 end_tv_usec = start_tv_usec + (timeout_milliseconds % 1000) * 1000; 2683 end_tv_sec += end_tv_usec / _DBUS_USEC_PER_SECOND; 2684 end_tv_usec = end_tv_usec % _DBUS_USEC_PER_SECOND; 2685 2686 _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", 2687 timeout_milliseconds, 2688 client_serial, 2689 start_tv_sec, start_tv_usec, 2690 end_tv_sec, end_tv_usec); 2691 2692 /* check to see if we already got the data off the socket */ 2693 /* from another blocked pending call */ 2694 if (check_for_reply_and_update_dispatch_unlocked (connection, pending)) 2695 return; 2696 2697 /* Now we wait... */ 2698 /* always block at least once as we know we don't have the reply yet */ 2699 _dbus_connection_do_iteration_unlocked (connection, 2700 DBUS_ITERATION_DO_READING | 2701 DBUS_ITERATION_BLOCK, 2702 timeout_milliseconds); 2703 2704 recheck_status: 2705 2706 _dbus_verbose ("%s top of recheck\n", _DBUS_FUNCTION_NAME); 2707 2708 HAVE_LOCK_CHECK (connection); 2709 2710 /* queue messages and get status */ 2711 2712 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2713 2714 /* the get_completed() is in case a dispatch() while we were blocking 2715 * got the reply instead of us. 2716 */ 2717 if (_dbus_pending_call_get_completed_unlocked (pending)) 2718 { 2719 _dbus_verbose ("Pending call completed by dispatch in %s\n", _DBUS_FUNCTION_NAME); 2720 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2721 dbus_pending_call_unref (pending); 2722 return; 2723 } 2724 2725 if (status == DBUS_DISPATCH_DATA_REMAINS) { 2726 if (check_for_reply_and_update_dispatch_unlocked (connection, pending)) 2727 return; 2728 } 2729 2730 _dbus_get_current_time (&tv_sec, &tv_usec); 2731 2732 if (!_dbus_connection_get_is_connected_unlocked (connection)) 2733 { 2734 /* FIXME 1.0 send a "DBUS_ERROR_DISCONNECTED" instead, just to help 2735 * programmers understand what went wrong since the timeout is 2736 * confusing 2737 */ 2738 2739 complete_pending_call_and_unlock (connection, pending, NULL); 2740 dbus_pending_call_unref (pending); 2741 return; 2742 } 2743 else if (tv_sec < start_tv_sec) 2744 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n"); 2745 else if (connection->disconnect_message_link == NULL) 2746 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n"); 2747 else if (tv_sec < end_tv_sec || 2748 (tv_sec == end_tv_sec && tv_usec < end_tv_usec)) 2749 { 2750 timeout_milliseconds = (end_tv_sec - tv_sec) * 1000 + 2751 (end_tv_usec - tv_usec) / 1000; 2752 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds); 2753 _dbus_assert (timeout_milliseconds >= 0); 2754 2755 if (status == DBUS_DISPATCH_NEED_MEMORY) 2756 { 2757 /* Try sleeping a bit, as we aren't sure we need to block for reading, 2758 * we may already have a reply in the buffer and just can't process 2759 * it. 2760 */ 2761 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n"); 2762 2763 _dbus_memory_pause_based_on_timeout (timeout_milliseconds); 2764 } 2765 else 2766 { 2767 /* block again, we don't have the reply buffered yet. */ 2768 _dbus_connection_do_iteration_unlocked (connection, 2769 DBUS_ITERATION_DO_READING | 2770 DBUS_ITERATION_BLOCK, 2771 timeout_milliseconds); 2772 } 2773 2774 goto recheck_status; 2775 } 2776 2777 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %ld milliseconds and got no reply\n", 2778 (tv_sec - start_tv_sec) * 1000 + (tv_usec - start_tv_usec) / 1000); 2779 2780 _dbus_assert (!_dbus_pending_call_get_completed_unlocked (pending)); 2781 2782 /* unlock and call user code */ 2783 complete_pending_call_and_unlock (connection, pending, NULL); 2784 2785 /* update user code on dispatch status */ 2786 CONNECTION_LOCK (connection); 2787 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2788 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2789 dbus_pending_call_unref (pending); 2790} 2791 2792/** 2793 * Sends a message and blocks a certain time period while waiting for 2794 * a reply. This function does not reenter the main loop, 2795 * i.e. messages other than the reply are queued up but not 2796 * processed. This function is used to do non-reentrant "method 2797 * calls." 2798 * 2799 * If a normal reply is received, it is returned, and removed from the 2800 * incoming message queue. If it is not received, #NULL is returned 2801 * and the error is set to #DBUS_ERROR_NO_REPLY. If an error reply is 2802 * received, it is converted to a #DBusError and returned as an error, 2803 * then the reply message is deleted. If something else goes wrong, 2804 * result is set to whatever is appropriate, such as 2805 * #DBUS_ERROR_NO_MEMORY or #DBUS_ERROR_DISCONNECTED. 2806 * 2807 * @param connection the connection 2808 * @param message the message to send 2809 * @param timeout_milliseconds timeout in milliseconds or -1 for default 2810 * @param error return location for error message 2811 * @returns the message that is the reply or #NULL with an error code if the 2812 * function fails. 2813 */ 2814DBusMessage* 2815dbus_connection_send_with_reply_and_block (DBusConnection *connection, 2816 DBusMessage *message, 2817 int timeout_milliseconds, 2818 DBusError *error) 2819{ 2820 DBusMessage *reply; 2821 DBusPendingCall *pending; 2822 2823 _dbus_return_val_if_fail (connection != NULL, NULL); 2824 _dbus_return_val_if_fail (message != NULL, NULL); 2825 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL); 2826 _dbus_return_val_if_error_is_set (error, NULL); 2827 2828 if (!dbus_connection_send_with_reply (connection, message, 2829 &pending, timeout_milliseconds)) 2830 { 2831 _DBUS_SET_OOM (error); 2832 return NULL; 2833 } 2834 2835 _dbus_assert (pending != NULL); 2836 2837 dbus_pending_call_block (pending); 2838 2839 reply = dbus_pending_call_steal_reply (pending); 2840 dbus_pending_call_unref (pending); 2841 2842 /* call_complete_and_unlock() called from pending_call_block() should 2843 * always fill this in. 2844 */ 2845 _dbus_assert (reply != NULL); 2846 2847 if (dbus_set_error_from_message (error, reply)) 2848 { 2849 dbus_message_unref (reply); 2850 return NULL; 2851 } 2852 else 2853 return reply; 2854} 2855 2856/** 2857 * Blocks until the outgoing message queue is empty. 2858 * Assumes connection lock already held. 2859 * 2860 * If you call this, you MUST call update_dispatch_status afterword... 2861 * 2862 * @param connection the connection. 2863 */ 2864DBusDispatchStatus 2865_dbus_connection_flush_unlocked (DBusConnection *connection) 2866{ 2867 /* We have to specify DBUS_ITERATION_DO_READING here because 2868 * otherwise we could have two apps deadlock if they are both doing 2869 * a flush(), and the kernel buffers fill up. This could change the 2870 * dispatch status. 2871 */ 2872 DBusDispatchStatus status; 2873 2874 HAVE_LOCK_CHECK (connection); 2875 2876 while (connection->n_outgoing > 0 && 2877 _dbus_connection_get_is_connected_unlocked (connection)) 2878 { 2879 _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME); 2880 HAVE_LOCK_CHECK (connection); 2881 _dbus_connection_do_iteration_unlocked (connection, 2882 DBUS_ITERATION_DO_READING | 2883 DBUS_ITERATION_DO_WRITING | 2884 DBUS_ITERATION_BLOCK, 2885 -1); 2886 } 2887 2888 HAVE_LOCK_CHECK (connection); 2889 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME); 2890 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2891 2892 HAVE_LOCK_CHECK (connection); 2893 return status; 2894} 2895 2896/** 2897 * Blocks until the outgoing message queue is empty. 2898 * 2899 * @param connection the connection. 2900 */ 2901void 2902dbus_connection_flush (DBusConnection *connection) 2903{ 2904 /* We have to specify DBUS_ITERATION_DO_READING here because 2905 * otherwise we could have two apps deadlock if they are both doing 2906 * a flush(), and the kernel buffers fill up. This could change the 2907 * dispatch status. 2908 */ 2909 DBusDispatchStatus status; 2910 2911 _dbus_return_if_fail (connection != NULL); 2912 2913 CONNECTION_LOCK (connection); 2914 2915 status = _dbus_connection_flush_unlocked (connection); 2916 2917 HAVE_LOCK_CHECK (connection); 2918 /* Unlocks and calls out to user code */ 2919 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2920 2921 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME); 2922} 2923 2924/** 2925 * This function is intended for use with applications that don't want 2926 * to write a main loop and deal with #DBusWatch and #DBusTimeout. An 2927 * example usage would be: 2928 * 2929 * @code 2930 * while (dbus_connection_read_write_dispatch (connection, -1)) 2931 * ; // empty loop body 2932 * @endcode 2933 * 2934 * In this usage you would normally have set up a filter function to look 2935 * at each message as it is dispatched. The loop terminates when the last 2936 * message from the connection (the disconnected signal) is processed. 2937 * 2938 * If there are messages to dispatch and the dispatch flag is set, this 2939 * function will dbus_connection_dispatch() once, and return. If there are no 2940 * messages to dispatch, this function will block until it can read or write, 2941 * then read or write, then return. 2942 * 2943 * The way to think of this function is that it either makes some sort 2944 * of progress, or it blocks. 2945 * 2946 * The return value indicates whether the disconnect message has been 2947 * processed, NOT whether the connection is connected. This is 2948 * important because even after disconnecting, you want to process any 2949 * messages you received prior to the disconnect. 2950 * 2951 * @param connection the connection 2952 * @param timeout_milliseconds max time to block or -1 for infinite 2953 * @param dispatch dispatch new messages or leave them on the incoming queue 2954 * @returns #TRUE if the disconnect message has not been processed 2955 */ 2956static dbus_bool_t 2957_dbus_connection_read_write_dispatch (DBusConnection *connection, 2958 int timeout_milliseconds, 2959 dbus_bool_t dispatch) 2960{ 2961 DBusDispatchStatus dstatus; 2962 dbus_bool_t dispatched_disconnected; 2963 2964 dstatus = dbus_connection_get_dispatch_status (connection); 2965 2966 if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS) 2967 { 2968 _dbus_verbose ("doing dispatch in %s\n", _DBUS_FUNCTION_NAME); 2969 dbus_connection_dispatch (connection); 2970 CONNECTION_LOCK (connection); 2971 } 2972 else if (dstatus == DBUS_DISPATCH_NEED_MEMORY) 2973 { 2974 _dbus_verbose ("pausing for memory in %s\n", _DBUS_FUNCTION_NAME); 2975 _dbus_memory_pause_based_on_timeout (timeout_milliseconds); 2976 CONNECTION_LOCK (connection); 2977 } 2978 else 2979 { 2980 CONNECTION_LOCK (connection); 2981 if (_dbus_connection_get_is_connected_unlocked (connection)) 2982 { 2983 _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME); 2984 _dbus_connection_do_iteration_unlocked (connection, 2985 DBUS_ITERATION_DO_READING | 2986 DBUS_ITERATION_DO_WRITING | 2987 DBUS_ITERATION_BLOCK, 2988 timeout_milliseconds); 2989 } 2990 } 2991 2992 HAVE_LOCK_CHECK (connection); 2993 dispatched_disconnected = connection->n_incoming == 0 && 2994 connection->disconnect_message_link == NULL; 2995 CONNECTION_UNLOCK (connection); 2996 return !dispatched_disconnected; /* TRUE if we have not processed disconnected */ 2997} 2998 2999 3000/** 3001 * This function is intended for use with applications that don't want 3002 * to write a main loop and deal with #DBusWatch and #DBusTimeout. An 3003 * example usage would be: 3004 * 3005 * @code 3006 * while (dbus_connection_read_write_dispatch (connection, -1)) 3007 * ; // empty loop body 3008 * @endcode 3009 * 3010 * In this usage you would normally have set up a filter function to look 3011 * at each message as it is dispatched. The loop terminates when the last 3012 * message from the connection (the disconnected signal) is processed. 3013 * 3014 * If there are messages to dispatch, this function will 3015 * dbus_connection_dispatch() once, and return. If there are no 3016 * messages to dispatch, this function will block until it can read or 3017 * write, then read or write, then return. 3018 * 3019 * The way to think of this function is that it either makes some sort 3020 * of progress, or it blocks. 3021 * 3022 * The return value indicates whether the disconnect message has been 3023 * processed, NOT whether the connection is connected. This is 3024 * important because even after disconnecting, you want to process any 3025 * messages you received prior to the disconnect. 3026 * 3027 * @param connection the connection 3028 * @param timeout_milliseconds max time to block or -1 for infinite 3029 * @returns #TRUE if the disconnect message has not been processed 3030 */ 3031dbus_bool_t 3032dbus_connection_read_write_dispatch (DBusConnection *connection, 3033 int timeout_milliseconds) 3034{ 3035 _dbus_return_val_if_fail (connection != NULL, FALSE); 3036 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE); 3037 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE); 3038} 3039 3040/** 3041 * This function is intended for use with applications that don't want to 3042 * write a main loop and deal with #DBusWatch and #DBusTimeout. 3043 * 3044 * If there are no messages to dispatch, this function will block until it can 3045 * read or write, then read or write, then return. 3046 * 3047 * The return value indicates whether the disconnect message has been 3048 * processed, NOT whether the connection is connected. This is important 3049 * because even after disconnecting, you want to process any messages you 3050 * received prior to the disconnect. 3051 * 3052 * @param connection the connection 3053 * @param timeout_milliseconds max time to block or -1 for infinite 3054 * @returns #TRUE if the disconnect message has not been processed 3055 */ 3056dbus_bool_t 3057dbus_connection_read_write (DBusConnection *connection, 3058 int timeout_milliseconds) 3059{ 3060 _dbus_return_val_if_fail (connection != NULL, FALSE); 3061 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE); 3062 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE); 3063} 3064 3065/** 3066 * Returns the first-received message from the incoming message queue, 3067 * leaving it in the queue. If the queue is empty, returns #NULL. 3068 * 3069 * The caller does not own a reference to the returned message, and 3070 * must either return it using dbus_connection_return_message() or 3071 * keep it after calling dbus_connection_steal_borrowed_message(). No 3072 * one can get at the message while its borrowed, so return it as 3073 * quickly as possible and don't keep a reference to it after 3074 * returning it. If you need to keep the message, make a copy of it. 3075 * 3076 * dbus_connection_dispatch() will block if called while a borrowed 3077 * message is outstanding; only one piece of code can be playing with 3078 * the incoming queue at a time. This function will block if called 3079 * during a dbus_connection_dispatch(). 3080 * 3081 * @param connection the connection. 3082 * @returns next message in the incoming queue. 3083 */ 3084DBusMessage* 3085dbus_connection_borrow_message (DBusConnection *connection) 3086{ 3087 DBusDispatchStatus status; 3088 DBusMessage *message; 3089 3090 _dbus_return_val_if_fail (connection != NULL, NULL); 3091 3092 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME); 3093 3094 /* this is called for the side effect that it queues 3095 * up any messages from the transport 3096 */ 3097 status = dbus_connection_get_dispatch_status (connection); 3098 if (status != DBUS_DISPATCH_DATA_REMAINS) 3099 return NULL; 3100 3101 CONNECTION_LOCK (connection); 3102 3103 _dbus_connection_acquire_dispatch (connection); 3104 3105 /* While a message is outstanding, the dispatch lock is held */ 3106 _dbus_assert (connection->message_borrowed == NULL); 3107 3108 connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages); 3109 3110 message = connection->message_borrowed; 3111 3112 /* Note that we KEEP the dispatch lock until the message is returned */ 3113 if (message == NULL) 3114 _dbus_connection_release_dispatch (connection); 3115 3116 CONNECTION_UNLOCK (connection); 3117 3118 return message; 3119} 3120 3121/** 3122 * Used to return a message after peeking at it using 3123 * dbus_connection_borrow_message(). Only called if 3124 * message from dbus_connection_borrow_message() was non-#NULL. 3125 * 3126 * @param connection the connection 3127 * @param message the message from dbus_connection_borrow_message() 3128 */ 3129void 3130dbus_connection_return_message (DBusConnection *connection, 3131 DBusMessage *message) 3132{ 3133 _dbus_return_if_fail (connection != NULL); 3134 _dbus_return_if_fail (message != NULL); 3135 _dbus_return_if_fail (message == connection->message_borrowed); 3136 _dbus_return_if_fail (connection->dispatch_acquired); 3137 3138 CONNECTION_LOCK (connection); 3139 3140 _dbus_assert (message == connection->message_borrowed); 3141 3142 connection->message_borrowed = NULL; 3143 3144 _dbus_connection_release_dispatch (connection); 3145 3146 CONNECTION_UNLOCK (connection); 3147} 3148 3149/** 3150 * Used to keep a message after peeking at it using 3151 * dbus_connection_borrow_message(). Before using this function, see 3152 * the caveats/warnings in the documentation for 3153 * dbus_connection_pop_message(). 3154 * 3155 * @param connection the connection 3156 * @param message the message from dbus_connection_borrow_message() 3157 */ 3158void 3159dbus_connection_steal_borrowed_message (DBusConnection *connection, 3160 DBusMessage *message) 3161{ 3162 DBusMessage *pop_message; 3163 3164 _dbus_return_if_fail (connection != NULL); 3165 _dbus_return_if_fail (message != NULL); 3166 _dbus_return_if_fail (message == connection->message_borrowed); 3167 _dbus_return_if_fail (connection->dispatch_acquired); 3168 3169 CONNECTION_LOCK (connection); 3170 3171 _dbus_assert (message == connection->message_borrowed); 3172 3173 pop_message = _dbus_list_pop_first (&connection->incoming_messages); 3174 _dbus_assert (message == pop_message); 3175 3176 connection->n_incoming -= 1; 3177 3178 _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n", 3179 message, connection->n_incoming); 3180 3181 connection->message_borrowed = NULL; 3182 3183 _dbus_connection_release_dispatch (connection); 3184 3185 CONNECTION_UNLOCK (connection); 3186} 3187 3188/* See dbus_connection_pop_message, but requires the caller to own 3189 * the lock before calling. May drop the lock while running. 3190 */ 3191static DBusList* 3192_dbus_connection_pop_message_link_unlocked (DBusConnection *connection) 3193{ 3194 HAVE_LOCK_CHECK (connection); 3195 3196 _dbus_assert (connection->message_borrowed == NULL); 3197 3198 if (connection->n_incoming > 0) 3199 { 3200 DBusList *link; 3201 3202 link = _dbus_list_pop_first_link (&connection->incoming_messages); 3203 connection->n_incoming -= 1; 3204 3205 _dbus_verbose ("Message %p (%d %s %s %s '%s') removed from incoming queue %p, %d incoming\n", 3206 link->data, 3207 dbus_message_get_type (link->data), 3208 dbus_message_get_path (link->data) ? 3209 dbus_message_get_path (link->data) : 3210 "no path", 3211 dbus_message_get_interface (link->data) ? 3212 dbus_message_get_interface (link->data) : 3213 "no interface", 3214 dbus_message_get_member (link->data) ? 3215 dbus_message_get_member (link->data) : 3216 "no member", 3217 dbus_message_get_signature (link->data), 3218 connection, connection->n_incoming); 3219 3220 return link; 3221 } 3222 else 3223 return NULL; 3224} 3225 3226/* See dbus_connection_pop_message, but requires the caller to own 3227 * the lock before calling. May drop the lock while running. 3228 */ 3229static DBusMessage* 3230_dbus_connection_pop_message_unlocked (DBusConnection *connection) 3231{ 3232 DBusList *link; 3233 3234 HAVE_LOCK_CHECK (connection); 3235 3236 link = _dbus_connection_pop_message_link_unlocked (connection); 3237 3238 if (link != NULL) 3239 { 3240 DBusMessage *message; 3241 3242 message = link->data; 3243 3244 _dbus_list_free_link (link); 3245 3246 return message; 3247 } 3248 else 3249 return NULL; 3250} 3251 3252static void 3253_dbus_connection_putback_message_link_unlocked (DBusConnection *connection, 3254 DBusList *message_link) 3255{ 3256 HAVE_LOCK_CHECK (connection); 3257 3258 _dbus_assert (message_link != NULL); 3259 /* You can't borrow a message while a link is outstanding */ 3260 _dbus_assert (connection->message_borrowed == NULL); 3261 /* We had to have the dispatch lock across the pop/putback */ 3262 _dbus_assert (connection->dispatch_acquired); 3263 3264 _dbus_list_prepend_link (&connection->incoming_messages, 3265 message_link); 3266 connection->n_incoming += 1; 3267 3268 _dbus_verbose ("Message %p (%d %s %s '%s') put back into queue %p, %d incoming\n", 3269 message_link->data, 3270 dbus_message_get_type (message_link->data), 3271 dbus_message_get_interface (message_link->data) ? 3272 dbus_message_get_interface (message_link->data) : 3273 "no interface", 3274 dbus_message_get_member (message_link->data) ? 3275 dbus_message_get_member (message_link->data) : 3276 "no member", 3277 dbus_message_get_signature (message_link->data), 3278 connection, connection->n_incoming); 3279} 3280 3281/** 3282 * Returns the first-received message from the incoming message queue, 3283 * removing it from the queue. The caller owns a reference to the 3284 * returned message. If the queue is empty, returns #NULL. 3285 * 3286 * This function bypasses any message handlers that are registered, 3287 * and so using it is usually wrong. Instead, let the main loop invoke 3288 * dbus_connection_dispatch(). Popping messages manually is only 3289 * useful in very simple programs that don't share a #DBusConnection 3290 * with any libraries or other modules. 3291 * 3292 * There is a lock that covers all ways of accessing the incoming message 3293 * queue, so dbus_connection_dispatch(), dbus_connection_pop_message(), 3294 * dbus_connection_borrow_message(), etc. will all block while one of the others 3295 * in the group is running. 3296 * 3297 * @param connection the connection. 3298 * @returns next message in the incoming queue. 3299 */ 3300DBusMessage* 3301dbus_connection_pop_message (DBusConnection *connection) 3302{ 3303 DBusMessage *message; 3304 DBusDispatchStatus status; 3305 3306 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME); 3307 3308 /* this is called for the side effect that it queues 3309 * up any messages from the transport 3310 */ 3311 status = dbus_connection_get_dispatch_status (connection); 3312 if (status != DBUS_DISPATCH_DATA_REMAINS) 3313 return NULL; 3314 3315 CONNECTION_LOCK (connection); 3316 _dbus_connection_acquire_dispatch (connection); 3317 HAVE_LOCK_CHECK (connection); 3318 3319 message = _dbus_connection_pop_message_unlocked (connection); 3320 3321 _dbus_verbose ("Returning popped message %p\n", message); 3322 3323 _dbus_connection_release_dispatch (connection); 3324 CONNECTION_UNLOCK (connection); 3325 3326 return message; 3327} 3328 3329/** 3330 * Acquire the dispatcher. This is a separate lock so the main 3331 * connection lock can be dropped to call out to application dispatch 3332 * handlers. 3333 * 3334 * @param connection the connection. 3335 */ 3336static void 3337_dbus_connection_acquire_dispatch (DBusConnection *connection) 3338{ 3339 HAVE_LOCK_CHECK (connection); 3340 3341 _dbus_connection_ref_unlocked (connection); 3342 CONNECTION_UNLOCK (connection); 3343 3344 _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME); 3345 _dbus_mutex_lock (connection->dispatch_mutex); 3346 3347 while (connection->dispatch_acquired) 3348 { 3349 _dbus_verbose ("%s waiting for dispatch to be acquirable\n", _DBUS_FUNCTION_NAME); 3350 _dbus_condvar_wait (connection->dispatch_cond, 3351 connection->dispatch_mutex); 3352 } 3353 3354 _dbus_assert (!connection->dispatch_acquired); 3355 3356 connection->dispatch_acquired = TRUE; 3357 3358 _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME); 3359 _dbus_mutex_unlock (connection->dispatch_mutex); 3360 3361 CONNECTION_LOCK (connection); 3362 _dbus_connection_unref_unlocked (connection); 3363} 3364 3365/** 3366 * Release the dispatcher when you're done with it. Only call 3367 * after you've acquired the dispatcher. Wakes up at most one 3368 * thread currently waiting to acquire the dispatcher. 3369 * 3370 * @param connection the connection. 3371 */ 3372static void 3373_dbus_connection_release_dispatch (DBusConnection *connection) 3374{ 3375 HAVE_LOCK_CHECK (connection); 3376 3377 _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME); 3378 _dbus_mutex_lock (connection->dispatch_mutex); 3379 3380 _dbus_assert (connection->dispatch_acquired); 3381 3382 connection->dispatch_acquired = FALSE; 3383 _dbus_condvar_wake_one (connection->dispatch_cond); 3384 3385 _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME); 3386 _dbus_mutex_unlock (connection->dispatch_mutex); 3387} 3388 3389static void 3390_dbus_connection_failed_pop (DBusConnection *connection, 3391 DBusList *message_link) 3392{ 3393 _dbus_list_prepend_link (&connection->incoming_messages, 3394 message_link); 3395 connection->n_incoming += 1; 3396} 3397 3398static DBusDispatchStatus 3399_dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection) 3400{ 3401 HAVE_LOCK_CHECK (connection); 3402 3403 if (connection->n_incoming > 0) 3404 return DBUS_DISPATCH_DATA_REMAINS; 3405 else if (!_dbus_transport_queue_messages (connection->transport)) 3406 return DBUS_DISPATCH_NEED_MEMORY; 3407 else 3408 { 3409 DBusDispatchStatus status; 3410 dbus_bool_t is_connected; 3411 3412 status = _dbus_transport_get_dispatch_status (connection->transport); 3413 is_connected = _dbus_transport_get_is_connected (connection->transport); 3414 3415 _dbus_verbose ("dispatch status = %s is_connected = %d\n", 3416 DISPATCH_STATUS_NAME (status), is_connected); 3417 3418 if (!is_connected) 3419 { 3420 if (status == DBUS_DISPATCH_COMPLETE && 3421 connection->disconnect_message_link) 3422 { 3423 _dbus_verbose ("Sending disconnect message from %s\n", 3424 _DBUS_FUNCTION_NAME); 3425 3426 connection_forget_shared_unlocked (connection); 3427 3428 /* If we have pending calls queued timeouts on disconnect */ 3429 connection_timeout_and_complete_all_pending_calls_unlocked (connection); 3430 3431 /* We haven't sent the disconnect message already, 3432 * and all real messages have been queued up. 3433 */ 3434 _dbus_connection_queue_synthesized_message_link (connection, 3435 connection->disconnect_message_link); 3436 connection->disconnect_message_link = NULL; 3437 3438 status = DBUS_DISPATCH_DATA_REMAINS; 3439 } 3440 3441 /* Dump the outgoing queue, we aren't going to be able to 3442 * send it now, and we'd like accessors like 3443 * dbus_connection_get_outgoing_size() to be accurate. 3444 */ 3445 if (connection->n_outgoing > 0) 3446 { 3447 DBusList *link; 3448 3449 _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n", 3450 connection->n_outgoing); 3451 3452 while ((link = _dbus_list_get_last_link (&connection->outgoing_messages))) 3453 { 3454 _dbus_connection_message_sent (connection, link->data); 3455 } 3456 } 3457 } 3458 3459 if (status != DBUS_DISPATCH_COMPLETE) 3460 return status; 3461 else if (connection->n_incoming > 0) 3462 return DBUS_DISPATCH_DATA_REMAINS; 3463 else 3464 return DBUS_DISPATCH_COMPLETE; 3465 } 3466} 3467 3468static void 3469_dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection, 3470 DBusDispatchStatus new_status) 3471{ 3472 dbus_bool_t changed; 3473 DBusDispatchStatusFunction function; 3474 void *data; 3475 3476 HAVE_LOCK_CHECK (connection); 3477 3478 _dbus_connection_ref_unlocked (connection); 3479 3480 changed = new_status != connection->last_dispatch_status; 3481 3482 connection->last_dispatch_status = new_status; 3483 3484 function = connection->dispatch_status_function; 3485 data = connection->dispatch_status_data; 3486 3487 /* We drop the lock */ 3488 CONNECTION_UNLOCK (connection); 3489 3490 if (changed && function) 3491 { 3492 _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n", 3493 connection, new_status, 3494 DISPATCH_STATUS_NAME (new_status)); 3495 (* function) (connection, new_status, data); 3496 } 3497 3498 dbus_connection_unref (connection); 3499} 3500 3501/** 3502 * Gets the current state (what we would currently return 3503 * from dbus_connection_dispatch()) but doesn't actually 3504 * dispatch any messages. 3505 * 3506 * @param connection the connection. 3507 * @returns current dispatch status 3508 */ 3509DBusDispatchStatus 3510dbus_connection_get_dispatch_status (DBusConnection *connection) 3511{ 3512 DBusDispatchStatus status; 3513 3514 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE); 3515 3516 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME); 3517 3518 CONNECTION_LOCK (connection); 3519 3520 status = _dbus_connection_get_dispatch_status_unlocked (connection); 3521 3522 CONNECTION_UNLOCK (connection); 3523 3524 return status; 3525} 3526 3527/** 3528* Filter funtion for handling the Peer standard interface 3529**/ 3530static DBusHandlerResult 3531_dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection, 3532 DBusMessage *message) 3533{ 3534 if (dbus_message_is_method_call (message, 3535 DBUS_INTERFACE_PEER, 3536 "Ping")) 3537 { 3538 DBusMessage *ret; 3539 dbus_bool_t sent; 3540 3541 ret = dbus_message_new_method_return (message); 3542 if (ret == NULL) 3543 return DBUS_HANDLER_RESULT_NEED_MEMORY; 3544 3545 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL); 3546 3547 dbus_message_unref (ret); 3548 3549 if (!sent) 3550 return DBUS_HANDLER_RESULT_NEED_MEMORY; 3551 3552 return DBUS_HANDLER_RESULT_HANDLED; 3553 } 3554 3555 3556 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 3557} 3558 3559/** 3560* Processes all builtin filter functions 3561* 3562* If the spec specifies a standard interface 3563* they should be processed from this method 3564**/ 3565static DBusHandlerResult 3566_dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection, 3567 DBusMessage *message) 3568{ 3569 /* We just run one filter for now but have the option to run more 3570 if the spec calls for it in the future */ 3571 3572 return _dbus_connection_peer_filter_unlocked_no_update (connection, message); 3573} 3574 3575/** 3576 * Processes data buffered while handling watches, queueing zero or 3577 * more incoming messages. Then pops the first-received message from 3578 * the current incoming message queue, runs any handlers for it, and 3579 * unrefs the message. Returns a status indicating whether messages/data 3580 * remain, more memory is needed, or all data has been processed. 3581 * 3582 * Even if the dispatch status is #DBUS_DISPATCH_DATA_REMAINS, 3583 * does not necessarily dispatch a message, as the data may 3584 * be part of authentication or the like. 3585 * 3586 * @todo some FIXME in here about handling DBUS_HANDLER_RESULT_NEED_MEMORY 3587 * 3588 * @todo FIXME what if we call out to application code to handle a 3589 * message, holding the dispatch lock, and the application code runs 3590 * the main loop and dispatches again? Probably deadlocks at the 3591 * moment. Maybe we want a dispatch status of DBUS_DISPATCH_IN_PROGRESS, 3592 * and then the GSource etc. could handle the situation? Right now 3593 * our GSource is NO_RECURSE 3594 * 3595 * @param connection the connection 3596 * @returns dispatch status 3597 */ 3598DBusDispatchStatus 3599dbus_connection_dispatch (DBusConnection *connection) 3600{ 3601 DBusMessage *message; 3602 DBusList *link, *filter_list_copy, *message_link; 3603 DBusHandlerResult result; 3604 DBusPendingCall *pending; 3605 dbus_int32_t reply_serial; 3606 DBusDispatchStatus status; 3607 3608 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE); 3609 3610 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME); 3611 3612 CONNECTION_LOCK (connection); 3613 status = _dbus_connection_get_dispatch_status_unlocked (connection); 3614 if (status != DBUS_DISPATCH_DATA_REMAINS) 3615 { 3616 /* unlocks and calls out to user code */ 3617 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 3618 return status; 3619 } 3620 3621 /* We need to ref the connection since the callback could potentially 3622 * drop the last ref to it 3623 */ 3624 _dbus_connection_ref_unlocked (connection); 3625 3626 _dbus_connection_acquire_dispatch (connection); 3627 HAVE_LOCK_CHECK (connection); 3628 3629 message_link = _dbus_connection_pop_message_link_unlocked (connection); 3630 if (message_link == NULL) 3631 { 3632 /* another thread dispatched our stuff */ 3633 3634 _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n"); 3635 3636 _dbus_connection_release_dispatch (connection); 3637 3638 status = _dbus_connection_get_dispatch_status_unlocked (connection); 3639 3640 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 3641 3642 dbus_connection_unref (connection); 3643 3644 return status; 3645 } 3646 3647 message = message_link->data; 3648 3649 _dbus_verbose (" dispatching message %p (%d %s %s '%s')\n", 3650 message, 3651 dbus_message_get_type (message), 3652 dbus_message_get_interface (message) ? 3653 dbus_message_get_interface (message) : 3654 "no interface", 3655 dbus_message_get_member (message) ? 3656 dbus_message_get_member (message) : 3657 "no member", 3658 dbus_message_get_signature (message)); 3659 3660 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 3661 3662 /* Pending call handling must be first, because if you do 3663 * dbus_connection_send_with_reply_and_block() or 3664 * dbus_pending_call_block() then no handlers/filters will be run on 3665 * the reply. We want consistent semantics in the case where we 3666 * dbus_connection_dispatch() the reply. 3667 */ 3668 3669 reply_serial = dbus_message_get_reply_serial (message); 3670 pending = _dbus_hash_table_lookup_int (connection->pending_replies, 3671 reply_serial); 3672 if (pending) 3673 { 3674 _dbus_verbose ("Dispatching a pending reply\n"); 3675 complete_pending_call_and_unlock (connection, pending, message); 3676 pending = NULL; /* it's probably unref'd */ 3677 3678 CONNECTION_LOCK (connection); 3679 _dbus_verbose ("pending call completed in dispatch\n"); 3680 result = DBUS_HANDLER_RESULT_HANDLED; 3681 goto out; 3682 } 3683 3684 result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message); 3685 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED) 3686 goto out; 3687 3688 if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy)) 3689 { 3690 _dbus_connection_release_dispatch (connection); 3691 HAVE_LOCK_CHECK (connection); 3692 3693 _dbus_connection_failed_pop (connection, message_link); 3694 3695 /* unlocks and calls user code */ 3696 _dbus_connection_update_dispatch_status_and_unlock (connection, 3697 DBUS_DISPATCH_NEED_MEMORY); 3698 3699 if (pending) 3700 dbus_pending_call_unref (pending); 3701 dbus_connection_unref (connection); 3702 3703 return DBUS_DISPATCH_NEED_MEMORY; 3704 } 3705 3706 _dbus_list_foreach (&filter_list_copy, 3707 (DBusForeachFunction)_dbus_message_filter_ref, 3708 NULL); 3709 3710 /* We're still protected from dispatch() reentrancy here 3711 * since we acquired the dispatcher 3712 */ 3713 CONNECTION_UNLOCK (connection); 3714 3715 link = _dbus_list_get_first_link (&filter_list_copy); 3716 while (link != NULL) 3717 { 3718 DBusMessageFilter *filter = link->data; 3719 DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link); 3720 3721 _dbus_verbose (" running filter on message %p\n", message); 3722 result = (* filter->function) (connection, message, filter->user_data); 3723 3724 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED) 3725 break; 3726 3727 link = next; 3728 } 3729 3730 _dbus_list_foreach (&filter_list_copy, 3731 (DBusForeachFunction)_dbus_message_filter_unref, 3732 NULL); 3733 _dbus_list_clear (&filter_list_copy); 3734 3735 CONNECTION_LOCK (connection); 3736 3737 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY) 3738 { 3739 _dbus_verbose ("No memory in %s\n", _DBUS_FUNCTION_NAME); 3740 goto out; 3741 } 3742 else if (result == DBUS_HANDLER_RESULT_HANDLED) 3743 { 3744 _dbus_verbose ("filter handled message in dispatch\n"); 3745 goto out; 3746 } 3747 3748 /* We're still protected from dispatch() reentrancy here 3749 * since we acquired the dispatcher 3750 */ 3751 _dbus_verbose (" running object path dispatch on message %p (%d %s %s '%s')\n", 3752 message, 3753 dbus_message_get_type (message), 3754 dbus_message_get_interface (message) ? 3755 dbus_message_get_interface (message) : 3756 "no interface", 3757 dbus_message_get_member (message) ? 3758 dbus_message_get_member (message) : 3759 "no member", 3760 dbus_message_get_signature (message)); 3761 3762 HAVE_LOCK_CHECK (connection); 3763 result = _dbus_object_tree_dispatch_and_unlock (connection->objects, 3764 message); 3765 3766 CONNECTION_LOCK (connection); 3767 3768 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED) 3769 { 3770 _dbus_verbose ("object tree handled message in dispatch\n"); 3771 goto out; 3772 } 3773 3774 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL) 3775 { 3776 DBusMessage *reply; 3777 DBusString str; 3778 DBusPreallocatedSend *preallocated; 3779 3780 _dbus_verbose (" sending error %s\n", 3781 DBUS_ERROR_UNKNOWN_METHOD); 3782 3783 if (!_dbus_string_init (&str)) 3784 { 3785 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 3786 _dbus_verbose ("no memory for error string in dispatch\n"); 3787 goto out; 3788 } 3789 3790 if (!_dbus_string_append_printf (&str, 3791 "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n", 3792 dbus_message_get_member (message), 3793 dbus_message_get_signature (message), 3794 dbus_message_get_interface (message))) 3795 { 3796 _dbus_string_free (&str); 3797 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 3798 _dbus_verbose ("no memory for error string in dispatch\n"); 3799 goto out; 3800 } 3801 3802 reply = dbus_message_new_error (message, 3803 DBUS_ERROR_UNKNOWN_METHOD, 3804 _dbus_string_get_const_data (&str)); 3805 _dbus_string_free (&str); 3806 3807 if (reply == NULL) 3808 { 3809 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 3810 _dbus_verbose ("no memory for error reply in dispatch\n"); 3811 goto out; 3812 } 3813 3814 preallocated = _dbus_connection_preallocate_send_unlocked (connection); 3815 3816 if (preallocated == NULL) 3817 { 3818 dbus_message_unref (reply); 3819 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 3820 _dbus_verbose ("no memory for error send in dispatch\n"); 3821 goto out; 3822 } 3823 3824 _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated, 3825 reply, NULL); 3826 3827 dbus_message_unref (reply); 3828 3829 result = DBUS_HANDLER_RESULT_HANDLED; 3830 } 3831 3832 _dbus_verbose (" done dispatching %p (%d %s %s '%s') on connection %p\n", message, 3833 dbus_message_get_type (message), 3834 dbus_message_get_interface (message) ? 3835 dbus_message_get_interface (message) : 3836 "no interface", 3837 dbus_message_get_member (message) ? 3838 dbus_message_get_member (message) : 3839 "no member", 3840 dbus_message_get_signature (message), 3841 connection); 3842 3843 out: 3844 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY) 3845 { 3846 _dbus_verbose ("out of memory in %s\n", _DBUS_FUNCTION_NAME); 3847 3848 /* Put message back, and we'll start over. 3849 * Yes this means handlers must be idempotent if they 3850 * don't return HANDLED; c'est la vie. 3851 */ 3852 _dbus_connection_putback_message_link_unlocked (connection, 3853 message_link); 3854 } 3855 else 3856 { 3857 _dbus_verbose (" ... done dispatching in %s\n", _DBUS_FUNCTION_NAME); 3858 3859 if (dbus_message_is_signal (message, 3860 DBUS_INTERFACE_LOCAL, 3861 "Disconnected")) 3862 { 3863 _dbus_bus_check_connection_and_unref_unlocked (connection); 3864 3865 if (connection->exit_on_disconnect) 3866 { 3867 CONNECTION_UNLOCK (connection); 3868 3869 _dbus_verbose ("Exiting on Disconnected signal\n"); 3870 _dbus_exit (1); 3871 _dbus_assert_not_reached ("Call to exit() returned"); 3872 } 3873 } 3874 3875 _dbus_list_free_link (message_link); 3876 dbus_message_unref (message); /* don't want the message to count in max message limits 3877 * in computing dispatch status below 3878 */ 3879 } 3880 3881 _dbus_connection_release_dispatch (connection); 3882 HAVE_LOCK_CHECK (connection); 3883 3884 _dbus_verbose ("%s before final status update\n", _DBUS_FUNCTION_NAME); 3885 status = _dbus_connection_get_dispatch_status_unlocked (connection); 3886 3887 /* unlocks and calls user code */ 3888 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 3889 3890 dbus_connection_unref (connection); 3891 3892 return status; 3893} 3894 3895/** 3896 * Sets the watch functions for the connection. These functions are 3897 * responsible for making the application's main loop aware of file 3898 * descriptors that need to be monitored for events, using select() or 3899 * poll(). When using Qt, typically the DBusAddWatchFunction would 3900 * create a QSocketNotifier. When using GLib, the DBusAddWatchFunction 3901 * could call g_io_add_watch(), or could be used as part of a more 3902 * elaborate GSource. Note that when a watch is added, it may 3903 * not be enabled. 3904 * 3905 * The DBusWatchToggledFunction notifies the application that the 3906 * watch has been enabled or disabled. Call dbus_watch_get_enabled() 3907 * to check this. A disabled watch should have no effect, and enabled 3908 * watch should be added to the main loop. This feature is used 3909 * instead of simply adding/removing the watch because 3910 * enabling/disabling can be done without memory allocation. The 3911 * toggled function may be NULL if a main loop re-queries 3912 * dbus_watch_get_enabled() every time anyway. 3913 * 3914 * The DBusWatch can be queried for the file descriptor to watch using 3915 * dbus_watch_get_fd(), and for the events to watch for using 3916 * dbus_watch_get_flags(). The flags returned by 3917 * dbus_watch_get_flags() will only contain DBUS_WATCH_READABLE and 3918 * DBUS_WATCH_WRITABLE, never DBUS_WATCH_HANGUP or DBUS_WATCH_ERROR; 3919 * all watches implicitly include a watch for hangups, errors, and 3920 * other exceptional conditions. 3921 * 3922 * Once a file descriptor becomes readable or writable, or an exception 3923 * occurs, dbus_watch_handle() should be called to 3924 * notify the connection of the file descriptor's condition. 3925 * 3926 * dbus_watch_handle() cannot be called during the 3927 * DBusAddWatchFunction, as the connection will not be ready to handle 3928 * that watch yet. 3929 * 3930 * It is not allowed to reference a DBusWatch after it has been passed 3931 * to remove_function. 3932 * 3933 * If #FALSE is returned due to lack of memory, the failure may be due 3934 * to a #FALSE return from the new add_function. If so, the 3935 * add_function may have been called successfully one or more times, 3936 * but the remove_function will also have been called to remove any 3937 * successful adds. i.e. if #FALSE is returned the net result 3938 * should be that dbus_connection_set_watch_functions() has no effect, 3939 * but the add_function and remove_function may have been called. 3940 * 3941 * @todo We need to drop the lock when we call the 3942 * add/remove/toggled functions which can be a side effect 3943 * of setting the watch functions. 3944 * 3945 * @param connection the connection. 3946 * @param add_function function to begin monitoring a new descriptor. 3947 * @param remove_function function to stop monitoring a descriptor. 3948 * @param toggled_function function to notify of enable/disable 3949 * @param data data to pass to add_function and remove_function. 3950 * @param free_data_function function to be called to free the data. 3951 * @returns #FALSE on failure (no memory) 3952 */ 3953dbus_bool_t 3954dbus_connection_set_watch_functions (DBusConnection *connection, 3955 DBusAddWatchFunction add_function, 3956 DBusRemoveWatchFunction remove_function, 3957 DBusWatchToggledFunction toggled_function, 3958 void *data, 3959 DBusFreeFunction free_data_function) 3960{ 3961 dbus_bool_t retval; 3962 DBusWatchList *watches; 3963 3964 _dbus_return_val_if_fail (connection != NULL, FALSE); 3965 3966 CONNECTION_LOCK (connection); 3967 3968#ifndef DBUS_DISABLE_CHECKS 3969 if (connection->watches == NULL) 3970 { 3971 _dbus_warn ("Re-entrant call to %s is not allowed\n", 3972 _DBUS_FUNCTION_NAME); 3973 return FALSE; 3974 } 3975#endif 3976 3977 /* ref connection for slightly better reentrancy */ 3978 _dbus_connection_ref_unlocked (connection); 3979 3980 /* This can call back into user code, and we need to drop the 3981 * connection lock when it does. This is kind of a lame 3982 * way to do it. 3983 */ 3984 watches = connection->watches; 3985 connection->watches = NULL; 3986 CONNECTION_UNLOCK (connection); 3987 3988 retval = _dbus_watch_list_set_functions (watches, 3989 add_function, remove_function, 3990 toggled_function, 3991 data, free_data_function); 3992 CONNECTION_LOCK (connection); 3993 connection->watches = watches; 3994 3995 CONNECTION_UNLOCK (connection); 3996 /* drop our paranoid refcount */ 3997 dbus_connection_unref (connection); 3998 3999 return retval; 4000} 4001 4002/** 4003 * Sets the timeout functions for the connection. These functions are 4004 * responsible for making the application's main loop aware of timeouts. 4005 * When using Qt, typically the DBusAddTimeoutFunction would create a 4006 * QTimer. When using GLib, the DBusAddTimeoutFunction would call 4007 * g_timeout_add. 4008 * 4009 * The DBusTimeoutToggledFunction notifies the application that the 4010 * timeout has been enabled or disabled. Call 4011 * dbus_timeout_get_enabled() to check this. A disabled timeout should 4012 * have no effect, and enabled timeout should be added to the main 4013 * loop. This feature is used instead of simply adding/removing the 4014 * timeout because enabling/disabling can be done without memory 4015 * allocation. With Qt, QTimer::start() and QTimer::stop() can be used 4016 * to enable and disable. The toggled function may be NULL if a main 4017 * loop re-queries dbus_timeout_get_enabled() every time anyway. 4018 * Whenever a timeout is toggled, its interval may change. 4019 * 4020 * The DBusTimeout can be queried for the timer interval using 4021 * dbus_timeout_get_interval(). dbus_timeout_handle() should be called 4022 * repeatedly, each time the interval elapses, starting after it has 4023 * elapsed once. The timeout stops firing when it is removed with the 4024 * given remove_function. The timer interval may change whenever the 4025 * timeout is added, removed, or toggled. 4026 * 4027 * @param connection the connection. 4028 * @param add_function function to add a timeout. 4029 * @param remove_function function to remove a timeout. 4030 * @param toggled_function function to notify of enable/disable 4031 * @param data data to pass to add_function and remove_function. 4032 * @param free_data_function function to be called to free the data. 4033 * @returns #FALSE on failure (no memory) 4034 */ 4035dbus_bool_t 4036dbus_connection_set_timeout_functions (DBusConnection *connection, 4037 DBusAddTimeoutFunction add_function, 4038 DBusRemoveTimeoutFunction remove_function, 4039 DBusTimeoutToggledFunction toggled_function, 4040 void *data, 4041 DBusFreeFunction free_data_function) 4042{ 4043 dbus_bool_t retval; 4044 DBusTimeoutList *timeouts; 4045 4046 _dbus_return_val_if_fail (connection != NULL, FALSE); 4047 4048 CONNECTION_LOCK (connection); 4049 4050#ifndef DBUS_DISABLE_CHECKS 4051 if (connection->timeouts == NULL) 4052 { 4053 _dbus_warn ("Re-entrant call to %s is not allowed\n", 4054 _DBUS_FUNCTION_NAME); 4055 return FALSE; 4056 } 4057#endif 4058 4059 /* ref connection for slightly better reentrancy */ 4060 _dbus_connection_ref_unlocked (connection); 4061 4062 timeouts = connection->timeouts; 4063 connection->timeouts = NULL; 4064 CONNECTION_UNLOCK (connection); 4065 4066 retval = _dbus_timeout_list_set_functions (timeouts, 4067 add_function, remove_function, 4068 toggled_function, 4069 data, free_data_function); 4070 CONNECTION_LOCK (connection); 4071 connection->timeouts = timeouts; 4072 4073 CONNECTION_UNLOCK (connection); 4074 /* drop our paranoid refcount */ 4075 dbus_connection_unref (connection); 4076 4077 return retval; 4078} 4079 4080/** 4081 * Sets the mainloop wakeup function for the connection. This function is 4082 * responsible for waking up the main loop (if its sleeping) when some some 4083 * change has happened to the connection that the mainloop needs to reconsider 4084 * (e.g. a message has been queued for writing). 4085 * When using Qt, this typically results in a call to QEventLoop::wakeUp(). 4086 * When using GLib, it would call g_main_context_wakeup(). 4087 * 4088 * 4089 * @param connection the connection. 4090 * @param wakeup_main_function function to wake up the mainloop 4091 * @param data data to pass wakeup_main_function 4092 * @param free_data_function function to be called to free the data. 4093 */ 4094void 4095dbus_connection_set_wakeup_main_function (DBusConnection *connection, 4096 DBusWakeupMainFunction wakeup_main_function, 4097 void *data, 4098 DBusFreeFunction free_data_function) 4099{ 4100 void *old_data; 4101 DBusFreeFunction old_free_data; 4102 4103 _dbus_return_if_fail (connection != NULL); 4104 4105 CONNECTION_LOCK (connection); 4106 old_data = connection->wakeup_main_data; 4107 old_free_data = connection->free_wakeup_main_data; 4108 4109 connection->wakeup_main_function = wakeup_main_function; 4110 connection->wakeup_main_data = data; 4111 connection->free_wakeup_main_data = free_data_function; 4112 4113 CONNECTION_UNLOCK (connection); 4114 4115 /* Callback outside the lock */ 4116 if (old_free_data) 4117 (*old_free_data) (old_data); 4118} 4119 4120/** 4121 * Set a function to be invoked when the dispatch status changes. 4122 * If the dispatch status is #DBUS_DISPATCH_DATA_REMAINS, then 4123 * dbus_connection_dispatch() needs to be called to process incoming 4124 * messages. However, dbus_connection_dispatch() MUST NOT BE CALLED 4125 * from inside the DBusDispatchStatusFunction. Indeed, almost 4126 * any reentrancy in this function is a bad idea. Instead, 4127 * the DBusDispatchStatusFunction should simply save an indication 4128 * that messages should be dispatched later, when the main loop 4129 * is re-entered. 4130 * 4131 * @param connection the connection 4132 * @param function function to call on dispatch status changes 4133 * @param data data for function 4134 * @param free_data_function free the function data 4135 */ 4136void 4137dbus_connection_set_dispatch_status_function (DBusConnection *connection, 4138 DBusDispatchStatusFunction function, 4139 void *data, 4140 DBusFreeFunction free_data_function) 4141{ 4142 void *old_data; 4143 DBusFreeFunction old_free_data; 4144 4145 _dbus_return_if_fail (connection != NULL); 4146 4147 CONNECTION_LOCK (connection); 4148 old_data = connection->dispatch_status_data; 4149 old_free_data = connection->free_dispatch_status_data; 4150 4151 connection->dispatch_status_function = function; 4152 connection->dispatch_status_data = data; 4153 connection->free_dispatch_status_data = free_data_function; 4154 4155 CONNECTION_UNLOCK (connection); 4156 4157 /* Callback outside the lock */ 4158 if (old_free_data) 4159 (*old_free_data) (old_data); 4160} 4161 4162/** 4163 * Get the UNIX file descriptor of the connection, if any. This can 4164 * be used for SELinux access control checks with getpeercon() for 4165 * example. DO NOT read or write to the file descriptor, or try to 4166 * select() on it; use DBusWatch for main loop integration. Not all 4167 * connections will have a file descriptor. So for adding descriptors 4168 * to the main loop, use dbus_watch_get_fd() and so forth. 4169 * 4170 * @param connection the connection 4171 * @param fd return location for the file descriptor. 4172 * @returns #TRUE if fd is successfully obtained. 4173 */ 4174dbus_bool_t 4175dbus_connection_get_unix_fd (DBusConnection *connection, 4176 int *fd) 4177{ 4178 dbus_bool_t retval; 4179 4180 _dbus_return_val_if_fail (connection != NULL, FALSE); 4181 _dbus_return_val_if_fail (connection->transport != NULL, FALSE); 4182 4183 CONNECTION_LOCK (connection); 4184 4185 retval = _dbus_transport_get_unix_fd (connection->transport, 4186 fd); 4187 4188 CONNECTION_UNLOCK (connection); 4189 4190 return retval; 4191} 4192 4193/** 4194 * Gets the UNIX user ID of the connection if any. 4195 * Returns #TRUE if the uid is filled in. 4196 * Always returns #FALSE on non-UNIX platforms. 4197 * Always returns #FALSE prior to authenticating the 4198 * connection. 4199 * 4200 * @param connection the connection 4201 * @param uid return location for the user ID 4202 * @returns #TRUE if uid is filled in with a valid user ID 4203 */ 4204dbus_bool_t 4205dbus_connection_get_unix_user (DBusConnection *connection, 4206 unsigned long *uid) 4207{ 4208 dbus_bool_t result; 4209 4210 _dbus_return_val_if_fail (connection != NULL, FALSE); 4211 _dbus_return_val_if_fail (uid != NULL, FALSE); 4212 4213 CONNECTION_LOCK (connection); 4214 4215 if (!_dbus_transport_get_is_authenticated (connection->transport)) 4216 result = FALSE; 4217 else 4218 result = _dbus_transport_get_unix_user (connection->transport, 4219 uid); 4220 CONNECTION_UNLOCK (connection); 4221 4222 return result; 4223} 4224 4225/** 4226 * Gets the process ID of the connection if any. 4227 * Returns #TRUE if the uid is filled in. 4228 * Always returns #FALSE prior to authenticating the 4229 * connection. 4230 * 4231 * @param connection the connection 4232 * @param pid return location for the process ID 4233 * @returns #TRUE if uid is filled in with a valid process ID 4234 */ 4235dbus_bool_t 4236dbus_connection_get_unix_process_id (DBusConnection *connection, 4237 unsigned long *pid) 4238{ 4239 dbus_bool_t result; 4240 4241 _dbus_return_val_if_fail (connection != NULL, FALSE); 4242 _dbus_return_val_if_fail (pid != NULL, FALSE); 4243 4244 CONNECTION_LOCK (connection); 4245 4246 if (!_dbus_transport_get_is_authenticated (connection->transport)) 4247 result = FALSE; 4248 else 4249 result = _dbus_transport_get_unix_process_id (connection->transport, 4250 pid); 4251 CONNECTION_UNLOCK (connection); 4252 4253 return result; 4254} 4255 4256/** 4257 * Sets a predicate function used to determine whether a given user ID 4258 * is allowed to connect. When an incoming connection has 4259 * authenticated with a particular user ID, this function is called; 4260 * if it returns #TRUE, the connection is allowed to proceed, 4261 * otherwise the connection is disconnected. 4262 * 4263 * If the function is set to #NULL (as it is by default), then 4264 * only the same UID as the server process will be allowed to 4265 * connect. 4266 * 4267 * @param connection the connection 4268 * @param function the predicate 4269 * @param data data to pass to the predicate 4270 * @param free_data_function function to free the data 4271 */ 4272void 4273dbus_connection_set_unix_user_function (DBusConnection *connection, 4274 DBusAllowUnixUserFunction function, 4275 void *data, 4276 DBusFreeFunction free_data_function) 4277{ 4278 void *old_data = NULL; 4279 DBusFreeFunction old_free_function = NULL; 4280 4281 _dbus_return_if_fail (connection != NULL); 4282 4283 CONNECTION_LOCK (connection); 4284 _dbus_transport_set_unix_user_function (connection->transport, 4285 function, data, free_data_function, 4286 &old_data, &old_free_function); 4287 CONNECTION_UNLOCK (connection); 4288 4289 if (old_free_function != NULL) 4290 (* old_free_function) (old_data); 4291} 4292 4293/** 4294 * Adds a message filter. Filters are handlers that are run on all 4295 * incoming messages, prior to the objects registered with 4296 * dbus_connection_register_object_path(). Filters are run in the 4297 * order that they were added. The same handler can be added as a 4298 * filter more than once, in which case it will be run more than once. 4299 * Filters added during a filter callback won't be run on the message 4300 * being processed. 4301 * 4302 * @todo we don't run filters on messages while blocking without 4303 * entering the main loop, since filters are run as part of 4304 * dbus_connection_dispatch(). This is probably a feature, as filters 4305 * could create arbitrary reentrancy. But kind of sucks if you're 4306 * trying to filter METHOD_RETURN for some reason. 4307 * 4308 * @param connection the connection 4309 * @param function function to handle messages 4310 * @param user_data user data to pass to the function 4311 * @param free_data_function function to use for freeing user data 4312 * @returns #TRUE on success, #FALSE if not enough memory. 4313 */ 4314dbus_bool_t 4315dbus_connection_add_filter (DBusConnection *connection, 4316 DBusHandleMessageFunction function, 4317 void *user_data, 4318 DBusFreeFunction free_data_function) 4319{ 4320 DBusMessageFilter *filter; 4321 4322 _dbus_return_val_if_fail (connection != NULL, FALSE); 4323 _dbus_return_val_if_fail (function != NULL, FALSE); 4324 4325 filter = dbus_new0 (DBusMessageFilter, 1); 4326 if (filter == NULL) 4327 return FALSE; 4328 4329 filter->refcount.value = 1; 4330 4331 CONNECTION_LOCK (connection); 4332 4333 if (!_dbus_list_append (&connection->filter_list, 4334 filter)) 4335 { 4336 _dbus_message_filter_unref (filter); 4337 CONNECTION_UNLOCK (connection); 4338 return FALSE; 4339 } 4340 4341 /* Fill in filter after all memory allocated, 4342 * so we don't run the free_user_data_function 4343 * if the add_filter() fails 4344 */ 4345 4346 filter->function = function; 4347 filter->user_data = user_data; 4348 filter->free_user_data_function = free_data_function; 4349 4350 CONNECTION_UNLOCK (connection); 4351 return TRUE; 4352} 4353 4354/** 4355 * Removes a previously-added message filter. It is a programming 4356 * error to call this function for a handler that has not been added 4357 * as a filter. If the given handler was added more than once, only 4358 * one instance of it will be removed (the most recently-added 4359 * instance). 4360 * 4361 * @param connection the connection 4362 * @param function the handler to remove 4363 * @param user_data user data for the handler to remove 4364 * 4365 */ 4366void 4367dbus_connection_remove_filter (DBusConnection *connection, 4368 DBusHandleMessageFunction function, 4369 void *user_data) 4370{ 4371 DBusList *link; 4372 DBusMessageFilter *filter; 4373 4374 _dbus_return_if_fail (connection != NULL); 4375 _dbus_return_if_fail (function != NULL); 4376 4377 CONNECTION_LOCK (connection); 4378 4379 filter = NULL; 4380 4381 link = _dbus_list_get_last_link (&connection->filter_list); 4382 while (link != NULL) 4383 { 4384 filter = link->data; 4385 4386 if (filter->function == function && 4387 filter->user_data == user_data) 4388 { 4389 _dbus_list_remove_link (&connection->filter_list, link); 4390 filter->function = NULL; 4391 4392 break; 4393 } 4394 4395 link = _dbus_list_get_prev_link (&connection->filter_list, link); 4396 } 4397 4398 CONNECTION_UNLOCK (connection); 4399 4400#ifndef DBUS_DISABLE_CHECKS 4401 if (filter == NULL) 4402 { 4403 _dbus_warn ("Attempt to remove filter function %p user data %p, but no such filter has been added\n", 4404 function, user_data); 4405 return; 4406 } 4407#endif 4408 4409 /* Call application code */ 4410 if (filter->free_user_data_function) 4411 (* filter->free_user_data_function) (filter->user_data); 4412 4413 filter->free_user_data_function = NULL; 4414 filter->user_data = NULL; 4415 4416 _dbus_message_filter_unref (filter); 4417} 4418 4419/** 4420 * Registers a handler for a given path in the object hierarchy. 4421 * The given vtable handles messages sent to exactly the given path. 4422 * 4423 * 4424 * @param connection the connection 4425 * @param path a '/' delimited string of path elements 4426 * @param vtable the virtual table 4427 * @param user_data data to pass to functions in the vtable 4428 * @returns #FALSE if not enough memory 4429 */ 4430dbus_bool_t 4431dbus_connection_register_object_path (DBusConnection *connection, 4432 const char *path, 4433 const DBusObjectPathVTable *vtable, 4434 void *user_data) 4435{ 4436 char **decomposed_path; 4437 dbus_bool_t retval; 4438 4439 _dbus_return_val_if_fail (connection != NULL, FALSE); 4440 _dbus_return_val_if_fail (path != NULL, FALSE); 4441 _dbus_return_val_if_fail (path[0] == '/', FALSE); 4442 _dbus_return_val_if_fail (vtable != NULL, FALSE); 4443 4444 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) 4445 return FALSE; 4446 4447 CONNECTION_LOCK (connection); 4448 4449 retval = _dbus_object_tree_register (connection->objects, 4450 FALSE, 4451 (const char **) decomposed_path, vtable, 4452 user_data); 4453 4454 CONNECTION_UNLOCK (connection); 4455 4456 dbus_free_string_array (decomposed_path); 4457 4458 return retval; 4459} 4460 4461/** 4462 * Registers a fallback handler for a given subsection of the object 4463 * hierarchy. The given vtable handles messages at or below the given 4464 * path. You can use this to establish a default message handling 4465 * policy for a whole "subdirectory." 4466 * 4467 * @param connection the connection 4468 * @param path a '/' delimited string of path elements 4469 * @param vtable the virtual table 4470 * @param user_data data to pass to functions in the vtable 4471 * @returns #FALSE if not enough memory 4472 */ 4473dbus_bool_t 4474dbus_connection_register_fallback (DBusConnection *connection, 4475 const char *path, 4476 const DBusObjectPathVTable *vtable, 4477 void *user_data) 4478{ 4479 char **decomposed_path; 4480 dbus_bool_t retval; 4481 4482 _dbus_return_val_if_fail (connection != NULL, FALSE); 4483 _dbus_return_val_if_fail (path != NULL, FALSE); 4484 _dbus_return_val_if_fail (path[0] == '/', FALSE); 4485 _dbus_return_val_if_fail (vtable != NULL, FALSE); 4486 4487 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) 4488 return FALSE; 4489 4490 CONNECTION_LOCK (connection); 4491 4492 retval = _dbus_object_tree_register (connection->objects, 4493 TRUE, 4494 (const char **) decomposed_path, vtable, 4495 user_data); 4496 4497 CONNECTION_UNLOCK (connection); 4498 4499 dbus_free_string_array (decomposed_path); 4500 4501 return retval; 4502} 4503 4504/** 4505 * Unregisters the handler registered with exactly the given path. 4506 * It's a bug to call this function for a path that isn't registered. 4507 * Can unregister both fallback paths and object paths. 4508 * 4509 * @param connection the connection 4510 * @param path a '/' delimited string of path elements 4511 * @returns #FALSE if not enough memory 4512 */ 4513dbus_bool_t 4514dbus_connection_unregister_object_path (DBusConnection *connection, 4515 const char *path) 4516{ 4517 char **decomposed_path; 4518 4519 _dbus_return_val_if_fail (connection != NULL, FALSE); 4520 _dbus_return_val_if_fail (path != NULL, FALSE); 4521 _dbus_return_val_if_fail (path[0] == '/', FALSE); 4522 4523 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) 4524 return FALSE; 4525 4526 CONNECTION_LOCK (connection); 4527 4528 _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path); 4529 4530 dbus_free_string_array (decomposed_path); 4531 4532 return TRUE; 4533} 4534 4535/** 4536 * Gets the user data passed to dbus_connection_register_object_path() 4537 * or dbus_connection_register_fallback(). If nothing was registered 4538 * at this path, the data is filled in with #NULL. 4539 * 4540 * @param connection the connection 4541 * @param path the path you registered with 4542 * @param data_p location to store the user data, or #NULL 4543 * @returns #FALSE if not enough memory 4544 */ 4545dbus_bool_t 4546dbus_connection_get_object_path_data (DBusConnection *connection, 4547 const char *path, 4548 void **data_p) 4549{ 4550 char **decomposed_path; 4551 4552 _dbus_return_val_if_fail (connection != NULL, FALSE); 4553 _dbus_return_val_if_fail (path != NULL, FALSE); 4554 _dbus_return_val_if_fail (data_p != NULL, FALSE); 4555 4556 *data_p = NULL; 4557 4558 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) 4559 return FALSE; 4560 4561 CONNECTION_LOCK (connection); 4562 4563 *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path); 4564 4565 CONNECTION_UNLOCK (connection); 4566 4567 dbus_free_string_array (decomposed_path); 4568 4569 return TRUE; 4570} 4571 4572/** 4573 * Lists the registered fallback handlers and object path handlers at 4574 * the given parent_path. The returned array should be freed with 4575 * dbus_free_string_array(). 4576 * 4577 * @param connection the connection 4578 * @param parent_path the path to list the child handlers of 4579 * @param child_entries returns #NULL-terminated array of children 4580 * @returns #FALSE if no memory to allocate the child entries 4581 */ 4582dbus_bool_t 4583dbus_connection_list_registered (DBusConnection *connection, 4584 const char *parent_path, 4585 char ***child_entries) 4586{ 4587 char **decomposed_path; 4588 dbus_bool_t retval; 4589 _dbus_return_val_if_fail (connection != NULL, FALSE); 4590 _dbus_return_val_if_fail (parent_path != NULL, FALSE); 4591 _dbus_return_val_if_fail (parent_path[0] == '/', FALSE); 4592 _dbus_return_val_if_fail (child_entries != NULL, FALSE); 4593 4594 if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL)) 4595 return FALSE; 4596 4597 CONNECTION_LOCK (connection); 4598 4599 retval = _dbus_object_tree_list_registered_and_unlock (connection->objects, 4600 (const char **) decomposed_path, 4601 child_entries); 4602 dbus_free_string_array (decomposed_path); 4603 4604 return retval; 4605} 4606 4607static DBusDataSlotAllocator slot_allocator; 4608_DBUS_DEFINE_GLOBAL_LOCK (connection_slots); 4609 4610/** 4611 * Allocates an integer ID to be used for storing application-specific 4612 * data on any DBusConnection. The allocated ID may then be used 4613 * with dbus_connection_set_data() and dbus_connection_get_data(). 4614 * The passed-in slot must be initialized to -1, and is filled in 4615 * with the slot ID. If the passed-in slot is not -1, it's assumed 4616 * to be already allocated, and its refcount is incremented. 4617 * 4618 * The allocated slot is global, i.e. all DBusConnection objects will 4619 * have a slot with the given integer ID reserved. 4620 * 4621 * @param slot_p address of a global variable storing the slot 4622 * @returns #FALSE on failure (no memory) 4623 */ 4624dbus_bool_t 4625dbus_connection_allocate_data_slot (dbus_int32_t *slot_p) 4626{ 4627 return _dbus_data_slot_allocator_alloc (&slot_allocator, 4628 &_DBUS_LOCK_NAME (connection_slots), 4629 slot_p); 4630} 4631 4632/** 4633 * Deallocates a global ID for connection data slots. 4634 * dbus_connection_get_data() and dbus_connection_set_data() may no 4635 * longer be used with this slot. Existing data stored on existing 4636 * DBusConnection objects will be freed when the connection is 4637 * finalized, but may not be retrieved (and may only be replaced if 4638 * someone else reallocates the slot). When the refcount on the 4639 * passed-in slot reaches 0, it is set to -1. 4640 * 4641 * @param slot_p address storing the slot to deallocate 4642 */ 4643void 4644dbus_connection_free_data_slot (dbus_int32_t *slot_p) 4645{ 4646 _dbus_return_if_fail (*slot_p >= 0); 4647 4648 _dbus_data_slot_allocator_free (&slot_allocator, slot_p); 4649} 4650 4651/** 4652 * Stores a pointer on a DBusConnection, along 4653 * with an optional function to be used for freeing 4654 * the data when the data is set again, or when 4655 * the connection is finalized. The slot number 4656 * must have been allocated with dbus_connection_allocate_data_slot(). 4657 * 4658 * @param connection the connection 4659 * @param slot the slot number 4660 * @param data the data to store 4661 * @param free_data_func finalizer function for the data 4662 * @returns #TRUE if there was enough memory to store the data 4663 */ 4664dbus_bool_t 4665dbus_connection_set_data (DBusConnection *connection, 4666 dbus_int32_t slot, 4667 void *data, 4668 DBusFreeFunction free_data_func) 4669{ 4670 DBusFreeFunction old_free_func; 4671 void *old_data; 4672 dbus_bool_t retval; 4673 4674 _dbus_return_val_if_fail (connection != NULL, FALSE); 4675 _dbus_return_val_if_fail (slot >= 0, FALSE); 4676 4677 CONNECTION_LOCK (connection); 4678 4679 retval = _dbus_data_slot_list_set (&slot_allocator, 4680 &connection->slot_list, 4681 slot, data, free_data_func, 4682 &old_free_func, &old_data); 4683 4684 CONNECTION_UNLOCK (connection); 4685 4686 if (retval) 4687 { 4688 /* Do the actual free outside the connection lock */ 4689 if (old_free_func) 4690 (* old_free_func) (old_data); 4691 } 4692 4693 return retval; 4694} 4695 4696/** 4697 * Retrieves data previously set with dbus_connection_set_data(). 4698 * The slot must still be allocated (must not have been freed). 4699 * 4700 * @param connection the connection 4701 * @param slot the slot to get data from 4702 * @returns the data, or #NULL if not found 4703 */ 4704void* 4705dbus_connection_get_data (DBusConnection *connection, 4706 dbus_int32_t slot) 4707{ 4708 void *res; 4709 4710 _dbus_return_val_if_fail (connection != NULL, NULL); 4711 4712 CONNECTION_LOCK (connection); 4713 4714 res = _dbus_data_slot_list_get (&slot_allocator, 4715 &connection->slot_list, 4716 slot); 4717 4718 CONNECTION_UNLOCK (connection); 4719 4720 return res; 4721} 4722 4723/** 4724 * This function sets a global flag for whether dbus_connection_new() 4725 * will set SIGPIPE behavior to SIG_IGN. 4726 * 4727 * @param will_modify_sigpipe #TRUE to allow sigpipe to be set to SIG_IGN 4728 */ 4729void 4730dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe) 4731{ 4732 _dbus_modify_sigpipe = will_modify_sigpipe != FALSE; 4733} 4734 4735/** 4736 * Specifies the maximum size message this connection is allowed to 4737 * receive. Larger messages will result in disconnecting the 4738 * connection. 4739 * 4740 * @param connection a #DBusConnection 4741 * @param size maximum message size the connection can receive, in bytes 4742 */ 4743void 4744dbus_connection_set_max_message_size (DBusConnection *connection, 4745 long size) 4746{ 4747 _dbus_return_if_fail (connection != NULL); 4748 4749 CONNECTION_LOCK (connection); 4750 _dbus_transport_set_max_message_size (connection->transport, 4751 size); 4752 CONNECTION_UNLOCK (connection); 4753} 4754 4755/** 4756 * Gets the value set by dbus_connection_set_max_message_size(). 4757 * 4758 * @param connection the connection 4759 * @returns the max size of a single message 4760 */ 4761long 4762dbus_connection_get_max_message_size (DBusConnection *connection) 4763{ 4764 long res; 4765 4766 _dbus_return_val_if_fail (connection != NULL, 0); 4767 4768 CONNECTION_LOCK (connection); 4769 res = _dbus_transport_get_max_message_size (connection->transport); 4770 CONNECTION_UNLOCK (connection); 4771 return res; 4772} 4773 4774/** 4775 * Sets the maximum total number of bytes that can be used for all messages 4776 * received on this connection. Messages count toward the maximum until 4777 * they are finalized. When the maximum is reached, the connection will 4778 * not read more data until some messages are finalized. 4779 * 4780 * The semantics of the maximum are: if outstanding messages are 4781 * already above the maximum, additional messages will not be read. 4782 * The semantics are not: if the next message would cause us to exceed 4783 * the maximum, we don't read it. The reason is that we don't know the 4784 * size of a message until after we read it. 4785 * 4786 * Thus, the max live messages size can actually be exceeded 4787 * by up to the maximum size of a single message. 4788 * 4789 * Also, if we read say 1024 bytes off the wire in a single read(), 4790 * and that contains a half-dozen small messages, we may exceed the 4791 * size max by that amount. But this should be inconsequential. 4792 * 4793 * This does imply that we can't call read() with a buffer larger 4794 * than we're willing to exceed this limit by. 4795 * 4796 * @param connection the connection 4797 * @param size the maximum size in bytes of all outstanding messages 4798 */ 4799void 4800dbus_connection_set_max_received_size (DBusConnection *connection, 4801 long size) 4802{ 4803 _dbus_return_if_fail (connection != NULL); 4804 4805 CONNECTION_LOCK (connection); 4806 _dbus_transport_set_max_received_size (connection->transport, 4807 size); 4808 CONNECTION_UNLOCK (connection); 4809} 4810 4811/** 4812 * Gets the value set by dbus_connection_set_max_received_size(). 4813 * 4814 * @param connection the connection 4815 * @returns the max size of all live messages 4816 */ 4817long 4818dbus_connection_get_max_received_size (DBusConnection *connection) 4819{ 4820 long res; 4821 4822 _dbus_return_val_if_fail (connection != NULL, 0); 4823 4824 CONNECTION_LOCK (connection); 4825 res = _dbus_transport_get_max_received_size (connection->transport); 4826 CONNECTION_UNLOCK (connection); 4827 return res; 4828} 4829 4830/** 4831 * Gets the approximate size in bytes of all messages in the outgoing 4832 * message queue. The size is approximate in that you shouldn't use 4833 * it to decide how many bytes to read off the network or anything 4834 * of that nature, as optimizations may choose to tell small white lies 4835 * to avoid performance overhead. 4836 * 4837 * @param connection the connection 4838 * @returns the number of bytes that have been queued up but not sent 4839 */ 4840long 4841dbus_connection_get_outgoing_size (DBusConnection *connection) 4842{ 4843 long res; 4844 4845 _dbus_return_val_if_fail (connection != NULL, 0); 4846 4847 CONNECTION_LOCK (connection); 4848 res = _dbus_counter_get_value (connection->outgoing_counter); 4849 CONNECTION_UNLOCK (connection); 4850 return res; 4851} 4852 4853/** @} */ 4854