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