dbus-connection.c revision c9c0adce43caa00345ad2aeb55822eabde523c2c
1/* -*- mode: C; c-file-style: "gnu" -*- */ 2/* dbus-connection.c DBusConnection object 3 * 4 * Copyright (C) 2002, 2003 Red Hat Inc. 5 * 6 * Licensed under the Academic Free License version 2.0 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * 22 */ 23 24#include <config.h> 25#include "dbus-shared.h" 26#include "dbus-connection.h" 27#include "dbus-list.h" 28#include "dbus-timeout.h" 29#include "dbus-transport.h" 30#include "dbus-watch.h" 31#include "dbus-connection-internal.h" 32#include "dbus-list.h" 33#include "dbus-hash.h" 34#include "dbus-message-internal.h" 35#include "dbus-threads.h" 36#include "dbus-protocol.h" 37#include "dbus-dataslot.h" 38#include "dbus-string.h" 39#include "dbus-pending-call.h" 40#include "dbus-object-tree.h" 41#include "dbus-marshal.h" 42 43#if 0 44#define CONNECTION_LOCK(connection) do { \ 45 _dbus_verbose (" LOCK: %s\n", _DBUS_FUNCTION_NAME); \ 46 dbus_mutex_lock ((connection)->mutex); \ 47 } while (0) 48#define CONNECTION_UNLOCK(connection) do { \ 49 _dbus_verbose (" UNLOCK: %s\n", _DBUS_FUNCTION_NAME); \ 50 dbus_mutex_unlock ((connection)->mutex); \ 51 } while (0) 52#else 53#define CONNECTION_LOCK(connection) dbus_mutex_lock ((connection)->mutex) 54#define CONNECTION_UNLOCK(connection) dbus_mutex_unlock ((connection)->mutex) 55#endif 56 57/** 58 * @defgroup DBusConnection DBusConnection 59 * @ingroup DBus 60 * @brief Connection to another application 61 * 62 * A DBusConnection represents a connection to another 63 * application. Messages can be sent and received via this connection. 64 * The other application may be a message bus; for convenience, the 65 * function dbus_bus_get() is provided to automatically open a 66 * connection to the well-known message buses. 67 * 68 * In brief a DBusConnection is a message queue associated with some 69 * message transport mechanism such as a socket. The connection 70 * maintains a queue of incoming messages and a queue of outgoing 71 * messages. 72 * 73 * Incoming messages are normally processed by calling 74 * dbus_connection_dispatch(). dbus_connection_dispatch() runs any 75 * handlers registered for the topmost message in the message queue, 76 * then discards the message, then returns. 77 * 78 * dbus_connection_get_dispatch_status() indicates whether 79 * messages are currently in the queue that need dispatching. 80 * dbus_connection_set_dispatch_status_function() allows 81 * you to set a function to be used to monitor the dispatch status. 82 * 83 * If you're using GLib or Qt add-on libraries for D-BUS, there are 84 * special convenience APIs in those libraries that hide 85 * all the details of dispatch and watch/timeout monitoring. 86 * For example, dbus_connection_setup_with_g_main(). 87 * 88 * If you aren't using these add-on libraries, you have to manually 89 * call dbus_connection_set_dispatch_status_function(), 90 * dbus_connection_set_watch_functions(), 91 * dbus_connection_set_timeout_functions() providing appropriate 92 * functions to integrate the connection with your application's main 93 * loop. 94 * 95 * When you use dbus_connection_send() or one of its variants to send 96 * a message, the message is added to the outgoing queue. It's 97 * actually written to the network later; either in 98 * dbus_watch_handle() invoked by your main loop, or in 99 * dbus_connection_flush() which blocks until it can write out the 100 * entire outgoing queue. The GLib/Qt add-on libraries again 101 * handle the details here for you by setting up watch functions. 102 * 103 * When a connection is disconnected, you are guaranteed to get a 104 * signal "Disconnected" from the interface 105 * #DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL, path 106 * #DBUS_PATH_ORG_FREEDESKTOP_LOCAL. 107 * 108 * You may not drop the last reference to a #DBusConnection 109 * until that connection has been disconnected. 110 * 111 * You may dispatch the unprocessed incoming message queue even if the 112 * connection is disconnected. However, "Disconnected" will always be 113 * the last message in the queue (obviously no messages are received 114 * after disconnection). 115 * 116 * #DBusConnection has thread locks and drops them when invoking user 117 * callbacks, so in general is transparently threadsafe. However, 118 * #DBusMessage does NOT have thread locks; you must not send the same 119 * message to multiple #DBusConnection that will be used from 120 * different threads. 121 */ 122 123/** 124 * @defgroup DBusConnectionInternals DBusConnection implementation details 125 * @ingroup DBusInternals 126 * @brief Implementation details of DBusConnection 127 * 128 * @{ 129 */ 130 131/** 132 * Internal struct representing a message filter function 133 */ 134typedef struct DBusMessageFilter DBusMessageFilter; 135 136/** 137 * Internal struct representing a message filter function 138 */ 139struct DBusMessageFilter 140{ 141 DBusAtomic refcount; /**< Reference count */ 142 DBusHandleMessageFunction function; /**< Function to call to filter */ 143 void *user_data; /**< User data for the function */ 144 DBusFreeFunction free_user_data_function; /**< Function to free the user data */ 145}; 146 147 148/** 149 * Internals of DBusPreallocatedSend 150 */ 151struct DBusPreallocatedSend 152{ 153 DBusConnection *connection; /**< Connection we'd send the message to */ 154 DBusList *queue_link; /**< Preallocated link in the queue */ 155 DBusList *counter_link; /**< Preallocated link in the resource counter */ 156}; 157 158static dbus_bool_t _dbus_modify_sigpipe = TRUE; 159 160/** 161 * Implementation details of DBusConnection. All fields are private. 162 */ 163struct DBusConnection 164{ 165 DBusAtomic refcount; /**< Reference count. */ 166 167 DBusMutex *mutex; /**< Lock on the entire DBusConnection */ 168 169 dbus_bool_t dispatch_acquired; /**< Protects dispatch() */ 170 DBusCondVar *dispatch_cond; /**< Protects dispatch() */ 171 172 dbus_bool_t io_path_acquired; /**< Protects transport io path */ 173 DBusCondVar *io_path_cond; /**< Protects transport io path */ 174 175 DBusList *outgoing_messages; /**< Queue of messages we need to send, send the end of the list first. */ 176 DBusList *incoming_messages; /**< Queue of messages we have received, end of the list received most recently. */ 177 178 DBusMessage *message_borrowed; /**< True if the first incoming message has been borrowed */ 179 DBusCondVar *message_returned_cond; /**< Used with dbus_connection_borrow_message() */ 180 181 int n_outgoing; /**< Length of outgoing queue. */ 182 int n_incoming; /**< Length of incoming queue. */ 183 184 DBusCounter *outgoing_counter; /**< Counts size of outgoing messages. */ 185 186 DBusTransport *transport; /**< Object that sends/receives messages over network. */ 187 DBusWatchList *watches; /**< Stores active watches. */ 188 DBusTimeoutList *timeouts; /**< Stores active timeouts. */ 189 190 DBusList *filter_list; /**< List of filters. */ 191 192 DBusDataSlotList slot_list; /**< Data stored by allocated integer ID */ 193 194 DBusHashTable *pending_replies; /**< Hash of message serials to #DBusPendingCall. */ 195 196 dbus_uint32_t client_serial; /**< Client serial. Increments each time a message is sent */ 197 DBusList *disconnect_message_link; /**< Preallocated list node for queueing the disconnection message */ 198 199 DBusWakeupMainFunction wakeup_main_function; /**< Function to wake up the mainloop */ 200 void *wakeup_main_data; /**< Application data for wakeup_main_function */ 201 DBusFreeFunction free_wakeup_main_data; /**< free wakeup_main_data */ 202 203 DBusDispatchStatusFunction dispatch_status_function; /**< Function on dispatch status changes */ 204 void *dispatch_status_data; /**< Application data for dispatch_status_function */ 205 DBusFreeFunction free_dispatch_status_data; /**< free dispatch_status_data */ 206 207 DBusDispatchStatus last_dispatch_status; /**< The last dispatch status we reported to the application. */ 208 209 DBusList *link_cache; /**< A cache of linked list links to prevent contention 210 * for the global linked list mempool lock 211 */ 212 DBusObjectTree *objects; /**< Object path handlers registered with this connection */ 213 214 unsigned int exit_on_disconnect : 1; /**< If #TRUE, exit after handling disconnect signal */ 215}; 216 217static void _dbus_connection_remove_timeout_locked (DBusConnection *connection, 218 DBusTimeout *timeout); 219static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection); 220static void _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection, 221 DBusDispatchStatus new_status); 222static void _dbus_connection_last_unref (DBusConnection *connection); 223 224static DBusMessageFilter * 225_dbus_message_filter_ref (DBusMessageFilter *filter) 226{ 227 _dbus_assert (filter->refcount.value > 0); 228 _dbus_atomic_inc (&filter->refcount); 229 230 return filter; 231} 232 233static void 234_dbus_message_filter_unref (DBusMessageFilter *filter) 235{ 236 _dbus_assert (filter->refcount.value > 0); 237 238 if (_dbus_atomic_dec (&filter->refcount) == 1) 239 { 240 if (filter->free_user_data_function) 241 (* filter->free_user_data_function) (filter->user_data); 242 243 dbus_free (filter); 244 } 245} 246 247/** 248 * Acquires the connection lock. 249 * 250 * @param connection the connection. 251 */ 252void 253_dbus_connection_lock (DBusConnection *connection) 254{ 255 CONNECTION_LOCK (connection); 256} 257 258/** 259 * Releases the connection lock. 260 * 261 * @param connection the connection. 262 */ 263void 264_dbus_connection_unlock (DBusConnection *connection) 265{ 266 CONNECTION_UNLOCK (connection); 267} 268 269/** 270 * Wakes up the main loop if it is sleeping 271 * Needed if we're e.g. queueing outgoing messages 272 * on a thread while the mainloop sleeps. 273 * 274 * @param connection the connection. 275 */ 276static void 277_dbus_connection_wakeup_mainloop (DBusConnection *connection) 278{ 279 if (connection->wakeup_main_function) 280 (*connection->wakeup_main_function) (connection->wakeup_main_data); 281} 282 283#ifdef DBUS_BUILD_TESTS 284/* For now this function isn't used */ 285/** 286 * Adds a message to the incoming message queue, returning #FALSE 287 * if there's insufficient memory to queue the message. 288 * Does not take over refcount of the message. 289 * 290 * @param connection the connection. 291 * @param message the message to queue. 292 * @returns #TRUE on success. 293 */ 294dbus_bool_t 295_dbus_connection_queue_received_message (DBusConnection *connection, 296 DBusMessage *message) 297{ 298 DBusList *link; 299 300 link = _dbus_list_alloc_link (message); 301 if (link == NULL) 302 return FALSE; 303 304 dbus_message_ref (message); 305 _dbus_connection_queue_received_message_link (connection, link); 306 307 return TRUE; 308} 309#endif 310 311/** 312 * Adds a message-containing list link to the incoming message queue, 313 * taking ownership of the link and the message's current refcount. 314 * Cannot fail due to lack of memory. 315 * 316 * @param connection the connection. 317 * @param link the message link to queue. 318 */ 319void 320_dbus_connection_queue_received_message_link (DBusConnection *connection, 321 DBusList *link) 322{ 323 DBusPendingCall *pending; 324 dbus_int32_t reply_serial; 325 DBusMessage *message; 326 327 _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport)); 328 329 _dbus_list_append_link (&connection->incoming_messages, 330 link); 331 message = link->data; 332 333 /* If this is a reply we're waiting on, remove timeout for it */ 334 reply_serial = dbus_message_get_reply_serial (message); 335 if (reply_serial != -1) 336 { 337 pending = _dbus_hash_table_lookup_int (connection->pending_replies, 338 reply_serial); 339 if (pending != NULL) 340 { 341 if (pending->timeout_added) 342 _dbus_connection_remove_timeout_locked (connection, 343 pending->timeout); 344 345 pending->timeout_added = FALSE; 346 } 347 } 348 349 connection->n_incoming += 1; 350 351 _dbus_connection_wakeup_mainloop (connection); 352 353 _dbus_verbose ("Message %p (%d %s '%s') added to incoming queue %p, %d incoming\n", 354 message, 355 dbus_message_get_type (message), 356 dbus_message_get_interface (message) ? 357 dbus_message_get_interface (message) : 358 "no interface", 359 dbus_message_get_signature (message), 360 connection, 361 connection->n_incoming); 362} 363 364/** 365 * Adds a link + message to the incoming message queue. 366 * Can't fail. Takes ownership of both link and message. 367 * 368 * @param connection the connection. 369 * @param link the list node and message to queue. 370 * 371 * @todo This needs to wake up the mainloop if it is in 372 * a poll/select and this is a multithreaded app. 373 */ 374static void 375_dbus_connection_queue_synthesized_message_link (DBusConnection *connection, 376 DBusList *link) 377{ 378 _dbus_list_append_link (&connection->incoming_messages, link); 379 380 connection->n_incoming += 1; 381 382 _dbus_connection_wakeup_mainloop (connection); 383 384 _dbus_verbose ("Synthesized message %p added to incoming queue %p, %d incoming\n", 385 link->data, connection, connection->n_incoming); 386} 387 388 389/** 390 * Checks whether there are messages in the outgoing message queue. 391 * 392 * @param connection the connection. 393 * @returns #TRUE if the outgoing queue is non-empty. 394 */ 395dbus_bool_t 396_dbus_connection_have_messages_to_send (DBusConnection *connection) 397{ 398 return connection->outgoing_messages != NULL; 399} 400 401/** 402 * Gets the next outgoing message. The message remains in the 403 * queue, and the caller does not own a reference to it. 404 * 405 * @param connection the connection. 406 * @returns the message to be sent. 407 */ 408DBusMessage* 409_dbus_connection_get_message_to_send (DBusConnection *connection) 410{ 411 return _dbus_list_get_last (&connection->outgoing_messages); 412} 413 414/** 415 * Notifies the connection that a message has been sent, so the 416 * message can be removed from the outgoing queue. 417 * Called with the connection lock held. 418 * 419 * @param connection the connection. 420 * @param message the message that was sent. 421 */ 422void 423_dbus_connection_message_sent (DBusConnection *connection, 424 DBusMessage *message) 425{ 426 DBusList *link; 427 428 _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport)); 429 430 link = _dbus_list_get_last_link (&connection->outgoing_messages); 431 _dbus_assert (link != NULL); 432 _dbus_assert (link->data == message); 433 434 /* Save this link in the link cache */ 435 _dbus_list_unlink (&connection->outgoing_messages, 436 link); 437 _dbus_list_prepend_link (&connection->link_cache, link); 438 439 connection->n_outgoing -= 1; 440 441 _dbus_verbose ("Message %p (%d %s '%s') removed from outgoing queue %p, %d left to send\n", 442 message, 443 dbus_message_get_type (message), 444 dbus_message_get_interface (message) ? 445 dbus_message_get_interface (message) : 446 "no interface", 447 dbus_message_get_signature (message), 448 connection, connection->n_outgoing); 449 450 /* Save this link in the link cache also */ 451 _dbus_message_remove_size_counter (message, connection->outgoing_counter, 452 &link); 453 _dbus_list_prepend_link (&connection->link_cache, link); 454 455 dbus_message_unref (message); 456 457 if (connection->n_outgoing == 0) 458 _dbus_transport_messages_pending (connection->transport, 459 connection->n_outgoing); 460} 461 462/** 463 * Adds a watch using the connection's DBusAddWatchFunction if 464 * available. Otherwise records the watch to be added when said 465 * function is available. Also re-adds the watch if the 466 * DBusAddWatchFunction changes. May fail due to lack of memory. 467 * 468 * @param connection the connection. 469 * @param watch the watch to add. 470 * @returns #TRUE on success. 471 */ 472dbus_bool_t 473_dbus_connection_add_watch (DBusConnection *connection, 474 DBusWatch *watch) 475{ 476 if (connection->watches) /* null during finalize */ 477 return _dbus_watch_list_add_watch (connection->watches, 478 watch); 479 else 480 return FALSE; 481} 482 483/** 484 * Removes a watch using the connection's DBusRemoveWatchFunction 485 * if available. It's an error to call this function on a watch 486 * that was not previously added. 487 * 488 * @param connection the connection. 489 * @param watch the watch to remove. 490 */ 491void 492_dbus_connection_remove_watch (DBusConnection *connection, 493 DBusWatch *watch) 494{ 495 if (connection->watches) /* null during finalize */ 496 _dbus_watch_list_remove_watch (connection->watches, 497 watch); 498} 499 500/** 501 * Toggles a watch and notifies app via connection's 502 * DBusWatchToggledFunction if available. It's an error to call this 503 * function on a watch that was not previously added. 504 * 505 * @param connection the connection. 506 * @param watch the watch to toggle. 507 * @param enabled whether to enable or disable 508 */ 509void 510_dbus_connection_toggle_watch (DBusConnection *connection, 511 DBusWatch *watch, 512 dbus_bool_t enabled) 513{ 514 if (connection->watches) /* null during finalize */ 515 _dbus_watch_list_toggle_watch (connection->watches, 516 watch, enabled); 517} 518 519/** 520 * Adds a timeout using the connection's DBusAddTimeoutFunction if 521 * available. Otherwise records the timeout to be added when said 522 * function is available. Also re-adds the timeout if the 523 * DBusAddTimeoutFunction changes. May fail due to lack of memory. 524 * The timeout will fire repeatedly until removed. 525 * 526 * @param connection the connection. 527 * @param timeout the timeout to add. 528 * @returns #TRUE on success. 529 */ 530dbus_bool_t 531_dbus_connection_add_timeout (DBusConnection *connection, 532 DBusTimeout *timeout) 533{ 534 if (connection->timeouts) /* null during finalize */ 535 return _dbus_timeout_list_add_timeout (connection->timeouts, 536 timeout); 537 else 538 return FALSE; 539} 540 541/** 542 * Removes a timeout using the connection's DBusRemoveTimeoutFunction 543 * if available. It's an error to call this function on a timeout 544 * that was not previously added. 545 * 546 * @param connection the connection. 547 * @param timeout the timeout to remove. 548 */ 549void 550_dbus_connection_remove_timeout (DBusConnection *connection, 551 DBusTimeout *timeout) 552{ 553 if (connection->timeouts) /* null during finalize */ 554 _dbus_timeout_list_remove_timeout (connection->timeouts, 555 timeout); 556} 557 558static void 559_dbus_connection_remove_timeout_locked (DBusConnection *connection, 560 DBusTimeout *timeout) 561{ 562 CONNECTION_LOCK (connection); 563 _dbus_connection_remove_timeout (connection, timeout); 564 CONNECTION_UNLOCK (connection); 565} 566 567/** 568 * Toggles a timeout and notifies app via connection's 569 * DBusTimeoutToggledFunction if available. It's an error to call this 570 * function on a timeout that was not previously added. 571 * 572 * @param connection the connection. 573 * @param timeout the timeout to toggle. 574 * @param enabled whether to enable or disable 575 */ 576void 577_dbus_connection_toggle_timeout (DBusConnection *connection, 578 DBusTimeout *timeout, 579 dbus_bool_t enabled) 580{ 581 if (connection->timeouts) /* null during finalize */ 582 _dbus_timeout_list_toggle_timeout (connection->timeouts, 583 timeout, enabled); 584} 585 586static dbus_bool_t 587_dbus_connection_attach_pending_call_unlocked (DBusConnection *connection, 588 DBusPendingCall *pending) 589{ 590 _dbus_assert (pending->reply_serial != 0); 591 592 if (!_dbus_connection_add_timeout (connection, pending->timeout)) 593 return FALSE; 594 595 if (!_dbus_hash_table_insert_int (connection->pending_replies, 596 pending->reply_serial, 597 pending)) 598 { 599 _dbus_connection_remove_timeout (connection, pending->timeout); 600 return FALSE; 601 } 602 603 pending->timeout_added = TRUE; 604 pending->connection = connection; 605 606 dbus_pending_call_ref (pending); 607 608 return TRUE; 609} 610 611static void 612free_pending_call_on_hash_removal (void *data) 613{ 614 DBusPendingCall *pending; 615 616 if (data == NULL) 617 return; 618 619 pending = data; 620 621 if (pending->connection) 622 { 623 if (pending->timeout_added) 624 { 625 _dbus_connection_remove_timeout (pending->connection, 626 pending->timeout); 627 pending->timeout_added = FALSE; 628 } 629 630 pending->connection = NULL; 631 632 dbus_pending_call_unref (pending); 633 } 634} 635 636static void 637_dbus_connection_detach_pending_call_and_unlock (DBusConnection *connection, 638 DBusPendingCall *pending) 639{ 640 /* The idea here is to avoid finalizing the pending call 641 * with the lock held, since there's a destroy notifier 642 * in pending call that goes out to application code. 643 */ 644 dbus_pending_call_ref (pending); 645 _dbus_hash_table_remove_int (connection->pending_replies, 646 pending->reply_serial); 647 CONNECTION_UNLOCK (connection); 648 dbus_pending_call_unref (pending); 649} 650 651/** 652 * Removes a pending call from the connection, such that 653 * the pending reply will be ignored. May drop the last 654 * reference to the pending call. 655 * 656 * @param connection the connection 657 * @param pending the pending call 658 */ 659void 660_dbus_connection_remove_pending_call (DBusConnection *connection, 661 DBusPendingCall *pending) 662{ 663 CONNECTION_LOCK (connection); 664 _dbus_connection_detach_pending_call_and_unlock (connection, pending); 665} 666 667/** 668 * Completes a pending call with the given message, 669 * or if the message is #NULL, by timing out the pending call. 670 * 671 * @param pending the pending call 672 * @param message the message to complete the call with, or #NULL 673 * to time out the call 674 */ 675void 676_dbus_pending_call_complete_and_unlock (DBusPendingCall *pending, 677 DBusMessage *message) 678{ 679 if (message == NULL) 680 { 681 message = pending->timeout_link->data; 682 _dbus_list_clear (&pending->timeout_link); 683 } 684 else 685 dbus_message_ref (message); 686 687 _dbus_verbose (" handing message %p (%s) to pending call serial %u\n", 688 message, 689 dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_RETURN ? 690 "method return" : 691 dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR ? 692 "error" : "other type", 693 pending->reply_serial); 694 695 _dbus_assert (pending->reply == NULL); 696 _dbus_assert (pending->reply_serial == dbus_message_get_reply_serial (message)); 697 pending->reply = message; 698 699 dbus_pending_call_ref (pending); /* in case there's no app with a ref held */ 700 _dbus_connection_detach_pending_call_and_unlock (pending->connection, pending); 701 702 /* Must be called unlocked since it invokes app callback */ 703 _dbus_pending_call_notify (pending); 704 dbus_pending_call_unref (pending); 705} 706 707/** 708 * Acquire the transporter I/O path. This must be done before 709 * doing any I/O in the transporter. May sleep and drop the 710 * connection mutex while waiting for the I/O path. 711 * 712 * @param connection the connection. 713 * @param timeout_milliseconds maximum blocking time, or -1 for no limit. 714 * @returns TRUE if the I/O path was acquired. 715 */ 716static dbus_bool_t 717_dbus_connection_acquire_io_path (DBusConnection *connection, 718 int timeout_milliseconds) 719{ 720 dbus_bool_t res = TRUE; 721 722 if (connection->io_path_acquired) 723 { 724 if (timeout_milliseconds != -1) 725 res = dbus_condvar_wait_timeout (connection->io_path_cond, 726 connection->mutex, 727 timeout_milliseconds); 728 else 729 dbus_condvar_wait (connection->io_path_cond, connection->mutex); 730 } 731 732 if (res) 733 { 734 _dbus_assert (!connection->io_path_acquired); 735 736 connection->io_path_acquired = TRUE; 737 } 738 739 return res; 740} 741 742/** 743 * Release the I/O path when you're done with it. Only call 744 * after you've acquired the I/O. Wakes up at most one thread 745 * currently waiting to acquire the I/O path. 746 * 747 * @param connection the connection. 748 */ 749static void 750_dbus_connection_release_io_path (DBusConnection *connection) 751{ 752 _dbus_assert (connection->io_path_acquired); 753 754 connection->io_path_acquired = FALSE; 755 dbus_condvar_wake_one (connection->io_path_cond); 756} 757 758 759/** 760 * Queues incoming messages and sends outgoing messages for this 761 * connection, optionally blocking in the process. Each call to 762 * _dbus_connection_do_iteration() will call select() or poll() one 763 * time and then read or write data if possible. 764 * 765 * The purpose of this function is to be able to flush outgoing 766 * messages or queue up incoming messages without returning 767 * control to the application and causing reentrancy weirdness. 768 * 769 * The flags parameter allows you to specify whether to 770 * read incoming messages, write outgoing messages, or both, 771 * and whether to block if no immediate action is possible. 772 * 773 * The timeout_milliseconds parameter does nothing unless the 774 * iteration is blocking. 775 * 776 * If there are no outgoing messages and DBUS_ITERATION_DO_READING 777 * wasn't specified, then it's impossible to block, even if 778 * you specify DBUS_ITERATION_BLOCK; in that case the function 779 * returns immediately. 780 * 781 * @param connection the connection. 782 * @param flags iteration flags. 783 * @param timeout_milliseconds maximum blocking time, or -1 for no limit. 784 */ 785void 786_dbus_connection_do_iteration (DBusConnection *connection, 787 unsigned int flags, 788 int timeout_milliseconds) 789{ 790 if (connection->n_outgoing == 0) 791 flags &= ~DBUS_ITERATION_DO_WRITING; 792 793 if (_dbus_connection_acquire_io_path (connection, 794 (flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0)) 795 { 796 _dbus_transport_do_iteration (connection->transport, 797 flags, timeout_milliseconds); 798 _dbus_connection_release_io_path (connection); 799 } 800} 801 802/** 803 * Creates a new connection for the given transport. A transport 804 * represents a message stream that uses some concrete mechanism, such 805 * as UNIX domain sockets. May return #NULL if insufficient 806 * memory exists to create the connection. 807 * 808 * @param transport the transport. 809 * @returns the new connection, or #NULL on failure. 810 */ 811DBusConnection* 812_dbus_connection_new_for_transport (DBusTransport *transport) 813{ 814 DBusConnection *connection; 815 DBusWatchList *watch_list; 816 DBusTimeoutList *timeout_list; 817 DBusHashTable *pending_replies; 818 DBusMutex *mutex; 819 DBusCondVar *message_returned_cond; 820 DBusCondVar *dispatch_cond; 821 DBusCondVar *io_path_cond; 822 DBusList *disconnect_link; 823 DBusMessage *disconnect_message; 824 DBusCounter *outgoing_counter; 825 DBusObjectTree *objects; 826 827 watch_list = NULL; 828 connection = NULL; 829 pending_replies = NULL; 830 timeout_list = NULL; 831 mutex = NULL; 832 message_returned_cond = NULL; 833 dispatch_cond = NULL; 834 io_path_cond = NULL; 835 disconnect_link = NULL; 836 disconnect_message = NULL; 837 outgoing_counter = NULL; 838 objects = NULL; 839 840 watch_list = _dbus_watch_list_new (); 841 if (watch_list == NULL) 842 goto error; 843 844 timeout_list = _dbus_timeout_list_new (); 845 if (timeout_list == NULL) 846 goto error; 847 848 pending_replies = 849 _dbus_hash_table_new (DBUS_HASH_INT, 850 NULL, 851 (DBusFreeFunction)free_pending_call_on_hash_removal); 852 if (pending_replies == NULL) 853 goto error; 854 855 connection = dbus_new0 (DBusConnection, 1); 856 if (connection == NULL) 857 goto error; 858 859 mutex = dbus_mutex_new (); 860 if (mutex == NULL) 861 goto error; 862 863 message_returned_cond = dbus_condvar_new (); 864 if (message_returned_cond == NULL) 865 goto error; 866 867 dispatch_cond = dbus_condvar_new (); 868 if (dispatch_cond == NULL) 869 goto error; 870 871 io_path_cond = dbus_condvar_new (); 872 if (io_path_cond == NULL) 873 goto error; 874 875 disconnect_message = dbus_message_new_signal (DBUS_PATH_ORG_FREEDESKTOP_LOCAL, 876 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL, 877 "Disconnected"); 878 879 if (disconnect_message == NULL) 880 goto error; 881 882 disconnect_link = _dbus_list_alloc_link (disconnect_message); 883 if (disconnect_link == NULL) 884 goto error; 885 886 outgoing_counter = _dbus_counter_new (); 887 if (outgoing_counter == NULL) 888 goto error; 889 890 objects = _dbus_object_tree_new (connection); 891 if (objects == NULL) 892 goto error; 893 894 if (_dbus_modify_sigpipe) 895 _dbus_disable_sigpipe (); 896 897 connection->refcount.value = 1; 898 connection->mutex = mutex; 899 connection->dispatch_cond = dispatch_cond; 900 connection->io_path_cond = io_path_cond; 901 connection->message_returned_cond = message_returned_cond; 902 connection->transport = transport; 903 connection->watches = watch_list; 904 connection->timeouts = timeout_list; 905 connection->pending_replies = pending_replies; 906 connection->outgoing_counter = outgoing_counter; 907 connection->filter_list = NULL; 908 connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE; /* so we're notified first time there's data */ 909 connection->objects = objects; 910 connection->exit_on_disconnect = FALSE; 911 912 _dbus_data_slot_list_init (&connection->slot_list); 913 914 connection->client_serial = 1; 915 916 connection->disconnect_message_link = disconnect_link; 917 918 if (!_dbus_transport_set_connection (transport, connection)) 919 goto error; 920 921 _dbus_transport_ref (transport); 922 923 return connection; 924 925 error: 926 if (disconnect_message != NULL) 927 dbus_message_unref (disconnect_message); 928 929 if (disconnect_link != NULL) 930 _dbus_list_free_link (disconnect_link); 931 932 if (io_path_cond != NULL) 933 dbus_condvar_free (io_path_cond); 934 935 if (dispatch_cond != NULL) 936 dbus_condvar_free (dispatch_cond); 937 938 if (message_returned_cond != NULL) 939 dbus_condvar_free (message_returned_cond); 940 941 if (mutex != NULL) 942 dbus_mutex_free (mutex); 943 944 if (connection != NULL) 945 dbus_free (connection); 946 947 if (pending_replies) 948 _dbus_hash_table_unref (pending_replies); 949 950 if (watch_list) 951 _dbus_watch_list_free (watch_list); 952 953 if (timeout_list) 954 _dbus_timeout_list_free (timeout_list); 955 956 if (outgoing_counter) 957 _dbus_counter_unref (outgoing_counter); 958 959 if (objects) 960 _dbus_object_tree_unref (objects); 961 962 return NULL; 963} 964 965/** 966 * Increments the reference count of a DBusConnection. 967 * Requires that the caller already holds the connection lock. 968 * 969 * @param connection the connection. 970 * @returns the connection. 971 */ 972DBusConnection * 973_dbus_connection_ref_unlocked (DBusConnection *connection) 974{ 975#ifdef DBUS_HAVE_ATOMIC_INT 976 _dbus_atomic_inc (&connection->refcount); 977#else 978 _dbus_assert (connection->refcount.value > 0); 979 connection->refcount.value += 1; 980#endif 981 982 return connection; 983} 984 985/** 986 * Decrements the reference count of a DBusConnection. 987 * Requires that the caller already holds the connection lock. 988 * 989 * @param connection the connection. 990 */ 991void 992_dbus_connection_unref_unlocked (DBusConnection *connection) 993{ 994 dbus_bool_t last_unref; 995 996 _dbus_return_if_fail (connection != NULL); 997 998 /* The connection lock is better than the global 999 * lock in the atomic increment fallback 1000 */ 1001 1002#ifdef DBUS_HAVE_ATOMIC_INT 1003 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1); 1004#else 1005 _dbus_assert (connection->refcount.value > 0); 1006 1007 connection->refcount.value -= 1; 1008 last_unref = (connection->refcount.value == 0); 1009#if 0 1010 printf ("unref_unlocked() connection %p count = %d\n", connection, connection->refcount.value); 1011#endif 1012#endif 1013 1014 if (last_unref) 1015 _dbus_connection_last_unref (connection); 1016} 1017 1018static dbus_uint32_t 1019_dbus_connection_get_next_client_serial (DBusConnection *connection) 1020{ 1021 int serial; 1022 1023 serial = connection->client_serial++; 1024 1025 if (connection->client_serial < 0) 1026 connection->client_serial = 1; 1027 1028 return serial; 1029} 1030 1031/** 1032 * A callback for use with dbus_watch_new() to create a DBusWatch. 1033 * 1034 * @todo This is basically a hack - we could delete _dbus_transport_handle_watch() 1035 * and the virtual handle_watch in DBusTransport if we got rid of it. 1036 * The reason this is some work is threading, see the _dbus_connection_handle_watch() 1037 * implementation. 1038 * 1039 * @param watch the watch. 1040 * @param condition the current condition of the file descriptors being watched. 1041 * @param data must be a pointer to a #DBusConnection 1042 * @returns #FALSE if the IO condition may not have been fully handled due to lack of memory 1043 */ 1044dbus_bool_t 1045_dbus_connection_handle_watch (DBusWatch *watch, 1046 unsigned int condition, 1047 void *data) 1048{ 1049 DBusConnection *connection; 1050 dbus_bool_t retval; 1051 DBusDispatchStatus status; 1052 1053 connection = data; 1054 1055 CONNECTION_LOCK (connection); 1056 _dbus_connection_acquire_io_path (connection, -1); 1057 retval = _dbus_transport_handle_watch (connection->transport, 1058 watch, condition); 1059 _dbus_connection_release_io_path (connection); 1060 1061 status = _dbus_connection_get_dispatch_status_unlocked (connection); 1062 1063 /* this calls out to user code */ 1064 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 1065 1066 return retval; 1067} 1068 1069/** @} */ 1070 1071/** 1072 * @addtogroup DBusConnection 1073 * 1074 * @{ 1075 */ 1076 1077/** 1078 * Opens a new connection to a remote address. 1079 * 1080 * @todo specify what the address parameter is. Right now 1081 * it's just the name of a UNIX domain socket. It should be 1082 * something more complex that encodes which transport to use. 1083 * 1084 * If the open fails, the function returns #NULL, and provides 1085 * a reason for the failure in the result parameter. Pass 1086 * #NULL for the result parameter if you aren't interested 1087 * in the reason for failure. 1088 * 1089 * @param address the address. 1090 * @param error address where an error can be returned. 1091 * @returns new connection, or #NULL on failure. 1092 */ 1093DBusConnection* 1094dbus_connection_open (const char *address, 1095 DBusError *error) 1096{ 1097 DBusConnection *connection; 1098 DBusTransport *transport; 1099 1100 _dbus_return_val_if_fail (address != NULL, NULL); 1101 _dbus_return_val_if_error_is_set (error, NULL); 1102 1103 transport = _dbus_transport_open (address, error); 1104 if (transport == NULL) 1105 { 1106 _DBUS_ASSERT_ERROR_IS_SET (error); 1107 return NULL; 1108 } 1109 1110 connection = _dbus_connection_new_for_transport (transport); 1111 1112 _dbus_transport_unref (transport); 1113 1114 if (connection == NULL) 1115 { 1116 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 1117 return NULL; 1118 } 1119 1120 return connection; 1121} 1122 1123/** 1124 * Increments the reference count of a DBusConnection. 1125 * 1126 * @param connection the connection. 1127 * @returns the connection. 1128 */ 1129DBusConnection * 1130dbus_connection_ref (DBusConnection *connection) 1131{ 1132 _dbus_return_val_if_fail (connection != NULL, NULL); 1133 1134 /* The connection lock is better than the global 1135 * lock in the atomic increment fallback 1136 */ 1137 1138#ifdef DBUS_HAVE_ATOMIC_INT 1139 _dbus_atomic_inc (&connection->refcount); 1140#else 1141 CONNECTION_LOCK (connection); 1142 _dbus_assert (connection->refcount.value > 0); 1143 1144 connection->refcount.value += 1; 1145 CONNECTION_UNLOCK (connection); 1146#endif 1147 1148 return connection; 1149} 1150 1151static void 1152free_outgoing_message (void *element, 1153 void *data) 1154{ 1155 DBusMessage *message = element; 1156 DBusConnection *connection = data; 1157 1158 _dbus_message_remove_size_counter (message, 1159 connection->outgoing_counter, 1160 NULL); 1161 dbus_message_unref (message); 1162} 1163 1164/* This is run without the mutex held, but after the last reference 1165 * to the connection has been dropped we should have no thread-related 1166 * problems 1167 */ 1168static void 1169_dbus_connection_last_unref (DBusConnection *connection) 1170{ 1171 DBusList *link; 1172 1173 _dbus_verbose ("Finalizing connection %p\n", connection); 1174 1175 _dbus_assert (connection->refcount.value == 0); 1176 1177 /* You have to disconnect the connection before unref:ing it. Otherwise 1178 * you won't get the disconnected message. 1179 */ 1180 _dbus_assert (!_dbus_transport_get_is_connected (connection->transport)); 1181 1182 /* ---- We're going to call various application callbacks here, hope it doesn't break anything... */ 1183 _dbus_object_tree_free_all_unlocked (connection->objects); 1184 1185 dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL); 1186 dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL); 1187 dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL); 1188 1189 _dbus_watch_list_free (connection->watches); 1190 connection->watches = NULL; 1191 1192 _dbus_timeout_list_free (connection->timeouts); 1193 connection->timeouts = NULL; 1194 1195 _dbus_data_slot_list_free (&connection->slot_list); 1196 1197 link = _dbus_list_get_first_link (&connection->filter_list); 1198 while (link != NULL) 1199 { 1200 DBusMessageFilter *filter = link->data; 1201 DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link); 1202 1203 filter->function = NULL; 1204 _dbus_message_filter_unref (filter); /* calls app callback */ 1205 link->data = NULL; 1206 1207 link = next; 1208 } 1209 _dbus_list_clear (&connection->filter_list); 1210 1211 /* ---- Done with stuff that invokes application callbacks */ 1212 1213 _dbus_object_tree_unref (connection->objects); 1214 1215 _dbus_hash_table_unref (connection->pending_replies); 1216 connection->pending_replies = NULL; 1217 1218 _dbus_list_clear (&connection->filter_list); 1219 1220 _dbus_list_foreach (&connection->outgoing_messages, 1221 free_outgoing_message, 1222 connection); 1223 _dbus_list_clear (&connection->outgoing_messages); 1224 1225 _dbus_list_foreach (&connection->incoming_messages, 1226 (DBusForeachFunction) dbus_message_unref, 1227 NULL); 1228 _dbus_list_clear (&connection->incoming_messages); 1229 1230 _dbus_counter_unref (connection->outgoing_counter); 1231 1232 _dbus_transport_unref (connection->transport); 1233 1234 if (connection->disconnect_message_link) 1235 { 1236 DBusMessage *message = connection->disconnect_message_link->data; 1237 dbus_message_unref (message); 1238 _dbus_list_free_link (connection->disconnect_message_link); 1239 } 1240 1241 _dbus_list_clear (&connection->link_cache); 1242 1243 dbus_condvar_free (connection->dispatch_cond); 1244 dbus_condvar_free (connection->io_path_cond); 1245 dbus_condvar_free (connection->message_returned_cond); 1246 1247 dbus_mutex_free (connection->mutex); 1248 1249 dbus_free (connection); 1250} 1251 1252/** 1253 * Decrements the reference count of a DBusConnection, and finalizes 1254 * it if the count reaches zero. It is a bug to drop the last reference 1255 * to a connection that has not been disconnected. 1256 * 1257 * @todo in practice it can be quite tricky to never unref a connection 1258 * that's still connected; maybe there's some way we could avoid 1259 * the requirement. 1260 * 1261 * @param connection the connection. 1262 */ 1263void 1264dbus_connection_unref (DBusConnection *connection) 1265{ 1266 dbus_bool_t last_unref; 1267 1268 _dbus_return_if_fail (connection != NULL); 1269 1270 /* The connection lock is better than the global 1271 * lock in the atomic increment fallback 1272 */ 1273 1274#ifdef DBUS_HAVE_ATOMIC_INT 1275 last_unref = (_dbus_atomic_dec (&connection->refcount) == 1); 1276#else 1277 CONNECTION_LOCK (connection); 1278 1279 _dbus_assert (connection->refcount.value > 0); 1280 1281 connection->refcount.value -= 1; 1282 last_unref = (connection->refcount.value == 0); 1283 1284#if 0 1285 printf ("unref() connection %p count = %d\n", connection, connection->refcount.value); 1286#endif 1287 1288 CONNECTION_UNLOCK (connection); 1289#endif 1290 1291 if (last_unref) 1292 _dbus_connection_last_unref (connection); 1293} 1294 1295/** 1296 * Closes the connection, so no further data can be sent or received. 1297 * Any further attempts to send data will result in errors. This 1298 * function does not affect the connection's reference count. It's 1299 * safe to disconnect a connection more than once; all calls after the 1300 * first do nothing. It's impossible to "reconnect" a connection, a 1301 * new connection must be created. This function may result in a call 1302 * to the DBusDispatchStatusFunction set with 1303 * dbus_connection_set_dispatch_status_function(), as the disconnect 1304 * message it generates needs to be dispatched. 1305 * 1306 * @param connection the connection. 1307 */ 1308void 1309dbus_connection_disconnect (DBusConnection *connection) 1310{ 1311 DBusDispatchStatus status; 1312 1313 _dbus_return_if_fail (connection != NULL); 1314 1315 CONNECTION_LOCK (connection); 1316 _dbus_transport_disconnect (connection->transport); 1317 1318 status = _dbus_connection_get_dispatch_status_unlocked (connection); 1319 1320 /* this calls out to user code */ 1321 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 1322} 1323 1324static dbus_bool_t 1325_dbus_connection_get_is_connected_unlocked (DBusConnection *connection) 1326{ 1327 return _dbus_transport_get_is_connected (connection->transport); 1328} 1329 1330/** 1331 * Gets whether the connection is currently connected. All 1332 * connections are connected when they are opened. A connection may 1333 * become disconnected when the remote application closes its end, or 1334 * exits; a connection may also be disconnected with 1335 * dbus_connection_disconnect(). 1336 * 1337 * @param connection the connection. 1338 * @returns #TRUE if the connection is still alive. 1339 */ 1340dbus_bool_t 1341dbus_connection_get_is_connected (DBusConnection *connection) 1342{ 1343 dbus_bool_t res; 1344 1345 _dbus_return_val_if_fail (connection != NULL, FALSE); 1346 1347 CONNECTION_LOCK (connection); 1348 res = _dbus_connection_get_is_connected_unlocked (connection); 1349 CONNECTION_UNLOCK (connection); 1350 1351 return res; 1352} 1353 1354/** 1355 * Gets whether the connection was authenticated. (Note that 1356 * if the connection was authenticated then disconnected, 1357 * this function still returns #TRUE) 1358 * 1359 * @param connection the connection 1360 * @returns #TRUE if the connection was ever authenticated 1361 */ 1362dbus_bool_t 1363dbus_connection_get_is_authenticated (DBusConnection *connection) 1364{ 1365 dbus_bool_t res; 1366 1367 _dbus_return_val_if_fail (connection != NULL, FALSE); 1368 1369 CONNECTION_LOCK (connection); 1370 res = _dbus_transport_get_is_authenticated (connection->transport); 1371 CONNECTION_UNLOCK (connection); 1372 1373 return res; 1374} 1375 1376/** 1377 * Set whether _exit() should be called when the connection receives a 1378 * disconnect signal. The call to _exit() comes after any handlers for 1379 * the disconnect signal run; handlers can cancel the exit by calling 1380 * this function. 1381 * 1382 * By default, exit_on_disconnect is #FALSE; but for message bus 1383 * connections returned from dbus_bus_get() it will be toggled on 1384 * by default. 1385 * 1386 * @param connection the connection 1387 * @param exit_on_disconnect #TRUE if _exit() should be called after a disconnect signal 1388 */ 1389void 1390dbus_connection_set_exit_on_disconnect (DBusConnection *connection, 1391 dbus_bool_t exit_on_disconnect) 1392{ 1393 _dbus_return_if_fail (connection != NULL); 1394 1395 CONNECTION_LOCK (connection); 1396 connection->exit_on_disconnect = exit_on_disconnect != FALSE; 1397 CONNECTION_UNLOCK (connection); 1398} 1399 1400static DBusPreallocatedSend* 1401_dbus_connection_preallocate_send_unlocked (DBusConnection *connection) 1402{ 1403 DBusPreallocatedSend *preallocated; 1404 1405 _dbus_return_val_if_fail (connection != NULL, NULL); 1406 1407 preallocated = dbus_new (DBusPreallocatedSend, 1); 1408 if (preallocated == NULL) 1409 return NULL; 1410 1411 if (connection->link_cache != NULL) 1412 { 1413 preallocated->queue_link = 1414 _dbus_list_pop_first_link (&connection->link_cache); 1415 preallocated->queue_link->data = NULL; 1416 } 1417 else 1418 { 1419 preallocated->queue_link = _dbus_list_alloc_link (NULL); 1420 if (preallocated->queue_link == NULL) 1421 goto failed_0; 1422 } 1423 1424 if (connection->link_cache != NULL) 1425 { 1426 preallocated->counter_link = 1427 _dbus_list_pop_first_link (&connection->link_cache); 1428 preallocated->counter_link->data = connection->outgoing_counter; 1429 } 1430 else 1431 { 1432 preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter); 1433 if (preallocated->counter_link == NULL) 1434 goto failed_1; 1435 } 1436 1437 _dbus_counter_ref (preallocated->counter_link->data); 1438 1439 preallocated->connection = connection; 1440 1441 return preallocated; 1442 1443 failed_1: 1444 _dbus_list_free_link (preallocated->queue_link); 1445 failed_0: 1446 dbus_free (preallocated); 1447 1448 return NULL; 1449} 1450 1451/** 1452 * Preallocates resources needed to send a message, allowing the message 1453 * to be sent without the possibility of memory allocation failure. 1454 * Allows apps to create a future guarantee that they can send 1455 * a message regardless of memory shortages. 1456 * 1457 * @param connection the connection we're preallocating for. 1458 * @returns the preallocated resources, or #NULL 1459 */ 1460DBusPreallocatedSend* 1461dbus_connection_preallocate_send (DBusConnection *connection) 1462{ 1463 DBusPreallocatedSend *preallocated; 1464 1465 _dbus_return_val_if_fail (connection != NULL, NULL); 1466 1467 CONNECTION_LOCK (connection); 1468 1469 preallocated = 1470 _dbus_connection_preallocate_send_unlocked (connection); 1471 1472 CONNECTION_UNLOCK (connection); 1473 1474 return preallocated; 1475} 1476 1477/** 1478 * Frees preallocated message-sending resources from 1479 * dbus_connection_preallocate_send(). Should only 1480 * be called if the preallocated resources are not used 1481 * to send a message. 1482 * 1483 * @param connection the connection 1484 * @param preallocated the resources 1485 */ 1486void 1487dbus_connection_free_preallocated_send (DBusConnection *connection, 1488 DBusPreallocatedSend *preallocated) 1489{ 1490 _dbus_return_if_fail (connection != NULL); 1491 _dbus_return_if_fail (preallocated != NULL); 1492 _dbus_return_if_fail (connection == preallocated->connection); 1493 1494 _dbus_list_free_link (preallocated->queue_link); 1495 _dbus_counter_unref (preallocated->counter_link->data); 1496 _dbus_list_free_link (preallocated->counter_link); 1497 dbus_free (preallocated); 1498} 1499 1500static void 1501_dbus_connection_send_preallocated_unlocked (DBusConnection *connection, 1502 DBusPreallocatedSend *preallocated, 1503 DBusMessage *message, 1504 dbus_uint32_t *client_serial) 1505{ 1506 dbus_uint32_t serial; 1507 1508 preallocated->queue_link->data = message; 1509 _dbus_list_prepend_link (&connection->outgoing_messages, 1510 preallocated->queue_link); 1511 1512 _dbus_message_add_size_counter_link (message, 1513 preallocated->counter_link); 1514 1515 dbus_free (preallocated); 1516 preallocated = NULL; 1517 1518 dbus_message_ref (message); 1519 1520 connection->n_outgoing += 1; 1521 1522 _dbus_verbose ("Message %p (%d %s '%s') added to outgoing queue %p, %d pending to send\n", 1523 message, 1524 dbus_message_get_type (message), 1525 dbus_message_get_interface (message) ? 1526 dbus_message_get_interface (message) : 1527 "no interface", 1528 dbus_message_get_signature (message), 1529 connection, 1530 connection->n_outgoing); 1531 1532 if (dbus_message_get_serial (message) == 0) 1533 { 1534 serial = _dbus_connection_get_next_client_serial (connection); 1535 _dbus_message_set_serial (message, serial); 1536 if (client_serial) 1537 *client_serial = serial; 1538 } 1539 else 1540 { 1541 if (client_serial) 1542 *client_serial = dbus_message_get_serial (message); 1543 } 1544 1545 _dbus_message_lock (message); 1546 1547 if (connection->n_outgoing == 1) 1548 _dbus_transport_messages_pending (connection->transport, 1549 connection->n_outgoing); 1550 1551 _dbus_connection_wakeup_mainloop (connection); 1552} 1553 1554/** 1555 * Sends a message using preallocated resources. This function cannot fail. 1556 * It works identically to dbus_connection_send() in other respects. 1557 * Preallocated resources comes from dbus_connection_preallocate_send(). 1558 * This function "consumes" the preallocated resources, they need not 1559 * be freed separately. 1560 * 1561 * @param connection the connection 1562 * @param preallocated the preallocated resources 1563 * @param message the message to send 1564 * @param client_serial return location for client serial assigned to the message 1565 */ 1566void 1567dbus_connection_send_preallocated (DBusConnection *connection, 1568 DBusPreallocatedSend *preallocated, 1569 DBusMessage *message, 1570 dbus_uint32_t *client_serial) 1571{ 1572 _dbus_return_if_fail (connection != NULL); 1573 _dbus_return_if_fail (preallocated != NULL); 1574 _dbus_return_if_fail (message != NULL); 1575 _dbus_return_if_fail (preallocated->connection == connection); 1576 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL || 1577 (dbus_message_get_interface (message) != NULL && 1578 dbus_message_get_member (message) != NULL)); 1579 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL || 1580 (dbus_message_get_interface (message) != NULL && 1581 dbus_message_get_member (message) != NULL)); 1582 1583 CONNECTION_LOCK (connection); 1584 _dbus_connection_send_preallocated_unlocked (connection, 1585 preallocated, 1586 message, client_serial); 1587 CONNECTION_UNLOCK (connection); 1588} 1589 1590static dbus_bool_t 1591_dbus_connection_send_unlocked (DBusConnection *connection, 1592 DBusMessage *message, 1593 dbus_uint32_t *client_serial) 1594{ 1595 DBusPreallocatedSend *preallocated; 1596 1597 _dbus_assert (connection != NULL); 1598 _dbus_assert (message != NULL); 1599 1600 preallocated = _dbus_connection_preallocate_send_unlocked (connection); 1601 if (preallocated == NULL) 1602 return FALSE; 1603 1604 1605 _dbus_connection_send_preallocated_unlocked (connection, 1606 preallocated, 1607 message, 1608 client_serial); 1609 return TRUE; 1610} 1611 1612/** 1613 * Adds a message to the outgoing message queue. Does not block to 1614 * write the message to the network; that happens asynchronously. To 1615 * force the message to be written, call dbus_connection_flush(). 1616 * Because this only queues the message, the only reason it can 1617 * fail is lack of memory. Even if the connection is disconnected, 1618 * no error will be returned. 1619 * 1620 * If the function fails due to lack of memory, it returns #FALSE. 1621 * The function will never fail for other reasons; even if the 1622 * connection is disconnected, you can queue an outgoing message, 1623 * though obviously it won't be sent. 1624 * 1625 * @param connection the connection. 1626 * @param message the message to write. 1627 * @param client_serial return location for client serial. 1628 * @returns #TRUE on success. 1629 */ 1630dbus_bool_t 1631dbus_connection_send (DBusConnection *connection, 1632 DBusMessage *message, 1633 dbus_uint32_t *client_serial) 1634{ 1635 _dbus_return_val_if_fail (connection != NULL, FALSE); 1636 _dbus_return_val_if_fail (message != NULL, FALSE); 1637 1638 CONNECTION_LOCK (connection); 1639 1640 if (!_dbus_connection_send_unlocked (connection, message, client_serial)) 1641 { 1642 CONNECTION_UNLOCK (connection); 1643 return FALSE; 1644 } 1645 1646 CONNECTION_UNLOCK (connection); 1647 return TRUE; 1648} 1649 1650static dbus_bool_t 1651reply_handler_timeout (void *data) 1652{ 1653 DBusConnection *connection; 1654 DBusDispatchStatus status; 1655 DBusPendingCall *pending = data; 1656 1657 connection = pending->connection; 1658 1659 CONNECTION_LOCK (connection); 1660 if (pending->timeout_link) 1661 { 1662 _dbus_connection_queue_synthesized_message_link (connection, 1663 pending->timeout_link); 1664 pending->timeout_link = NULL; 1665 } 1666 1667 _dbus_connection_remove_timeout (connection, 1668 pending->timeout); 1669 pending->timeout_added = FALSE; 1670 1671 status = _dbus_connection_get_dispatch_status_unlocked (connection); 1672 1673 /* Unlocks, and calls out to user code */ 1674 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 1675 1676 return TRUE; 1677} 1678 1679/** 1680 * Queues a message to send, as with dbus_connection_send_message(), 1681 * but also returns a #DBusPendingCall used to receive a reply to the 1682 * message. If no reply is received in the given timeout_milliseconds, 1683 * this function expires the pending reply and generates a synthetic 1684 * error reply (generated in-process, not by the remote application) 1685 * indicating that a timeout occurred. 1686 * 1687 * A #DBusPendingCall will see a reply message after any filters, but 1688 * before any object instances or other handlers. A #DBusPendingCall 1689 * will always see exactly one reply message, unless it's cancelled 1690 * with dbus_pending_call_cancel(). 1691 * 1692 * If a filter filters out the reply before the handler sees it, the 1693 * reply is immediately timed out and a timeout error reply is 1694 * generated. If a filter removes the timeout error reply then the 1695 * #DBusPendingCall will get confused. Filtering the timeout error 1696 * is thus considered a bug and will print a warning. 1697 * 1698 * If #NULL is passed for the pending_return, the #DBusPendingCall 1699 * will still be generated internally, and used to track 1700 * the message reply timeout. This means a timeout error will 1701 * occur if no reply arrives, unlike with dbus_connection_send(). 1702 * 1703 * If -1 is passed for the timeout, a sane default timeout is used. -1 1704 * is typically the best value for the timeout for this reason, unless 1705 * you want a very short or very long timeout. There is no way to 1706 * avoid a timeout entirely, other than passing INT_MAX for the 1707 * timeout to postpone it indefinitely. 1708 * 1709 * @param connection the connection 1710 * @param message the message to send 1711 * @param pending_return return location for a #DBusPendingCall object, or #NULL 1712 * @param timeout_milliseconds timeout in milliseconds or -1 for default 1713 * @returns #TRUE if the message is successfully queued, #FALSE if no memory. 1714 * 1715 */ 1716dbus_bool_t 1717dbus_connection_send_with_reply (DBusConnection *connection, 1718 DBusMessage *message, 1719 DBusPendingCall **pending_return, 1720 int timeout_milliseconds) 1721{ 1722 DBusPendingCall *pending; 1723 DBusMessage *reply; 1724 DBusList *reply_link; 1725 dbus_int32_t serial = -1; 1726 1727 _dbus_return_val_if_fail (connection != NULL, FALSE); 1728 _dbus_return_val_if_fail (message != NULL, FALSE); 1729 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE); 1730 1731 if (pending_return) 1732 *pending_return = NULL; 1733 1734 pending = _dbus_pending_call_new (connection, 1735 timeout_milliseconds, 1736 reply_handler_timeout); 1737 1738 if (pending == NULL) 1739 return FALSE; 1740 1741 CONNECTION_LOCK (connection); 1742 1743 /* Assign a serial to the message */ 1744 if (dbus_message_get_serial (message) == 0) 1745 { 1746 serial = _dbus_connection_get_next_client_serial (connection); 1747 _dbus_message_set_serial (message, serial); 1748 } 1749 1750 pending->reply_serial = serial; 1751 1752 reply = dbus_message_new_error (message, DBUS_ERROR_NO_REPLY, 1753 "No reply within specified time"); 1754 if (reply == NULL) 1755 goto error; 1756 1757 reply_link = _dbus_list_alloc_link (reply); 1758 if (reply_link == NULL) 1759 { 1760 CONNECTION_UNLOCK (connection); 1761 dbus_message_unref (reply); 1762 goto error_unlocked; 1763 } 1764 1765 pending->timeout_link = reply_link; 1766 1767 /* Insert the serial in the pending replies hash; 1768 * hash takes a refcount on DBusPendingCall. 1769 * Also, add the timeout. 1770 */ 1771 if (!_dbus_connection_attach_pending_call_unlocked (connection, 1772 pending)) 1773 goto error; 1774 1775 if (!_dbus_connection_send_unlocked (connection, message, NULL)) 1776 { 1777 _dbus_connection_detach_pending_call_and_unlock (connection, 1778 pending); 1779 goto error_unlocked; 1780 } 1781 1782 if (pending_return) 1783 *pending_return = pending; 1784 else 1785 dbus_pending_call_unref (pending); 1786 1787 CONNECTION_UNLOCK (connection); 1788 1789 return TRUE; 1790 1791 error: 1792 CONNECTION_UNLOCK (connection); 1793 error_unlocked: 1794 dbus_pending_call_unref (pending); 1795 return FALSE; 1796} 1797 1798static DBusMessage* 1799check_for_reply_unlocked (DBusConnection *connection, 1800 dbus_uint32_t client_serial) 1801{ 1802 DBusList *link; 1803 1804 link = _dbus_list_get_first_link (&connection->incoming_messages); 1805 1806 while (link != NULL) 1807 { 1808 DBusMessage *reply = link->data; 1809 1810 if (dbus_message_get_reply_serial (reply) == client_serial) 1811 { 1812 _dbus_list_remove_link (&connection->incoming_messages, link); 1813 connection->n_incoming -= 1; 1814 return reply; 1815 } 1816 link = _dbus_list_get_next_link (&connection->incoming_messages, link); 1817 } 1818 1819 return NULL; 1820} 1821 1822/** 1823 * Blocks a certain time period while waiting for a reply. 1824 * If no reply arrives, returns #NULL. 1825 * 1826 * @todo could use performance improvements (it keeps scanning 1827 * the whole message queue for example) and has thread issues, 1828 * see comments in source 1829 * 1830 * Does not re-enter the main loop or run filter/path-registered 1831 * callbacks. The reply to the message will not be seen by 1832 * filter callbacks. 1833 * 1834 * @param connection the connection 1835 * @param client_serial the reply serial to wait for 1836 * @param timeout_milliseconds timeout in milliseconds or -1 for default 1837 * @returns the message that is the reply or #NULL if no reply 1838 */ 1839DBusMessage* 1840_dbus_connection_block_for_reply (DBusConnection *connection, 1841 dbus_uint32_t client_serial, 1842 int timeout_milliseconds) 1843{ 1844 long start_tv_sec, start_tv_usec; 1845 long end_tv_sec, end_tv_usec; 1846 long tv_sec, tv_usec; 1847 DBusDispatchStatus status; 1848 1849 _dbus_return_val_if_fail (connection != NULL, NULL); 1850 _dbus_return_val_if_fail (client_serial != 0, NULL); 1851 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE); 1852 1853 if (timeout_milliseconds == -1) 1854 timeout_milliseconds = _DBUS_DEFAULT_TIMEOUT_VALUE; 1855 1856 /* it would probably seem logical to pass in _DBUS_INT_MAX 1857 * for infinite timeout, but then math below would get 1858 * all overflow-prone, so smack that down. 1859 */ 1860 if (timeout_milliseconds > _DBUS_ONE_HOUR_IN_MILLISECONDS * 6) 1861 timeout_milliseconds = _DBUS_ONE_HOUR_IN_MILLISECONDS * 6; 1862 1863 /* Flush message queue */ 1864 dbus_connection_flush (connection); 1865 1866 CONNECTION_LOCK (connection); 1867 1868 _dbus_get_current_time (&start_tv_sec, &start_tv_usec); 1869 end_tv_sec = start_tv_sec + timeout_milliseconds / 1000; 1870 end_tv_usec = start_tv_usec + (timeout_milliseconds % 1000) * 1000; 1871 end_tv_sec += end_tv_usec / _DBUS_USEC_PER_SECOND; 1872 end_tv_usec = end_tv_usec % _DBUS_USEC_PER_SECOND; 1873 1874 _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", 1875 timeout_milliseconds, 1876 client_serial, 1877 start_tv_sec, start_tv_usec, 1878 end_tv_sec, end_tv_usec); 1879 1880 /* Now we wait... */ 1881 /* THREAD TODO: This is busted. What if a dispatch() or pop_message 1882 * gets the message before we do? 1883 */ 1884 /* always block at least once as we know we don't have the reply yet */ 1885 _dbus_connection_do_iteration (connection, 1886 DBUS_ITERATION_DO_READING | 1887 DBUS_ITERATION_BLOCK, 1888 timeout_milliseconds); 1889 1890 recheck_status: 1891 1892 /* queue messages and get status */ 1893 status = _dbus_connection_get_dispatch_status_unlocked (connection); 1894 1895 if (status == DBUS_DISPATCH_DATA_REMAINS) 1896 { 1897 DBusMessage *reply; 1898 1899 reply = check_for_reply_unlocked (connection, client_serial); 1900 if (reply != NULL) 1901 { 1902 status = _dbus_connection_get_dispatch_status_unlocked (connection); 1903 1904 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n"); 1905 1906 /* Unlocks, and calls out to user code */ 1907 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 1908 1909 return reply; 1910 } 1911 } 1912 1913 _dbus_get_current_time (&tv_sec, &tv_usec); 1914 1915 if (!_dbus_connection_get_is_connected_unlocked (connection)) 1916 return NULL; 1917 else if (tv_sec < start_tv_sec) 1918 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n"); 1919 else if (connection->disconnect_message_link == NULL) 1920 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n"); 1921 else if (tv_sec < end_tv_sec || 1922 (tv_sec == end_tv_sec && tv_usec < end_tv_usec)) 1923 { 1924 timeout_milliseconds = (end_tv_sec - tv_sec) * 1000 + 1925 (end_tv_usec - tv_usec) / 1000; 1926 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds); 1927 _dbus_assert (timeout_milliseconds >= 0); 1928 1929 if (status == DBUS_DISPATCH_NEED_MEMORY) 1930 { 1931 /* Try sleeping a bit, as we aren't sure we need to block for reading, 1932 * we may already have a reply in the buffer and just can't process 1933 * it. 1934 */ 1935 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n"); 1936 1937 if (timeout_milliseconds < 100) 1938 ; /* just busy loop */ 1939 else if (timeout_milliseconds <= 1000) 1940 _dbus_sleep_milliseconds (timeout_milliseconds / 3); 1941 else 1942 _dbus_sleep_milliseconds (1000); 1943 } 1944 else 1945 { 1946 /* block again, we don't have the reply buffered yet. */ 1947 _dbus_connection_do_iteration (connection, 1948 DBUS_ITERATION_DO_READING | 1949 DBUS_ITERATION_BLOCK, 1950 timeout_milliseconds); 1951 } 1952 1953 goto recheck_status; 1954 } 1955 1956 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %ld milliseconds and got no reply\n", 1957 (tv_sec - start_tv_sec) * 1000 + (tv_usec - start_tv_usec) / 1000); 1958 1959 /* unlocks and calls out to user code */ 1960 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 1961 1962 return NULL; 1963} 1964 1965/** 1966 * Sends a message and blocks a certain time period while waiting for 1967 * a reply. This function does not reenter the main loop, 1968 * i.e. messages other than the reply are queued up but not 1969 * processed. This function is used to do non-reentrant "method 1970 * calls." 1971 * 1972 * If a normal reply is received, it is returned, and removed from the 1973 * incoming message queue. If it is not received, #NULL is returned 1974 * and the error is set to #DBUS_ERROR_NO_REPLY. If an error reply is 1975 * received, it is converted to a #DBusError and returned as an error, 1976 * then the reply message is deleted. If something else goes wrong, 1977 * result is set to whatever is appropriate, such as 1978 * #DBUS_ERROR_NO_MEMORY or #DBUS_ERROR_DISCONNECTED. 1979 * 1980 * @param connection the connection 1981 * @param message the message to send 1982 * @param timeout_milliseconds timeout in milliseconds or -1 for default 1983 * @param error return location for error message 1984 * @returns the message that is the reply or #NULL with an error code if the 1985 * function fails. 1986 */ 1987DBusMessage * 1988dbus_connection_send_with_reply_and_block (DBusConnection *connection, 1989 DBusMessage *message, 1990 int timeout_milliseconds, 1991 DBusError *error) 1992{ 1993 dbus_uint32_t client_serial; 1994 DBusMessage *reply; 1995 1996 _dbus_return_val_if_fail (connection != NULL, NULL); 1997 _dbus_return_val_if_fail (message != NULL, NULL); 1998 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE); 1999 _dbus_return_val_if_error_is_set (error, NULL); 2000 2001 if (!dbus_connection_send (connection, message, &client_serial)) 2002 { 2003 _DBUS_SET_OOM (error); 2004 return NULL; 2005 } 2006 2007 reply = _dbus_connection_block_for_reply (connection, 2008 client_serial, 2009 timeout_milliseconds); 2010 2011 if (reply == NULL) 2012 { 2013 if (dbus_connection_get_is_connected (connection)) 2014 dbus_set_error (error, DBUS_ERROR_NO_REPLY, "Message did not receive a reply"); 2015 else 2016 dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Disconnected prior to receiving a reply"); 2017 2018 return NULL; 2019 } 2020 else if (dbus_set_error_from_message (error, reply)) 2021 { 2022 dbus_message_unref (reply); 2023 return NULL; 2024 } 2025 else 2026 return reply; 2027} 2028 2029/** 2030 * Blocks until the outgoing message queue is empty. 2031 * 2032 * @param connection the connection. 2033 */ 2034void 2035dbus_connection_flush (DBusConnection *connection) 2036{ 2037 /* We have to specify DBUS_ITERATION_DO_READING here because 2038 * otherwise we could have two apps deadlock if they are both doing 2039 * a flush(), and the kernel buffers fill up. This could change the 2040 * dispatch status. 2041 */ 2042 DBusDispatchStatus status; 2043 2044 _dbus_return_if_fail (connection != NULL); 2045 2046 CONNECTION_LOCK (connection); 2047 while (connection->n_outgoing > 0 && 2048 _dbus_connection_get_is_connected_unlocked (connection)) 2049 _dbus_connection_do_iteration (connection, 2050 DBUS_ITERATION_DO_READING | 2051 DBUS_ITERATION_DO_WRITING | 2052 DBUS_ITERATION_BLOCK, 2053 -1); 2054 2055 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2056 2057 /* Unlocks and calls out to user code */ 2058 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2059} 2060 2061/* Call with mutex held. Will drop it while waiting and re-acquire 2062 * before returning 2063 */ 2064static void 2065_dbus_connection_wait_for_borrowed (DBusConnection *connection) 2066{ 2067 _dbus_assert (connection->message_borrowed != NULL); 2068 2069 while (connection->message_borrowed != NULL) 2070 dbus_condvar_wait (connection->message_returned_cond, connection->mutex); 2071} 2072 2073/** 2074 * Returns the first-received message from the incoming message queue, 2075 * leaving it in the queue. If the queue is empty, returns #NULL. 2076 * 2077 * The caller does not own a reference to the returned message, and 2078 * must either return it using dbus_connection_return_message() or 2079 * keep it after calling dbus_connection_steal_borrowed_message(). No 2080 * one can get at the message while its borrowed, so return it as 2081 * quickly as possible and don't keep a reference to it after 2082 * returning it. If you need to keep the message, make a copy of it. 2083 * 2084 * @param connection the connection. 2085 * @returns next message in the incoming queue. 2086 */ 2087DBusMessage* 2088dbus_connection_borrow_message (DBusConnection *connection) 2089{ 2090 DBusMessage *message; 2091 DBusDispatchStatus status; 2092 2093 _dbus_return_val_if_fail (connection != NULL, NULL); 2094 /* can't borrow during dispatch */ 2095 _dbus_return_val_if_fail (!connection->dispatch_acquired, NULL); 2096 2097 /* this is called for the side effect that it queues 2098 * up any messages from the transport 2099 */ 2100 status = dbus_connection_get_dispatch_status (connection); 2101 if (status != DBUS_DISPATCH_DATA_REMAINS) 2102 return NULL; 2103 2104 CONNECTION_LOCK (connection); 2105 2106 if (connection->message_borrowed != NULL) 2107 _dbus_connection_wait_for_borrowed (connection); 2108 2109 message = _dbus_list_get_first (&connection->incoming_messages); 2110 2111 if (message) 2112 connection->message_borrowed = message; 2113 2114 CONNECTION_UNLOCK (connection); 2115 return message; 2116} 2117 2118/** 2119 * Used to return a message after peeking at it using 2120 * dbus_connection_borrow_message(). 2121 * 2122 * @param connection the connection 2123 * @param message the message from dbus_connection_borrow_message() 2124 */ 2125void 2126dbus_connection_return_message (DBusConnection *connection, 2127 DBusMessage *message) 2128{ 2129 _dbus_return_if_fail (connection != NULL); 2130 _dbus_return_if_fail (message != NULL); 2131 /* can't borrow during dispatch */ 2132 _dbus_return_if_fail (!connection->dispatch_acquired); 2133 2134 CONNECTION_LOCK (connection); 2135 2136 _dbus_assert (message == connection->message_borrowed); 2137 2138 connection->message_borrowed = NULL; 2139 dbus_condvar_wake_all (connection->message_returned_cond); 2140 2141 CONNECTION_UNLOCK (connection); 2142} 2143 2144/** 2145 * Used to keep a message after peeking at it using 2146 * dbus_connection_borrow_message(). Before using this function, see 2147 * the caveats/warnings in the documentation for 2148 * dbus_connection_pop_message(). 2149 * 2150 * @param connection the connection 2151 * @param message the message from dbus_connection_borrow_message() 2152 */ 2153void 2154dbus_connection_steal_borrowed_message (DBusConnection *connection, 2155 DBusMessage *message) 2156{ 2157 DBusMessage *pop_message; 2158 2159 _dbus_return_if_fail (connection != NULL); 2160 _dbus_return_if_fail (message != NULL); 2161 /* can't borrow during dispatch */ 2162 _dbus_return_if_fail (!connection->dispatch_acquired); 2163 2164 CONNECTION_LOCK (connection); 2165 2166 _dbus_assert (message == connection->message_borrowed); 2167 2168 pop_message = _dbus_list_pop_first (&connection->incoming_messages); 2169 _dbus_assert (message == pop_message); 2170 2171 connection->n_incoming -= 1; 2172 2173 _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n", 2174 message, connection->n_incoming); 2175 2176 connection->message_borrowed = NULL; 2177 dbus_condvar_wake_all (connection->message_returned_cond); 2178 2179 CONNECTION_UNLOCK (connection); 2180} 2181 2182/* See dbus_connection_pop_message, but requires the caller to own 2183 * the lock before calling. May drop the lock while running. 2184 */ 2185static DBusList* 2186_dbus_connection_pop_message_link_unlocked (DBusConnection *connection) 2187{ 2188 if (connection->message_borrowed != NULL) 2189 _dbus_connection_wait_for_borrowed (connection); 2190 2191 if (connection->n_incoming > 0) 2192 { 2193 DBusList *link; 2194 2195 link = _dbus_list_pop_first_link (&connection->incoming_messages); 2196 connection->n_incoming -= 1; 2197 2198 _dbus_verbose ("Message %p (%d %s '%s') removed from incoming queue %p, %d incoming\n", 2199 link->data, 2200 dbus_message_get_type (link->data), 2201 dbus_message_get_interface (link->data) ? 2202 dbus_message_get_interface (link->data) : 2203 "no interface", 2204 dbus_message_get_signature (link->data), 2205 connection, connection->n_incoming); 2206 2207 return link; 2208 } 2209 else 2210 return NULL; 2211} 2212 2213/* See dbus_connection_pop_message, but requires the caller to own 2214 * the lock before calling. May drop the lock while running. 2215 */ 2216static DBusMessage* 2217_dbus_connection_pop_message_unlocked (DBusConnection *connection) 2218{ 2219 DBusList *link; 2220 2221 link = _dbus_connection_pop_message_link_unlocked (connection); 2222 2223 if (link != NULL) 2224 { 2225 DBusMessage *message; 2226 2227 message = link->data; 2228 2229 _dbus_list_free_link (link); 2230 2231 return message; 2232 } 2233 else 2234 return NULL; 2235} 2236 2237static void 2238_dbus_connection_putback_message_link_unlocked (DBusConnection *connection, 2239 DBusList *message_link) 2240{ 2241 _dbus_assert (message_link != NULL); 2242 /* You can't borrow a message while a link is outstanding */ 2243 _dbus_assert (connection->message_borrowed == NULL); 2244 2245 _dbus_list_prepend_link (&connection->incoming_messages, 2246 message_link); 2247 connection->n_incoming += 1; 2248 2249 _dbus_verbose ("Message %p (%d %s '%s') put back into queue %p, %d incoming\n", 2250 message_link->data, 2251 dbus_message_get_type (message_link->data), 2252 dbus_message_get_interface (message_link->data) ? 2253 dbus_message_get_interface (message_link->data) : 2254 "no interface", 2255 dbus_message_get_signature (message_link->data), 2256 connection, connection->n_incoming); 2257} 2258 2259/** 2260 * Returns the first-received message from the incoming message queue, 2261 * removing it from the queue. The caller owns a reference to the 2262 * returned message. If the queue is empty, returns #NULL. 2263 * 2264 * This function bypasses any message handlers that are registered, 2265 * and so using it is usually wrong. Instead, let the main loop invoke 2266 * dbus_connection_dispatch(). Popping messages manually is only 2267 * useful in very simple programs that don't share a #DBusConnection 2268 * with any libraries or other modules. 2269 * 2270 * @param connection the connection. 2271 * @returns next message in the incoming queue. 2272 */ 2273DBusMessage* 2274dbus_connection_pop_message (DBusConnection *connection) 2275{ 2276 DBusMessage *message; 2277 DBusDispatchStatus status; 2278 2279 /* this is called for the side effect that it queues 2280 * up any messages from the transport 2281 */ 2282 status = dbus_connection_get_dispatch_status (connection); 2283 if (status != DBUS_DISPATCH_DATA_REMAINS) 2284 return NULL; 2285 2286 CONNECTION_LOCK (connection); 2287 2288 message = _dbus_connection_pop_message_unlocked (connection); 2289 2290 _dbus_verbose ("Returning popped message %p\n", message); 2291 2292 CONNECTION_UNLOCK (connection); 2293 2294 return message; 2295} 2296 2297/** 2298 * Acquire the dispatcher. This must be done before dispatching 2299 * messages in order to guarantee the right order of 2300 * message delivery. May sleep and drop the connection mutex 2301 * while waiting for the dispatcher. 2302 * 2303 * @param connection the connection. 2304 */ 2305static void 2306_dbus_connection_acquire_dispatch (DBusConnection *connection) 2307{ 2308 if (connection->dispatch_acquired) 2309 dbus_condvar_wait (connection->dispatch_cond, connection->mutex); 2310 _dbus_assert (!connection->dispatch_acquired); 2311 2312 connection->dispatch_acquired = TRUE; 2313} 2314 2315/** 2316 * Release the dispatcher when you're done with it. Only call 2317 * after you've acquired the dispatcher. Wakes up at most one 2318 * thread currently waiting to acquire the dispatcher. 2319 * 2320 * @param connection the connection. 2321 */ 2322static void 2323_dbus_connection_release_dispatch (DBusConnection *connection) 2324{ 2325 _dbus_assert (connection->dispatch_acquired); 2326 2327 connection->dispatch_acquired = FALSE; 2328 dbus_condvar_wake_one (connection->dispatch_cond); 2329} 2330 2331static void 2332_dbus_connection_failed_pop (DBusConnection *connection, 2333 DBusList *message_link) 2334{ 2335 _dbus_list_prepend_link (&connection->incoming_messages, 2336 message_link); 2337 connection->n_incoming += 1; 2338} 2339 2340static DBusDispatchStatus 2341_dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection) 2342{ 2343 if (connection->n_incoming > 0) 2344 return DBUS_DISPATCH_DATA_REMAINS; 2345 else if (!_dbus_transport_queue_messages (connection->transport)) 2346 return DBUS_DISPATCH_NEED_MEMORY; 2347 else 2348 { 2349 DBusDispatchStatus status; 2350 2351 status = _dbus_transport_get_dispatch_status (connection->transport); 2352 2353 if (status == DBUS_DISPATCH_COMPLETE && 2354 connection->disconnect_message_link && 2355 !_dbus_transport_get_is_connected (connection->transport)) 2356 { 2357 /* We haven't sent the disconnect message already, 2358 * and all real messages have been queued up. 2359 */ 2360 _dbus_connection_queue_synthesized_message_link (connection, 2361 connection->disconnect_message_link); 2362 connection->disconnect_message_link = NULL; 2363 } 2364 2365 if (status != DBUS_DISPATCH_COMPLETE) 2366 return status; 2367 else if (connection->n_incoming > 0) 2368 return DBUS_DISPATCH_DATA_REMAINS; 2369 else 2370 return DBUS_DISPATCH_COMPLETE; 2371 } 2372} 2373 2374static void 2375_dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection, 2376 DBusDispatchStatus new_status) 2377{ 2378 dbus_bool_t changed; 2379 DBusDispatchStatusFunction function; 2380 void *data; 2381 2382 /* We have the lock */ 2383 2384 _dbus_connection_ref_unlocked (connection); 2385 2386 changed = new_status != connection->last_dispatch_status; 2387 2388 connection->last_dispatch_status = new_status; 2389 2390 function = connection->dispatch_status_function; 2391 data = connection->dispatch_status_data; 2392 2393 /* We drop the lock */ 2394 CONNECTION_UNLOCK (connection); 2395 2396 if (changed && function) 2397 { 2398 _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n", 2399 connection, new_status, 2400 new_status == DBUS_DISPATCH_COMPLETE ? "complete" : 2401 new_status == DBUS_DISPATCH_DATA_REMAINS ? "data remains" : 2402 new_status == DBUS_DISPATCH_NEED_MEMORY ? "need memory" : 2403 "???"); 2404 (* function) (connection, new_status, data); 2405 } 2406 2407 dbus_connection_unref (connection); 2408} 2409 2410/** 2411 * Gets the current state (what we would currently return 2412 * from dbus_connection_dispatch()) but doesn't actually 2413 * dispatch any messages. 2414 * 2415 * @param connection the connection. 2416 * @returns current dispatch status 2417 */ 2418DBusDispatchStatus 2419dbus_connection_get_dispatch_status (DBusConnection *connection) 2420{ 2421 DBusDispatchStatus status; 2422 2423 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE); 2424 2425 CONNECTION_LOCK (connection); 2426 2427 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2428 2429 CONNECTION_UNLOCK (connection); 2430 2431 return status; 2432} 2433 2434/** 2435 * Processes data buffered while handling watches, queueing zero or 2436 * more incoming messages. Then pops the first-received message from 2437 * the current incoming message queue, runs any handlers for it, and 2438 * unrefs the message. Returns a status indicating whether messages/data 2439 * remain, more memory is needed, or all data has been processed. 2440 * 2441 * Even if the dispatch status is #DBUS_DISPATCH_DATA_REMAINS, 2442 * does not necessarily dispatch a message, as the data may 2443 * be part of authentication or the like. 2444 * 2445 * @todo some FIXME in here about handling DBUS_HANDLER_RESULT_NEED_MEMORY 2446 * 2447 * @todo right now a message filter gets run on replies to a pending 2448 * call in here, but not in the case where we block without entering 2449 * the main loop. Simple solution might be to just have the pending 2450 * call stuff run before the filters. 2451 * 2452 * @todo FIXME what if we call out to application code to handle a 2453 * message, holding the dispatch lock, and the application code runs 2454 * the main loop and dispatches again? Probably deadlocks at the 2455 * moment. Maybe we want a dispatch status of DBUS_DISPATCH_IN_PROGRESS, 2456 * and then the GSource etc. could handle the situation? 2457 * 2458 * @param connection the connection 2459 * @returns dispatch status 2460 */ 2461DBusDispatchStatus 2462dbus_connection_dispatch (DBusConnection *connection) 2463{ 2464 DBusMessage *message; 2465 DBusList *link, *filter_list_copy, *message_link; 2466 DBusHandlerResult result; 2467 DBusPendingCall *pending; 2468 dbus_int32_t reply_serial; 2469 DBusDispatchStatus status; 2470 2471 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE); 2472 2473 CONNECTION_LOCK (connection); 2474 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2475 if (status != DBUS_DISPATCH_DATA_REMAINS) 2476 { 2477 /* unlocks and calls out to user code */ 2478 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2479 return status; 2480 } 2481 2482 /* We need to ref the connection since the callback could potentially 2483 * drop the last ref to it 2484 */ 2485 _dbus_connection_ref_unlocked (connection); 2486 2487 _dbus_connection_acquire_dispatch (connection); 2488 2489 /* This call may drop the lock during the execution (if waiting for 2490 * borrowed messages to be returned) but the order of message 2491 * dispatch if several threads call dispatch() is still 2492 * protected by the lock, since only one will get the lock, and that 2493 * one will finish the message dispatching 2494 */ 2495 message_link = _dbus_connection_pop_message_link_unlocked (connection); 2496 if (message_link == NULL) 2497 { 2498 /* another thread dispatched our stuff */ 2499 2500 _dbus_connection_release_dispatch (connection); 2501 2502 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2503 2504 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2505 2506 dbus_connection_unref (connection); 2507 2508 return status; 2509 } 2510 2511 message = message_link->data; 2512 2513 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 2514 2515 reply_serial = dbus_message_get_reply_serial (message); 2516 pending = _dbus_hash_table_lookup_int (connection->pending_replies, 2517 reply_serial); 2518 2519 if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy)) 2520 { 2521 _dbus_connection_release_dispatch (connection); 2522 2523 _dbus_connection_failed_pop (connection, message_link); 2524 2525 /* unlocks and calls user code */ 2526 _dbus_connection_update_dispatch_status_and_unlock (connection, 2527 DBUS_DISPATCH_NEED_MEMORY); 2528 2529 dbus_connection_unref (connection); 2530 2531 return DBUS_DISPATCH_NEED_MEMORY; 2532 } 2533 2534 _dbus_list_foreach (&filter_list_copy, 2535 (DBusForeachFunction)_dbus_message_filter_ref, 2536 NULL); 2537 2538 /* We're still protected from dispatch() reentrancy here 2539 * since we acquired the dispatcher 2540 */ 2541 CONNECTION_UNLOCK (connection); 2542 2543 link = _dbus_list_get_first_link (&filter_list_copy); 2544 while (link != NULL) 2545 { 2546 DBusMessageFilter *filter = link->data; 2547 DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link); 2548 2549 _dbus_verbose (" running filter on message %p\n", message); 2550 result = (* filter->function) (connection, message, filter->user_data); 2551 2552 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED) 2553 break; 2554 2555 link = next; 2556 } 2557 2558 _dbus_list_foreach (&filter_list_copy, 2559 (DBusForeachFunction)_dbus_message_filter_unref, 2560 NULL); 2561 _dbus_list_clear (&filter_list_copy); 2562 2563 CONNECTION_LOCK (connection); 2564 2565 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY) 2566 goto out; 2567 2568 /* Did a reply we were waiting on get filtered? */ 2569 if (pending && result == DBUS_HANDLER_RESULT_HANDLED) 2570 { 2571 /* Queue the timeout immediately! */ 2572 if (pending->timeout_link) 2573 { 2574 _dbus_connection_queue_synthesized_message_link (connection, 2575 pending->timeout_link); 2576 pending->timeout_link = NULL; 2577 } 2578 else 2579 { 2580 /* We already queued the timeout? Then it was filtered! */ 2581 _dbus_warn ("The timeout error with reply serial %d was filtered, so the DBusPendingCall will never stop pending.\n", reply_serial); 2582 } 2583 } 2584 2585 if (result == DBUS_HANDLER_RESULT_HANDLED) 2586 goto out; 2587 2588 if (pending) 2589 { 2590 _dbus_pending_call_complete_and_unlock (pending, message); 2591 2592 pending = NULL; 2593 2594 CONNECTION_LOCK (connection); 2595 goto out; 2596 } 2597 2598 /* We're still protected from dispatch() reentrancy here 2599 * since we acquired the dispatcher 2600 */ 2601 _dbus_verbose (" running object path dispatch on message %p (%d %s '%s')\n", 2602 message, 2603 dbus_message_get_type (message), 2604 dbus_message_get_interface (message) ? 2605 dbus_message_get_interface (message) : 2606 "no interface", 2607 dbus_message_get_signature (message)); 2608 2609 result = _dbus_object_tree_dispatch_and_unlock (connection->objects, 2610 message); 2611 2612 CONNECTION_LOCK (connection); 2613 2614 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED) 2615 goto out; 2616 2617 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL) 2618 { 2619 DBusMessage *reply; 2620 DBusString str; 2621 DBusPreallocatedSend *preallocated; 2622 2623 _dbus_verbose (" sending error %s\n", 2624 DBUS_ERROR_UNKNOWN_METHOD); 2625 2626 if (!_dbus_string_init (&str)) 2627 { 2628 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 2629 goto out; 2630 } 2631 2632 if (!_dbus_string_append_printf (&str, 2633 "Method \"%s\" on interface \"%s\" doesn't exist\n", 2634 dbus_message_get_member (message), 2635 dbus_message_get_interface (message))) 2636 { 2637 _dbus_string_free (&str); 2638 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 2639 goto out; 2640 } 2641 2642 reply = dbus_message_new_error (message, 2643 DBUS_ERROR_UNKNOWN_METHOD, 2644 _dbus_string_get_const_data (&str)); 2645 _dbus_string_free (&str); 2646 2647 if (reply == NULL) 2648 { 2649 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 2650 goto out; 2651 } 2652 2653 preallocated = _dbus_connection_preallocate_send_unlocked (connection); 2654 2655 if (preallocated == NULL) 2656 { 2657 dbus_message_unref (reply); 2658 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 2659 goto out; 2660 } 2661 2662 _dbus_connection_send_preallocated_unlocked (connection, preallocated, 2663 reply, NULL); 2664 2665 dbus_message_unref (reply); 2666 2667 result = DBUS_HANDLER_RESULT_HANDLED; 2668 } 2669 2670 _dbus_verbose (" done dispatching %p (%d %s '%s') on connection %p\n", message, 2671 dbus_message_get_type (message), 2672 dbus_message_get_interface (message) ? 2673 dbus_message_get_interface (message) : 2674 "no interface", 2675 dbus_message_get_signature (message), 2676 connection); 2677 2678 out: 2679 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY) 2680 { 2681 _dbus_verbose ("out of memory in %s\n", _DBUS_FUNCTION_NAME); 2682 2683 /* Put message back, and we'll start over. 2684 * Yes this means handlers must be idempotent if they 2685 * don't return HANDLED; c'est la vie. 2686 */ 2687 _dbus_connection_putback_message_link_unlocked (connection, 2688 message_link); 2689 } 2690 else 2691 { 2692 _dbus_verbose ("Done with message in %s\n", _DBUS_FUNCTION_NAME); 2693 2694 if (connection->exit_on_disconnect && 2695 dbus_message_is_signal (message, 2696 DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL, 2697 "Disconnected")) 2698 { 2699 _dbus_verbose ("Exiting on Disconnected signal\n"); 2700 CONNECTION_UNLOCK (connection); 2701 _dbus_exit (1); 2702 _dbus_assert_not_reached ("Call to exit() returned"); 2703 } 2704 2705 _dbus_list_free_link (message_link); 2706 dbus_message_unref (message); /* don't want the message to count in max message limits 2707 * in computing dispatch status below 2708 */ 2709 } 2710 2711 _dbus_connection_release_dispatch (connection); 2712 2713 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2714 2715 /* unlocks and calls user code */ 2716 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2717 2718 dbus_connection_unref (connection); 2719 2720 return status; 2721} 2722 2723/** 2724 * Sets the watch functions for the connection. These functions are 2725 * responsible for making the application's main loop aware of file 2726 * descriptors that need to be monitored for events, using select() or 2727 * poll(). When using Qt, typically the DBusAddWatchFunction would 2728 * create a QSocketNotifier. When using GLib, the DBusAddWatchFunction 2729 * could call g_io_add_watch(), or could be used as part of a more 2730 * elaborate GSource. Note that when a watch is added, it may 2731 * not be enabled. 2732 * 2733 * The DBusWatchToggledFunction notifies the application that the 2734 * watch has been enabled or disabled. Call dbus_watch_get_enabled() 2735 * to check this. A disabled watch should have no effect, and enabled 2736 * watch should be added to the main loop. This feature is used 2737 * instead of simply adding/removing the watch because 2738 * enabling/disabling can be done without memory allocation. The 2739 * toggled function may be NULL if a main loop re-queries 2740 * dbus_watch_get_enabled() every time anyway. 2741 * 2742 * The DBusWatch can be queried for the file descriptor to watch using 2743 * dbus_watch_get_fd(), and for the events to watch for using 2744 * dbus_watch_get_flags(). The flags returned by 2745 * dbus_watch_get_flags() will only contain DBUS_WATCH_READABLE and 2746 * DBUS_WATCH_WRITABLE, never DBUS_WATCH_HANGUP or DBUS_WATCH_ERROR; 2747 * all watches implicitly include a watch for hangups, errors, and 2748 * other exceptional conditions. 2749 * 2750 * Once a file descriptor becomes readable or writable, or an exception 2751 * occurs, dbus_watch_handle() should be called to 2752 * notify the connection of the file descriptor's condition. 2753 * 2754 * dbus_watch_handle() cannot be called during the 2755 * DBusAddWatchFunction, as the connection will not be ready to handle 2756 * that watch yet. 2757 * 2758 * It is not allowed to reference a DBusWatch after it has been passed 2759 * to remove_function. 2760 * 2761 * If #FALSE is returned due to lack of memory, the failure may be due 2762 * to a #FALSE return from the new add_function. If so, the 2763 * add_function may have been called successfully one or more times, 2764 * but the remove_function will also have been called to remove any 2765 * successful adds. i.e. if #FALSE is returned the net result 2766 * should be that dbus_connection_set_watch_functions() has no effect, 2767 * but the add_function and remove_function may have been called. 2768 * 2769 * @todo We need to drop the lock when we call the 2770 * add/remove/toggled functions which can be a side effect 2771 * of setting the watch functions. 2772 * 2773 * @param connection the connection. 2774 * @param add_function function to begin monitoring a new descriptor. 2775 * @param remove_function function to stop monitoring a descriptor. 2776 * @param toggled_function function to notify of enable/disable 2777 * @param data data to pass to add_function and remove_function. 2778 * @param free_data_function function to be called to free the data. 2779 * @returns #FALSE on failure (no memory) 2780 */ 2781dbus_bool_t 2782dbus_connection_set_watch_functions (DBusConnection *connection, 2783 DBusAddWatchFunction add_function, 2784 DBusRemoveWatchFunction remove_function, 2785 DBusWatchToggledFunction toggled_function, 2786 void *data, 2787 DBusFreeFunction free_data_function) 2788{ 2789 dbus_bool_t retval; 2790 2791 _dbus_return_val_if_fail (connection != NULL, FALSE); 2792 2793 CONNECTION_LOCK (connection); 2794 /* ref connection for slightly better reentrancy */ 2795 _dbus_connection_ref_unlocked (connection); 2796 2797 /* FIXME this can call back into user code, and we need to drop the 2798 * connection lock when it does. 2799 */ 2800 retval = _dbus_watch_list_set_functions (connection->watches, 2801 add_function, remove_function, 2802 toggled_function, 2803 data, free_data_function); 2804 2805 CONNECTION_UNLOCK (connection); 2806 /* drop our paranoid refcount */ 2807 dbus_connection_unref (connection); 2808 2809 return retval; 2810} 2811 2812/** 2813 * Sets the timeout functions for the connection. These functions are 2814 * responsible for making the application's main loop aware of timeouts. 2815 * When using Qt, typically the DBusAddTimeoutFunction would create a 2816 * QTimer. When using GLib, the DBusAddTimeoutFunction would call 2817 * g_timeout_add. 2818 * 2819 * The DBusTimeoutToggledFunction notifies the application that the 2820 * timeout has been enabled or disabled. Call 2821 * dbus_timeout_get_enabled() to check this. A disabled timeout should 2822 * have no effect, and enabled timeout should be added to the main 2823 * loop. This feature is used instead of simply adding/removing the 2824 * timeout because enabling/disabling can be done without memory 2825 * allocation. With Qt, QTimer::start() and QTimer::stop() can be used 2826 * to enable and disable. The toggled function may be NULL if a main 2827 * loop re-queries dbus_timeout_get_enabled() every time anyway. 2828 * Whenever a timeout is toggled, its interval may change. 2829 * 2830 * The DBusTimeout can be queried for the timer interval using 2831 * dbus_timeout_get_interval(). dbus_timeout_handle() should be called 2832 * repeatedly, each time the interval elapses, starting after it has 2833 * elapsed once. The timeout stops firing when it is removed with the 2834 * given remove_function. The timer interval may change whenever the 2835 * timeout is added, removed, or toggled. 2836 * 2837 * @param connection the connection. 2838 * @param add_function function to add a timeout. 2839 * @param remove_function function to remove a timeout. 2840 * @param toggled_function function to notify of enable/disable 2841 * @param data data to pass to add_function and remove_function. 2842 * @param free_data_function function to be called to free the data. 2843 * @returns #FALSE on failure (no memory) 2844 */ 2845dbus_bool_t 2846dbus_connection_set_timeout_functions (DBusConnection *connection, 2847 DBusAddTimeoutFunction add_function, 2848 DBusRemoveTimeoutFunction remove_function, 2849 DBusTimeoutToggledFunction toggled_function, 2850 void *data, 2851 DBusFreeFunction free_data_function) 2852{ 2853 dbus_bool_t retval; 2854 2855 _dbus_return_val_if_fail (connection != NULL, FALSE); 2856 2857 CONNECTION_LOCK (connection); 2858 /* ref connection for slightly better reentrancy */ 2859 _dbus_connection_ref_unlocked (connection); 2860 2861 retval = _dbus_timeout_list_set_functions (connection->timeouts, 2862 add_function, remove_function, 2863 toggled_function, 2864 data, free_data_function); 2865 2866 CONNECTION_UNLOCK (connection); 2867 /* drop our paranoid refcount */ 2868 dbus_connection_unref (connection); 2869 2870 return retval; 2871} 2872 2873/** 2874 * Sets the mainloop wakeup function for the connection. Thi function is 2875 * responsible for waking up the main loop (if its sleeping) when some some 2876 * change has happened to the connection that the mainloop needs to reconsiders 2877 * (e.g. a message has been queued for writing). 2878 * When using Qt, this typically results in a call to QEventLoop::wakeUp(). 2879 * When using GLib, it would call g_main_context_wakeup(). 2880 * 2881 * 2882 * @param connection the connection. 2883 * @param wakeup_main_function function to wake up the mainloop 2884 * @param data data to pass wakeup_main_function 2885 * @param free_data_function function to be called to free the data. 2886 */ 2887void 2888dbus_connection_set_wakeup_main_function (DBusConnection *connection, 2889 DBusWakeupMainFunction wakeup_main_function, 2890 void *data, 2891 DBusFreeFunction free_data_function) 2892{ 2893 void *old_data; 2894 DBusFreeFunction old_free_data; 2895 2896 _dbus_return_if_fail (connection != NULL); 2897 2898 CONNECTION_LOCK (connection); 2899 old_data = connection->wakeup_main_data; 2900 old_free_data = connection->free_wakeup_main_data; 2901 2902 connection->wakeup_main_function = wakeup_main_function; 2903 connection->wakeup_main_data = data; 2904 connection->free_wakeup_main_data = free_data_function; 2905 2906 CONNECTION_UNLOCK (connection); 2907 2908 /* Callback outside the lock */ 2909 if (old_free_data) 2910 (*old_free_data) (old_data); 2911} 2912 2913/** 2914 * Set a function to be invoked when the dispatch status changes. 2915 * If the dispatch status is #DBUS_DISPATCH_DATA_REMAINS, then 2916 * dbus_connection_dispatch() needs to be called to process incoming 2917 * messages. However, dbus_connection_dispatch() MUST NOT BE CALLED 2918 * from inside the DBusDispatchStatusFunction. Indeed, almost 2919 * any reentrancy in this function is a bad idea. Instead, 2920 * the DBusDispatchStatusFunction should simply save an indication 2921 * that messages should be dispatched later, when the main loop 2922 * is re-entered. 2923 * 2924 * @param connection the connection 2925 * @param function function to call on dispatch status changes 2926 * @param data data for function 2927 * @param free_data_function free the function data 2928 */ 2929void 2930dbus_connection_set_dispatch_status_function (DBusConnection *connection, 2931 DBusDispatchStatusFunction function, 2932 void *data, 2933 DBusFreeFunction free_data_function) 2934{ 2935 void *old_data; 2936 DBusFreeFunction old_free_data; 2937 2938 _dbus_return_if_fail (connection != NULL); 2939 2940 CONNECTION_LOCK (connection); 2941 old_data = connection->dispatch_status_data; 2942 old_free_data = connection->free_dispatch_status_data; 2943 2944 connection->dispatch_status_function = function; 2945 connection->dispatch_status_data = data; 2946 connection->free_dispatch_status_data = free_data_function; 2947 2948 CONNECTION_UNLOCK (connection); 2949 2950 /* Callback outside the lock */ 2951 if (old_free_data) 2952 (*old_free_data) (old_data); 2953} 2954 2955/** 2956 * Gets the UNIX user ID of the connection if any. 2957 * Returns #TRUE if the uid is filled in. 2958 * Always returns #FALSE on non-UNIX platforms. 2959 * Always returns #FALSE prior to authenticating the 2960 * connection. 2961 * 2962 * @param connection the connection 2963 * @param uid return location for the user ID 2964 * @returns #TRUE if uid is filled in with a valid user ID 2965 */ 2966dbus_bool_t 2967dbus_connection_get_unix_user (DBusConnection *connection, 2968 unsigned long *uid) 2969{ 2970 dbus_bool_t result; 2971 2972 _dbus_return_val_if_fail (connection != NULL, FALSE); 2973 _dbus_return_val_if_fail (uid != NULL, FALSE); 2974 2975 CONNECTION_LOCK (connection); 2976 2977 if (!_dbus_transport_get_is_authenticated (connection->transport)) 2978 result = FALSE; 2979 else 2980 result = _dbus_transport_get_unix_user (connection->transport, 2981 uid); 2982 CONNECTION_UNLOCK (connection); 2983 2984 return result; 2985} 2986 2987/** 2988 * Gets the process ID of the connection if any. 2989 * Returns #TRUE if the uid is filled in. 2990 * Always returns #FALSE prior to authenticating the 2991 * connection. 2992 * 2993 * @param connection the connection 2994 * @param pid return location for the process ID 2995 * @returns #TRUE if uid is filled in with a valid process ID 2996 */ 2997dbus_bool_t 2998dbus_connection_get_unix_process_id (DBusConnection *connection, 2999 unsigned long *pid) 3000{ 3001 dbus_bool_t result; 3002 3003 _dbus_return_val_if_fail (connection != NULL, FALSE); 3004 _dbus_return_val_if_fail (pid != NULL, FALSE); 3005 3006 CONNECTION_LOCK (connection); 3007 3008 if (!_dbus_transport_get_is_authenticated (connection->transport)) 3009 result = FALSE; 3010 else 3011 result = _dbus_transport_get_unix_process_id (connection->transport, 3012 pid); 3013 CONNECTION_UNLOCK (connection); 3014 3015 return result; 3016} 3017 3018/** 3019 * Sets a predicate function used to determine whether a given user ID 3020 * is allowed to connect. When an incoming connection has 3021 * authenticated with a particular user ID, this function is called; 3022 * if it returns #TRUE, the connection is allowed to proceed, 3023 * otherwise the connection is disconnected. 3024 * 3025 * If the function is set to #NULL (as it is by default), then 3026 * only the same UID as the server process will be allowed to 3027 * connect. 3028 * 3029 * @param connection the connection 3030 * @param function the predicate 3031 * @param data data to pass to the predicate 3032 * @param free_data_function function to free the data 3033 */ 3034void 3035dbus_connection_set_unix_user_function (DBusConnection *connection, 3036 DBusAllowUnixUserFunction function, 3037 void *data, 3038 DBusFreeFunction free_data_function) 3039{ 3040 void *old_data = NULL; 3041 DBusFreeFunction old_free_function = NULL; 3042 3043 _dbus_return_if_fail (connection != NULL); 3044 3045 CONNECTION_LOCK (connection); 3046 _dbus_transport_set_unix_user_function (connection->transport, 3047 function, data, free_data_function, 3048 &old_data, &old_free_function); 3049 CONNECTION_UNLOCK (connection); 3050 3051 if (old_free_function != NULL) 3052 (* old_free_function) (old_data); 3053} 3054 3055/** 3056 * Adds a message filter. Filters are handlers that are run on all 3057 * incoming messages, prior to the objects registered with 3058 * dbus_connection_register_object_path(). Filters are run in the 3059 * order that they were added. The same handler can be added as a 3060 * filter more than once, in which case it will be run more than once. 3061 * Filters added during a filter callback won't be run on the message 3062 * being processed. 3063 * 3064 * @todo we don't run filters on messages while blocking without 3065 * entering the main loop, since filters are run as part of 3066 * dbus_connection_dispatch(). This is probably a feature, as filters 3067 * could create arbitrary reentrancy. But kind of sucks if you're 3068 * trying to filter METHOD_RETURN for some reason. 3069 * 3070 * @param connection the connection 3071 * @param function function to handle messages 3072 * @param user_data user data to pass to the function 3073 * @param free_data_function function to use for freeing user data 3074 * @returns #TRUE on success, #FALSE if not enough memory. 3075 */ 3076dbus_bool_t 3077dbus_connection_add_filter (DBusConnection *connection, 3078 DBusHandleMessageFunction function, 3079 void *user_data, 3080 DBusFreeFunction free_data_function) 3081{ 3082 DBusMessageFilter *filter; 3083 3084 _dbus_return_val_if_fail (connection != NULL, FALSE); 3085 _dbus_return_val_if_fail (function != NULL, FALSE); 3086 3087 filter = dbus_new0 (DBusMessageFilter, 1); 3088 if (filter == NULL) 3089 return FALSE; 3090 3091 filter->refcount.value = 1; 3092 3093 CONNECTION_LOCK (connection); 3094 3095 if (!_dbus_list_append (&connection->filter_list, 3096 filter)) 3097 { 3098 _dbus_message_filter_unref (filter); 3099 CONNECTION_UNLOCK (connection); 3100 return FALSE; 3101 } 3102 3103 /* Fill in filter after all memory allocated, 3104 * so we don't run the free_user_data_function 3105 * if the add_filter() fails 3106 */ 3107 3108 filter->function = function; 3109 filter->user_data = user_data; 3110 filter->free_user_data_function = free_data_function; 3111 3112 CONNECTION_UNLOCK (connection); 3113 return TRUE; 3114} 3115 3116/** 3117 * Removes a previously-added message filter. It is a programming 3118 * error to call this function for a handler that has not been added 3119 * as a filter. If the given handler was added more than once, only 3120 * one instance of it will be removed (the most recently-added 3121 * instance). 3122 * 3123 * @param connection the connection 3124 * @param function the handler to remove 3125 * @param user_data user data for the handler to remove 3126 * 3127 */ 3128void 3129dbus_connection_remove_filter (DBusConnection *connection, 3130 DBusHandleMessageFunction function, 3131 void *user_data) 3132{ 3133 DBusList *link; 3134 DBusMessageFilter *filter; 3135 3136 _dbus_return_if_fail (connection != NULL); 3137 _dbus_return_if_fail (function != NULL); 3138 3139 CONNECTION_LOCK (connection); 3140 3141 filter = NULL; 3142 3143 link = _dbus_list_get_last_link (&connection->filter_list); 3144 while (link != NULL) 3145 { 3146 filter = link->data; 3147 3148 if (filter->function == function && 3149 filter->user_data == user_data) 3150 { 3151 _dbus_list_remove_link (&connection->filter_list, link); 3152 filter->function = NULL; 3153 3154 break; 3155 } 3156 3157 link = _dbus_list_get_prev_link (&connection->filter_list, link); 3158 } 3159 3160 CONNECTION_UNLOCK (connection); 3161 3162#ifndef DBUS_DISABLE_CHECKS 3163 if (filter == NULL) 3164 { 3165 _dbus_warn ("Attempt to remove filter function %p user data %p, but no such filter has been added\n", 3166 function, user_data); 3167 return; 3168 } 3169#endif 3170 3171 /* Call application code */ 3172 if (filter->free_user_data_function) 3173 (* filter->free_user_data_function) (filter->user_data); 3174 3175 filter->free_user_data_function = NULL; 3176 filter->user_data = NULL; 3177 3178 _dbus_message_filter_unref (filter); 3179} 3180 3181/** 3182 * Registers a handler for a given path in the object hierarchy. 3183 * The given vtable handles messages sent to exactly the given path. 3184 * 3185 * 3186 * @param connection the connection 3187 * @param path a '/' delimited string of path elements 3188 * @param vtable the virtual table 3189 * @param user_data data to pass to functions in the vtable 3190 * @returns #FALSE if not enough memory 3191 */ 3192dbus_bool_t 3193dbus_connection_register_object_path (DBusConnection *connection, 3194 const char *path, 3195 const DBusObjectPathVTable *vtable, 3196 void *user_data) 3197{ 3198 char **decomposed_path; 3199 dbus_bool_t retval; 3200 3201 _dbus_return_val_if_fail (connection != NULL, FALSE); 3202 _dbus_return_val_if_fail (path != NULL, FALSE); 3203 _dbus_return_val_if_fail (path[0] == '/', FALSE); 3204 _dbus_return_val_if_fail (vtable != NULL, FALSE); 3205 3206 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) 3207 return FALSE; 3208 3209 CONNECTION_LOCK (connection); 3210 3211 retval = _dbus_object_tree_register (connection->objects, 3212 FALSE, 3213 (const char **) decomposed_path, vtable, 3214 user_data); 3215 3216 CONNECTION_UNLOCK (connection); 3217 3218 dbus_free_string_array (decomposed_path); 3219 3220 return retval; 3221} 3222 3223/** 3224 * Registers a fallback handler for a given subsection of the object 3225 * hierarchy. The given vtable handles messages at or below the given 3226 * path. You can use this to establish a default message handling 3227 * policy for a whole "subdirectory." 3228 * 3229 * @param connection the connection 3230 * @param path a '/' delimited string of path elements 3231 * @param vtable the virtual table 3232 * @param user_data data to pass to functions in the vtable 3233 * @returns #FALSE if not enough memory 3234 */ 3235dbus_bool_t 3236dbus_connection_register_fallback (DBusConnection *connection, 3237 const char *path, 3238 const DBusObjectPathVTable *vtable, 3239 void *user_data) 3240{ 3241 char **decomposed_path; 3242 dbus_bool_t retval; 3243 3244 _dbus_return_val_if_fail (connection != NULL, FALSE); 3245 _dbus_return_val_if_fail (path != NULL, FALSE); 3246 _dbus_return_val_if_fail (path[0] == '/', FALSE); 3247 _dbus_return_val_if_fail (vtable != NULL, FALSE); 3248 3249 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) 3250 return FALSE; 3251 3252 CONNECTION_LOCK (connection); 3253 3254 retval = _dbus_object_tree_register (connection->objects, 3255 TRUE, 3256 (const char **) decomposed_path, vtable, 3257 user_data); 3258 3259 CONNECTION_UNLOCK (connection); 3260 3261 dbus_free_string_array (decomposed_path); 3262 3263 return retval; 3264} 3265 3266/** 3267 * Unregisters the handler registered with exactly the given path. 3268 * It's a bug to call this function for a path that isn't registered. 3269 * Can unregister both fallback paths and object paths. 3270 * 3271 * @param connection the connection 3272 * @param path a '/' delimited string of path elements 3273 * @returns #FALSE if not enough memory 3274 */ 3275dbus_bool_t 3276dbus_connection_unregister_object_path (DBusConnection *connection, 3277 const char *path) 3278{ 3279 char **decomposed_path; 3280 3281 _dbus_return_val_if_fail (connection != NULL, FALSE); 3282 _dbus_return_val_if_fail (path != NULL, FALSE); 3283 _dbus_return_val_if_fail (path[0] == '/', FALSE); 3284 3285 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) 3286 return FALSE; 3287 3288 CONNECTION_LOCK (connection); 3289 3290 _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path); 3291 3292 dbus_free_string_array (decomposed_path); 3293 3294 return TRUE; 3295} 3296 3297/** 3298 * Lists the registered fallback handlers and object path handlers at 3299 * the given parent_path. The returned array should be freed with 3300 * dbus_free_string_array(). 3301 * 3302 * @param connection the connection 3303 * @param parent_path the path to list the child handlers of 3304 * @param child_entries returns #NULL-terminated array of children 3305 * @returns #FALSE if no memory to allocate the child entries 3306 */ 3307dbus_bool_t 3308dbus_connection_list_registered (DBusConnection *connection, 3309 const char *parent_path, 3310 char ***child_entries) 3311{ 3312 char **decomposed_path; 3313 dbus_bool_t retval; 3314 _dbus_return_val_if_fail (connection != NULL, FALSE); 3315 _dbus_return_val_if_fail (parent_path != NULL, FALSE); 3316 _dbus_return_val_if_fail (parent_path[0] == '/', FALSE); 3317 _dbus_return_val_if_fail (child_entries != NULL, FALSE); 3318 3319 if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL)) 3320 return FALSE; 3321 3322 CONNECTION_LOCK (connection); 3323 3324 retval = _dbus_object_tree_list_registered_and_unlock (connection->objects, 3325 (const char **) decomposed_path, 3326 child_entries); 3327 dbus_free_string_array (decomposed_path); 3328 3329 return retval; 3330} 3331 3332static DBusDataSlotAllocator slot_allocator; 3333_DBUS_DEFINE_GLOBAL_LOCK (connection_slots); 3334 3335/** 3336 * Allocates an integer ID to be used for storing application-specific 3337 * data on any DBusConnection. The allocated ID may then be used 3338 * with dbus_connection_set_data() and dbus_connection_get_data(). 3339 * The passed-in slot must be initialized to -1, and is filled in 3340 * with the slot ID. If the passed-in slot is not -1, it's assumed 3341 * to be already allocated, and its refcount is incremented. 3342 * 3343 * The allocated slot is global, i.e. all DBusConnection objects will 3344 * have a slot with the given integer ID reserved. 3345 * 3346 * @param slot_p address of a global variable storing the slot 3347 * @returns #FALSE on failure (no memory) 3348 */ 3349dbus_bool_t 3350dbus_connection_allocate_data_slot (dbus_int32_t *slot_p) 3351{ 3352 return _dbus_data_slot_allocator_alloc (&slot_allocator, 3353 _DBUS_LOCK_NAME (connection_slots), 3354 slot_p); 3355} 3356 3357/** 3358 * Deallocates a global ID for connection data slots. 3359 * dbus_connection_get_data() and dbus_connection_set_data() may no 3360 * longer be used with this slot. Existing data stored on existing 3361 * DBusConnection objects will be freed when the connection is 3362 * finalized, but may not be retrieved (and may only be replaced if 3363 * someone else reallocates the slot). When the refcount on the 3364 * passed-in slot reaches 0, it is set to -1. 3365 * 3366 * @param slot_p address storing the slot to deallocate 3367 */ 3368void 3369dbus_connection_free_data_slot (dbus_int32_t *slot_p) 3370{ 3371 _dbus_return_if_fail (*slot_p >= 0); 3372 3373 _dbus_data_slot_allocator_free (&slot_allocator, slot_p); 3374} 3375 3376/** 3377 * Stores a pointer on a DBusConnection, along 3378 * with an optional function to be used for freeing 3379 * the data when the data is set again, or when 3380 * the connection is finalized. The slot number 3381 * must have been allocated with dbus_connection_allocate_data_slot(). 3382 * 3383 * @param connection the connection 3384 * @param slot the slot number 3385 * @param data the data to store 3386 * @param free_data_func finalizer function for the data 3387 * @returns #TRUE if there was enough memory to store the data 3388 */ 3389dbus_bool_t 3390dbus_connection_set_data (DBusConnection *connection, 3391 dbus_int32_t slot, 3392 void *data, 3393 DBusFreeFunction free_data_func) 3394{ 3395 DBusFreeFunction old_free_func; 3396 void *old_data; 3397 dbus_bool_t retval; 3398 3399 _dbus_return_val_if_fail (connection != NULL, FALSE); 3400 _dbus_return_val_if_fail (slot >= 0, FALSE); 3401 3402 CONNECTION_LOCK (connection); 3403 3404 retval = _dbus_data_slot_list_set (&slot_allocator, 3405 &connection->slot_list, 3406 slot, data, free_data_func, 3407 &old_free_func, &old_data); 3408 3409 CONNECTION_UNLOCK (connection); 3410 3411 if (retval) 3412 { 3413 /* Do the actual free outside the connection lock */ 3414 if (old_free_func) 3415 (* old_free_func) (old_data); 3416 } 3417 3418 return retval; 3419} 3420 3421/** 3422 * Retrieves data previously set with dbus_connection_set_data(). 3423 * The slot must still be allocated (must not have been freed). 3424 * 3425 * @param connection the connection 3426 * @param slot the slot to get data from 3427 * @returns the data, or #NULL if not found 3428 */ 3429void* 3430dbus_connection_get_data (DBusConnection *connection, 3431 dbus_int32_t slot) 3432{ 3433 void *res; 3434 3435 _dbus_return_val_if_fail (connection != NULL, NULL); 3436 3437 CONNECTION_LOCK (connection); 3438 3439 res = _dbus_data_slot_list_get (&slot_allocator, 3440 &connection->slot_list, 3441 slot); 3442 3443 CONNECTION_UNLOCK (connection); 3444 3445 return res; 3446} 3447 3448/** 3449 * This function sets a global flag for whether dbus_connection_new() 3450 * will set SIGPIPE behavior to SIG_IGN. 3451 * 3452 * @param will_modify_sigpipe #TRUE to allow sigpipe to be set to SIG_IGN 3453 */ 3454void 3455dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe) 3456{ 3457 _dbus_modify_sigpipe = will_modify_sigpipe != FALSE; 3458} 3459 3460/** 3461 * Specifies the maximum size message this connection is allowed to 3462 * receive. Larger messages will result in disconnecting the 3463 * connection. 3464 * 3465 * @param connection a #DBusConnection 3466 * @param size maximum message size the connection can receive, in bytes 3467 */ 3468void 3469dbus_connection_set_max_message_size (DBusConnection *connection, 3470 long size) 3471{ 3472 _dbus_return_if_fail (connection != NULL); 3473 3474 CONNECTION_LOCK (connection); 3475 _dbus_transport_set_max_message_size (connection->transport, 3476 size); 3477 CONNECTION_UNLOCK (connection); 3478} 3479 3480/** 3481 * Gets the value set by dbus_connection_set_max_message_size(). 3482 * 3483 * @param connection the connection 3484 * @returns the max size of a single message 3485 */ 3486long 3487dbus_connection_get_max_message_size (DBusConnection *connection) 3488{ 3489 long res; 3490 3491 _dbus_return_val_if_fail (connection != NULL, 0); 3492 3493 CONNECTION_LOCK (connection); 3494 res = _dbus_transport_get_max_message_size (connection->transport); 3495 CONNECTION_UNLOCK (connection); 3496 return res; 3497} 3498 3499/** 3500 * Sets the maximum total number of bytes that can be used for all messages 3501 * received on this connection. Messages count toward the maximum until 3502 * they are finalized. When the maximum is reached, the connection will 3503 * not read more data until some messages are finalized. 3504 * 3505 * The semantics of the maximum are: if outstanding messages are 3506 * already above the maximum, additional messages will not be read. 3507 * The semantics are not: if the next message would cause us to exceed 3508 * the maximum, we don't read it. The reason is that we don't know the 3509 * size of a message until after we read it. 3510 * 3511 * Thus, the max live messages size can actually be exceeded 3512 * by up to the maximum size of a single message. 3513 * 3514 * Also, if we read say 1024 bytes off the wire in a single read(), 3515 * and that contains a half-dozen small messages, we may exceed the 3516 * size max by that amount. But this should be inconsequential. 3517 * 3518 * This does imply that we can't call read() with a buffer larger 3519 * than we're willing to exceed this limit by. 3520 * 3521 * @param connection the connection 3522 * @param size the maximum size in bytes of all outstanding messages 3523 */ 3524void 3525dbus_connection_set_max_received_size (DBusConnection *connection, 3526 long size) 3527{ 3528 _dbus_return_if_fail (connection != NULL); 3529 3530 CONNECTION_LOCK (connection); 3531 _dbus_transport_set_max_received_size (connection->transport, 3532 size); 3533 CONNECTION_UNLOCK (connection); 3534} 3535 3536/** 3537 * Gets the value set by dbus_connection_set_max_received_size(). 3538 * 3539 * @param connection the connection 3540 * @returns the max size of all live messages 3541 */ 3542long 3543dbus_connection_get_max_received_size (DBusConnection *connection) 3544{ 3545 long res; 3546 3547 _dbus_return_val_if_fail (connection != NULL, 0); 3548 3549 CONNECTION_LOCK (connection); 3550 res = _dbus_transport_get_max_received_size (connection->transport); 3551 CONNECTION_UNLOCK (connection); 3552 return res; 3553} 3554 3555/** 3556 * Gets the approximate size in bytes of all messages in the outgoing 3557 * message queue. The size is approximate in that you shouldn't use 3558 * it to decide how many bytes to read off the network or anything 3559 * of that nature, as optimizations may choose to tell small white lies 3560 * to avoid performance overhead. 3561 * 3562 * @param connection the connection 3563 * @returns the number of bytes that have been queued up but not sent 3564 */ 3565long 3566dbus_connection_get_outgoing_size (DBusConnection *connection) 3567{ 3568 long res; 3569 3570 _dbus_return_val_if_fail (connection != NULL, 0); 3571 3572 CONNECTION_LOCK (connection); 3573 res = _dbus_counter_get_value (connection->outgoing_counter); 3574 CONNECTION_UNLOCK (connection); 3575 return res; 3576} 3577 3578/** @} */ 3579