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