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