dbus-connection.c revision d96c9e465abb291cb943a1b4ec3643de4b3f6423
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 (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_interface (message) ? 396 dbus_message_get_interface (message) : 397 "no interface", 398 dbus_message_get_member (message) ? 399 dbus_message_get_member (message) : 400 "no member", 401 dbus_message_get_signature (message), 402 dbus_message_get_reply_serial (message), 403 connection, 404 connection->n_incoming); 405} 406 407/** 408 * Adds a link + message to the incoming message queue. 409 * Can't fail. Takes ownership of both link and message. 410 * 411 * @param connection the connection. 412 * @param link the list node and message to queue. 413 * 414 * @todo This needs to wake up the mainloop if it is in 415 * a poll/select and this is a multithreaded app. 416 */ 417static void 418_dbus_connection_queue_synthesized_message_link (DBusConnection *connection, 419 DBusList *link) 420{ 421 HAVE_LOCK_CHECK (connection); 422 423 _dbus_list_append_link (&connection->incoming_messages, link); 424 425 connection->n_incoming += 1; 426 427 _dbus_connection_wakeup_mainloop (connection); 428 429 _dbus_verbose ("Synthesized message %p added to incoming queue %p, %d incoming\n", 430 link->data, connection, connection->n_incoming); 431} 432 433 434/** 435 * Checks whether there are messages in the outgoing message queue. 436 * Called with connection lock held. 437 * 438 * @param connection the connection. 439 * @returns #TRUE if the outgoing queue is non-empty. 440 */ 441dbus_bool_t 442_dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection) 443{ 444 HAVE_LOCK_CHECK (connection); 445 return connection->outgoing_messages != NULL; 446} 447 448/** 449 * Checks whether there are messages in the outgoing message queue. 450 * 451 * @param connection the connection. 452 * @returns #TRUE if the outgoing queue is non-empty. 453 */ 454dbus_bool_t 455dbus_connection_has_messages_to_send (DBusConnection *connection) 456{ 457 dbus_bool_t v; 458 459 _dbus_return_val_if_fail (connection != NULL, FALSE); 460 461 CONNECTION_LOCK (connection); 462 v = _dbus_connection_has_messages_to_send_unlocked (connection); 463 CONNECTION_UNLOCK (connection); 464 465 return v; 466} 467 468/** 469 * Gets the next outgoing message. The message remains in the 470 * queue, and the caller does not own a reference to it. 471 * 472 * @param connection the connection. 473 * @returns the message to be sent. 474 */ 475DBusMessage* 476_dbus_connection_get_message_to_send (DBusConnection *connection) 477{ 478 HAVE_LOCK_CHECK (connection); 479 480 return _dbus_list_get_last (&connection->outgoing_messages); 481} 482 483/** 484 * Notifies the connection that a message has been sent, so the 485 * message can be removed from the outgoing queue. 486 * Called with the connection lock held. 487 * 488 * @param connection the connection. 489 * @param message the message that was sent. 490 */ 491void 492_dbus_connection_message_sent (DBusConnection *connection, 493 DBusMessage *message) 494{ 495 DBusList *link; 496 497 HAVE_LOCK_CHECK (connection); 498 499 /* This can be called before we even complete authentication, since 500 * it's called on disconnect to clean up the outgoing queue. 501 * It's also called as we successfully send each message. 502 */ 503 504 link = _dbus_list_get_last_link (&connection->outgoing_messages); 505 _dbus_assert (link != NULL); 506 _dbus_assert (link->data == message); 507 508 /* Save this link in the link cache */ 509 _dbus_list_unlink (&connection->outgoing_messages, 510 link); 511 _dbus_list_prepend_link (&connection->link_cache, link); 512 513 connection->n_outgoing -= 1; 514 515 _dbus_verbose ("Message %p (%d %s %s %s '%s') removed from outgoing queue %p, %d left to send\n", 516 message, 517 dbus_message_get_type (message), 518 dbus_message_get_path (message), 519 dbus_message_get_interface (message) ? 520 dbus_message_get_interface (message) : 521 "no interface", 522 dbus_message_get_member (message) ? 523 dbus_message_get_member (message) : 524 "no member", 525 dbus_message_get_signature (message), 526 connection, connection->n_outgoing); 527 528 /* Save this link in the link cache also */ 529 _dbus_message_remove_size_counter (message, connection->outgoing_counter, 530 &link); 531 _dbus_list_prepend_link (&connection->link_cache, link); 532 533 dbus_message_unref (message); 534} 535 536typedef dbus_bool_t (* DBusWatchAddFunction) (DBusWatchList *list, 537 DBusWatch *watch); 538typedef void (* DBusWatchRemoveFunction) (DBusWatchList *list, 539 DBusWatch *watch); 540typedef void (* DBusWatchToggleFunction) (DBusWatchList *list, 541 DBusWatch *watch, 542 dbus_bool_t enabled); 543 544static dbus_bool_t 545protected_change_watch (DBusConnection *connection, 546 DBusWatch *watch, 547 DBusWatchAddFunction add_function, 548 DBusWatchRemoveFunction remove_function, 549 DBusWatchToggleFunction toggle_function, 550 dbus_bool_t enabled) 551{ 552 DBusWatchList *watches; 553 dbus_bool_t retval; 554 555 HAVE_LOCK_CHECK (connection); 556 557 /* This isn't really safe or reasonable; a better pattern is the "do everything, then 558 * drop lock and call out" one; but it has to be propagated up through all callers 559 */ 560 561 watches = connection->watches; 562 if (watches) 563 { 564 connection->watches = NULL; 565 _dbus_connection_ref_unlocked (connection); 566 CONNECTION_UNLOCK (connection); 567 568 if (add_function) 569 retval = (* add_function) (watches, watch); 570 else if (remove_function) 571 { 572 retval = TRUE; 573 (* remove_function) (watches, watch); 574 } 575 else 576 { 577 retval = TRUE; 578 (* toggle_function) (watches, watch, enabled); 579 } 580 581 CONNECTION_LOCK (connection); 582 connection->watches = watches; 583 _dbus_connection_unref_unlocked (connection); 584 585 return retval; 586 } 587 else 588 return FALSE; 589} 590 591 592/** 593 * Adds a watch using the connection's DBusAddWatchFunction if 594 * available. Otherwise records the watch to be added when said 595 * function is available. Also re-adds the watch if the 596 * DBusAddWatchFunction changes. May fail due to lack of memory. 597 * 598 * @param connection the connection. 599 * @param watch the watch to add. 600 * @returns #TRUE on success. 601 */ 602dbus_bool_t 603_dbus_connection_add_watch (DBusConnection *connection, 604 DBusWatch *watch) 605{ 606 return protected_change_watch (connection, watch, 607 _dbus_watch_list_add_watch, 608 NULL, NULL, FALSE); 609} 610 611/** 612 * Removes a watch using the connection's DBusRemoveWatchFunction 613 * if available. It's an error to call this function on a watch 614 * that was not previously added. 615 * 616 * @param connection the connection. 617 * @param watch the watch to remove. 618 */ 619void 620_dbus_connection_remove_watch (DBusConnection *connection, 621 DBusWatch *watch) 622{ 623 protected_change_watch (connection, watch, 624 NULL, 625 _dbus_watch_list_remove_watch, 626 NULL, FALSE); 627} 628 629/** 630 * Toggles a watch and notifies app via connection's 631 * DBusWatchToggledFunction if available. It's an error to call this 632 * function on a watch that was not previously added. 633 * Connection lock should be held when calling this. 634 * 635 * @param connection the connection. 636 * @param watch the watch to toggle. 637 * @param enabled whether to enable or disable 638 */ 639void 640_dbus_connection_toggle_watch (DBusConnection *connection, 641 DBusWatch *watch, 642 dbus_bool_t enabled) 643{ 644 _dbus_assert (watch != NULL); 645 646 protected_change_watch (connection, watch, 647 NULL, NULL, 648 _dbus_watch_list_toggle_watch, 649 enabled); 650} 651 652typedef dbus_bool_t (* DBusTimeoutAddFunction) (DBusTimeoutList *list, 653 DBusTimeout *timeout); 654typedef void (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list, 655 DBusTimeout *timeout); 656typedef void (* DBusTimeoutToggleFunction) (DBusTimeoutList *list, 657 DBusTimeout *timeout, 658 dbus_bool_t enabled); 659 660static dbus_bool_t 661protected_change_timeout (DBusConnection *connection, 662 DBusTimeout *timeout, 663 DBusTimeoutAddFunction add_function, 664 DBusTimeoutRemoveFunction remove_function, 665 DBusTimeoutToggleFunction toggle_function, 666 dbus_bool_t enabled) 667{ 668 DBusTimeoutList *timeouts; 669 dbus_bool_t retval; 670 671 HAVE_LOCK_CHECK (connection); 672 673 /* This isn't really safe or reasonable; a better pattern is the "do everything, then 674 * drop lock and call out" one; but it has to be propagated up through all callers 675 */ 676 677 timeouts = connection->timeouts; 678 if (timeouts) 679 { 680 connection->timeouts = NULL; 681 _dbus_connection_ref_unlocked (connection); 682 CONNECTION_UNLOCK (connection); 683 684 if (add_function) 685 retval = (* add_function) (timeouts, timeout); 686 else if (remove_function) 687 { 688 retval = TRUE; 689 (* remove_function) (timeouts, timeout); 690 } 691 else 692 { 693 retval = TRUE; 694 (* toggle_function) (timeouts, timeout, enabled); 695 } 696 697 CONNECTION_LOCK (connection); 698 connection->timeouts = timeouts; 699 _dbus_connection_unref_unlocked (connection); 700 701 return retval; 702 } 703 else 704 return FALSE; 705} 706 707/** 708 * Adds a timeout using the connection's DBusAddTimeoutFunction if 709 * available. Otherwise records the timeout to be added when said 710 * function is available. Also re-adds the timeout if the 711 * DBusAddTimeoutFunction changes. May fail due to lack of memory. 712 * The timeout will fire repeatedly until removed. 713 * 714 * @param connection the connection. 715 * @param timeout the timeout to add. 716 * @returns #TRUE on success. 717 */ 718dbus_bool_t 719_dbus_connection_add_timeout (DBusConnection *connection, 720 DBusTimeout *timeout) 721{ 722 return protected_change_timeout (connection, timeout, 723 _dbus_timeout_list_add_timeout, 724 NULL, NULL, FALSE); 725} 726 727/** 728 * Removes a timeout using the connection's DBusRemoveTimeoutFunction 729 * if available. It's an error to call this function on a timeout 730 * that was not previously added. 731 * 732 * @param connection the connection. 733 * @param timeout the timeout to remove. 734 */ 735void 736_dbus_connection_remove_timeout (DBusConnection *connection, 737 DBusTimeout *timeout) 738{ 739 protected_change_timeout (connection, timeout, 740 NULL, 741 _dbus_timeout_list_remove_timeout, 742 NULL, FALSE); 743} 744 745/** 746 * Toggles a timeout and notifies app via connection's 747 * DBusTimeoutToggledFunction if available. It's an error to call this 748 * function on a timeout that was not previously added. 749 * 750 * @param connection the connection. 751 * @param timeout the timeout to toggle. 752 * @param enabled whether to enable or disable 753 */ 754void 755_dbus_connection_toggle_timeout (DBusConnection *connection, 756 DBusTimeout *timeout, 757 dbus_bool_t enabled) 758{ 759 protected_change_timeout (connection, timeout, 760 NULL, NULL, 761 _dbus_timeout_list_toggle_timeout, 762 enabled); 763} 764 765static dbus_bool_t 766_dbus_connection_attach_pending_call_unlocked (DBusConnection *connection, 767 DBusPendingCall *pending) 768{ 769 HAVE_LOCK_CHECK (connection); 770 771 _dbus_assert (pending->reply_serial != 0); 772 773 if (!_dbus_connection_add_timeout (connection, pending->timeout)) 774 return FALSE; 775 776 if (!_dbus_hash_table_insert_int (connection->pending_replies, 777 pending->reply_serial, 778 pending)) 779 { 780 _dbus_connection_remove_timeout (connection, pending->timeout); 781 782 HAVE_LOCK_CHECK (connection); 783 return FALSE; 784 } 785 786 pending->timeout_added = TRUE; 787 pending->connection = connection; 788 789 dbus_pending_call_ref (pending); 790 791 HAVE_LOCK_CHECK (connection); 792 793 return TRUE; 794} 795 796static void 797free_pending_call_on_hash_removal (void *data) 798{ 799 DBusPendingCall *pending; 800 801 if (data == NULL) 802 return; 803 804 pending = data; 805 806 if (pending->connection) 807 { 808 if (pending->timeout_added) 809 { 810 _dbus_connection_remove_timeout (pending->connection, 811 pending->timeout); 812 pending->timeout_added = FALSE; 813 } 814 815 pending->connection = NULL; 816 817 dbus_pending_call_unref (pending); 818 } 819} 820 821static void 822_dbus_connection_detach_pending_call_unlocked (DBusConnection *connection, 823 DBusPendingCall *pending) 824{ 825 /* Can't have a destroy notifier on the pending call if we're going to do this */ 826 827 dbus_pending_call_ref (pending); 828 _dbus_hash_table_remove_int (connection->pending_replies, 829 pending->reply_serial); 830 _dbus_assert (pending->connection == NULL); 831 dbus_pending_call_unref (pending); 832} 833 834static void 835_dbus_connection_detach_pending_call_and_unlock (DBusConnection *connection, 836 DBusPendingCall *pending) 837{ 838 /* The idea here is to avoid finalizing the pending call 839 * with the lock held, since there's a destroy notifier 840 * in pending call that goes out to application code. 841 */ 842 dbus_pending_call_ref (pending); 843 _dbus_hash_table_remove_int (connection->pending_replies, 844 pending->reply_serial); 845 _dbus_assert (pending->connection == NULL); 846 CONNECTION_UNLOCK (connection); 847 dbus_pending_call_unref (pending); 848} 849 850/** 851 * Removes a pending call from the connection, such that 852 * the pending reply will be ignored. May drop the last 853 * reference to the pending call. 854 * 855 * @param connection the connection 856 * @param pending the pending call 857 */ 858void 859_dbus_connection_remove_pending_call (DBusConnection *connection, 860 DBusPendingCall *pending) 861{ 862 CONNECTION_LOCK (connection); 863 _dbus_connection_detach_pending_call_and_unlock (connection, pending); 864} 865 866/** 867 * Completes a pending call with the given message, 868 * or if the message is #NULL, by timing out the pending call. 869 * 870 * @param pending the pending call 871 * @param message the message to complete the call with, or #NULL 872 * to time out the call 873 */ 874void 875_dbus_pending_call_complete_and_unlock (DBusPendingCall *pending, 876 DBusMessage *message) 877{ 878 if (message == NULL) 879 { 880 message = pending->timeout_link->data; 881 _dbus_list_clear (&pending->timeout_link); 882 } 883 else 884 dbus_message_ref (message); 885 886 _dbus_verbose (" handing message %p (%s) to pending call serial %u\n", 887 message, 888 dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN ? 889 "method return" : 890 dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR ? 891 "error" : "other type", 892 pending->reply_serial); 893 894 _dbus_assert (pending->reply == NULL); 895 _dbus_assert (pending->reply_serial == dbus_message_get_reply_serial (message)); 896 pending->reply = message; 897 898 dbus_pending_call_ref (pending); /* in case there's no app with a ref held */ 899 _dbus_connection_detach_pending_call_and_unlock (pending->connection, pending); 900 901 /* Must be called unlocked since it invokes app callback */ 902 _dbus_pending_call_notify (pending); 903 dbus_pending_call_unref (pending); 904} 905 906/** 907 * Acquire the transporter I/O path. This must be done before 908 * doing any I/O in the transporter. May sleep and drop the 909 * IO path mutex while waiting for the I/O path. 910 * 911 * @param connection the connection. 912 * @param timeout_milliseconds maximum blocking time, or -1 for no limit. 913 * @returns TRUE if the I/O path was acquired. 914 */ 915static dbus_bool_t 916_dbus_connection_acquire_io_path (DBusConnection *connection, 917 int timeout_milliseconds) 918{ 919 dbus_bool_t we_acquired; 920 921 HAVE_LOCK_CHECK (connection); 922 923 /* We don't want the connection to vanish */ 924 _dbus_connection_ref_unlocked (connection); 925 926 /* We will only touch io_path_acquired which is protected by our mutex */ 927 CONNECTION_UNLOCK (connection); 928 929 _dbus_verbose ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME); 930 _dbus_mutex_lock (connection->io_path_mutex); 931 932 _dbus_verbose ("%s start connection->io_path_acquired = %d timeout = %d\n", 933 _DBUS_FUNCTION_NAME, connection->io_path_acquired, timeout_milliseconds); 934 935 we_acquired = FALSE; 936 937 if (connection->io_path_acquired) 938 { 939 if (timeout_milliseconds != -1) 940 { 941 _dbus_verbose ("%s waiting %d for IO path to be acquirable\n", 942 _DBUS_FUNCTION_NAME, timeout_milliseconds); 943 _dbus_condvar_wait_timeout (connection->io_path_cond, 944 connection->io_path_mutex, 945 timeout_milliseconds); 946 } 947 else 948 { 949 while (connection->io_path_acquired) 950 { 951 _dbus_verbose ("%s waiting for IO path to be acquirable\n", _DBUS_FUNCTION_NAME); 952 _dbus_condvar_wait (connection->io_path_cond, connection->io_path_mutex); 953 } 954 } 955 } 956 957 if (!connection->io_path_acquired) 958 { 959 we_acquired = TRUE; 960 connection->io_path_acquired = TRUE; 961 } 962 963 _dbus_verbose ("%s end connection->io_path_acquired = %d we_acquired = %d\n", 964 _DBUS_FUNCTION_NAME, connection->io_path_acquired, we_acquired); 965 966 _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME); 967 _dbus_mutex_unlock (connection->io_path_mutex); 968 969 CONNECTION_LOCK (connection); 970 971 HAVE_LOCK_CHECK (connection); 972 973 _dbus_connection_unref_unlocked (connection); 974 975 return we_acquired; 976} 977 978/** 979 * Release the I/O path when you're done with it. Only call 980 * after you've acquired the I/O. Wakes up at most one thread 981 * currently waiting to acquire the I/O path. 982 * 983 * @param connection the connection. 984 */ 985static void 986_dbus_connection_release_io_path (DBusConnection *connection) 987{ 988 HAVE_LOCK_CHECK (connection); 989 990 _dbus_verbose ("%s locking io_path_mutex\n", _DBUS_FUNCTION_NAME); 991 _dbus_mutex_lock (connection->io_path_mutex); 992 993 _dbus_assert (connection->io_path_acquired); 994 995 _dbus_verbose ("%s start connection->io_path_acquired = %d\n", 996 _DBUS_FUNCTION_NAME, connection->io_path_acquired); 997 998 connection->io_path_acquired = FALSE; 999 _dbus_condvar_wake_one (connection->io_path_cond); 1000 1001 _dbus_verbose ("%s unlocking io_path_mutex\n", _DBUS_FUNCTION_NAME); 1002 _dbus_mutex_unlock (connection->io_path_mutex); 1003} 1004 1005/** 1006 * Queues incoming messages and sends outgoing messages for this 1007 * connection, optionally blocking in the process. Each call to 1008 * _dbus_connection_do_iteration_unlocked() will call select() or poll() one 1009 * time and then read or write data if possible. 1010 * 1011 * The purpose of this function is to be able to flush outgoing 1012 * messages or queue up incoming messages without returning 1013 * control to the application and causing reentrancy weirdness. 1014 * 1015 * The flags parameter allows you to specify whether to 1016 * read incoming messages, write outgoing messages, or both, 1017 * and whether to block if no immediate action is possible. 1018 * 1019 * The timeout_milliseconds parameter does nothing unless the 1020 * iteration is blocking. 1021 * 1022 * If there are no outgoing messages and DBUS_ITERATION_DO_READING 1023 * wasn't specified, then it's impossible to block, even if 1024 * you specify DBUS_ITERATION_BLOCK; in that case the function 1025 * returns immediately. 1026 * 1027 * Called with connection lock held. 1028 * 1029 * @param connection the connection. 1030 * @param flags iteration flags. 1031 * @param timeout_milliseconds maximum blocking time, or -1 for no limit. 1032 */ 1033void 1034_dbus_connection_do_iteration_unlocked (DBusConnection *connection, 1035 unsigned int flags, 1036 int timeout_milliseconds) 1037{ 1038 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME); 1039 1040 HAVE_LOCK_CHECK (connection); 1041 1042 if (connection->n_outgoing == 0) 1043 flags &= ~DBUS_ITERATION_DO_WRITING; 1044 1045 if (_dbus_connection_acquire_io_path (connection, 1046 (flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0)) 1047 { 1048 HAVE_LOCK_CHECK (connection); 1049 1050 _dbus_transport_do_iteration (connection->transport, 1051 flags, timeout_milliseconds); 1052 _dbus_connection_release_io_path (connection); 1053 } 1054 1055 HAVE_LOCK_CHECK (connection); 1056 1057 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME); 1058} 1059 1060/** 1061 * Creates a new connection for the given transport. A transport 1062 * represents a message stream that uses some concrete mechanism, such 1063 * as UNIX domain sockets. May return #NULL if insufficient 1064 * memory exists to create the connection. 1065 * 1066 * @param transport the transport. 1067 * @returns the new connection, or #NULL on failure. 1068 */ 1069DBusConnection* 1070_dbus_connection_new_for_transport (DBusTransport *transport) 1071{ 1072 DBusConnection *connection; 1073 DBusWatchList *watch_list; 1074 DBusTimeoutList *timeout_list; 1075 DBusHashTable *pending_replies; 1076 DBusMutex *mutex; 1077 DBusMutex *io_path_mutex; 1078 DBusMutex *dispatch_mutex; 1079 DBusCondVar *message_returned_cond; 1080 DBusCondVar *dispatch_cond; 1081 DBusCondVar *io_path_cond; 1082 DBusList *disconnect_link; 1083 DBusMessage *disconnect_message; 1084 DBusCounter *outgoing_counter; 1085 DBusObjectTree *objects; 1086 1087 watch_list = NULL; 1088 connection = NULL; 1089 pending_replies = NULL; 1090 timeout_list = NULL; 1091 mutex = NULL; 1092 io_path_mutex = NULL; 1093 dispatch_mutex = NULL; 1094 message_returned_cond = NULL; 1095 dispatch_cond = NULL; 1096 io_path_cond = NULL; 1097 disconnect_link = NULL; 1098 disconnect_message = NULL; 1099 outgoing_counter = NULL; 1100 objects = NULL; 1101 1102 watch_list = _dbus_watch_list_new (); 1103 if (watch_list == NULL) 1104 goto error; 1105 1106 timeout_list = _dbus_timeout_list_new (); 1107 if (timeout_list == NULL) 1108 goto error; 1109 1110 pending_replies = 1111 _dbus_hash_table_new (DBUS_HASH_INT, 1112 NULL, 1113 (DBusFreeFunction)free_pending_call_on_hash_removal); 1114 if (pending_replies == NULL) 1115 goto error; 1116 1117 connection = dbus_new0 (DBusConnection, 1); 1118 if (connection == NULL) 1119 goto error; 1120 1121 mutex = _dbus_mutex_new (); 1122 if (mutex == NULL) 1123 goto error; 1124 1125 io_path_mutex = _dbus_mutex_new (); 1126 if (io_path_mutex == NULL) 1127 goto error; 1128 1129 dispatch_mutex = _dbus_mutex_new (); 1130 if (dispatch_mutex == NULL) 1131 goto error; 1132 1133 message_returned_cond = _dbus_condvar_new (); 1134 if (message_returned_cond == NULL) 1135 goto error; 1136 1137 dispatch_cond = _dbus_condvar_new (); 1138 if (dispatch_cond == NULL) 1139 goto error; 1140 1141 io_path_cond = _dbus_condvar_new (); 1142 if (io_path_cond == NULL) 1143 goto error; 1144 1145 disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL, 1146 DBUS_INTERFACE_LOCAL, 1147 "Disconnected"); 1148 1149 if (disconnect_message == NULL) 1150 goto error; 1151 1152 disconnect_link = _dbus_list_alloc_link (disconnect_message); 1153 if (disconnect_link == NULL) 1154 goto error; 1155 1156 outgoing_counter = _dbus_counter_new (); 1157 if (outgoing_counter == NULL) 1158 goto error; 1159 1160 objects = _dbus_object_tree_new (connection); 1161 if (objects == NULL) 1162 goto error; 1163 1164 if (_dbus_modify_sigpipe) 1165 _dbus_disable_sigpipe (); 1166 1167 connection->refcount.value = 1; 1168 connection->mutex = mutex; 1169 connection->dispatch_cond = dispatch_cond; 1170 connection->dispatch_mutex = dispatch_mutex; 1171 connection->io_path_cond = io_path_cond; 1172 connection->io_path_mutex = io_path_mutex; 1173 connection->transport = transport; 1174 connection->watches = watch_list; 1175 connection->timeouts = timeout_list; 1176 connection->pending_replies = pending_replies; 1177 connection->outgoing_counter = outgoing_counter; 1178 connection->filter_list = NULL; 1179 connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE; /* so we're notified first time there's data */ 1180 connection->objects = objects; 1181 connection->exit_on_disconnect = FALSE; 1182 connection->shareable = FALSE; 1183#ifndef DBUS_DISABLE_CHECKS 1184 connection->generation = _dbus_current_generation; 1185#endif 1186 1187 _dbus_data_slot_list_init (&connection->slot_list); 1188 1189 connection->client_serial = 1; 1190 1191 connection->disconnect_message_link = disconnect_link; 1192 1193 CONNECTION_LOCK (connection); 1194 1195 if (!_dbus_transport_set_connection (transport, connection)) 1196 goto error; 1197 1198 _dbus_transport_ref (transport); 1199 1200 CONNECTION_UNLOCK (connection); 1201 1202 return connection; 1203 1204 error: 1205 if (disconnect_message != NULL) 1206 dbus_message_unref (disconnect_message); 1207 1208 if (disconnect_link != NULL) 1209 _dbus_list_free_link (disconnect_link); 1210 1211 if (io_path_cond != NULL) 1212 _dbus_condvar_free (io_path_cond); 1213 1214 if (dispatch_cond != NULL) 1215 _dbus_condvar_free (dispatch_cond); 1216 1217 if (message_returned_cond != NULL) 1218 _dbus_condvar_free (message_returned_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_disconnect (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 "reconnect" 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_disconnect (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 1950static dbus_bool_t 1951_dbus_connection_get_is_connected_unlocked (DBusConnection *connection) 1952{ 1953 HAVE_LOCK_CHECK (connection); 1954 return _dbus_transport_get_is_connected (connection->transport); 1955} 1956 1957/** 1958 * Gets whether the connection is currently connected. All 1959 * connections are connected when they are opened. A connection may 1960 * become disconnected when the remote application closes its end, or 1961 * exits; a connection may also be disconnected with 1962 * dbus_connection_disconnect(). 1963 * 1964 * @param connection the connection. 1965 * @returns #TRUE if the connection is still alive. 1966 */ 1967dbus_bool_t 1968dbus_connection_get_is_connected (DBusConnection *connection) 1969{ 1970 dbus_bool_t res; 1971 1972 _dbus_return_val_if_fail (connection != NULL, FALSE); 1973 1974 CONNECTION_LOCK (connection); 1975 res = _dbus_connection_get_is_connected_unlocked (connection); 1976 CONNECTION_UNLOCK (connection); 1977 1978 return res; 1979} 1980 1981/** 1982 * Gets whether the connection was authenticated. (Note that 1983 * if the connection was authenticated then disconnected, 1984 * this function still returns #TRUE) 1985 * 1986 * @param connection the connection 1987 * @returns #TRUE if the connection was ever authenticated 1988 */ 1989dbus_bool_t 1990dbus_connection_get_is_authenticated (DBusConnection *connection) 1991{ 1992 dbus_bool_t res; 1993 1994 _dbus_return_val_if_fail (connection != NULL, FALSE); 1995 1996 CONNECTION_LOCK (connection); 1997 res = _dbus_transport_get_is_authenticated (connection->transport); 1998 CONNECTION_UNLOCK (connection); 1999 2000 return res; 2001} 2002 2003/** 2004 * Set whether _exit() should be called when the connection receives a 2005 * disconnect signal. The call to _exit() comes after any handlers for 2006 * the disconnect signal run; handlers can cancel the exit by calling 2007 * this function. 2008 * 2009 * By default, exit_on_disconnect is #FALSE; but for message bus 2010 * connections returned from dbus_bus_get() it will be toggled on 2011 * by default. 2012 * 2013 * @param connection the connection 2014 * @param exit_on_disconnect #TRUE if _exit() should be called after a disconnect signal 2015 */ 2016void 2017dbus_connection_set_exit_on_disconnect (DBusConnection *connection, 2018 dbus_bool_t exit_on_disconnect) 2019{ 2020 _dbus_return_if_fail (connection != NULL); 2021 2022 CONNECTION_LOCK (connection); 2023 connection->exit_on_disconnect = exit_on_disconnect != FALSE; 2024 CONNECTION_UNLOCK (connection); 2025} 2026 2027static DBusPreallocatedSend* 2028_dbus_connection_preallocate_send_unlocked (DBusConnection *connection) 2029{ 2030 DBusPreallocatedSend *preallocated; 2031 2032 HAVE_LOCK_CHECK (connection); 2033 2034 _dbus_assert (connection != NULL); 2035 2036 preallocated = dbus_new (DBusPreallocatedSend, 1); 2037 if (preallocated == NULL) 2038 return NULL; 2039 2040 if (connection->link_cache != NULL) 2041 { 2042 preallocated->queue_link = 2043 _dbus_list_pop_first_link (&connection->link_cache); 2044 preallocated->queue_link->data = NULL; 2045 } 2046 else 2047 { 2048 preallocated->queue_link = _dbus_list_alloc_link (NULL); 2049 if (preallocated->queue_link == NULL) 2050 goto failed_0; 2051 } 2052 2053 if (connection->link_cache != NULL) 2054 { 2055 preallocated->counter_link = 2056 _dbus_list_pop_first_link (&connection->link_cache); 2057 preallocated->counter_link->data = connection->outgoing_counter; 2058 } 2059 else 2060 { 2061 preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter); 2062 if (preallocated->counter_link == NULL) 2063 goto failed_1; 2064 } 2065 2066 _dbus_counter_ref (preallocated->counter_link->data); 2067 2068 preallocated->connection = connection; 2069 2070 return preallocated; 2071 2072 failed_1: 2073 _dbus_list_free_link (preallocated->queue_link); 2074 failed_0: 2075 dbus_free (preallocated); 2076 2077 return NULL; 2078} 2079 2080/** 2081 * Preallocates resources needed to send a message, allowing the message 2082 * to be sent without the possibility of memory allocation failure. 2083 * Allows apps to create a future guarantee that they can send 2084 * a message regardless of memory shortages. 2085 * 2086 * @param connection the connection we're preallocating for. 2087 * @returns the preallocated resources, or #NULL 2088 */ 2089DBusPreallocatedSend* 2090dbus_connection_preallocate_send (DBusConnection *connection) 2091{ 2092 DBusPreallocatedSend *preallocated; 2093 2094 _dbus_return_val_if_fail (connection != NULL, NULL); 2095 2096 CONNECTION_LOCK (connection); 2097 2098 preallocated = 2099 _dbus_connection_preallocate_send_unlocked (connection); 2100 2101 CONNECTION_UNLOCK (connection); 2102 2103 return preallocated; 2104} 2105 2106/** 2107 * Frees preallocated message-sending resources from 2108 * dbus_connection_preallocate_send(). Should only 2109 * be called if the preallocated resources are not used 2110 * to send a message. 2111 * 2112 * @param connection the connection 2113 * @param preallocated the resources 2114 */ 2115void 2116dbus_connection_free_preallocated_send (DBusConnection *connection, 2117 DBusPreallocatedSend *preallocated) 2118{ 2119 _dbus_return_if_fail (connection != NULL); 2120 _dbus_return_if_fail (preallocated != NULL); 2121 _dbus_return_if_fail (connection == preallocated->connection); 2122 2123 _dbus_list_free_link (preallocated->queue_link); 2124 _dbus_counter_unref (preallocated->counter_link->data); 2125 _dbus_list_free_link (preallocated->counter_link); 2126 dbus_free (preallocated); 2127} 2128 2129/* Called with lock held, does not update dispatch status */ 2130static void 2131_dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *connection, 2132 DBusPreallocatedSend *preallocated, 2133 DBusMessage *message, 2134 dbus_uint32_t *client_serial) 2135{ 2136 dbus_uint32_t serial; 2137 const char *sig; 2138 2139 preallocated->queue_link->data = message; 2140 _dbus_list_prepend_link (&connection->outgoing_messages, 2141 preallocated->queue_link); 2142 2143 _dbus_message_add_size_counter_link (message, 2144 preallocated->counter_link); 2145 2146 dbus_free (preallocated); 2147 preallocated = NULL; 2148 2149 dbus_message_ref (message); 2150 2151 connection->n_outgoing += 1; 2152 2153 sig = dbus_message_get_signature (message); 2154 2155 _dbus_verbose ("Message %p (%d %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n", 2156 message, 2157 dbus_message_get_type (message), 2158 dbus_message_get_path (message), 2159 dbus_message_get_interface (message) ? 2160 dbus_message_get_interface (message) : 2161 "no interface", 2162 dbus_message_get_member (message) ? 2163 dbus_message_get_member (message) : 2164 "no member", 2165 sig, 2166 dbus_message_get_destination (message) ? 2167 dbus_message_get_destination (message) : 2168 "null", 2169 connection, 2170 connection->n_outgoing); 2171 2172 if (dbus_message_get_serial (message) == 0) 2173 { 2174 serial = _dbus_connection_get_next_client_serial (connection); 2175 _dbus_message_set_serial (message, serial); 2176 if (client_serial) 2177 *client_serial = serial; 2178 } 2179 else 2180 { 2181 if (client_serial) 2182 *client_serial = dbus_message_get_serial (message); 2183 } 2184 2185 _dbus_verbose ("Message %p serial is %u\n", 2186 message, dbus_message_get_serial (message)); 2187 2188 _dbus_message_lock (message); 2189 2190 /* Now we need to run an iteration to hopefully just write the messages 2191 * out immediately, and otherwise get them queued up 2192 */ 2193 _dbus_connection_do_iteration_unlocked (connection, 2194 DBUS_ITERATION_DO_WRITING, 2195 -1); 2196 2197 /* If stuff is still queued up, be sure we wake up the main loop */ 2198 if (connection->n_outgoing > 0) 2199 _dbus_connection_wakeup_mainloop (connection); 2200} 2201 2202static void 2203_dbus_connection_send_preallocated_and_unlock (DBusConnection *connection, 2204 DBusPreallocatedSend *preallocated, 2205 DBusMessage *message, 2206 dbus_uint32_t *client_serial) 2207{ 2208 DBusDispatchStatus status; 2209 2210 HAVE_LOCK_CHECK (connection); 2211 2212 _dbus_connection_send_preallocated_unlocked_no_update (connection, 2213 preallocated, 2214 message, client_serial); 2215 2216 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME); 2217 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2218 2219 /* this calls out to user code */ 2220 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2221} 2222 2223/** 2224 * Sends a message using preallocated resources. This function cannot fail. 2225 * It works identically to dbus_connection_send() in other respects. 2226 * Preallocated resources comes from dbus_connection_preallocate_send(). 2227 * This function "consumes" the preallocated resources, they need not 2228 * be freed separately. 2229 * 2230 * @param connection the connection 2231 * @param preallocated the preallocated resources 2232 * @param message the message to send 2233 * @param client_serial return location for client serial assigned to the message 2234 */ 2235void 2236dbus_connection_send_preallocated (DBusConnection *connection, 2237 DBusPreallocatedSend *preallocated, 2238 DBusMessage *message, 2239 dbus_uint32_t *client_serial) 2240{ 2241 _dbus_return_if_fail (connection != NULL); 2242 _dbus_return_if_fail (preallocated != NULL); 2243 _dbus_return_if_fail (message != NULL); 2244 _dbus_return_if_fail (preallocated->connection == connection); 2245 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL || 2246 (dbus_message_get_interface (message) != NULL && 2247 dbus_message_get_member (message) != NULL)); 2248 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL || 2249 (dbus_message_get_interface (message) != NULL && 2250 dbus_message_get_member (message) != NULL)); 2251 2252 CONNECTION_LOCK (connection); 2253 _dbus_connection_send_preallocated_and_unlock (connection, 2254 preallocated, 2255 message, client_serial); 2256} 2257 2258static dbus_bool_t 2259_dbus_connection_send_unlocked_no_update (DBusConnection *connection, 2260 DBusMessage *message, 2261 dbus_uint32_t *client_serial) 2262{ 2263 DBusPreallocatedSend *preallocated; 2264 2265 _dbus_assert (connection != NULL); 2266 _dbus_assert (message != NULL); 2267 2268 preallocated = _dbus_connection_preallocate_send_unlocked (connection); 2269 if (preallocated == NULL) 2270 return FALSE; 2271 2272 _dbus_connection_send_preallocated_unlocked_no_update (connection, 2273 preallocated, 2274 message, 2275 client_serial); 2276 return TRUE; 2277} 2278 2279dbus_bool_t 2280_dbus_connection_send_and_unlock (DBusConnection *connection, 2281 DBusMessage *message, 2282 dbus_uint32_t *client_serial) 2283{ 2284 DBusPreallocatedSend *preallocated; 2285 2286 _dbus_assert (connection != NULL); 2287 _dbus_assert (message != NULL); 2288 2289 preallocated = _dbus_connection_preallocate_send_unlocked (connection); 2290 if (preallocated == NULL) 2291 { 2292 CONNECTION_UNLOCK (connection); 2293 return FALSE; 2294 } 2295 2296 _dbus_connection_send_preallocated_and_unlock (connection, 2297 preallocated, 2298 message, 2299 client_serial); 2300 return TRUE; 2301} 2302 2303/** 2304 * Adds a message to the outgoing message queue. Does not block to 2305 * write the message to the network; that happens asynchronously. To 2306 * force the message to be written, call dbus_connection_flush(). 2307 * Because this only queues the message, the only reason it can 2308 * fail is lack of memory. Even if the connection is disconnected, 2309 * no error will be returned. 2310 * 2311 * If the function fails due to lack of memory, it returns #FALSE. 2312 * The function will never fail for other reasons; even if the 2313 * connection is disconnected, you can queue an outgoing message, 2314 * though obviously it won't be sent. 2315 * 2316 * @param connection the connection. 2317 * @param message the message to write. 2318 * @param client_serial return location for client serial. 2319 * @returns #TRUE on success. 2320 */ 2321dbus_bool_t 2322dbus_connection_send (DBusConnection *connection, 2323 DBusMessage *message, 2324 dbus_uint32_t *client_serial) 2325{ 2326 _dbus_return_val_if_fail (connection != NULL, FALSE); 2327 _dbus_return_val_if_fail (message != NULL, FALSE); 2328 2329 CONNECTION_LOCK (connection); 2330 2331 return _dbus_connection_send_and_unlock (connection, 2332 message, 2333 client_serial); 2334} 2335 2336static dbus_bool_t 2337reply_handler_timeout (void *data) 2338{ 2339 DBusConnection *connection; 2340 DBusDispatchStatus status; 2341 DBusPendingCall *pending = data; 2342 2343 connection = pending->connection; 2344 2345 CONNECTION_LOCK (connection); 2346 if (pending->timeout_link) 2347 { 2348 _dbus_connection_queue_synthesized_message_link (connection, 2349 pending->timeout_link); 2350 pending->timeout_link = NULL; 2351 } 2352 2353 _dbus_connection_remove_timeout (connection, 2354 pending->timeout); 2355 pending->timeout_added = FALSE; 2356 2357 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME); 2358 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2359 2360 /* Unlocks, and calls out to user code */ 2361 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2362 2363 return TRUE; 2364} 2365 2366/** 2367 * Queues a message to send, as with dbus_connection_send_message(), 2368 * but also returns a #DBusPendingCall used to receive a reply to the 2369 * message. If no reply is received in the given timeout_milliseconds, 2370 * this function expires the pending reply and generates a synthetic 2371 * error reply (generated in-process, not by the remote application) 2372 * indicating that a timeout occurred. 2373 * 2374 * A #DBusPendingCall will see a reply message after any filters, but 2375 * before any object instances or other handlers. A #DBusPendingCall 2376 * will always see exactly one reply message, unless it's cancelled 2377 * with dbus_pending_call_cancel(). 2378 * 2379 * If a filter filters out the reply before the handler sees it, the 2380 * reply is immediately timed out and a timeout error reply is 2381 * generated. If a filter removes the timeout error reply then the 2382 * #DBusPendingCall will get confused. Filtering the timeout error 2383 * is thus considered a bug and will print a warning. 2384 * 2385 * If #NULL is passed for the pending_return, the #DBusPendingCall 2386 * will still be generated internally, and used to track 2387 * the message reply timeout. This means a timeout error will 2388 * occur if no reply arrives, unlike with dbus_connection_send(). 2389 * 2390 * If -1 is passed for the timeout, a sane default timeout is used. -1 2391 * is typically the best value for the timeout for this reason, unless 2392 * you want a very short or very long timeout. There is no way to 2393 * avoid a timeout entirely, other than passing INT_MAX for the 2394 * timeout to postpone it indefinitely. 2395 * 2396 * @param connection the connection 2397 * @param message the message to send 2398 * @param pending_return return location for a #DBusPendingCall object, or #NULL 2399 * @param timeout_milliseconds timeout in milliseconds or -1 for default 2400 * @returns #TRUE if the message is successfully queued, #FALSE if no memory. 2401 * 2402 */ 2403dbus_bool_t 2404dbus_connection_send_with_reply (DBusConnection *connection, 2405 DBusMessage *message, 2406 DBusPendingCall **pending_return, 2407 int timeout_milliseconds) 2408{ 2409 DBusPendingCall *pending; 2410 DBusMessage *reply; 2411 DBusList *reply_link; 2412 dbus_int32_t serial = -1; 2413 DBusDispatchStatus status; 2414 2415 _dbus_return_val_if_fail (connection != NULL, FALSE); 2416 _dbus_return_val_if_fail (message != NULL, FALSE); 2417 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE); 2418 2419 if (pending_return) 2420 *pending_return = NULL; 2421 2422 pending = _dbus_pending_call_new (connection, 2423 timeout_milliseconds, 2424 reply_handler_timeout); 2425 2426 if (pending == NULL) 2427 return FALSE; 2428 2429 CONNECTION_LOCK (connection); 2430 2431 /* Assign a serial to the message */ 2432 if (dbus_message_get_serial (message) == 0) 2433 { 2434 serial = _dbus_connection_get_next_client_serial (connection); 2435 _dbus_message_set_serial (message, serial); 2436 } 2437 2438 pending->reply_serial = serial; 2439 2440 reply = dbus_message_new_error (message, DBUS_ERROR_NO_REPLY, 2441 "No reply within specified time"); 2442 if (reply == NULL) 2443 goto error; 2444 2445 reply_link = _dbus_list_alloc_link (reply); 2446 if (reply_link == NULL) 2447 { 2448 CONNECTION_UNLOCK (connection); 2449 dbus_message_unref (reply); 2450 goto error_unlocked; 2451 } 2452 2453 pending->timeout_link = reply_link; 2454 2455 /* Insert the serial in the pending replies hash; 2456 * hash takes a refcount on DBusPendingCall. 2457 * Also, add the timeout. 2458 */ 2459 if (!_dbus_connection_attach_pending_call_unlocked (connection, 2460 pending)) 2461 goto error; 2462 2463 dbus_pending_call_unref (pending); 2464 2465 if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL)) 2466 { 2467 _dbus_connection_detach_pending_call_and_unlock (connection, 2468 pending); 2469 goto error_unlocked; 2470 } 2471 2472 if (pending_return) 2473 *pending_return = pending; 2474 else 2475 { 2476 _dbus_connection_detach_pending_call_unlocked (connection, pending); 2477 dbus_pending_call_unref (pending); 2478 } 2479 2480 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME); 2481 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2482 2483 /* this calls out to user code */ 2484 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2485 2486 return TRUE; 2487 2488 error: 2489 CONNECTION_UNLOCK (connection); 2490 error_unlocked: 2491 dbus_pending_call_unref (pending); 2492 return FALSE; 2493} 2494 2495/* This is slightly strange since we can pop a message here without 2496 * the dispatch lock. 2497 */ 2498static DBusMessage* 2499check_for_reply_unlocked (DBusConnection *connection, 2500 dbus_uint32_t client_serial) 2501{ 2502 DBusList *link; 2503 2504 HAVE_LOCK_CHECK (connection); 2505 2506 link = _dbus_list_get_first_link (&connection->incoming_messages); 2507 2508 while (link != NULL) 2509 { 2510 DBusMessage *reply = link->data; 2511 2512 if (dbus_message_get_reply_serial (reply) == client_serial) 2513 { 2514 _dbus_list_remove_link (&connection->incoming_messages, link); 2515 connection->n_incoming -= 1; 2516 return reply; 2517 } 2518 link = _dbus_list_get_next_link (&connection->incoming_messages, link); 2519 } 2520 2521 return NULL; 2522} 2523 2524/** 2525 * Blocks until a pending call times out or gets a reply. 2526 * 2527 * Does not re-enter the main loop or run filter/path-registered 2528 * callbacks. The reply to the message will not be seen by 2529 * filter callbacks. 2530 * 2531 * Returns immediately if pending call already got a reply. 2532 * 2533 * @todo could use performance improvements (it keeps scanning 2534 * the whole message queue for example) 2535 * 2536 * @param pending the pending call we block for a reply on 2537 */ 2538void 2539_dbus_connection_block_pending_call (DBusPendingCall *pending) 2540{ 2541 long start_tv_sec, start_tv_usec; 2542 long end_tv_sec, end_tv_usec; 2543 long tv_sec, tv_usec; 2544 DBusDispatchStatus status; 2545 DBusConnection *connection; 2546 dbus_uint32_t client_serial; 2547 int timeout_milliseconds; 2548 2549 _dbus_assert (pending != NULL); 2550 2551 if (dbus_pending_call_get_completed (pending)) 2552 return; 2553 2554 if (pending->connection == NULL) 2555 return; /* call already detached */ 2556 2557 dbus_pending_call_ref (pending); /* necessary because the call could be canceled */ 2558 2559 connection = pending->connection; 2560 client_serial = pending->reply_serial; 2561 2562 /* note that timeout_milliseconds is limited to a smallish value 2563 * in _dbus_pending_call_new() so overflows aren't possible 2564 * below 2565 */ 2566 timeout_milliseconds = dbus_timeout_get_interval (pending->timeout); 2567 2568 /* Flush message queue */ 2569 dbus_connection_flush (connection); 2570 2571 CONNECTION_LOCK (connection); 2572 2573 _dbus_get_current_time (&start_tv_sec, &start_tv_usec); 2574 end_tv_sec = start_tv_sec + timeout_milliseconds / 1000; 2575 end_tv_usec = start_tv_usec + (timeout_milliseconds % 1000) * 1000; 2576 end_tv_sec += end_tv_usec / _DBUS_USEC_PER_SECOND; 2577 end_tv_usec = end_tv_usec % _DBUS_USEC_PER_SECOND; 2578 2579 _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", 2580 timeout_milliseconds, 2581 client_serial, 2582 start_tv_sec, start_tv_usec, 2583 end_tv_sec, end_tv_usec); 2584 2585 /* Now we wait... */ 2586 /* always block at least once as we know we don't have the reply yet */ 2587 _dbus_connection_do_iteration_unlocked (connection, 2588 DBUS_ITERATION_DO_READING | 2589 DBUS_ITERATION_BLOCK, 2590 timeout_milliseconds); 2591 2592 recheck_status: 2593 2594 _dbus_verbose ("%s top of recheck\n", _DBUS_FUNCTION_NAME); 2595 2596 HAVE_LOCK_CHECK (connection); 2597 2598 /* queue messages and get status */ 2599 2600 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2601 2602 /* the get_completed() is in case a dispatch() while we were blocking 2603 * got the reply instead of us. 2604 */ 2605 if (dbus_pending_call_get_completed (pending)) 2606 { 2607 _dbus_verbose ("Pending call completed by dispatch in %s\n", _DBUS_FUNCTION_NAME); 2608 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2609 return; 2610 } 2611 2612 if (status == DBUS_DISPATCH_DATA_REMAINS) 2613 { 2614 DBusMessage *reply; 2615 2616 reply = check_for_reply_unlocked (connection, client_serial); 2617 if (reply != NULL) 2618 { 2619 _dbus_verbose ("%s checked for reply\n", _DBUS_FUNCTION_NAME); 2620 2621 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n"); 2622 2623 _dbus_pending_call_complete_and_unlock (pending, reply); 2624 dbus_message_unref (reply); 2625 2626 CONNECTION_LOCK (connection); 2627 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2628 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2629 2630 return; 2631 } 2632 } 2633 2634 _dbus_get_current_time (&tv_sec, &tv_usec); 2635 2636 if (!_dbus_connection_get_is_connected_unlocked (connection)) 2637 { 2638 /* FIXME send a "DBUS_ERROR_DISCONNECTED" instead, just to help 2639 * programmers understand what went wrong since the timeout is 2640 * confusing 2641 */ 2642 2643 _dbus_pending_call_complete_and_unlock (pending, NULL); 2644 return; 2645 } 2646 else if (tv_sec < start_tv_sec) 2647 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n"); 2648 else if (connection->disconnect_message_link == NULL) 2649 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n"); 2650 else if (tv_sec < end_tv_sec || 2651 (tv_sec == end_tv_sec && tv_usec < end_tv_usec)) 2652 { 2653 timeout_milliseconds = (end_tv_sec - tv_sec) * 1000 + 2654 (end_tv_usec - tv_usec) / 1000; 2655 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds); 2656 _dbus_assert (timeout_milliseconds >= 0); 2657 2658 if (status == DBUS_DISPATCH_NEED_MEMORY) 2659 { 2660 /* Try sleeping a bit, as we aren't sure we need to block for reading, 2661 * we may already have a reply in the buffer and just can't process 2662 * it. 2663 */ 2664 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n"); 2665 2666 if (timeout_milliseconds < 100) 2667 ; /* just busy loop */ 2668 else if (timeout_milliseconds <= 1000) 2669 _dbus_sleep_milliseconds (timeout_milliseconds / 3); 2670 else 2671 _dbus_sleep_milliseconds (1000); 2672 } 2673 else 2674 { 2675 /* block again, we don't have the reply buffered yet. */ 2676 _dbus_connection_do_iteration_unlocked (connection, 2677 DBUS_ITERATION_DO_READING | 2678 DBUS_ITERATION_BLOCK, 2679 timeout_milliseconds); 2680 } 2681 2682 goto recheck_status; 2683 } 2684 2685 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %ld milliseconds and got no reply\n", 2686 (tv_sec - start_tv_sec) * 1000 + (tv_usec - start_tv_usec) / 1000); 2687 2688 _dbus_assert (!dbus_pending_call_get_completed (pending)); 2689 2690 /* unlock and call user code */ 2691 _dbus_pending_call_complete_and_unlock (pending, NULL); 2692 2693 /* update user code on dispatch status */ 2694 CONNECTION_LOCK (connection); 2695 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2696 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2697} 2698 2699/** 2700 * Sends a message and blocks a certain time period while waiting for 2701 * a reply. This function does not reenter the main loop, 2702 * i.e. messages other than the reply are queued up but not 2703 * processed. This function is used to do non-reentrant "method 2704 * calls." 2705 * 2706 * If a normal reply is received, it is returned, and removed from the 2707 * incoming message queue. If it is not received, #NULL is returned 2708 * and the error is set to #DBUS_ERROR_NO_REPLY. If an error reply is 2709 * received, it is converted to a #DBusError and returned as an error, 2710 * then the reply message is deleted. If something else goes wrong, 2711 * result is set to whatever is appropriate, such as 2712 * #DBUS_ERROR_NO_MEMORY or #DBUS_ERROR_DISCONNECTED. 2713 * 2714 * @param connection the connection 2715 * @param message the message to send 2716 * @param timeout_milliseconds timeout in milliseconds or -1 for default 2717 * @param error return location for error message 2718 * @returns the message that is the reply or #NULL with an error code if the 2719 * function fails. 2720 */ 2721DBusMessage* 2722dbus_connection_send_with_reply_and_block (DBusConnection *connection, 2723 DBusMessage *message, 2724 int timeout_milliseconds, 2725 DBusError *error) 2726{ 2727 DBusMessage *reply; 2728 DBusPendingCall *pending; 2729 2730 _dbus_return_val_if_fail (connection != NULL, NULL); 2731 _dbus_return_val_if_fail (message != NULL, NULL); 2732 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE); 2733 _dbus_return_val_if_error_is_set (error, NULL); 2734 2735 if (!dbus_connection_send_with_reply (connection, message, 2736 &pending, timeout_milliseconds)) 2737 { 2738 _DBUS_SET_OOM (error); 2739 return NULL; 2740 } 2741 2742 _dbus_assert (pending != NULL); 2743 2744 dbus_pending_call_block (pending); 2745 2746 reply = dbus_pending_call_steal_reply (pending); 2747 dbus_pending_call_unref (pending); 2748 2749 /* call_complete_and_unlock() called from pending_call_block() should 2750 * always fill this in. 2751 */ 2752 _dbus_assert (reply != NULL); 2753 2754 if (dbus_set_error_from_message (error, reply)) 2755 { 2756 dbus_message_unref (reply); 2757 return NULL; 2758 } 2759 else 2760 return reply; 2761} 2762 2763/** 2764 * Blocks until the outgoing message queue is empty. 2765 * 2766 * @param connection the connection. 2767 */ 2768void 2769dbus_connection_flush (DBusConnection *connection) 2770{ 2771 /* We have to specify DBUS_ITERATION_DO_READING here because 2772 * otherwise we could have two apps deadlock if they are both doing 2773 * a flush(), and the kernel buffers fill up. This could change the 2774 * dispatch status. 2775 */ 2776 DBusDispatchStatus status; 2777 2778 _dbus_return_if_fail (connection != NULL); 2779 2780 CONNECTION_LOCK (connection); 2781 while (connection->n_outgoing > 0 && 2782 _dbus_connection_get_is_connected_unlocked (connection)) 2783 { 2784 _dbus_verbose ("doing iteration in %s\n", _DBUS_FUNCTION_NAME); 2785 HAVE_LOCK_CHECK (connection); 2786 _dbus_connection_do_iteration_unlocked (connection, 2787 DBUS_ITERATION_DO_READING | 2788 DBUS_ITERATION_DO_WRITING | 2789 DBUS_ITERATION_BLOCK, 2790 -1); 2791 } 2792 2793 HAVE_LOCK_CHECK (connection); 2794 _dbus_verbose ("%s middle\n", _DBUS_FUNCTION_NAME); 2795 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2796 2797 HAVE_LOCK_CHECK (connection); 2798 /* Unlocks and calls out to user code */ 2799 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2800 2801 _dbus_verbose ("%s end\n", _DBUS_FUNCTION_NAME); 2802} 2803 2804/** 2805 * Returns the first-received message from the incoming message queue, 2806 * leaving it in the queue. If the queue is empty, returns #NULL. 2807 * 2808 * The caller does not own a reference to the returned message, and 2809 * must either return it using dbus_connection_return_message() or 2810 * keep it after calling dbus_connection_steal_borrowed_message(). No 2811 * one can get at the message while its borrowed, so return it as 2812 * quickly as possible and don't keep a reference to it after 2813 * returning it. If you need to keep the message, make a copy of it. 2814 * 2815 * dbus_connection_dispatch() will block if called while a borrowed 2816 * message is outstanding; only one piece of code can be playing with 2817 * the incoming queue at a time. This function will block if called 2818 * during a dbus_connection_dispatch(). 2819 * 2820 * @param connection the connection. 2821 * @returns next message in the incoming queue. 2822 */ 2823DBusMessage* 2824dbus_connection_borrow_message (DBusConnection *connection) 2825{ 2826 DBusDispatchStatus status; 2827 DBusMessage *message; 2828 2829 _dbus_return_val_if_fail (connection != NULL, NULL); 2830 2831 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME); 2832 2833 /* this is called for the side effect that it queues 2834 * up any messages from the transport 2835 */ 2836 status = dbus_connection_get_dispatch_status (connection); 2837 if (status != DBUS_DISPATCH_DATA_REMAINS) 2838 return NULL; 2839 2840 CONNECTION_LOCK (connection); 2841 2842 _dbus_connection_acquire_dispatch (connection); 2843 2844 /* While a message is outstanding, the dispatch lock is held */ 2845 _dbus_assert (connection->message_borrowed == NULL); 2846 2847 connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages); 2848 2849 message = connection->message_borrowed; 2850 2851 /* Note that we KEEP the dispatch lock until the message is returned */ 2852 if (message == NULL) 2853 _dbus_connection_release_dispatch (connection); 2854 2855 CONNECTION_UNLOCK (connection); 2856 2857 return message; 2858} 2859 2860/** 2861 * Used to return a message after peeking at it using 2862 * dbus_connection_borrow_message(). Only called if 2863 * message from dbus_connection_borrow_message() was non-#NULL. 2864 * 2865 * @param connection the connection 2866 * @param message the message from dbus_connection_borrow_message() 2867 */ 2868void 2869dbus_connection_return_message (DBusConnection *connection, 2870 DBusMessage *message) 2871{ 2872 _dbus_return_if_fail (connection != NULL); 2873 _dbus_return_if_fail (message != NULL); 2874 _dbus_return_if_fail (message == connection->message_borrowed); 2875 _dbus_return_if_fail (connection->dispatch_acquired); 2876 2877 CONNECTION_LOCK (connection); 2878 2879 _dbus_assert (message == connection->message_borrowed); 2880 2881 connection->message_borrowed = NULL; 2882 2883 _dbus_connection_release_dispatch (connection); 2884 2885 CONNECTION_UNLOCK (connection); 2886} 2887 2888/** 2889 * Used to keep a message after peeking at it using 2890 * dbus_connection_borrow_message(). Before using this function, see 2891 * the caveats/warnings in the documentation for 2892 * dbus_connection_pop_message(). 2893 * 2894 * @param connection the connection 2895 * @param message the message from dbus_connection_borrow_message() 2896 */ 2897void 2898dbus_connection_steal_borrowed_message (DBusConnection *connection, 2899 DBusMessage *message) 2900{ 2901 DBusMessage *pop_message; 2902 2903 _dbus_return_if_fail (connection != NULL); 2904 _dbus_return_if_fail (message != NULL); 2905 _dbus_return_if_fail (message == connection->message_borrowed); 2906 _dbus_return_if_fail (connection->dispatch_acquired); 2907 2908 CONNECTION_LOCK (connection); 2909 2910 _dbus_assert (message == connection->message_borrowed); 2911 2912 pop_message = _dbus_list_pop_first (&connection->incoming_messages); 2913 _dbus_assert (message == pop_message); 2914 2915 connection->n_incoming -= 1; 2916 2917 _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n", 2918 message, connection->n_incoming); 2919 2920 connection->message_borrowed = NULL; 2921 2922 _dbus_connection_release_dispatch (connection); 2923 2924 CONNECTION_UNLOCK (connection); 2925} 2926 2927/* See dbus_connection_pop_message, but requires the caller to own 2928 * the lock before calling. May drop the lock while running. 2929 */ 2930static DBusList* 2931_dbus_connection_pop_message_link_unlocked (DBusConnection *connection) 2932{ 2933 HAVE_LOCK_CHECK (connection); 2934 2935 _dbus_assert (connection->message_borrowed == NULL); 2936 2937 if (connection->n_incoming > 0) 2938 { 2939 DBusList *link; 2940 2941 link = _dbus_list_pop_first_link (&connection->incoming_messages); 2942 connection->n_incoming -= 1; 2943 2944 _dbus_verbose ("Message %p (%d %s %s %s '%s') removed from incoming queue %p, %d incoming\n", 2945 link->data, 2946 dbus_message_get_type (link->data), 2947 dbus_message_get_path (link->data), 2948 dbus_message_get_interface (link->data) ? 2949 dbus_message_get_interface (link->data) : 2950 "no interface", 2951 dbus_message_get_member (link->data) ? 2952 dbus_message_get_member (link->data) : 2953 "no member", 2954 dbus_message_get_signature (link->data), 2955 connection, connection->n_incoming); 2956 2957 return link; 2958 } 2959 else 2960 return NULL; 2961} 2962 2963/* See dbus_connection_pop_message, but requires the caller to own 2964 * the lock before calling. May drop the lock while running. 2965 */ 2966static DBusMessage* 2967_dbus_connection_pop_message_unlocked (DBusConnection *connection) 2968{ 2969 DBusList *link; 2970 2971 HAVE_LOCK_CHECK (connection); 2972 2973 link = _dbus_connection_pop_message_link_unlocked (connection); 2974 2975 if (link != NULL) 2976 { 2977 DBusMessage *message; 2978 2979 message = link->data; 2980 2981 _dbus_list_free_link (link); 2982 2983 return message; 2984 } 2985 else 2986 return NULL; 2987} 2988 2989static void 2990_dbus_connection_putback_message_link_unlocked (DBusConnection *connection, 2991 DBusList *message_link) 2992{ 2993 HAVE_LOCK_CHECK (connection); 2994 2995 _dbus_assert (message_link != NULL); 2996 /* You can't borrow a message while a link is outstanding */ 2997 _dbus_assert (connection->message_borrowed == NULL); 2998 /* We had to have the dispatch lock across the pop/putback */ 2999 _dbus_assert (connection->dispatch_acquired); 3000 3001 _dbus_list_prepend_link (&connection->incoming_messages, 3002 message_link); 3003 connection->n_incoming += 1; 3004 3005 _dbus_verbose ("Message %p (%d %s %s '%s') put back into queue %p, %d incoming\n", 3006 message_link->data, 3007 dbus_message_get_type (message_link->data), 3008 dbus_message_get_interface (message_link->data) ? 3009 dbus_message_get_interface (message_link->data) : 3010 "no interface", 3011 dbus_message_get_member (message_link->data) ? 3012 dbus_message_get_member (message_link->data) : 3013 "no member", 3014 dbus_message_get_signature (message_link->data), 3015 connection, connection->n_incoming); 3016} 3017 3018/** 3019 * Returns the first-received message from the incoming message queue, 3020 * removing it from the queue. The caller owns a reference to the 3021 * returned message. If the queue is empty, returns #NULL. 3022 * 3023 * This function bypasses any message handlers that are registered, 3024 * and so using it is usually wrong. Instead, let the main loop invoke 3025 * dbus_connection_dispatch(). Popping messages manually is only 3026 * useful in very simple programs that don't share a #DBusConnection 3027 * with any libraries or other modules. 3028 * 3029 * There is a lock that covers all ways of accessing the incoming message 3030 * queue, so dbus_connection_dispatch(), dbus_connection_pop_message(), 3031 * dbus_connection_borrow_message(), etc. will all block while one of the others 3032 * in the group is running. 3033 * 3034 * @param connection the connection. 3035 * @returns next message in the incoming queue. 3036 */ 3037DBusMessage* 3038dbus_connection_pop_message (DBusConnection *connection) 3039{ 3040 DBusMessage *message; 3041 DBusDispatchStatus status; 3042 3043 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME); 3044 3045 /* this is called for the side effect that it queues 3046 * up any messages from the transport 3047 */ 3048 status = dbus_connection_get_dispatch_status (connection); 3049 if (status != DBUS_DISPATCH_DATA_REMAINS) 3050 return NULL; 3051 3052 CONNECTION_LOCK (connection); 3053 _dbus_connection_acquire_dispatch (connection); 3054 HAVE_LOCK_CHECK (connection); 3055 3056 message = _dbus_connection_pop_message_unlocked (connection); 3057 3058 _dbus_verbose ("Returning popped message %p\n", message); 3059 3060 _dbus_connection_release_dispatch (connection); 3061 CONNECTION_UNLOCK (connection); 3062 3063 return message; 3064} 3065 3066/** 3067 * Acquire the dispatcher. This is a separate lock so the main 3068 * connection lock can be dropped to call out to application dispatch 3069 * handlers. 3070 * 3071 * @param connection the connection. 3072 */ 3073static void 3074_dbus_connection_acquire_dispatch (DBusConnection *connection) 3075{ 3076 HAVE_LOCK_CHECK (connection); 3077 3078 _dbus_connection_ref_unlocked (connection); 3079 CONNECTION_UNLOCK (connection); 3080 3081 _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME); 3082 _dbus_mutex_lock (connection->dispatch_mutex); 3083 3084 while (connection->dispatch_acquired) 3085 { 3086 _dbus_verbose ("%s waiting for dispatch to be acquirable\n", _DBUS_FUNCTION_NAME); 3087 _dbus_condvar_wait (connection->dispatch_cond, connection->dispatch_mutex); 3088 } 3089 3090 _dbus_assert (!connection->dispatch_acquired); 3091 3092 connection->dispatch_acquired = TRUE; 3093 3094 _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME); 3095 _dbus_mutex_unlock (connection->dispatch_mutex); 3096 3097 CONNECTION_LOCK (connection); 3098 _dbus_connection_unref_unlocked (connection); 3099} 3100 3101/** 3102 * Release the dispatcher when you're done with it. Only call 3103 * after you've acquired the dispatcher. Wakes up at most one 3104 * thread currently waiting to acquire the dispatcher. 3105 * 3106 * @param connection the connection. 3107 */ 3108static void 3109_dbus_connection_release_dispatch (DBusConnection *connection) 3110{ 3111 HAVE_LOCK_CHECK (connection); 3112 3113 _dbus_verbose ("%s locking dispatch_mutex\n", _DBUS_FUNCTION_NAME); 3114 _dbus_mutex_lock (connection->dispatch_mutex); 3115 3116 _dbus_assert (connection->dispatch_acquired); 3117 3118 connection->dispatch_acquired = FALSE; 3119 _dbus_condvar_wake_one (connection->dispatch_cond); 3120 3121 _dbus_verbose ("%s unlocking dispatch_mutex\n", _DBUS_FUNCTION_NAME); 3122 _dbus_mutex_unlock (connection->dispatch_mutex); 3123} 3124 3125static void 3126_dbus_connection_failed_pop (DBusConnection *connection, 3127 DBusList *message_link) 3128{ 3129 _dbus_list_prepend_link (&connection->incoming_messages, 3130 message_link); 3131 connection->n_incoming += 1; 3132} 3133 3134static DBusDispatchStatus 3135_dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection) 3136{ 3137 HAVE_LOCK_CHECK (connection); 3138 3139 if (connection->n_incoming > 0) 3140 return DBUS_DISPATCH_DATA_REMAINS; 3141 else if (!_dbus_transport_queue_messages (connection->transport)) 3142 return DBUS_DISPATCH_NEED_MEMORY; 3143 else 3144 { 3145 DBusDispatchStatus status; 3146 dbus_bool_t is_connected; 3147 3148 status = _dbus_transport_get_dispatch_status (connection->transport); 3149 is_connected = _dbus_transport_get_is_connected (connection->transport); 3150 3151 _dbus_verbose ("dispatch status = %s is_connected = %d\n", 3152 DISPATCH_STATUS_NAME (status), is_connected); 3153 3154 if (!is_connected) 3155 { 3156 if (status == DBUS_DISPATCH_COMPLETE && 3157 connection->disconnect_message_link) 3158 { 3159 _dbus_verbose ("Sending disconnect message from %s\n", 3160 _DBUS_FUNCTION_NAME); 3161 3162 connection_forget_shared_unlocked (connection); 3163 3164 /* We haven't sent the disconnect message already, 3165 * and all real messages have been queued up. 3166 */ 3167 _dbus_connection_queue_synthesized_message_link (connection, 3168 connection->disconnect_message_link); 3169 connection->disconnect_message_link = NULL; 3170 } 3171 3172 /* Dump the outgoing queue, we aren't going to be able to 3173 * send it now, and we'd like accessors like 3174 * dbus_connection_get_outgoing_size() to be accurate. 3175 */ 3176 if (connection->n_outgoing > 0) 3177 { 3178 DBusList *link; 3179 3180 _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n", 3181 connection->n_outgoing); 3182 3183 while ((link = _dbus_list_get_last_link (&connection->outgoing_messages))) 3184 { 3185 _dbus_connection_message_sent (connection, link->data); 3186 } 3187 } 3188 } 3189 3190 if (status != DBUS_DISPATCH_COMPLETE) 3191 return status; 3192 else if (connection->n_incoming > 0) 3193 return DBUS_DISPATCH_DATA_REMAINS; 3194 else 3195 return DBUS_DISPATCH_COMPLETE; 3196 } 3197} 3198 3199static void 3200_dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection, 3201 DBusDispatchStatus new_status) 3202{ 3203 dbus_bool_t changed; 3204 DBusDispatchStatusFunction function; 3205 void *data; 3206 3207 HAVE_LOCK_CHECK (connection); 3208 3209 _dbus_connection_ref_unlocked (connection); 3210 3211 changed = new_status != connection->last_dispatch_status; 3212 3213 connection->last_dispatch_status = new_status; 3214 3215 function = connection->dispatch_status_function; 3216 data = connection->dispatch_status_data; 3217 3218 /* We drop the lock */ 3219 CONNECTION_UNLOCK (connection); 3220 3221 if (changed && function) 3222 { 3223 _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n", 3224 connection, new_status, 3225 DISPATCH_STATUS_NAME (new_status)); 3226 (* function) (connection, new_status, data); 3227 } 3228 3229 dbus_connection_unref (connection); 3230} 3231 3232/** 3233 * Gets the current state (what we would currently return 3234 * from dbus_connection_dispatch()) but doesn't actually 3235 * dispatch any messages. 3236 * 3237 * @param connection the connection. 3238 * @returns current dispatch status 3239 */ 3240DBusDispatchStatus 3241dbus_connection_get_dispatch_status (DBusConnection *connection) 3242{ 3243 DBusDispatchStatus status; 3244 3245 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE); 3246 3247 _dbus_verbose ("%s start\n", _DBUS_FUNCTION_NAME); 3248 3249 CONNECTION_LOCK (connection); 3250 3251 status = _dbus_connection_get_dispatch_status_unlocked (connection); 3252 3253 CONNECTION_UNLOCK (connection); 3254 3255 return status; 3256} 3257 3258/** 3259 * Processes data buffered while handling watches, queueing zero or 3260 * more incoming messages. Then pops the first-received message from 3261 * the current incoming message queue, runs any handlers for it, and 3262 * unrefs the message. Returns a status indicating whether messages/data 3263 * remain, more memory is needed, or all data has been processed. 3264 * 3265 * Even if the dispatch status is #DBUS_DISPATCH_DATA_REMAINS, 3266 * does not necessarily dispatch a message, as the data may 3267 * be part of authentication or the like. 3268 * 3269 * @todo some FIXME in here about handling DBUS_HANDLER_RESULT_NEED_MEMORY 3270 * 3271 * @todo FIXME what if we call out to application code to handle a 3272 * message, holding the dispatch lock, and the application code runs 3273 * the main loop and dispatches again? Probably deadlocks at the 3274 * moment. Maybe we want a dispatch status of DBUS_DISPATCH_IN_PROGRESS, 3275 * and then the GSource etc. could handle the situation? Right now 3276 * our GSource is NO_RECURSE 3277 * 3278 * @param connection the connection 3279 * @returns dispatch status 3280 */ 3281DBusDispatchStatus 3282dbus_connection_dispatch (DBusConnection *connection) 3283{ 3284 DBusMessage *message; 3285 DBusList *link, *filter_list_copy, *message_link; 3286 DBusHandlerResult result; 3287 DBusPendingCall *pending; 3288 dbus_int32_t reply_serial; 3289 DBusDispatchStatus status; 3290 3291 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE); 3292 3293 _dbus_verbose ("%s\n", _DBUS_FUNCTION_NAME); 3294 3295 CONNECTION_LOCK (connection); 3296 status = _dbus_connection_get_dispatch_status_unlocked (connection); 3297 if (status != DBUS_DISPATCH_DATA_REMAINS) 3298 { 3299 /* unlocks and calls out to user code */ 3300 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 3301 return status; 3302 } 3303 3304 /* We need to ref the connection since the callback could potentially 3305 * drop the last ref to it 3306 */ 3307 _dbus_connection_ref_unlocked (connection); 3308 3309 _dbus_connection_acquire_dispatch (connection); 3310 HAVE_LOCK_CHECK (connection); 3311 3312 message_link = _dbus_connection_pop_message_link_unlocked (connection); 3313 if (message_link == NULL) 3314 { 3315 /* another thread dispatched our stuff */ 3316 3317 _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n"); 3318 3319 _dbus_connection_release_dispatch (connection); 3320 3321 status = _dbus_connection_get_dispatch_status_unlocked (connection); 3322 3323 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 3324 3325 dbus_connection_unref (connection); 3326 3327 return status; 3328 } 3329 3330 message = message_link->data; 3331 3332 _dbus_verbose (" dispatching message %p (%d %s %s '%s')\n", 3333 message, 3334 dbus_message_get_type (message), 3335 dbus_message_get_interface (message) ? 3336 dbus_message_get_interface (message) : 3337 "no interface", 3338 dbus_message_get_member (message) ? 3339 dbus_message_get_member (message) : 3340 "no member", 3341 dbus_message_get_signature (message)); 3342 3343 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 3344 3345 /* Pending call handling must be first, because if you do 3346 * dbus_connection_send_with_reply_and_block() or 3347 * dbus_pending_call_block() then no handlers/filters will be run on 3348 * the reply. We want consistent semantics in the case where we 3349 * dbus_connection_dispatch() the reply. 3350 */ 3351 3352 reply_serial = dbus_message_get_reply_serial (message); 3353 pending = _dbus_hash_table_lookup_int (connection->pending_replies, 3354 reply_serial); 3355 if (pending) 3356 { 3357 _dbus_verbose ("Dispatching a pending reply\n"); 3358 _dbus_pending_call_complete_and_unlock (pending, message); 3359 pending = NULL; /* it's probably unref'd */ 3360 3361 CONNECTION_LOCK (connection); 3362 _dbus_verbose ("pending call completed in dispatch\n"); 3363 result = DBUS_HANDLER_RESULT_HANDLED; 3364 goto out; 3365 } 3366 3367 if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy)) 3368 { 3369 _dbus_connection_release_dispatch (connection); 3370 HAVE_LOCK_CHECK (connection); 3371 3372 _dbus_connection_failed_pop (connection, message_link); 3373 3374 /* unlocks and calls user code */ 3375 _dbus_connection_update_dispatch_status_and_unlock (connection, 3376 DBUS_DISPATCH_NEED_MEMORY); 3377 3378 if (pending) 3379 dbus_pending_call_unref (pending); 3380 dbus_connection_unref (connection); 3381 3382 return DBUS_DISPATCH_NEED_MEMORY; 3383 } 3384 3385 _dbus_list_foreach (&filter_list_copy, 3386 (DBusForeachFunction)_dbus_message_filter_ref, 3387 NULL); 3388 3389 /* We're still protected from dispatch() reentrancy here 3390 * since we acquired the dispatcher 3391 */ 3392 CONNECTION_UNLOCK (connection); 3393 3394 link = _dbus_list_get_first_link (&filter_list_copy); 3395 while (link != NULL) 3396 { 3397 DBusMessageFilter *filter = link->data; 3398 DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link); 3399 3400 _dbus_verbose (" running filter on message %p\n", message); 3401 result = (* filter->function) (connection, message, filter->user_data); 3402 3403 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED) 3404 break; 3405 3406 link = next; 3407 } 3408 3409 _dbus_list_foreach (&filter_list_copy, 3410 (DBusForeachFunction)_dbus_message_filter_unref, 3411 NULL); 3412 _dbus_list_clear (&filter_list_copy); 3413 3414 CONNECTION_LOCK (connection); 3415 3416 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY) 3417 { 3418 _dbus_verbose ("No memory in %s\n", _DBUS_FUNCTION_NAME); 3419 goto out; 3420 } 3421 else if (result == DBUS_HANDLER_RESULT_HANDLED) 3422 { 3423 _dbus_verbose ("filter handled message in dispatch\n"); 3424 goto out; 3425 } 3426 3427 /* We're still protected from dispatch() reentrancy here 3428 * since we acquired the dispatcher 3429 */ 3430 _dbus_verbose (" running object path dispatch on message %p (%d %s %s '%s')\n", 3431 message, 3432 dbus_message_get_type (message), 3433 dbus_message_get_interface (message) ? 3434 dbus_message_get_interface (message) : 3435 "no interface", 3436 dbus_message_get_member (message) ? 3437 dbus_message_get_member (message) : 3438 "no member", 3439 dbus_message_get_signature (message)); 3440 3441 HAVE_LOCK_CHECK (connection); 3442 result = _dbus_object_tree_dispatch_and_unlock (connection->objects, 3443 message); 3444 3445 CONNECTION_LOCK (connection); 3446 3447 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED) 3448 { 3449 _dbus_verbose ("object tree handled message in dispatch\n"); 3450 goto out; 3451 } 3452 3453 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL) 3454 { 3455 DBusMessage *reply; 3456 DBusString str; 3457 DBusPreallocatedSend *preallocated; 3458 3459 _dbus_verbose (" sending error %s\n", 3460 DBUS_ERROR_UNKNOWN_METHOD); 3461 3462 if (!_dbus_string_init (&str)) 3463 { 3464 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 3465 _dbus_verbose ("no memory for error string in dispatch\n"); 3466 goto out; 3467 } 3468 3469 if (!_dbus_string_append_printf (&str, 3470 "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n", 3471 dbus_message_get_member (message), 3472 dbus_message_get_signature (message), 3473 dbus_message_get_interface (message))) 3474 { 3475 _dbus_string_free (&str); 3476 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 3477 _dbus_verbose ("no memory for error string in dispatch\n"); 3478 goto out; 3479 } 3480 3481 reply = dbus_message_new_error (message, 3482 DBUS_ERROR_UNKNOWN_METHOD, 3483 _dbus_string_get_const_data (&str)); 3484 _dbus_string_free (&str); 3485 3486 if (reply == NULL) 3487 { 3488 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 3489 _dbus_verbose ("no memory for error reply in dispatch\n"); 3490 goto out; 3491 } 3492 3493 preallocated = _dbus_connection_preallocate_send_unlocked (connection); 3494 3495 if (preallocated == NULL) 3496 { 3497 dbus_message_unref (reply); 3498 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 3499 _dbus_verbose ("no memory for error send in dispatch\n"); 3500 goto out; 3501 } 3502 3503 _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated, 3504 reply, NULL); 3505 3506 dbus_message_unref (reply); 3507 3508 result = DBUS_HANDLER_RESULT_HANDLED; 3509 } 3510 3511 _dbus_verbose (" done dispatching %p (%d %s %s '%s') on connection %p\n", message, 3512 dbus_message_get_type (message), 3513 dbus_message_get_interface (message) ? 3514 dbus_message_get_interface (message) : 3515 "no interface", 3516 dbus_message_get_member (message) ? 3517 dbus_message_get_member (message) : 3518 "no member", 3519 dbus_message_get_signature (message), 3520 connection); 3521 3522 out: 3523 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY) 3524 { 3525 _dbus_verbose ("out of memory in %s\n", _DBUS_FUNCTION_NAME); 3526 3527 /* Put message back, and we'll start over. 3528 * Yes this means handlers must be idempotent if they 3529 * don't return HANDLED; c'est la vie. 3530 */ 3531 _dbus_connection_putback_message_link_unlocked (connection, 3532 message_link); 3533 } 3534 else 3535 { 3536 _dbus_verbose (" ... done dispatching in %s\n", _DBUS_FUNCTION_NAME); 3537 3538 if (connection->exit_on_disconnect && 3539 dbus_message_is_signal (message, 3540 DBUS_INTERFACE_LOCAL, 3541 "Disconnected")) 3542 { 3543 _dbus_verbose ("Exiting on Disconnected signal\n"); 3544 CONNECTION_UNLOCK (connection); 3545 _dbus_exit (1); 3546 _dbus_assert_not_reached ("Call to exit() returned"); 3547 } 3548 3549 _dbus_list_free_link (message_link); 3550 dbus_message_unref (message); /* don't want the message to count in max message limits 3551 * in computing dispatch status below 3552 */ 3553 } 3554 3555 _dbus_connection_release_dispatch (connection); 3556 HAVE_LOCK_CHECK (connection); 3557 3558 _dbus_verbose ("%s before final status update\n", _DBUS_FUNCTION_NAME); 3559 status = _dbus_connection_get_dispatch_status_unlocked (connection); 3560 3561 /* unlocks and calls user code */ 3562 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 3563 3564 dbus_connection_unref (connection); 3565 3566 return status; 3567} 3568 3569/** 3570 * Sets the watch functions for the connection. These functions are 3571 * responsible for making the application's main loop aware of file 3572 * descriptors that need to be monitored for events, using select() or 3573 * poll(). When using Qt, typically the DBusAddWatchFunction would 3574 * create a QSocketNotifier. When using GLib, the DBusAddWatchFunction 3575 * could call g_io_add_watch(), or could be used as part of a more 3576 * elaborate GSource. Note that when a watch is added, it may 3577 * not be enabled. 3578 * 3579 * The DBusWatchToggledFunction notifies the application that the 3580 * watch has been enabled or disabled. Call dbus_watch_get_enabled() 3581 * to check this. A disabled watch should have no effect, and enabled 3582 * watch should be added to the main loop. This feature is used 3583 * instead of simply adding/removing the watch because 3584 * enabling/disabling can be done without memory allocation. The 3585 * toggled function may be NULL if a main loop re-queries 3586 * dbus_watch_get_enabled() every time anyway. 3587 * 3588 * The DBusWatch can be queried for the file descriptor to watch using 3589 * dbus_watch_get_fd(), and for the events to watch for using 3590 * dbus_watch_get_flags(). The flags returned by 3591 * dbus_watch_get_flags() will only contain DBUS_WATCH_READABLE and 3592 * DBUS_WATCH_WRITABLE, never DBUS_WATCH_HANGUP or DBUS_WATCH_ERROR; 3593 * all watches implicitly include a watch for hangups, errors, and 3594 * other exceptional conditions. 3595 * 3596 * Once a file descriptor becomes readable or writable, or an exception 3597 * occurs, dbus_watch_handle() should be called to 3598 * notify the connection of the file descriptor's condition. 3599 * 3600 * dbus_watch_handle() cannot be called during the 3601 * DBusAddWatchFunction, as the connection will not be ready to handle 3602 * that watch yet. 3603 * 3604 * It is not allowed to reference a DBusWatch after it has been passed 3605 * to remove_function. 3606 * 3607 * If #FALSE is returned due to lack of memory, the failure may be due 3608 * to a #FALSE return from the new add_function. If so, the 3609 * add_function may have been called successfully one or more times, 3610 * but the remove_function will also have been called to remove any 3611 * successful adds. i.e. if #FALSE is returned the net result 3612 * should be that dbus_connection_set_watch_functions() has no effect, 3613 * but the add_function and remove_function may have been called. 3614 * 3615 * @todo We need to drop the lock when we call the 3616 * add/remove/toggled functions which can be a side effect 3617 * of setting the watch functions. 3618 * 3619 * @param connection the connection. 3620 * @param add_function function to begin monitoring a new descriptor. 3621 * @param remove_function function to stop monitoring a descriptor. 3622 * @param toggled_function function to notify of enable/disable 3623 * @param data data to pass to add_function and remove_function. 3624 * @param free_data_function function to be called to free the data. 3625 * @returns #FALSE on failure (no memory) 3626 */ 3627dbus_bool_t 3628dbus_connection_set_watch_functions (DBusConnection *connection, 3629 DBusAddWatchFunction add_function, 3630 DBusRemoveWatchFunction remove_function, 3631 DBusWatchToggledFunction toggled_function, 3632 void *data, 3633 DBusFreeFunction free_data_function) 3634{ 3635 dbus_bool_t retval; 3636 DBusWatchList *watches; 3637 3638 _dbus_return_val_if_fail (connection != NULL, FALSE); 3639 3640 CONNECTION_LOCK (connection); 3641 3642#ifndef DBUS_DISABLE_CHECKS 3643 if (connection->watches == NULL) 3644 { 3645 _dbus_warn ("Re-entrant call to %s is not allowed\n", 3646 _DBUS_FUNCTION_NAME); 3647 return FALSE; 3648 } 3649#endif 3650 3651 /* ref connection for slightly better reentrancy */ 3652 _dbus_connection_ref_unlocked (connection); 3653 3654 /* This can call back into user code, and we need to drop the 3655 * connection lock when it does. This is kind of a lame 3656 * way to do it. 3657 */ 3658 watches = connection->watches; 3659 connection->watches = NULL; 3660 CONNECTION_UNLOCK (connection); 3661 3662 retval = _dbus_watch_list_set_functions (watches, 3663 add_function, remove_function, 3664 toggled_function, 3665 data, free_data_function); 3666 CONNECTION_LOCK (connection); 3667 connection->watches = watches; 3668 3669 CONNECTION_UNLOCK (connection); 3670 /* drop our paranoid refcount */ 3671 dbus_connection_unref (connection); 3672 3673 return retval; 3674} 3675 3676/** 3677 * Sets the timeout functions for the connection. These functions are 3678 * responsible for making the application's main loop aware of timeouts. 3679 * When using Qt, typically the DBusAddTimeoutFunction would create a 3680 * QTimer. When using GLib, the DBusAddTimeoutFunction would call 3681 * g_timeout_add. 3682 * 3683 * The DBusTimeoutToggledFunction notifies the application that the 3684 * timeout has been enabled or disabled. Call 3685 * dbus_timeout_get_enabled() to check this. A disabled timeout should 3686 * have no effect, and enabled timeout should be added to the main 3687 * loop. This feature is used instead of simply adding/removing the 3688 * timeout because enabling/disabling can be done without memory 3689 * allocation. With Qt, QTimer::start() and QTimer::stop() can be used 3690 * to enable and disable. The toggled function may be NULL if a main 3691 * loop re-queries dbus_timeout_get_enabled() every time anyway. 3692 * Whenever a timeout is toggled, its interval may change. 3693 * 3694 * The DBusTimeout can be queried for the timer interval using 3695 * dbus_timeout_get_interval(). dbus_timeout_handle() should be called 3696 * repeatedly, each time the interval elapses, starting after it has 3697 * elapsed once. The timeout stops firing when it is removed with the 3698 * given remove_function. The timer interval may change whenever the 3699 * timeout is added, removed, or toggled. 3700 * 3701 * @param connection the connection. 3702 * @param add_function function to add a timeout. 3703 * @param remove_function function to remove a timeout. 3704 * @param toggled_function function to notify of enable/disable 3705 * @param data data to pass to add_function and remove_function. 3706 * @param free_data_function function to be called to free the data. 3707 * @returns #FALSE on failure (no memory) 3708 */ 3709dbus_bool_t 3710dbus_connection_set_timeout_functions (DBusConnection *connection, 3711 DBusAddTimeoutFunction add_function, 3712 DBusRemoveTimeoutFunction remove_function, 3713 DBusTimeoutToggledFunction toggled_function, 3714 void *data, 3715 DBusFreeFunction free_data_function) 3716{ 3717 dbus_bool_t retval; 3718 DBusTimeoutList *timeouts; 3719 3720 _dbus_return_val_if_fail (connection != NULL, FALSE); 3721 3722 CONNECTION_LOCK (connection); 3723 3724#ifndef DBUS_DISABLE_CHECKS 3725 if (connection->timeouts == NULL) 3726 { 3727 _dbus_warn ("Re-entrant call to %s is not allowed\n", 3728 _DBUS_FUNCTION_NAME); 3729 return FALSE; 3730 } 3731#endif 3732 3733 /* ref connection for slightly better reentrancy */ 3734 _dbus_connection_ref_unlocked (connection); 3735 3736 timeouts = connection->timeouts; 3737 connection->timeouts = NULL; 3738 CONNECTION_UNLOCK (connection); 3739 3740 retval = _dbus_timeout_list_set_functions (timeouts, 3741 add_function, remove_function, 3742 toggled_function, 3743 data, free_data_function); 3744 CONNECTION_LOCK (connection); 3745 connection->timeouts = timeouts; 3746 3747 CONNECTION_UNLOCK (connection); 3748 /* drop our paranoid refcount */ 3749 dbus_connection_unref (connection); 3750 3751 return retval; 3752} 3753 3754/** 3755 * Sets the mainloop wakeup function for the connection. Thi function is 3756 * responsible for waking up the main loop (if its sleeping) when some some 3757 * change has happened to the connection that the mainloop needs to reconsiders 3758 * (e.g. a message has been queued for writing). 3759 * When using Qt, this typically results in a call to QEventLoop::wakeUp(). 3760 * When using GLib, it would call g_main_context_wakeup(). 3761 * 3762 * 3763 * @param connection the connection. 3764 * @param wakeup_main_function function to wake up the mainloop 3765 * @param data data to pass wakeup_main_function 3766 * @param free_data_function function to be called to free the data. 3767 */ 3768void 3769dbus_connection_set_wakeup_main_function (DBusConnection *connection, 3770 DBusWakeupMainFunction wakeup_main_function, 3771 void *data, 3772 DBusFreeFunction free_data_function) 3773{ 3774 void *old_data; 3775 DBusFreeFunction old_free_data; 3776 3777 _dbus_return_if_fail (connection != NULL); 3778 3779 CONNECTION_LOCK (connection); 3780 old_data = connection->wakeup_main_data; 3781 old_free_data = connection->free_wakeup_main_data; 3782 3783 connection->wakeup_main_function = wakeup_main_function; 3784 connection->wakeup_main_data = data; 3785 connection->free_wakeup_main_data = free_data_function; 3786 3787 CONNECTION_UNLOCK (connection); 3788 3789 /* Callback outside the lock */ 3790 if (old_free_data) 3791 (*old_free_data) (old_data); 3792} 3793 3794/** 3795 * Set a function to be invoked when the dispatch status changes. 3796 * If the dispatch status is #DBUS_DISPATCH_DATA_REMAINS, then 3797 * dbus_connection_dispatch() needs to be called to process incoming 3798 * messages. However, dbus_connection_dispatch() MUST NOT BE CALLED 3799 * from inside the DBusDispatchStatusFunction. Indeed, almost 3800 * any reentrancy in this function is a bad idea. Instead, 3801 * the DBusDispatchStatusFunction should simply save an indication 3802 * that messages should be dispatched later, when the main loop 3803 * is re-entered. 3804 * 3805 * @param connection the connection 3806 * @param function function to call on dispatch status changes 3807 * @param data data for function 3808 * @param free_data_function free the function data 3809 */ 3810void 3811dbus_connection_set_dispatch_status_function (DBusConnection *connection, 3812 DBusDispatchStatusFunction function, 3813 void *data, 3814 DBusFreeFunction free_data_function) 3815{ 3816 void *old_data; 3817 DBusFreeFunction old_free_data; 3818 3819 _dbus_return_if_fail (connection != NULL); 3820 3821 CONNECTION_LOCK (connection); 3822 old_data = connection->dispatch_status_data; 3823 old_free_data = connection->free_dispatch_status_data; 3824 3825 connection->dispatch_status_function = function; 3826 connection->dispatch_status_data = data; 3827 connection->free_dispatch_status_data = free_data_function; 3828 3829 CONNECTION_UNLOCK (connection); 3830 3831 /* Callback outside the lock */ 3832 if (old_free_data) 3833 (*old_free_data) (old_data); 3834} 3835 3836/** 3837 * Get the UNIX file descriptor of the connection, if any. This can 3838 * be used for SELinux access control checks with getpeercon() for 3839 * example. DO NOT read or write to the file descriptor, or try to 3840 * select() on it; use DBusWatch for main loop integration. Not all 3841 * connections will have a file descriptor. So for adding descriptors 3842 * to the main loop, use dbus_watch_get_fd() and so forth. 3843 * 3844 * @param connection the connection 3845 * @param fd return location for the file descriptor. 3846 * @returns #TRUE if fd is successfully obtained. 3847 */ 3848dbus_bool_t 3849dbus_connection_get_unix_fd (DBusConnection *connection, 3850 int *fd) 3851{ 3852 dbus_bool_t retval; 3853 3854 _dbus_return_val_if_fail (connection != NULL, FALSE); 3855 _dbus_return_val_if_fail (connection->transport != NULL, FALSE); 3856 3857 CONNECTION_LOCK (connection); 3858 3859 retval = _dbus_transport_get_unix_fd (connection->transport, 3860 fd); 3861 3862 CONNECTION_UNLOCK (connection); 3863 3864 return retval; 3865} 3866 3867/** 3868 * Gets the UNIX user ID of the connection if any. 3869 * Returns #TRUE if the uid is filled in. 3870 * Always returns #FALSE on non-UNIX platforms. 3871 * Always returns #FALSE prior to authenticating the 3872 * connection. 3873 * 3874 * @param connection the connection 3875 * @param uid return location for the user ID 3876 * @returns #TRUE if uid is filled in with a valid user ID 3877 */ 3878dbus_bool_t 3879dbus_connection_get_unix_user (DBusConnection *connection, 3880 unsigned long *uid) 3881{ 3882 dbus_bool_t result; 3883 3884 _dbus_return_val_if_fail (connection != NULL, FALSE); 3885 _dbus_return_val_if_fail (uid != NULL, FALSE); 3886 3887 CONNECTION_LOCK (connection); 3888 3889 if (!_dbus_transport_get_is_authenticated (connection->transport)) 3890 result = FALSE; 3891 else 3892 result = _dbus_transport_get_unix_user (connection->transport, 3893 uid); 3894 CONNECTION_UNLOCK (connection); 3895 3896 return result; 3897} 3898 3899/** 3900 * Gets the process ID of the connection if any. 3901 * Returns #TRUE if the uid is filled in. 3902 * Always returns #FALSE prior to authenticating the 3903 * connection. 3904 * 3905 * @param connection the connection 3906 * @param pid return location for the process ID 3907 * @returns #TRUE if uid is filled in with a valid process ID 3908 */ 3909dbus_bool_t 3910dbus_connection_get_unix_process_id (DBusConnection *connection, 3911 unsigned long *pid) 3912{ 3913 dbus_bool_t result; 3914 3915 _dbus_return_val_if_fail (connection != NULL, FALSE); 3916 _dbus_return_val_if_fail (pid != NULL, FALSE); 3917 3918 CONNECTION_LOCK (connection); 3919 3920 if (!_dbus_transport_get_is_authenticated (connection->transport)) 3921 result = FALSE; 3922 else 3923 result = _dbus_transport_get_unix_process_id (connection->transport, 3924 pid); 3925 CONNECTION_UNLOCK (connection); 3926 3927 return result; 3928} 3929 3930/** 3931 * Sets a predicate function used to determine whether a given user ID 3932 * is allowed to connect. When an incoming connection has 3933 * authenticated with a particular user ID, this function is called; 3934 * if it returns #TRUE, the connection is allowed to proceed, 3935 * otherwise the connection is disconnected. 3936 * 3937 * If the function is set to #NULL (as it is by default), then 3938 * only the same UID as the server process will be allowed to 3939 * connect. 3940 * 3941 * @param connection the connection 3942 * @param function the predicate 3943 * @param data data to pass to the predicate 3944 * @param free_data_function function to free the data 3945 */ 3946void 3947dbus_connection_set_unix_user_function (DBusConnection *connection, 3948 DBusAllowUnixUserFunction function, 3949 void *data, 3950 DBusFreeFunction free_data_function) 3951{ 3952 void *old_data = NULL; 3953 DBusFreeFunction old_free_function = NULL; 3954 3955 _dbus_return_if_fail (connection != NULL); 3956 3957 CONNECTION_LOCK (connection); 3958 _dbus_transport_set_unix_user_function (connection->transport, 3959 function, data, free_data_function, 3960 &old_data, &old_free_function); 3961 CONNECTION_UNLOCK (connection); 3962 3963 if (old_free_function != NULL) 3964 (* old_free_function) (old_data); 3965} 3966 3967/** 3968 * Adds a message filter. Filters are handlers that are run on all 3969 * incoming messages, prior to the objects registered with 3970 * dbus_connection_register_object_path(). Filters are run in the 3971 * order that they were added. The same handler can be added as a 3972 * filter more than once, in which case it will be run more than once. 3973 * Filters added during a filter callback won't be run on the message 3974 * being processed. 3975 * 3976 * @todo we don't run filters on messages while blocking without 3977 * entering the main loop, since filters are run as part of 3978 * dbus_connection_dispatch(). This is probably a feature, as filters 3979 * could create arbitrary reentrancy. But kind of sucks if you're 3980 * trying to filter METHOD_RETURN for some reason. 3981 * 3982 * @param connection the connection 3983 * @param function function to handle messages 3984 * @param user_data user data to pass to the function 3985 * @param free_data_function function to use for freeing user data 3986 * @returns #TRUE on success, #FALSE if not enough memory. 3987 */ 3988dbus_bool_t 3989dbus_connection_add_filter (DBusConnection *connection, 3990 DBusHandleMessageFunction function, 3991 void *user_data, 3992 DBusFreeFunction free_data_function) 3993{ 3994 DBusMessageFilter *filter; 3995 3996 _dbus_return_val_if_fail (connection != NULL, FALSE); 3997 _dbus_return_val_if_fail (function != NULL, FALSE); 3998 3999 filter = dbus_new0 (DBusMessageFilter, 1); 4000 if (filter == NULL) 4001 return FALSE; 4002 4003 filter->refcount.value = 1; 4004 4005 CONNECTION_LOCK (connection); 4006 4007 if (!_dbus_list_append (&connection->filter_list, 4008 filter)) 4009 { 4010 _dbus_message_filter_unref (filter); 4011 CONNECTION_UNLOCK (connection); 4012 return FALSE; 4013 } 4014 4015 /* Fill in filter after all memory allocated, 4016 * so we don't run the free_user_data_function 4017 * if the add_filter() fails 4018 */ 4019 4020 filter->function = function; 4021 filter->user_data = user_data; 4022 filter->free_user_data_function = free_data_function; 4023 4024 CONNECTION_UNLOCK (connection); 4025 return TRUE; 4026} 4027 4028/** 4029 * Removes a previously-added message filter. It is a programming 4030 * error to call this function for a handler that has not been added 4031 * as a filter. If the given handler was added more than once, only 4032 * one instance of it will be removed (the most recently-added 4033 * instance). 4034 * 4035 * @param connection the connection 4036 * @param function the handler to remove 4037 * @param user_data user data for the handler to remove 4038 * 4039 */ 4040void 4041dbus_connection_remove_filter (DBusConnection *connection, 4042 DBusHandleMessageFunction function, 4043 void *user_data) 4044{ 4045 DBusList *link; 4046 DBusMessageFilter *filter; 4047 4048 _dbus_return_if_fail (connection != NULL); 4049 _dbus_return_if_fail (function != NULL); 4050 4051 CONNECTION_LOCK (connection); 4052 4053 filter = NULL; 4054 4055 link = _dbus_list_get_last_link (&connection->filter_list); 4056 while (link != NULL) 4057 { 4058 filter = link->data; 4059 4060 if (filter->function == function && 4061 filter->user_data == user_data) 4062 { 4063 _dbus_list_remove_link (&connection->filter_list, link); 4064 filter->function = NULL; 4065 4066 break; 4067 } 4068 4069 link = _dbus_list_get_prev_link (&connection->filter_list, link); 4070 } 4071 4072 CONNECTION_UNLOCK (connection); 4073 4074#ifndef DBUS_DISABLE_CHECKS 4075 if (filter == NULL) 4076 { 4077 _dbus_warn ("Attempt to remove filter function %p user data %p, but no such filter has been added\n", 4078 function, user_data); 4079 return; 4080 } 4081#endif 4082 4083 /* Call application code */ 4084 if (filter->free_user_data_function) 4085 (* filter->free_user_data_function) (filter->user_data); 4086 4087 filter->free_user_data_function = NULL; 4088 filter->user_data = NULL; 4089 4090 _dbus_message_filter_unref (filter); 4091} 4092 4093/** 4094 * Registers a handler for a given path in the object hierarchy. 4095 * The given vtable handles messages sent to exactly the given path. 4096 * 4097 * 4098 * @param connection the connection 4099 * @param path a '/' delimited string of path elements 4100 * @param vtable the virtual table 4101 * @param user_data data to pass to functions in the vtable 4102 * @returns #FALSE if not enough memory 4103 */ 4104dbus_bool_t 4105dbus_connection_register_object_path (DBusConnection *connection, 4106 const char *path, 4107 const DBusObjectPathVTable *vtable, 4108 void *user_data) 4109{ 4110 char **decomposed_path; 4111 dbus_bool_t retval; 4112 4113 _dbus_return_val_if_fail (connection != NULL, FALSE); 4114 _dbus_return_val_if_fail (path != NULL, FALSE); 4115 _dbus_return_val_if_fail (path[0] == '/', FALSE); 4116 _dbus_return_val_if_fail (vtable != NULL, FALSE); 4117 4118 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) 4119 return FALSE; 4120 4121 CONNECTION_LOCK (connection); 4122 4123 retval = _dbus_object_tree_register (connection->objects, 4124 FALSE, 4125 (const char **) decomposed_path, vtable, 4126 user_data); 4127 4128 CONNECTION_UNLOCK (connection); 4129 4130 dbus_free_string_array (decomposed_path); 4131 4132 return retval; 4133} 4134 4135/** 4136 * Registers a fallback handler for a given subsection of the object 4137 * hierarchy. The given vtable handles messages at or below the given 4138 * path. You can use this to establish a default message handling 4139 * policy for a whole "subdirectory." 4140 * 4141 * @param connection the connection 4142 * @param path a '/' delimited string of path elements 4143 * @param vtable the virtual table 4144 * @param user_data data to pass to functions in the vtable 4145 * @returns #FALSE if not enough memory 4146 */ 4147dbus_bool_t 4148dbus_connection_register_fallback (DBusConnection *connection, 4149 const char *path, 4150 const DBusObjectPathVTable *vtable, 4151 void *user_data) 4152{ 4153 char **decomposed_path; 4154 dbus_bool_t retval; 4155 4156 _dbus_return_val_if_fail (connection != NULL, FALSE); 4157 _dbus_return_val_if_fail (path != NULL, FALSE); 4158 _dbus_return_val_if_fail (path[0] == '/', FALSE); 4159 _dbus_return_val_if_fail (vtable != NULL, FALSE); 4160 4161 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) 4162 return FALSE; 4163 4164 CONNECTION_LOCK (connection); 4165 4166 retval = _dbus_object_tree_register (connection->objects, 4167 TRUE, 4168 (const char **) decomposed_path, vtable, 4169 user_data); 4170 4171 CONNECTION_UNLOCK (connection); 4172 4173 dbus_free_string_array (decomposed_path); 4174 4175 return retval; 4176} 4177 4178/** 4179 * Unregisters the handler registered with exactly the given path. 4180 * It's a bug to call this function for a path that isn't registered. 4181 * Can unregister both fallback paths and object paths. 4182 * 4183 * @param connection the connection 4184 * @param path a '/' delimited string of path elements 4185 * @returns #FALSE if not enough memory 4186 */ 4187dbus_bool_t 4188dbus_connection_unregister_object_path (DBusConnection *connection, 4189 const char *path) 4190{ 4191 char **decomposed_path; 4192 4193 _dbus_return_val_if_fail (connection != NULL, FALSE); 4194 _dbus_return_val_if_fail (path != NULL, FALSE); 4195 _dbus_return_val_if_fail (path[0] == '/', FALSE); 4196 4197 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) 4198 return FALSE; 4199 4200 CONNECTION_LOCK (connection); 4201 4202 _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path); 4203 4204 dbus_free_string_array (decomposed_path); 4205 4206 return TRUE; 4207} 4208 4209/** 4210 * Lists the registered fallback handlers and object path handlers at 4211 * the given parent_path. The returned array should be freed with 4212 * dbus_free_string_array(). 4213 * 4214 * @param connection the connection 4215 * @param parent_path the path to list the child handlers of 4216 * @param child_entries returns #NULL-terminated array of children 4217 * @returns #FALSE if no memory to allocate the child entries 4218 */ 4219dbus_bool_t 4220dbus_connection_list_registered (DBusConnection *connection, 4221 const char *parent_path, 4222 char ***child_entries) 4223{ 4224 char **decomposed_path; 4225 dbus_bool_t retval; 4226 _dbus_return_val_if_fail (connection != NULL, FALSE); 4227 _dbus_return_val_if_fail (parent_path != NULL, FALSE); 4228 _dbus_return_val_if_fail (parent_path[0] == '/', FALSE); 4229 _dbus_return_val_if_fail (child_entries != NULL, FALSE); 4230 4231 if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL)) 4232 return FALSE; 4233 4234 CONNECTION_LOCK (connection); 4235 4236 retval = _dbus_object_tree_list_registered_and_unlock (connection->objects, 4237 (const char **) decomposed_path, 4238 child_entries); 4239 dbus_free_string_array (decomposed_path); 4240 4241 return retval; 4242} 4243 4244static DBusDataSlotAllocator slot_allocator; 4245_DBUS_DEFINE_GLOBAL_LOCK (connection_slots); 4246 4247/** 4248 * Allocates an integer ID to be used for storing application-specific 4249 * data on any DBusConnection. The allocated ID may then be used 4250 * with dbus_connection_set_data() and dbus_connection_get_data(). 4251 * The passed-in slot must be initialized to -1, and is filled in 4252 * with the slot ID. If the passed-in slot is not -1, it's assumed 4253 * to be already allocated, and its refcount is incremented. 4254 * 4255 * The allocated slot is global, i.e. all DBusConnection objects will 4256 * have a slot with the given integer ID reserved. 4257 * 4258 * @param slot_p address of a global variable storing the slot 4259 * @returns #FALSE on failure (no memory) 4260 */ 4261dbus_bool_t 4262dbus_connection_allocate_data_slot (dbus_int32_t *slot_p) 4263{ 4264 return _dbus_data_slot_allocator_alloc (&slot_allocator, 4265 _DBUS_LOCK_NAME (connection_slots), 4266 slot_p); 4267} 4268 4269/** 4270 * Deallocates a global ID for connection data slots. 4271 * dbus_connection_get_data() and dbus_connection_set_data() may no 4272 * longer be used with this slot. Existing data stored on existing 4273 * DBusConnection objects will be freed when the connection is 4274 * finalized, but may not be retrieved (and may only be replaced if 4275 * someone else reallocates the slot). When the refcount on the 4276 * passed-in slot reaches 0, it is set to -1. 4277 * 4278 * @param slot_p address storing the slot to deallocate 4279 */ 4280void 4281dbus_connection_free_data_slot (dbus_int32_t *slot_p) 4282{ 4283 _dbus_return_if_fail (*slot_p >= 0); 4284 4285 _dbus_data_slot_allocator_free (&slot_allocator, slot_p); 4286} 4287 4288/** 4289 * Stores a pointer on a DBusConnection, along 4290 * with an optional function to be used for freeing 4291 * the data when the data is set again, or when 4292 * the connection is finalized. The slot number 4293 * must have been allocated with dbus_connection_allocate_data_slot(). 4294 * 4295 * @param connection the connection 4296 * @param slot the slot number 4297 * @param data the data to store 4298 * @param free_data_func finalizer function for the data 4299 * @returns #TRUE if there was enough memory to store the data 4300 */ 4301dbus_bool_t 4302dbus_connection_set_data (DBusConnection *connection, 4303 dbus_int32_t slot, 4304 void *data, 4305 DBusFreeFunction free_data_func) 4306{ 4307 DBusFreeFunction old_free_func; 4308 void *old_data; 4309 dbus_bool_t retval; 4310 4311 _dbus_return_val_if_fail (connection != NULL, FALSE); 4312 _dbus_return_val_if_fail (slot >= 0, FALSE); 4313 4314 CONNECTION_LOCK (connection); 4315 4316 retval = _dbus_data_slot_list_set (&slot_allocator, 4317 &connection->slot_list, 4318 slot, data, free_data_func, 4319 &old_free_func, &old_data); 4320 4321 CONNECTION_UNLOCK (connection); 4322 4323 if (retval) 4324 { 4325 /* Do the actual free outside the connection lock */ 4326 if (old_free_func) 4327 (* old_free_func) (old_data); 4328 } 4329 4330 return retval; 4331} 4332 4333/** 4334 * Retrieves data previously set with dbus_connection_set_data(). 4335 * The slot must still be allocated (must not have been freed). 4336 * 4337 * @param connection the connection 4338 * @param slot the slot to get data from 4339 * @returns the data, or #NULL if not found 4340 */ 4341void* 4342dbus_connection_get_data (DBusConnection *connection, 4343 dbus_int32_t slot) 4344{ 4345 void *res; 4346 4347 _dbus_return_val_if_fail (connection != NULL, NULL); 4348 4349 CONNECTION_LOCK (connection); 4350 4351 res = _dbus_data_slot_list_get (&slot_allocator, 4352 &connection->slot_list, 4353 slot); 4354 4355 CONNECTION_UNLOCK (connection); 4356 4357 return res; 4358} 4359 4360/** 4361 * This function sets a global flag for whether dbus_connection_new() 4362 * will set SIGPIPE behavior to SIG_IGN. 4363 * 4364 * @param will_modify_sigpipe #TRUE to allow sigpipe to be set to SIG_IGN 4365 */ 4366void 4367dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe) 4368{ 4369 _dbus_modify_sigpipe = will_modify_sigpipe != FALSE; 4370} 4371 4372/** 4373 * Specifies the maximum size message this connection is allowed to 4374 * receive. Larger messages will result in disconnecting the 4375 * connection. 4376 * 4377 * @param connection a #DBusConnection 4378 * @param size maximum message size the connection can receive, in bytes 4379 */ 4380void 4381dbus_connection_set_max_message_size (DBusConnection *connection, 4382 long size) 4383{ 4384 _dbus_return_if_fail (connection != NULL); 4385 4386 CONNECTION_LOCK (connection); 4387 _dbus_transport_set_max_message_size (connection->transport, 4388 size); 4389 CONNECTION_UNLOCK (connection); 4390} 4391 4392/** 4393 * Gets the value set by dbus_connection_set_max_message_size(). 4394 * 4395 * @param connection the connection 4396 * @returns the max size of a single message 4397 */ 4398long 4399dbus_connection_get_max_message_size (DBusConnection *connection) 4400{ 4401 long res; 4402 4403 _dbus_return_val_if_fail (connection != NULL, 0); 4404 4405 CONNECTION_LOCK (connection); 4406 res = _dbus_transport_get_max_message_size (connection->transport); 4407 CONNECTION_UNLOCK (connection); 4408 return res; 4409} 4410 4411/** 4412 * Sets the maximum total number of bytes that can be used for all messages 4413 * received on this connection. Messages count toward the maximum until 4414 * they are finalized. When the maximum is reached, the connection will 4415 * not read more data until some messages are finalized. 4416 * 4417 * The semantics of the maximum are: if outstanding messages are 4418 * already above the maximum, additional messages will not be read. 4419 * The semantics are not: if the next message would cause us to exceed 4420 * the maximum, we don't read it. The reason is that we don't know the 4421 * size of a message until after we read it. 4422 * 4423 * Thus, the max live messages size can actually be exceeded 4424 * by up to the maximum size of a single message. 4425 * 4426 * Also, if we read say 1024 bytes off the wire in a single read(), 4427 * and that contains a half-dozen small messages, we may exceed the 4428 * size max by that amount. But this should be inconsequential. 4429 * 4430 * This does imply that we can't call read() with a buffer larger 4431 * than we're willing to exceed this limit by. 4432 * 4433 * @param connection the connection 4434 * @param size the maximum size in bytes of all outstanding messages 4435 */ 4436void 4437dbus_connection_set_max_received_size (DBusConnection *connection, 4438 long size) 4439{ 4440 _dbus_return_if_fail (connection != NULL); 4441 4442 CONNECTION_LOCK (connection); 4443 _dbus_transport_set_max_received_size (connection->transport, 4444 size); 4445 CONNECTION_UNLOCK (connection); 4446} 4447 4448/** 4449 * Gets the value set by dbus_connection_set_max_received_size(). 4450 * 4451 * @param connection the connection 4452 * @returns the max size of all live messages 4453 */ 4454long 4455dbus_connection_get_max_received_size (DBusConnection *connection) 4456{ 4457 long res; 4458 4459 _dbus_return_val_if_fail (connection != NULL, 0); 4460 4461 CONNECTION_LOCK (connection); 4462 res = _dbus_transport_get_max_received_size (connection->transport); 4463 CONNECTION_UNLOCK (connection); 4464 return res; 4465} 4466 4467/** 4468 * Gets the approximate size in bytes of all messages in the outgoing 4469 * message queue. The size is approximate in that you shouldn't use 4470 * it to decide how many bytes to read off the network or anything 4471 * of that nature, as optimizations may choose to tell small white lies 4472 * to avoid performance overhead. 4473 * 4474 * @param connection the connection 4475 * @returns the number of bytes that have been queued up but not sent 4476 */ 4477long 4478dbus_connection_get_outgoing_size (DBusConnection *connection) 4479{ 4480 long res; 4481 4482 _dbus_return_val_if_fail (connection != NULL, 0); 4483 4484 CONNECTION_LOCK (connection); 4485 res = _dbus_counter_get_value (connection->outgoing_counter); 4486 CONNECTION_UNLOCK (connection); 4487 return res; 4488} 4489 4490/** @} */ 4491