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