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