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