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