1/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 2/* dbus-connection.c DBusConnection object 3 * 4 * Copyright (C) 2002-2006 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 * 22 */ 23 24#include <config.h> 25#include "dbus-shared.h" 26#include "dbus-connection.h" 27#include "dbus-list.h" 28#include "dbus-timeout.h" 29#include "dbus-transport.h" 30#include "dbus-watch.h" 31#include "dbus-connection-internal.h" 32#include "dbus-pending-call-internal.h" 33#include "dbus-list.h" 34#include "dbus-hash.h" 35#include "dbus-message-internal.h" 36#include "dbus-message-private.h" 37#include "dbus-threads.h" 38#include "dbus-protocol.h" 39#include "dbus-dataslot.h" 40#include "dbus-string.h" 41#include "dbus-signature.h" 42#include "dbus-pending-call.h" 43#include "dbus-object-tree.h" 44#include "dbus-threads-internal.h" 45#include "dbus-bus.h" 46#include "dbus-marshal-basic.h" 47 48#ifdef DBUS_DISABLE_CHECKS 49#define TOOK_LOCK_CHECK(connection) 50#define RELEASING_LOCK_CHECK(connection) 51#define HAVE_LOCK_CHECK(connection) 52#else 53#define TOOK_LOCK_CHECK(connection) do { \ 54 _dbus_assert (!(connection)->have_connection_lock); \ 55 (connection)->have_connection_lock = TRUE; \ 56 } while (0) 57#define RELEASING_LOCK_CHECK(connection) do { \ 58 _dbus_assert ((connection)->have_connection_lock); \ 59 (connection)->have_connection_lock = FALSE; \ 60 } while (0) 61#define HAVE_LOCK_CHECK(connection) _dbus_assert ((connection)->have_connection_lock) 62/* A "DO_NOT_HAVE_LOCK_CHECK" is impossible since we need the lock to check the flag */ 63#endif 64 65#define TRACE_LOCKS 1 66 67#define CONNECTION_LOCK(connection) do { \ 68 if (TRACE_LOCKS) { _dbus_verbose ("LOCK\n"); } \ 69 _dbus_rmutex_lock ((connection)->mutex); \ 70 TOOK_LOCK_CHECK (connection); \ 71 } while (0) 72 73#define CONNECTION_UNLOCK(connection) _dbus_connection_unlock (connection) 74 75#define SLOTS_LOCK(connection) do { \ 76 _dbus_rmutex_lock ((connection)->slot_mutex); \ 77 } while (0) 78 79#define SLOTS_UNLOCK(connection) do { \ 80 _dbus_rmutex_unlock ((connection)->slot_mutex); \ 81 } while (0) 82 83#define DISPATCH_STATUS_NAME(s) \ 84 ((s) == DBUS_DISPATCH_COMPLETE ? "complete" : \ 85 (s) == DBUS_DISPATCH_DATA_REMAINS ? "data remains" : \ 86 (s) == DBUS_DISPATCH_NEED_MEMORY ? "need memory" : \ 87 "???") 88 89/** 90 * @defgroup DBusConnection DBusConnection 91 * @ingroup DBus 92 * @brief Connection to another application 93 * 94 * A DBusConnection represents a connection to another 95 * application. Messages can be sent and received via this connection. 96 * The other application may be a message bus; for convenience, the 97 * function dbus_bus_get() is provided to automatically open a 98 * connection to the well-known message buses. 99 * 100 * In brief a DBusConnection is a message queue associated with some 101 * message transport mechanism such as a socket. The connection 102 * maintains a queue of incoming messages and a queue of outgoing 103 * messages. 104 * 105 * Several functions use the following terms: 106 * <ul> 107 * <li><b>read</b> means to fill the incoming message queue by reading from the socket</li> 108 * <li><b>write</b> means to drain the outgoing queue by writing to the socket</li> 109 * <li><b>dispatch</b> means to drain the incoming queue by invoking application-provided message handlers</li> 110 * </ul> 111 * 112 * The function dbus_connection_read_write_dispatch() for example does all 113 * three of these things, offering a simple alternative to a main loop. 114 * 115 * In an application with a main loop, the read/write/dispatch 116 * operations are usually separate. 117 * 118 * The connection provides #DBusWatch and #DBusTimeout objects to 119 * the main loop. These are used to know when reading, writing, or 120 * dispatching should be performed. 121 * 122 * Incoming messages are processed 123 * by calling dbus_connection_dispatch(). dbus_connection_dispatch() 124 * runs any handlers registered for the topmost message in the message 125 * queue, then discards the message, then returns. 126 * 127 * dbus_connection_get_dispatch_status() indicates whether 128 * messages are currently in the queue that need dispatching. 129 * dbus_connection_set_dispatch_status_function() allows 130 * you to set a function to be used to monitor the dispatch status. 131 * 132 * If you're using GLib or Qt add-on libraries for D-Bus, there are 133 * special convenience APIs in those libraries that hide 134 * all the details of dispatch and watch/timeout monitoring. 135 * For example, dbus_connection_setup_with_g_main(). 136 * 137 * If you aren't using these add-on libraries, but want to process 138 * messages asynchronously, you must manually call 139 * dbus_connection_set_dispatch_status_function(), 140 * dbus_connection_set_watch_functions(), 141 * dbus_connection_set_timeout_functions() providing appropriate 142 * functions to integrate the connection with your application's main 143 * loop. This can be tricky to get right; main loops are not simple. 144 * 145 * If you don't need to be asynchronous, you can ignore #DBusWatch, 146 * #DBusTimeout, and dbus_connection_dispatch(). Instead, 147 * dbus_connection_read_write_dispatch() can be used. 148 * 149 * Or, in <em>very</em> simple applications, 150 * dbus_connection_pop_message() may be all you need, allowing you to 151 * avoid setting up any handler functions (see 152 * dbus_connection_add_filter(), 153 * dbus_connection_register_object_path() for more on handlers). 154 * 155 * When you use dbus_connection_send() or one of its variants to send 156 * a message, the message is added to the outgoing queue. It's 157 * actually written to the network later; either in 158 * dbus_watch_handle() invoked by your main loop, or in 159 * dbus_connection_flush() which blocks until it can write out the 160 * entire outgoing queue. The GLib/Qt add-on libraries again 161 * handle the details here for you by setting up watch functions. 162 * 163 * When a connection is disconnected, you are guaranteed to get a 164 * signal "Disconnected" from the interface 165 * #DBUS_INTERFACE_LOCAL, path 166 * #DBUS_PATH_LOCAL. 167 * 168 * You may not drop the last reference to a #DBusConnection 169 * until that connection has been disconnected. 170 * 171 * You may dispatch the unprocessed incoming message queue even if the 172 * connection is disconnected. However, "Disconnected" will always be 173 * the last message in the queue (obviously no messages are received 174 * after disconnection). 175 * 176 * After calling dbus_threads_init(), #DBusConnection has thread 177 * locks and drops them when invoking user callbacks, so in general is 178 * transparently threadsafe. However, #DBusMessage does NOT have 179 * thread locks; you must not send the same message to multiple 180 * #DBusConnection if those connections will be used from different threads, 181 * for example. 182 * 183 * Also, if you dispatch or pop messages from multiple threads, it 184 * may work in the sense that it won't crash, but it's tough to imagine 185 * sane results; it will be completely unpredictable which messages 186 * go to which threads. 187 * 188 * It's recommended to dispatch from a single thread. 189 * 190 * The most useful function to call from multiple threads at once 191 * is dbus_connection_send_with_reply_and_block(). That is, 192 * multiple threads can make method calls at the same time. 193 * 194 * If you aren't using threads, you can use a main loop and 195 * dbus_pending_call_set_notify() to achieve a similar result. 196 */ 197 198/** 199 * @defgroup DBusConnectionInternals DBusConnection implementation details 200 * @ingroup DBusInternals 201 * @brief Implementation details of DBusConnection 202 * 203 * @{ 204 */ 205 206#ifdef DBUS_ENABLE_VERBOSE_MODE 207static void 208_dbus_connection_trace_ref (DBusConnection *connection, 209 int old_refcount, 210 int new_refcount, 211 const char *why) 212{ 213 static int enabled = -1; 214 215 _dbus_trace_ref ("DBusConnection", connection, old_refcount, new_refcount, 216 why, "DBUS_CONNECTION_TRACE", &enabled); 217} 218#else 219#define _dbus_connection_trace_ref(c,o,n,w) \ 220 do \ 221 {\ 222 (void) (o); \ 223 (void) (n); \ 224 } while (0) 225#endif 226 227/** 228 * Internal struct representing a message filter function 229 */ 230typedef struct DBusMessageFilter DBusMessageFilter; 231 232/** 233 * Internal struct representing a message filter function 234 */ 235struct DBusMessageFilter 236{ 237 DBusAtomic refcount; /**< Reference count */ 238 DBusHandleMessageFunction function; /**< Function to call to filter */ 239 void *user_data; /**< User data for the function */ 240 DBusFreeFunction free_user_data_function; /**< Function to free the user data */ 241}; 242 243 244/** 245 * Internals of DBusPreallocatedSend 246 */ 247struct DBusPreallocatedSend 248{ 249 DBusConnection *connection; /**< Connection we'd send the message to */ 250 DBusList *queue_link; /**< Preallocated link in the queue */ 251 DBusList *counter_link; /**< Preallocated link in the resource counter */ 252}; 253 254#if HAVE_DECL_MSG_NOSIGNAL 255static dbus_bool_t _dbus_modify_sigpipe = FALSE; 256#else 257static dbus_bool_t _dbus_modify_sigpipe = TRUE; 258#endif 259 260/** 261 * Implementation details of DBusConnection. All fields are private. 262 */ 263struct DBusConnection 264{ 265 DBusAtomic refcount; /**< Reference count. */ 266 267 DBusRMutex *mutex; /**< Lock on the entire DBusConnection */ 268 269 DBusCMutex *dispatch_mutex; /**< Protects dispatch_acquired */ 270 DBusCondVar *dispatch_cond; /**< Notify when dispatch_acquired is available */ 271 DBusCMutex *io_path_mutex; /**< Protects io_path_acquired */ 272 DBusCondVar *io_path_cond; /**< Notify when io_path_acquired is available */ 273 274 DBusList *outgoing_messages; /**< Queue of messages we need to send, send the end of the list first. */ 275 DBusList *incoming_messages; /**< Queue of messages we have received, end of the list received most recently. */ 276 DBusList *expired_messages; /**< Messages that will be released when we next unlock. */ 277 278 DBusMessage *message_borrowed; /**< Filled in if the first incoming message has been borrowed; 279 * dispatch_acquired will be set by the borrower 280 */ 281 282 int n_outgoing; /**< Length of outgoing queue. */ 283 int n_incoming; /**< Length of incoming queue. */ 284 285 DBusCounter *outgoing_counter; /**< Counts size of outgoing messages. */ 286 287 DBusTransport *transport; /**< Object that sends/receives messages over network. */ 288 DBusWatchList *watches; /**< Stores active watches. */ 289 DBusTimeoutList *timeouts; /**< Stores active timeouts. */ 290 291 DBusList *filter_list; /**< List of filters. */ 292 293 DBusRMutex *slot_mutex; /**< Lock on slot_list so overall connection lock need not be taken */ 294 DBusDataSlotList slot_list; /**< Data stored by allocated integer ID */ 295 296 DBusHashTable *pending_replies; /**< Hash of message serials to #DBusPendingCall. */ 297 298 dbus_uint32_t client_serial; /**< Client serial. Increments each time a message is sent */ 299 DBusList *disconnect_message_link; /**< Preallocated list node for queueing the disconnection message */ 300 301 DBusWakeupMainFunction wakeup_main_function; /**< Function to wake up the mainloop */ 302 void *wakeup_main_data; /**< Application data for wakeup_main_function */ 303 DBusFreeFunction free_wakeup_main_data; /**< free wakeup_main_data */ 304 305 DBusDispatchStatusFunction dispatch_status_function; /**< Function on dispatch status changes */ 306 void *dispatch_status_data; /**< Application data for dispatch_status_function */ 307 DBusFreeFunction free_dispatch_status_data; /**< free dispatch_status_data */ 308 309 DBusDispatchStatus last_dispatch_status; /**< The last dispatch status we reported to the application. */ 310 311 DBusObjectTree *objects; /**< Object path handlers registered with this connection */ 312 313 char *server_guid; /**< GUID of server if we are in shared_connections, #NULL if server GUID is unknown or connection is private */ 314 315 /* These two MUST be bools and not bitfields, because they are protected by a separate lock 316 * from connection->mutex and all bitfields in a word have to be read/written together. 317 * So you can't have a different lock for different bitfields in the same word. 318 */ 319 dbus_bool_t dispatch_acquired; /**< Someone has dispatch path (can drain incoming queue) */ 320 dbus_bool_t io_path_acquired; /**< Someone has transport io path (can use the transport to read/write messages) */ 321 322 unsigned int shareable : 1; /**< #TRUE if libdbus owns a reference to the connection and can return it from dbus_connection_open() more than once */ 323 324 unsigned int exit_on_disconnect : 1; /**< If #TRUE, exit after handling disconnect signal */ 325 326 unsigned int route_peer_messages : 1; /**< If #TRUE, if org.freedesktop.DBus.Peer messages have a bus name, don't handle them automatically */ 327 328 unsigned int disconnected_message_arrived : 1; /**< We popped or are dispatching the disconnected message. 329 * if the disconnect_message_link is NULL then we queued it, but 330 * this flag is whether it got to the head of the queue. 331 */ 332 unsigned int disconnected_message_processed : 1; /**< We did our default handling of the disconnected message, 333 * such as closing the connection. 334 */ 335 336#ifndef DBUS_DISABLE_CHECKS 337 unsigned int have_connection_lock : 1; /**< Used to check locking */ 338#endif 339 340#ifndef DBUS_DISABLE_CHECKS 341 int generation; /**< _dbus_current_generation that should correspond to this connection */ 342#endif 343}; 344 345static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection); 346static void _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection, 347 DBusDispatchStatus new_status); 348static void _dbus_connection_last_unref (DBusConnection *connection); 349static void _dbus_connection_acquire_dispatch (DBusConnection *connection); 350static void _dbus_connection_release_dispatch (DBusConnection *connection); 351static DBusDispatchStatus _dbus_connection_flush_unlocked (DBusConnection *connection); 352static void _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection); 353static dbus_bool_t _dbus_connection_get_is_connected_unlocked (DBusConnection *connection); 354static dbus_bool_t _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection, 355 dbus_uint32_t client_serial); 356 357static DBusMessageFilter * 358_dbus_message_filter_ref (DBusMessageFilter *filter) 359{ 360#ifdef DBUS_DISABLE_ASSERT 361 _dbus_atomic_inc (&filter->refcount); 362#else 363 dbus_int32_t old_value; 364 365 old_value = _dbus_atomic_inc (&filter->refcount); 366 _dbus_assert (old_value > 0); 367#endif 368 369 return filter; 370} 371 372static void 373_dbus_message_filter_unref (DBusMessageFilter *filter) 374{ 375 dbus_int32_t old_value; 376 377 old_value = _dbus_atomic_dec (&filter->refcount); 378 _dbus_assert (old_value > 0); 379 380 if (old_value == 1) 381 { 382 if (filter->free_user_data_function) 383 (* filter->free_user_data_function) (filter->user_data); 384 385 dbus_free (filter); 386 } 387} 388 389/** 390 * Acquires the connection lock. 391 * 392 * @param connection the connection. 393 */ 394void 395_dbus_connection_lock (DBusConnection *connection) 396{ 397 CONNECTION_LOCK (connection); 398} 399 400/** 401 * Releases the connection lock. 402 * 403 * @param connection the connection. 404 */ 405void 406_dbus_connection_unlock (DBusConnection *connection) 407{ 408 DBusList *expired_messages; 409 DBusList *iter; 410 411 if (TRACE_LOCKS) 412 { 413 _dbus_verbose ("UNLOCK\n"); 414 } 415 416 /* If we had messages that expired (fell off the incoming or outgoing 417 * queues) while we were locked, actually release them now */ 418 expired_messages = connection->expired_messages; 419 connection->expired_messages = NULL; 420 421 RELEASING_LOCK_CHECK (connection); 422 _dbus_rmutex_unlock (connection->mutex); 423 424 for (iter = _dbus_list_pop_first_link (&expired_messages); 425 iter != NULL; 426 iter = _dbus_list_pop_first_link (&expired_messages)) 427 { 428 DBusMessage *message = iter->data; 429 430 dbus_message_unref (message); 431 _dbus_list_free_link (iter); 432 } 433} 434 435/** 436 * Wakes up the main loop if it is sleeping 437 * Needed if we're e.g. queueing outgoing messages 438 * on a thread while the mainloop sleeps. 439 * 440 * @param connection the connection. 441 */ 442static void 443_dbus_connection_wakeup_mainloop (DBusConnection *connection) 444{ 445 if (connection->wakeup_main_function) 446 (*connection->wakeup_main_function) (connection->wakeup_main_data); 447} 448 449#ifdef DBUS_BUILD_TESTS 450/** 451 * Gets the locks so we can examine them 452 * 453 * @param connection the connection. 454 * @param mutex_loc return for the location of the main mutex pointer 455 * @param dispatch_mutex_loc return location of the dispatch mutex pointer 456 * @param io_path_mutex_loc return location of the io_path mutex pointer 457 * @param dispatch_cond_loc return location of the dispatch conditional 458 * variable pointer 459 * @param io_path_cond_loc return location of the io_path conditional 460 * variable pointer 461 */ 462void 463_dbus_connection_test_get_locks (DBusConnection *connection, 464 DBusMutex **mutex_loc, 465 DBusMutex **dispatch_mutex_loc, 466 DBusMutex **io_path_mutex_loc, 467 DBusCondVar **dispatch_cond_loc, 468 DBusCondVar **io_path_cond_loc) 469{ 470 *mutex_loc = (DBusMutex *) connection->mutex; 471 *dispatch_mutex_loc = (DBusMutex *) connection->dispatch_mutex; 472 *io_path_mutex_loc = (DBusMutex *) connection->io_path_mutex; 473 *dispatch_cond_loc = connection->dispatch_cond; 474 *io_path_cond_loc = connection->io_path_cond; 475} 476#endif 477 478/** 479 * Adds a message-containing list link to the incoming message queue, 480 * taking ownership of the link and the message's current refcount. 481 * Cannot fail due to lack of memory. 482 * 483 * @param connection the connection. 484 * @param link the message link to queue. 485 */ 486void 487_dbus_connection_queue_received_message_link (DBusConnection *connection, 488 DBusList *link) 489{ 490 DBusPendingCall *pending; 491 dbus_uint32_t reply_serial; 492 DBusMessage *message; 493 494 _dbus_assert (_dbus_transport_get_is_authenticated (connection->transport)); 495 496 _dbus_list_append_link (&connection->incoming_messages, 497 link); 498 message = link->data; 499 500 /* If this is a reply we're waiting on, remove timeout for it */ 501 reply_serial = dbus_message_get_reply_serial (message); 502 if (reply_serial != 0) 503 { 504 pending = _dbus_hash_table_lookup_int (connection->pending_replies, 505 reply_serial); 506 if (pending != NULL) 507 { 508 if (_dbus_pending_call_is_timeout_added_unlocked (pending)) 509 _dbus_connection_remove_timeout_unlocked (connection, 510 _dbus_pending_call_get_timeout_unlocked (pending)); 511 512 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE); 513 } 514 } 515 516 517 518 connection->n_incoming += 1; 519 520 _dbus_connection_wakeup_mainloop (connection); 521 522 _dbus_verbose ("Message %p (%s %s %s %s '%s' reply to %u) added to incoming queue %p, %d incoming\n", 523 message, 524 dbus_message_type_to_string (dbus_message_get_type (message)), 525 dbus_message_get_path (message) ? 526 dbus_message_get_path (message) : 527 "no path", 528 dbus_message_get_interface (message) ? 529 dbus_message_get_interface (message) : 530 "no interface", 531 dbus_message_get_member (message) ? 532 dbus_message_get_member (message) : 533 "no member", 534 dbus_message_get_signature (message), 535 dbus_message_get_reply_serial (message), 536 connection, 537 connection->n_incoming); 538 539 _dbus_message_trace_ref (message, -1, -1, 540 "_dbus_conection_queue_received_message_link"); 541} 542 543/** 544 * Adds a link + message to the incoming message queue. 545 * Can't fail. Takes ownership of both link and message. 546 * 547 * @param connection the connection. 548 * @param link the list node and message to queue. 549 * 550 */ 551void 552_dbus_connection_queue_synthesized_message_link (DBusConnection *connection, 553 DBusList *link) 554{ 555 HAVE_LOCK_CHECK (connection); 556 557 _dbus_list_append_link (&connection->incoming_messages, link); 558 559 connection->n_incoming += 1; 560 561 _dbus_connection_wakeup_mainloop (connection); 562 563 _dbus_message_trace_ref (link->data, -1, -1, 564 "_dbus_connection_queue_synthesized_message_link"); 565 566 _dbus_verbose ("Synthesized message %p added to incoming queue %p, %d incoming\n", 567 link->data, connection, connection->n_incoming); 568} 569 570 571/** 572 * Checks whether there are messages in the outgoing message queue. 573 * Called with connection lock held. 574 * 575 * @param connection the connection. 576 * @returns #TRUE if the outgoing queue is non-empty. 577 */ 578dbus_bool_t 579_dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection) 580{ 581 HAVE_LOCK_CHECK (connection); 582 return connection->outgoing_messages != NULL; 583} 584 585/** 586 * Checks whether there are messages in the outgoing message queue. 587 * Use dbus_connection_flush() to block until all outgoing 588 * messages have been written to the underlying transport 589 * (such as a socket). 590 * 591 * @param connection the connection. 592 * @returns #TRUE if the outgoing queue is non-empty. 593 */ 594dbus_bool_t 595dbus_connection_has_messages_to_send (DBusConnection *connection) 596{ 597 dbus_bool_t v; 598 599 _dbus_return_val_if_fail (connection != NULL, FALSE); 600 601 CONNECTION_LOCK (connection); 602 v = _dbus_connection_has_messages_to_send_unlocked (connection); 603 CONNECTION_UNLOCK (connection); 604 605 return v; 606} 607 608/** 609 * Gets the next outgoing message. The message remains in the 610 * queue, and the caller does not own a reference to it. 611 * 612 * @param connection the connection. 613 * @returns the message to be sent. 614 */ 615DBusMessage* 616_dbus_connection_get_message_to_send (DBusConnection *connection) 617{ 618 HAVE_LOCK_CHECK (connection); 619 620 return _dbus_list_get_last (&connection->outgoing_messages); 621} 622 623/** 624 * Notifies the connection that a message has been sent, so the 625 * message can be removed from the outgoing queue. 626 * Called with the connection lock held. 627 * 628 * @param connection the connection. 629 * @param message the message that was sent. 630 */ 631void 632_dbus_connection_message_sent_unlocked (DBusConnection *connection, 633 DBusMessage *message) 634{ 635 DBusList *link; 636 637 HAVE_LOCK_CHECK (connection); 638 639 /* This can be called before we even complete authentication, since 640 * it's called on disconnect to clean up the outgoing queue. 641 * It's also called as we successfully send each message. 642 */ 643 644 link = _dbus_list_get_last_link (&connection->outgoing_messages); 645 _dbus_assert (link != NULL); 646 _dbus_assert (link->data == message); 647 648 _dbus_list_unlink (&connection->outgoing_messages, 649 link); 650 _dbus_list_prepend_link (&connection->expired_messages, link); 651 652 connection->n_outgoing -= 1; 653 654 _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from outgoing queue %p, %d left to send\n", 655 message, 656 dbus_message_type_to_string (dbus_message_get_type (message)), 657 dbus_message_get_path (message) ? 658 dbus_message_get_path (message) : 659 "no path", 660 dbus_message_get_interface (message) ? 661 dbus_message_get_interface (message) : 662 "no interface", 663 dbus_message_get_member (message) ? 664 dbus_message_get_member (message) : 665 "no member", 666 dbus_message_get_signature (message), 667 connection, connection->n_outgoing); 668 669 /* It's OK that in principle we call the notify function, because for the 670 * outgoing limit, there isn't one */ 671 _dbus_message_remove_counter (message, connection->outgoing_counter); 672 673 /* The message will actually be unreffed when we unlock */ 674} 675 676/** Function to be called in protected_change_watch() with refcount held */ 677typedef dbus_bool_t (* DBusWatchAddFunction) (DBusWatchList *list, 678 DBusWatch *watch); 679/** Function to be called in protected_change_watch() with refcount held */ 680typedef void (* DBusWatchRemoveFunction) (DBusWatchList *list, 681 DBusWatch *watch); 682/** Function to be called in protected_change_watch() with refcount held */ 683typedef void (* DBusWatchToggleFunction) (DBusWatchList *list, 684 DBusWatch *watch, 685 dbus_bool_t enabled); 686 687static dbus_bool_t 688protected_change_watch (DBusConnection *connection, 689 DBusWatch *watch, 690 DBusWatchAddFunction add_function, 691 DBusWatchRemoveFunction remove_function, 692 DBusWatchToggleFunction toggle_function, 693 dbus_bool_t enabled) 694{ 695 dbus_bool_t retval; 696 697 HAVE_LOCK_CHECK (connection); 698 699 /* The original purpose of protected_change_watch() was to hold a 700 * ref on the connection while dropping the connection lock, then 701 * calling out to the app. This was a broken hack that did not 702 * work, since the connection was in a hosed state (no WatchList 703 * field) while calling out. 704 * 705 * So for now we'll just keep the lock while calling out. This means 706 * apps are not allowed to call DBusConnection methods inside a 707 * watch function or they will deadlock. 708 * 709 * The "real fix" is to use the _and_unlock() pattern found 710 * elsewhere in the code, to defer calling out to the app until 711 * we're about to drop locks and return flow of control to the app 712 * anyway. 713 * 714 * See http://lists.freedesktop.org/archives/dbus/2007-July/thread.html#8144 715 */ 716 717 if (connection->watches) 718 { 719 if (add_function) 720 retval = (* add_function) (connection->watches, watch); 721 else if (remove_function) 722 { 723 retval = TRUE; 724 (* remove_function) (connection->watches, watch); 725 } 726 else 727 { 728 retval = TRUE; 729 (* toggle_function) (connection->watches, watch, enabled); 730 } 731 return retval; 732 } 733 else 734 return FALSE; 735} 736 737 738/** 739 * Adds a watch using the connection's DBusAddWatchFunction if 740 * available. Otherwise records the watch to be added when said 741 * function is available. Also re-adds the watch if the 742 * DBusAddWatchFunction changes. May fail due to lack of memory. 743 * Connection lock should be held when calling this. 744 * 745 * @param connection the connection. 746 * @param watch the watch to add. 747 * @returns #TRUE on success. 748 */ 749dbus_bool_t 750_dbus_connection_add_watch_unlocked (DBusConnection *connection, 751 DBusWatch *watch) 752{ 753 return protected_change_watch (connection, watch, 754 _dbus_watch_list_add_watch, 755 NULL, NULL, FALSE); 756} 757 758/** 759 * Removes a watch using the connection's DBusRemoveWatchFunction 760 * if available. It's an error to call this function on a watch 761 * that was not previously added. 762 * Connection lock should be held when calling this. 763 * 764 * @param connection the connection. 765 * @param watch the watch to remove. 766 */ 767void 768_dbus_connection_remove_watch_unlocked (DBusConnection *connection, 769 DBusWatch *watch) 770{ 771 protected_change_watch (connection, watch, 772 NULL, 773 _dbus_watch_list_remove_watch, 774 NULL, FALSE); 775} 776 777/** 778 * Toggles a watch and notifies app via connection's 779 * DBusWatchToggledFunction if available. It's an error to call this 780 * function on a watch that was not previously added. 781 * Connection lock should be held when calling this. 782 * 783 * @param connection the connection. 784 * @param watch the watch to toggle. 785 * @param enabled whether to enable or disable 786 */ 787void 788_dbus_connection_toggle_watch_unlocked (DBusConnection *connection, 789 DBusWatch *watch, 790 dbus_bool_t enabled) 791{ 792 _dbus_assert (watch != NULL); 793 794 protected_change_watch (connection, watch, 795 NULL, NULL, 796 _dbus_watch_list_toggle_watch, 797 enabled); 798} 799 800/** Function to be called in protected_change_timeout() with refcount held */ 801typedef dbus_bool_t (* DBusTimeoutAddFunction) (DBusTimeoutList *list, 802 DBusTimeout *timeout); 803/** Function to be called in protected_change_timeout() with refcount held */ 804typedef void (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list, 805 DBusTimeout *timeout); 806/** Function to be called in protected_change_timeout() with refcount held */ 807typedef void (* DBusTimeoutToggleFunction) (DBusTimeoutList *list, 808 DBusTimeout *timeout, 809 dbus_bool_t enabled); 810 811static dbus_bool_t 812protected_change_timeout (DBusConnection *connection, 813 DBusTimeout *timeout, 814 DBusTimeoutAddFunction add_function, 815 DBusTimeoutRemoveFunction remove_function, 816 DBusTimeoutToggleFunction toggle_function, 817 dbus_bool_t enabled) 818{ 819 dbus_bool_t retval; 820 821 HAVE_LOCK_CHECK (connection); 822 823 /* The original purpose of protected_change_timeout() was to hold a 824 * ref on the connection while dropping the connection lock, then 825 * calling out to the app. This was a broken hack that did not 826 * work, since the connection was in a hosed state (no TimeoutList 827 * field) while calling out. 828 * 829 * So for now we'll just keep the lock while calling out. This means 830 * apps are not allowed to call DBusConnection methods inside a 831 * timeout function or they will deadlock. 832 * 833 * The "real fix" is to use the _and_unlock() pattern found 834 * elsewhere in the code, to defer calling out to the app until 835 * we're about to drop locks and return flow of control to the app 836 * anyway. 837 * 838 * See http://lists.freedesktop.org/archives/dbus/2007-July/thread.html#8144 839 */ 840 841 if (connection->timeouts) 842 { 843 if (add_function) 844 retval = (* add_function) (connection->timeouts, timeout); 845 else if (remove_function) 846 { 847 retval = TRUE; 848 (* remove_function) (connection->timeouts, timeout); 849 } 850 else 851 { 852 retval = TRUE; 853 (* toggle_function) (connection->timeouts, timeout, enabled); 854 } 855 return retval; 856 } 857 else 858 return FALSE; 859} 860 861/** 862 * Adds a timeout using the connection's DBusAddTimeoutFunction if 863 * available. Otherwise records the timeout to be added when said 864 * function is available. Also re-adds the timeout if the 865 * DBusAddTimeoutFunction changes. May fail due to lack of memory. 866 * The timeout will fire repeatedly until removed. 867 * Connection lock should be held when calling this. 868 * 869 * @param connection the connection. 870 * @param timeout the timeout to add. 871 * @returns #TRUE on success. 872 */ 873dbus_bool_t 874_dbus_connection_add_timeout_unlocked (DBusConnection *connection, 875 DBusTimeout *timeout) 876{ 877 return protected_change_timeout (connection, timeout, 878 _dbus_timeout_list_add_timeout, 879 NULL, NULL, FALSE); 880} 881 882/** 883 * Removes a timeout using the connection's DBusRemoveTimeoutFunction 884 * if available. It's an error to call this function on a timeout 885 * that was not previously added. 886 * Connection lock should be held when calling this. 887 * 888 * @param connection the connection. 889 * @param timeout the timeout to remove. 890 */ 891void 892_dbus_connection_remove_timeout_unlocked (DBusConnection *connection, 893 DBusTimeout *timeout) 894{ 895 protected_change_timeout (connection, timeout, 896 NULL, 897 _dbus_timeout_list_remove_timeout, 898 NULL, FALSE); 899} 900 901/** 902 * Toggles a timeout and notifies app via connection's 903 * DBusTimeoutToggledFunction if available. It's an error to call this 904 * function on a timeout that was not previously added. 905 * Connection lock should be held when calling this. 906 * 907 * @param connection the connection. 908 * @param timeout the timeout to toggle. 909 * @param enabled whether to enable or disable 910 */ 911void 912_dbus_connection_toggle_timeout_unlocked (DBusConnection *connection, 913 DBusTimeout *timeout, 914 dbus_bool_t enabled) 915{ 916 protected_change_timeout (connection, timeout, 917 NULL, NULL, 918 _dbus_timeout_list_toggle_timeout, 919 enabled); 920} 921 922static dbus_bool_t 923_dbus_connection_attach_pending_call_unlocked (DBusConnection *connection, 924 DBusPendingCall *pending) 925{ 926 dbus_uint32_t reply_serial; 927 DBusTimeout *timeout; 928 929 HAVE_LOCK_CHECK (connection); 930 931 reply_serial = _dbus_pending_call_get_reply_serial_unlocked (pending); 932 933 _dbus_assert (reply_serial != 0); 934 935 timeout = _dbus_pending_call_get_timeout_unlocked (pending); 936 937 if (timeout) 938 { 939 if (!_dbus_connection_add_timeout_unlocked (connection, timeout)) 940 return FALSE; 941 942 if (!_dbus_hash_table_insert_int (connection->pending_replies, 943 reply_serial, 944 pending)) 945 { 946 _dbus_connection_remove_timeout_unlocked (connection, timeout); 947 948 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE); 949 HAVE_LOCK_CHECK (connection); 950 return FALSE; 951 } 952 953 _dbus_pending_call_set_timeout_added_unlocked (pending, TRUE); 954 } 955 else 956 { 957 if (!_dbus_hash_table_insert_int (connection->pending_replies, 958 reply_serial, 959 pending)) 960 { 961 HAVE_LOCK_CHECK (connection); 962 return FALSE; 963 } 964 } 965 966 _dbus_pending_call_ref_unlocked (pending); 967 968 HAVE_LOCK_CHECK (connection); 969 970 return TRUE; 971} 972 973static void 974free_pending_call_on_hash_removal (void *data) 975{ 976 DBusPendingCall *pending; 977 DBusConnection *connection; 978 979 if (data == NULL) 980 return; 981 982 pending = data; 983 984 connection = _dbus_pending_call_get_connection_unlocked (pending); 985 986 HAVE_LOCK_CHECK (connection); 987 988 if (_dbus_pending_call_is_timeout_added_unlocked (pending)) 989 { 990 _dbus_connection_remove_timeout_unlocked (connection, 991 _dbus_pending_call_get_timeout_unlocked (pending)); 992 993 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE); 994 } 995 996 /* FIXME 1.0? this is sort of dangerous and undesirable to drop the lock 997 * here, but the pending call finalizer could in principle call out to 998 * application code so we pretty much have to... some larger code reorg 999 * might be needed. 1000 */ 1001 _dbus_connection_ref_unlocked (connection); 1002 _dbus_pending_call_unref_and_unlock (pending); 1003 CONNECTION_LOCK (connection); 1004 _dbus_connection_unref_unlocked (connection); 1005} 1006 1007static void 1008_dbus_connection_detach_pending_call_unlocked (DBusConnection *connection, 1009 DBusPendingCall *pending) 1010{ 1011 /* This ends up unlocking to call the pending call finalizer, which is unexpected to 1012 * say the least. 1013 */ 1014 _dbus_hash_table_remove_int (connection->pending_replies, 1015 _dbus_pending_call_get_reply_serial_unlocked (pending)); 1016} 1017 1018static void 1019_dbus_connection_detach_pending_call_and_unlock (DBusConnection *connection, 1020 DBusPendingCall *pending) 1021{ 1022 /* The idea here is to avoid finalizing the pending call 1023 * with the lock held, since there's a destroy notifier 1024 * in pending call that goes out to application code. 1025 * 1026 * There's an extra unlock inside the hash table 1027 * "free pending call" function FIXME... 1028 */ 1029 _dbus_pending_call_ref_unlocked (pending); 1030 _dbus_hash_table_remove_int (connection->pending_replies, 1031 _dbus_pending_call_get_reply_serial_unlocked (pending)); 1032 1033 if (_dbus_pending_call_is_timeout_added_unlocked (pending)) 1034 _dbus_connection_remove_timeout_unlocked (connection, 1035 _dbus_pending_call_get_timeout_unlocked (pending)); 1036 1037 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE); 1038 1039 _dbus_pending_call_unref_and_unlock (pending); 1040} 1041 1042/** 1043 * Removes a pending call from the connection, such that 1044 * the pending reply will be ignored. May drop the last 1045 * reference to the pending call. 1046 * 1047 * @param connection the connection 1048 * @param pending the pending call 1049 */ 1050void 1051_dbus_connection_remove_pending_call (DBusConnection *connection, 1052 DBusPendingCall *pending) 1053{ 1054 CONNECTION_LOCK (connection); 1055 _dbus_connection_detach_pending_call_and_unlock (connection, pending); 1056} 1057 1058/** 1059 * Acquire the transporter I/O path. This must be done before 1060 * doing any I/O in the transporter. May sleep and drop the 1061 * IO path mutex while waiting for the I/O path. 1062 * 1063 * @param connection the connection. 1064 * @param timeout_milliseconds maximum blocking time, or -1 for no limit. 1065 * @returns TRUE if the I/O path was acquired. 1066 */ 1067static dbus_bool_t 1068_dbus_connection_acquire_io_path (DBusConnection *connection, 1069 int timeout_milliseconds) 1070{ 1071 dbus_bool_t we_acquired; 1072 1073 HAVE_LOCK_CHECK (connection); 1074 1075 /* We don't want the connection to vanish */ 1076 _dbus_connection_ref_unlocked (connection); 1077 1078 /* We will only touch io_path_acquired which is protected by our mutex */ 1079 CONNECTION_UNLOCK (connection); 1080 1081 _dbus_verbose ("locking io_path_mutex\n"); 1082 _dbus_cmutex_lock (connection->io_path_mutex); 1083 1084 _dbus_verbose ("start connection->io_path_acquired = %d timeout = %d\n", 1085 connection->io_path_acquired, timeout_milliseconds); 1086 1087 we_acquired = FALSE; 1088 1089 if (connection->io_path_acquired) 1090 { 1091 if (timeout_milliseconds != -1) 1092 { 1093 _dbus_verbose ("waiting %d for IO path to be acquirable\n", 1094 timeout_milliseconds); 1095 1096 if (!_dbus_condvar_wait_timeout (connection->io_path_cond, 1097 connection->io_path_mutex, 1098 timeout_milliseconds)) 1099 { 1100 /* We timed out before anyone signaled. */ 1101 /* (writing the loop to handle the !timedout case by 1102 * waiting longer if needed is a pain since dbus 1103 * wraps pthread_cond_timedwait to take a relative 1104 * time instead of absolute, something kind of stupid 1105 * on our part. for now it doesn't matter, we will just 1106 * end up back here eventually.) 1107 */ 1108 } 1109 } 1110 else 1111 { 1112 while (connection->io_path_acquired) 1113 { 1114 _dbus_verbose ("waiting for IO path to be acquirable\n"); 1115 _dbus_condvar_wait (connection->io_path_cond, 1116 connection->io_path_mutex); 1117 } 1118 } 1119 } 1120 1121 if (!connection->io_path_acquired) 1122 { 1123 we_acquired = TRUE; 1124 connection->io_path_acquired = TRUE; 1125 } 1126 1127 _dbus_verbose ("end connection->io_path_acquired = %d we_acquired = %d\n", 1128 connection->io_path_acquired, we_acquired); 1129 1130 _dbus_verbose ("unlocking io_path_mutex\n"); 1131 _dbus_cmutex_unlock (connection->io_path_mutex); 1132 1133 CONNECTION_LOCK (connection); 1134 1135 HAVE_LOCK_CHECK (connection); 1136 1137 _dbus_connection_unref_unlocked (connection); 1138 1139 return we_acquired; 1140} 1141 1142/** 1143 * Release the I/O path when you're done with it. Only call 1144 * after you've acquired the I/O. Wakes up at most one thread 1145 * currently waiting to acquire the I/O path. 1146 * 1147 * @param connection the connection. 1148 */ 1149static void 1150_dbus_connection_release_io_path (DBusConnection *connection) 1151{ 1152 HAVE_LOCK_CHECK (connection); 1153 1154 _dbus_verbose ("locking io_path_mutex\n"); 1155 _dbus_cmutex_lock (connection->io_path_mutex); 1156 1157 _dbus_assert (connection->io_path_acquired); 1158 1159 _dbus_verbose ("start connection->io_path_acquired = %d\n", 1160 connection->io_path_acquired); 1161 1162 connection->io_path_acquired = FALSE; 1163 _dbus_condvar_wake_one (connection->io_path_cond); 1164 1165 _dbus_verbose ("unlocking io_path_mutex\n"); 1166 _dbus_cmutex_unlock (connection->io_path_mutex); 1167} 1168 1169/** 1170 * Queues incoming messages and sends outgoing messages for this 1171 * connection, optionally blocking in the process. Each call to 1172 * _dbus_connection_do_iteration_unlocked() will call select() or poll() one 1173 * time and then read or write data if possible. 1174 * 1175 * The purpose of this function is to be able to flush outgoing 1176 * messages or queue up incoming messages without returning 1177 * control to the application and causing reentrancy weirdness. 1178 * 1179 * The flags parameter allows you to specify whether to 1180 * read incoming messages, write outgoing messages, or both, 1181 * and whether to block if no immediate action is possible. 1182 * 1183 * The timeout_milliseconds parameter does nothing unless the 1184 * iteration is blocking. 1185 * 1186 * If there are no outgoing messages and DBUS_ITERATION_DO_READING 1187 * wasn't specified, then it's impossible to block, even if 1188 * you specify DBUS_ITERATION_BLOCK; in that case the function 1189 * returns immediately. 1190 * 1191 * If pending is not NULL then a check is made if the pending call 1192 * is completed after the io path has been required. If the call 1193 * has been completed nothing is done. This must be done since 1194 * the _dbus_connection_acquire_io_path releases the connection 1195 * lock for a while. 1196 * 1197 * Called with connection lock held. 1198 * 1199 * @param connection the connection. 1200 * @param pending the pending call that should be checked or NULL 1201 * @param flags iteration flags. 1202 * @param timeout_milliseconds maximum blocking time, or -1 for no limit. 1203 */ 1204void 1205_dbus_connection_do_iteration_unlocked (DBusConnection *connection, 1206 DBusPendingCall *pending, 1207 unsigned int flags, 1208 int timeout_milliseconds) 1209{ 1210 _dbus_verbose ("start\n"); 1211 1212 HAVE_LOCK_CHECK (connection); 1213 1214 if (connection->n_outgoing == 0) 1215 flags &= ~DBUS_ITERATION_DO_WRITING; 1216 1217 if (_dbus_connection_acquire_io_path (connection, 1218 (flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0)) 1219 { 1220 HAVE_LOCK_CHECK (connection); 1221 1222 if ( (pending != NULL) && _dbus_pending_call_get_completed_unlocked(pending)) 1223 { 1224 _dbus_verbose ("pending call completed while acquiring I/O path"); 1225 } 1226 else if ( (pending != NULL) && 1227 _dbus_connection_peek_for_reply_unlocked (connection, 1228 _dbus_pending_call_get_reply_serial_unlocked (pending))) 1229 { 1230 _dbus_verbose ("pending call completed while acquiring I/O path (reply found in queue)"); 1231 } 1232 else 1233 { 1234 _dbus_transport_do_iteration (connection->transport, 1235 flags, timeout_milliseconds); 1236 } 1237 1238 _dbus_connection_release_io_path (connection); 1239 } 1240 1241 HAVE_LOCK_CHECK (connection); 1242 1243 _dbus_verbose ("end\n"); 1244} 1245 1246/** 1247 * Creates a new connection for the given transport. A transport 1248 * represents a message stream that uses some concrete mechanism, such 1249 * as UNIX domain sockets. May return #NULL if insufficient 1250 * memory exists to create the connection. 1251 * 1252 * @param transport the transport. 1253 * @returns the new connection, or #NULL on failure. 1254 */ 1255DBusConnection* 1256_dbus_connection_new_for_transport (DBusTransport *transport) 1257{ 1258 DBusConnection *connection; 1259 DBusWatchList *watch_list; 1260 DBusTimeoutList *timeout_list; 1261 DBusHashTable *pending_replies; 1262 DBusList *disconnect_link; 1263 DBusMessage *disconnect_message; 1264 DBusCounter *outgoing_counter; 1265 DBusObjectTree *objects; 1266 1267 watch_list = NULL; 1268 connection = NULL; 1269 pending_replies = NULL; 1270 timeout_list = NULL; 1271 disconnect_link = NULL; 1272 disconnect_message = NULL; 1273 outgoing_counter = NULL; 1274 objects = NULL; 1275 1276 watch_list = _dbus_watch_list_new (); 1277 if (watch_list == NULL) 1278 goto error; 1279 1280 timeout_list = _dbus_timeout_list_new (); 1281 if (timeout_list == NULL) 1282 goto error; 1283 1284 pending_replies = 1285 _dbus_hash_table_new (DBUS_HASH_INT, 1286 NULL, 1287 (DBusFreeFunction)free_pending_call_on_hash_removal); 1288 if (pending_replies == NULL) 1289 goto error; 1290 1291 connection = dbus_new0 (DBusConnection, 1); 1292 if (connection == NULL) 1293 goto error; 1294 1295 _dbus_rmutex_new_at_location (&connection->mutex); 1296 if (connection->mutex == NULL) 1297 goto error; 1298 1299 _dbus_cmutex_new_at_location (&connection->io_path_mutex); 1300 if (connection->io_path_mutex == NULL) 1301 goto error; 1302 1303 _dbus_cmutex_new_at_location (&connection->dispatch_mutex); 1304 if (connection->dispatch_mutex == NULL) 1305 goto error; 1306 1307 _dbus_condvar_new_at_location (&connection->dispatch_cond); 1308 if (connection->dispatch_cond == NULL) 1309 goto error; 1310 1311 _dbus_condvar_new_at_location (&connection->io_path_cond); 1312 if (connection->io_path_cond == NULL) 1313 goto error; 1314 1315 _dbus_rmutex_new_at_location (&connection->slot_mutex); 1316 if (connection->slot_mutex == NULL) 1317 goto error; 1318 1319 disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL, 1320 DBUS_INTERFACE_LOCAL, 1321 "Disconnected"); 1322 1323 if (disconnect_message == NULL) 1324 goto error; 1325 1326 disconnect_link = _dbus_list_alloc_link (disconnect_message); 1327 if (disconnect_link == NULL) 1328 goto error; 1329 1330 outgoing_counter = _dbus_counter_new (); 1331 if (outgoing_counter == NULL) 1332 goto error; 1333 1334 objects = _dbus_object_tree_new (connection); 1335 if (objects == NULL) 1336 goto error; 1337 1338 if (_dbus_modify_sigpipe) 1339 _dbus_disable_sigpipe (); 1340 1341 /* initialized to 0: use atomic op to avoid mixing atomic and non-atomic */ 1342 _dbus_atomic_inc (&connection->refcount); 1343 connection->transport = transport; 1344 connection->watches = watch_list; 1345 connection->timeouts = timeout_list; 1346 connection->pending_replies = pending_replies; 1347 connection->outgoing_counter = outgoing_counter; 1348 connection->filter_list = NULL; 1349 connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE; /* so we're notified first time there's data */ 1350 connection->objects = objects; 1351 connection->exit_on_disconnect = FALSE; 1352 connection->shareable = FALSE; 1353 connection->route_peer_messages = FALSE; 1354 connection->disconnected_message_arrived = FALSE; 1355 connection->disconnected_message_processed = FALSE; 1356 1357#ifndef DBUS_DISABLE_CHECKS 1358 connection->generation = _dbus_current_generation; 1359#endif 1360 1361 _dbus_data_slot_list_init (&connection->slot_list); 1362 1363 connection->client_serial = 1; 1364 1365 connection->disconnect_message_link = disconnect_link; 1366 1367 CONNECTION_LOCK (connection); 1368 1369 if (!_dbus_transport_set_connection (transport, connection)) 1370 { 1371 CONNECTION_UNLOCK (connection); 1372 1373 goto error; 1374 } 1375 1376 _dbus_transport_ref (transport); 1377 1378 CONNECTION_UNLOCK (connection); 1379 1380 _dbus_connection_trace_ref (connection, 0, 1, "new_for_transport"); 1381 return connection; 1382 1383 error: 1384 if (disconnect_message != NULL) 1385 dbus_message_unref (disconnect_message); 1386 1387 if (disconnect_link != NULL) 1388 _dbus_list_free_link (disconnect_link); 1389 1390 if (connection != NULL) 1391 { 1392 _dbus_condvar_free_at_location (&connection->io_path_cond); 1393 _dbus_condvar_free_at_location (&connection->dispatch_cond); 1394 _dbus_rmutex_free_at_location (&connection->mutex); 1395 _dbus_cmutex_free_at_location (&connection->io_path_mutex); 1396 _dbus_cmutex_free_at_location (&connection->dispatch_mutex); 1397 _dbus_rmutex_free_at_location (&connection->slot_mutex); 1398 dbus_free (connection); 1399 } 1400 if (pending_replies) 1401 _dbus_hash_table_unref (pending_replies); 1402 1403 if (watch_list) 1404 _dbus_watch_list_free (watch_list); 1405 1406 if (timeout_list) 1407 _dbus_timeout_list_free (timeout_list); 1408 1409 if (outgoing_counter) 1410 _dbus_counter_unref (outgoing_counter); 1411 1412 if (objects) 1413 _dbus_object_tree_unref (objects); 1414 1415 return NULL; 1416} 1417 1418/** 1419 * Increments the reference count of a DBusConnection. 1420 * Requires that the caller already holds the connection lock. 1421 * 1422 * @param connection the connection. 1423 * @returns the connection. 1424 */ 1425DBusConnection * 1426_dbus_connection_ref_unlocked (DBusConnection *connection) 1427{ 1428 dbus_int32_t old_refcount; 1429 1430 _dbus_assert (connection != NULL); 1431 _dbus_assert (connection->generation == _dbus_current_generation); 1432 1433 HAVE_LOCK_CHECK (connection); 1434 1435 old_refcount = _dbus_atomic_inc (&connection->refcount); 1436 _dbus_connection_trace_ref (connection, old_refcount, old_refcount + 1, 1437 "ref_unlocked"); 1438 1439 return connection; 1440} 1441 1442/** 1443 * Decrements the reference count of a DBusConnection. 1444 * Requires that the caller already holds the connection lock. 1445 * 1446 * @param connection the connection. 1447 */ 1448void 1449_dbus_connection_unref_unlocked (DBusConnection *connection) 1450{ 1451 dbus_int32_t old_refcount; 1452 1453 HAVE_LOCK_CHECK (connection); 1454 1455 _dbus_assert (connection != NULL); 1456 1457 old_refcount = _dbus_atomic_dec (&connection->refcount); 1458 1459 _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1, 1460 "unref_unlocked"); 1461 1462 if (old_refcount == 1) 1463 _dbus_connection_last_unref (connection); 1464} 1465 1466static dbus_uint32_t 1467_dbus_connection_get_next_client_serial (DBusConnection *connection) 1468{ 1469 dbus_uint32_t serial; 1470 1471 serial = connection->client_serial++; 1472 1473 if (connection->client_serial == 0) 1474 connection->client_serial = 1; 1475 1476 return serial; 1477} 1478 1479/** 1480 * A callback for use with dbus_watch_new() to create a DBusWatch. 1481 * 1482 * @todo This is basically a hack - we could delete _dbus_transport_handle_watch() 1483 * and the virtual handle_watch in DBusTransport if we got rid of it. 1484 * The reason this is some work is threading, see the _dbus_connection_handle_watch() 1485 * implementation. 1486 * 1487 * @param watch the watch. 1488 * @param condition the current condition of the file descriptors being watched. 1489 * @param data must be a pointer to a #DBusConnection 1490 * @returns #FALSE if the IO condition may not have been fully handled due to lack of memory 1491 */ 1492dbus_bool_t 1493_dbus_connection_handle_watch (DBusWatch *watch, 1494 unsigned int condition, 1495 void *data) 1496{ 1497 DBusConnection *connection; 1498 dbus_bool_t retval; 1499 DBusDispatchStatus status; 1500 1501 connection = data; 1502 1503 _dbus_verbose ("start\n"); 1504 1505 CONNECTION_LOCK (connection); 1506 1507 if (!_dbus_connection_acquire_io_path (connection, 1)) 1508 { 1509 /* another thread is handling the message */ 1510 CONNECTION_UNLOCK (connection); 1511 return TRUE; 1512 } 1513 1514 HAVE_LOCK_CHECK (connection); 1515 retval = _dbus_transport_handle_watch (connection->transport, 1516 watch, condition); 1517 1518 _dbus_connection_release_io_path (connection); 1519 1520 HAVE_LOCK_CHECK (connection); 1521 1522 _dbus_verbose ("middle\n"); 1523 1524 status = _dbus_connection_get_dispatch_status_unlocked (connection); 1525 1526 /* this calls out to user code */ 1527 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 1528 1529 _dbus_verbose ("end\n"); 1530 1531 return retval; 1532} 1533 1534_DBUS_DEFINE_GLOBAL_LOCK (shared_connections); 1535static DBusHashTable *shared_connections = NULL; 1536static DBusList *shared_connections_no_guid = NULL; 1537 1538static void 1539close_connection_on_shutdown (DBusConnection *connection) 1540{ 1541 DBusMessage *message; 1542 1543 dbus_connection_ref (connection); 1544 _dbus_connection_close_possibly_shared (connection); 1545 1546 /* Churn through to the Disconnected message */ 1547 while ((message = dbus_connection_pop_message (connection))) 1548 { 1549 dbus_message_unref (message); 1550 } 1551 dbus_connection_unref (connection); 1552} 1553 1554static void 1555shared_connections_shutdown (void *data) 1556{ 1557 int n_entries; 1558 1559 _DBUS_LOCK (shared_connections); 1560 1561 /* This is a little bit unpleasant... better ideas? */ 1562 while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0) 1563 { 1564 DBusConnection *connection; 1565 DBusHashIter iter; 1566 1567 _dbus_hash_iter_init (shared_connections, &iter); 1568 _dbus_hash_iter_next (&iter); 1569 1570 connection = _dbus_hash_iter_get_value (&iter); 1571 1572 _DBUS_UNLOCK (shared_connections); 1573 close_connection_on_shutdown (connection); 1574 _DBUS_LOCK (shared_connections); 1575 1576 /* The connection should now be dead and not in our hash ... */ 1577 _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) < n_entries); 1578 } 1579 1580 _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) == 0); 1581 1582 _dbus_hash_table_unref (shared_connections); 1583 shared_connections = NULL; 1584 1585 if (shared_connections_no_guid != NULL) 1586 { 1587 DBusConnection *connection; 1588 connection = _dbus_list_pop_first (&shared_connections_no_guid); 1589 while (connection != NULL) 1590 { 1591 _DBUS_UNLOCK (shared_connections); 1592 close_connection_on_shutdown (connection); 1593 _DBUS_LOCK (shared_connections); 1594 connection = _dbus_list_pop_first (&shared_connections_no_guid); 1595 } 1596 } 1597 1598 shared_connections_no_guid = NULL; 1599 1600 _DBUS_UNLOCK (shared_connections); 1601} 1602 1603static dbus_bool_t 1604connection_lookup_shared (DBusAddressEntry *entry, 1605 DBusConnection **result) 1606{ 1607 _dbus_verbose ("checking for existing connection\n"); 1608 1609 *result = NULL; 1610 1611 _DBUS_LOCK (shared_connections); 1612 1613 if (shared_connections == NULL) 1614 { 1615 _dbus_verbose ("creating shared_connections hash table\n"); 1616 1617 shared_connections = _dbus_hash_table_new (DBUS_HASH_STRING, 1618 dbus_free, 1619 NULL); 1620 if (shared_connections == NULL) 1621 { 1622 _DBUS_UNLOCK (shared_connections); 1623 return FALSE; 1624 } 1625 1626 if (!_dbus_register_shutdown_func (shared_connections_shutdown, NULL)) 1627 { 1628 _dbus_hash_table_unref (shared_connections); 1629 shared_connections = NULL; 1630 _DBUS_UNLOCK (shared_connections); 1631 return FALSE; 1632 } 1633 1634 _dbus_verbose (" successfully created shared_connections\n"); 1635 1636 _DBUS_UNLOCK (shared_connections); 1637 return TRUE; /* no point looking up in the hash we just made */ 1638 } 1639 else 1640 { 1641 const char *guid; 1642 1643 guid = dbus_address_entry_get_value (entry, "guid"); 1644 1645 if (guid != NULL) 1646 { 1647 DBusConnection *connection; 1648 1649 connection = _dbus_hash_table_lookup_string (shared_connections, 1650 guid); 1651 1652 if (connection) 1653 { 1654 /* The DBusConnection can't be finalized without taking 1655 * the shared_connections lock to remove it from the 1656 * hash. So it's safe to ref the connection here. 1657 * However, it may be disconnected if the Disconnected 1658 * message hasn't been processed yet, in which case we 1659 * want to pretend it isn't in the hash and avoid 1660 * returning it. 1661 * 1662 * The idea is to avoid ever returning a disconnected connection 1663 * from dbus_connection_open(). We could just synchronously 1664 * drop our shared ref to the connection on connection disconnect, 1665 * and then assert here that the connection is connected, but 1666 * that causes reentrancy headaches. 1667 */ 1668 CONNECTION_LOCK (connection); 1669 if (_dbus_connection_get_is_connected_unlocked (connection)) 1670 { 1671 _dbus_connection_ref_unlocked (connection); 1672 *result = connection; 1673 _dbus_verbose ("looked up existing connection to server guid %s\n", 1674 guid); 1675 } 1676 else 1677 { 1678 _dbus_verbose ("looked up existing connection to server guid %s but it was disconnected so ignoring it\n", 1679 guid); 1680 } 1681 CONNECTION_UNLOCK (connection); 1682 } 1683 } 1684 1685 _DBUS_UNLOCK (shared_connections); 1686 return TRUE; 1687 } 1688} 1689 1690static dbus_bool_t 1691connection_record_shared_unlocked (DBusConnection *connection, 1692 const char *guid) 1693{ 1694 char *guid_key; 1695 char *guid_in_connection; 1696 1697 HAVE_LOCK_CHECK (connection); 1698 _dbus_assert (connection->server_guid == NULL); 1699 _dbus_assert (connection->shareable); 1700 1701 /* get a hard ref on this connection, even if 1702 * we won't in fact store it in the hash, we still 1703 * need to hold a ref on it until it's disconnected. 1704 */ 1705 _dbus_connection_ref_unlocked (connection); 1706 1707 if (guid == NULL) 1708 { 1709 _DBUS_LOCK (shared_connections); 1710 1711 if (!_dbus_list_prepend (&shared_connections_no_guid, connection)) 1712 { 1713 _DBUS_UNLOCK (shared_connections); 1714 return FALSE; 1715 } 1716 1717 _DBUS_UNLOCK (shared_connections); 1718 return TRUE; /* don't store in the hash */ 1719 } 1720 1721 /* A separate copy of the key is required in the hash table, because 1722 * we don't have a lock on the connection when we are doing a hash 1723 * lookup. 1724 */ 1725 1726 guid_key = _dbus_strdup (guid); 1727 if (guid_key == NULL) 1728 return FALSE; 1729 1730 guid_in_connection = _dbus_strdup (guid); 1731 if (guid_in_connection == NULL) 1732 { 1733 dbus_free (guid_key); 1734 return FALSE; 1735 } 1736 1737 _DBUS_LOCK (shared_connections); 1738 _dbus_assert (shared_connections != NULL); 1739 1740 if (!_dbus_hash_table_insert_string (shared_connections, 1741 guid_key, connection)) 1742 { 1743 dbus_free (guid_key); 1744 dbus_free (guid_in_connection); 1745 _DBUS_UNLOCK (shared_connections); 1746 return FALSE; 1747 } 1748 1749 connection->server_guid = guid_in_connection; 1750 1751 _dbus_verbose ("stored connection to %s to be shared\n", 1752 connection->server_guid); 1753 1754 _DBUS_UNLOCK (shared_connections); 1755 1756 _dbus_assert (connection->server_guid != NULL); 1757 1758 return TRUE; 1759} 1760 1761static void 1762connection_forget_shared_unlocked (DBusConnection *connection) 1763{ 1764 HAVE_LOCK_CHECK (connection); 1765 1766 if (!connection->shareable) 1767 return; 1768 1769 _DBUS_LOCK (shared_connections); 1770 1771 if (connection->server_guid != NULL) 1772 { 1773 _dbus_verbose ("dropping connection to %s out of the shared table\n", 1774 connection->server_guid); 1775 1776 if (!_dbus_hash_table_remove_string (shared_connections, 1777 connection->server_guid)) 1778 _dbus_assert_not_reached ("connection was not in the shared table"); 1779 1780 dbus_free (connection->server_guid); 1781 connection->server_guid = NULL; 1782 } 1783 else 1784 { 1785 _dbus_list_remove (&shared_connections_no_guid, connection); 1786 } 1787 1788 _DBUS_UNLOCK (shared_connections); 1789 1790 /* remove our reference held on all shareable connections */ 1791 _dbus_connection_unref_unlocked (connection); 1792} 1793 1794static DBusConnection* 1795connection_try_from_address_entry (DBusAddressEntry *entry, 1796 DBusError *error) 1797{ 1798 DBusTransport *transport; 1799 DBusConnection *connection; 1800 1801 transport = _dbus_transport_open (entry, error); 1802 1803 if (transport == NULL) 1804 { 1805 _DBUS_ASSERT_ERROR_IS_SET (error); 1806 return NULL; 1807 } 1808 1809 connection = _dbus_connection_new_for_transport (transport); 1810 1811 _dbus_transport_unref (transport); 1812 1813 if (connection == NULL) 1814 { 1815 _DBUS_SET_OOM (error); 1816 return NULL; 1817 } 1818 1819#ifndef DBUS_DISABLE_CHECKS 1820 _dbus_assert (!connection->have_connection_lock); 1821#endif 1822 return connection; 1823} 1824 1825/* 1826 * If the shared parameter is true, then any existing connection will 1827 * be used (and if a new connection is created, it will be available 1828 * for use by others). If the shared parameter is false, a new 1829 * connection will always be created, and the new connection will 1830 * never be returned to other callers. 1831 * 1832 * @param address the address 1833 * @param shared whether the connection is shared or private 1834 * @param error error return 1835 * @returns the connection or #NULL on error 1836 */ 1837static DBusConnection* 1838_dbus_connection_open_internal (const char *address, 1839 dbus_bool_t shared, 1840 DBusError *error) 1841{ 1842 DBusConnection *connection; 1843 DBusAddressEntry **entries; 1844 DBusError tmp_error = DBUS_ERROR_INIT; 1845 DBusError first_error = DBUS_ERROR_INIT; 1846 int len, i; 1847 1848 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1849 1850 _dbus_verbose ("opening %s connection to: %s\n", 1851 shared ? "shared" : "private", address); 1852 1853 if (!dbus_parse_address (address, &entries, &len, error)) 1854 return NULL; 1855 1856 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1857 1858 connection = NULL; 1859 1860 for (i = 0; i < len; i++) 1861 { 1862 if (shared) 1863 { 1864 if (!connection_lookup_shared (entries[i], &connection)) 1865 _DBUS_SET_OOM (&tmp_error); 1866 } 1867 1868 if (connection == NULL) 1869 { 1870 connection = connection_try_from_address_entry (entries[i], 1871 &tmp_error); 1872 1873 if (connection != NULL && shared) 1874 { 1875 const char *guid; 1876 1877 connection->shareable = TRUE; 1878 1879 /* guid may be NULL */ 1880 guid = dbus_address_entry_get_value (entries[i], "guid"); 1881 1882 CONNECTION_LOCK (connection); 1883 1884 if (!connection_record_shared_unlocked (connection, guid)) 1885 { 1886 _DBUS_SET_OOM (&tmp_error); 1887 _dbus_connection_close_possibly_shared_and_unlock (connection); 1888 dbus_connection_unref (connection); 1889 connection = NULL; 1890 } 1891 else 1892 CONNECTION_UNLOCK (connection); 1893 } 1894 } 1895 1896 if (connection) 1897 break; 1898 1899 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error); 1900 1901 if (i == 0) 1902 dbus_move_error (&tmp_error, &first_error); 1903 else 1904 dbus_error_free (&tmp_error); 1905 } 1906 1907 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1908 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error); 1909 1910 if (connection == NULL) 1911 { 1912 _DBUS_ASSERT_ERROR_IS_SET (&first_error); 1913 dbus_move_error (&first_error, error); 1914 } 1915 else 1916 dbus_error_free (&first_error); 1917 1918 dbus_address_entries_free (entries); 1919 return connection; 1920} 1921 1922/** 1923 * Closes a shared OR private connection, while dbus_connection_close() can 1924 * only be used on private connections. Should only be called by the 1925 * dbus code that owns the connection - an owner must be known, 1926 * the open/close state is like malloc/free, not like ref/unref. 1927 * 1928 * @param connection the connection 1929 */ 1930void 1931_dbus_connection_close_possibly_shared (DBusConnection *connection) 1932{ 1933 _dbus_assert (connection != NULL); 1934 _dbus_assert (connection->generation == _dbus_current_generation); 1935 1936 CONNECTION_LOCK (connection); 1937 _dbus_connection_close_possibly_shared_and_unlock (connection); 1938} 1939 1940static DBusPreallocatedSend* 1941_dbus_connection_preallocate_send_unlocked (DBusConnection *connection) 1942{ 1943 DBusPreallocatedSend *preallocated; 1944 1945 HAVE_LOCK_CHECK (connection); 1946 1947 _dbus_assert (connection != NULL); 1948 1949 preallocated = dbus_new (DBusPreallocatedSend, 1); 1950 if (preallocated == NULL) 1951 return NULL; 1952 1953 preallocated->queue_link = _dbus_list_alloc_link (NULL); 1954 if (preallocated->queue_link == NULL) 1955 goto failed_0; 1956 1957 preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter); 1958 if (preallocated->counter_link == NULL) 1959 goto failed_1; 1960 1961 _dbus_counter_ref (preallocated->counter_link->data); 1962 1963 preallocated->connection = connection; 1964 1965 return preallocated; 1966 1967 failed_1: 1968 _dbus_list_free_link (preallocated->queue_link); 1969 failed_0: 1970 dbus_free (preallocated); 1971 1972 return NULL; 1973} 1974 1975/* Called with lock held, does not update dispatch status */ 1976static void 1977_dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *connection, 1978 DBusPreallocatedSend *preallocated, 1979 DBusMessage *message, 1980 dbus_uint32_t *client_serial) 1981{ 1982 dbus_uint32_t serial; 1983 1984 preallocated->queue_link->data = message; 1985 _dbus_list_prepend_link (&connection->outgoing_messages, 1986 preallocated->queue_link); 1987 1988 /* It's OK that we'll never call the notify function, because for the 1989 * outgoing limit, there isn't one */ 1990 _dbus_message_add_counter_link (message, 1991 preallocated->counter_link); 1992 1993 dbus_free (preallocated); 1994 preallocated = NULL; 1995 1996 dbus_message_ref (message); 1997 1998 connection->n_outgoing += 1; 1999 2000 _dbus_verbose ("Message %p (%s %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n", 2001 message, 2002 dbus_message_type_to_string (dbus_message_get_type (message)), 2003 dbus_message_get_path (message) ? 2004 dbus_message_get_path (message) : 2005 "no path", 2006 dbus_message_get_interface (message) ? 2007 dbus_message_get_interface (message) : 2008 "no interface", 2009 dbus_message_get_member (message) ? 2010 dbus_message_get_member (message) : 2011 "no member", 2012 dbus_message_get_signature (message), 2013 dbus_message_get_destination (message) ? 2014 dbus_message_get_destination (message) : 2015 "null", 2016 connection, 2017 connection->n_outgoing); 2018 2019 if (dbus_message_get_serial (message) == 0) 2020 { 2021 serial = _dbus_connection_get_next_client_serial (connection); 2022 dbus_message_set_serial (message, serial); 2023 if (client_serial) 2024 *client_serial = serial; 2025 } 2026 else 2027 { 2028 if (client_serial) 2029 *client_serial = dbus_message_get_serial (message); 2030 } 2031 2032 _dbus_verbose ("Message %p serial is %u\n", 2033 message, dbus_message_get_serial (message)); 2034 2035 dbus_message_lock (message); 2036 2037 /* Now we need to run an iteration to hopefully just write the messages 2038 * out immediately, and otherwise get them queued up 2039 */ 2040 _dbus_connection_do_iteration_unlocked (connection, 2041 NULL, 2042 DBUS_ITERATION_DO_WRITING, 2043 -1); 2044 2045 /* If stuff is still queued up, be sure we wake up the main loop */ 2046 if (connection->n_outgoing > 0) 2047 _dbus_connection_wakeup_mainloop (connection); 2048} 2049 2050static void 2051_dbus_connection_send_preallocated_and_unlock (DBusConnection *connection, 2052 DBusPreallocatedSend *preallocated, 2053 DBusMessage *message, 2054 dbus_uint32_t *client_serial) 2055{ 2056 DBusDispatchStatus status; 2057 2058 HAVE_LOCK_CHECK (connection); 2059 2060 _dbus_connection_send_preallocated_unlocked_no_update (connection, 2061 preallocated, 2062 message, client_serial); 2063 2064 _dbus_verbose ("middle\n"); 2065 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2066 2067 /* this calls out to user code */ 2068 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2069} 2070 2071/** 2072 * Like dbus_connection_send(), but assumes the connection 2073 * is already locked on function entry, and unlocks before returning. 2074 * 2075 * @param connection the connection 2076 * @param message the message to send 2077 * @param client_serial return location for client serial of sent message 2078 * @returns #FALSE on out-of-memory 2079 */ 2080dbus_bool_t 2081_dbus_connection_send_and_unlock (DBusConnection *connection, 2082 DBusMessage *message, 2083 dbus_uint32_t *client_serial) 2084{ 2085 DBusPreallocatedSend *preallocated; 2086 2087 _dbus_assert (connection != NULL); 2088 _dbus_assert (message != NULL); 2089 2090 preallocated = _dbus_connection_preallocate_send_unlocked (connection); 2091 if (preallocated == NULL) 2092 { 2093 CONNECTION_UNLOCK (connection); 2094 return FALSE; 2095 } 2096 2097 _dbus_connection_send_preallocated_and_unlock (connection, 2098 preallocated, 2099 message, 2100 client_serial); 2101 return TRUE; 2102} 2103 2104/** 2105 * Used internally to handle the semantics of dbus_server_set_new_connection_function(). 2106 * If the new connection function does not ref the connection, we want to close it. 2107 * 2108 * A bit of a hack, probably the new connection function should have returned a value 2109 * for whether to close, or should have had to close the connection itself if it 2110 * didn't want it. 2111 * 2112 * But, this works OK as long as the new connection function doesn't do anything 2113 * crazy like keep the connection around without ref'ing it. 2114 * 2115 * We have to lock the connection across refcount check and close in case 2116 * the new connection function spawns a thread that closes and unrefs. 2117 * In that case, if the app thread 2118 * closes and unrefs first, we'll harmlessly close again; if the app thread 2119 * still has the ref, we'll close and then the app will close harmlessly. 2120 * If the app unrefs without closing, the app is broken since if the 2121 * app refs from the new connection function it is supposed to also close. 2122 * 2123 * If we didn't atomically check the refcount and close with the lock held 2124 * though, we could screw this up. 2125 * 2126 * @param connection the connection 2127 */ 2128void 2129_dbus_connection_close_if_only_one_ref (DBusConnection *connection) 2130{ 2131 dbus_int32_t refcount; 2132 2133 CONNECTION_LOCK (connection); 2134 2135 refcount = _dbus_atomic_get (&connection->refcount); 2136 /* The caller should have at least one ref */ 2137 _dbus_assert (refcount >= 1); 2138 2139 if (refcount == 1) 2140 _dbus_connection_close_possibly_shared_and_unlock (connection); 2141 else 2142 CONNECTION_UNLOCK (connection); 2143} 2144 2145 2146/** 2147 * When a function that blocks has been called with a timeout, and we 2148 * run out of memory, the time to wait for memory is based on the 2149 * timeout. If the caller was willing to block a long time we wait a 2150 * relatively long time for memory, if they were only willing to block 2151 * briefly then we retry for memory at a rapid rate. 2152 * 2153 * @timeout_milliseconds the timeout requested for blocking 2154 */ 2155static void 2156_dbus_memory_pause_based_on_timeout (int timeout_milliseconds) 2157{ 2158 if (timeout_milliseconds == -1) 2159 _dbus_sleep_milliseconds (1000); 2160 else if (timeout_milliseconds < 100) 2161 ; /* just busy loop */ 2162 else if (timeout_milliseconds <= 1000) 2163 _dbus_sleep_milliseconds (timeout_milliseconds / 3); 2164 else 2165 _dbus_sleep_milliseconds (1000); 2166} 2167 2168static DBusMessage * 2169generate_local_error_message (dbus_uint32_t serial, 2170 char *error_name, 2171 char *error_msg) 2172{ 2173 DBusMessage *message; 2174 message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR); 2175 if (!message) 2176 goto out; 2177 2178 if (!dbus_message_set_error_name (message, error_name)) 2179 { 2180 dbus_message_unref (message); 2181 message = NULL; 2182 goto out; 2183 } 2184 2185 dbus_message_set_no_reply (message, TRUE); 2186 2187 if (!dbus_message_set_reply_serial (message, 2188 serial)) 2189 { 2190 dbus_message_unref (message); 2191 message = NULL; 2192 goto out; 2193 } 2194 2195 if (error_msg != NULL) 2196 { 2197 DBusMessageIter iter; 2198 2199 dbus_message_iter_init_append (message, &iter); 2200 if (!dbus_message_iter_append_basic (&iter, 2201 DBUS_TYPE_STRING, 2202 &error_msg)) 2203 { 2204 dbus_message_unref (message); 2205 message = NULL; 2206 goto out; 2207 } 2208 } 2209 2210 out: 2211 return message; 2212} 2213 2214/* 2215 * Peek the incoming queue to see if we got reply for a specific serial 2216 */ 2217static dbus_bool_t 2218_dbus_connection_peek_for_reply_unlocked (DBusConnection *connection, 2219 dbus_uint32_t client_serial) 2220{ 2221 DBusList *link; 2222 HAVE_LOCK_CHECK (connection); 2223 2224 link = _dbus_list_get_first_link (&connection->incoming_messages); 2225 2226 while (link != NULL) 2227 { 2228 DBusMessage *reply = link->data; 2229 2230 if (dbus_message_get_reply_serial (reply) == client_serial) 2231 { 2232 _dbus_verbose ("%s reply to %d found in queue\n", _DBUS_FUNCTION_NAME, client_serial); 2233 return TRUE; 2234 } 2235 link = _dbus_list_get_next_link (&connection->incoming_messages, link); 2236 } 2237 2238 return FALSE; 2239} 2240 2241/* This is slightly strange since we can pop a message here without 2242 * the dispatch lock. 2243 */ 2244static DBusMessage* 2245check_for_reply_unlocked (DBusConnection *connection, 2246 dbus_uint32_t client_serial) 2247{ 2248 DBusList *link; 2249 2250 HAVE_LOCK_CHECK (connection); 2251 2252 link = _dbus_list_get_first_link (&connection->incoming_messages); 2253 2254 while (link != NULL) 2255 { 2256 DBusMessage *reply = link->data; 2257 2258 if (dbus_message_get_reply_serial (reply) == client_serial) 2259 { 2260 _dbus_list_remove_link (&connection->incoming_messages, link); 2261 connection->n_incoming -= 1; 2262 return reply; 2263 } 2264 link = _dbus_list_get_next_link (&connection->incoming_messages, link); 2265 } 2266 2267 return NULL; 2268} 2269 2270static void 2271connection_timeout_and_complete_all_pending_calls_unlocked (DBusConnection *connection) 2272{ 2273 /* We can't iterate over the hash in the normal way since we'll be 2274 * dropping the lock for each item. So we restart the 2275 * iter each time as we drain the hash table. 2276 */ 2277 2278 while (_dbus_hash_table_get_n_entries (connection->pending_replies) > 0) 2279 { 2280 DBusPendingCall *pending; 2281 DBusHashIter iter; 2282 2283 _dbus_hash_iter_init (connection->pending_replies, &iter); 2284 _dbus_hash_iter_next (&iter); 2285 2286 pending = _dbus_hash_iter_get_value (&iter); 2287 _dbus_pending_call_ref_unlocked (pending); 2288 2289 _dbus_pending_call_queue_timeout_error_unlocked (pending, 2290 connection); 2291 2292 if (_dbus_pending_call_is_timeout_added_unlocked (pending)) 2293 _dbus_connection_remove_timeout_unlocked (connection, 2294 _dbus_pending_call_get_timeout_unlocked (pending)); 2295 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE); 2296 _dbus_hash_iter_remove_entry (&iter); 2297 2298 _dbus_pending_call_unref_and_unlock (pending); 2299 CONNECTION_LOCK (connection); 2300 } 2301 HAVE_LOCK_CHECK (connection); 2302} 2303 2304static void 2305complete_pending_call_and_unlock (DBusConnection *connection, 2306 DBusPendingCall *pending, 2307 DBusMessage *message) 2308{ 2309 _dbus_pending_call_set_reply_unlocked (pending, message); 2310 _dbus_pending_call_ref_unlocked (pending); /* in case there's no app with a ref held */ 2311 _dbus_connection_detach_pending_call_and_unlock (connection, pending); 2312 2313 /* Must be called unlocked since it invokes app callback */ 2314 _dbus_pending_call_complete (pending); 2315 dbus_pending_call_unref (pending); 2316} 2317 2318static dbus_bool_t 2319check_for_reply_and_update_dispatch_unlocked (DBusConnection *connection, 2320 DBusPendingCall *pending) 2321{ 2322 DBusMessage *reply; 2323 DBusDispatchStatus status; 2324 2325 reply = check_for_reply_unlocked (connection, 2326 _dbus_pending_call_get_reply_serial_unlocked (pending)); 2327 if (reply != NULL) 2328 { 2329 _dbus_verbose ("checked for reply\n"); 2330 2331 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n"); 2332 2333 complete_pending_call_and_unlock (connection, pending, reply); 2334 dbus_message_unref (reply); 2335 2336 CONNECTION_LOCK (connection); 2337 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2338 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2339 dbus_pending_call_unref (pending); 2340 2341 return TRUE; 2342 } 2343 2344 return FALSE; 2345} 2346 2347/** 2348 * Blocks until a pending call times out or gets a reply. 2349 * 2350 * Does not re-enter the main loop or run filter/path-registered 2351 * callbacks. The reply to the message will not be seen by 2352 * filter callbacks. 2353 * 2354 * Returns immediately if pending call already got a reply. 2355 * 2356 * @todo could use performance improvements (it keeps scanning 2357 * the whole message queue for example) 2358 * 2359 * @param pending the pending call we block for a reply on 2360 */ 2361void 2362_dbus_connection_block_pending_call (DBusPendingCall *pending) 2363{ 2364 long start_tv_sec, start_tv_usec; 2365 long tv_sec, tv_usec; 2366 DBusDispatchStatus status; 2367 DBusConnection *connection; 2368 dbus_uint32_t client_serial; 2369 DBusTimeout *timeout; 2370 int timeout_milliseconds, elapsed_milliseconds; 2371 2372 _dbus_assert (pending != NULL); 2373 2374 if (dbus_pending_call_get_completed (pending)) 2375 return; 2376 2377 dbus_pending_call_ref (pending); /* necessary because the call could be canceled */ 2378 2379 connection = _dbus_pending_call_get_connection_and_lock (pending); 2380 2381 /* Flush message queue - note, can affect dispatch status */ 2382 _dbus_connection_flush_unlocked (connection); 2383 2384 client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending); 2385 2386 /* note that timeout_milliseconds is limited to a smallish value 2387 * in _dbus_pending_call_new() so overflows aren't possible 2388 * below 2389 */ 2390 timeout = _dbus_pending_call_get_timeout_unlocked (pending); 2391 _dbus_get_monotonic_time (&start_tv_sec, &start_tv_usec); 2392 if (timeout) 2393 { 2394 timeout_milliseconds = dbus_timeout_get_interval (timeout); 2395 2396 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec\n", 2397 timeout_milliseconds, 2398 client_serial, 2399 start_tv_sec, start_tv_usec); 2400 } 2401 else 2402 { 2403 timeout_milliseconds = -1; 2404 2405 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block for reply serial %u\n", client_serial); 2406 } 2407 2408 /* check to see if we already got the data off the socket */ 2409 /* from another blocked pending call */ 2410 if (check_for_reply_and_update_dispatch_unlocked (connection, pending)) 2411 return; 2412 2413 /* Now we wait... */ 2414 /* always block at least once as we know we don't have the reply yet */ 2415 _dbus_connection_do_iteration_unlocked (connection, 2416 pending, 2417 DBUS_ITERATION_DO_READING | 2418 DBUS_ITERATION_BLOCK, 2419 timeout_milliseconds); 2420 2421 recheck_status: 2422 2423 _dbus_verbose ("top of recheck\n"); 2424 2425 HAVE_LOCK_CHECK (connection); 2426 2427 /* queue messages and get status */ 2428 2429 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2430 2431 /* the get_completed() is in case a dispatch() while we were blocking 2432 * got the reply instead of us. 2433 */ 2434 if (_dbus_pending_call_get_completed_unlocked (pending)) 2435 { 2436 _dbus_verbose ("Pending call completed by dispatch\n"); 2437 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2438 dbus_pending_call_unref (pending); 2439 return; 2440 } 2441 2442 if (status == DBUS_DISPATCH_DATA_REMAINS) 2443 { 2444 if (check_for_reply_and_update_dispatch_unlocked (connection, pending)) 2445 return; 2446 } 2447 2448 _dbus_get_monotonic_time (&tv_sec, &tv_usec); 2449 elapsed_milliseconds = (tv_sec - start_tv_sec) * 1000 + 2450 (tv_usec - start_tv_usec) / 1000; 2451 2452 if (!_dbus_connection_get_is_connected_unlocked (connection)) 2453 { 2454 DBusMessage *error_msg; 2455 2456 error_msg = generate_local_error_message (client_serial, 2457 DBUS_ERROR_DISCONNECTED, 2458 "Connection was disconnected before a reply was received"); 2459 2460 /* on OOM error_msg is set to NULL */ 2461 complete_pending_call_and_unlock (connection, pending, error_msg); 2462 dbus_pending_call_unref (pending); 2463 return; 2464 } 2465 else if (connection->disconnect_message_link == NULL) 2466 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n"); 2467 else if (timeout == NULL) 2468 { 2469 if (status == DBUS_DISPATCH_NEED_MEMORY) 2470 { 2471 /* Try sleeping a bit, as we aren't sure we need to block for reading, 2472 * we may already have a reply in the buffer and just can't process 2473 * it. 2474 */ 2475 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n"); 2476 2477 _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds); 2478 } 2479 else 2480 { 2481 /* block again, we don't have the reply buffered yet. */ 2482 _dbus_connection_do_iteration_unlocked (connection, 2483 pending, 2484 DBUS_ITERATION_DO_READING | 2485 DBUS_ITERATION_BLOCK, 2486 timeout_milliseconds - elapsed_milliseconds); 2487 } 2488 2489 goto recheck_status; 2490 } 2491 else if (tv_sec < start_tv_sec) 2492 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n"); 2493 else if (elapsed_milliseconds < timeout_milliseconds) 2494 { 2495 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds - elapsed_milliseconds); 2496 2497 if (status == DBUS_DISPATCH_NEED_MEMORY) 2498 { 2499 /* Try sleeping a bit, as we aren't sure we need to block for reading, 2500 * we may already have a reply in the buffer and just can't process 2501 * it. 2502 */ 2503 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n"); 2504 2505 _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds); 2506 } 2507 else 2508 { 2509 /* block again, we don't have the reply buffered yet. */ 2510 _dbus_connection_do_iteration_unlocked (connection, 2511 NULL, 2512 DBUS_ITERATION_DO_READING | 2513 DBUS_ITERATION_BLOCK, 2514 timeout_milliseconds - elapsed_milliseconds); 2515 } 2516 2517 goto recheck_status; 2518 } 2519 2520 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %d milliseconds and got no reply\n", 2521 elapsed_milliseconds); 2522 2523 _dbus_assert (!_dbus_pending_call_get_completed_unlocked (pending)); 2524 2525 /* unlock and call user code */ 2526 complete_pending_call_and_unlock (connection, pending, NULL); 2527 2528 /* update user code on dispatch status */ 2529 CONNECTION_LOCK (connection); 2530 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2531 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2532 dbus_pending_call_unref (pending); 2533} 2534 2535/** @} */ 2536 2537/** 2538 * @addtogroup DBusConnection 2539 * 2540 * @{ 2541 */ 2542 2543/** 2544 * Gets a connection to a remote address. If a connection to the given 2545 * address already exists, returns the existing connection with its 2546 * reference count incremented. Otherwise, returns a new connection 2547 * and saves the new connection for possible re-use if a future call 2548 * to dbus_connection_open() asks to connect to the same server. 2549 * 2550 * Use dbus_connection_open_private() to get a dedicated connection 2551 * not shared with other callers of dbus_connection_open(). 2552 * 2553 * If the open fails, the function returns #NULL, and provides a 2554 * reason for the failure in the error parameter. Pass #NULL for the 2555 * error parameter if you aren't interested in the reason for 2556 * failure. 2557 * 2558 * Because this connection is shared, no user of the connection 2559 * may call dbus_connection_close(). However, when you are done with the 2560 * connection you should call dbus_connection_unref(). 2561 * 2562 * @note Prefer dbus_connection_open() to dbus_connection_open_private() 2563 * unless you have good reason; connections are expensive enough 2564 * that it's wasteful to create lots of connections to the same 2565 * server. 2566 * 2567 * @param address the address. 2568 * @param error address where an error can be returned. 2569 * @returns new connection, or #NULL on failure. 2570 */ 2571DBusConnection* 2572dbus_connection_open (const char *address, 2573 DBusError *error) 2574{ 2575 DBusConnection *connection; 2576 2577 _dbus_return_val_if_fail (address != NULL, NULL); 2578 _dbus_return_val_if_error_is_set (error, NULL); 2579 2580 connection = _dbus_connection_open_internal (address, 2581 TRUE, 2582 error); 2583 2584 return connection; 2585} 2586 2587/** 2588 * Opens a new, dedicated connection to a remote address. Unlike 2589 * dbus_connection_open(), always creates a new connection. 2590 * This connection will not be saved or recycled by libdbus. 2591 * 2592 * If the open fails, the function returns #NULL, and provides a 2593 * reason for the failure in the error parameter. Pass #NULL for the 2594 * error parameter if you aren't interested in the reason for 2595 * failure. 2596 * 2597 * When you are done with this connection, you must 2598 * dbus_connection_close() to disconnect it, 2599 * and dbus_connection_unref() to free the connection object. 2600 * 2601 * (The dbus_connection_close() can be skipped if the 2602 * connection is already known to be disconnected, for example 2603 * if you are inside a handler for the Disconnected signal.) 2604 * 2605 * @note Prefer dbus_connection_open() to dbus_connection_open_private() 2606 * unless you have good reason; connections are expensive enough 2607 * that it's wasteful to create lots of connections to the same 2608 * server. 2609 * 2610 * @param address the address. 2611 * @param error address where an error can be returned. 2612 * @returns new connection, or #NULL on failure. 2613 */ 2614DBusConnection* 2615dbus_connection_open_private (const char *address, 2616 DBusError *error) 2617{ 2618 DBusConnection *connection; 2619 2620 _dbus_return_val_if_fail (address != NULL, NULL); 2621 _dbus_return_val_if_error_is_set (error, NULL); 2622 2623 connection = _dbus_connection_open_internal (address, 2624 FALSE, 2625 error); 2626 2627 return connection; 2628} 2629 2630/** 2631 * Increments the reference count of a DBusConnection. 2632 * 2633 * @param connection the connection. 2634 * @returns the connection. 2635 */ 2636DBusConnection * 2637dbus_connection_ref (DBusConnection *connection) 2638{ 2639 dbus_int32_t old_refcount; 2640 2641 _dbus_return_val_if_fail (connection != NULL, NULL); 2642 _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL); 2643 old_refcount = _dbus_atomic_inc (&connection->refcount); 2644 _dbus_connection_trace_ref (connection, old_refcount, old_refcount + 1, 2645 "ref"); 2646 2647 return connection; 2648} 2649 2650static void 2651free_outgoing_message (void *element, 2652 void *data) 2653{ 2654 DBusMessage *message = element; 2655 DBusConnection *connection = data; 2656 2657 _dbus_message_remove_counter (message, connection->outgoing_counter); 2658 dbus_message_unref (message); 2659} 2660 2661/* This is run without the mutex held, but after the last reference 2662 * to the connection has been dropped we should have no thread-related 2663 * problems 2664 */ 2665static void 2666_dbus_connection_last_unref (DBusConnection *connection) 2667{ 2668 DBusList *link; 2669 2670 _dbus_verbose ("Finalizing connection %p\n", connection); 2671 2672 _dbus_assert (_dbus_atomic_get (&connection->refcount) == 0); 2673 2674 /* You have to disconnect the connection before unref:ing it. Otherwise 2675 * you won't get the disconnected message. 2676 */ 2677 _dbus_assert (!_dbus_transport_get_is_connected (connection->transport)); 2678 _dbus_assert (connection->server_guid == NULL); 2679 2680 /* ---- We're going to call various application callbacks here, hope it doesn't break anything... */ 2681 _dbus_object_tree_free_all_unlocked (connection->objects); 2682 2683 dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL); 2684 dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL); 2685 dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL); 2686 2687 _dbus_watch_list_free (connection->watches); 2688 connection->watches = NULL; 2689 2690 _dbus_timeout_list_free (connection->timeouts); 2691 connection->timeouts = NULL; 2692 2693 _dbus_data_slot_list_free (&connection->slot_list); 2694 2695 link = _dbus_list_get_first_link (&connection->filter_list); 2696 while (link != NULL) 2697 { 2698 DBusMessageFilter *filter = link->data; 2699 DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link); 2700 2701 filter->function = NULL; 2702 _dbus_message_filter_unref (filter); /* calls app callback */ 2703 link->data = NULL; 2704 2705 link = next; 2706 } 2707 _dbus_list_clear (&connection->filter_list); 2708 2709 /* ---- Done with stuff that invokes application callbacks */ 2710 2711 _dbus_object_tree_unref (connection->objects); 2712 2713 _dbus_hash_table_unref (connection->pending_replies); 2714 connection->pending_replies = NULL; 2715 2716 _dbus_list_clear (&connection->filter_list); 2717 2718 _dbus_list_foreach (&connection->outgoing_messages, 2719 free_outgoing_message, 2720 connection); 2721 _dbus_list_clear (&connection->outgoing_messages); 2722 2723 _dbus_list_foreach (&connection->incoming_messages, 2724 (DBusForeachFunction) dbus_message_unref, 2725 NULL); 2726 _dbus_list_clear (&connection->incoming_messages); 2727 2728 _dbus_counter_unref (connection->outgoing_counter); 2729 2730 _dbus_transport_unref (connection->transport); 2731 2732 if (connection->disconnect_message_link) 2733 { 2734 DBusMessage *message = connection->disconnect_message_link->data; 2735 dbus_message_unref (message); 2736 _dbus_list_free_link (connection->disconnect_message_link); 2737 } 2738 2739 _dbus_condvar_free_at_location (&connection->dispatch_cond); 2740 _dbus_condvar_free_at_location (&connection->io_path_cond); 2741 2742 _dbus_cmutex_free_at_location (&connection->io_path_mutex); 2743 _dbus_cmutex_free_at_location (&connection->dispatch_mutex); 2744 2745 _dbus_rmutex_free_at_location (&connection->slot_mutex); 2746 2747 _dbus_rmutex_free_at_location (&connection->mutex); 2748 2749 dbus_free (connection); 2750} 2751 2752/** 2753 * Decrements the reference count of a DBusConnection, and finalizes 2754 * it if the count reaches zero. 2755 * 2756 * Note: it is a bug to drop the last reference to a connection that 2757 * is still connected. 2758 * 2759 * For shared connections, libdbus will own a reference 2760 * as long as the connection is connected, so you can know that either 2761 * you don't have the last reference, or it's OK to drop the last reference. 2762 * Most connections are shared. dbus_connection_open() and dbus_bus_get() 2763 * return shared connections. 2764 * 2765 * For private connections, the creator of the connection must arrange for 2766 * dbus_connection_close() to be called prior to dropping the last reference. 2767 * Private connections come from dbus_connection_open_private() or dbus_bus_get_private(). 2768 * 2769 * @param connection the connection. 2770 */ 2771void 2772dbus_connection_unref (DBusConnection *connection) 2773{ 2774 dbus_int32_t old_refcount; 2775 2776 _dbus_return_if_fail (connection != NULL); 2777 _dbus_return_if_fail (connection->generation == _dbus_current_generation); 2778 2779 old_refcount = _dbus_atomic_dec (&connection->refcount); 2780 2781 _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1, 2782 "unref"); 2783 2784 if (old_refcount == 1) 2785 { 2786#ifndef DBUS_DISABLE_CHECKS 2787 if (_dbus_transport_get_is_connected (connection->transport)) 2788 { 2789 _dbus_warn_check_failed ("The last reference on a connection was dropped without closing the connection. This is a bug in an application. See dbus_connection_unref() documentation for details.\n%s", 2790 connection->shareable ? 2791 "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" : 2792 "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n"); 2793 return; 2794 } 2795#endif 2796 _dbus_connection_last_unref (connection); 2797 } 2798} 2799 2800/* 2801 * Note that the transport can disconnect itself (other end drops us) 2802 * and in that case this function never runs. So this function must 2803 * not do anything more than disconnect the transport and update the 2804 * dispatch status. 2805 * 2806 * If the transport self-disconnects, then we assume someone will 2807 * dispatch the connection to cause the dispatch status update. 2808 */ 2809static void 2810_dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection) 2811{ 2812 DBusDispatchStatus status; 2813 2814 HAVE_LOCK_CHECK (connection); 2815 2816 _dbus_verbose ("Disconnecting %p\n", connection); 2817 2818 /* We need to ref because update_dispatch_status_and_unlock will unref 2819 * the connection if it was shared and libdbus was the only remaining 2820 * refcount holder. 2821 */ 2822 _dbus_connection_ref_unlocked (connection); 2823 2824 _dbus_transport_disconnect (connection->transport); 2825 2826 /* This has the side effect of queuing the disconnect message link 2827 * (unless we don't have enough memory, possibly, so don't assert it). 2828 * After the disconnect message link is queued, dbus_bus_get/dbus_connection_open 2829 * should never again return the newly-disconnected connection. 2830 * 2831 * However, we only unref the shared connection and exit_on_disconnect when 2832 * the disconnect message reaches the head of the message queue, 2833 * NOT when it's first queued. 2834 */ 2835 status = _dbus_connection_get_dispatch_status_unlocked (connection); 2836 2837 /* This calls out to user code */ 2838 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 2839 2840 /* Could also call out to user code */ 2841 dbus_connection_unref (connection); 2842} 2843 2844/** 2845 * Closes a private connection, so no further data can be sent or received. 2846 * This disconnects the transport (such as a socket) underlying the 2847 * connection. 2848 * 2849 * Attempts to send messages after closing a connection are safe, but will result in 2850 * error replies generated locally in libdbus. 2851 * 2852 * This function does not affect the connection's reference count. It's 2853 * safe to close a connection more than once; all calls after the 2854 * first do nothing. It's impossible to "reopen" a connection, a 2855 * new connection must be created. This function may result in a call 2856 * to the DBusDispatchStatusFunction set with 2857 * dbus_connection_set_dispatch_status_function(), as the disconnect 2858 * message it generates needs to be dispatched. 2859 * 2860 * If a connection is dropped by the remote application, it will 2861 * close itself. 2862 * 2863 * You must close a connection prior to releasing the last reference to 2864 * the connection. If you dbus_connection_unref() for the last time 2865 * without closing the connection, the results are undefined; it 2866 * is a bug in your program and libdbus will try to print a warning. 2867 * 2868 * You may not close a shared connection. Connections created with 2869 * dbus_connection_open() or dbus_bus_get() are shared. 2870 * These connections are owned by libdbus, and applications should 2871 * only unref them, never close them. Applications can know it is 2872 * safe to unref these connections because libdbus will be holding a 2873 * reference as long as the connection is open. Thus, either the 2874 * connection is closed and it is OK to drop the last reference, 2875 * or the connection is open and the app knows it does not have the 2876 * last reference. 2877 * 2878 * Connections created with dbus_connection_open_private() or 2879 * dbus_bus_get_private() are not kept track of or referenced by 2880 * libdbus. The creator of these connections is responsible for 2881 * calling dbus_connection_close() prior to releasing the last 2882 * reference, if the connection is not already disconnected. 2883 * 2884 * @param connection the private (unshared) connection to close 2885 */ 2886void 2887dbus_connection_close (DBusConnection *connection) 2888{ 2889 _dbus_return_if_fail (connection != NULL); 2890 _dbus_return_if_fail (connection->generation == _dbus_current_generation); 2891 2892 CONNECTION_LOCK (connection); 2893 2894#ifndef DBUS_DISABLE_CHECKS 2895 if (connection->shareable) 2896 { 2897 CONNECTION_UNLOCK (connection); 2898 2899 _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n"); 2900 return; 2901 } 2902#endif 2903 2904 _dbus_connection_close_possibly_shared_and_unlock (connection); 2905} 2906 2907static dbus_bool_t 2908_dbus_connection_get_is_connected_unlocked (DBusConnection *connection) 2909{ 2910 HAVE_LOCK_CHECK (connection); 2911 return _dbus_transport_get_is_connected (connection->transport); 2912} 2913 2914/** 2915 * Gets whether the connection is currently open. A connection may 2916 * become disconnected when the remote application closes its end, or 2917 * exits; a connection may also be disconnected with 2918 * dbus_connection_close(). 2919 * 2920 * There are not separate states for "closed" and "disconnected," the two 2921 * terms are synonymous. This function should really be called 2922 * get_is_open() but for historical reasons is not. 2923 * 2924 * @param connection the connection. 2925 * @returns #TRUE if the connection is still alive. 2926 */ 2927dbus_bool_t 2928dbus_connection_get_is_connected (DBusConnection *connection) 2929{ 2930 dbus_bool_t res; 2931 2932 _dbus_return_val_if_fail (connection != NULL, FALSE); 2933 2934 CONNECTION_LOCK (connection); 2935 res = _dbus_connection_get_is_connected_unlocked (connection); 2936 CONNECTION_UNLOCK (connection); 2937 2938 return res; 2939} 2940 2941/** 2942 * Gets whether the connection was authenticated. (Note that 2943 * if the connection was authenticated then disconnected, 2944 * this function still returns #TRUE) 2945 * 2946 * @param connection the connection 2947 * @returns #TRUE if the connection was ever authenticated 2948 */ 2949dbus_bool_t 2950dbus_connection_get_is_authenticated (DBusConnection *connection) 2951{ 2952 dbus_bool_t res; 2953 2954 _dbus_return_val_if_fail (connection != NULL, FALSE); 2955 2956 CONNECTION_LOCK (connection); 2957 res = _dbus_transport_get_is_authenticated (connection->transport); 2958 CONNECTION_UNLOCK (connection); 2959 2960 return res; 2961} 2962 2963/** 2964 * Gets whether the connection is not authenticated as a specific 2965 * user. If the connection is not authenticated, this function 2966 * returns #TRUE, and if it is authenticated but as an anonymous user, 2967 * it returns #TRUE. If it is authenticated as a specific user, then 2968 * this returns #FALSE. (Note that if the connection was authenticated 2969 * as anonymous then disconnected, this function still returns #TRUE.) 2970 * 2971 * If the connection is not anonymous, you can use 2972 * dbus_connection_get_unix_user() and 2973 * dbus_connection_get_windows_user() to see who it's authorized as. 2974 * 2975 * If you want to prevent non-anonymous authorization, use 2976 * dbus_server_set_auth_mechanisms() to remove the mechanisms that 2977 * allow proving user identity (i.e. only allow the ANONYMOUS 2978 * mechanism). 2979 * 2980 * @param connection the connection 2981 * @returns #TRUE if not authenticated or authenticated as anonymous 2982 */ 2983dbus_bool_t 2984dbus_connection_get_is_anonymous (DBusConnection *connection) 2985{ 2986 dbus_bool_t res; 2987 2988 _dbus_return_val_if_fail (connection != NULL, FALSE); 2989 2990 CONNECTION_LOCK (connection); 2991 res = _dbus_transport_get_is_anonymous (connection->transport); 2992 CONNECTION_UNLOCK (connection); 2993 2994 return res; 2995} 2996 2997/** 2998 * Gets the ID of the server address we are authenticated to, if this 2999 * connection is on the client side. If the connection is on the 3000 * server side, this will always return #NULL - use dbus_server_get_id() 3001 * to get the ID of your own server, if you are the server side. 3002 * 3003 * If a client-side connection is not authenticated yet, the ID may be 3004 * available if it was included in the server address, but may not be 3005 * available. The only way to be sure the server ID is available 3006 * is to wait for authentication to complete. 3007 * 3008 * In general, each mode of connecting to a given server will have 3009 * its own ID. So for example, if the session bus daemon is listening 3010 * on UNIX domain sockets and on TCP, then each of those modalities 3011 * will have its own server ID. 3012 * 3013 * If you want an ID that identifies an entire session bus, look at 3014 * dbus_bus_get_id() instead (which is just a convenience wrapper 3015 * around the org.freedesktop.DBus.GetId method invoked on the bus). 3016 * 3017 * You can also get a machine ID; see dbus_get_local_machine_id() to 3018 * get the machine you are on. There isn't a convenience wrapper, but 3019 * you can invoke org.freedesktop.DBus.Peer.GetMachineId on any peer 3020 * to get the machine ID on the other end. 3021 * 3022 * The D-Bus specification describes the server ID and other IDs in a 3023 * bit more detail. 3024 * 3025 * @param connection the connection 3026 * @returns the server ID or #NULL if no memory or the connection is server-side 3027 */ 3028char* 3029dbus_connection_get_server_id (DBusConnection *connection) 3030{ 3031 char *id; 3032 3033 _dbus_return_val_if_fail (connection != NULL, NULL); 3034 3035 CONNECTION_LOCK (connection); 3036 id = _dbus_strdup (_dbus_transport_get_server_id (connection->transport)); 3037 CONNECTION_UNLOCK (connection); 3038 3039 return id; 3040} 3041 3042/** 3043 * Tests whether a certain type can be send via the connection. This 3044 * will always return TRUE for all types, with the exception of 3045 * DBUS_TYPE_UNIX_FD. The function will return TRUE for 3046 * DBUS_TYPE_UNIX_FD only on systems that know Unix file descriptors 3047 * and can send them via the chosen transport and when the remote side 3048 * supports this. 3049 * 3050 * This function can be used to do runtime checking for types that 3051 * might be unknown to the specific D-Bus client implementation 3052 * version, i.e. it will return FALSE for all types this 3053 * implementation does not know, including invalid or reserved types. 3054 * 3055 * @param connection the connection 3056 * @param type the type to check 3057 * @returns TRUE if the type may be send via the connection 3058 */ 3059dbus_bool_t 3060dbus_connection_can_send_type(DBusConnection *connection, 3061 int type) 3062{ 3063 _dbus_return_val_if_fail (connection != NULL, FALSE); 3064 3065 if (!dbus_type_is_valid (type)) 3066 return FALSE; 3067 3068 if (type != DBUS_TYPE_UNIX_FD) 3069 return TRUE; 3070 3071#ifdef HAVE_UNIX_FD_PASSING 3072 { 3073 dbus_bool_t b; 3074 3075 CONNECTION_LOCK(connection); 3076 b = _dbus_transport_can_pass_unix_fd(connection->transport); 3077 CONNECTION_UNLOCK(connection); 3078 3079 return b; 3080 } 3081#endif 3082 3083 return FALSE; 3084} 3085 3086/** 3087 * Set whether _exit() should be called when the connection receives a 3088 * disconnect signal. The call to _exit() comes after any handlers for 3089 * the disconnect signal run; handlers can cancel the exit by calling 3090 * this function. 3091 * 3092 * By default, exit_on_disconnect is #FALSE; but for message bus 3093 * connections returned from dbus_bus_get() it will be toggled on 3094 * by default. 3095 * 3096 * @param connection the connection 3097 * @param exit_on_disconnect #TRUE if _exit() should be called after a disconnect signal 3098 */ 3099void 3100dbus_connection_set_exit_on_disconnect (DBusConnection *connection, 3101 dbus_bool_t exit_on_disconnect) 3102{ 3103 _dbus_return_if_fail (connection != NULL); 3104 3105 CONNECTION_LOCK (connection); 3106 connection->exit_on_disconnect = exit_on_disconnect != FALSE; 3107 CONNECTION_UNLOCK (connection); 3108} 3109 3110/** 3111 * Preallocates resources needed to send a message, allowing the message 3112 * to be sent without the possibility of memory allocation failure. 3113 * Allows apps to create a future guarantee that they can send 3114 * a message regardless of memory shortages. 3115 * 3116 * @param connection the connection we're preallocating for. 3117 * @returns the preallocated resources, or #NULL 3118 */ 3119DBusPreallocatedSend* 3120dbus_connection_preallocate_send (DBusConnection *connection) 3121{ 3122 DBusPreallocatedSend *preallocated; 3123 3124 _dbus_return_val_if_fail (connection != NULL, NULL); 3125 3126 CONNECTION_LOCK (connection); 3127 3128 preallocated = 3129 _dbus_connection_preallocate_send_unlocked (connection); 3130 3131 CONNECTION_UNLOCK (connection); 3132 3133 return preallocated; 3134} 3135 3136/** 3137 * Frees preallocated message-sending resources from 3138 * dbus_connection_preallocate_send(). Should only 3139 * be called if the preallocated resources are not used 3140 * to send a message. 3141 * 3142 * @param connection the connection 3143 * @param preallocated the resources 3144 */ 3145void 3146dbus_connection_free_preallocated_send (DBusConnection *connection, 3147 DBusPreallocatedSend *preallocated) 3148{ 3149 _dbus_return_if_fail (connection != NULL); 3150 _dbus_return_if_fail (preallocated != NULL); 3151 _dbus_return_if_fail (connection == preallocated->connection); 3152 3153 _dbus_list_free_link (preallocated->queue_link); 3154 _dbus_counter_unref (preallocated->counter_link->data); 3155 _dbus_list_free_link (preallocated->counter_link); 3156 dbus_free (preallocated); 3157} 3158 3159/** 3160 * Sends a message using preallocated resources. This function cannot fail. 3161 * It works identically to dbus_connection_send() in other respects. 3162 * Preallocated resources comes from dbus_connection_preallocate_send(). 3163 * This function "consumes" the preallocated resources, they need not 3164 * be freed separately. 3165 * 3166 * @param connection the connection 3167 * @param preallocated the preallocated resources 3168 * @param message the message to send 3169 * @param client_serial return location for client serial assigned to the message 3170 */ 3171void 3172dbus_connection_send_preallocated (DBusConnection *connection, 3173 DBusPreallocatedSend *preallocated, 3174 DBusMessage *message, 3175 dbus_uint32_t *client_serial) 3176{ 3177 _dbus_return_if_fail (connection != NULL); 3178 _dbus_return_if_fail (preallocated != NULL); 3179 _dbus_return_if_fail (message != NULL); 3180 _dbus_return_if_fail (preallocated->connection == connection); 3181 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL || 3182 dbus_message_get_member (message) != NULL); 3183 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL || 3184 (dbus_message_get_interface (message) != NULL && 3185 dbus_message_get_member (message) != NULL)); 3186 3187 CONNECTION_LOCK (connection); 3188 3189#ifdef HAVE_UNIX_FD_PASSING 3190 3191 if (!_dbus_transport_can_pass_unix_fd(connection->transport) && 3192 message->n_unix_fds > 0) 3193 { 3194 /* Refuse to send fds on a connection that cannot handle 3195 them. Unfortunately we cannot return a proper error here, so 3196 the best we can is just return. */ 3197 CONNECTION_UNLOCK (connection); 3198 return; 3199 } 3200 3201#endif 3202 3203 _dbus_connection_send_preallocated_and_unlock (connection, 3204 preallocated, 3205 message, client_serial); 3206} 3207 3208static dbus_bool_t 3209_dbus_connection_send_unlocked_no_update (DBusConnection *connection, 3210 DBusMessage *message, 3211 dbus_uint32_t *client_serial) 3212{ 3213 DBusPreallocatedSend *preallocated; 3214 3215 _dbus_assert (connection != NULL); 3216 _dbus_assert (message != NULL); 3217 3218 preallocated = _dbus_connection_preallocate_send_unlocked (connection); 3219 if (preallocated == NULL) 3220 return FALSE; 3221 3222 _dbus_connection_send_preallocated_unlocked_no_update (connection, 3223 preallocated, 3224 message, 3225 client_serial); 3226 return TRUE; 3227} 3228 3229/** 3230 * Adds a message to the outgoing message queue. Does not block to 3231 * write the message to the network; that happens asynchronously. To 3232 * force the message to be written, call dbus_connection_flush() however 3233 * it is not necessary to call dbus_connection_flush() by hand; the 3234 * message will be sent the next time the main loop is run. 3235 * dbus_connection_flush() should only be used, for example, if 3236 * the application was expected to exit before running the main loop. 3237 * 3238 * Because this only queues the message, the only reason it can 3239 * fail is lack of memory. Even if the connection is disconnected, 3240 * no error will be returned. If the function fails due to lack of memory, 3241 * it returns #FALSE. The function will never fail for other reasons; even 3242 * if the connection is disconnected, you can queue an outgoing message, 3243 * though obviously it won't be sent. 3244 * 3245 * The message serial is used by the remote application to send a 3246 * reply; see dbus_message_get_serial() or the D-Bus specification. 3247 * 3248 * dbus_message_unref() can be called as soon as this method returns 3249 * as the message queue will hold its own ref until the message is sent. 3250 * 3251 * @param connection the connection. 3252 * @param message the message to write. 3253 * @param serial return location for message serial, or #NULL if you don't care 3254 * @returns #TRUE on success. 3255 */ 3256dbus_bool_t 3257dbus_connection_send (DBusConnection *connection, 3258 DBusMessage *message, 3259 dbus_uint32_t *serial) 3260{ 3261 _dbus_return_val_if_fail (connection != NULL, FALSE); 3262 _dbus_return_val_if_fail (message != NULL, FALSE); 3263 3264 CONNECTION_LOCK (connection); 3265 3266#ifdef HAVE_UNIX_FD_PASSING 3267 3268 if (!_dbus_transport_can_pass_unix_fd(connection->transport) && 3269 message->n_unix_fds > 0) 3270 { 3271 /* Refuse to send fds on a connection that cannot handle 3272 them. Unfortunately we cannot return a proper error here, so 3273 the best we can is just return. */ 3274 CONNECTION_UNLOCK (connection); 3275 return FALSE; 3276 } 3277 3278#endif 3279 3280 return _dbus_connection_send_and_unlock (connection, 3281 message, 3282 serial); 3283} 3284 3285static dbus_bool_t 3286reply_handler_timeout (void *data) 3287{ 3288 DBusConnection *connection; 3289 DBusDispatchStatus status; 3290 DBusPendingCall *pending = data; 3291 3292 connection = _dbus_pending_call_get_connection_and_lock (pending); 3293 _dbus_connection_ref_unlocked (connection); 3294 3295 _dbus_pending_call_queue_timeout_error_unlocked (pending, 3296 connection); 3297 _dbus_connection_remove_timeout_unlocked (connection, 3298 _dbus_pending_call_get_timeout_unlocked (pending)); 3299 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE); 3300 3301 _dbus_verbose ("middle\n"); 3302 status = _dbus_connection_get_dispatch_status_unlocked (connection); 3303 3304 /* Unlocks, and calls out to user code */ 3305 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 3306 dbus_connection_unref (connection); 3307 3308 return TRUE; 3309} 3310 3311/** 3312 * Queues a message to send, as with dbus_connection_send(), 3313 * but also returns a #DBusPendingCall used to receive a reply to the 3314 * message. If no reply is received in the given timeout_milliseconds, 3315 * this function expires the pending reply and generates a synthetic 3316 * error reply (generated in-process, not by the remote application) 3317 * indicating that a timeout occurred. 3318 * 3319 * A #DBusPendingCall will see a reply message before any filters or 3320 * registered object path handlers. See dbus_connection_dispatch() for 3321 * details on when handlers are run. 3322 * 3323 * A #DBusPendingCall will always see exactly one reply message, 3324 * unless it's cancelled with dbus_pending_call_cancel(). 3325 * 3326 * If #NULL is passed for the pending_return, the #DBusPendingCall 3327 * will still be generated internally, and used to track 3328 * the message reply timeout. This means a timeout error will 3329 * occur if no reply arrives, unlike with dbus_connection_send(). 3330 * 3331 * If -1 is passed for the timeout, a sane default timeout is used. -1 3332 * is typically the best value for the timeout for this reason, unless 3333 * you want a very short or very long timeout. If #DBUS_TIMEOUT_INFINITE is 3334 * passed for the timeout, no timeout will be set and the call will block 3335 * forever. 3336 * 3337 * @warning if the connection is disconnected or you try to send Unix 3338 * file descriptors on a connection that does not support them, the 3339 * #DBusPendingCall will be set to #NULL, so be careful with this. 3340 * 3341 * @param connection the connection 3342 * @param message the message to send 3343 * @param pending_return return location for a #DBusPendingCall 3344 * object, or #NULL if connection is disconnected or when you try to 3345 * send Unix file descriptors on a connection that does not support 3346 * them. 3347 * @param timeout_milliseconds timeout in milliseconds, -1 (or 3348 * #DBUS_TIMEOUT_USE_DEFAULT) for default or #DBUS_TIMEOUT_INFINITE for no 3349 * timeout 3350 * @returns #FALSE if no memory, #TRUE otherwise. 3351 * 3352 */ 3353dbus_bool_t 3354dbus_connection_send_with_reply (DBusConnection *connection, 3355 DBusMessage *message, 3356 DBusPendingCall **pending_return, 3357 int timeout_milliseconds) 3358{ 3359 DBusPendingCall *pending; 3360 dbus_int32_t serial = -1; 3361 DBusDispatchStatus status; 3362 3363 _dbus_return_val_if_fail (connection != NULL, FALSE); 3364 _dbus_return_val_if_fail (message != NULL, FALSE); 3365 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE); 3366 3367 if (pending_return) 3368 *pending_return = NULL; 3369 3370 CONNECTION_LOCK (connection); 3371 3372#ifdef HAVE_UNIX_FD_PASSING 3373 3374 if (!_dbus_transport_can_pass_unix_fd(connection->transport) && 3375 message->n_unix_fds > 0) 3376 { 3377 /* Refuse to send fds on a connection that cannot handle 3378 them. Unfortunately we cannot return a proper error here, so 3379 the best we can do is return TRUE but leave *pending_return 3380 as NULL. */ 3381 CONNECTION_UNLOCK (connection); 3382 return TRUE; 3383 } 3384 3385#endif 3386 3387 if (!_dbus_connection_get_is_connected_unlocked (connection)) 3388 { 3389 CONNECTION_UNLOCK (connection); 3390 3391 return TRUE; 3392 } 3393 3394 pending = _dbus_pending_call_new_unlocked (connection, 3395 timeout_milliseconds, 3396 reply_handler_timeout); 3397 3398 if (pending == NULL) 3399 { 3400 CONNECTION_UNLOCK (connection); 3401 return FALSE; 3402 } 3403 3404 /* Assign a serial to the message */ 3405 serial = dbus_message_get_serial (message); 3406 if (serial == 0) 3407 { 3408 serial = _dbus_connection_get_next_client_serial (connection); 3409 dbus_message_set_serial (message, serial); 3410 } 3411 3412 if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial)) 3413 goto error; 3414 3415 /* Insert the serial in the pending replies hash; 3416 * hash takes a refcount on DBusPendingCall. 3417 * Also, add the timeout. 3418 */ 3419 if (!_dbus_connection_attach_pending_call_unlocked (connection, 3420 pending)) 3421 goto error; 3422 3423 if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL)) 3424 { 3425 _dbus_connection_detach_pending_call_and_unlock (connection, 3426 pending); 3427 goto error_unlocked; 3428 } 3429 3430 if (pending_return) 3431 *pending_return = pending; /* hand off refcount */ 3432 else 3433 { 3434 _dbus_connection_detach_pending_call_unlocked (connection, pending); 3435 /* we still have a ref to the pending call in this case, we unref 3436 * after unlocking, below 3437 */ 3438 } 3439 3440 status = _dbus_connection_get_dispatch_status_unlocked (connection); 3441 3442 /* this calls out to user code */ 3443 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 3444 3445 if (pending_return == NULL) 3446 dbus_pending_call_unref (pending); 3447 3448 return TRUE; 3449 3450 error: 3451 CONNECTION_UNLOCK (connection); 3452 error_unlocked: 3453 dbus_pending_call_unref (pending); 3454 return FALSE; 3455} 3456 3457/** 3458 * Sends a message and blocks a certain time period while waiting for 3459 * a reply. This function does not reenter the main loop, 3460 * i.e. messages other than the reply are queued up but not 3461 * processed. This function is used to invoke method calls on a 3462 * remote object. 3463 * 3464 * If a normal reply is received, it is returned, and removed from the 3465 * incoming message queue. If it is not received, #NULL is returned 3466 * and the error is set to #DBUS_ERROR_NO_REPLY. If an error reply is 3467 * received, it is converted to a #DBusError and returned as an error, 3468 * then the reply message is deleted and #NULL is returned. If 3469 * something else goes wrong, result is set to whatever is 3470 * appropriate, such as #DBUS_ERROR_NO_MEMORY or 3471 * #DBUS_ERROR_DISCONNECTED. 3472 * 3473 * @warning While this function blocks the calling thread will not be 3474 * processing the incoming message queue. This means you can end up 3475 * deadlocked if the application you're talking to needs you to reply 3476 * to a method. To solve this, either avoid the situation, block in a 3477 * separate thread from the main connection-dispatching thread, or use 3478 * dbus_pending_call_set_notify() to avoid blocking. 3479 * 3480 * @param connection the connection 3481 * @param message the message to send 3482 * @param timeout_milliseconds timeout in milliseconds, -1 (or 3483 * #DBUS_TIMEOUT_USE_DEFAULT) for default or #DBUS_TIMEOUT_INFINITE for no 3484 * timeout 3485 * @param error return location for error message 3486 * @returns the message that is the reply or #NULL with an error code if the 3487 * function fails. 3488 */ 3489DBusMessage* 3490dbus_connection_send_with_reply_and_block (DBusConnection *connection, 3491 DBusMessage *message, 3492 int timeout_milliseconds, 3493 DBusError *error) 3494{ 3495 DBusMessage *reply; 3496 DBusPendingCall *pending; 3497 3498 _dbus_return_val_if_fail (connection != NULL, NULL); 3499 _dbus_return_val_if_fail (message != NULL, NULL); 3500 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL); 3501 _dbus_return_val_if_error_is_set (error, NULL); 3502 3503#ifdef HAVE_UNIX_FD_PASSING 3504 3505 CONNECTION_LOCK (connection); 3506 if (!_dbus_transport_can_pass_unix_fd(connection->transport) && 3507 message->n_unix_fds > 0) 3508 { 3509 CONNECTION_UNLOCK (connection); 3510 dbus_set_error(error, DBUS_ERROR_FAILED, "Cannot send file descriptors on this connection."); 3511 return NULL; 3512 } 3513 CONNECTION_UNLOCK (connection); 3514 3515#endif 3516 3517 if (!dbus_connection_send_with_reply (connection, message, 3518 &pending, timeout_milliseconds)) 3519 { 3520 _DBUS_SET_OOM (error); 3521 return NULL; 3522 } 3523 3524 if (pending == NULL) 3525 { 3526 dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Connection is closed"); 3527 return NULL; 3528 } 3529 3530 dbus_pending_call_block (pending); 3531 3532 reply = dbus_pending_call_steal_reply (pending); 3533 dbus_pending_call_unref (pending); 3534 3535 /* call_complete_and_unlock() called from pending_call_block() should 3536 * always fill this in. 3537 */ 3538 _dbus_assert (reply != NULL); 3539 3540 if (dbus_set_error_from_message (error, reply)) 3541 { 3542 dbus_message_unref (reply); 3543 return NULL; 3544 } 3545 else 3546 return reply; 3547} 3548 3549/** 3550 * Blocks until the outgoing message queue is empty. 3551 * Assumes connection lock already held. 3552 * 3553 * If you call this, you MUST call update_dispatch_status afterword... 3554 * 3555 * @param connection the connection. 3556 */ 3557static DBusDispatchStatus 3558_dbus_connection_flush_unlocked (DBusConnection *connection) 3559{ 3560 /* We have to specify DBUS_ITERATION_DO_READING here because 3561 * otherwise we could have two apps deadlock if they are both doing 3562 * a flush(), and the kernel buffers fill up. This could change the 3563 * dispatch status. 3564 */ 3565 DBusDispatchStatus status; 3566 3567 HAVE_LOCK_CHECK (connection); 3568 3569 while (connection->n_outgoing > 0 && 3570 _dbus_connection_get_is_connected_unlocked (connection)) 3571 { 3572 _dbus_verbose ("doing iteration in\n"); 3573 HAVE_LOCK_CHECK (connection); 3574 _dbus_connection_do_iteration_unlocked (connection, 3575 NULL, 3576 DBUS_ITERATION_DO_READING | 3577 DBUS_ITERATION_DO_WRITING | 3578 DBUS_ITERATION_BLOCK, 3579 -1); 3580 } 3581 3582 HAVE_LOCK_CHECK (connection); 3583 _dbus_verbose ("middle\n"); 3584 status = _dbus_connection_get_dispatch_status_unlocked (connection); 3585 3586 HAVE_LOCK_CHECK (connection); 3587 return status; 3588} 3589 3590/** 3591 * Blocks until the outgoing message queue is empty. 3592 * 3593 * @param connection the connection. 3594 */ 3595void 3596dbus_connection_flush (DBusConnection *connection) 3597{ 3598 /* We have to specify DBUS_ITERATION_DO_READING here because 3599 * otherwise we could have two apps deadlock if they are both doing 3600 * a flush(), and the kernel buffers fill up. This could change the 3601 * dispatch status. 3602 */ 3603 DBusDispatchStatus status; 3604 3605 _dbus_return_if_fail (connection != NULL); 3606 3607 CONNECTION_LOCK (connection); 3608 3609 status = _dbus_connection_flush_unlocked (connection); 3610 3611 HAVE_LOCK_CHECK (connection); 3612 /* Unlocks and calls out to user code */ 3613 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 3614 3615 _dbus_verbose ("end\n"); 3616} 3617 3618/** 3619 * This function implements dbus_connection_read_write_dispatch() and 3620 * dbus_connection_read_write() (they pass a different value for the 3621 * dispatch parameter). 3622 * 3623 * @param connection the connection 3624 * @param timeout_milliseconds max time to block or -1 for infinite 3625 * @param dispatch dispatch new messages or leave them on the incoming queue 3626 * @returns #TRUE if the disconnect message has not been processed 3627 */ 3628static dbus_bool_t 3629_dbus_connection_read_write_dispatch (DBusConnection *connection, 3630 int timeout_milliseconds, 3631 dbus_bool_t dispatch) 3632{ 3633 DBusDispatchStatus dstatus; 3634 dbus_bool_t progress_possible; 3635 3636 /* Need to grab a ref here in case we're a private connection and 3637 * the user drops the last ref in a handler we call; see bug 3638 * https://bugs.freedesktop.org/show_bug.cgi?id=15635 3639 */ 3640 dbus_connection_ref (connection); 3641 dstatus = dbus_connection_get_dispatch_status (connection); 3642 3643 if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS) 3644 { 3645 _dbus_verbose ("doing dispatch\n"); 3646 dbus_connection_dispatch (connection); 3647 CONNECTION_LOCK (connection); 3648 } 3649 else if (dstatus == DBUS_DISPATCH_NEED_MEMORY) 3650 { 3651 _dbus_verbose ("pausing for memory\n"); 3652 _dbus_memory_pause_based_on_timeout (timeout_milliseconds); 3653 CONNECTION_LOCK (connection); 3654 } 3655 else 3656 { 3657 CONNECTION_LOCK (connection); 3658 if (_dbus_connection_get_is_connected_unlocked (connection)) 3659 { 3660 _dbus_verbose ("doing iteration\n"); 3661 _dbus_connection_do_iteration_unlocked (connection, 3662 NULL, 3663 DBUS_ITERATION_DO_READING | 3664 DBUS_ITERATION_DO_WRITING | 3665 DBUS_ITERATION_BLOCK, 3666 timeout_milliseconds); 3667 } 3668 } 3669 3670 HAVE_LOCK_CHECK (connection); 3671 /* If we can dispatch, we can make progress until the Disconnected message 3672 * has been processed; if we can only read/write, we can make progress 3673 * as long as the transport is open. 3674 */ 3675 if (dispatch) 3676 progress_possible = connection->n_incoming != 0 || 3677 connection->disconnect_message_link != NULL; 3678 else 3679 progress_possible = _dbus_connection_get_is_connected_unlocked (connection); 3680 3681 CONNECTION_UNLOCK (connection); 3682 3683 dbus_connection_unref (connection); 3684 3685 return progress_possible; /* TRUE if we can make more progress */ 3686} 3687 3688 3689/** 3690 * This function is intended for use with applications that don't want 3691 * to write a main loop and deal with #DBusWatch and #DBusTimeout. An 3692 * example usage would be: 3693 * 3694 * @code 3695 * while (dbus_connection_read_write_dispatch (connection, -1)) 3696 * ; // empty loop body 3697 * @endcode 3698 * 3699 * In this usage you would normally have set up a filter function to look 3700 * at each message as it is dispatched. The loop terminates when the last 3701 * message from the connection (the disconnected signal) is processed. 3702 * 3703 * If there are messages to dispatch, this function will 3704 * dbus_connection_dispatch() once, and return. If there are no 3705 * messages to dispatch, this function will block until it can read or 3706 * write, then read or write, then return. 3707 * 3708 * The way to think of this function is that it either makes some sort 3709 * of progress, or it blocks. Note that, while it is blocked on I/O, it 3710 * cannot be interrupted (even by other threads), which makes this function 3711 * unsuitable for applications that do more than just react to received 3712 * messages. 3713 * 3714 * The return value indicates whether the disconnect message has been 3715 * processed, NOT whether the connection is connected. This is 3716 * important because even after disconnecting, you want to process any 3717 * messages you received prior to the disconnect. 3718 * 3719 * @param connection the connection 3720 * @param timeout_milliseconds max time to block or -1 for infinite 3721 * @returns #TRUE if the disconnect message has not been processed 3722 */ 3723dbus_bool_t 3724dbus_connection_read_write_dispatch (DBusConnection *connection, 3725 int timeout_milliseconds) 3726{ 3727 _dbus_return_val_if_fail (connection != NULL, FALSE); 3728 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE); 3729 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE); 3730} 3731 3732/** 3733 * This function is intended for use with applications that don't want to 3734 * write a main loop and deal with #DBusWatch and #DBusTimeout. See also 3735 * dbus_connection_read_write_dispatch(). 3736 * 3737 * As long as the connection is open, this function will block until it can 3738 * read or write, then read or write, then return #TRUE. 3739 * 3740 * If the connection is closed, the function returns #FALSE. 3741 * 3742 * The return value indicates whether reading or writing is still 3743 * possible, i.e. whether the connection is connected. 3744 * 3745 * Note that even after disconnection, messages may remain in the 3746 * incoming queue that need to be 3747 * processed. dbus_connection_read_write_dispatch() dispatches 3748 * incoming messages for you; with dbus_connection_read_write() you 3749 * have to arrange to drain the incoming queue yourself. 3750 * 3751 * @param connection the connection 3752 * @param timeout_milliseconds max time to block or -1 for infinite 3753 * @returns #TRUE if still connected 3754 */ 3755dbus_bool_t 3756dbus_connection_read_write (DBusConnection *connection, 3757 int timeout_milliseconds) 3758{ 3759 _dbus_return_val_if_fail (connection != NULL, FALSE); 3760 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE); 3761 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE); 3762} 3763 3764/* We need to call this anytime we pop the head of the queue, and then 3765 * update_dispatch_status_and_unlock needs to be called afterward 3766 * which will "process" the disconnected message and set 3767 * disconnected_message_processed. 3768 */ 3769static void 3770check_disconnected_message_arrived_unlocked (DBusConnection *connection, 3771 DBusMessage *head_of_queue) 3772{ 3773 HAVE_LOCK_CHECK (connection); 3774 3775 /* checking that the link is NULL is an optimization to avoid the is_signal call */ 3776 if (connection->disconnect_message_link == NULL && 3777 dbus_message_is_signal (head_of_queue, 3778 DBUS_INTERFACE_LOCAL, 3779 "Disconnected")) 3780 { 3781 connection->disconnected_message_arrived = TRUE; 3782 } 3783} 3784 3785/** 3786 * Returns the first-received message from the incoming message queue, 3787 * leaving it in the queue. If the queue is empty, returns #NULL. 3788 * 3789 * The caller does not own a reference to the returned message, and 3790 * must either return it using dbus_connection_return_message() or 3791 * keep it after calling dbus_connection_steal_borrowed_message(). No 3792 * one can get at the message while its borrowed, so return it as 3793 * quickly as possible and don't keep a reference to it after 3794 * returning it. If you need to keep the message, make a copy of it. 3795 * 3796 * dbus_connection_dispatch() will block if called while a borrowed 3797 * message is outstanding; only one piece of code can be playing with 3798 * the incoming queue at a time. This function will block if called 3799 * during a dbus_connection_dispatch(). 3800 * 3801 * @param connection the connection. 3802 * @returns next message in the incoming queue. 3803 */ 3804DBusMessage* 3805dbus_connection_borrow_message (DBusConnection *connection) 3806{ 3807 DBusDispatchStatus status; 3808 DBusMessage *message; 3809 3810 _dbus_return_val_if_fail (connection != NULL, NULL); 3811 3812 _dbus_verbose ("start\n"); 3813 3814 /* this is called for the side effect that it queues 3815 * up any messages from the transport 3816 */ 3817 status = dbus_connection_get_dispatch_status (connection); 3818 if (status != DBUS_DISPATCH_DATA_REMAINS) 3819 return NULL; 3820 3821 CONNECTION_LOCK (connection); 3822 3823 _dbus_connection_acquire_dispatch (connection); 3824 3825 /* While a message is outstanding, the dispatch lock is held */ 3826 _dbus_assert (connection->message_borrowed == NULL); 3827 3828 connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages); 3829 3830 message = connection->message_borrowed; 3831 3832 check_disconnected_message_arrived_unlocked (connection, message); 3833 3834 /* Note that we KEEP the dispatch lock until the message is returned */ 3835 if (message == NULL) 3836 _dbus_connection_release_dispatch (connection); 3837 3838 CONNECTION_UNLOCK (connection); 3839 3840 _dbus_message_trace_ref (message, -1, -1, "dbus_connection_borrow_message"); 3841 3842 /* We don't update dispatch status until it's returned or stolen */ 3843 3844 return message; 3845} 3846 3847/** 3848 * Used to return a message after peeking at it using 3849 * dbus_connection_borrow_message(). Only called if 3850 * message from dbus_connection_borrow_message() was non-#NULL. 3851 * 3852 * @param connection the connection 3853 * @param message the message from dbus_connection_borrow_message() 3854 */ 3855void 3856dbus_connection_return_message (DBusConnection *connection, 3857 DBusMessage *message) 3858{ 3859 DBusDispatchStatus status; 3860 3861 _dbus_return_if_fail (connection != NULL); 3862 _dbus_return_if_fail (message != NULL); 3863 _dbus_return_if_fail (message == connection->message_borrowed); 3864 _dbus_return_if_fail (connection->dispatch_acquired); 3865 3866 CONNECTION_LOCK (connection); 3867 3868 _dbus_assert (message == connection->message_borrowed); 3869 3870 connection->message_borrowed = NULL; 3871 3872 _dbus_connection_release_dispatch (connection); 3873 3874 status = _dbus_connection_get_dispatch_status_unlocked (connection); 3875 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 3876 3877 _dbus_message_trace_ref (message, -1, -1, "dbus_connection_return_message"); 3878} 3879 3880/** 3881 * Used to keep a message after peeking at it using 3882 * dbus_connection_borrow_message(). Before using this function, see 3883 * the caveats/warnings in the documentation for 3884 * dbus_connection_pop_message(). 3885 * 3886 * @param connection the connection 3887 * @param message the message from dbus_connection_borrow_message() 3888 */ 3889void 3890dbus_connection_steal_borrowed_message (DBusConnection *connection, 3891 DBusMessage *message) 3892{ 3893 DBusMessage *pop_message; 3894 DBusDispatchStatus status; 3895 3896 _dbus_return_if_fail (connection != NULL); 3897 _dbus_return_if_fail (message != NULL); 3898 _dbus_return_if_fail (message == connection->message_borrowed); 3899 _dbus_return_if_fail (connection->dispatch_acquired); 3900 3901 CONNECTION_LOCK (connection); 3902 3903 _dbus_assert (message == connection->message_borrowed); 3904 3905 pop_message = _dbus_list_pop_first (&connection->incoming_messages); 3906 _dbus_assert (message == pop_message); 3907 (void) pop_message; /* unused unless asserting */ 3908 3909 connection->n_incoming -= 1; 3910 3911 _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n", 3912 message, connection->n_incoming); 3913 3914 connection->message_borrowed = NULL; 3915 3916 _dbus_connection_release_dispatch (connection); 3917 3918 status = _dbus_connection_get_dispatch_status_unlocked (connection); 3919 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 3920 _dbus_message_trace_ref (message, -1, -1, 3921 "dbus_connection_steal_borrowed_message"); 3922} 3923 3924/* See dbus_connection_pop_message, but requires the caller to own 3925 * the lock before calling. May drop the lock while running. 3926 */ 3927static DBusList* 3928_dbus_connection_pop_message_link_unlocked (DBusConnection *connection) 3929{ 3930 HAVE_LOCK_CHECK (connection); 3931 3932 _dbus_assert (connection->message_borrowed == NULL); 3933 3934 if (connection->n_incoming > 0) 3935 { 3936 DBusList *link; 3937 3938 link = _dbus_list_pop_first_link (&connection->incoming_messages); 3939 connection->n_incoming -= 1; 3940 3941 _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from incoming queue %p, %d incoming\n", 3942 link->data, 3943 dbus_message_type_to_string (dbus_message_get_type (link->data)), 3944 dbus_message_get_path (link->data) ? 3945 dbus_message_get_path (link->data) : 3946 "no path", 3947 dbus_message_get_interface (link->data) ? 3948 dbus_message_get_interface (link->data) : 3949 "no interface", 3950 dbus_message_get_member (link->data) ? 3951 dbus_message_get_member (link->data) : 3952 "no member", 3953 dbus_message_get_signature (link->data), 3954 connection, connection->n_incoming); 3955 3956 _dbus_message_trace_ref (link->data, -1, -1, 3957 "_dbus_connection_pop_message_link_unlocked"); 3958 3959 check_disconnected_message_arrived_unlocked (connection, link->data); 3960 3961 return link; 3962 } 3963 else 3964 return NULL; 3965} 3966 3967/* See dbus_connection_pop_message, but requires the caller to own 3968 * the lock before calling. May drop the lock while running. 3969 */ 3970static DBusMessage* 3971_dbus_connection_pop_message_unlocked (DBusConnection *connection) 3972{ 3973 DBusList *link; 3974 3975 HAVE_LOCK_CHECK (connection); 3976 3977 link = _dbus_connection_pop_message_link_unlocked (connection); 3978 3979 if (link != NULL) 3980 { 3981 DBusMessage *message; 3982 3983 message = link->data; 3984 3985 _dbus_list_free_link (link); 3986 3987 return message; 3988 } 3989 else 3990 return NULL; 3991} 3992 3993static void 3994_dbus_connection_putback_message_link_unlocked (DBusConnection *connection, 3995 DBusList *message_link) 3996{ 3997 HAVE_LOCK_CHECK (connection); 3998 3999 _dbus_assert (message_link != NULL); 4000 /* You can't borrow a message while a link is outstanding */ 4001 _dbus_assert (connection->message_borrowed == NULL); 4002 /* We had to have the dispatch lock across the pop/putback */ 4003 _dbus_assert (connection->dispatch_acquired); 4004 4005 _dbus_list_prepend_link (&connection->incoming_messages, 4006 message_link); 4007 connection->n_incoming += 1; 4008 4009 _dbus_verbose ("Message %p (%s %s %s '%s') put back into queue %p, %d incoming\n", 4010 message_link->data, 4011 dbus_message_type_to_string (dbus_message_get_type (message_link->data)), 4012 dbus_message_get_interface (message_link->data) ? 4013 dbus_message_get_interface (message_link->data) : 4014 "no interface", 4015 dbus_message_get_member (message_link->data) ? 4016 dbus_message_get_member (message_link->data) : 4017 "no member", 4018 dbus_message_get_signature (message_link->data), 4019 connection, connection->n_incoming); 4020 4021 _dbus_message_trace_ref (message_link->data, -1, -1, 4022 "_dbus_connection_putback_message_link_unlocked"); 4023} 4024 4025/** 4026 * Returns the first-received message from the incoming message queue, 4027 * removing it from the queue. The caller owns a reference to the 4028 * returned message. If the queue is empty, returns #NULL. 4029 * 4030 * This function bypasses any message handlers that are registered, 4031 * and so using it is usually wrong. Instead, let the main loop invoke 4032 * dbus_connection_dispatch(). Popping messages manually is only 4033 * useful in very simple programs that don't share a #DBusConnection 4034 * with any libraries or other modules. 4035 * 4036 * There is a lock that covers all ways of accessing the incoming message 4037 * queue, so dbus_connection_dispatch(), dbus_connection_pop_message(), 4038 * dbus_connection_borrow_message(), etc. will all block while one of the others 4039 * in the group is running. 4040 * 4041 * @param connection the connection. 4042 * @returns next message in the incoming queue. 4043 */ 4044DBusMessage* 4045dbus_connection_pop_message (DBusConnection *connection) 4046{ 4047 DBusMessage *message; 4048 DBusDispatchStatus status; 4049 4050 _dbus_verbose ("start\n"); 4051 4052 /* this is called for the side effect that it queues 4053 * up any messages from the transport 4054 */ 4055 status = dbus_connection_get_dispatch_status (connection); 4056 if (status != DBUS_DISPATCH_DATA_REMAINS) 4057 return NULL; 4058 4059 CONNECTION_LOCK (connection); 4060 _dbus_connection_acquire_dispatch (connection); 4061 HAVE_LOCK_CHECK (connection); 4062 4063 message = _dbus_connection_pop_message_unlocked (connection); 4064 4065 _dbus_verbose ("Returning popped message %p\n", message); 4066 4067 _dbus_connection_release_dispatch (connection); 4068 4069 status = _dbus_connection_get_dispatch_status_unlocked (connection); 4070 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 4071 4072 return message; 4073} 4074 4075/** 4076 * Acquire the dispatcher. This is a separate lock so the main 4077 * connection lock can be dropped to call out to application dispatch 4078 * handlers. 4079 * 4080 * @param connection the connection. 4081 */ 4082static void 4083_dbus_connection_acquire_dispatch (DBusConnection *connection) 4084{ 4085 HAVE_LOCK_CHECK (connection); 4086 4087 _dbus_connection_ref_unlocked (connection); 4088 CONNECTION_UNLOCK (connection); 4089 4090 _dbus_verbose ("locking dispatch_mutex\n"); 4091 _dbus_cmutex_lock (connection->dispatch_mutex); 4092 4093 while (connection->dispatch_acquired) 4094 { 4095 _dbus_verbose ("waiting for dispatch to be acquirable\n"); 4096 _dbus_condvar_wait (connection->dispatch_cond, 4097 connection->dispatch_mutex); 4098 } 4099 4100 _dbus_assert (!connection->dispatch_acquired); 4101 4102 connection->dispatch_acquired = TRUE; 4103 4104 _dbus_verbose ("unlocking dispatch_mutex\n"); 4105 _dbus_cmutex_unlock (connection->dispatch_mutex); 4106 4107 CONNECTION_LOCK (connection); 4108 _dbus_connection_unref_unlocked (connection); 4109} 4110 4111/** 4112 * Release the dispatcher when you're done with it. Only call 4113 * after you've acquired the dispatcher. Wakes up at most one 4114 * thread currently waiting to acquire the dispatcher. 4115 * 4116 * @param connection the connection. 4117 */ 4118static void 4119_dbus_connection_release_dispatch (DBusConnection *connection) 4120{ 4121 HAVE_LOCK_CHECK (connection); 4122 4123 _dbus_verbose ("locking dispatch_mutex\n"); 4124 _dbus_cmutex_lock (connection->dispatch_mutex); 4125 4126 _dbus_assert (connection->dispatch_acquired); 4127 4128 connection->dispatch_acquired = FALSE; 4129 _dbus_condvar_wake_one (connection->dispatch_cond); 4130 4131 _dbus_verbose ("unlocking dispatch_mutex\n"); 4132 _dbus_cmutex_unlock (connection->dispatch_mutex); 4133} 4134 4135static void 4136_dbus_connection_failed_pop (DBusConnection *connection, 4137 DBusList *message_link) 4138{ 4139 _dbus_list_prepend_link (&connection->incoming_messages, 4140 message_link); 4141 connection->n_incoming += 1; 4142} 4143 4144/* Note this may be called multiple times since we don't track whether we already did it */ 4145static void 4146notify_disconnected_unlocked (DBusConnection *connection) 4147{ 4148 HAVE_LOCK_CHECK (connection); 4149 4150 /* Set the weakref in dbus-bus.c to NULL, so nobody will get a disconnected 4151 * connection from dbus_bus_get(). We make the same guarantee for 4152 * dbus_connection_open() but in a different way since we don't want to 4153 * unref right here; we instead check for connectedness before returning 4154 * the connection from the hash. 4155 */ 4156 _dbus_bus_notify_shared_connection_disconnected_unlocked (connection); 4157 4158 /* Dump the outgoing queue, we aren't going to be able to 4159 * send it now, and we'd like accessors like 4160 * dbus_connection_get_outgoing_size() to be accurate. 4161 */ 4162 if (connection->n_outgoing > 0) 4163 { 4164 DBusList *link; 4165 4166 _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n", 4167 connection->n_outgoing); 4168 4169 while ((link = _dbus_list_get_last_link (&connection->outgoing_messages))) 4170 { 4171 _dbus_connection_message_sent_unlocked (connection, link->data); 4172 } 4173 } 4174} 4175 4176/* Note this may be called multiple times since we don't track whether we already did it */ 4177static DBusDispatchStatus 4178notify_disconnected_and_dispatch_complete_unlocked (DBusConnection *connection) 4179{ 4180 HAVE_LOCK_CHECK (connection); 4181 4182 if (connection->disconnect_message_link != NULL) 4183 { 4184 _dbus_verbose ("Sending disconnect message\n"); 4185 4186 /* If we have pending calls, queue their timeouts - we want the Disconnected 4187 * to be the last message, after these timeouts. 4188 */ 4189 connection_timeout_and_complete_all_pending_calls_unlocked (connection); 4190 4191 /* We haven't sent the disconnect message already, 4192 * and all real messages have been queued up. 4193 */ 4194 _dbus_connection_queue_synthesized_message_link (connection, 4195 connection->disconnect_message_link); 4196 connection->disconnect_message_link = NULL; 4197 4198 return DBUS_DISPATCH_DATA_REMAINS; 4199 } 4200 4201 return DBUS_DISPATCH_COMPLETE; 4202} 4203 4204static DBusDispatchStatus 4205_dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection) 4206{ 4207 HAVE_LOCK_CHECK (connection); 4208 4209 if (connection->n_incoming > 0) 4210 return DBUS_DISPATCH_DATA_REMAINS; 4211 else if (!_dbus_transport_queue_messages (connection->transport)) 4212 return DBUS_DISPATCH_NEED_MEMORY; 4213 else 4214 { 4215 DBusDispatchStatus status; 4216 dbus_bool_t is_connected; 4217 4218 status = _dbus_transport_get_dispatch_status (connection->transport); 4219 is_connected = _dbus_transport_get_is_connected (connection->transport); 4220 4221 _dbus_verbose ("dispatch status = %s is_connected = %d\n", 4222 DISPATCH_STATUS_NAME (status), is_connected); 4223 4224 if (!is_connected) 4225 { 4226 /* It's possible this would be better done by having an explicit 4227 * notification from _dbus_transport_disconnect() that would 4228 * synchronously do this, instead of waiting for the next dispatch 4229 * status check. However, probably not good to change until it causes 4230 * a problem. 4231 */ 4232 notify_disconnected_unlocked (connection); 4233 4234 /* I'm not sure this is needed; the idea is that we want to 4235 * queue the Disconnected only after we've read all the 4236 * messages, but if we're disconnected maybe we are guaranteed 4237 * to have read them all ? 4238 */ 4239 if (status == DBUS_DISPATCH_COMPLETE) 4240 status = notify_disconnected_and_dispatch_complete_unlocked (connection); 4241 } 4242 4243 if (status != DBUS_DISPATCH_COMPLETE) 4244 return status; 4245 else if (connection->n_incoming > 0) 4246 return DBUS_DISPATCH_DATA_REMAINS; 4247 else 4248 return DBUS_DISPATCH_COMPLETE; 4249 } 4250} 4251 4252static void 4253_dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection, 4254 DBusDispatchStatus new_status) 4255{ 4256 dbus_bool_t changed; 4257 DBusDispatchStatusFunction function; 4258 void *data; 4259 4260 HAVE_LOCK_CHECK (connection); 4261 4262 _dbus_connection_ref_unlocked (connection); 4263 4264 changed = new_status != connection->last_dispatch_status; 4265 4266 connection->last_dispatch_status = new_status; 4267 4268 function = connection->dispatch_status_function; 4269 data = connection->dispatch_status_data; 4270 4271 if (connection->disconnected_message_arrived && 4272 !connection->disconnected_message_processed) 4273 { 4274 connection->disconnected_message_processed = TRUE; 4275 4276 /* this does an unref, but we have a ref 4277 * so we should not run the finalizer here 4278 * inside the lock. 4279 */ 4280 connection_forget_shared_unlocked (connection); 4281 4282 if (connection->exit_on_disconnect) 4283 { 4284 CONNECTION_UNLOCK (connection); 4285 4286 _dbus_verbose ("Exiting on Disconnected signal\n"); 4287 _dbus_exit (1); 4288 _dbus_assert_not_reached ("Call to exit() returned"); 4289 } 4290 } 4291 4292 /* We drop the lock */ 4293 CONNECTION_UNLOCK (connection); 4294 4295 if (changed && function) 4296 { 4297 _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n", 4298 connection, new_status, 4299 DISPATCH_STATUS_NAME (new_status)); 4300 (* function) (connection, new_status, data); 4301 } 4302 4303 dbus_connection_unref (connection); 4304} 4305 4306/** 4307 * Gets the current state of the incoming message queue. 4308 * #DBUS_DISPATCH_DATA_REMAINS indicates that the message queue 4309 * may contain messages. #DBUS_DISPATCH_COMPLETE indicates that the 4310 * incoming queue is empty. #DBUS_DISPATCH_NEED_MEMORY indicates that 4311 * there could be data, but we can't know for sure without more 4312 * memory. 4313 * 4314 * To process the incoming message queue, use dbus_connection_dispatch() 4315 * or (in rare cases) dbus_connection_pop_message(). 4316 * 4317 * Note, #DBUS_DISPATCH_DATA_REMAINS really means that either we 4318 * have messages in the queue, or we have raw bytes buffered up 4319 * that need to be parsed. When these bytes are parsed, they 4320 * may not add up to an entire message. Thus, it's possible 4321 * to see a status of #DBUS_DISPATCH_DATA_REMAINS but not 4322 * have a message yet. 4323 * 4324 * In particular this happens on initial connection, because all sorts 4325 * of authentication protocol stuff has to be parsed before the 4326 * first message arrives. 4327 * 4328 * @param connection the connection. 4329 * @returns current dispatch status 4330 */ 4331DBusDispatchStatus 4332dbus_connection_get_dispatch_status (DBusConnection *connection) 4333{ 4334 DBusDispatchStatus status; 4335 4336 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE); 4337 4338 _dbus_verbose ("start\n"); 4339 4340 CONNECTION_LOCK (connection); 4341 4342 status = _dbus_connection_get_dispatch_status_unlocked (connection); 4343 4344 CONNECTION_UNLOCK (connection); 4345 4346 return status; 4347} 4348 4349/** 4350 * Filter funtion for handling the Peer standard interface. 4351 */ 4352static DBusHandlerResult 4353_dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection, 4354 DBusMessage *message) 4355{ 4356 dbus_bool_t sent = FALSE; 4357 DBusMessage *ret = NULL; 4358 DBusList *expire_link; 4359 4360 if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL) 4361 { 4362 /* This means we're letting the bus route this message */ 4363 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 4364 } 4365 4366 if (!dbus_message_has_interface (message, DBUS_INTERFACE_PEER)) 4367 { 4368 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 4369 } 4370 4371 /* Preallocate a linked-list link, so that if we need to dispose of a 4372 * message, we can attach it to the expired list */ 4373 expire_link = _dbus_list_alloc_link (NULL); 4374 4375 if (!expire_link) 4376 return DBUS_HANDLER_RESULT_NEED_MEMORY; 4377 4378 if (dbus_message_is_method_call (message, 4379 DBUS_INTERFACE_PEER, 4380 "Ping")) 4381 { 4382 ret = dbus_message_new_method_return (message); 4383 if (ret == NULL) 4384 goto out; 4385 4386 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL); 4387 } 4388 else if (dbus_message_is_method_call (message, 4389 DBUS_INTERFACE_PEER, 4390 "GetMachineId")) 4391 { 4392 DBusString uuid; 4393 4394 ret = dbus_message_new_method_return (message); 4395 if (ret == NULL) 4396 goto out; 4397 4398 _dbus_string_init (&uuid); 4399 if (_dbus_get_local_machine_uuid_encoded (&uuid)) 4400 { 4401 const char *v_STRING = _dbus_string_get_const_data (&uuid); 4402 if (dbus_message_append_args (ret, 4403 DBUS_TYPE_STRING, &v_STRING, 4404 DBUS_TYPE_INVALID)) 4405 { 4406 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL); 4407 } 4408 } 4409 _dbus_string_free (&uuid); 4410 } 4411 else 4412 { 4413 /* We need to bounce anything else with this interface, otherwise apps 4414 * could start extending the interface and when we added extensions 4415 * here to DBusConnection we'd break those apps. 4416 */ 4417 ret = dbus_message_new_error (message, 4418 DBUS_ERROR_UNKNOWN_METHOD, 4419 "Unknown method invoked on org.freedesktop.DBus.Peer interface"); 4420 if (ret == NULL) 4421 goto out; 4422 4423 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL); 4424 } 4425 4426out: 4427 if (ret == NULL) 4428 { 4429 _dbus_list_free_link (expire_link); 4430 } 4431 else 4432 { 4433 /* It'll be safe to unref the reply when we unlock */ 4434 expire_link->data = ret; 4435 _dbus_list_prepend_link (&connection->expired_messages, expire_link); 4436 } 4437 4438 if (!sent) 4439 return DBUS_HANDLER_RESULT_NEED_MEMORY; 4440 4441 return DBUS_HANDLER_RESULT_HANDLED; 4442} 4443 4444/** 4445* Processes all builtin filter functions 4446* 4447* If the spec specifies a standard interface 4448* they should be processed from this method 4449**/ 4450static DBusHandlerResult 4451_dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection, 4452 DBusMessage *message) 4453{ 4454 /* We just run one filter for now but have the option to run more 4455 if the spec calls for it in the future */ 4456 4457 return _dbus_connection_peer_filter_unlocked_no_update (connection, message); 4458} 4459 4460/** 4461 * Processes any incoming data. 4462 * 4463 * If there's incoming raw data that has not yet been parsed, it is 4464 * parsed, which may or may not result in adding messages to the 4465 * incoming queue. 4466 * 4467 * The incoming data buffer is filled when the connection reads from 4468 * its underlying transport (such as a socket). Reading usually 4469 * happens in dbus_watch_handle() or dbus_connection_read_write(). 4470 * 4471 * If there are complete messages in the incoming queue, 4472 * dbus_connection_dispatch() removes one message from the queue and 4473 * processes it. Processing has three steps. 4474 * 4475 * First, any method replies are passed to #DBusPendingCall or 4476 * dbus_connection_send_with_reply_and_block() in order to 4477 * complete the pending method call. 4478 * 4479 * Second, any filters registered with dbus_connection_add_filter() 4480 * are run. If any filter returns #DBUS_HANDLER_RESULT_HANDLED 4481 * then processing stops after that filter. 4482 * 4483 * Third, if the message is a method call it is forwarded to 4484 * any registered object path handlers added with 4485 * dbus_connection_register_object_path() or 4486 * dbus_connection_register_fallback(). 4487 * 4488 * A single call to dbus_connection_dispatch() will process at most 4489 * one message; it will not clear the entire message queue. 4490 * 4491 * Be careful about calling dbus_connection_dispatch() from inside a 4492 * message handler, i.e. calling dbus_connection_dispatch() 4493 * recursively. If threads have been initialized with a recursive 4494 * mutex function, then this will not deadlock; however, it can 4495 * certainly confuse your application. 4496 * 4497 * @todo some FIXME in here about handling DBUS_HANDLER_RESULT_NEED_MEMORY 4498 * 4499 * @param connection the connection 4500 * @returns dispatch status, see dbus_connection_get_dispatch_status() 4501 */ 4502DBusDispatchStatus 4503dbus_connection_dispatch (DBusConnection *connection) 4504{ 4505 DBusMessage *message; 4506 DBusList *link, *filter_list_copy, *message_link; 4507 DBusHandlerResult result; 4508 DBusPendingCall *pending; 4509 dbus_int32_t reply_serial; 4510 DBusDispatchStatus status; 4511 dbus_bool_t found_object; 4512 4513 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE); 4514 4515 _dbus_verbose ("\n"); 4516 4517 CONNECTION_LOCK (connection); 4518 status = _dbus_connection_get_dispatch_status_unlocked (connection); 4519 if (status != DBUS_DISPATCH_DATA_REMAINS) 4520 { 4521 /* unlocks and calls out to user code */ 4522 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 4523 return status; 4524 } 4525 4526 /* We need to ref the connection since the callback could potentially 4527 * drop the last ref to it 4528 */ 4529 _dbus_connection_ref_unlocked (connection); 4530 4531 _dbus_connection_acquire_dispatch (connection); 4532 HAVE_LOCK_CHECK (connection); 4533 4534 message_link = _dbus_connection_pop_message_link_unlocked (connection); 4535 if (message_link == NULL) 4536 { 4537 /* another thread dispatched our stuff */ 4538 4539 _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n"); 4540 4541 _dbus_connection_release_dispatch (connection); 4542 4543 status = _dbus_connection_get_dispatch_status_unlocked (connection); 4544 4545 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 4546 4547 dbus_connection_unref (connection); 4548 4549 return status; 4550 } 4551 4552 message = message_link->data; 4553 4554 _dbus_verbose (" dispatching message %p (%s %s %s '%s')\n", 4555 message, 4556 dbus_message_type_to_string (dbus_message_get_type (message)), 4557 dbus_message_get_interface (message) ? 4558 dbus_message_get_interface (message) : 4559 "no interface", 4560 dbus_message_get_member (message) ? 4561 dbus_message_get_member (message) : 4562 "no member", 4563 dbus_message_get_signature (message)); 4564 4565 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 4566 4567 /* Pending call handling must be first, because if you do 4568 * dbus_connection_send_with_reply_and_block() or 4569 * dbus_pending_call_block() then no handlers/filters will be run on 4570 * the reply. We want consistent semantics in the case where we 4571 * dbus_connection_dispatch() the reply. 4572 */ 4573 4574 reply_serial = dbus_message_get_reply_serial (message); 4575 pending = _dbus_hash_table_lookup_int (connection->pending_replies, 4576 reply_serial); 4577 if (pending) 4578 { 4579 _dbus_verbose ("Dispatching a pending reply\n"); 4580 complete_pending_call_and_unlock (connection, pending, message); 4581 pending = NULL; /* it's probably unref'd */ 4582 4583 CONNECTION_LOCK (connection); 4584 _dbus_verbose ("pending call completed in dispatch\n"); 4585 result = DBUS_HANDLER_RESULT_HANDLED; 4586 goto out; 4587 } 4588 4589 result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message); 4590 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED) 4591 goto out; 4592 4593 if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy)) 4594 { 4595 _dbus_connection_release_dispatch (connection); 4596 HAVE_LOCK_CHECK (connection); 4597 4598 _dbus_connection_failed_pop (connection, message_link); 4599 4600 /* unlocks and calls user code */ 4601 _dbus_connection_update_dispatch_status_and_unlock (connection, 4602 DBUS_DISPATCH_NEED_MEMORY); 4603 dbus_connection_unref (connection); 4604 4605 return DBUS_DISPATCH_NEED_MEMORY; 4606 } 4607 4608 _dbus_list_foreach (&filter_list_copy, 4609 (DBusForeachFunction)_dbus_message_filter_ref, 4610 NULL); 4611 4612 /* We're still protected from dispatch() reentrancy here 4613 * since we acquired the dispatcher 4614 */ 4615 CONNECTION_UNLOCK (connection); 4616 4617 link = _dbus_list_get_first_link (&filter_list_copy); 4618 while (link != NULL) 4619 { 4620 DBusMessageFilter *filter = link->data; 4621 DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link); 4622 4623 if (filter->function == NULL) 4624 { 4625 _dbus_verbose (" filter was removed in a callback function\n"); 4626 link = next; 4627 continue; 4628 } 4629 4630 _dbus_verbose (" running filter on message %p\n", message); 4631 result = (* filter->function) (connection, message, filter->user_data); 4632 4633 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED) 4634 break; 4635 4636 link = next; 4637 } 4638 4639 _dbus_list_foreach (&filter_list_copy, 4640 (DBusForeachFunction)_dbus_message_filter_unref, 4641 NULL); 4642 _dbus_list_clear (&filter_list_copy); 4643 4644 CONNECTION_LOCK (connection); 4645 4646 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY) 4647 { 4648 _dbus_verbose ("No memory\n"); 4649 goto out; 4650 } 4651 else if (result == DBUS_HANDLER_RESULT_HANDLED) 4652 { 4653 _dbus_verbose ("filter handled message in dispatch\n"); 4654 goto out; 4655 } 4656 4657 /* We're still protected from dispatch() reentrancy here 4658 * since we acquired the dispatcher 4659 */ 4660 _dbus_verbose (" running object path dispatch on message %p (%s %s %s '%s')\n", 4661 message, 4662 dbus_message_type_to_string (dbus_message_get_type (message)), 4663 dbus_message_get_interface (message) ? 4664 dbus_message_get_interface (message) : 4665 "no interface", 4666 dbus_message_get_member (message) ? 4667 dbus_message_get_member (message) : 4668 "no member", 4669 dbus_message_get_signature (message)); 4670 4671 HAVE_LOCK_CHECK (connection); 4672 result = _dbus_object_tree_dispatch_and_unlock (connection->objects, 4673 message, 4674 &found_object); 4675 4676 CONNECTION_LOCK (connection); 4677 4678 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED) 4679 { 4680 _dbus_verbose ("object tree handled message in dispatch\n"); 4681 goto out; 4682 } 4683 4684 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL) 4685 { 4686 DBusMessage *reply; 4687 DBusString str; 4688 DBusPreallocatedSend *preallocated; 4689 DBusList *expire_link; 4690 4691 _dbus_verbose (" sending error %s\n", 4692 DBUS_ERROR_UNKNOWN_METHOD); 4693 4694 if (!_dbus_string_init (&str)) 4695 { 4696 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 4697 _dbus_verbose ("no memory for error string in dispatch\n"); 4698 goto out; 4699 } 4700 4701 if (!_dbus_string_append_printf (&str, 4702 "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n", 4703 dbus_message_get_member (message), 4704 dbus_message_get_signature (message), 4705 dbus_message_get_interface (message))) 4706 { 4707 _dbus_string_free (&str); 4708 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 4709 _dbus_verbose ("no memory for error string in dispatch\n"); 4710 goto out; 4711 } 4712 4713 reply = dbus_message_new_error (message, 4714 found_object ? DBUS_ERROR_UNKNOWN_METHOD : DBUS_ERROR_UNKNOWN_OBJECT, 4715 _dbus_string_get_const_data (&str)); 4716 _dbus_string_free (&str); 4717 4718 if (reply == NULL) 4719 { 4720 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 4721 _dbus_verbose ("no memory for error reply in dispatch\n"); 4722 goto out; 4723 } 4724 4725 expire_link = _dbus_list_alloc_link (reply); 4726 4727 if (expire_link == NULL) 4728 { 4729 dbus_message_unref (reply); 4730 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 4731 _dbus_verbose ("no memory for error send in dispatch\n"); 4732 goto out; 4733 } 4734 4735 preallocated = _dbus_connection_preallocate_send_unlocked (connection); 4736 4737 if (preallocated == NULL) 4738 { 4739 _dbus_list_free_link (expire_link); 4740 /* It's OK that this is finalized, because it hasn't been seen by 4741 * anything that could attach user callbacks */ 4742 dbus_message_unref (reply); 4743 result = DBUS_HANDLER_RESULT_NEED_MEMORY; 4744 _dbus_verbose ("no memory for error send in dispatch\n"); 4745 goto out; 4746 } 4747 4748 _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated, 4749 reply, NULL); 4750 /* reply will be freed when we release the lock */ 4751 _dbus_list_prepend_link (&connection->expired_messages, expire_link); 4752 4753 result = DBUS_HANDLER_RESULT_HANDLED; 4754 } 4755 4756 _dbus_verbose (" done dispatching %p (%s %s %s '%s') on connection %p\n", message, 4757 dbus_message_type_to_string (dbus_message_get_type (message)), 4758 dbus_message_get_interface (message) ? 4759 dbus_message_get_interface (message) : 4760 "no interface", 4761 dbus_message_get_member (message) ? 4762 dbus_message_get_member (message) : 4763 "no member", 4764 dbus_message_get_signature (message), 4765 connection); 4766 4767 out: 4768 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY) 4769 { 4770 _dbus_verbose ("out of memory\n"); 4771 4772 /* Put message back, and we'll start over. 4773 * Yes this means handlers must be idempotent if they 4774 * don't return HANDLED; c'est la vie. 4775 */ 4776 _dbus_connection_putback_message_link_unlocked (connection, 4777 message_link); 4778 /* now we don't want to free them */ 4779 message_link = NULL; 4780 message = NULL; 4781 } 4782 else 4783 { 4784 _dbus_verbose (" ... done dispatching\n"); 4785 } 4786 4787 _dbus_connection_release_dispatch (connection); 4788 HAVE_LOCK_CHECK (connection); 4789 4790 if (message != NULL) 4791 { 4792 /* We don't want this message to count in maximum message limits when 4793 * computing the dispatch status, below. We have to drop the lock 4794 * temporarily, because finalizing a message can trigger callbacks. 4795 * 4796 * We have a reference to the connection, and we don't use any cached 4797 * pointers to the connection's internals below this point, so it should 4798 * be safe to drop the lock and take it back. */ 4799 CONNECTION_UNLOCK (connection); 4800 dbus_message_unref (message); 4801 CONNECTION_LOCK (connection); 4802 } 4803 4804 if (message_link != NULL) 4805 _dbus_list_free_link (message_link); 4806 4807 _dbus_verbose ("before final status update\n"); 4808 status = _dbus_connection_get_dispatch_status_unlocked (connection); 4809 4810 /* unlocks and calls user code */ 4811 _dbus_connection_update_dispatch_status_and_unlock (connection, status); 4812 4813 dbus_connection_unref (connection); 4814 4815 return status; 4816} 4817 4818/** 4819 * Sets the watch functions for the connection. These functions are 4820 * responsible for making the application's main loop aware of file 4821 * descriptors that need to be monitored for events, using select() or 4822 * poll(). When using Qt, typically the DBusAddWatchFunction would 4823 * create a QSocketNotifier. When using GLib, the DBusAddWatchFunction 4824 * could call g_io_add_watch(), or could be used as part of a more 4825 * elaborate GSource. Note that when a watch is added, it may 4826 * not be enabled. 4827 * 4828 * The DBusWatchToggledFunction notifies the application that the 4829 * watch has been enabled or disabled. Call dbus_watch_get_enabled() 4830 * to check this. A disabled watch should have no effect, and enabled 4831 * watch should be added to the main loop. This feature is used 4832 * instead of simply adding/removing the watch because 4833 * enabling/disabling can be done without memory allocation. The 4834 * toggled function may be NULL if a main loop re-queries 4835 * dbus_watch_get_enabled() every time anyway. 4836 * 4837 * The DBusWatch can be queried for the file descriptor to watch using 4838 * dbus_watch_get_unix_fd() or dbus_watch_get_socket(), and for the 4839 * events to watch for using dbus_watch_get_flags(). The flags 4840 * returned by dbus_watch_get_flags() will only contain 4841 * DBUS_WATCH_READABLE and DBUS_WATCH_WRITABLE, never 4842 * DBUS_WATCH_HANGUP or DBUS_WATCH_ERROR; all watches implicitly 4843 * include a watch for hangups, errors, and other exceptional 4844 * conditions. 4845 * 4846 * Once a file descriptor becomes readable or writable, or an exception 4847 * occurs, dbus_watch_handle() should be called to 4848 * notify the connection of the file descriptor's condition. 4849 * 4850 * dbus_watch_handle() cannot be called during the 4851 * DBusAddWatchFunction, as the connection will not be ready to handle 4852 * that watch yet. 4853 * 4854 * It is not allowed to reference a DBusWatch after it has been passed 4855 * to remove_function. 4856 * 4857 * If #FALSE is returned due to lack of memory, the failure may be due 4858 * to a #FALSE return from the new add_function. If so, the 4859 * add_function may have been called successfully one or more times, 4860 * but the remove_function will also have been called to remove any 4861 * successful adds. i.e. if #FALSE is returned the net result 4862 * should be that dbus_connection_set_watch_functions() has no effect, 4863 * but the add_function and remove_function may have been called. 4864 * 4865 * @note The thread lock on DBusConnection is held while 4866 * watch functions are invoked, so inside these functions you 4867 * may not invoke any methods on DBusConnection or it will deadlock. 4868 * See the comments in the code or http://lists.freedesktop.org/archives/dbus/2007-July/tread.html#8144 4869 * if you encounter this issue and want to attempt writing a patch. 4870 * 4871 * @param connection the connection. 4872 * @param add_function function to begin monitoring a new descriptor. 4873 * @param remove_function function to stop monitoring a descriptor. 4874 * @param toggled_function function to notify of enable/disable 4875 * @param data data to pass to add_function and remove_function. 4876 * @param free_data_function function to be called to free the data. 4877 * @returns #FALSE on failure (no memory) 4878 */ 4879dbus_bool_t 4880dbus_connection_set_watch_functions (DBusConnection *connection, 4881 DBusAddWatchFunction add_function, 4882 DBusRemoveWatchFunction remove_function, 4883 DBusWatchToggledFunction toggled_function, 4884 void *data, 4885 DBusFreeFunction free_data_function) 4886{ 4887 dbus_bool_t retval; 4888 4889 _dbus_return_val_if_fail (connection != NULL, FALSE); 4890 4891 CONNECTION_LOCK (connection); 4892 4893 retval = _dbus_watch_list_set_functions (connection->watches, 4894 add_function, remove_function, 4895 toggled_function, 4896 data, free_data_function); 4897 4898 CONNECTION_UNLOCK (connection); 4899 4900 return retval; 4901} 4902 4903/** 4904 * Sets the timeout functions for the connection. These functions are 4905 * responsible for making the application's main loop aware of timeouts. 4906 * When using Qt, typically the DBusAddTimeoutFunction would create a 4907 * QTimer. When using GLib, the DBusAddTimeoutFunction would call 4908 * g_timeout_add. 4909 * 4910 * The DBusTimeoutToggledFunction notifies the application that the 4911 * timeout has been enabled or disabled. Call 4912 * dbus_timeout_get_enabled() to check this. A disabled timeout should 4913 * have no effect, and enabled timeout should be added to the main 4914 * loop. This feature is used instead of simply adding/removing the 4915 * timeout because enabling/disabling can be done without memory 4916 * allocation. With Qt, QTimer::start() and QTimer::stop() can be used 4917 * to enable and disable. The toggled function may be NULL if a main 4918 * loop re-queries dbus_timeout_get_enabled() every time anyway. 4919 * Whenever a timeout is toggled, its interval may change. 4920 * 4921 * The DBusTimeout can be queried for the timer interval using 4922 * dbus_timeout_get_interval(). dbus_timeout_handle() should be called 4923 * repeatedly, each time the interval elapses, starting after it has 4924 * elapsed once. The timeout stops firing when it is removed with the 4925 * given remove_function. The timer interval may change whenever the 4926 * timeout is added, removed, or toggled. 4927 * 4928 * @note The thread lock on DBusConnection is held while 4929 * timeout functions are invoked, so inside these functions you 4930 * may not invoke any methods on DBusConnection or it will deadlock. 4931 * See the comments in the code or http://lists.freedesktop.org/archives/dbus/2007-July/thread.html#8144 4932 * if you encounter this issue and want to attempt writing a patch. 4933 * 4934 * @param connection the connection. 4935 * @param add_function function to add a timeout. 4936 * @param remove_function function to remove a timeout. 4937 * @param toggled_function function to notify of enable/disable 4938 * @param data data to pass to add_function and remove_function. 4939 * @param free_data_function function to be called to free the data. 4940 * @returns #FALSE on failure (no memory) 4941 */ 4942dbus_bool_t 4943dbus_connection_set_timeout_functions (DBusConnection *connection, 4944 DBusAddTimeoutFunction add_function, 4945 DBusRemoveTimeoutFunction remove_function, 4946 DBusTimeoutToggledFunction toggled_function, 4947 void *data, 4948 DBusFreeFunction free_data_function) 4949{ 4950 dbus_bool_t retval; 4951 4952 _dbus_return_val_if_fail (connection != NULL, FALSE); 4953 4954 CONNECTION_LOCK (connection); 4955 4956 retval = _dbus_timeout_list_set_functions (connection->timeouts, 4957 add_function, remove_function, 4958 toggled_function, 4959 data, free_data_function); 4960 4961 CONNECTION_UNLOCK (connection); 4962 4963 return retval; 4964} 4965 4966/** 4967 * Sets the mainloop wakeup function for the connection. This function 4968 * is responsible for waking up the main loop (if its sleeping in 4969 * another thread) when some some change has happened to the 4970 * connection that the mainloop needs to reconsider (e.g. a message 4971 * has been queued for writing). When using Qt, this typically 4972 * results in a call to QEventLoop::wakeUp(). When using GLib, it 4973 * would call g_main_context_wakeup(). 4974 * 4975 * @param connection the connection. 4976 * @param wakeup_main_function function to wake up the mainloop 4977 * @param data data to pass wakeup_main_function 4978 * @param free_data_function function to be called to free the data. 4979 */ 4980void 4981dbus_connection_set_wakeup_main_function (DBusConnection *connection, 4982 DBusWakeupMainFunction wakeup_main_function, 4983 void *data, 4984 DBusFreeFunction free_data_function) 4985{ 4986 void *old_data; 4987 DBusFreeFunction old_free_data; 4988 4989 _dbus_return_if_fail (connection != NULL); 4990 4991 CONNECTION_LOCK (connection); 4992 old_data = connection->wakeup_main_data; 4993 old_free_data = connection->free_wakeup_main_data; 4994 4995 connection->wakeup_main_function = wakeup_main_function; 4996 connection->wakeup_main_data = data; 4997 connection->free_wakeup_main_data = free_data_function; 4998 4999 CONNECTION_UNLOCK (connection); 5000 5001 /* Callback outside the lock */ 5002 if (old_free_data) 5003 (*old_free_data) (old_data); 5004} 5005 5006/** 5007 * Set a function to be invoked when the dispatch status changes. 5008 * If the dispatch status is #DBUS_DISPATCH_DATA_REMAINS, then 5009 * dbus_connection_dispatch() needs to be called to process incoming 5010 * messages. However, dbus_connection_dispatch() MUST NOT BE CALLED 5011 * from inside the DBusDispatchStatusFunction. Indeed, almost 5012 * any reentrancy in this function is a bad idea. Instead, 5013 * the DBusDispatchStatusFunction should simply save an indication 5014 * that messages should be dispatched later, when the main loop 5015 * is re-entered. 5016 * 5017 * If you don't set a dispatch status function, you have to be sure to 5018 * dispatch on every iteration of your main loop, especially if 5019 * dbus_watch_handle() or dbus_timeout_handle() were called. 5020 * 5021 * @param connection the connection 5022 * @param function function to call on dispatch status changes 5023 * @param data data for function 5024 * @param free_data_function free the function data 5025 */ 5026void 5027dbus_connection_set_dispatch_status_function (DBusConnection *connection, 5028 DBusDispatchStatusFunction function, 5029 void *data, 5030 DBusFreeFunction free_data_function) 5031{ 5032 void *old_data; 5033 DBusFreeFunction old_free_data; 5034 5035 _dbus_return_if_fail (connection != NULL); 5036 5037 CONNECTION_LOCK (connection); 5038 old_data = connection->dispatch_status_data; 5039 old_free_data = connection->free_dispatch_status_data; 5040 5041 connection->dispatch_status_function = function; 5042 connection->dispatch_status_data = data; 5043 connection->free_dispatch_status_data = free_data_function; 5044 5045 CONNECTION_UNLOCK (connection); 5046 5047 /* Callback outside the lock */ 5048 if (old_free_data) 5049 (*old_free_data) (old_data); 5050} 5051 5052/** 5053 * Get the UNIX file descriptor of the connection, if any. This can 5054 * be used for SELinux access control checks with getpeercon() for 5055 * example. DO NOT read or write to the file descriptor, or try to 5056 * select() on it; use DBusWatch for main loop integration. Not all 5057 * connections will have a file descriptor. So for adding descriptors 5058 * to the main loop, use dbus_watch_get_unix_fd() and so forth. 5059 * 5060 * If the connection is socket-based, you can also use 5061 * dbus_connection_get_socket(), which will work on Windows too. 5062 * This function always fails on Windows. 5063 * 5064 * Right now the returned descriptor is always a socket, but 5065 * that is not guaranteed. 5066 * 5067 * @param connection the connection 5068 * @param fd return location for the file descriptor. 5069 * @returns #TRUE if fd is successfully obtained. 5070 */ 5071dbus_bool_t 5072dbus_connection_get_unix_fd (DBusConnection *connection, 5073 int *fd) 5074{ 5075 _dbus_return_val_if_fail (connection != NULL, FALSE); 5076 _dbus_return_val_if_fail (connection->transport != NULL, FALSE); 5077 5078#ifdef DBUS_WIN 5079 /* FIXME do this on a lower level */ 5080 return FALSE; 5081#endif 5082 5083 return dbus_connection_get_socket(connection, fd); 5084} 5085 5086/** 5087 * Gets the underlying Windows or UNIX socket file descriptor 5088 * of the connection, if any. DO NOT read or write to the file descriptor, or try to 5089 * select() on it; use DBusWatch for main loop integration. Not all 5090 * connections will have a socket. So for adding descriptors 5091 * to the main loop, use dbus_watch_get_socket() and so forth. 5092 * 5093 * If the connection is not socket-based, this function will return FALSE, 5094 * even if the connection does have a file descriptor of some kind. 5095 * i.e. this function always returns specifically a socket file descriptor. 5096 * 5097 * @param connection the connection 5098 * @param fd return location for the file descriptor. 5099 * @returns #TRUE if fd is successfully obtained. 5100 */ 5101dbus_bool_t 5102dbus_connection_get_socket(DBusConnection *connection, 5103 int *fd) 5104{ 5105 dbus_bool_t retval; 5106 5107 _dbus_return_val_if_fail (connection != NULL, FALSE); 5108 _dbus_return_val_if_fail (connection->transport != NULL, FALSE); 5109 5110 CONNECTION_LOCK (connection); 5111 5112 retval = _dbus_transport_get_socket_fd (connection->transport, 5113 fd); 5114 5115 CONNECTION_UNLOCK (connection); 5116 5117 return retval; 5118} 5119 5120 5121/** 5122 * Gets the UNIX user ID of the connection if known. Returns #TRUE if 5123 * the uid is filled in. Always returns #FALSE on non-UNIX platforms 5124 * for now, though in theory someone could hook Windows to NIS or 5125 * something. Always returns #FALSE prior to authenticating the 5126 * connection. 5127 * 5128 * The UID is only read by servers from clients; clients can't usually 5129 * get the UID of servers, because servers do not authenticate to 5130 * clients. The returned UID is the UID the connection authenticated 5131 * as. 5132 * 5133 * The message bus is a server and the apps connecting to the bus 5134 * are clients. 5135 * 5136 * You can ask the bus to tell you the UID of another connection though 5137 * if you like; this is done with dbus_bus_get_unix_user(). 5138 * 5139 * @param connection the connection 5140 * @param uid return location for the user ID 5141 * @returns #TRUE if uid is filled in with a valid user ID 5142 */ 5143dbus_bool_t 5144dbus_connection_get_unix_user (DBusConnection *connection, 5145 unsigned long *uid) 5146{ 5147 dbus_bool_t result; 5148 5149 _dbus_return_val_if_fail (connection != NULL, FALSE); 5150 _dbus_return_val_if_fail (uid != NULL, FALSE); 5151 5152 CONNECTION_LOCK (connection); 5153 5154 if (!_dbus_transport_get_is_authenticated (connection->transport)) 5155 result = FALSE; 5156 else 5157 result = _dbus_transport_get_unix_user (connection->transport, 5158 uid); 5159 5160#ifdef DBUS_WIN 5161 _dbus_assert (!result); 5162#endif 5163 5164 CONNECTION_UNLOCK (connection); 5165 5166 return result; 5167} 5168 5169/** 5170 * Gets the process ID of the connection if any. 5171 * Returns #TRUE if the pid is filled in. 5172 * Always returns #FALSE prior to authenticating the 5173 * connection. 5174 * 5175 * @param connection the connection 5176 * @param pid return location for the process ID 5177 * @returns #TRUE if uid is filled in with a valid process ID 5178 */ 5179dbus_bool_t 5180dbus_connection_get_unix_process_id (DBusConnection *connection, 5181 unsigned long *pid) 5182{ 5183 dbus_bool_t result; 5184 5185 _dbus_return_val_if_fail (connection != NULL, FALSE); 5186 _dbus_return_val_if_fail (pid != NULL, FALSE); 5187 5188 CONNECTION_LOCK (connection); 5189 5190 if (!_dbus_transport_get_is_authenticated (connection->transport)) 5191 result = FALSE; 5192 else 5193 result = _dbus_transport_get_unix_process_id (connection->transport, 5194 pid); 5195 5196 CONNECTION_UNLOCK (connection); 5197 5198 return result; 5199} 5200 5201/** 5202 * Gets the ADT audit data of the connection if any. 5203 * Returns #TRUE if the structure pointer is returned. 5204 * Always returns #FALSE prior to authenticating the 5205 * connection. 5206 * 5207 * @param connection the connection 5208 * @param data return location for audit data 5209 * @returns #TRUE if audit data is filled in with a valid ucred pointer 5210 */ 5211dbus_bool_t 5212dbus_connection_get_adt_audit_session_data (DBusConnection *connection, 5213 void **data, 5214 dbus_int32_t *data_size) 5215{ 5216 dbus_bool_t result; 5217 5218 _dbus_return_val_if_fail (connection != NULL, FALSE); 5219 _dbus_return_val_if_fail (data != NULL, FALSE); 5220 _dbus_return_val_if_fail (data_size != NULL, FALSE); 5221 5222 CONNECTION_LOCK (connection); 5223 5224 if (!_dbus_transport_get_is_authenticated (connection->transport)) 5225 result = FALSE; 5226 else 5227 result = _dbus_transport_get_adt_audit_session_data (connection->transport, 5228 data, 5229 data_size); 5230 CONNECTION_UNLOCK (connection); 5231 5232 return result; 5233} 5234 5235/** 5236 * Sets a predicate function used to determine whether a given user ID 5237 * is allowed to connect. When an incoming connection has 5238 * authenticated with a particular user ID, this function is called; 5239 * if it returns #TRUE, the connection is allowed to proceed, 5240 * otherwise the connection is disconnected. 5241 * 5242 * If the function is set to #NULL (as it is by default), then 5243 * only the same UID as the server process will be allowed to 5244 * connect. Also, root is always allowed to connect. 5245 * 5246 * On Windows, the function will be set and its free_data_function will 5247 * be invoked when the connection is freed or a new function is set. 5248 * However, the function will never be called, because there are 5249 * no UNIX user ids to pass to it, or at least none of the existing 5250 * auth protocols would allow authenticating as a UNIX user on Windows. 5251 * 5252 * @param connection the connection 5253 * @param function the predicate 5254 * @param data data to pass to the predicate 5255 * @param free_data_function function to free the data 5256 */ 5257void 5258dbus_connection_set_unix_user_function (DBusConnection *connection, 5259 DBusAllowUnixUserFunction function, 5260 void *data, 5261 DBusFreeFunction free_data_function) 5262{ 5263 void *old_data = NULL; 5264 DBusFreeFunction old_free_function = NULL; 5265 5266 _dbus_return_if_fail (connection != NULL); 5267 5268 CONNECTION_LOCK (connection); 5269 _dbus_transport_set_unix_user_function (connection->transport, 5270 function, data, free_data_function, 5271 &old_data, &old_free_function); 5272 CONNECTION_UNLOCK (connection); 5273 5274 if (old_free_function != NULL) 5275 (* old_free_function) (old_data); 5276} 5277 5278/** 5279 * Gets the Windows user SID of the connection if known. Returns 5280 * #TRUE if the ID is filled in. Always returns #FALSE on non-Windows 5281 * platforms for now, though in theory someone could hook UNIX to 5282 * Active Directory or something. Always returns #FALSE prior to 5283 * authenticating the connection. 5284 * 5285 * The user is only read by servers from clients; clients can't usually 5286 * get the user of servers, because servers do not authenticate to 5287 * clients. The returned user is the user the connection authenticated 5288 * as. 5289 * 5290 * The message bus is a server and the apps connecting to the bus 5291 * are clients. 5292 * 5293 * The returned user string has to be freed with dbus_free(). 5294 * 5295 * The return value indicates whether the user SID is available; 5296 * if it's available but we don't have the memory to copy it, 5297 * then the return value is #TRUE and #NULL is given as the SID. 5298 * 5299 * @todo We would like to be able to say "You can ask the bus to tell 5300 * you the user of another connection though if you like; this is done 5301 * with dbus_bus_get_windows_user()." But this has to be implemented 5302 * in bus/driver.c and dbus/dbus-bus.c, and is pointless anyway 5303 * since on Windows we only use the session bus for now. 5304 * 5305 * @param connection the connection 5306 * @param windows_sid_p return location for an allocated copy of the user ID, or #NULL if no memory 5307 * @returns #TRUE if user is available (returned value may be #NULL anyway if no memory) 5308 */ 5309dbus_bool_t 5310dbus_connection_get_windows_user (DBusConnection *connection, 5311 char **windows_sid_p) 5312{ 5313 dbus_bool_t result; 5314 5315 _dbus_return_val_if_fail (connection != NULL, FALSE); 5316 _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE); 5317 5318 CONNECTION_LOCK (connection); 5319 5320 if (!_dbus_transport_get_is_authenticated (connection->transport)) 5321 result = FALSE; 5322 else 5323 result = _dbus_transport_get_windows_user (connection->transport, 5324 windows_sid_p); 5325 5326#ifdef DBUS_UNIX 5327 _dbus_assert (!result); 5328#endif 5329 5330 CONNECTION_UNLOCK (connection); 5331 5332 return result; 5333} 5334 5335/** 5336 * Sets a predicate function used to determine whether a given user ID 5337 * is allowed to connect. When an incoming connection has 5338 * authenticated with a particular user ID, this function is called; 5339 * if it returns #TRUE, the connection is allowed to proceed, 5340 * otherwise the connection is disconnected. 5341 * 5342 * If the function is set to #NULL (as it is by default), then 5343 * only the same user owning the server process will be allowed to 5344 * connect. 5345 * 5346 * On UNIX, the function will be set and its free_data_function will 5347 * be invoked when the connection is freed or a new function is set. 5348 * However, the function will never be called, because there is no 5349 * way right now to authenticate as a Windows user on UNIX. 5350 * 5351 * @param connection the connection 5352 * @param function the predicate 5353 * @param data data to pass to the predicate 5354 * @param free_data_function function to free the data 5355 */ 5356void 5357dbus_connection_set_windows_user_function (DBusConnection *connection, 5358 DBusAllowWindowsUserFunction function, 5359 void *data, 5360 DBusFreeFunction free_data_function) 5361{ 5362 void *old_data = NULL; 5363 DBusFreeFunction old_free_function = NULL; 5364 5365 _dbus_return_if_fail (connection != NULL); 5366 5367 CONNECTION_LOCK (connection); 5368 _dbus_transport_set_windows_user_function (connection->transport, 5369 function, data, free_data_function, 5370 &old_data, &old_free_function); 5371 CONNECTION_UNLOCK (connection); 5372 5373 if (old_free_function != NULL) 5374 (* old_free_function) (old_data); 5375} 5376 5377/** 5378 * This function must be called on the server side of a connection when the 5379 * connection is first seen in the #DBusNewConnectionFunction. If set to 5380 * #TRUE (the default is #FALSE), then the connection can proceed even if 5381 * the client does not authenticate as some user identity, i.e. clients 5382 * can connect anonymously. 5383 * 5384 * This setting interacts with the available authorization mechanisms 5385 * (see dbus_server_set_auth_mechanisms()). Namely, an auth mechanism 5386 * such as ANONYMOUS that supports anonymous auth must be included in 5387 * the list of available mechanisms for anonymous login to work. 5388 * 5389 * This setting also changes the default rule for connections 5390 * authorized as a user; normally, if a connection authorizes as 5391 * a user identity, it is permitted if the user identity is 5392 * root or the user identity matches the user identity of the server 5393 * process. If anonymous connections are allowed, however, 5394 * then any user identity is allowed. 5395 * 5396 * You can override the rules for connections authorized as a 5397 * user identity with dbus_connection_set_unix_user_function() 5398 * and dbus_connection_set_windows_user_function(). 5399 * 5400 * @param connection the connection 5401 * @param value whether to allow authentication as an anonymous user 5402 */ 5403void 5404dbus_connection_set_allow_anonymous (DBusConnection *connection, 5405 dbus_bool_t value) 5406{ 5407 _dbus_return_if_fail (connection != NULL); 5408 5409 CONNECTION_LOCK (connection); 5410 _dbus_transport_set_allow_anonymous (connection->transport, value); 5411 CONNECTION_UNLOCK (connection); 5412} 5413 5414/** 5415 * 5416 * Normally #DBusConnection automatically handles all messages to the 5417 * org.freedesktop.DBus.Peer interface. However, the message bus wants 5418 * to be able to route methods on that interface through the bus and 5419 * to other applications. If routing peer messages is enabled, then 5420 * messages with the org.freedesktop.DBus.Peer interface that also 5421 * have a bus destination name set will not be automatically 5422 * handled by the #DBusConnection and instead will be dispatched 5423 * normally to the application. 5424 * 5425 * If a normal application sets this flag, it can break things badly. 5426 * So don't set this unless you are the message bus. 5427 * 5428 * @param connection the connection 5429 * @param value #TRUE to pass through org.freedesktop.DBus.Peer messages with a bus name set 5430 */ 5431void 5432dbus_connection_set_route_peer_messages (DBusConnection *connection, 5433 dbus_bool_t value) 5434{ 5435 _dbus_return_if_fail (connection != NULL); 5436 5437 CONNECTION_LOCK (connection); 5438 connection->route_peer_messages = TRUE; 5439 CONNECTION_UNLOCK (connection); 5440} 5441 5442/** 5443 * Adds a message filter. Filters are handlers that are run on all 5444 * incoming messages, prior to the objects registered with 5445 * dbus_connection_register_object_path(). Filters are run in the 5446 * order that they were added. The same handler can be added as a 5447 * filter more than once, in which case it will be run more than once. 5448 * Filters added during a filter callback won't be run on the message 5449 * being processed. 5450 * 5451 * @todo we don't run filters on messages while blocking without 5452 * entering the main loop, since filters are run as part of 5453 * dbus_connection_dispatch(). This is probably a feature, as filters 5454 * could create arbitrary reentrancy. But kind of sucks if you're 5455 * trying to filter METHOD_RETURN for some reason. 5456 * 5457 * @param connection the connection 5458 * @param function function to handle messages 5459 * @param user_data user data to pass to the function 5460 * @param free_data_function function to use for freeing user data 5461 * @returns #TRUE on success, #FALSE if not enough memory. 5462 */ 5463dbus_bool_t 5464dbus_connection_add_filter (DBusConnection *connection, 5465 DBusHandleMessageFunction function, 5466 void *user_data, 5467 DBusFreeFunction free_data_function) 5468{ 5469 DBusMessageFilter *filter; 5470 5471 _dbus_return_val_if_fail (connection != NULL, FALSE); 5472 _dbus_return_val_if_fail (function != NULL, FALSE); 5473 5474 filter = dbus_new0 (DBusMessageFilter, 1); 5475 if (filter == NULL) 5476 return FALSE; 5477 5478 _dbus_atomic_inc (&filter->refcount); 5479 5480 CONNECTION_LOCK (connection); 5481 5482 if (!_dbus_list_append (&connection->filter_list, 5483 filter)) 5484 { 5485 _dbus_message_filter_unref (filter); 5486 CONNECTION_UNLOCK (connection); 5487 return FALSE; 5488 } 5489 5490 /* Fill in filter after all memory allocated, 5491 * so we don't run the free_user_data_function 5492 * if the add_filter() fails 5493 */ 5494 5495 filter->function = function; 5496 filter->user_data = user_data; 5497 filter->free_user_data_function = free_data_function; 5498 5499 CONNECTION_UNLOCK (connection); 5500 return TRUE; 5501} 5502 5503/** 5504 * Removes a previously-added message filter. It is a programming 5505 * error to call this function for a handler that has not been added 5506 * as a filter. If the given handler was added more than once, only 5507 * one instance of it will be removed (the most recently-added 5508 * instance). 5509 * 5510 * @param connection the connection 5511 * @param function the handler to remove 5512 * @param user_data user data for the handler to remove 5513 * 5514 */ 5515void 5516dbus_connection_remove_filter (DBusConnection *connection, 5517 DBusHandleMessageFunction function, 5518 void *user_data) 5519{ 5520 DBusList *link; 5521 DBusMessageFilter *filter; 5522 5523 _dbus_return_if_fail (connection != NULL); 5524 _dbus_return_if_fail (function != NULL); 5525 5526 CONNECTION_LOCK (connection); 5527 5528 filter = NULL; 5529 5530 link = _dbus_list_get_last_link (&connection->filter_list); 5531 while (link != NULL) 5532 { 5533 filter = link->data; 5534 5535 if (filter->function == function && 5536 filter->user_data == user_data) 5537 { 5538 _dbus_list_remove_link (&connection->filter_list, link); 5539 filter->function = NULL; 5540 5541 break; 5542 } 5543 5544 link = _dbus_list_get_prev_link (&connection->filter_list, link); 5545 filter = NULL; 5546 } 5547 5548 CONNECTION_UNLOCK (connection); 5549 5550#ifndef DBUS_DISABLE_CHECKS 5551 if (filter == NULL) 5552 { 5553 _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n", 5554 function, user_data); 5555 return; 5556 } 5557#endif 5558 5559 /* Call application code */ 5560 if (filter->free_user_data_function) 5561 (* filter->free_user_data_function) (filter->user_data); 5562 5563 filter->free_user_data_function = NULL; 5564 filter->user_data = NULL; 5565 5566 _dbus_message_filter_unref (filter); 5567} 5568 5569/** 5570 * Registers a handler for a given path or subsection in the object 5571 * hierarchy. The given vtable handles messages sent to exactly the 5572 * given path or also for paths bellow that, depending on fallback 5573 * parameter. 5574 * 5575 * @param connection the connection 5576 * @param fallback whether to handle messages also for "subdirectory" 5577 * @param path a '/' delimited string of path elements 5578 * @param vtable the virtual table 5579 * @param user_data data to pass to functions in the vtable 5580 * @param error address where an error can be returned 5581 * @returns #FALSE if an error (#DBUS_ERROR_NO_MEMORY or 5582 * #DBUS_ERROR_OBJECT_PATH_IN_USE) is reported 5583 */ 5584static dbus_bool_t 5585_dbus_connection_register_object_path (DBusConnection *connection, 5586 dbus_bool_t fallback, 5587 const char *path, 5588 const DBusObjectPathVTable *vtable, 5589 void *user_data, 5590 DBusError *error) 5591{ 5592 char **decomposed_path; 5593 dbus_bool_t retval; 5594 5595 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) 5596 return FALSE; 5597 5598 CONNECTION_LOCK (connection); 5599 5600 retval = _dbus_object_tree_register (connection->objects, 5601 fallback, 5602 (const char **) decomposed_path, vtable, 5603 user_data, error); 5604 5605 CONNECTION_UNLOCK (connection); 5606 5607 dbus_free_string_array (decomposed_path); 5608 5609 return retval; 5610} 5611 5612/** 5613 * Registers a handler for a given path in the object hierarchy. 5614 * The given vtable handles messages sent to exactly the given path. 5615 * 5616 * @param connection the connection 5617 * @param path a '/' delimited string of path elements 5618 * @param vtable the virtual table 5619 * @param user_data data to pass to functions in the vtable 5620 * @param error address where an error can be returned 5621 * @returns #FALSE if an error (#DBUS_ERROR_NO_MEMORY or 5622 * #DBUS_ERROR_OBJECT_PATH_IN_USE) is reported 5623 */ 5624dbus_bool_t 5625dbus_connection_try_register_object_path (DBusConnection *connection, 5626 const char *path, 5627 const DBusObjectPathVTable *vtable, 5628 void *user_data, 5629 DBusError *error) 5630{ 5631 _dbus_return_val_if_fail (connection != NULL, FALSE); 5632 _dbus_return_val_if_fail (path != NULL, FALSE); 5633 _dbus_return_val_if_fail (path[0] == '/', FALSE); 5634 _dbus_return_val_if_fail (vtable != NULL, FALSE); 5635 5636 return _dbus_connection_register_object_path (connection, FALSE, path, vtable, user_data, error); 5637} 5638 5639/** 5640 * Registers a handler for a given path in the object hierarchy. 5641 * The given vtable handles messages sent to exactly the given path. 5642 * 5643 * It is a bug to call this function for object paths which already 5644 * have a handler. Use dbus_connection_try_register_object_path() if this 5645 * might be the case. 5646 * 5647 * @param connection the connection 5648 * @param path a '/' delimited string of path elements 5649 * @param vtable the virtual table 5650 * @param user_data data to pass to functions in the vtable 5651 * @returns #FALSE if an error (#DBUS_ERROR_NO_MEMORY or 5652 * #DBUS_ERROR_OBJECT_PATH_IN_USE) ocurred 5653 */ 5654dbus_bool_t 5655dbus_connection_register_object_path (DBusConnection *connection, 5656 const char *path, 5657 const DBusObjectPathVTable *vtable, 5658 void *user_data) 5659{ 5660 dbus_bool_t retval; 5661 DBusError error = DBUS_ERROR_INIT; 5662 5663 _dbus_return_val_if_fail (connection != NULL, FALSE); 5664 _dbus_return_val_if_fail (path != NULL, FALSE); 5665 _dbus_return_val_if_fail (path[0] == '/', FALSE); 5666 _dbus_return_val_if_fail (vtable != NULL, FALSE); 5667 5668 retval = _dbus_connection_register_object_path (connection, FALSE, path, vtable, user_data, &error); 5669 5670 if (dbus_error_has_name (&error, DBUS_ERROR_OBJECT_PATH_IN_USE)) 5671 { 5672 _dbus_warn ("%s\n", error.message); 5673 dbus_error_free (&error); 5674 return FALSE; 5675 } 5676 5677 return retval; 5678} 5679 5680/** 5681 * Registers a fallback handler for a given subsection of the object 5682 * hierarchy. The given vtable handles messages at or below the given 5683 * path. You can use this to establish a default message handling 5684 * policy for a whole "subdirectory." 5685 * 5686 * @param connection the connection 5687 * @param path a '/' delimited string of path elements 5688 * @param vtable the virtual table 5689 * @param user_data data to pass to functions in the vtable 5690 * @param error address where an error can be returned 5691 * @returns #FALSE if an error (#DBUS_ERROR_NO_MEMORY or 5692 * #DBUS_ERROR_OBJECT_PATH_IN_USE) is reported 5693 */ 5694dbus_bool_t 5695dbus_connection_try_register_fallback (DBusConnection *connection, 5696 const char *path, 5697 const DBusObjectPathVTable *vtable, 5698 void *user_data, 5699 DBusError *error) 5700{ 5701 _dbus_return_val_if_fail (connection != NULL, FALSE); 5702 _dbus_return_val_if_fail (path != NULL, FALSE); 5703 _dbus_return_val_if_fail (path[0] == '/', FALSE); 5704 _dbus_return_val_if_fail (vtable != NULL, FALSE); 5705 5706 return _dbus_connection_register_object_path (connection, TRUE, path, vtable, user_data, error); 5707} 5708 5709/** 5710 * Registers a fallback handler for a given subsection of the object 5711 * hierarchy. The given vtable handles messages at or below the given 5712 * path. You can use this to establish a default message handling 5713 * policy for a whole "subdirectory." 5714 * 5715 * It is a bug to call this function for object paths which already 5716 * have a handler. Use dbus_connection_try_register_fallback() if this 5717 * might be the case. 5718 * 5719 * @param connection the connection 5720 * @param path a '/' delimited string of path elements 5721 * @param vtable the virtual table 5722 * @param user_data data to pass to functions in the vtable 5723 * @returns #FALSE if an error (#DBUS_ERROR_NO_MEMORY or 5724 * #DBUS_ERROR_OBJECT_PATH_IN_USE) occured 5725 */ 5726dbus_bool_t 5727dbus_connection_register_fallback (DBusConnection *connection, 5728 const char *path, 5729 const DBusObjectPathVTable *vtable, 5730 void *user_data) 5731{ 5732 dbus_bool_t retval; 5733 DBusError error = DBUS_ERROR_INIT; 5734 5735 _dbus_return_val_if_fail (connection != NULL, FALSE); 5736 _dbus_return_val_if_fail (path != NULL, FALSE); 5737 _dbus_return_val_if_fail (path[0] == '/', FALSE); 5738 _dbus_return_val_if_fail (vtable != NULL, FALSE); 5739 5740 retval = _dbus_connection_register_object_path (connection, TRUE, path, vtable, user_data, &error); 5741 5742 if (dbus_error_has_name (&error, DBUS_ERROR_OBJECT_PATH_IN_USE)) 5743 { 5744 _dbus_warn ("%s\n", error.message); 5745 dbus_error_free (&error); 5746 return FALSE; 5747 } 5748 5749 return retval; 5750} 5751 5752/** 5753 * Unregisters the handler registered with exactly the given path. 5754 * It's a bug to call this function for a path that isn't registered. 5755 * Can unregister both fallback paths and object paths. 5756 * 5757 * @param connection the connection 5758 * @param path a '/' delimited string of path elements 5759 * @returns #FALSE if not enough memory 5760 */ 5761dbus_bool_t 5762dbus_connection_unregister_object_path (DBusConnection *connection, 5763 const char *path) 5764{ 5765 char **decomposed_path; 5766 5767 _dbus_return_val_if_fail (connection != NULL, FALSE); 5768 _dbus_return_val_if_fail (path != NULL, FALSE); 5769 _dbus_return_val_if_fail (path[0] == '/', FALSE); 5770 5771 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) 5772 return FALSE; 5773 5774 CONNECTION_LOCK (connection); 5775 5776 _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path); 5777 5778 dbus_free_string_array (decomposed_path); 5779 5780 return TRUE; 5781} 5782 5783/** 5784 * Gets the user data passed to dbus_connection_register_object_path() 5785 * or dbus_connection_register_fallback(). If nothing was registered 5786 * at this path, the data is filled in with #NULL. 5787 * 5788 * @param connection the connection 5789 * @param path the path you registered with 5790 * @param data_p location to store the user data, or #NULL 5791 * @returns #FALSE if not enough memory 5792 */ 5793dbus_bool_t 5794dbus_connection_get_object_path_data (DBusConnection *connection, 5795 const char *path, 5796 void **data_p) 5797{ 5798 char **decomposed_path; 5799 5800 _dbus_return_val_if_fail (connection != NULL, FALSE); 5801 _dbus_return_val_if_fail (path != NULL, FALSE); 5802 _dbus_return_val_if_fail (data_p != NULL, FALSE); 5803 5804 *data_p = NULL; 5805 5806 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL)) 5807 return FALSE; 5808 5809 CONNECTION_LOCK (connection); 5810 5811 *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path); 5812 5813 CONNECTION_UNLOCK (connection); 5814 5815 dbus_free_string_array (decomposed_path); 5816 5817 return TRUE; 5818} 5819 5820/** 5821 * Lists the registered fallback handlers and object path handlers at 5822 * the given parent_path. The returned array should be freed with 5823 * dbus_free_string_array(). 5824 * 5825 * @param connection the connection 5826 * @param parent_path the path to list the child handlers of 5827 * @param child_entries returns #NULL-terminated array of children 5828 * @returns #FALSE if no memory to allocate the child entries 5829 */ 5830dbus_bool_t 5831dbus_connection_list_registered (DBusConnection *connection, 5832 const char *parent_path, 5833 char ***child_entries) 5834{ 5835 char **decomposed_path; 5836 dbus_bool_t retval; 5837 _dbus_return_val_if_fail (connection != NULL, FALSE); 5838 _dbus_return_val_if_fail (parent_path != NULL, FALSE); 5839 _dbus_return_val_if_fail (parent_path[0] == '/', FALSE); 5840 _dbus_return_val_if_fail (child_entries != NULL, FALSE); 5841 5842 if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL)) 5843 return FALSE; 5844 5845 CONNECTION_LOCK (connection); 5846 5847 retval = _dbus_object_tree_list_registered_and_unlock (connection->objects, 5848 (const char **) decomposed_path, 5849 child_entries); 5850 dbus_free_string_array (decomposed_path); 5851 5852 return retval; 5853} 5854 5855static DBusDataSlotAllocator slot_allocator; 5856_DBUS_DEFINE_GLOBAL_LOCK (connection_slots); 5857 5858/** 5859 * Allocates an integer ID to be used for storing application-specific 5860 * data on any DBusConnection. The allocated ID may then be used 5861 * with dbus_connection_set_data() and dbus_connection_get_data(). 5862 * The passed-in slot must be initialized to -1, and is filled in 5863 * with the slot ID. If the passed-in slot is not -1, it's assumed 5864 * to be already allocated, and its refcount is incremented. 5865 * 5866 * The allocated slot is global, i.e. all DBusConnection objects will 5867 * have a slot with the given integer ID reserved. 5868 * 5869 * @param slot_p address of a global variable storing the slot 5870 * @returns #FALSE on failure (no memory) 5871 */ 5872dbus_bool_t 5873dbus_connection_allocate_data_slot (dbus_int32_t *slot_p) 5874{ 5875 return _dbus_data_slot_allocator_alloc (&slot_allocator, 5876 &_DBUS_LOCK_NAME (connection_slots), 5877 slot_p); 5878} 5879 5880/** 5881 * Deallocates a global ID for connection data slots. 5882 * dbus_connection_get_data() and dbus_connection_set_data() may no 5883 * longer be used with this slot. Existing data stored on existing 5884 * DBusConnection objects will be freed when the connection is 5885 * finalized, but may not be retrieved (and may only be replaced if 5886 * someone else reallocates the slot). When the refcount on the 5887 * passed-in slot reaches 0, it is set to -1. 5888 * 5889 * @param slot_p address storing the slot to deallocate 5890 */ 5891void 5892dbus_connection_free_data_slot (dbus_int32_t *slot_p) 5893{ 5894 _dbus_return_if_fail (*slot_p >= 0); 5895 5896 _dbus_data_slot_allocator_free (&slot_allocator, slot_p); 5897} 5898 5899/** 5900 * Stores a pointer on a DBusConnection, along 5901 * with an optional function to be used for freeing 5902 * the data when the data is set again, or when 5903 * the connection is finalized. The slot number 5904 * must have been allocated with dbus_connection_allocate_data_slot(). 5905 * 5906 * @note This function does not take the 5907 * main thread lock on DBusConnection, which allows it to be 5908 * used from inside watch and timeout functions. (See the 5909 * note in docs for dbus_connection_set_watch_functions().) 5910 * A side effect of this is that you need to know there's 5911 * a reference held on the connection while invoking 5912 * dbus_connection_set_data(), or the connection could be 5913 * finalized during dbus_connection_set_data(). 5914 * 5915 * @param connection the connection 5916 * @param slot the slot number 5917 * @param data the data to store 5918 * @param free_data_func finalizer function for the data 5919 * @returns #TRUE if there was enough memory to store the data 5920 */ 5921dbus_bool_t 5922dbus_connection_set_data (DBusConnection *connection, 5923 dbus_int32_t slot, 5924 void *data, 5925 DBusFreeFunction free_data_func) 5926{ 5927 DBusFreeFunction old_free_func; 5928 void *old_data; 5929 dbus_bool_t retval; 5930 5931 _dbus_return_val_if_fail (connection != NULL, FALSE); 5932 _dbus_return_val_if_fail (slot >= 0, FALSE); 5933 5934 SLOTS_LOCK (connection); 5935 5936 retval = _dbus_data_slot_list_set (&slot_allocator, 5937 &connection->slot_list, 5938 slot, data, free_data_func, 5939 &old_free_func, &old_data); 5940 5941 SLOTS_UNLOCK (connection); 5942 5943 if (retval) 5944 { 5945 /* Do the actual free outside the connection lock */ 5946 if (old_free_func) 5947 (* old_free_func) (old_data); 5948 } 5949 5950 return retval; 5951} 5952 5953/** 5954 * Retrieves data previously set with dbus_connection_set_data(). 5955 * The slot must still be allocated (must not have been freed). 5956 * 5957 * @note This function does not take the 5958 * main thread lock on DBusConnection, which allows it to be 5959 * used from inside watch and timeout functions. (See the 5960 * note in docs for dbus_connection_set_watch_functions().) 5961 * A side effect of this is that you need to know there's 5962 * a reference held on the connection while invoking 5963 * dbus_connection_get_data(), or the connection could be 5964 * finalized during dbus_connection_get_data(). 5965 * 5966 * @param connection the connection 5967 * @param slot the slot to get data from 5968 * @returns the data, or #NULL if not found 5969 */ 5970void* 5971dbus_connection_get_data (DBusConnection *connection, 5972 dbus_int32_t slot) 5973{ 5974 void *res; 5975 5976 _dbus_return_val_if_fail (connection != NULL, NULL); 5977 5978 SLOTS_LOCK (connection); 5979 5980 res = _dbus_data_slot_list_get (&slot_allocator, 5981 &connection->slot_list, 5982 slot); 5983 5984 SLOTS_UNLOCK (connection); 5985 5986 return res; 5987} 5988 5989/** 5990 * This function sets a global flag for whether dbus_connection_new() 5991 * will set SIGPIPE behavior to SIG_IGN. 5992 * 5993 * @param will_modify_sigpipe #TRUE to allow sigpipe to be set to SIG_IGN 5994 */ 5995void 5996dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe) 5997{ 5998 _dbus_modify_sigpipe = will_modify_sigpipe != FALSE; 5999} 6000 6001/** 6002 * Specifies the maximum size message this connection is allowed to 6003 * receive. Larger messages will result in disconnecting the 6004 * connection. 6005 * 6006 * @param connection a #DBusConnection 6007 * @param size maximum message size the connection can receive, in bytes 6008 */ 6009void 6010dbus_connection_set_max_message_size (DBusConnection *connection, 6011 long size) 6012{ 6013 _dbus_return_if_fail (connection != NULL); 6014 6015 CONNECTION_LOCK (connection); 6016 _dbus_transport_set_max_message_size (connection->transport, 6017 size); 6018 CONNECTION_UNLOCK (connection); 6019} 6020 6021/** 6022 * Gets the value set by dbus_connection_set_max_message_size(). 6023 * 6024 * @param connection the connection 6025 * @returns the max size of a single message 6026 */ 6027long 6028dbus_connection_get_max_message_size (DBusConnection *connection) 6029{ 6030 long res; 6031 6032 _dbus_return_val_if_fail (connection != NULL, 0); 6033 6034 CONNECTION_LOCK (connection); 6035 res = _dbus_transport_get_max_message_size (connection->transport); 6036 CONNECTION_UNLOCK (connection); 6037 return res; 6038} 6039 6040/** 6041 * Specifies the maximum number of unix fds a message on this 6042 * connection is allowed to receive. Messages with more unix fds will 6043 * result in disconnecting the connection. 6044 * 6045 * @param connection a #DBusConnection 6046 * @param size maximum message unix fds the connection can receive 6047 */ 6048void 6049dbus_connection_set_max_message_unix_fds (DBusConnection *connection, 6050 long n) 6051{ 6052 _dbus_return_if_fail (connection != NULL); 6053 6054 CONNECTION_LOCK (connection); 6055 _dbus_transport_set_max_message_unix_fds (connection->transport, 6056 n); 6057 CONNECTION_UNLOCK (connection); 6058} 6059 6060/** 6061 * Gets the value set by dbus_connection_set_max_message_unix_fds(). 6062 * 6063 * @param connection the connection 6064 * @returns the max numer of unix fds of a single message 6065 */ 6066long 6067dbus_connection_get_max_message_unix_fds (DBusConnection *connection) 6068{ 6069 long res; 6070 6071 _dbus_return_val_if_fail (connection != NULL, 0); 6072 6073 CONNECTION_LOCK (connection); 6074 res = _dbus_transport_get_max_message_unix_fds (connection->transport); 6075 CONNECTION_UNLOCK (connection); 6076 return res; 6077} 6078 6079/** 6080 * Sets the maximum total number of bytes that can be used for all messages 6081 * received on this connection. Messages count toward the maximum until 6082 * they are finalized. When the maximum is reached, the connection will 6083 * not read more data until some messages are finalized. 6084 * 6085 * The semantics of the maximum are: if outstanding messages are 6086 * already above the maximum, additional messages will not be read. 6087 * The semantics are not: if the next message would cause us to exceed 6088 * the maximum, we don't read it. The reason is that we don't know the 6089 * size of a message until after we read it. 6090 * 6091 * Thus, the max live messages size can actually be exceeded 6092 * by up to the maximum size of a single message. 6093 * 6094 * Also, if we read say 1024 bytes off the wire in a single read(), 6095 * and that contains a half-dozen small messages, we may exceed the 6096 * size max by that amount. But this should be inconsequential. 6097 * 6098 * This does imply that we can't call read() with a buffer larger 6099 * than we're willing to exceed this limit by. 6100 * 6101 * @param connection the connection 6102 * @param size the maximum size in bytes of all outstanding messages 6103 */ 6104void 6105dbus_connection_set_max_received_size (DBusConnection *connection, 6106 long size) 6107{ 6108 _dbus_return_if_fail (connection != NULL); 6109 6110 CONNECTION_LOCK (connection); 6111 _dbus_transport_set_max_received_size (connection->transport, 6112 size); 6113 CONNECTION_UNLOCK (connection); 6114} 6115 6116/** 6117 * Gets the value set by dbus_connection_set_max_received_size(). 6118 * 6119 * @param connection the connection 6120 * @returns the max size of all live messages 6121 */ 6122long 6123dbus_connection_get_max_received_size (DBusConnection *connection) 6124{ 6125 long res; 6126 6127 _dbus_return_val_if_fail (connection != NULL, 0); 6128 6129 CONNECTION_LOCK (connection); 6130 res = _dbus_transport_get_max_received_size (connection->transport); 6131 CONNECTION_UNLOCK (connection); 6132 return res; 6133} 6134 6135/** 6136 * Sets the maximum total number of unix fds that can be used for all messages 6137 * received on this connection. Messages count toward the maximum until 6138 * they are finalized. When the maximum is reached, the connection will 6139 * not read more data until some messages are finalized. 6140 * 6141 * The semantics are analogous to those of dbus_connection_set_max_received_size(). 6142 * 6143 * @param connection the connection 6144 * @param size the maximum size in bytes of all outstanding messages 6145 */ 6146void 6147dbus_connection_set_max_received_unix_fds (DBusConnection *connection, 6148 long n) 6149{ 6150 _dbus_return_if_fail (connection != NULL); 6151 6152 CONNECTION_LOCK (connection); 6153 _dbus_transport_set_max_received_unix_fds (connection->transport, 6154 n); 6155 CONNECTION_UNLOCK (connection); 6156} 6157 6158/** 6159 * Gets the value set by dbus_connection_set_max_received_unix_fds(). 6160 * 6161 * @param connection the connection 6162 * @returns the max unix fds of all live messages 6163 */ 6164long 6165dbus_connection_get_max_received_unix_fds (DBusConnection *connection) 6166{ 6167 long res; 6168 6169 _dbus_return_val_if_fail (connection != NULL, 0); 6170 6171 CONNECTION_LOCK (connection); 6172 res = _dbus_transport_get_max_received_unix_fds (connection->transport); 6173 CONNECTION_UNLOCK (connection); 6174 return res; 6175} 6176 6177/** 6178 * Gets the approximate size in bytes of all messages in the outgoing 6179 * message queue. The size is approximate in that you shouldn't use 6180 * it to decide how many bytes to read off the network or anything 6181 * of that nature, as optimizations may choose to tell small white lies 6182 * to avoid performance overhead. 6183 * 6184 * @param connection the connection 6185 * @returns the number of bytes that have been queued up but not sent 6186 */ 6187long 6188dbus_connection_get_outgoing_size (DBusConnection *connection) 6189{ 6190 long res; 6191 6192 _dbus_return_val_if_fail (connection != NULL, 0); 6193 6194 CONNECTION_LOCK (connection); 6195 res = _dbus_counter_get_size_value (connection->outgoing_counter); 6196 CONNECTION_UNLOCK (connection); 6197 return res; 6198} 6199 6200#ifdef DBUS_ENABLE_STATS 6201void 6202_dbus_connection_get_stats (DBusConnection *connection, 6203 dbus_uint32_t *in_messages, 6204 dbus_uint32_t *in_bytes, 6205 dbus_uint32_t *in_fds, 6206 dbus_uint32_t *in_peak_bytes, 6207 dbus_uint32_t *in_peak_fds, 6208 dbus_uint32_t *out_messages, 6209 dbus_uint32_t *out_bytes, 6210 dbus_uint32_t *out_fds, 6211 dbus_uint32_t *out_peak_bytes, 6212 dbus_uint32_t *out_peak_fds) 6213{ 6214 CONNECTION_LOCK (connection); 6215 6216 if (in_messages != NULL) 6217 *in_messages = connection->n_incoming; 6218 6219 _dbus_transport_get_stats (connection->transport, 6220 in_bytes, in_fds, in_peak_bytes, in_peak_fds); 6221 6222 if (out_messages != NULL) 6223 *out_messages = connection->n_outgoing; 6224 6225 if (out_bytes != NULL) 6226 *out_bytes = _dbus_counter_get_size_value (connection->outgoing_counter); 6227 6228 if (out_fds != NULL) 6229 *out_fds = _dbus_counter_get_unix_fd_value (connection->outgoing_counter); 6230 6231 if (out_peak_bytes != NULL) 6232 *out_peak_bytes = _dbus_counter_get_peak_size_value (connection->outgoing_counter); 6233 6234 if (out_peak_fds != NULL) 6235 *out_peak_fds = _dbus_counter_get_peak_unix_fd_value (connection->outgoing_counter); 6236 6237 CONNECTION_UNLOCK (connection); 6238} 6239#endif /* DBUS_ENABLE_STATS */ 6240 6241/** 6242 * Gets the approximate number of uni fds of all messages in the 6243 * outgoing message queue. 6244 * 6245 * @param connection the connection 6246 * @returns the number of unix fds that have been queued up but not sent 6247 */ 6248long 6249dbus_connection_get_outgoing_unix_fds (DBusConnection *connection) 6250{ 6251 long res; 6252 6253 _dbus_return_val_if_fail (connection != NULL, 0); 6254 6255 CONNECTION_LOCK (connection); 6256 res = _dbus_counter_get_unix_fd_value (connection->outgoing_counter); 6257 CONNECTION_UNLOCK (connection); 6258 return res; 6259} 6260 6261#ifdef DBUS_BUILD_TESTS 6262/** 6263 * Returns the address of the transport object of this connection 6264 * 6265 * @param connection the connection 6266 * @returns the address string 6267 */ 6268const char* 6269_dbus_connection_get_address (DBusConnection *connection) 6270{ 6271 return _dbus_transport_get_address (connection->transport); 6272} 6273#endif 6274 6275/** @} */ 6276