dbus-connection.c revision da4182fb2976608bea64d676677681fdf2cd910b
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 _dbus_return_val_if_fail (connection != NULL, FALSE); 2894 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE); 2895 dstatus = dbus_connection_get_dispatch_status (connection); 2896 2897 if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS) 2898 { 2899 _dbus_verbose ("doing dispatch in %s\n", _DBUS_FUNCTION_NAME); 2900 dbus_connection_dispatch (connection); 2901 CONNECTION_LOCK (connection); 2902 } 2903 else if (dstatus == DBUS_DISPATCH_NEED_MEMORY) 2904 { 2905 _dbus_verbose ("pausing for memory in %s\n", _DBUS_FUNCTION_NAME); 2906 _dbus_memory_pause_based_on_timeout (timeout_milliseconds); 2907 CONNECTION_LOCK (connection); 2908 } 2909 else 2910 { 2911 CONNECTION_LOCK (connection); 2912 if (_dbus_connection_get_is_connected_unlocked (connection)) 2913 { 2914 _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME); 2915 _dbus_connection_do_iteration_unlocked (connection, 2916 DBUS_ITERATION_DO_READING | 2917 DBUS_ITERATION_DO_WRITING | 2918 DBUS_ITERATION_BLOCK, 2919 timeout_milliseconds); 2920 } 2921 } 2922 2923 HAVE_LOCK_CHECK (connection); 2924 dispatched_disconnected = connection->n_incoming == 0 && 2925 connection->disconnect_message_link == NULL; 2926 CONNECTION_UNLOCK (connection); 2927 return !dispatched_disconnected; /* TRUE if we have not processed disconnected */ 2928} 2929 2930 2931/** 2932 * This function is intended for use with applications that don't want 2933 * to write a main loop and deal with #DBusWatch and #DBusTimeout. An 2934 * example usage would be: 2935 * 2936 * @code 2937 * while (dbus_connection_read_write_dispatch (connection, -1)) 2938 * ; // empty loop body 2939 * @endcode 2940 * 2941 * In this usage you would normally have set up a filter function to look 2942 * at each message as it is dispatched. The loop terminates when the last 2943 * message from the connection (the disconnected signal) is processed. 2944 * 2945 * If there are messages to dispatch, this function will 2946 * dbus_connection_dispatch() once, and return. If there are no 2947 * messages to dispatch, this function will block until it can read or 2948 * write, then read or write, then return. 2949 * 2950 * The way to think of this function is that it either makes some sort 2951 * of progress, or it blocks. 2952 * 2953 * The return value indicates whether the disconnect message has been 2954 * processed, NOT whether the connection is connected. This is 2955 * important because even after disconnecting, you want to process any 2956 * messages you received prior to the disconnect. 2957 * 2958 * @param connection the connection 2959 * @param timeout_milliseconds max time to block or -1 for infinite 2960 * @returns #TRUE if the disconnect message has not been processed 2961 */ 2962dbus_bool_t 2963dbus_connection_read_write_dispatch (DBusConnection *connection, 2964 int timeout_milliseconds) 2965{ 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 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE); 2990} 2991 2992/** 2993 * Returns the first-received message from the incoming message queue, 2994 * leaving it in the queue. If the queue is empty, returns #NULL. 2995 * 2996 * The caller does not own a reference to the returned message, and 2997 * must either return it using dbus_connection_return_message() or 2998 * keep it after calling dbus_connection_steal_borrowed_message(). No 2999 * one can get at the message while its borrowed, so return it as 3000 * quickly as possible and don't keep a reference to it after 3001 * returning it. If you need to keep the message, make a copy of it. 3002 * 3003 * dbus_connection_dispatch() will block if called while a borrowed 3004 * message is outstanding; only one piece of code can be playing with 3005 * the incoming queue at a time. This function will block if called 3006 * during a dbus_connection_dispatch(). 3007 * 3008 * @param connection the connection. 3009 * @returns next message in the incoming queue. 3010 */ 3011DBusMessage* 3012dbus_connection_borrow_message (DBusConnection *connection) 3013{ 3014 DBusDispatchStatus status; 3015 DBusMessage *message; 3016 3017 _dbus_return_val_if_fail (connection != NULL, NULL); 3018 3019 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME); 3020 3021 /* this is called for the side effect that it queues 3022 * up any messages from the transport 3023 */ 3024 status = dbus_connection_get_dispatch_status (connection); 3025 if (status != DBUS_DISPATCH_DATA_REMAINS) 3026 return NULL; 3027 3028 CONNECTION_LOCK (connection); 3029 3030 _dbus_connection_acquire_dispatch (connection); 3031 3032 /* While a message is outstanding, the dispatch lock is held */ 3033 _dbus_assert (connection->message_borrowed == NULL); 3034 3035 connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages); 3036 3037 message = connection->message_borrowed; 3038 3039 /* Note that we KEEP the dispatch lock until the message is returned */ 3040 if (message == NULL) 3041 _dbus_connection_release_dispatch (connection); 3042 3043 CONNECTION_UNLOCK (connection); 3044 3045 return message; 3046} 3047 3048/** 3049 * Used to return a message after peeking at it using 3050 * dbus_connection_borrow_message(). Only called if 3051 * message from dbus_connection_borrow_message() was non-#NULL. 3052 * 3053 * @param connection the connection 3054 * @param message the message from dbus_connection_borrow_message() 3055 */ 3056void 3057dbus_connection_return_message (DBusConnection *connection, 3058 DBusMessage *message) 3059{ 3060 _dbus_return_if_fail (connection != NULL); 3061 _dbus_return_if_fail (message != NULL); 3062 _dbus_return_if_fail (message == connection->message_borrowed); 3063 _dbus_return_if_fail (connection->dispatch_acquired); 3064 3065 CONNECTION_LOCK (connection); 3066 3067 _dbus_assert (message == connection->message_borrowed); 3068 3069 connection->message_borrowed = NULL; 3070 3071 _dbus_connection_release_dispatch (connection); 3072 3073 CONNECTION_UNLOCK (connection); 3074} 3075 3076/** 3077 * Used to keep a message after peeking at it using 3078 * dbus_connection_borrow_message(). Before using this function, see 3079 * the caveats/warnings in the documentation for 3080 * dbus_connection_pop_message(). 3081 * 3082 * @param connection the connection 3083 * @param message the message from dbus_connection_borrow_message() 3084 */ 3085void 3086dbus_connection_steal_borrowed_message (DBusConnection *connection, 3087 DBusMessage *message) 3088{ 3089 DBusMessage *pop_message; 3090 3091 _dbus_return_if_fail (connection != NULL); 3092 _dbus_return_if_fail (message != NULL); 3093 _dbus_return_if_fail (message == connection->message_borrowed); 3094 _dbus_return_if_fail (connection->dispatch_acquired); 3095 3096 CONNECTION_LOCK (connection); 3097 3098 _dbus_assert (message == connection->message_borrowed); 3099 3100 pop_message = _dbus_list_pop_first (&connection->incoming_messages); 3101 _dbus_assert (message == pop_message); 3102 3103 connection->n_incoming -= 1; 3104 3105 _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n", 3106 message, connection->n_incoming); 3107 3108 connection->message_borrowed = NULL; 3109 3110 _dbus_connection_release_dispatch (connection); 3111 3112 CONNECTION_UNLOCK (connection); 3113} 3114 3115/* See dbus_connection_pop_message, but requires the caller to own 3116 * the lock before calling. May drop the lock while running. 3117 */ 3118static DBusList* 3119_dbus_connection_pop_message_link_unlocked (DBusConnection *connection) 3120{ 3121 HAVE_LOCK_CHECK (connection); 3122 3123 _dbus_assert (connection->message_borrowed == NULL); 3124 3125 if (connection->n_incoming > 0) 3126 { 3127 DBusList *link; 3128 3129 link = _dbus_list_pop_first_link (&connection->incoming_messages); 3130 connection->n_incoming -= 1; 3131 3132 _dbus_verbose ("Message %p (%d %s %s %s '%s') removed from incoming queue %p, %d incoming\n", 3133 link->data, 3134 dbus_message_get_type (link->data), 3135 dbus_message_get_path (link->data) ? 3136 dbus_message_get_path (link->data) : 3137 "no path", 3138 dbus_message_get_interface (link->data) ? 3139 dbus_message_get_interface (link->data) : 3140 "no interface", 3141 dbus_message_get_member (link->data) ? 3142 dbus_message_get_member (link->data) : 3143 "no member", 3144 dbus_message_get_signature (link->data), 3145 connection, connection->n_incoming); 3146 3147 return link; 3148 } 3149 else 3150 return NULL; 3151} 3152 3153/* See dbus_connection_pop_message, but requires the caller to own 3154 * the lock before calling. May drop the lock while running. 3155 */ 3156static DBusMessage* 3157_dbus_connection_pop_message_unlocked (DBusConnection *connection) 3158{ 3159 DBusList *link; 3160 3161 HAVE_LOCK_CHECK (connection); 3162 3163 link = _dbus_connection_pop_message_link_unlocked (connection); 3164 3165 if (link != NULL) 3166 { 3167 DBusMessage *message; 3168 3169 message = link->data; 3170 3171 _dbus_list_free_link (link); 3172 3173 return message; 3174 } 3175 else 3176 return NULL; 3177} 3178 3179static void 3180_dbus_connection_putback_message_link_unlocked (DBusConnection *connection, 3181 DBusList *message_link) 3182{ 3183 HAVE_LOCK_CHECK (connection); 3184 3185 _dbus_assert (message_link != NULL); 3186 /* You can't borrow a message while a link is outstanding */ 3187 _dbus_assert (connection->message_borrowed == NULL); 3188 /* We had to have the dispatch lock across the pop/putback */ 3189 _dbus_assert (connection->dispatch_acquired); 3190 3191 _dbus_list_prepend_link (&connection->incoming_messages, 3192 message_link); 3193 connection->n_incoming += 1; 3194 3195 _dbus_verbose ("Message %p (%d %s %s '%s') put back into queue %p, %d incoming\n", 3196 message_link->data, 3197 dbus_message_get_type (message_link->data), 3198 dbus_message_get_interface (message_link->data) ? 3199 dbus_message_get_interface (message_link->data) : 3200 "no interface", 3201 dbus_message_get_member (message_link->data) ? 3202 dbus_message_get_member (message_link->data) : 3203 "no member", 3204 dbus_message_get_signature (message_link->data), 3205 connection, connection->n_incoming); 3206} 3207 3208/** 3209 * Returns the first-received message from the incoming message queue, 3210 * removing it from the queue. The caller owns a reference to the 3211 * returned message. If the queue is empty, returns #NULL. 3212 * 3213 * This function bypasses any message handlers that are registered, 3214 * and so using it is usually wrong. Instead, let the main loop invoke 3215 * dbus_connection_dispatch(). Popping messages manually is only 3216 * useful in very simple programs that don't share a #DBusConnection 3217 * with any libraries or other modules. 3218 * 3219 * There is a lock that covers all ways of accessing the incoming message 3220 * queue, so dbus_connection_dispatch(), dbus_connection_pop_message(), 3221 * dbus_connection_borrow_message(), etc. will all block while one of the others 3222 * in the group is running. 3223 * 3224 * @param connection the connection. 3225 * @returns next message in the incoming queue. 3226 */ 3227DBusMessage* 3228dbus_connection_pop_message (DBusConnection *connection) 3229{ 3230 DBusMessage *message; 3231 DBusDispatchStatus status; 3232 3233 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME); 3234 3235 /* this is called for the side effect that it queues 3236 * up any messages from the transport 3237 */ 3238 status = dbus_connection_get_dispatch_status (connection); 3239 if (status != DBUS_DISPATCH_DATA_REMAINS) 3240 return NULL; 3241 3242 CONNECTION_LOCK (connection); 3243 _dbus_connection_acquire_dispatch (connection); 3244 HAVE_LOCK_CHECK (connection); 3245 3246 message = _dbus_connection_pop_message_unlocked (connection); 3247 3248 _dbus_verbose ("Returning popped message %p\n", message); 3249 3250 _dbus_connection_release_dispatch (connection); 3251 CONNECTION_UNLOCK (connection); 3252 3253 return message; 3254} 3255 3256/** 3257 * Acquire the dispatcher. This is a separate lock so the main 3258 * connection lock can be dropped to call out to application dispatch 3259 * handlers. 3260 * 3261 * @param connection the connection. 3262 */ 3263static void 3264_dbus_connection_acquire_dispatch (DBusConnection *connection) 3265{ 3266 HAVE_LOCK_CHECK (connection); 3267 3268 _dbus_connection_ref_unlocked (connection); 3269 CONNECTION_UNLOCK (connection); 3270 3271 _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME); 3272 _dbus_mutex_lock (connection->dispatch_mutex); 3273 3274 while (connection->dispatch_acquired) 3275 { 3276 _dbus_verbose ("%s waiting for dispatch to be acquirable\n", _DBUS_FUNCTION_NAME); 3277 _dbus_condvar_wait (connection->dispatch_cond, connection->dispatch_mutex); 3278 } 3279 3280 _dbus_assert (!connection->dispatch_acquired); 3281 3282 connection->dispatch_acquired = TRUE; 3283 3284 _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME); 3285 _dbus_mutex_unlock (connection->dispatch_mutex); 3286 3287 CONNECTION_LOCK (connection); 3288 _dbus_connection_unref_unlocked (connection); 3289} 3290 3291/** 3292 * Release the dispatcher when you're done with it. Only call 3293 * after you've acquired the dispatcher. Wakes up at most one 3294 * thread currently waiting to acquire the dispatcher. 3295 * 3296 * @param connection the connection. 3297 */ 3298static void 3299_dbus_connection_release_dispatch (DBusConnection *connection) 3300{ 3301 HAVE_LOCK_CHECK (connection); 3302 3303 _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME); 3304 _dbus_mutex_lock (connection->dispatch_mutex); 3305 3306 _dbus_assert (connection->dispatch_acquired); 3307 3308 connection->dispatch_acquired = FALSE; 3309 _dbus_condvar_wake_one (connection->dispatch_cond); 3310 3311 _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME); 3312 _dbus_mutex_unlock (connection->dispatch_mutex); 3313} 3314 3315static void 3316_dbus_connection_failed_pop (DBusConnection *connection, 3317 DBusList *message_link) 3318{ 3319 _dbus_list_prepend_link (&connection->incoming_messages, 3320 message_link); 3321 connection->n_incoming += 1; 3322} 3323 3324static DBusDispatchStatus 3325_dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection) 3326{ 3327 HAVE_LOCK_CHECK (connection); 3328 3329 if (connection->n_incoming > 0) 3330 return DBUS_DISPATCH_DATA_REMAINS; 3331 else if (!_dbus_transport_queue_messages (connection->transport)) 3332 return DBUS_DISPATCH_NEED_MEMORY; 3333 else 3334 { 3335 DBusDispatchStatus status; 3336 dbus_bool_t is_connected; 3337 3338 status = _dbus_transport_get_dispatch_status (connection->transport); 3339 is_connected = _dbus_transport_get_is_connected (connection->transport); 3340 3341 _dbus_verbose ("dispatch status = %s is_connected = %d\n", 3342 DISPATCH_STATUS_NAME (status), is_connected); 3343 3344 if (!is_connected) 3345 { 3346 if (status == DBUS_DISPATCH_COMPLETE && 3347 connection->disconnect_message_link) 3348 { 3349 _dbus_verbose ("Sending disconnect message from %s\n", 3350 _DBUS_FUNCTION_NAME); 3351 3352 connection_forget_shared_unlocked (connection); 3353 3354 /* We haven't sent the disconnect message already, 3355 * and all real messages have been queued up. 3356 */ 3357 _dbus_connection_queue_synthesized_message_link (connection, 3358 connection->disconnect_message_link); 3359 connection->disconnect_message_link = NULL; 3360 3361 status = DBUS_DISPATCH_DATA_REMAINS; 3362 } 3363 3364 /* Dump the outgoing queue, we aren't going to be able to 3365 * send it now, and we'd like accessors like 3366 * dbus_connection_get_outgoing_size() to be accurate. 3367 */ 3368 if (connection->n_outgoing > 0) 3369 { 3370 DBusList *link; 3371 3372 _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n", 3373 connection->n_outgoing); 3374 3375 while ((link = _dbus_list_get_last_link (&connection->outgoing_messages))) 3376 { 3377 _dbus_connection_message_sent (connection, link->data); 3378 } 3379 } 3380 } 3381 3382 if (status != DBUS_DISPATCH_COMPLETE) 3383 return status; 3384 else if (connection->n_incoming > 0) 3385 return DBUS_DISPATCH_DATA_REMAINS; 3386 else 3387 return DBUS_DISPATCH_COMPLETE; 3388 } 3389} 3390 3391static void 3392_dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection, 3393 DBusDispatchStatus new_status) 3394{ 3395 dbus_bool_t changed; 3396 DBusDispatchStatusFunction function; 3397 void *data; 3398 3399 HAVE_LOCK_CHECK (connection); 3400 3401 _dbus_connection_ref_unlocked (connection); 3402 3403 changed = new_status != connection->last_dispatch_status; 3404 3405 connection->last_dispatch_status = new_status; 3406 3407 function = connection->dispatch_status_function; 3408 data = connection->dispatch_status_data; 3409 3410 /* We drop the lock */ 3411 CONNECTION_UNLOCK (connection); 3412 3413 if (changed && function) 3414 { 3415 _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n", 3416 connection, new_status, 3417 DISPATCH_STATUS_NAME (new_status)); 3418 (* function) (connection, new_status, data); 3419 } 3420 3421 dbus_connection_unref (connection); 3422} 3423 3424/** 3425 * Gets the current state (what we would currently return 3426 * from dbus_connection_dispatch()) but doesn't actually 3427 * dispatch any messages. 3428 * 3429 * @param connection the connection. 3430 * @returns current dispatch status 3431 */ 3432DBusDispatchStatus 3433dbus_connection_get_dispatch_status (DBusConnection *connection) 3434{ 3435 DBusDispatchStatus status; 3436 3437 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE); 3438 3439 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME); 3440 3441 CONNECTION_LOCK (connection); 3442 3443 status = _dbus_connection_get_dispatch_status_unlocked (connection); 3444 3445 CONNECTION_UNLOCK (connection); 3446 3447 return status; 3448} 3449 3450/** 3451* Filter funtion for handling the Peer standard interface 3452**/ 3453static DBusHandlerResult 3454_dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection, 3455 DBusMessage *message) 3456{ 3457 if (dbus_message_is_method_call (message, 3458 DBUS_INTERFACE_PEER, 3459 "Ping")) 3460 { 3461 DBusMessage *ret; 3462 dbus_bool_t sent; 3463 3464 ret = dbus_message_new_method_return (message); 3465 if (ret == NULL) 3466 return DBUS_HANDLER_RESULT_NEED_MEMORY; 3467 3468 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL); 3469 3470 dbus_message_unref (ret); 3471 3472 if (!sent) 3473 return DBUS_HANDLER_RESULT_NEED_MEMORY; 3474 3475 return DBUS_HANDLER_RESULT_HANDLED; 3476 } 3477 3478 3479 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 3480} 3481 3482/** 3483* Processes all builtin filter functions 3484* 3485* If the spec specifies a standard interface 3486* they should be processed from this method 3487**/ 3488static DBusHandlerResult 3489_dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection, 3490 DBusMessage *message) 3491{ 3492 /* We just run one filter for now but have the option to run more 3493 if the spec calls for it in the future */ 3494 3495 return _dbus_connection_peer_filter_unlocked_no_update (connection, message); 3496} 3497 3498/** 3499 * Processes data buffered while handling watches, queueing zero or 3500 * more incoming messages. Then pops the first-received message from 3501 * the current incoming message queue, runs any handlers for it, and 3502 * unrefs the message. Returns a status indicating whether messages/data 3503 * remain, more memory is needed, or all data has been processed. 3504 * 3505 * Even if the dispatch status is #DBUS_DISPATCH_DATA_REMAINS, 3506 * does not necessarily dispatch a message, as the data may 3507 * be part of authentication or the like. 3508 * 3509 * @todo some FIXME in here about handling DBUS_HANDLER_RESULT_NEED_MEMORY 3510 * 3511 * @todo FIXME what if we call out to application code to handle a 3512 * message, holding the dispatch lock, and the application code runs 3513 * the main loop and dispatches again? Probably deadlocks at the 3514 * moment. Maybe we want a dispatch status of DBUS_DISPATCH_IN_PROGRESS, 3515 * and then the GSource etc. could handle the situation? Right now 3516 * our GSource is NO_RECURSE 3517 * 3518 * @param connection the connection 3519 * @returns dispatch status 3520 */ 3521DBusDispatchStatus 3522dbus_connection_dispatch (DBusConnection *connection) 3523{ 3524 DBusMessage *message; 3525 DBusList *link, *filter_list_copy, *message_link; 3526 DBusHandlerResult result; 3527 DBusPendingCall *pending; 3528 dbus_int32_t reply_serial; 3529 DBusDispatchStatus status; 3530 3531 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE); 3532 3533 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME); 3534 3535 CONNECTION_LOCK (connection); 3536 status = _dbus_connection_get_dispatch_status_unlocked (connection); 3537 if (status != DBUS_DISPATCH_DATA_REMAINS) 3538 { 3539 /* unlocks and calls out to user code */ 3540 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 3541 return status; 3542 } 3543 3544 /* We need to ref the connection since the callback could potentially 3545 * drop the last ref to it 3546 */ 3547 _dbus_connection_ref_unlocked (connection); 3548 3549 _dbus_connection_acquire_dispatch (connection); 3550 HAVE_LOCK_CHECK (connection); 3551 3552 message_link = _dbus_connection_pop_message_link_unlocked (connection); 3553 if (message_link == NULL) 3554 { 3555 /* another thread dispatched our stuff */ 3556 3557 _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n"); 3558 3559 _dbus_connection_release_dispatch (connection); 3560 3561 status = _dbus_connection_get_dispatch_status_unlocked (connection); 3562 3563 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 3564 3565 dbus_connection_unref (connection); 3566 3567 return status; 3568 } 3569 3570 message = message_link->data; 3571 3572 _dbus_verbose (" dispatching message %p (%d %s %s '%s')\n", 3573 message, 3574 dbus_message_get_type (message), 3575 dbus_message_get_interface (message) ? 3576 dbus_message_get_interface (message) : 3577 "no interface", 3578 dbus_message_get_member (message) ? 3579 dbus_message_get_member (message) : 3580 "no member", 3581 dbus_message_get_signature (message)); 3582 3583 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 3584 3585 /* Pending call handling must be first, because if you do 3586 * dbus_connection_send_with_reply_and_block() or 3587 * dbus_pending_call_block() then no handlers/filters will be run on 3588 * the reply. We want consistent semantics in the case where we 3589 * dbus_connection_dispatch() the reply. 3590 */ 3591 3592 reply_serial = dbus_message_get_reply_serial (message); 3593 pending = _dbus_hash_table_lookup_int (connection->pending_replies, 3594 reply_serial); 3595 if (pending) 3596 { 3597 _dbus_verbose ("Dispatching a pending reply\n"); 3598 _dbus_pending_call_complete_and_unlock (pending, message); 3599 pending = NULL; /* it's probably unref'd */ 3600 3601 CONNECTION_LOCK (connection); 3602 _dbus_verbose ("pending call completed in dispatch\n"); 3603 result = DBUS_HANDLER_RESULT_HANDLED; 3604 goto out; 3605 } 3606 3607 result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message); 3608 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED) 3609 goto out; 3610 3611 if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy)) 3612 { 3613 _dbus_connection_release_dispatch (connection); 3614 HAVE_LOCK_CHECK (connection); 3615 3616 _dbus_connection_failed_pop (connection, message_link); 3617 3618 /* unlocks and calls user code */ 3619 _dbus_connection_update_dispatch_status_and_unlock (connection, 3620 DBUS_DISPATCH_NEED_MEMORY); 3621 3622 if (pending) 3623 dbus_pending_call_unref (pending); 3624 dbus_connection_unref (connection); 3625 3626 return DBUS_DISPATCH_NEED_MEMORY; 3627 } 3628 3629 _dbus_list_foreach (&filter_list_copy, 3630 (DBusForeachFunction)_dbus_message_filter_ref, 3631 NULL); 3632 3633 /* We're still protected from dispatch() reentrancy here 3634 * since we acquired the dispatcher 3635 */ 3636 CONNECTION_UNLOCK (connection); 3637 3638 link = _dbus_list_get_first_link (&filter_list_copy); 3639 while (link != NULL) 3640 { 3641 DBusMessageFilter *filter = link->data; 3642 DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link); 3643 3644 _dbus_verbose (" running filter on message %p\n", message); 3645 result = (* filter->function) (connection, message, filter->user_data); 3646 3647 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED) 3648 break; 3649 3650 link = next; 3651 } 3652 3653 _dbus_list_foreach (&filter_list_copy, 3654 (DBusForeachFunction)_dbus_message_filter_unref, 3655 NULL); 3656 _dbus_list_clear (&filter_list_copy); 3657 3658 CONNECTION_LOCK (connection); 3659 3660 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY) 3661 { 3662 _dbus_verbose ("No memory in %s\n", _DBUS_FUNCTION_NAME); 3663 goto out; 3664 } 3665 else if (result == DBUS_HANDLER_RESULT_HANDLED) 3666 { 3667 _dbus_verbose ("filter handled message in dispatch\n"); 3668 goto out; 3669 } 3670 3671 /* We're still protected from dispatch() reentrancy here 3672 * since we acquired the dispatcher 3673 */ 3674 _dbus_verbose (" running object path dispatch on message %p (%d %s %s '%s')\n", 3675 message, 3676 dbus_message_get_type (message), 3677 dbus_message_get_interface (message) ? 3678 dbus_message_get_interface (message) : 3679 "no interface", 3680 dbus_message_get_member (message) ? 3681 dbus_message_get_member (message) : 3682 "no member", 3683 dbus_message_get_signature (message)); 3684 3685 HAVE_LOCK_CHECK (connection); 3686 result = _dbus_object_tree_dispatch_and_unlock (connection->objects, 3687 message); 3688 3689 CONNECTION_LOCK (connection); 3690 3691 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED) 3692 { 3693 _dbus_verbose ("object tree handled message in dispatch\n"); 3694 goto out; 3695 } 3696 3697 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL) 3698 { 3699 DBusMessage *reply; 3700 DBusString str; 3701 DBusPreallocatedSend *preallocated; 3702 3703 _dbus_verbose (" sending error %s\n", 3704 DBUS_ERROR_UNKNOWN_METHOD); 3705 3706 if (!_dbus_string_init (&str)) 3707 { 3708 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 3709 _dbus_verbose ("no memory for error string in dispatch\n"); 3710 goto out; 3711 } 3712 3713 if (!_dbus_string_append_printf (&str, 3714 "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n", 3715 dbus_message_get_member (message), 3716 dbus_message_get_signature (message), 3717 dbus_message_get_interface (message))) 3718 { 3719 _dbus_string_free (&str); 3720 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 3721 _dbus_verbose ("no memory for error string in dispatch\n"); 3722 goto out; 3723 } 3724 3725 reply = dbus_message_new_error (message, 3726 DBUS_ERROR_UNKNOWN_METHOD, 3727 _dbus_string_get_const_data (&str)); 3728 _dbus_string_free (&str); 3729 3730 if (reply == NULL) 3731 { 3732 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 3733 _dbus_verbose ("no memory for error reply in dispatch\n"); 3734 goto out; 3735 } 3736 3737 preallocated = _dbus_connection_preallocate_send_unlocked (connection); 3738 3739 if (preallocated == NULL) 3740 { 3741 dbus_message_unref (reply); 3742 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 3743 _dbus_verbose ("no memory for error send in dispatch\n"); 3744 goto out; 3745 } 3746 3747 _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated, 3748 reply, NULL); 3749 3750 dbus_message_unref (reply); 3751 3752 result = DBUS_HANDLER_RESULT_HANDLED; 3753 } 3754 3755 _dbus_verbose (" done dispatching %p (%d %s %s '%s') on connection %p\n", message, 3756 dbus_message_get_type (message), 3757 dbus_message_get_interface (message) ? 3758 dbus_message_get_interface (message) : 3759 "no interface", 3760 dbus_message_get_member (message) ? 3761 dbus_message_get_member (message) : 3762 "no member", 3763 dbus_message_get_signature (message), 3764 connection); 3765 3766 out: 3767 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY) 3768 { 3769 _dbus_verbose ("out of memory in %s\n", _DBUS_FUNCTION_NAME); 3770 3771 /* Put message back, and we'll start over. 3772 * Yes this means handlers must be idempotent if they 3773 * don't return HANDLED; c'est la vie. 3774 */ 3775 _dbus_connection_putback_message_link_unlocked (connection, 3776 message_link); 3777 } 3778 else 3779 { 3780 _dbus_verbose (" ... done dispatching in %s\n", _DBUS_FUNCTION_NAME); 3781 3782 if (connection->exit_on_disconnect && 3783 dbus_message_is_signal (message, 3784 DBUS_INTERFACE_LOCAL, 3785 "Disconnected")) 3786 { 3787 _dbus_verbose ("Exiting on Disconnected signal\n"); 3788 CONNECTION_UNLOCK (connection); 3789 _dbus_exit (1); 3790 _dbus_assert_not_reached ("Call to exit() returned"); 3791 } 3792 3793 _dbus_list_free_link (message_link); 3794 dbus_message_unref (message); /* don't want the message to count in max message limits 3795 * in computing dispatch status below 3796 */ 3797 } 3798 3799 _dbus_connection_release_dispatch (connection); 3800 HAVE_LOCK_CHECK (connection); 3801 3802 _dbus_verbose ("%s before final status update\n", _DBUS_FUNCTION_NAME); 3803 status = _dbus_connection_get_dispatch_status_unlocked (connection); 3804 3805 /* unlocks and calls user code */ 3806 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 3807 3808 dbus_connection_unref (connection); 3809 3810 return status; 3811} 3812 3813/** 3814 * Sets the watch functions for the connection. These functions are 3815 * responsible for making the application's main loop aware of file 3816 * descriptors that need to be monitored for events, using select() or 3817 * poll(). When using Qt, typically the DBusAddWatchFunction would 3818 * create a QSocketNotifier. When using GLib, the DBusAddWatchFunction 3819 * could call g_io_add_watch(), or could be used as part of a more 3820 * elaborate GSource. Note that when a watch is added, it may 3821 * not be enabled. 3822 * 3823 * The DBusWatchToggledFunction notifies the application that the 3824 * watch has been enabled or disabled. Call dbus_watch_get_enabled() 3825 * to check this. A disabled watch should have no effect, and enabled 3826 * watch should be added to the main loop. This feature is used 3827 * instead of simply adding/removing the watch because 3828 * enabling/disabling can be done without memory allocation. The 3829 * toggled function may be NULL if a main loop re-queries 3830 * dbus_watch_get_enabled() every time anyway. 3831 * 3832 * The DBusWatch can be queried for the file descriptor to watch using 3833 * dbus_watch_get_fd(), and for the events to watch for using 3834 * dbus_watch_get_flags(). The flags returned by 3835 * dbus_watch_get_flags() will only contain DBUS_WATCH_READABLE and 3836 * DBUS_WATCH_WRITABLE, never DBUS_WATCH_HANGUP or DBUS_WATCH_ERROR; 3837 * all watches implicitly include a watch for hangups, errors, and 3838 * other exceptional conditions. 3839 * 3840 * Once a file descriptor becomes readable or writable, or an exception 3841 * occurs, dbus_watch_handle() should be called to 3842 * notify the connection of the file descriptor's condition. 3843 * 3844 * dbus_watch_handle() cannot be called during the 3845 * DBusAddWatchFunction, as the connection will not be ready to handle 3846 * that watch yet. 3847 * 3848 * It is not allowed to reference a DBusWatch after it has been passed 3849 * to remove_function. 3850 * 3851 * If #FALSE is returned due to lack of memory, the failure may be due 3852 * to a #FALSE return from the new add_function. If so, the 3853 * add_function may have been called successfully one or more times, 3854 * but the remove_function will also have been called to remove any 3855 * successful adds. i.e. if #FALSE is returned the net result 3856 * should be that dbus_connection_set_watch_functions() has no effect, 3857 * but the add_function and remove_function may have been called. 3858 * 3859 * @todo We need to drop the lock when we call the 3860 * add/remove/toggled functions which can be a side effect 3861 * of setting the watch functions. 3862 * 3863 * @param connection the connection. 3864 * @param add_function function to begin monitoring a new descriptor. 3865 * @param remove_function function to stop monitoring a descriptor. 3866 * @param toggled_function function to notify of enable/disable 3867 * @param data data to pass to add_function and remove_function. 3868 * @param free_data_function function to be called to free the data. 3869 * @returns #FALSE on failure (no memory) 3870 */ 3871dbus_bool_t 3872dbus_connection_set_watch_functions (DBusConnection *connection, 3873 DBusAddWatchFunction add_function, 3874 DBusRemoveWatchFunction remove_function, 3875 DBusWatchToggledFunction toggled_function, 3876 void *data, 3877 DBusFreeFunction free_data_function) 3878{ 3879 dbus_bool_t retval; 3880 DBusWatchList *watches; 3881 3882 _dbus_return_val_if_fail (connection != NULL, FALSE); 3883 3884 CONNECTION_LOCK (connection); 3885 3886#ifndef DBUS_DISABLE_CHECKS 3887 if (connection->watches == NULL) 3888 { 3889 _dbus_warn ("Re-entrant call to %s is not allowed\n", 3890 _DBUS_FUNCTION_NAME); 3891 return FALSE; 3892 } 3893#endif 3894 3895 /* ref connection for slightly better reentrancy */ 3896 _dbus_connection_ref_unlocked (connection); 3897 3898 /* This can call back into user code, and we need to drop the 3899 * connection lock when it does. This is kind of a lame 3900 * way to do it. 3901 */ 3902 watches = connection->watches; 3903 connection->watches = NULL; 3904 CONNECTION_UNLOCK (connection); 3905 3906 retval = _dbus_watch_list_set_functions (watches, 3907 add_function, remove_function, 3908 toggled_function, 3909 data, free_data_function); 3910 CONNECTION_LOCK (connection); 3911 connection->watches = watches; 3912 3913 CONNECTION_UNLOCK (connection); 3914 /* drop our paranoid refcount */ 3915 dbus_connection_unref (connection); 3916 3917 return retval; 3918} 3919 3920/** 3921 * Sets the timeout functions for the connection. These functions are 3922 * responsible for making the application's main loop aware of timeouts. 3923 * When using Qt, typically the DBusAddTimeoutFunction would create a 3924 * QTimer. When using GLib, the DBusAddTimeoutFunction would call 3925 * g_timeout_add. 3926 * 3927 * The DBusTimeoutToggledFunction notifies the application that the 3928 * timeout has been enabled or disabled. Call 3929 * dbus_timeout_get_enabled() to check this. A disabled timeout should 3930 * have no effect, and enabled timeout should be added to the main 3931 * loop. This feature is used instead of simply adding/removing the 3932 * timeout because enabling/disabling can be done without memory 3933 * allocation. With Qt, QTimer::start() and QTimer::stop() can be used 3934 * to enable and disable. The toggled function may be NULL if a main 3935 * loop re-queries dbus_timeout_get_enabled() every time anyway. 3936 * Whenever a timeout is toggled, its interval may change. 3937 * 3938 * The DBusTimeout can be queried for the timer interval using 3939 * dbus_timeout_get_interval(). dbus_timeout_handle() should be called 3940 * repeatedly, each time the interval elapses, starting after it has 3941 * elapsed once. The timeout stops firing when it is removed with the 3942 * given remove_function. The timer interval may change whenever the 3943 * timeout is added, removed, or toggled. 3944 * 3945 * @param connection the connection. 3946 * @param add_function function to add a timeout. 3947 * @param remove_function function to remove a timeout. 3948 * @param toggled_function function to notify of enable/disable 3949 * @param data data to pass to add_function and remove_function. 3950 * @param free_data_function function to be called to free the data. 3951 * @returns #FALSE on failure (no memory) 3952 */ 3953dbus_bool_t 3954dbus_connection_set_timeout_functions (DBusConnection *connection, 3955 DBusAddTimeoutFunction add_function, 3956 DBusRemoveTimeoutFunction remove_function, 3957 DBusTimeoutToggledFunction toggled_function, 3958 void *data, 3959 DBusFreeFunction free_data_function) 3960{ 3961 dbus_bool_t retval; 3962 DBusTimeoutList *timeouts; 3963 3964 _dbus_return_val_if_fail (connection != NULL, FALSE); 3965 3966 CONNECTION_LOCK (connection); 3967 3968#ifndef DBUS_DISABLE_CHECKS 3969 if (connection->timeouts == NULL) 3970 { 3971 _dbus_warn ("Re-entrant call to %s is not allowed\n", 3972 _DBUS_FUNCTION_NAME); 3973 return FALSE; 3974 } 3975#endif 3976 3977 /* ref connection for slightly better reentrancy */ 3978 _dbus_connection_ref_unlocked (connection); 3979 3980 timeouts = connection->timeouts; 3981 connection->timeouts = NULL; 3982 CONNECTION_UNLOCK (connection); 3983 3984 retval = _dbus_timeout_list_set_functions (timeouts, 3985 add_function, remove_function, 3986 toggled_function, 3987 data, free_data_function); 3988 CONNECTION_LOCK (connection); 3989 connection->timeouts = timeouts; 3990 3991 CONNECTION_UNLOCK (connection); 3992 /* drop our paranoid refcount */ 3993 dbus_connection_unref (connection); 3994 3995 return retval; 3996} 3997 3998/** 3999 * Sets the mainloop wakeup function for the connection. This function is 4000 * responsible for waking up the main loop (if its sleeping) when some some 4001 * change has happened to the connection that the mainloop needs to reconsider 4002 * (e.g. a message has been queued for writing). 4003 * When using Qt, this typically results in a call to QEventLoop::wakeUp(). 4004 * When using GLib, it would call g_main_context_wakeup(). 4005 * 4006 * 4007 * @param connection the connection. 4008 * @param wakeup_main_function function to wake up the mainloop 4009 * @param data data to pass wakeup_main_function 4010 * @param free_data_function function to be called to free the data. 4011 */ 4012void 4013dbus_connection_set_wakeup_main_function (DBusConnection *connection, 4014 DBusWakeupMainFunction wakeup_main_function, 4015 void *data, 4016 DBusFreeFunction free_data_function) 4017{ 4018 void *old_data; 4019 DBusFreeFunction old_free_data; 4020 4021 _dbus_return_if_fail (connection != NULL); 4022 4023 CONNECTION_LOCK (connection); 4024 old_data = connection->wakeup_main_data; 4025 old_free_data = connection->free_wakeup_main_data; 4026 4027 connection->wakeup_main_function = wakeup_main_function; 4028 connection->wakeup_main_data = data; 4029 connection->free_wakeup_main_data = free_data_function; 4030 4031 CONNECTION_UNLOCK (connection); 4032 4033 /* Callback outside the lock */ 4034 if (old_free_data) 4035 (*old_free_data) (old_data); 4036} 4037 4038/** 4039 * Set a function to be invoked when the dispatch status changes. 4040 * If the dispatch status is #DBUS_DISPATCH_DATA_REMAINS, then 4041 * dbus_connection_dispatch() needs to be called to process incoming 4042 * messages. However, dbus_connection_dispatch() MUST NOT BE CALLED 4043 * from inside the DBusDispatchStatusFunction. Indeed, almost 4044 * any reentrancy in this function is a bad idea. Instead, 4045 * the DBusDispatchStatusFunction should simply save an indication 4046 * that messages should be dispatched later, when the main loop 4047 * is re-entered. 4048 * 4049 * @param connection the connection 4050 * @param function function to call on dispatch status changes 4051 * @param data data for function 4052 * @param free_data_function free the function data 4053 */ 4054void 4055dbus_connection_set_dispatch_status_function (DBusConnection *connection, 4056 DBusDispatchStatusFunction function, 4057 void *data, 4058 DBusFreeFunction free_data_function) 4059{ 4060 void *old_data; 4061 DBusFreeFunction old_free_data; 4062 4063 _dbus_return_if_fail (connection != NULL); 4064 4065 CONNECTION_LOCK (connection); 4066 old_data = connection->dispatch_status_data; 4067 old_free_data = connection->free_dispatch_status_data; 4068 4069 connection->dispatch_status_function = function; 4070 connection->dispatch_status_data = data; 4071 connection->free_dispatch_status_data = free_data_function; 4072 4073 CONNECTION_UNLOCK (connection); 4074 4075 /* Callback outside the lock */ 4076 if (old_free_data) 4077 (*old_free_data) (old_data); 4078} 4079 4080/** 4081 * Get the UNIX file descriptor of the connection, if any. This can 4082 * be used for SELinux access control checks with getpeercon() for 4083 * example. DO NOT read or write to the file descriptor, or try to 4084 * select() on it; use DBusWatch for main loop integration. Not all 4085 * connections will have a file descriptor. So for adding descriptors 4086 * to the main loop, use dbus_watch_get_fd() and so forth. 4087 * 4088 * @param connection the connection 4089 * @param fd return location for the file descriptor. 4090 * @returns #TRUE if fd is successfully obtained. 4091 */ 4092dbus_bool_t 4093dbus_connection_get_unix_fd (DBusConnection *connection, 4094 int *fd) 4095{ 4096 dbus_bool_t retval; 4097 4098 _dbus_return_val_if_fail (connection != NULL, FALSE); 4099 _dbus_return_val_if_fail (connection->transport != NULL, FALSE); 4100 4101 CONNECTION_LOCK (connection); 4102 4103 retval = _dbus_transport_get_unix_fd (connection->transport, 4104 fd); 4105 4106 CONNECTION_UNLOCK (connection); 4107 4108 return retval; 4109} 4110 4111/** 4112 * Gets the UNIX user ID of the connection if any. 4113 * Returns #TRUE if the uid is filled in. 4114 * Always returns #FALSE on non-UNIX platforms. 4115 * Always returns #FALSE prior to authenticating the 4116 * connection. 4117 * 4118 * @param connection the connection 4119 * @param uid return location for the user ID 4120 * @returns #TRUE if uid is filled in with a valid user ID 4121 */ 4122dbus_bool_t 4123dbus_connection_get_unix_user (DBusConnection *connection, 4124 unsigned long *uid) 4125{ 4126 dbus_bool_t result; 4127 4128 _dbus_return_val_if_fail (connection != NULL, FALSE); 4129 _dbus_return_val_if_fail (uid != NULL, FALSE); 4130 4131 CONNECTION_LOCK (connection); 4132 4133 if (!_dbus_transport_get_is_authenticated (connection->transport)) 4134 result = FALSE; 4135 else 4136 result = _dbus_transport_get_unix_user (connection->transport, 4137 uid); 4138 CONNECTION_UNLOCK (connection); 4139 4140 return result; 4141} 4142 4143/** 4144 * Gets the process ID of the connection if any. 4145 * Returns #TRUE if the uid is filled in. 4146 * Always returns #FALSE prior to authenticating the 4147 * connection. 4148 * 4149 * @param connection the connection 4150 * @param pid return location for the process ID 4151 * @returns #TRUE if uid is filled in with a valid process ID 4152 */ 4153dbus_bool_t 4154dbus_connection_get_unix_process_id (DBusConnection *connection, 4155 unsigned long *pid) 4156{ 4157 dbus_bool_t result; 4158 4159 _dbus_return_val_if_fail (connection != NULL, FALSE); 4160 _dbus_return_val_if_fail (pid != NULL, FALSE); 4161 4162 CONNECTION_LOCK (connection); 4163 4164 if (!_dbus_transport_get_is_authenticated (connection->transport)) 4165 result = FALSE; 4166 else 4167 result = _dbus_transport_get_unix_process_id (connection->transport, 4168 pid); 4169 CONNECTION_UNLOCK (connection); 4170 4171 return result; 4172} 4173 4174/** 4175 * Sets a predicate function used to determine whether a given user ID 4176 * is allowed to connect. When an incoming connection has 4177 * authenticated with a particular user ID, this function is called; 4178 * if it returns #TRUE, the connection is allowed to proceed, 4179 * otherwise the connection is disconnected. 4180 * 4181 * If the function is set to #NULL (as it is by default), then 4182 * only the same UID as the server process will be allowed to 4183 * connect. 4184 * 4185 * @param connection the connection 4186 * @param function the predicate 4187 * @param data data to pass to the predicate 4188 * @param free_data_function function to free the data 4189 */ 4190void 4191dbus_connection_set_unix_user_function (DBusConnection *connection, 4192 DBusAllowUnixUserFunction function, 4193 void *data, 4194 DBusFreeFunction free_data_function) 4195{ 4196 void *old_data = NULL; 4197 DBusFreeFunction old_free_function = NULL; 4198 4199 _dbus_return_if_fail (connection != NULL); 4200 4201 CONNECTION_LOCK (connection); 4202 _dbus_transport_set_unix_user_function (connection->transport, 4203 function, data, free_data_function, 4204 &old_data, &old_free_function); 4205 CONNECTION_UNLOCK (connection); 4206 4207 if (old_free_function != NULL) 4208 (* old_free_function) (old_data); 4209} 4210 4211/** 4212 * Adds a message filter. Filters are handlers that are run on all 4213 * incoming messages, prior to the objects registered with 4214 * dbus_connection_register_object_path(). Filters are run in the 4215 * order that they were added. The same handler can be added as a 4216 * filter more than once, in which case it will be run more than once. 4217 * Filters added during a filter callback won't be run on the message 4218 * being processed. 4219 * 4220 * @todo we don't run filters on messages while blocking without 4221 * entering the main loop, since filters are run as part of 4222 * dbus_connection_dispatch(). This is probably a feature, as filters 4223 * could create arbitrary reentrancy. But kind of sucks if you're 4224 * trying to filter METHOD_RETURN for some reason. 4225 * 4226 * @param connection the connection 4227 * @param function function to handle messages 4228 * @param user_data user data to pass to the function 4229 * @param free_data_function function to use for freeing user data 4230 * @returns #TRUE on success, #FALSE if not enough memory. 4231 */ 4232dbus_bool_t 4233dbus_connection_add_filter (DBusConnection *connection, 4234 DBusHandleMessageFunction function, 4235 void *user_data, 4236 DBusFreeFunction free_data_function) 4237{ 4238 DBusMessageFilter *filter; 4239 4240 _dbus_return_val_if_fail (connection != NULL, FALSE); 4241 _dbus_return_val_if_fail (function != NULL, FALSE); 4242 4243 filter = dbus_new0 (DBusMessageFilter, 1); 4244 if (filter == NULL) 4245 return FALSE; 4246 4247 filter->refcount.value = 1; 4248 4249 CONNECTION_LOCK (connection); 4250 4251 if (!_dbus_list_append (&connection->filter_list, 4252 filter)) 4253 { 4254 _dbus_message_filter_unref (filter); 4255 CONNECTION_UNLOCK (connection); 4256 return FALSE; 4257 } 4258 4259 /* Fill in filter after all memory allocated, 4260 * so we don't run the free_user_data_function 4261 * if the add_filter() fails 4262 */ 4263 4264 filter->function = function; 4265 filter->user_data = user_data; 4266 filter->free_user_data_function = free_data_function; 4267 4268 CONNECTION_UNLOCK (connection); 4269 return TRUE; 4270} 4271 4272/** 4273 * Removes a previously-added message filter. It is a programming 4274 * error to call this function for a handler that has not been added 4275 * as a filter. If the given handler was added more than once, only 4276 * one instance of it will be removed (the most recently-added 4277 * instance). 4278 * 4279 * @param connection the connection 4280 * @param function the handler to remove 4281 * @param user_data user data for the handler to remove 4282 * 4283 */ 4284void 4285dbus_connection_remove_filter (DBusConnection *connection, 4286 DBusHandleMessageFunction function, 4287 void *user_data) 4288{ 4289 DBusList *link; 4290 DBusMessageFilter *filter; 4291 4292 _dbus_return_if_fail (connection != NULL); 4293 _dbus_return_if_fail (function != NULL); 4294 4295 CONNECTION_LOCK (connection); 4296 4297 filter = NULL; 4298 4299 link = _dbus_list_get_last_link (&connection->filter_list); 4300 while (link != NULL) 4301 { 4302 filter = link->data; 4303 4304 if (filter->function == function && 4305 filter->user_data == user_data) 4306 { 4307 _dbus_list_remove_link (&connection->filter_list, link); 4308 filter->function = NULL; 4309 4310 break; 4311 } 4312 4313 link = _dbus_list_get_prev_link (&connection->filter_list, link); 4314 } 4315 4316 CONNECTION_UNLOCK (connection); 4317 4318#ifndef DBUS_DISABLE_CHECKS 4319 if (filter == NULL) 4320 { 4321 _dbus_warn ("Attempt to remove filter function %p user data %p, but no such filter has been added\n", 4322 function, user_data); 4323 return; 4324 } 4325#endif 4326 4327 /* Call application code */ 4328 if (filter->free_user_data_function) 4329 (* filter->free_user_data_function) (filter->user_data); 4330 4331 filter->free_user_data_function = NULL; 4332 filter->user_data = NULL; 4333 4334 _dbus_message_filter_unref (filter); 4335} 4336 4337/** 4338 * Registers a handler for a given path in the object hierarchy. 4339 * The given vtable handles messages sent to exactly the given path. 4340 * 4341 * 4342 * @param connection the connection 4343 * @param path a '/' delimited string of path elements 4344 * @param vtable the virtual table 4345 * @param user_data data to pass to functions in the vtable 4346 * @returns #FALSE if not enough memory 4347 */ 4348dbus_bool_t 4349dbus_connection_register_object_path (DBusConnection *connection, 4350 const char *path, 4351 const DBusObjectPathVTable *vtable, 4352 void *user_data) 4353{ 4354 char **decomposed_path; 4355 dbus_bool_t retval; 4356 4357 _dbus_return_val_if_fail (connection != NULL, FALSE); 4358 _dbus_return_val_if_fail (path != NULL, FALSE); 4359 _dbus_return_val_if_fail (path[0] == '/', FALSE); 4360 _dbus_return_val_if_fail (vtable != NULL, FALSE); 4361 4362 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) 4363 return FALSE; 4364 4365 CONNECTION_LOCK (connection); 4366 4367 retval = _dbus_object_tree_register (connection->objects, 4368 FALSE, 4369 (const char **) decomposed_path, vtable, 4370 user_data); 4371 4372 CONNECTION_UNLOCK (connection); 4373 4374 dbus_free_string_array (decomposed_path); 4375 4376 return retval; 4377} 4378 4379/** 4380 * Registers a fallback handler for a given subsection of the object 4381 * hierarchy. The given vtable handles messages at or below the given 4382 * path. You can use this to establish a default message handling 4383 * policy for a whole "subdirectory." 4384 * 4385 * @param connection the connection 4386 * @param path a '/' delimited string of path elements 4387 * @param vtable the virtual table 4388 * @param user_data data to pass to functions in the vtable 4389 * @returns #FALSE if not enough memory 4390 */ 4391dbus_bool_t 4392dbus_connection_register_fallback (DBusConnection *connection, 4393 const char *path, 4394 const DBusObjectPathVTable *vtable, 4395 void *user_data) 4396{ 4397 char **decomposed_path; 4398 dbus_bool_t retval; 4399 4400 _dbus_return_val_if_fail (connection != NULL, FALSE); 4401 _dbus_return_val_if_fail (path != NULL, FALSE); 4402 _dbus_return_val_if_fail (path[0] == '/', FALSE); 4403 _dbus_return_val_if_fail (vtable != NULL, FALSE); 4404 4405 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) 4406 return FALSE; 4407 4408 CONNECTION_LOCK (connection); 4409 4410 retval = _dbus_object_tree_register (connection->objects, 4411 TRUE, 4412 (const char **) decomposed_path, vtable, 4413 user_data); 4414 4415 CONNECTION_UNLOCK (connection); 4416 4417 dbus_free_string_array (decomposed_path); 4418 4419 return retval; 4420} 4421 4422/** 4423 * Unregisters the handler registered with exactly the given path. 4424 * It's a bug to call this function for a path that isn't registered. 4425 * Can unregister both fallback paths and object paths. 4426 * 4427 * @param connection the connection 4428 * @param path a '/' delimited string of path elements 4429 * @returns #FALSE if not enough memory 4430 */ 4431dbus_bool_t 4432dbus_connection_unregister_object_path (DBusConnection *connection, 4433 const char *path) 4434{ 4435 char **decomposed_path; 4436 4437 _dbus_return_val_if_fail (connection != NULL, FALSE); 4438 _dbus_return_val_if_fail (path != NULL, FALSE); 4439 _dbus_return_val_if_fail (path[0] == '/', FALSE); 4440 4441 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) 4442 return FALSE; 4443 4444 CONNECTION_LOCK (connection); 4445 4446 _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path); 4447 4448 dbus_free_string_array (decomposed_path); 4449 4450 return TRUE; 4451} 4452 4453/** 4454 * Gets the user data passed to dbus_connection_register_object_path() 4455 * or dbus_connection_register_fallback(). If nothing was registered 4456 * at this path, the data is filled in with #NULL. 4457 * 4458 * @param connection the connection 4459 * @param path the path you registered with 4460 * @param data_p location to store the user data, or #NULL 4461 * @returns #FALSE if not enough memory 4462 */ 4463dbus_bool_t 4464dbus_connection_get_object_path_data (DBusConnection *connection, 4465 const char *path, 4466 void **data_p) 4467{ 4468 char **decomposed_path; 4469 4470 _dbus_return_val_if_fail (connection != NULL, FALSE); 4471 _dbus_return_val_if_fail (path != NULL, FALSE); 4472 _dbus_return_val_if_fail (data_p != NULL, FALSE); 4473 4474 *data_p = NULL; 4475 4476 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) 4477 return FALSE; 4478 4479 CONNECTION_LOCK (connection); 4480 4481 *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path); 4482 4483 CONNECTION_UNLOCK (connection); 4484 4485 dbus_free_string_array (decomposed_path); 4486 4487 return TRUE; 4488} 4489 4490/** 4491 * Lists the registered fallback handlers and object path handlers at 4492 * the given parent_path. The returned array should be freed with 4493 * dbus_free_string_array(). 4494 * 4495 * @param connection the connection 4496 * @param parent_path the path to list the child handlers of 4497 * @param child_entries returns #NULL-terminated array of children 4498 * @returns #FALSE if no memory to allocate the child entries 4499 */ 4500dbus_bool_t 4501dbus_connection_list_registered (DBusConnection *connection, 4502 const char *parent_path, 4503 char ***child_entries) 4504{ 4505 char **decomposed_path; 4506 dbus_bool_t retval; 4507 _dbus_return_val_if_fail (connection != NULL, FALSE); 4508 _dbus_return_val_if_fail (parent_path != NULL, FALSE); 4509 _dbus_return_val_if_fail (parent_path[0] == '/', FALSE); 4510 _dbus_return_val_if_fail (child_entries != NULL, FALSE); 4511 4512 if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL)) 4513 return FALSE; 4514 4515 CONNECTION_LOCK (connection); 4516 4517 retval = _dbus_object_tree_list_registered_and_unlock (connection->objects, 4518 (const char **) decomposed_path, 4519 child_entries); 4520 dbus_free_string_array (decomposed_path); 4521 4522 return retval; 4523} 4524 4525static DBusDataSlotAllocator slot_allocator; 4526_DBUS_DEFINE_GLOBAL_LOCK (connection_slots); 4527 4528/** 4529 * Allocates an integer ID to be used for storing application-specific 4530 * data on any DBusConnection. The allocated ID may then be used 4531 * with dbus_connection_set_data() and dbus_connection_get_data(). 4532 * The passed-in slot must be initialized to -1, and is filled in 4533 * with the slot ID. If the passed-in slot is not -1, it's assumed 4534 * to be already allocated, and its refcount is incremented. 4535 * 4536 * The allocated slot is global, i.e. all DBusConnection objects will 4537 * have a slot with the given integer ID reserved. 4538 * 4539 * @param slot_p address of a global variable storing the slot 4540 * @returns #FALSE on failure (no memory) 4541 */ 4542dbus_bool_t 4543dbus_connection_allocate_data_slot (dbus_int32_t *slot_p) 4544{ 4545 return _dbus_data_slot_allocator_alloc (&slot_allocator, 4546 _DBUS_LOCK_NAME (connection_slots), 4547 slot_p); 4548} 4549 4550/** 4551 * Deallocates a global ID for connection data slots. 4552 * dbus_connection_get_data() and dbus_connection_set_data() may no 4553 * longer be used with this slot. Existing data stored on existing 4554 * DBusConnection objects will be freed when the connection is 4555 * finalized, but may not be retrieved (and may only be replaced if 4556 * someone else reallocates the slot). When the refcount on the 4557 * passed-in slot reaches 0, it is set to -1. 4558 * 4559 * @param slot_p address storing the slot to deallocate 4560 */ 4561void 4562dbus_connection_free_data_slot (dbus_int32_t *slot_p) 4563{ 4564 _dbus_return_if_fail (*slot_p >= 0); 4565 4566 _dbus_data_slot_allocator_free (&slot_allocator, slot_p); 4567} 4568 4569/** 4570 * Stores a pointer on a DBusConnection, along 4571 * with an optional function to be used for freeing 4572 * the data when the data is set again, or when 4573 * the connection is finalized. The slot number 4574 * must have been allocated with dbus_connection_allocate_data_slot(). 4575 * 4576 * @param connection the connection 4577 * @param slot the slot number 4578 * @param data the data to store 4579 * @param free_data_func finalizer function for the data 4580 * @returns #TRUE if there was enough memory to store the data 4581 */ 4582dbus_bool_t 4583dbus_connection_set_data (DBusConnection *connection, 4584 dbus_int32_t slot, 4585 void *data, 4586 DBusFreeFunction free_data_func) 4587{ 4588 DBusFreeFunction old_free_func; 4589 void *old_data; 4590 dbus_bool_t retval; 4591 4592 _dbus_return_val_if_fail (connection != NULL, FALSE); 4593 _dbus_return_val_if_fail (slot >= 0, FALSE); 4594 4595 CONNECTION_LOCK (connection); 4596 4597 retval = _dbus_data_slot_list_set (&slot_allocator, 4598 &connection->slot_list, 4599 slot, data, free_data_func, 4600 &old_free_func, &old_data); 4601 4602 CONNECTION_UNLOCK (connection); 4603 4604 if (retval) 4605 { 4606 /* Do the actual free outside the connection lock */ 4607 if (old_free_func) 4608 (* old_free_func) (old_data); 4609 } 4610 4611 return retval; 4612} 4613 4614/** 4615 * Retrieves data previously set with dbus_connection_set_data(). 4616 * The slot must still be allocated (must not have been freed). 4617 * 4618 * @param connection the connection 4619 * @param slot the slot to get data from 4620 * @returns the data, or #NULL if not found 4621 */ 4622void* 4623dbus_connection_get_data (DBusConnection *connection, 4624 dbus_int32_t slot) 4625{ 4626 void *res; 4627 4628 _dbus_return_val_if_fail (connection != NULL, NULL); 4629 4630 CONNECTION_LOCK (connection); 4631 4632 res = _dbus_data_slot_list_get (&slot_allocator, 4633 &connection->slot_list, 4634 slot); 4635 4636 CONNECTION_UNLOCK (connection); 4637 4638 return res; 4639} 4640 4641/** 4642 * This function sets a global flag for whether dbus_connection_new() 4643 * will set SIGPIPE behavior to SIG_IGN. 4644 * 4645 * @param will_modify_sigpipe #TRUE to allow sigpipe to be set to SIG_IGN 4646 */ 4647void 4648dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe) 4649{ 4650 _dbus_modify_sigpipe = will_modify_sigpipe != FALSE; 4651} 4652 4653/** 4654 * Specifies the maximum size message this connection is allowed to 4655 * receive. Larger messages will result in disconnecting the 4656 * connection. 4657 * 4658 * @param connection a #DBusConnection 4659 * @param size maximum message size the connection can receive, in bytes 4660 */ 4661void 4662dbus_connection_set_max_message_size (DBusConnection *connection, 4663 long size) 4664{ 4665 _dbus_return_if_fail (connection != NULL); 4666 4667 CONNECTION_LOCK (connection); 4668 _dbus_transport_set_max_message_size (connection->transport, 4669 size); 4670 CONNECTION_UNLOCK (connection); 4671} 4672 4673/** 4674 * Gets the value set by dbus_connection_set_max_message_size(). 4675 * 4676 * @param connection the connection 4677 * @returns the max size of a single message 4678 */ 4679long 4680dbus_connection_get_max_message_size (DBusConnection *connection) 4681{ 4682 long res; 4683 4684 _dbus_return_val_if_fail (connection != NULL, 0); 4685 4686 CONNECTION_LOCK (connection); 4687 res = _dbus_transport_get_max_message_size (connection->transport); 4688 CONNECTION_UNLOCK (connection); 4689 return res; 4690} 4691 4692/** 4693 * Sets the maximum total number of bytes that can be used for all messages 4694 * received on this connection. Messages count toward the maximum until 4695 * they are finalized. When the maximum is reached, the connection will 4696 * not read more data until some messages are finalized. 4697 * 4698 * The semantics of the maximum are: if outstanding messages are 4699 * already above the maximum, additional messages will not be read. 4700 * The semantics are not: if the next message would cause us to exceed 4701 * the maximum, we don't read it. The reason is that we don't know the 4702 * size of a message until after we read it. 4703 * 4704 * Thus, the max live messages size can actually be exceeded 4705 * by up to the maximum size of a single message. 4706 * 4707 * Also, if we read say 1024 bytes off the wire in a single read(), 4708 * and that contains a half-dozen small messages, we may exceed the 4709 * size max by that amount. But this should be inconsequential. 4710 * 4711 * This does imply that we can't call read() with a buffer larger 4712 * than we're willing to exceed this limit by. 4713 * 4714 * @param connection the connection 4715 * @param size the maximum size in bytes of all outstanding messages 4716 */ 4717void 4718dbus_connection_set_max_received_size (DBusConnection *connection, 4719 long size) 4720{ 4721 _dbus_return_if_fail (connection != NULL); 4722 4723 CONNECTION_LOCK (connection); 4724 _dbus_transport_set_max_received_size (connection->transport, 4725 size); 4726 CONNECTION_UNLOCK (connection); 4727} 4728 4729/** 4730 * Gets the value set by dbus_connection_set_max_received_size(). 4731 * 4732 * @param connection the connection 4733 * @returns the max size of all live messages 4734 */ 4735long 4736dbus_connection_get_max_received_size (DBusConnection *connection) 4737{ 4738 long res; 4739 4740 _dbus_return_val_if_fail (connection != NULL, 0); 4741 4742 CONNECTION_LOCK (connection); 4743 res = _dbus_transport_get_max_received_size (connection->transport); 4744 CONNECTION_UNLOCK (connection); 4745 return res; 4746} 4747 4748/** 4749 * Gets the approximate size in bytes of all messages in the outgoing 4750 * message queue. The size is approximate in that you shouldn't use 4751 * it to decide how many bytes to read off the network or anything 4752 * of that nature, as optimizations may choose to tell small white lies 4753 * to avoid performance overhead. 4754 * 4755 * @param connection the connection 4756 * @returns the number of bytes that have been queued up but not sent 4757 */ 4758long 4759dbus_connection_get_outgoing_size (DBusConnection *connection) 4760{ 4761 long res; 4762 4763 _dbus_return_val_if_fail (connection != NULL, 0); 4764 4765 CONNECTION_LOCK (connection); 4766 res = _dbus_counter_get_value (connection->outgoing_counter); 4767 CONNECTION_UNLOCK (connection); 4768 return res; 4769} 4770 4771/** @} */ 4772