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