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