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