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