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