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