D-Bus: dbus-connection.c Source File

D-Bus 1.10.18

dbus-connection.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-connection.c DBusConnection object
3 *
4 * Copyright (C) 2002-2006 Red Hat Inc.
5 *
6 * Licensed under the Academic Free License version 2.1
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 *
22 */
23
24 #include <config.h>
25 #include "dbus-shared.h"
26 #include "dbus-connection.h"
27 #include "dbus-list.h"
28 #include "dbus-timeout.h"
29 #include "dbus-transport.h"
30 #include "dbus-watch.h"
31 #include "dbus-connection-internal.h"
32 #include "dbus-pending-call-internal.h"
33 #include "dbus-list.h"
34 #include "dbus-hash.h"
35 #include "dbus-message-internal.h"
36 #include "dbus-message-private.h"
37 #include "dbus-threads.h"
38 #include "dbus-protocol.h"
39 #include "dbus-dataslot.h"
40 #include "dbus-string.h"
41 #include "dbus-signature.h"
42 #include "dbus-pending-call.h"
43 #include "dbus-object-tree.h"
44 #include "dbus-threads-internal.h"
45 #include "dbus-bus.h"
46 #include "dbus-marshal-basic.h"
47
48 #ifdef DBUS_DISABLE_CHECKS
49 #define TOOK_LOCK_CHECK(connection)
50 #define RELEASING_LOCK_CHECK(connection)
51 #define HAVE_LOCK_CHECK(connection)
52 #else
53 #define TOOK_LOCK_CHECK(connection) do { \
54 _dbus_assert (!(connection)->have_connection_lock); \
55 (connection)->have_connection_lock = TRUE; \
56 } while (0)
57 #define RELEASING_LOCK_CHECK(connection) do { \
58 _dbus_assert ((connection)->have_connection_lock); \
59 (connection)->have_connection_lock = FALSE; \
60 } while (0)
61 #define HAVE_LOCK_CHECK(connection) _dbus_assert ((connection)->have_connection_lock)
62 /* A "DO_NOT_HAVE_LOCK_CHECK" is impossible since we need the lock to check the flag */
63 #endif
64
65 #define TRACE_LOCKS 1
66
67 #define CONNECTION_LOCK(connection) do { \
68 if (TRACE_LOCKS) { _dbus_verbose ("LOCK\n"); } \
69 _dbus_rmutex_lock ((connection)->mutex); \
70 TOOK_LOCK_CHECK (connection); \
71 } while (0)
72
73 #define CONNECTION_UNLOCK(connection) _dbus_connection_unlock (connection)
74
75 #define SLOTS_LOCK(connection) do { \
76 _dbus_rmutex_lock ((connection)->slot_mutex); \
77 } while (0)
78
79 #define SLOTS_UNLOCK(connection) do { \
80 _dbus_rmutex_unlock ((connection)->slot_mutex); \
81 } while (0)
82
83 #define DISPATCH_STATUS_NAME(s) \
84 ((s) == DBUS_DISPATCH_COMPLETE ? "complete" : \
85 (s) == DBUS_DISPATCH_DATA_REMAINS ? "data remains" : \
86 (s) == DBUS_DISPATCH_NEED_MEMORY ? "need memory" : \
87 "???")
88
206 static void
207 _dbus_connection_trace_ref (DBusConnection *connection,
208 int old_refcount,
209 int new_refcount,
210 const char *why)
211 {
212 #ifdef DBUS_ENABLE_VERBOSE_MODE
213 static int enabled = -1;
214
215 _dbus_trace_ref ("DBusConnection", connection, old_refcount, new_refcount,
216 why, "DBUS_CONNECTION_TRACE", &enabled);
217 #endif
218 }
219
223 typedef struct DBusMessageFilter DBusMessageFilter;
224
228 struct DBusMessageFilter
229 {
230 DBusAtomic refcount;
231 DBusHandleMessageFunction function;
232 void *user_data;
233 DBusFreeFunction free_user_data_function;
234 };
235
236
240 struct DBusPreallocatedSend
241 {
242 DBusConnection *connection;
243 DBusList *queue_link;
244 DBusList *counter_link;
245 };
246
247 #if HAVE_DECL_MSG_NOSIGNAL
248 static dbus_bool_t _dbus_modify_sigpipe = FALSE;
249 #else
250 static dbus_bool_t _dbus_modify_sigpipe = TRUE;
251 #endif
252
256 struct DBusConnection
257 {
258 DBusAtomic refcount;
260 DBusRMutex *mutex;
262 DBusCMutex *dispatch_mutex;
263 DBusCondVar *dispatch_cond;
264 DBusCMutex *io_path_mutex;
265 DBusCondVar *io_path_cond;
267 DBusList *outgoing_messages;
268 DBusList *incoming_messages;
269 DBusList *expired_messages;
271 DBusMessage *message_borrowed;
275 int n_outgoing;
276 int n_incoming;
278 DBusCounter *outgoing_counter;
280 DBusTransport *transport;
281 DBusWatchList *watches;
282 DBusTimeoutList *timeouts;
284 DBusList *filter_list;
286 DBusRMutex *slot_mutex;
287 DBusDataSlotList slot_list;
289 DBusHashTable *pending_replies;
291 dbus_uint32_t client_serial;
292 DBusList *disconnect_message_link;
294 DBusWakeupMainFunction wakeup_main_function;
295 void *wakeup_main_data;
296 DBusFreeFunction free_wakeup_main_data;
298 DBusDispatchStatusFunction dispatch_status_function;
299 void *dispatch_status_data;
300 DBusFreeFunction free_dispatch_status_data;
302 DBusDispatchStatus last_dispatch_status;
304 DBusObjectTree *objects;
306 char *server_guid;
308 /* These two MUST be bools and not bitfields, because they are protected by a separate lock
309 * from connection->mutex and all bitfields in a word have to be read/written together.
310 * So you can't have a different lock for different bitfields in the same word.
311 */
312 dbus_bool_t dispatch_acquired;
313 dbus_bool_t io_path_acquired;
315 unsigned int shareable : 1;
317 unsigned int exit_on_disconnect : 1;
319 unsigned int route_peer_messages : 1;
321 unsigned int disconnected_message_arrived : 1;
325 unsigned int disconnected_message_processed : 1;
329 #ifndef DBUS_DISABLE_CHECKS
330 unsigned int have_connection_lock : 1;
331 #endif
332
333 #if defined(DBUS_ENABLE_CHECKS) || defined(DBUS_ENABLE_ASSERT)
334 int generation;
335 #endif
336 };
337
338 static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection);
339 static void _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
340 DBusDispatchStatus new_status);
341 static void _dbus_connection_last_unref (DBusConnection *connection);
342 static void _dbus_connection_acquire_dispatch (DBusConnection *connection);
343 static void _dbus_connection_release_dispatch (DBusConnection *connection);
344 static DBusDispatchStatus _dbus_connection_flush_unlocked (DBusConnection *connection);
345 static void _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection);
346 static dbus_bool_t _dbus_connection_get_is_connected_unlocked (DBusConnection *connection);
347 static dbus_bool_t _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection,
348 dbus_uint32_t client_serial);
349
350 static DBusMessageFilter *
351 _dbus_message_filter_ref (DBusMessageFilter *filter)
352 {
353 #ifdef DBUS_DISABLE_ASSERT
354 _dbus_atomic_inc (&filter->refcount);
355 #else
356 dbus_int32_t old_value;
357
358 old_value = _dbus_atomic_inc (&filter->refcount);
359 _dbus_assert (old_value > 0);
360 #endif
361
362 return filter;
363 }
364
365 static void
366 _dbus_message_filter_unref (DBusMessageFilter *filter)
367 {
368 dbus_int32_t old_value;
369
370 old_value = _dbus_atomic_dec (&filter->refcount);
371 _dbus_assert (old_value > 0);
372
373 if (old_value == 1)
374 {
375 if (filter->free_user_data_function)
376 (* filter->free_user_data_function) (filter->user_data);
377
378 dbus_free (filter);
379 }
380 }
381
387 void
388 _dbus_connection_lock (DBusConnection *connection)
389 {
390 CONNECTION_LOCK (connection);
391 }
392
398 void
399 _dbus_connection_unlock (DBusConnection *connection)
400 {
401 DBusList *expired_messages;
402 DBusList *iter;
403
404 if (TRACE_LOCKS)
405 {
406 _dbus_verbose ("UNLOCK\n");
407 }
408
409 /* If we had messages that expired (fell off the incoming or outgoing
410 * queues) while we were locked, actually release them now */
411 expired_messages = connection->expired_messages;
412 connection->expired_messages = NULL;
413
414 RELEASING_LOCK_CHECK (connection);
415 _dbus_rmutex_unlock (connection->mutex);
416
417 for (iter = _dbus_list_pop_first_link (&expired_messages);
418 iter != NULL;
419 iter = _dbus_list_pop_first_link (&expired_messages))
420 {
421 DBusMessage *message = iter->data;
422
423 dbus_message_unref (message);
424 _dbus_list_free_link (iter);
425 }
426 }
427
435 static void
436 _dbus_connection_wakeup_mainloop (DBusConnection *connection)
437 {
438 if (connection->wakeup_main_function)
439 (*connection->wakeup_main_function) (connection->wakeup_main_data);
440 }
441
442 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
443
455 void
456 _dbus_connection_test_get_locks (DBusConnection *connection,
457 DBusMutex **mutex_loc,
458 DBusMutex **dispatch_mutex_loc,
459 DBusMutex **io_path_mutex_loc,
460 DBusCondVar **dispatch_cond_loc,
461 DBusCondVar **io_path_cond_loc)
462 {
463 *mutex_loc = (DBusMutex *) connection->mutex;
464 *dispatch_mutex_loc = (DBusMutex *) connection->dispatch_mutex;
465 *io_path_mutex_loc = (DBusMutex *) connection->io_path_mutex;
466 *dispatch_cond_loc = connection->dispatch_cond;
467 *io_path_cond_loc = connection->io_path_cond;
468 }
469 #endif
470
479 void
480 _dbus_connection_queue_received_message_link (DBusConnection *connection,
481 DBusList *link)
482 {
483 DBusPendingCall *pending;
484 dbus_uint32_t reply_serial;
485 DBusMessage *message;
486
487 _dbus_assert (_dbus_transport_peek_is_authenticated (connection->transport));
488
489 _dbus_list_append_link (&connection->incoming_messages,
490 link);
491 message = link->data;
492
493 /* If this is a reply we're waiting on, remove timeout for it */
494 reply_serial = dbus_message_get_reply_serial (message);
495 if (reply_serial != 0)
496 {
497 pending = _dbus_hash_table_lookup_int (connection->pending_replies,
498 reply_serial);
499 if (pending != NULL)
500 {
501 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
502 _dbus_connection_remove_timeout_unlocked (connection,
503 _dbus_pending_call_get_timeout_unlocked (pending));
504
505 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
506 }
507 }
508
509
510
511 connection->n_incoming += 1;
512
513 _dbus_connection_wakeup_mainloop (connection);
514
515 _dbus_verbose ("Message %p (%s %s %s %s '%s' reply to %u) added to incoming queue %p, %d incoming\n",
516 message,
517 dbus_message_type_to_string (dbus_message_get_type (message)),
518 dbus_message_get_path (message) ?
519 dbus_message_get_path (message) :
520 "no path",
521 dbus_message_get_interface (message) ?
522 dbus_message_get_interface (message) :
523 "no interface",
524 dbus_message_get_member (message) ?
525 dbus_message_get_member (message) :
526 "no member",
527 dbus_message_get_signature (message),
528 dbus_message_get_reply_serial (message),
529 connection,
530 connection->n_incoming);
531
532 _dbus_message_trace_ref (message, -1, -1,
533 "_dbus_conection_queue_received_message_link");
534 }
535
544 void
545 _dbus_connection_queue_synthesized_message_link (DBusConnection *connection,
546 DBusList *link)
547 {
548 HAVE_LOCK_CHECK (connection);
549
550 _dbus_list_append_link (&connection->incoming_messages, link);
551
552 connection->n_incoming += 1;
553
554 _dbus_connection_wakeup_mainloop (connection);
555
556 _dbus_message_trace_ref (link->data, -1, -1,
557 "_dbus_connection_queue_synthesized_message_link");
558
559 _dbus_verbose ("Synthesized message %p added to incoming queue %p, %d incoming\n",
560 link->data, connection, connection->n_incoming);
561 }
562
563
571 dbus_bool_t
572 _dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection)
573 {
574 HAVE_LOCK_CHECK (connection);
575 return connection->outgoing_messages != NULL;
576 }
577
587 dbus_bool_t
588 dbus_connection_has_messages_to_send (DBusConnection *connection)
589 {
590 dbus_bool_t v;
591
592 _dbus_return_val_if_fail (connection != NULL, FALSE);
593
594 CONNECTION_LOCK (connection);
595 v = _dbus_connection_has_messages_to_send_unlocked (connection);
596 CONNECTION_UNLOCK (connection);
597
598 return v;
599 }
600
608 DBusMessage*
609 _dbus_connection_get_message_to_send (DBusConnection *connection)
610 {
611 HAVE_LOCK_CHECK (connection);
612
613 return _dbus_list_get_last (&connection->outgoing_messages);
614 }
615
624 void
625 _dbus_connection_message_sent_unlocked (DBusConnection *connection,
626 DBusMessage *message)
627 {
628 DBusList *link;
629
630 HAVE_LOCK_CHECK (connection);
631
632 /* This can be called before we even complete authentication, since
633 * it's called on disconnect to clean up the outgoing queue.
634 * It's also called as we successfully send each message.
635 */
636
637 link = _dbus_list_get_last_link (&connection->outgoing_messages);
638 _dbus_assert (link != NULL);
639 _dbus_assert (link->data == message);
640
641 _dbus_list_unlink (&connection->outgoing_messages,
642 link);
643 _dbus_list_prepend_link (&connection->expired_messages, link);
644
645 connection->n_outgoing -= 1;
646
647 _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from outgoing queue %p, %d left to send\n",
648 message,
649 dbus_message_type_to_string (dbus_message_get_type (message)),
650 dbus_message_get_path (message) ?
651 dbus_message_get_path (message) :
652 "no path",
653 dbus_message_get_interface (message) ?
654 dbus_message_get_interface (message) :
655 "no interface",
656 dbus_message_get_member (message) ?
657 dbus_message_get_member (message) :
658 "no member",
659 dbus_message_get_signature (message),
660 connection, connection->n_outgoing);
661
662 /* It's OK that in principle we call the notify function, because for the
663 * outgoing limit, there isn't one */
664 _dbus_message_remove_counter (message, connection->outgoing_counter);
665
666 /* The message will actually be unreffed when we unlock */
667 }
668
670 typedef dbus_bool_t (* DBusWatchAddFunction) (DBusWatchList *list,
671 DBusWatch *watch);
673 typedef void (* DBusWatchRemoveFunction) (DBusWatchList *list,
674 DBusWatch *watch);
676 typedef void (* DBusWatchToggleFunction) (DBusWatchList *list,
677 DBusWatch *watch,
678 dbus_bool_t enabled);
679
680 static dbus_bool_t
681 protected_change_watch (DBusConnection *connection,
682 DBusWatch *watch,
683 DBusWatchAddFunction add_function,
684 DBusWatchRemoveFunction remove_function,
685 DBusWatchToggleFunction toggle_function,
686 dbus_bool_t enabled)
687 {
688 dbus_bool_t retval;
689
690 HAVE_LOCK_CHECK (connection);
691
692 /* The original purpose of protected_change_watch() was to hold a
693 * ref on the connection while dropping the connection lock, then
694 * calling out to the app. This was a broken hack that did not
695 * work, since the connection was in a hosed state (no WatchList
696 * field) while calling out.
697 *
698 * So for now we'll just keep the lock while calling out. This means
699 * apps are not allowed to call DBusConnection methods inside a
700 * watch function or they will deadlock.
701 *
702 * The "real fix" is to use the _and_unlock() pattern found
703 * elsewhere in the code, to defer calling out to the app until
704 * we're about to drop locks and return flow of control to the app
705 * anyway.
706 *
707 * See http://lists.freedesktop.org/archives/dbus/2007-July/thread.html#8144
708 */
709
710 if (connection->watches)
711 {
712 if (add_function)
713 retval = (* add_function) (connection->watches, watch);
714 else if (remove_function)
715 {
716 retval = TRUE;
717 (* remove_function) (connection->watches, watch);
718 }
719 else
720 {
721 retval = TRUE;
722 (* toggle_function) (connection->watches, watch, enabled);
723 }
724 return retval;
725 }
726 else
727 return FALSE;
728 }
729
730
742 dbus_bool_t
743 _dbus_connection_add_watch_unlocked (DBusConnection *connection,
744 DBusWatch *watch)
745 {
746 return protected_change_watch (connection, watch,
747 _dbus_watch_list_add_watch,
748 NULL, NULL, FALSE);
749 }
750
760 void
761 _dbus_connection_remove_watch_unlocked (DBusConnection *connection,
762 DBusWatch *watch)
763 {
764 protected_change_watch (connection, watch,
765 NULL,
766 _dbus_watch_list_remove_watch,
767 NULL, FALSE);
768 }
769
780 void
781 _dbus_connection_toggle_watch_unlocked (DBusConnection *connection,
782 DBusWatch *watch,
783 dbus_bool_t enabled)
784 {
785 _dbus_assert (watch != NULL);
786
787 protected_change_watch (connection, watch,
788 NULL, NULL,
789 _dbus_watch_list_toggle_watch,
790 enabled);
791 }
792
794 typedef dbus_bool_t (* DBusTimeoutAddFunction) (DBusTimeoutList *list,
795 DBusTimeout *timeout);
797 typedef void (* DBusTimeoutRemoveFunction) (DBusTimeoutList *list,
798 DBusTimeout *timeout);
800 typedef void (* DBusTimeoutToggleFunction) (DBusTimeoutList *list,
801 DBusTimeout *timeout,
802 dbus_bool_t enabled);
803
804 static dbus_bool_t
805 protected_change_timeout (DBusConnection *connection,
806 DBusTimeout *timeout,
807 DBusTimeoutAddFunction add_function,
808 DBusTimeoutRemoveFunction remove_function,
809 DBusTimeoutToggleFunction toggle_function,
810 dbus_bool_t enabled)
811 {
812 dbus_bool_t retval;
813
814 HAVE_LOCK_CHECK (connection);
815
816 /* The original purpose of protected_change_timeout() was to hold a
817 * ref on the connection while dropping the connection lock, then
818 * calling out to the app. This was a broken hack that did not
819 * work, since the connection was in a hosed state (no TimeoutList
820 * field) while calling out.
821 *
822 * So for now we'll just keep the lock while calling out. This means
823 * apps are not allowed to call DBusConnection methods inside a
824 * timeout function or they will deadlock.
825 *
826 * The "real fix" is to use the _and_unlock() pattern found
827 * elsewhere in the code, to defer calling out to the app until
828 * we're about to drop locks and return flow of control to the app
829 * anyway.
830 *
831 * See http://lists.freedesktop.org/archives/dbus/2007-July/thread.html#8144
832 */
833
834 if (connection->timeouts)
835 {
836 if (add_function)
837 retval = (* add_function) (connection->timeouts, timeout);
838 else if (remove_function)
839 {
840 retval = TRUE;
841 (* remove_function) (connection->timeouts, timeout);
842 }
843 else
844 {
845 retval = TRUE;
846 (* toggle_function) (connection->timeouts, timeout, enabled);
847 }
848 return retval;
849 }
850 else
851 return FALSE;
852 }
853
866 dbus_bool_t
867 _dbus_connection_add_timeout_unlocked (DBusConnection *connection,
868 DBusTimeout *timeout)
869 {
870 return protected_change_timeout (connection, timeout,
871 _dbus_timeout_list_add_timeout,
872 NULL, NULL, FALSE);
873 }
874
884 void
885 _dbus_connection_remove_timeout_unlocked (DBusConnection *connection,
886 DBusTimeout *timeout)
887 {
888 protected_change_timeout (connection, timeout,
889 NULL,
890 _dbus_timeout_list_remove_timeout,
891 NULL, FALSE);
892 }
893
904 void
905 _dbus_connection_toggle_timeout_unlocked (DBusConnection *connection,
906 DBusTimeout *timeout,
907 dbus_bool_t enabled)
908 {
909 protected_change_timeout (connection, timeout,
910 NULL, NULL,
911 _dbus_timeout_list_toggle_timeout,
912 enabled);
913 }
914
915 static dbus_bool_t
916 _dbus_connection_attach_pending_call_unlocked (DBusConnection *connection,
917 DBusPendingCall *pending)
918 {
919 dbus_uint32_t reply_serial;
920 DBusTimeout *timeout;
921
922 HAVE_LOCK_CHECK (connection);
923
924 reply_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
925
926 _dbus_assert (reply_serial != 0);
927
928 timeout = _dbus_pending_call_get_timeout_unlocked (pending);
929
930 if (timeout)
931 {
932 if (!_dbus_connection_add_timeout_unlocked (connection, timeout))
933 return FALSE;
934
935 if (!_dbus_hash_table_insert_int (connection->pending_replies,
936 reply_serial,
937 pending))
938 {
939 _dbus_connection_remove_timeout_unlocked (connection, timeout);
940
941 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
942 HAVE_LOCK_CHECK (connection);
943 return FALSE;
944 }
945
946 _dbus_pending_call_set_timeout_added_unlocked (pending, TRUE);
947 }
948 else
949 {
950 if (!_dbus_hash_table_insert_int (connection->pending_replies,
951 reply_serial,
952 pending))
953 {
954 HAVE_LOCK_CHECK (connection);
955 return FALSE;
956 }
957 }
958
959 _dbus_pending_call_ref_unlocked (pending);
960
961 HAVE_LOCK_CHECK (connection);
962
963 return TRUE;
964 }
965
966 static void
967 free_pending_call_on_hash_removal (void *data)
968 {
969 DBusPendingCall *pending;
970 DBusConnection *connection;
971
972 if (data == NULL)
973 return;
974
975 pending = data;
976
977 connection = _dbus_pending_call_get_connection_unlocked (pending);
978
979 HAVE_LOCK_CHECK (connection);
980
981 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
982 {
983 _dbus_connection_remove_timeout_unlocked (connection,
984 _dbus_pending_call_get_timeout_unlocked (pending));
985
986 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
987 }
988
989 /* FIXME 1.0? this is sort of dangerous and undesirable to drop the lock
990 * here, but the pending call finalizer could in principle call out to
991 * application code so we pretty much have to... some larger code reorg
992 * might be needed.
993 */
994 _dbus_connection_ref_unlocked (connection);
995 _dbus_pending_call_unref_and_unlock (pending);
996 CONNECTION_LOCK (connection);
997 _dbus_connection_unref_unlocked (connection);
998 }
999
1000 static void
1001 _dbus_connection_detach_pending_call_unlocked (DBusConnection *connection,
1002 DBusPendingCall *pending)
1003 {
1004 /* This ends up unlocking to call the pending call finalizer, which is unexpected to
1005 * say the least.
1006 */
1007 _dbus_hash_table_remove_int (connection->pending_replies,
1008 _dbus_pending_call_get_reply_serial_unlocked (pending));
1009 }
1010
1011 static void
1012 _dbus_connection_detach_pending_call_and_unlock (DBusConnection *connection,
1013 DBusPendingCall *pending)
1014 {
1015 /* The idea here is to avoid finalizing the pending call
1016 * with the lock held, since there's a destroy notifier
1017 * in pending call that goes out to application code.
1018 *
1019 * There's an extra unlock inside the hash table
1020 * "free pending call" function FIXME...
1021 */
1022 _dbus_pending_call_ref_unlocked (pending);
1023 _dbus_hash_table_remove_int (connection->pending_replies,
1024 _dbus_pending_call_get_reply_serial_unlocked (pending));
1025
1026 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
1027 _dbus_connection_remove_timeout_unlocked (connection,
1028 _dbus_pending_call_get_timeout_unlocked (pending));
1029
1030 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
1031
1032 _dbus_pending_call_unref_and_unlock (pending);
1033 }
1034
1043 void
1044 _dbus_connection_remove_pending_call (DBusConnection *connection,
1045 DBusPendingCall *pending)
1046 {
1047 CONNECTION_LOCK (connection);
1048 _dbus_connection_detach_pending_call_and_unlock (connection, pending);
1049 }
1050
1060 static dbus_bool_t
1061 _dbus_connection_acquire_io_path (DBusConnection *connection,
1062 int timeout_milliseconds)
1063 {
1064 dbus_bool_t we_acquired;
1065
1066 HAVE_LOCK_CHECK (connection);
1067
1068 /* We don't want the connection to vanish */
1069 _dbus_connection_ref_unlocked (connection);
1070
1071 /* We will only touch io_path_acquired which is protected by our mutex */
1072 CONNECTION_UNLOCK (connection);
1073
1074 _dbus_verbose ("locking io_path_mutex\n");
1075 _dbus_cmutex_lock (connection->io_path_mutex);
1076
1077 _dbus_verbose ("start connection->io_path_acquired = %d timeout = %d\n",
1078 connection->io_path_acquired, timeout_milliseconds);
1079
1080 we_acquired = FALSE;
1081
1082 if (connection->io_path_acquired)
1083 {
1084 if (timeout_milliseconds != -1)
1085 {
1086 _dbus_verbose ("waiting %d for IO path to be acquirable\n",
1087 timeout_milliseconds);
1088
1089 if (!_dbus_condvar_wait_timeout (connection->io_path_cond,
1090 connection->io_path_mutex,
1091 timeout_milliseconds))
1092 {
1093 /* We timed out before anyone signaled. */
1094 /* (writing the loop to handle the !timedout case by
1095 * waiting longer if needed is a pain since dbus
1096 * wraps pthread_cond_timedwait to take a relative
1097 * time instead of absolute, something kind of stupid
1098 * on our part. for now it doesn't matter, we will just
1099 * end up back here eventually.)
1100 */
1101 }
1102 }
1103 else
1104 {
1105 while (connection->io_path_acquired)
1106 {
1107 _dbus_verbose ("waiting for IO path to be acquirable\n");
1108 _dbus_condvar_wait (connection->io_path_cond,
1109 connection->io_path_mutex);
1110 }
1111 }
1112 }
1113
1114 if (!connection->io_path_acquired)
1115 {
1116 we_acquired = TRUE;
1117 connection->io_path_acquired = TRUE;
1118 }
1119
1120 _dbus_verbose ("end connection->io_path_acquired = %d we_acquired = %d\n",
1121 connection->io_path_acquired, we_acquired);
1122
1123 _dbus_verbose ("unlocking io_path_mutex\n");
1124 _dbus_cmutex_unlock (connection->io_path_mutex);
1125
1126 CONNECTION_LOCK (connection);
1127
1128 HAVE_LOCK_CHECK (connection);
1129
1130 _dbus_connection_unref_unlocked (connection);
1131
1132 return we_acquired;
1133 }
1134
1142 static void
1143 _dbus_connection_release_io_path (DBusConnection *connection)
1144 {
1145 HAVE_LOCK_CHECK (connection);
1146
1147 _dbus_verbose ("locking io_path_mutex\n");
1148 _dbus_cmutex_lock (connection->io_path_mutex);
1149
1150 _dbus_assert (connection->io_path_acquired);
1151
1152 _dbus_verbose ("start connection->io_path_acquired = %d\n",
1153 connection->io_path_acquired);
1154
1155 connection->io_path_acquired = FALSE;
1156 _dbus_condvar_wake_one (connection->io_path_cond);
1157
1158 _dbus_verbose ("unlocking io_path_mutex\n");
1159 _dbus_cmutex_unlock (connection->io_path_mutex);
1160 }
1161
1197 void
1198 _dbus_connection_do_iteration_unlocked (DBusConnection *connection,
1199 DBusPendingCall *pending,
1200 unsigned int flags,
1201 int timeout_milliseconds)
1202 {
1203 _dbus_verbose ("start\n");
1204
1205 HAVE_LOCK_CHECK (connection);
1206
1207 if (connection->n_outgoing == 0)
1208 flags &= ~DBUS_ITERATION_DO_WRITING;
1209
1210 if (_dbus_connection_acquire_io_path (connection,
1211 (flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0))
1212 {
1213 HAVE_LOCK_CHECK (connection);
1214
1215 if ( (pending != NULL) && _dbus_pending_call_get_completed_unlocked(pending))
1216 {
1217 _dbus_verbose ("pending call completed while acquiring I/O path");
1218 }
1219 else if ( (pending != NULL) &&
1220 _dbus_connection_peek_for_reply_unlocked (connection,
1221 _dbus_pending_call_get_reply_serial_unlocked (pending)))
1222 {
1223 _dbus_verbose ("pending call completed while acquiring I/O path (reply found in queue)");
1224 }
1225 else
1226 {
1227 _dbus_transport_do_iteration (connection->transport,
1228 flags, timeout_milliseconds);
1229 }
1230
1231 _dbus_connection_release_io_path (connection);
1232 }
1233
1234 HAVE_LOCK_CHECK (connection);
1235
1236 _dbus_verbose ("end\n");
1237 }
1238
1248 DBusConnection*
1249 _dbus_connection_new_for_transport (DBusTransport *transport)
1250 {
1251 DBusConnection *connection;
1252 DBusWatchList *watch_list;
1253 DBusTimeoutList *timeout_list;
1254 DBusHashTable *pending_replies;
1255 DBusList *disconnect_link;
1256 DBusMessage *disconnect_message;
1257 DBusCounter *outgoing_counter;
1258 DBusObjectTree *objects;
1259
1260 watch_list = NULL;
1261 connection = NULL;
1262 pending_replies = NULL;
1263 timeout_list = NULL;
1264 disconnect_link = NULL;
1265 disconnect_message = NULL;
1266 outgoing_counter = NULL;
1267 objects = NULL;
1268
1269 watch_list = _dbus_watch_list_new ();
1270 if (watch_list == NULL)
1271 goto error;
1272
1273 timeout_list = _dbus_timeout_list_new ();
1274 if (timeout_list == NULL)
1275 goto error;
1276
1277 pending_replies =
1278 _dbus_hash_table_new (DBUS_HASH_INT,
1279 NULL,
1280 (DBusFreeFunction)free_pending_call_on_hash_removal);
1281 if (pending_replies == NULL)
1282 goto error;
1283
1284 connection = dbus_new0 (DBusConnection, 1);
1285 if (connection == NULL)
1286 goto error;
1287
1288 _dbus_rmutex_new_at_location (&connection->mutex);
1289 if (connection->mutex == NULL)
1290 goto error;
1291
1292 _dbus_cmutex_new_at_location (&connection->io_path_mutex);
1293 if (connection->io_path_mutex == NULL)
1294 goto error;
1295
1296 _dbus_cmutex_new_at_location (&connection->dispatch_mutex);
1297 if (connection->dispatch_mutex == NULL)
1298 goto error;
1299
1300 _dbus_condvar_new_at_location (&connection->dispatch_cond);
1301 if (connection->dispatch_cond == NULL)
1302 goto error;
1303
1304 _dbus_condvar_new_at_location (&connection->io_path_cond);
1305 if (connection->io_path_cond == NULL)
1306 goto error;
1307
1308 _dbus_rmutex_new_at_location (&connection->slot_mutex);
1309 if (connection->slot_mutex == NULL)
1310 goto error;
1311
1312 disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL,
1313 DBUS_INTERFACE_LOCAL,
1314 "Disconnected");
1315
1316 if (disconnect_message == NULL)
1317 goto error;
1318
1319 disconnect_link = _dbus_list_alloc_link (disconnect_message);
1320 if (disconnect_link == NULL)
1321 goto error;
1322
1323 outgoing_counter = _dbus_counter_new ();
1324 if (outgoing_counter == NULL)
1325 goto error;
1326
1327 objects = _dbus_object_tree_new (connection);
1328 if (objects == NULL)
1329 goto error;
1330
1331 if (_dbus_modify_sigpipe)
1332 _dbus_disable_sigpipe ();
1333
1334 /* initialized to 0: use atomic op to avoid mixing atomic and non-atomic */
1335 _dbus_atomic_inc (&connection->refcount);
1336 connection->transport = transport;
1337 connection->watches = watch_list;
1338 connection->timeouts = timeout_list;
1339 connection->pending_replies = pending_replies;
1340 connection->outgoing_counter = outgoing_counter;
1341 connection->filter_list = NULL;
1342 connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE; /* so we're notified first time there's data */
1343 connection->objects = objects;
1344 connection->exit_on_disconnect = FALSE;
1345 connection->shareable = FALSE;
1346 connection->route_peer_messages = FALSE;
1347 connection->disconnected_message_arrived = FALSE;
1348 connection->disconnected_message_processed = FALSE;
1349
1350 #if defined(DBUS_ENABLE_CHECKS) || defined(DBUS_ENABLE_ASSERT)
1351 connection->generation = _dbus_current_generation;
1352 #endif
1353
1354 _dbus_data_slot_list_init (&connection->slot_list);
1355
1356 connection->client_serial = 1;
1357
1358 connection->disconnect_message_link = disconnect_link;
1359
1360 CONNECTION_LOCK (connection);
1361
1362 if (!_dbus_transport_set_connection (transport, connection))
1363 {
1364 CONNECTION_UNLOCK (connection);
1365
1366 goto error;
1367 }
1368
1369 _dbus_transport_ref (transport);
1370
1371 CONNECTION_UNLOCK (connection);
1372
1373 _dbus_connection_trace_ref (connection, 0, 1, "new_for_transport");
1374 return connection;
1375
1376 error:
1377 if (disconnect_message != NULL)
1378 dbus_message_unref (disconnect_message);
1379
1380 if (disconnect_link != NULL)
1381 _dbus_list_free_link (disconnect_link);
1382
1383 if (connection != NULL)
1384 {
1385 _dbus_condvar_free_at_location (&connection->io_path_cond);
1386 _dbus_condvar_free_at_location (&connection->dispatch_cond);
1387 _dbus_rmutex_free_at_location (&connection->mutex);
1388 _dbus_cmutex_free_at_location (&connection->io_path_mutex);
1389 _dbus_cmutex_free_at_location (&connection->dispatch_mutex);
1390 _dbus_rmutex_free_at_location (&connection->slot_mutex);
1391 dbus_free (connection);
1392 }
1393 if (pending_replies)
1394 _dbus_hash_table_unref (pending_replies);
1395
1396 if (watch_list)
1397 _dbus_watch_list_free (watch_list);
1398
1399 if (timeout_list)
1400 _dbus_timeout_list_free (timeout_list);
1401
1402 if (outgoing_counter)
1403 _dbus_counter_unref (outgoing_counter);
1404
1405 if (objects)
1406 _dbus_object_tree_unref (objects);
1407
1408 return NULL;
1409 }
1410
1418 DBusConnection *
1419 _dbus_connection_ref_unlocked (DBusConnection *connection)
1420 {
1421 dbus_int32_t old_refcount;
1422
1423 _dbus_assert (connection != NULL);
1424 _dbus_assert (connection->generation == _dbus_current_generation);
1425
1426 HAVE_LOCK_CHECK (connection);
1427
1428 old_refcount = _dbus_atomic_inc (&connection->refcount);
1429 _dbus_connection_trace_ref (connection, old_refcount, old_refcount + 1,
1430 "ref_unlocked");
1431
1432 return connection;
1433 }
1434
1441 void
1442 _dbus_connection_unref_unlocked (DBusConnection *connection)
1443 {
1444 dbus_int32_t old_refcount;
1445
1446 HAVE_LOCK_CHECK (connection);
1447
1448 _dbus_assert (connection != NULL);
1449
1450 old_refcount = _dbus_atomic_dec (&connection->refcount);
1451
1452 _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1,
1453 "unref_unlocked");
1454
1455 if (old_refcount == 1)
1456 _dbus_connection_last_unref (connection);
1457 }
1458
1459 static dbus_uint32_t
1460 _dbus_connection_get_next_client_serial (DBusConnection *connection)
1461 {
1462 dbus_uint32_t serial;
1463
1464 serial = connection->client_serial++;
1465
1466 if (connection->client_serial == 0)
1467 connection->client_serial = 1;
1468
1469 return serial;
1470 }
1471
1485 dbus_bool_t
1486 _dbus_connection_handle_watch (DBusWatch *watch,
1487 unsigned int condition,
1488 void *data)
1489 {
1490 DBusConnection *connection;
1491 dbus_bool_t retval;
1492 DBusDispatchStatus status;
1493
1494 connection = data;
1495
1496 _dbus_verbose ("start\n");
1497
1498 CONNECTION_LOCK (connection);
1499
1500 if (!_dbus_connection_acquire_io_path (connection, 1))
1501 {
1502 /* another thread is handling the message */
1503 CONNECTION_UNLOCK (connection);
1504 return TRUE;
1505 }
1506
1507 HAVE_LOCK_CHECK (connection);
1508 retval = _dbus_transport_handle_watch (connection->transport,
1509 watch, condition);
1510
1511 _dbus_connection_release_io_path (connection);
1512
1513 HAVE_LOCK_CHECK (connection);
1514
1515 _dbus_verbose ("middle\n");
1516
1517 status = _dbus_connection_get_dispatch_status_unlocked (connection);
1518
1519 /* this calls out to user code */
1520 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
1521
1522 _dbus_verbose ("end\n");
1523
1524 return retval;
1525 }
1526
1527 /* Protected by _DBUS_LOCK (shared_connections) */
1528 static DBusHashTable *shared_connections = NULL;
1529 static DBusList *shared_connections_no_guid = NULL;
1530
1531 static void
1532 close_connection_on_shutdown (DBusConnection *connection)
1533 {
1534 DBusMessage *message;
1535
1536 dbus_connection_ref (connection);
1537 _dbus_connection_close_possibly_shared (connection);
1538
1539 /* Churn through to the Disconnected message */
1540 while ((message = dbus_connection_pop_message (connection)))
1541 {
1542 dbus_message_unref (message);
1543 }
1544 dbus_connection_unref (connection);
1545 }
1546
1547 static void
1548 shared_connections_shutdown (void *data)
1549 {
1550 int n_entries;
1551
1552 if (!_DBUS_LOCK (shared_connections))
1553 {
1554 /* We'd have initialized locks before adding anything, so there
1555 * can't be anything there. */
1556 return;
1557 }
1558
1559 /* This is a little bit unpleasant... better ideas? */
1560 while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0)
1561 {
1562 DBusConnection *connection;
1563 DBusHashIter iter;
1564
1565 _dbus_hash_iter_init (shared_connections, &iter);
1566 _dbus_hash_iter_next (&iter);
1567
1568 connection = _dbus_hash_iter_get_value (&iter);
1569
1570 _DBUS_UNLOCK (shared_connections);
1571 close_connection_on_shutdown (connection);
1572 if (!_DBUS_LOCK (shared_connections))
1573 _dbus_assert_not_reached ("global locks were already initialized");
1574
1575 /* The connection should now be dead and not in our hash ... */
1576 _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) < n_entries);
1577 }
1578
1579 _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) == 0);
1580
1581 _dbus_hash_table_unref (shared_connections);
1582 shared_connections = NULL;
1583
1584 if (shared_connections_no_guid != NULL)
1585 {
1586 DBusConnection *connection;
1587 connection = _dbus_list_pop_first (&shared_connections_no_guid);
1588 while (connection != NULL)
1589 {
1590 _DBUS_UNLOCK (shared_connections);
1591 close_connection_on_shutdown (connection);
1592 if (!_DBUS_LOCK (shared_connections))
1593 _dbus_assert_not_reached ("global locks were already initialized");
1594 connection = _dbus_list_pop_first (&shared_connections_no_guid);
1595 }
1596 }
1597
1598 shared_connections_no_guid = NULL;
1599
1600 _DBUS_UNLOCK (shared_connections);
1601 }
1602
1603 static dbus_bool_t
1604 connection_lookup_shared (DBusAddressEntry *entry,
1605 DBusConnection **result)
1606 {
1607 _dbus_verbose ("checking for existing connection\n");
1608
1609 *result = NULL;
1610
1611 if (!_DBUS_LOCK (shared_connections))
1612 {
1613 /* If it was shared, we'd have initialized global locks when we put
1614 * it in shared_connections. */
1615 return FALSE;
1616 }
1617
1618 if (shared_connections == NULL)
1619 {
1620 _dbus_verbose ("creating shared_connections hash table\n");
1621
1622 shared_connections = _dbus_hash_table_new (DBUS_HASH_STRING,
1623 dbus_free,
1624 NULL);
1625 if (shared_connections == NULL)
1626 {
1627 _DBUS_UNLOCK (shared_connections);
1628 return FALSE;
1629 }
1630
1631 if (!_dbus_register_shutdown_func (shared_connections_shutdown, NULL))
1632 {
1633 _dbus_hash_table_unref (shared_connections);
1634 shared_connections = NULL;
1635 _DBUS_UNLOCK (shared_connections);
1636 return FALSE;
1637 }
1638
1639 _dbus_verbose (" successfully created shared_connections\n");
1640
1641 _DBUS_UNLOCK (shared_connections);
1642 return TRUE; /* no point looking up in the hash we just made */
1643 }
1644 else
1645 {
1646 const char *guid;
1647
1648 guid = dbus_address_entry_get_value (entry, "guid");
1649
1650 if (guid != NULL)
1651 {
1652 DBusConnection *connection;
1653
1654 connection = _dbus_hash_table_lookup_string (shared_connections,
1655 guid);
1656
1657 if (connection)
1658 {
1659 /* The DBusConnection can't be finalized without taking
1660 * the shared_connections lock to remove it from the
1661 * hash. So it's safe to ref the connection here.
1662 * However, it may be disconnected if the Disconnected
1663 * message hasn't been processed yet, in which case we
1664 * want to pretend it isn't in the hash and avoid
1665 * returning it.
1666 *
1667 * The idea is to avoid ever returning a disconnected connection
1668 * from dbus_connection_open(). We could just synchronously
1669 * drop our shared ref to the connection on connection disconnect,
1670 * and then assert here that the connection is connected, but
1671 * that causes reentrancy headaches.
1672 */
1673 CONNECTION_LOCK (connection);
1674 if (_dbus_connection_get_is_connected_unlocked (connection))
1675 {
1676 _dbus_connection_ref_unlocked (connection);
1677 *result = connection;
1678 _dbus_verbose ("looked up existing connection to server guid %s\n",
1679 guid);
1680 }
1681 else
1682 {
1683 _dbus_verbose ("looked up existing connection to server guid %s but it was disconnected so ignoring it\n",
1684 guid);
1685 }
1686 CONNECTION_UNLOCK (connection);
1687 }
1688 }
1689
1690 _DBUS_UNLOCK (shared_connections);
1691 return TRUE;
1692 }
1693 }
1694
1695 static dbus_bool_t
1696 connection_record_shared_unlocked (DBusConnection *connection,
1697 const char *guid)
1698 {
1699 char *guid_key;
1700 char *guid_in_connection;
1701
1702 HAVE_LOCK_CHECK (connection);
1703 _dbus_assert (connection->server_guid == NULL);
1704 _dbus_assert (connection->shareable);
1705
1706 /* get a hard ref on this connection, even if
1707 * we won't in fact store it in the hash, we still
1708 * need to hold a ref on it until it's disconnected.
1709 */
1710 _dbus_connection_ref_unlocked (connection);
1711
1712 if (guid == NULL)
1713 {
1714 if (!_DBUS_LOCK (shared_connections))
1715 return FALSE;
1716
1717 if (!_dbus_list_prepend (&shared_connections_no_guid, connection))
1718 {
1719 _DBUS_UNLOCK (shared_connections);
1720 return FALSE;
1721 }
1722
1723 _DBUS_UNLOCK (shared_connections);
1724 return TRUE; /* don't store in the hash */
1725 }
1726
1727 /* A separate copy of the key is required in the hash table, because
1728 * we don't have a lock on the connection when we are doing a hash
1729 * lookup.
1730 */
1731
1732 guid_key = _dbus_strdup (guid);
1733 if (guid_key == NULL)
1734 return FALSE;
1735
1736 guid_in_connection = _dbus_strdup (guid);
1737 if (guid_in_connection == NULL)
1738 {
1739 dbus_free (guid_key);
1740 return FALSE;
1741 }
1742
1743 if (!_DBUS_LOCK (shared_connections))
1744 {
1745 dbus_free (guid_in_connection);
1746 dbus_free (guid_key);
1747 return FALSE;
1748 }
1749
1750 _dbus_assert (shared_connections != NULL);
1751
1752 if (!_dbus_hash_table_insert_string (shared_connections,
1753 guid_key, connection))
1754 {
1755 dbus_free (guid_key);
1756 dbus_free (guid_in_connection);
1757 _DBUS_UNLOCK (shared_connections);
1758 return FALSE;
1759 }
1760
1761 connection->server_guid = guid_in_connection;
1762
1763 _dbus_verbose ("stored connection to %s to be shared\n",
1764 connection->server_guid);
1765
1766 _DBUS_UNLOCK (shared_connections);
1767
1768 _dbus_assert (connection->server_guid != NULL);
1769
1770 return TRUE;
1771 }
1772
1773 static void
1774 connection_forget_shared_unlocked (DBusConnection *connection)
1775 {
1776 HAVE_LOCK_CHECK (connection);
1777
1778 if (!connection->shareable)
1779 return;
1780
1781 if (!_DBUS_LOCK (shared_connections))
1782 {
1783 /* If it was shared, we'd have initialized global locks when we put
1784 * it in the table; so it can't be there. */
1785 return;
1786 }
1787
1788 if (connection->server_guid != NULL)
1789 {
1790 _dbus_verbose ("dropping connection to %s out of the shared table\n",
1791 connection->server_guid);
1792
1793 if (!_dbus_hash_table_remove_string (shared_connections,
1794 connection->server_guid))
1795 _dbus_assert_not_reached ("connection was not in the shared table");
1796
1797 dbus_free (connection->server_guid);
1798 connection->server_guid = NULL;
1799 }
1800 else
1801 {
1802 _dbus_list_remove (&shared_connections_no_guid, connection);
1803 }
1804
1805 _DBUS_UNLOCK (shared_connections);
1806
1807 /* remove our reference held on all shareable connections */
1808 _dbus_connection_unref_unlocked (connection);
1809 }
1810
1811 static DBusConnection*
1812 connection_try_from_address_entry (DBusAddressEntry *entry,
1813 DBusError *error)
1814 {
1815 DBusTransport *transport;
1816 DBusConnection *connection;
1817
1818 transport = _dbus_transport_open (entry, error);
1819
1820 if (transport == NULL)
1821 {
1822 _DBUS_ASSERT_ERROR_IS_SET (error);
1823 return NULL;
1824 }
1825
1826 connection = _dbus_connection_new_for_transport (transport);
1827
1828 _dbus_transport_unref (transport);
1829
1830 if (connection == NULL)
1831 {
1832 _DBUS_SET_OOM (error);
1833 return NULL;
1834 }
1835
1836 #ifndef DBUS_DISABLE_CHECKS
1837 _dbus_assert (!connection->have_connection_lock);
1838 #endif
1839 return connection;
1840 }
1841
1842 /*
1843 * If the shared parameter is true, then any existing connection will
1844 * be used (and if a new connection is created, it will be available
1845 * for use by others). If the shared parameter is false, a new
1846 * connection will always be created, and the new connection will
1847 * never be returned to other callers.
1848 *
1849 * @param address the address
1850 * @param shared whether the connection is shared or private
1851 * @param error error return
1852 * @returns the connection or #NULL on error
1853 */
1854 static DBusConnection*
1855 _dbus_connection_open_internal (const char *address,
1856 dbus_bool_t shared,
1857 DBusError *error)
1858 {
1859 DBusConnection *connection;
1860 DBusAddressEntry **entries;
1861 DBusError tmp_error = DBUS_ERROR_INIT;
1862 DBusError first_error = DBUS_ERROR_INIT;
1863 int len, i;
1864
1865 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1866
1867 _dbus_verbose ("opening %s connection to: %s\n",
1868 shared ? "shared" : "private", address);
1869
1870 if (!dbus_parse_address (address, &entries, &len, error))
1871 return NULL;
1872
1873 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1874
1875 connection = NULL;
1876
1877 for (i = 0; i < len; i++)
1878 {
1879 if (shared)
1880 {
1881 if (!connection_lookup_shared (entries[i], &connection))
1882 _DBUS_SET_OOM (&tmp_error);
1883 }
1884
1885 if (connection == NULL)
1886 {
1887 connection = connection_try_from_address_entry (entries[i],
1888 &tmp_error);
1889
1890 if (connection != NULL && shared)
1891 {
1892 const char *guid;
1893
1894 connection->shareable = TRUE;
1895
1896 /* guid may be NULL */
1897 guid = dbus_address_entry_get_value (entries[i], "guid");
1898
1899 CONNECTION_LOCK (connection);
1900
1901 if (!connection_record_shared_unlocked (connection, guid))
1902 {
1903 _DBUS_SET_OOM (&tmp_error);
1904 _dbus_connection_close_possibly_shared_and_unlock (connection);
1905 dbus_connection_unref (connection);
1906 connection = NULL;
1907 }
1908 else
1909 CONNECTION_UNLOCK (connection);
1910 }
1911 }
1912
1913 if (connection)
1914 break;
1915
1916 _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
1917
1918 if (i == 0)
1919 dbus_move_error (&tmp_error, &first_error);
1920 else
1921 dbus_error_free (&tmp_error);
1922 }
1923
1924 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1925 _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
1926
1927 if (connection == NULL)
1928 {
1929 _DBUS_ASSERT_ERROR_IS_SET (&first_error);
1930 dbus_move_error (&first_error, error);
1931 }
1932 else
1933 dbus_error_free (&first_error);
1934
1935 dbus_address_entries_free (entries);
1936 return connection;
1937 }
1938
1947 void
1948 _dbus_connection_close_possibly_shared (DBusConnection *connection)
1949 {
1950 _dbus_assert (connection != NULL);
1951 _dbus_assert (connection->generation == _dbus_current_generation);
1952
1953 CONNECTION_LOCK (connection);
1954 _dbus_connection_close_possibly_shared_and_unlock (connection);
1955 }
1956
1957 static DBusPreallocatedSend*
1958 _dbus_connection_preallocate_send_unlocked (DBusConnection *connection)
1959 {
1960 DBusPreallocatedSend *preallocated;
1961
1962 HAVE_LOCK_CHECK (connection);
1963
1964 _dbus_assert (connection != NULL);
1965
1966 preallocated = dbus_new (DBusPreallocatedSend, 1);
1967 if (preallocated == NULL)
1968 return NULL;
1969
1970 preallocated->queue_link = _dbus_list_alloc_link (NULL);
1971 if (preallocated->queue_link == NULL)
1972 goto failed_0;
1973
1974 preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter);
1975 if (preallocated->counter_link == NULL)
1976 goto failed_1;
1977
1978 _dbus_counter_ref (preallocated->counter_link->data);
1979
1980 preallocated->connection = connection;
1981
1982 return preallocated;
1983
1984 failed_1:
1985 _dbus_list_free_link (preallocated->queue_link);
1986 failed_0:
1987 dbus_free (preallocated);
1988
1989 return NULL;
1990 }
1991
1992 /* Called with lock held, does not update dispatch status */
1993 static void
1994 _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *connection,
1995 DBusPreallocatedSend *preallocated,
1996 DBusMessage *message,
1997 dbus_uint32_t *client_serial)
1998 {
1999 dbus_uint32_t serial;
2000
2001 preallocated->queue_link->data = message;
2002 _dbus_list_prepend_link (&connection->outgoing_messages,
2003 preallocated->queue_link);
2004
2005 /* It's OK that we'll never call the notify function, because for the
2006 * outgoing limit, there isn't one */
2007 _dbus_message_add_counter_link (message,
2008 preallocated->counter_link);
2009
2010 dbus_free (preallocated);
2011 preallocated = NULL;
2012
2013 dbus_message_ref (message);
2014
2015 connection->n_outgoing += 1;
2016
2017 _dbus_verbose ("Message %p (%s %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
2018 message,
2019 dbus_message_type_to_string (dbus_message_get_type (message)),
2020 dbus_message_get_path (message) ?
2021 dbus_message_get_path (message) :
2022 "no path",
2023 dbus_message_get_interface (message) ?
2024 dbus_message_get_interface (message) :
2025 "no interface",
2026 dbus_message_get_member (message) ?
2027 dbus_message_get_member (message) :
2028 "no member",
2029 dbus_message_get_signature (message),
2030 dbus_message_get_destination (message) ?
2031 dbus_message_get_destination (message) :
2032 "null",
2033 connection,
2034 connection->n_outgoing);
2035
2036 if (dbus_message_get_serial (message) == 0)
2037 {
2038 serial = _dbus_connection_get_next_client_serial (connection);
2039 dbus_message_set_serial (message, serial);
2040 if (client_serial)
2041 *client_serial = serial;
2042 }
2043 else
2044 {
2045 if (client_serial)
2046 *client_serial = dbus_message_get_serial (message);
2047 }
2048
2049 _dbus_verbose ("Message %p serial is %u\n",
2050 message, dbus_message_get_serial (message));
2051
2052 dbus_message_lock (message);
2053
2054 /* Now we need to run an iteration to hopefully just write the messages
2055 * out immediately, and otherwise get them queued up
2056 */
2057 _dbus_connection_do_iteration_unlocked (connection,
2058 NULL,
2059 DBUS_ITERATION_DO_WRITING,
2060 -1);
2061
2062 /* If stuff is still queued up, be sure we wake up the main loop */
2063 if (connection->n_outgoing > 0)
2064 _dbus_connection_wakeup_mainloop (connection);
2065 }
2066
2067 static void
2068 _dbus_connection_send_preallocated_and_unlock (DBusConnection *connection,
2069 DBusPreallocatedSend *preallocated,
2070 DBusMessage *message,
2071 dbus_uint32_t *client_serial)
2072 {
2073 DBusDispatchStatus status;
2074
2075 HAVE_LOCK_CHECK (connection);
2076
2077 _dbus_connection_send_preallocated_unlocked_no_update (connection,
2078 preallocated,
2079 message, client_serial);
2080
2081 _dbus_verbose ("middle\n");
2082 status = _dbus_connection_get_dispatch_status_unlocked (connection);
2083
2084 /* this calls out to user code */
2085 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2086 }
2087
2097 dbus_bool_t
2098 _dbus_connection_send_and_unlock (DBusConnection *connection,
2099 DBusMessage *message,
2100 dbus_uint32_t *client_serial)
2101 {
2102 DBusPreallocatedSend *preallocated;
2103
2104 _dbus_assert (connection != NULL);
2105 _dbus_assert (message != NULL);
2106
2107 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
2108 if (preallocated == NULL)
2109 {
2110 CONNECTION_UNLOCK (connection);
2111 return FALSE;
2112 }
2113
2114 _dbus_connection_send_preallocated_and_unlock (connection,
2115 preallocated,
2116 message,
2117 client_serial);
2118 return TRUE;
2119 }
2120
2145 void
2146 _dbus_connection_close_if_only_one_ref (DBusConnection *connection)
2147 {
2148 dbus_int32_t refcount;
2149
2150 CONNECTION_LOCK (connection);
2151
2152 refcount = _dbus_atomic_get (&connection->refcount);
2153 /* The caller should have at least one ref */
2154 _dbus_assert (refcount >= 1);
2155
2156 if (refcount == 1)
2157 _dbus_connection_close_possibly_shared_and_unlock (connection);
2158 else
2159 CONNECTION_UNLOCK (connection);
2160 }
2161
2162
2172 static void
2173 _dbus_memory_pause_based_on_timeout (int timeout_milliseconds)
2174 {
2175 if (timeout_milliseconds == -1)
2176 _dbus_sleep_milliseconds (1000);
2177 else if (timeout_milliseconds < 100)
2178 ; /* just busy loop */
2179 else if (timeout_milliseconds <= 1000)
2180 _dbus_sleep_milliseconds (timeout_milliseconds / 3);
2181 else
2182 _dbus_sleep_milliseconds (1000);
2183 }
2184
2185 static DBusMessage *
2186 generate_local_error_message (dbus_uint32_t serial,
2187 char *error_name,
2188 char *error_msg)
2189 {
2190 DBusMessage *message;
2191 message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
2192 if (!message)
2193 goto out;
2194
2195 if (!dbus_message_set_error_name (message, error_name))
2196 {
2197 dbus_message_unref (message);
2198 message = NULL;
2199 goto out;
2200 }
2201
2202 dbus_message_set_no_reply (message, TRUE);
2203
2204 if (!dbus_message_set_reply_serial (message,
2205 serial))
2206 {
2207 dbus_message_unref (message);
2208 message = NULL;
2209 goto out;
2210 }
2211
2212 if (error_msg != NULL)
2213 {
2214 DBusMessageIter iter;
2215
2216 dbus_message_iter_init_append (message, &iter);
2217 if (!dbus_message_iter_append_basic (&iter,
2218 DBUS_TYPE_STRING,
2219 &error_msg))
2220 {
2221 dbus_message_unref (message);
2222 message = NULL;
2223 goto out;
2224 }
2225 }
2226
2227 out:
2228 return message;
2229 }
2230
2231 /*
2232 * Peek the incoming queue to see if we got reply for a specific serial
2233 */
2234 static dbus_bool_t
2235 _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection,
2236 dbus_uint32_t client_serial)
2237 {
2238 DBusList *link;
2239 HAVE_LOCK_CHECK (connection);
2240
2241 link = _dbus_list_get_first_link (&connection->incoming_messages);
2242
2243 while (link != NULL)
2244 {
2245 DBusMessage *reply = link->data;
2246
2247 if (dbus_message_get_reply_serial (reply) == client_serial)
2248 {
2249 _dbus_verbose ("%s reply to %d found in queue\n", _DBUS_FUNCTION_NAME, client_serial);
2250 return TRUE;
2251 }
2252 link = _dbus_list_get_next_link (&connection->incoming_messages, link);
2253 }
2254
2255 return FALSE;
2256 }
2257
2258 /* This is slightly strange since we can pop a message here without
2259 * the dispatch lock.
2260 */
2261 static DBusMessage*
2262 check_for_reply_unlocked (DBusConnection *connection,
2263 dbus_uint32_t client_serial)
2264 {
2265 DBusList *link;
2266
2267 HAVE_LOCK_CHECK (connection);
2268
2269 link = _dbus_list_get_first_link (&connection->incoming_messages);
2270
2271 while (link != NULL)
2272 {
2273 DBusMessage *reply = link->data;
2274
2275 if (dbus_message_get_reply_serial (reply) == client_serial)
2276 {
2277 _dbus_list_remove_link (&connection->incoming_messages, link);
2278 connection->n_incoming -= 1;
2279 return reply;
2280 }
2281 link = _dbus_list_get_next_link (&connection->incoming_messages, link);
2282 }
2283
2284 return NULL;
2285 }
2286
2287 static void
2288 connection_timeout_and_complete_all_pending_calls_unlocked (DBusConnection *connection)
2289 {
2290 /* We can't iterate over the hash in the normal way since we'll be
2291 * dropping the lock for each item. So we restart the
2292 * iter each time as we drain the hash table.
2293 */
2294
2295 while (_dbus_hash_table_get_n_entries (connection->pending_replies) > 0)
2296 {
2297 DBusPendingCall *pending;
2298 DBusHashIter iter;
2299
2300 _dbus_hash_iter_init (connection->pending_replies, &iter);
2301 _dbus_hash_iter_next (&iter);
2302
2303 pending = _dbus_hash_iter_get_value (&iter);
2304 _dbus_pending_call_ref_unlocked (pending);
2305
2306 _dbus_pending_call_queue_timeout_error_unlocked (pending,
2307 connection);
2308
2309 if (_dbus_pending_call_is_timeout_added_unlocked (pending))
2310 _dbus_connection_remove_timeout_unlocked (connection,
2311 _dbus_pending_call_get_timeout_unlocked (pending));
2312 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
2313 _dbus_hash_iter_remove_entry (&iter);
2314
2315 _dbus_pending_call_unref_and_unlock (pending);
2316 CONNECTION_LOCK (connection);
2317 }
2318 HAVE_LOCK_CHECK (connection);
2319 }
2320
2321 static void
2322 complete_pending_call_and_unlock (DBusConnection *connection,
2323 DBusPendingCall *pending,
2324 DBusMessage *message)
2325 {
2326 _dbus_pending_call_set_reply_unlocked (pending, message);
2327 _dbus_pending_call_ref_unlocked (pending); /* in case there's no app with a ref held */
2328 _dbus_connection_detach_pending_call_and_unlock (connection, pending);
2329
2330 /* Must be called unlocked since it invokes app callback */
2331 _dbus_pending_call_complete (pending);
2332 dbus_pending_call_unref (pending);
2333 }
2334
2335 static dbus_bool_t
2336 check_for_reply_and_update_dispatch_unlocked (DBusConnection *connection,
2337 DBusPendingCall *pending)
2338 {
2339 DBusMessage *reply;
2340 DBusDispatchStatus status;
2341
2342 reply = check_for_reply_unlocked (connection,
2343 _dbus_pending_call_get_reply_serial_unlocked (pending));
2344 if (reply != NULL)
2345 {
2346 _dbus_verbose ("checked for reply\n");
2347
2348 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
2349
2350 complete_pending_call_and_unlock (connection, pending, reply);
2351 dbus_message_unref (reply);
2352
2353 CONNECTION_LOCK (connection);
2354 status = _dbus_connection_get_dispatch_status_unlocked (connection);
2355 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2356 dbus_pending_call_unref (pending);
2357
2358 return TRUE;
2359 }
2360
2361 return FALSE;
2362 }
2363
2378 void
2379 _dbus_connection_block_pending_call (DBusPendingCall *pending)
2380 {
2381 long start_tv_sec, start_tv_usec;
2382 long tv_sec, tv_usec;
2383 DBusDispatchStatus status;
2384 DBusConnection *connection;
2385 dbus_uint32_t client_serial;
2386 DBusTimeout *timeout;
2387 int timeout_milliseconds, elapsed_milliseconds;
2388
2389 _dbus_assert (pending != NULL);
2390
2391 if (dbus_pending_call_get_completed (pending))
2392 return;
2393
2394 dbus_pending_call_ref (pending); /* necessary because the call could be canceled */
2395
2396 connection = _dbus_pending_call_get_connection_and_lock (pending);
2397
2398 /* Flush message queue - note, can affect dispatch status */
2399 _dbus_connection_flush_unlocked (connection);
2400
2401 client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
2402
2403 /* note that timeout_milliseconds is limited to a smallish value
2404 * in _dbus_pending_call_new() so overflows aren't possible
2405 * below
2406 */
2407 timeout = _dbus_pending_call_get_timeout_unlocked (pending);
2408 _dbus_get_monotonic_time (&start_tv_sec, &start_tv_usec);
2409 if (timeout)
2410 {
2411 timeout_milliseconds = dbus_timeout_get_interval (timeout);
2412
2413 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec\n",
2414 timeout_milliseconds,
2415 client_serial,
2416 start_tv_sec, start_tv_usec);
2417 }
2418 else
2419 {
2420 timeout_milliseconds = -1;
2421
2422 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block for reply serial %u\n", client_serial);
2423 }
2424
2425 /* check to see if we already got the data off the socket */
2426 /* from another blocked pending call */
2427 if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
2428 return;
2429
2430 /* Now we wait... */
2431 /* always block at least once as we know we don't have the reply yet */
2432 _dbus_connection_do_iteration_unlocked (connection,
2433 pending,
2434 DBUS_ITERATION_DO_READING |
2435 DBUS_ITERATION_BLOCK,
2436 timeout_milliseconds);
2437
2438 recheck_status:
2439
2440 _dbus_verbose ("top of recheck\n");
2441
2442 HAVE_LOCK_CHECK (connection);
2443
2444 /* queue messages and get status */
2445
2446 status = _dbus_connection_get_dispatch_status_unlocked (connection);
2447
2448 /* the get_completed() is in case a dispatch() while we were blocking
2449 * got the reply instead of us.
2450 */
2451 if (_dbus_pending_call_get_completed_unlocked (pending))
2452 {
2453 _dbus_verbose ("Pending call completed by dispatch\n");
2454 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2455 dbus_pending_call_unref (pending);
2456 return;
2457 }
2458
2459 if (status == DBUS_DISPATCH_DATA_REMAINS)
2460 {
2461 if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
2462 return;
2463 }
2464
2465 _dbus_get_monotonic_time (&tv_sec, &tv_usec);
2466 elapsed_milliseconds = (tv_sec - start_tv_sec) * 1000 +
2467 (tv_usec - start_tv_usec) / 1000;
2468
2469 if (!_dbus_connection_get_is_connected_unlocked (connection))
2470 {
2471 DBusMessage *error_msg;
2472
2473 error_msg = generate_local_error_message (client_serial,
2474 DBUS_ERROR_DISCONNECTED,
2475 "Connection was disconnected before a reply was received");
2476
2477 /* on OOM error_msg is set to NULL */
2478 complete_pending_call_and_unlock (connection, pending, error_msg);
2479 dbus_pending_call_unref (pending);
2480 return;
2481 }
2482 else if (connection->disconnect_message_link == NULL)
2483 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
2484 else if (timeout == NULL)
2485 {
2486 if (status == DBUS_DISPATCH_NEED_MEMORY)
2487 {
2488 /* Try sleeping a bit, as we aren't sure we need to block for reading,
2489 * we may already have a reply in the buffer and just can't process
2490 * it.
2491 */
2492 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
2493
2494 _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
2495 }
2496 else
2497 {
2498 /* block again, we don't have the reply buffered yet. */
2499 _dbus_connection_do_iteration_unlocked (connection,
2500 pending,
2501 DBUS_ITERATION_DO_READING |
2502 DBUS_ITERATION_BLOCK,
2503 timeout_milliseconds - elapsed_milliseconds);
2504 }
2505
2506 goto recheck_status;
2507 }
2508 else if (tv_sec < start_tv_sec)
2509 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
2510 else if (elapsed_milliseconds < timeout_milliseconds)
2511 {
2512 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds - elapsed_milliseconds);
2513
2514 if (status == DBUS_DISPATCH_NEED_MEMORY)
2515 {
2516 /* Try sleeping a bit, as we aren't sure we need to block for reading,
2517 * we may already have a reply in the buffer and just can't process
2518 * it.
2519 */
2520 _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
2521
2522 _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
2523 }
2524 else
2525 {
2526 /* block again, we don't have the reply buffered yet. */
2527 _dbus_connection_do_iteration_unlocked (connection,
2528 NULL,
2529 DBUS_ITERATION_DO_READING |
2530 DBUS_ITERATION_BLOCK,
2531 timeout_milliseconds - elapsed_milliseconds);
2532 }
2533
2534 goto recheck_status;
2535 }
2536
2537 _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %d milliseconds and got no reply\n",
2538 elapsed_milliseconds);
2539
2540 _dbus_assert (!_dbus_pending_call_get_completed_unlocked (pending));
2541
2542 /* unlock and call user code */
2543 complete_pending_call_and_unlock (connection, pending, NULL);
2544
2545 /* update user code on dispatch status */
2546 CONNECTION_LOCK (connection);
2547 status = _dbus_connection_get_dispatch_status_unlocked (connection);
2548 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2549 dbus_pending_call_unref (pending);
2550 }
2551
2557 int
2558 _dbus_connection_get_pending_fds_count (DBusConnection *connection)
2559 {
2560 return _dbus_transport_get_pending_fds_count (connection->transport);
2561 }
2562
2570 void
2571 _dbus_connection_set_pending_fds_function (DBusConnection *connection,
2572 DBusPendingFdsChangeFunction callback,
2573 void *data)
2574 {
2575 _dbus_transport_set_pending_fds_function (connection->transport,
2576 callback, data);
2577 }
2578
2615 DBusConnection*
2616 dbus_connection_open (const char *address,
2617 DBusError *error)
2618 {
2619 DBusConnection *connection;
2620
2621 _dbus_return_val_if_fail (address != NULL, NULL);
2622 _dbus_return_val_if_error_is_set (error, NULL);
2623
2624 connection = _dbus_connection_open_internal (address,
2625 TRUE,
2626 error);
2627
2628 return connection;
2629 }
2630
2658 DBusConnection*
2659 dbus_connection_open_private (const char *address,
2660 DBusError *error)
2661 {
2662 DBusConnection *connection;
2663
2664 _dbus_return_val_if_fail (address != NULL, NULL);
2665 _dbus_return_val_if_error_is_set (error, NULL);
2666
2667 connection = _dbus_connection_open_internal (address,
2668 FALSE,
2669 error);
2670
2671 return connection;
2672 }
2673
2680 DBusConnection *
2681 dbus_connection_ref (DBusConnection *connection)
2682 {
2683 dbus_int32_t old_refcount;
2684
2685 _dbus_return_val_if_fail (connection != NULL, NULL);
2686 _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
2687 old_refcount = _dbus_atomic_inc (&connection->refcount);
2688 _dbus_connection_trace_ref (connection, old_refcount, old_refcount + 1,
2689 "ref");
2690
2691 return connection;
2692 }
2693
2694 static void
2695 free_outgoing_message (void *element,
2696 void *data)
2697 {
2698 DBusMessage *message = element;
2699 DBusConnection *connection = data;
2700
2701 _dbus_message_remove_counter (message, connection->outgoing_counter);
2702 dbus_message_unref (message);
2703 }
2704
2705 /* This is run without the mutex held, but after the last reference
2706 * to the connection has been dropped we should have no thread-related
2707 * problems
2708 */
2709 static void
2710 _dbus_connection_last_unref (DBusConnection *connection)
2711 {
2712 DBusList *link;
2713
2714 _dbus_verbose ("Finalizing connection %p\n", connection);
2715
2716 _dbus_assert (_dbus_atomic_get (&connection->refcount) == 0);
2717
2718 /* You have to disconnect the connection before unref:ing it. Otherwise
2719 * you won't get the disconnected message.
2720 */
2721 _dbus_assert (!_dbus_transport_get_is_connected (connection->transport));
2722 _dbus_assert (connection->server_guid == NULL);
2723
2724 /* ---- We're going to call various application callbacks here, hope it doesn't break anything... */
2725 _dbus_object_tree_free_all_unlocked (connection->objects);
2726
2727 dbus_connection_set_dispatch_status_function (connection, NULL, NULL, NULL);
2728 dbus_connection_set_wakeup_main_function (connection, NULL, NULL, NULL);
2729 dbus_connection_set_unix_user_function (connection, NULL, NULL, NULL);
2730 dbus_connection_set_windows_user_function (connection, NULL, NULL, NULL);
2731
2732 _dbus_watch_list_free (connection->watches);
2733 connection->watches = NULL;
2734
2735 _dbus_timeout_list_free (connection->timeouts);
2736 connection->timeouts = NULL;
2737
2738 _dbus_data_slot_list_free (&connection->slot_list);
2739
2740 link = _dbus_list_get_first_link (&connection->filter_list);
2741 while (link != NULL)
2742 {
2743 DBusMessageFilter *filter = link->data;
2744 DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
2745
2746 filter->function = NULL;
2747 _dbus_message_filter_unref (filter); /* calls app callback */
2748 link->data = NULL;
2749
2750 link = next;
2751 }
2752 _dbus_list_clear (&connection->filter_list);
2753
2754 /* ---- Done with stuff that invokes application callbacks */
2755
2756 _dbus_object_tree_unref (connection->objects);
2757
2758 _dbus_hash_table_unref (connection->pending_replies);
2759 connection->pending_replies = NULL;
2760
2761 _dbus_list_clear (&connection->filter_list);
2762
2763 _dbus_list_foreach (&connection->outgoing_messages,
2764 free_outgoing_message,
2765 connection);
2766 _dbus_list_clear (&connection->outgoing_messages);
2767
2768 _dbus_list_foreach (&connection->incoming_messages,
2769 (DBusForeachFunction) dbus_message_unref,
2770 NULL);
2771 _dbus_list_clear (&connection->incoming_messages);
2772
2773 _dbus_counter_unref (connection->outgoing_counter);
2774
2775 _dbus_transport_unref (connection->transport);
2776
2777 if (connection->disconnect_message_link)
2778 {
2779 DBusMessage *message = connection->disconnect_message_link->data;
2780 dbus_message_unref (message);
2781 _dbus_list_free_link (connection->disconnect_message_link);
2782 }
2783
2784 _dbus_condvar_free_at_location (&connection->dispatch_cond);
2785 _dbus_condvar_free_at_location (&connection->io_path_cond);
2786
2787 _dbus_cmutex_free_at_location (&connection->io_path_mutex);
2788 _dbus_cmutex_free_at_location (&connection->dispatch_mutex);
2789
2790 _dbus_rmutex_free_at_location (&connection->slot_mutex);
2791
2792 _dbus_rmutex_free_at_location (&connection->mutex);
2793
2794 dbus_free (connection);
2795 }
2796
2816 void
2817 dbus_connection_unref (DBusConnection *connection)
2818 {
2819 dbus_int32_t old_refcount;
2820
2821 _dbus_return_if_fail (connection != NULL);
2822 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
2823
2824 old_refcount = _dbus_atomic_dec (&connection->refcount);
2825
2826 _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1,
2827 "unref");
2828
2829 if (old_refcount == 1)
2830 {
2831 #ifndef DBUS_DISABLE_CHECKS
2832 if (_dbus_transport_get_is_connected (connection->transport))
2833 {
2834 _dbus_warn_check_failed ("The last reference on a connection was dropped without closing the connection. This is a bug in an application. See dbus_connection_unref() documentation for details.\n%s",
2835 connection->shareable ?
2836 "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" :
2837 "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n");
2838 return;
2839 }
2840 #endif
2841 _dbus_connection_last_unref (connection);
2842 }
2843 }
2844
2845 /*
2846 * Note that the transport can disconnect itself (other end drops us)
2847 * and in that case this function never runs. So this function must
2848 * not do anything more than disconnect the transport and update the
2849 * dispatch status.
2850 *
2851 * If the transport self-disconnects, then we assume someone will
2852 * dispatch the connection to cause the dispatch status update.
2853 */
2854 static void
2855 _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection)
2856 {
2857 DBusDispatchStatus status;
2858
2859 HAVE_LOCK_CHECK (connection);
2860
2861 _dbus_verbose ("Disconnecting %p\n", connection);
2862
2863 /* We need to ref because update_dispatch_status_and_unlock will unref
2864 * the connection if it was shared and libdbus was the only remaining
2865 * refcount holder.
2866 */
2867 _dbus_connection_ref_unlocked (connection);
2868
2869 _dbus_transport_disconnect (connection->transport);
2870
2871 /* This has the side effect of queuing the disconnect message link
2872 * (unless we don't have enough memory, possibly, so don't assert it).
2873 * After the disconnect message link is queued, dbus_bus_get/dbus_connection_open
2874 * should never again return the newly-disconnected connection.
2875 *
2876 * However, we only unref the shared connection and exit_on_disconnect when
2877 * the disconnect message reaches the head of the message queue,
2878 * NOT when it's first queued.
2879 */
2880 status = _dbus_connection_get_dispatch_status_unlocked (connection);
2881
2882 /* This calls out to user code */
2883 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2884
2885 /* Could also call out to user code */
2886 dbus_connection_unref (connection);
2887 }
2888
2931 void
2932 dbus_connection_close (DBusConnection *connection)
2933 {
2934 _dbus_return_if_fail (connection != NULL);
2935 _dbus_return_if_fail (connection->generation == _dbus_current_generation);
2936
2937 CONNECTION_LOCK (connection);
2938
2939 #ifndef DBUS_DISABLE_CHECKS
2940 if (connection->shareable)
2941 {
2942 CONNECTION_UNLOCK (connection);
2943
2944 _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n");
2945 return;
2946 }
2947 #endif
2948
2949 _dbus_connection_close_possibly_shared_and_unlock (connection);
2950 }
2951
2952 static dbus_bool_t
2953 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
2954 {
2955 HAVE_LOCK_CHECK (connection);
2956 return _dbus_transport_get_is_connected (connection->transport);
2957 }
2958
2972 dbus_bool_t
2973 dbus_connection_get_is_connected (DBusConnection *connection)
2974 {
2975 dbus_bool_t res;
2976
2977 _dbus_return_val_if_fail (connection != NULL, FALSE);
2978
2979 CONNECTION_LOCK (connection);
2980 res = _dbus_connection_get_is_connected_unlocked (connection);
2981 CONNECTION_UNLOCK (connection);
2982
2983 return res;
2984 }
2985
2994 dbus_bool_t
2995 dbus_connection_get_is_authenticated (DBusConnection *connection)
2996 {
2997 dbus_bool_t res;
2998
2999 _dbus_return_val_if_fail (connection != NULL, FALSE);
3000
3001 CONNECTION_LOCK (connection);
3002 res = _dbus_transport_try_to_authenticate (connection->transport);
3003 CONNECTION_UNLOCK (connection);
3004
3005 return res;
3006 }
3007
3028 dbus_bool_t
3029 dbus_connection_get_is_anonymous (DBusConnection *connection)
3030 {
3031 dbus_bool_t res;
3032
3033 _dbus_return_val_if_fail (connection != NULL, FALSE);
3034
3035 CONNECTION_LOCK (connection);
3036 res = _dbus_transport_get_is_anonymous (connection->transport);
3037 CONNECTION_UNLOCK (connection);
3038
3039 return res;
3040 }
3041
3073 char*
3074 dbus_connection_get_server_id (DBusConnection *connection)
3075 {
3076 char *id;
3077
3078 _dbus_return_val_if_fail (connection != NULL, NULL);
3079
3080 CONNECTION_LOCK (connection);
3081 id = _dbus_strdup (_dbus_transport_get_server_id (connection->transport));
3082 CONNECTION_UNLOCK (connection);
3083
3084 return id;
3085 }
3086
3104 dbus_bool_t
3105 dbus_connection_can_send_type(DBusConnection *connection,
3106 int type)
3107 {
3108 _dbus_return_val_if_fail (connection != NULL, FALSE);
3109
3110 if (!dbus_type_is_valid (type))
3111 return FALSE;
3112
3113 if (type != DBUS_TYPE_UNIX_FD)
3114 return TRUE;
3115
3116 #ifdef HAVE_UNIX_FD_PASSING
3117 {
3118 dbus_bool_t b;
3119
3120 CONNECTION_LOCK(connection);
3121 b = _dbus_transport_can_pass_unix_fd(connection->transport);
3122 CONNECTION_UNLOCK(connection);
3123
3124 return b;
3125 }
3126 #endif
3127
3128 return FALSE;
3129 }
3130
3144 void
3145 dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
3146 dbus_bool_t exit_on_disconnect)
3147 {
3148 _dbus_return_if_fail (connection != NULL);
3149
3150 CONNECTION_LOCK (connection);
3151 connection->exit_on_disconnect = exit_on_disconnect != FALSE;
3152 CONNECTION_UNLOCK (connection);
3153 }
3154
3164 DBusPreallocatedSend*
3165 dbus_connection_preallocate_send (DBusConnection *connection)
3166 {
3167 DBusPreallocatedSend *preallocated;
3168
3169 _dbus_return_val_if_fail (connection != NULL, NULL);
3170
3171 CONNECTION_LOCK (connection);
3172
3173 preallocated =
3174 _dbus_connection_preallocate_send_unlocked (connection);
3175
3176 CONNECTION_UNLOCK (connection);
3177
3178 return preallocated;
3179 }
3180
3190 void
3191 dbus_connection_free_preallocated_send (DBusConnection *connection,
3192 DBusPreallocatedSend *preallocated)
3193 {
3194 _dbus_return_if_fail (connection != NULL);
3195 _dbus_return_if_fail (preallocated != NULL);
3196 _dbus_return_if_fail (connection == preallocated->connection);
3197
3198 _dbus_list_free_link (preallocated->queue_link);
3199 _dbus_counter_unref (preallocated->counter_link->data);
3200 _dbus_list_free_link (preallocated->counter_link);
3201 dbus_free (preallocated);
3202 }
3203
3216 void
3217 dbus_connection_send_preallocated (DBusConnection *connection,
3218 DBusPreallocatedSend *preallocated,
3219 DBusMessage *message,
3220 dbus_uint32_t *client_serial)
3221 {
3222 _dbus_return_if_fail (connection != NULL);
3223 _dbus_return_if_fail (preallocated != NULL);
3224 _dbus_return_if_fail (message != NULL);
3225 _dbus_return_if_fail (preallocated->connection == connection);
3226 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
3227 dbus_message_get_member (message) != NULL);
3228 _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
3229 (dbus_message_get_interface (message) != NULL &&
3230 dbus_message_get_member (message) != NULL));
3231
3232 CONNECTION_LOCK (connection);
3233
3234 #ifdef HAVE_UNIX_FD_PASSING
3235
3236 if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
3237 message->n_unix_fds > 0)
3238 {
3239 /* Refuse to send fds on a connection that cannot handle
3240 them. Unfortunately we cannot return a proper error here, so
3241 the best we can is just return. */
3242 CONNECTION_UNLOCK (connection);
3243 return;
3244 }
3245
3246 #endif
3247
3248 _dbus_connection_send_preallocated_and_unlock (connection,
3249 preallocated,
3250 message, client_serial);
3251 }
3252
3253 static dbus_bool_t
3254 _dbus_connection_send_unlocked_no_update (DBusConnection *connection,
3255 DBusMessage *message,
3256 dbus_uint32_t *client_serial)
3257 {
3258 DBusPreallocatedSend *preallocated;
3259
3260 _dbus_assert (connection != NULL);
3261 _dbus_assert (message != NULL);
3262
3263 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
3264 if (preallocated == NULL)
3265 return FALSE;
3266
3267 _dbus_connection_send_preallocated_unlocked_no_update (connection,
3268 preallocated,
3269 message,
3270 client_serial);
3271 return TRUE;
3272 }
3273
3301 dbus_bool_t
3302 dbus_connection_send (DBusConnection *connection,
3303 DBusMessage *message,
3304 dbus_uint32_t *serial)
3305 {
3306 _dbus_return_val_if_fail (connection != NULL, FALSE);
3307 _dbus_return_val_if_fail (message != NULL, FALSE);
3308
3309 CONNECTION_LOCK (connection);
3310
3311 #ifdef HAVE_UNIX_FD_PASSING
3312
3313 if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
3314 message->n_unix_fds > 0)
3315 {
3316 /* Refuse to send fds on a connection that cannot handle
3317 them. Unfortunately we cannot return a proper error here, so
3318 the best we can is just return. */
3319 CONNECTION_UNLOCK (connection);
3320 return FALSE;
3321 }
3322
3323 #endif
3324
3325 return _dbus_connection_send_and_unlock (connection,
3326 message,
3327 serial);
3328 }
3329
3330 static dbus_bool_t
3331 reply_handler_timeout (void *data)
3332 {
3333 DBusConnection *connection;
3334 DBusDispatchStatus status;
3335 DBusPendingCall *pending = data;
3336
3337 connection = _dbus_pending_call_get_connection_and_lock (pending);
3338 _dbus_connection_ref_unlocked (connection);
3339
3340 _dbus_pending_call_queue_timeout_error_unlocked (pending,
3341 connection);
3342 _dbus_connection_remove_timeout_unlocked (connection,
3343 _dbus_pending_call_get_timeout_unlocked (pending));
3344 _dbus_pending_call_set_timeout_added_unlocked (pending, FALSE);
3345
3346 _dbus_verbose ("middle\n");
3347 status = _dbus_connection_get_dispatch_status_unlocked (connection);
3348
3349 /* Unlocks, and calls out to user code */
3350 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3351 dbus_connection_unref (connection);
3352
3353 return TRUE;
3354 }
3355
3398 dbus_bool_t
3399 dbus_connection_send_with_reply (DBusConnection *connection,
3400 DBusMessage *message,
3401 DBusPendingCall **pending_return,
3402 int timeout_milliseconds)
3403 {
3404 DBusPendingCall *pending;
3405 dbus_int32_t serial = -1;
3406 DBusDispatchStatus status;
3407
3408 _dbus_return_val_if_fail (connection != NULL, FALSE);
3409 _dbus_return_val_if_fail (message != NULL, FALSE);
3410 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
3411
3412 if (pending_return)
3413 *pending_return = NULL;
3414
3415 CONNECTION_LOCK (connection);
3416
3417 #ifdef HAVE_UNIX_FD_PASSING
3418
3419 if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
3420 message->n_unix_fds > 0)
3421 {
3422 /* Refuse to send fds on a connection that cannot handle
3423 them. Unfortunately we cannot return a proper error here, so
3424 the best we can do is return TRUE but leave *pending_return
3425 as NULL. */
3426 CONNECTION_UNLOCK (connection);
3427 return TRUE;
3428 }
3429
3430 #endif
3431
3432 if (!_dbus_connection_get_is_connected_unlocked (connection))
3433 {
3434 CONNECTION_UNLOCK (connection);
3435
3436 return TRUE;
3437 }
3438
3439 pending = _dbus_pending_call_new_unlocked (connection,
3440 timeout_milliseconds,
3441 reply_handler_timeout);
3442
3443 if (pending == NULL)
3444 {
3445 CONNECTION_UNLOCK (connection);
3446 return FALSE;
3447 }
3448
3449 /* Assign a serial to the message */
3450 serial = dbus_message_get_serial (message);
3451 if (serial == 0)
3452 {
3453 serial = _dbus_connection_get_next_client_serial (connection);
3454 dbus_message_set_serial (message, serial);
3455 }
3456
3457 if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
3458 goto error;
3459
3460 /* Insert the serial in the pending replies hash;
3461 * hash takes a refcount on DBusPendingCall.
3462 * Also, add the timeout.
3463 */
3464 if (!_dbus_connection_attach_pending_call_unlocked (connection,
3465 pending))
3466 goto error;
3467
3468 if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
3469 {
3470 _dbus_connection_detach_pending_call_and_unlock (connection,
3471 pending);
3472 goto error_unlocked;
3473 }
3474
3475 if (pending_return)
3476 *pending_return = pending; /* hand off refcount */
3477 else
3478 {
3479 _dbus_connection_detach_pending_call_unlocked (connection, pending);
3480 /* we still have a ref to the pending call in this case, we unref
3481 * after unlocking, below
3482 */
3483 }
3484
3485 status = _dbus_connection_get_dispatch_status_unlocked (connection);
3486
3487 /* this calls out to user code */
3488 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3489
3490 if (pending_return == NULL)
3491 dbus_pending_call_unref (pending);
3492
3493 return TRUE;
3494
3495 error:
3496 CONNECTION_UNLOCK (connection);
3497 error_unlocked:
3498 dbus_pending_call_unref (pending);
3499 return FALSE;
3500 }
3501
3534 DBusMessage*
3535 dbus_connection_send_with_reply_and_block (DBusConnection *connection,
3536 DBusMessage *message,
3537 int timeout_milliseconds,
3538 DBusError *error)
3539 {
3540 DBusMessage *reply;
3541 DBusPendingCall *pending;
3542
3543 _dbus_return_val_if_fail (connection != NULL, NULL);
3544 _dbus_return_val_if_fail (message != NULL, NULL);
3545 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL);
3546 _dbus_return_val_if_error_is_set (error, NULL);
3547
3548 #ifdef HAVE_UNIX_FD_PASSING
3549
3550 CONNECTION_LOCK (connection);
3551 if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
3552 message->n_unix_fds > 0)
3553 {
3554 CONNECTION_UNLOCK (connection);
3555 dbus_set_error(error, DBUS_ERROR_FAILED, "Cannot send file descriptors on this connection.");
3556 return NULL;
3557 }
3558 CONNECTION_UNLOCK (connection);
3559
3560 #endif
3561
3562 if (!dbus_connection_send_with_reply (connection, message,
3563 &pending, timeout_milliseconds))
3564 {
3565 _DBUS_SET_OOM (error);
3566 return NULL;
3567 }
3568
3569 if (pending == NULL)
3570 {
3571 dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Connection is closed");
3572 return NULL;
3573 }
3574
3575 dbus_pending_call_block (pending);
3576
3577 reply = dbus_pending_call_steal_reply (pending);
3578 dbus_pending_call_unref (pending);
3579
3580 /* call_complete_and_unlock() called from pending_call_block() should
3581 * always fill this in.
3582 */
3583 _dbus_assert (reply != NULL);
3584
3585 if (dbus_set_error_from_message (error, reply))
3586 {
3587 dbus_message_unref (reply);
3588 return NULL;
3589 }
3590 else
3591 return reply;
3592 }
3593
3602 static DBusDispatchStatus
3603 _dbus_connection_flush_unlocked (DBusConnection *connection)
3604 {
3605 /* We have to specify DBUS_ITERATION_DO_READING here because
3606 * otherwise we could have two apps deadlock if they are both doing
3607 * a flush(), and the kernel buffers fill up. This could change the
3608 * dispatch status.
3609 */
3610 DBusDispatchStatus status;
3611
3612 HAVE_LOCK_CHECK (connection);
3613
3614 while (connection->n_outgoing > 0 &&
3615 _dbus_connection_get_is_connected_unlocked (connection))
3616 {
3617 _dbus_verbose ("doing iteration in\n");
3618 HAVE_LOCK_CHECK (connection);
3619 _dbus_connection_do_iteration_unlocked (connection,
3620 NULL,
3621 DBUS_ITERATION_DO_READING |
3622 DBUS_ITERATION_DO_WRITING |
3623 DBUS_ITERATION_BLOCK,
3624 -1);
3625 }
3626
3627 HAVE_LOCK_CHECK (connection);
3628 _dbus_verbose ("middle\n");
3629 status = _dbus_connection_get_dispatch_status_unlocked (connection);
3630
3631 HAVE_LOCK_CHECK (connection);
3632 return status;
3633 }
3634
3640 void
3641 dbus_connection_flush (DBusConnection *connection)
3642 {
3643 /* We have to specify DBUS_ITERATION_DO_READING here because
3644 * otherwise we could have two apps deadlock if they are both doing
3645 * a flush(), and the kernel buffers fill up. This could change the
3646 * dispatch status.
3647 */
3648 DBusDispatchStatus status;
3649
3650 _dbus_return_if_fail (connection != NULL);
3651
3652 CONNECTION_LOCK (connection);
3653
3654 status = _dbus_connection_flush_unlocked (connection);
3655
3656 HAVE_LOCK_CHECK (connection);
3657 /* Unlocks and calls out to user code */
3658 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3659
3660 _dbus_verbose ("end\n");
3661 }
3662
3673 static dbus_bool_t
3674 _dbus_connection_read_write_dispatch (DBusConnection *connection,
3675 int timeout_milliseconds,
3676 dbus_bool_t dispatch)
3677 {
3678 DBusDispatchStatus dstatus;
3679 dbus_bool_t progress_possible;
3680
3681 /* Need to grab a ref here in case we're a private connection and
3682 * the user drops the last ref in a handler we call; see bug
3683 * https://bugs.freedesktop.org/show_bug.cgi?id=15635
3684 */
3685 dbus_connection_ref (connection);
3686 dstatus = dbus_connection_get_dispatch_status (connection);
3687
3688 if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
3689 {
3690 _dbus_verbose ("doing dispatch\n");
3691 dbus_connection_dispatch (connection);
3692 CONNECTION_LOCK (connection);
3693 }
3694 else if (dstatus == DBUS_DISPATCH_NEED_MEMORY)
3695 {
3696 _dbus_verbose ("pausing for memory\n");
3697 _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
3698 CONNECTION_LOCK (connection);
3699 }
3700 else
3701 {
3702 CONNECTION_LOCK (connection);
3703 if (_dbus_connection_get_is_connected_unlocked (connection))
3704 {
3705 _dbus_verbose ("doing iteration\n");
3706 _dbus_connection_do_iteration_unlocked (connection,
3707 NULL,
3708 DBUS_ITERATION_DO_READING |
3709 DBUS_ITERATION_DO_WRITING |
3710 DBUS_ITERATION_BLOCK,
3711 timeout_milliseconds);
3712 }
3713 }
3714
3715 HAVE_LOCK_CHECK (connection);
3716 /* If we can dispatch, we can make progress until the Disconnected message
3717 * has been processed; if we can only read/write, we can make progress
3718 * as long as the transport is open.
3719 */
3720 if (dispatch)
3721 progress_possible = connection->n_incoming != 0 ||
3722 connection->disconnect_message_link != NULL;
3723 else
3724 progress_possible = _dbus_connection_get_is_connected_unlocked (connection);
3725
3726 CONNECTION_UNLOCK (connection);
3727
3728 dbus_connection_unref (connection);
3729
3730 return progress_possible; /* TRUE if we can make more progress */
3731 }
3732
3733
3768 dbus_bool_t
3769 dbus_connection_read_write_dispatch (DBusConnection *connection,
3770 int timeout_milliseconds)
3771 {
3772 _dbus_return_val_if_fail (connection != NULL, FALSE);
3773 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
3774 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE);
3775 }
3776
3800 dbus_bool_t
3801 dbus_connection_read_write (DBusConnection *connection,
3802 int timeout_milliseconds)
3803 {
3804 _dbus_return_val_if_fail (connection != NULL, FALSE);
3805 _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
3806 return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE);
3807 }
3808
3809 /* We need to call this anytime we pop the head of the queue, and then
3810 * update_dispatch_status_and_unlock needs to be called afterward
3811 * which will "process" the disconnected message and set
3812 * disconnected_message_processed.
3813 */
3814 static void
3815 check_disconnected_message_arrived_unlocked (DBusConnection *connection,
3816 DBusMessage *head_of_queue)
3817 {
3818 HAVE_LOCK_CHECK (connection);
3819
3820 /* checking that the link is NULL is an optimization to avoid the is_signal call */
3821 if (connection->disconnect_message_link == NULL &&
3822 dbus_message_is_signal (head_of_queue,
3823 DBUS_INTERFACE_LOCAL,
3824 "Disconnected"))
3825 {
3826 connection->disconnected_message_arrived = TRUE;
3827 }
3828 }
3829
3849 DBusMessage*
3850 dbus_connection_borrow_message (DBusConnection *connection)
3851 {
3852 DBusDispatchStatus status;
3853 DBusMessage *message;
3854
3855 _dbus_return_val_if_fail (connection != NULL, NULL);
3856
3857 _dbus_verbose ("start\n");
3858
3859 /* this is called for the side effect that it queues
3860 * up any messages from the transport
3861 */
3862 status = dbus_connection_get_dispatch_status (connection);
3863 if (status != DBUS_DISPATCH_DATA_REMAINS)
3864 return NULL;
3865
3866 CONNECTION_LOCK (connection);
3867
3868 _dbus_connection_acquire_dispatch (connection);
3869
3870 /* While a message is outstanding, the dispatch lock is held */
3871 _dbus_assert (connection->message_borrowed == NULL);
3872
3873 connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
3874
3875 message = connection->message_borrowed;
3876
3877 check_disconnected_message_arrived_unlocked (connection, message);
3878
3879 /* Note that we KEEP the dispatch lock until the message is returned */
3880 if (message == NULL)
3881 _dbus_connection_release_dispatch (connection);
3882
3883 CONNECTION_UNLOCK (connection);
3884
3885 _dbus_message_trace_ref (message, -1, -1, "dbus_connection_borrow_message");
3886
3887 /* We don't update dispatch status until it's returned or stolen */
3888
3889 return message;
3890 }
3891
3900 void
3901 dbus_connection_return_message (DBusConnection *connection,
3902 DBusMessage *message)
3903 {
3904 DBusDispatchStatus status;
3905
3906 _dbus_return_if_fail (connection != NULL);
3907 _dbus_return_if_fail (message != NULL);
3908 _dbus_return_if_fail (message == connection->message_borrowed);
3909 _dbus_return_if_fail (connection->dispatch_acquired);
3910
3911 CONNECTION_LOCK (connection);
3912
3913 _dbus_assert (message == connection->message_borrowed);
3914
3915 connection->message_borrowed = NULL;
3916
3917 _dbus_connection_release_dispatch (connection);
3918
3919 status = _dbus_connection_get_dispatch_status_unlocked (connection);
3920 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3921
3922 _dbus_message_trace_ref (message, -1, -1, "dbus_connection_return_message");
3923 }
3924
3934 void
3935 dbus_connection_steal_borrowed_message (DBusConnection *connection,
3936 DBusMessage *message)
3937 {
3938 DBusMessage *pop_message;
3939 DBusDispatchStatus status;
3940
3941 _dbus_return_if_fail (connection != NULL);
3942 _dbus_return_if_fail (message != NULL);
3943 _dbus_return_if_fail (message == connection->message_borrowed);
3944 _dbus_return_if_fail (connection->dispatch_acquired);
3945
3946 CONNECTION_LOCK (connection);
3947
3948 _dbus_assert (message == connection->message_borrowed);
3949
3950 pop_message = _dbus_list_pop_first (&connection->incoming_messages);
3951 _dbus_assert (message == pop_message);
3952 (void) pop_message; /* unused unless asserting */
3953
3954 connection->n_incoming -= 1;
3955
3956 _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
3957 message, connection->n_incoming);
3958
3959 connection->message_borrowed = NULL;
3960
3961 _dbus_connection_release_dispatch (connection);
3962
3963 status = _dbus_connection_get_dispatch_status_unlocked (connection);
3964 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3965 _dbus_message_trace_ref (message, -1, -1,
3966 "dbus_connection_steal_borrowed_message");
3967 }
3968
3969 /* See dbus_connection_pop_message, but requires the caller to own
3970 * the lock before calling. May drop the lock while running.
3971 */
3972 static DBusList*
3973 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
3974 {
3975 HAVE_LOCK_CHECK (connection);
3976
3977 _dbus_assert (connection->message_borrowed == NULL);
3978
3979 if (connection->n_incoming > 0)
3980 {
3981 DBusList *link;
3982
3983 link = _dbus_list_pop_first_link (&connection->incoming_messages);
3984 connection->n_incoming -= 1;
3985
3986 _dbus_verbose ("Message %p (%s %s %s %s sig:'%s' serial:%u) removed from incoming queue %p, %d incoming\n",
3987 link->data,
3988 dbus_message_type_to_string (dbus_message_get_type (link->data)),
3989 dbus_message_get_path (link->data) ?
3990 dbus_message_get_path (link->data) :
3991 "no path",
3992 dbus_message_get_interface (link->data) ?
3993 dbus_message_get_interface (link->data) :
3994 "no interface",
3995 dbus_message_get_member (link->data) ?
3996 dbus_message_get_member (link->data) :
3997 "no member",
3998 dbus_message_get_signature (link->data),
3999 dbus_message_get_serial (link->data),
4000 connection, connection->n_incoming);
4001
4002 _dbus_message_trace_ref (link->data, -1, -1,
4003 "_dbus_connection_pop_message_link_unlocked");
4004
4005 check_disconnected_message_arrived_unlocked (connection, link->data);
4006
4007 return link;
4008 }
4009 else
4010 return NULL;
4011 }
4012
4013 /* See dbus_connection_pop_message, but requires the caller to own
4014 * the lock before calling. May drop the lock while running.
4015 */
4016 static DBusMessage*
4017 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
4018 {
4019 DBusList *link;
4020
4021 HAVE_LOCK_CHECK (connection);
4022
4023 link = _dbus_connection_pop_message_link_unlocked (connection);
4024
4025 if (link != NULL)
4026 {
4027 DBusMessage *message;
4028
4029 message = link->data;
4030
4031 _dbus_list_free_link (link);
4032
4033 return message;
4034 }
4035 else
4036 return NULL;
4037 }
4038
4039 static void
4040 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
4041 DBusList *message_link)
4042 {
4043 HAVE_LOCK_CHECK (connection);
4044
4045 _dbus_assert (message_link != NULL);
4046 /* You can't borrow a message while a link is outstanding */
4047 _dbus_assert (connection->message_borrowed == NULL);
4048 /* We had to have the dispatch lock across the pop/putback */
4049 _dbus_assert (connection->dispatch_acquired);
4050
4051 _dbus_list_prepend_link (&connection->incoming_messages,
4052 message_link);
4053 connection->n_incoming += 1;
4054
4055 _dbus_verbose ("Message %p (%s %s %s '%s') put back into queue %p, %d incoming\n",
4056 message_link->data,
4057 dbus_message_type_to_string (dbus_message_get_type (message_link->data)),
4058 dbus_message_get_interface (message_link->data) ?
4059 dbus_message_get_interface (message_link->data) :
4060 "no interface",
4061 dbus_message_get_member (message_link->data) ?
4062 dbus_message_get_member (message_link->data) :
4063 "no member",
4064 dbus_message_get_signature (message_link->data),
4065 connection, connection->n_incoming);
4066
4067 _dbus_message_trace_ref (message_link->data, -1, -1,
4068 "_dbus_connection_putback_message_link_unlocked");
4069 }
4070
4090 DBusMessage*
4091 dbus_connection_pop_message (DBusConnection *connection)
4092 {
4093 DBusMessage *message;
4094 DBusDispatchStatus status;
4095
4096 _dbus_verbose ("start\n");
4097
4098 /* this is called for the side effect that it queues
4099 * up any messages from the transport
4100 */
4101 status = dbus_connection_get_dispatch_status (connection);
4102 if (status != DBUS_DISPATCH_DATA_REMAINS)
4103 return NULL;
4104
4105 CONNECTION_LOCK (connection);
4106 _dbus_connection_acquire_dispatch (connection);
4107 HAVE_LOCK_CHECK (connection);
4108
4109 message = _dbus_connection_pop_message_unlocked (connection);
4110
4111 _dbus_verbose ("Returning popped message %p\n", message);
4112
4113 _dbus_connection_release_dispatch (connection);
4114
4115 status = _dbus_connection_get_dispatch_status_unlocked (connection);
4116 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
4117
4118 return message;
4119 }
4120
4128 static void
4129 _dbus_connection_acquire_dispatch (DBusConnection *connection)
4130 {
4131 HAVE_LOCK_CHECK (connection);
4132
4133 _dbus_connection_ref_unlocked (connection);
4134 CONNECTION_UNLOCK (connection);
4135
4136 _dbus_verbose ("locking dispatch_mutex\n");
4137 _dbus_cmutex_lock (connection->dispatch_mutex);
4138
4139 while (connection->dispatch_acquired)
4140 {
4141 _dbus_verbose ("waiting for dispatch to be acquirable\n");
4142 _dbus_condvar_wait (connection->dispatch_cond,
4143 connection->dispatch_mutex);
4144 }
4145
4146 _dbus_assert (!connection->dispatch_acquired);
4147
4148 connection->dispatch_acquired = TRUE;
4149
4150 _dbus_verbose ("unlocking dispatch_mutex\n");
4151 _dbus_cmutex_unlock (connection->dispatch_mutex);
4152
4153 CONNECTION_LOCK (connection);
4154 _dbus_connection_unref_unlocked (connection);
4155 }
4156
4164 static void
4165 _dbus_connection_release_dispatch (DBusConnection *connection)
4166 {
4167 HAVE_LOCK_CHECK (connection);
4168
4169 _dbus_verbose ("locking dispatch_mutex\n");
4170 _dbus_cmutex_lock (connection->dispatch_mutex);
4171
4172 _dbus_assert (connection->dispatch_acquired);
4173
4174 connection->dispatch_acquired = FALSE;
4175 _dbus_condvar_wake_one (connection->dispatch_cond);
4176
4177 _dbus_verbose ("unlocking dispatch_mutex\n");
4178 _dbus_cmutex_unlock (connection->dispatch_mutex);
4179 }
4180
4181 static void
4182 _dbus_connection_failed_pop (DBusConnection *connection,
4183 DBusList *message_link)
4184 {
4185 _dbus_list_prepend_link (&connection->incoming_messages,
4186 message_link);
4187 connection->n_incoming += 1;
4188 }
4189
4190 /* Note this may be called multiple times since we don't track whether we already did it */
4191 static void
4192 notify_disconnected_unlocked (DBusConnection *connection)
4193 {
4194 HAVE_LOCK_CHECK (connection);
4195
4196 /* Set the weakref in dbus-bus.c to NULL, so nobody will get a disconnected
4197 * connection from dbus_bus_get(). We make the same guarantee for
4198 * dbus_connection_open() but in a different way since we don't want to
4199 * unref right here; we instead check for connectedness before returning
4200 * the connection from the hash.
4201 */
4202 _dbus_bus_notify_shared_connection_disconnected_unlocked (connection);
4203
4204 /* Dump the outgoing queue, we aren't going to be able to
4205 * send it now, and we'd like accessors like
4206 * dbus_connection_get_outgoing_size() to be accurate.
4207 */
4208 if (connection->n_outgoing > 0)
4209 {
4210 DBusList *link;
4211
4212 _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
4213 connection->n_outgoing);
4214
4215 while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
4216 {
4217 _dbus_connection_message_sent_unlocked (connection, link->data);
4218 }
4219 }
4220 }
4221
4222 /* Note this may be called multiple times since we don't track whether we already did it */
4223 static DBusDispatchStatus
4224 notify_disconnected_and_dispatch_complete_unlocked (DBusConnection *connection)
4225 {
4226 HAVE_LOCK_CHECK (connection);
4227
4228 if (connection->disconnect_message_link != NULL)
4229 {
4230 _dbus_verbose ("Sending disconnect message\n");
4231
4232 /* If we have pending calls, queue their timeouts - we want the Disconnected
4233 * to be the last message, after these timeouts.
4234 */
4235 connection_timeout_and_complete_all_pending_calls_unlocked (connection);
4236
4237 /* We haven't sent the disconnect message already,
4238 * and all real messages have been queued up.
4239 */
4240 _dbus_connection_queue_synthesized_message_link (connection,
4241 connection->disconnect_message_link);
4242 connection->disconnect_message_link = NULL;
4243
4244 return DBUS_DISPATCH_DATA_REMAINS;
4245 }
4246
4247 return DBUS_DISPATCH_COMPLETE;
4248 }
4249
4250 static DBusDispatchStatus
4251 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
4252 {
4253 HAVE_LOCK_CHECK (connection);
4254
4255 if (connection->n_incoming > 0)
4256 return DBUS_DISPATCH_DATA_REMAINS;
4257 else if (!_dbus_transport_queue_messages (connection->transport))
4258 return DBUS_DISPATCH_NEED_MEMORY;
4259 else
4260 {
4261 DBusDispatchStatus status;
4262 dbus_bool_t is_connected;
4263
4264 status = _dbus_transport_get_dispatch_status (connection->transport);
4265 is_connected = _dbus_transport_get_is_connected (connection->transport);
4266
4267 _dbus_verbose ("dispatch status = %s is_connected = %d\n",
4268 DISPATCH_STATUS_NAME (status), is_connected);
4269
4270 if (!is_connected)
4271 {
4272 /* It's possible this would be better done by having an explicit
4273 * notification from _dbus_transport_disconnect() that would
4274 * synchronously do this, instead of waiting for the next dispatch
4275 * status check. However, probably not good to change until it causes
4276 * a problem.
4277 */
4278 notify_disconnected_unlocked (connection);
4279
4280 /* I'm not sure this is needed; the idea is that we want to
4281 * queue the Disconnected only after we've read all the
4282 * messages, but if we're disconnected maybe we are guaranteed
4283 * to have read them all ?
4284 */
4285 if (status == DBUS_DISPATCH_COMPLETE)
4286 status = notify_disconnected_and_dispatch_complete_unlocked (connection);
4287 }
4288
4289 if (status != DBUS_DISPATCH_COMPLETE)
4290 return status;
4291 else if (connection->n_incoming > 0)
4292 return DBUS_DISPATCH_DATA_REMAINS;
4293 else
4294 return DBUS_DISPATCH_COMPLETE;
4295 }
4296 }
4297
4298 static void
4299 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
4300 DBusDispatchStatus new_status)
4301 {
4302 dbus_bool_t changed;
4303 DBusDispatchStatusFunction function;
4304 void *data;
4305
4306 HAVE_LOCK_CHECK (connection);
4307
4308 _dbus_connection_ref_unlocked (connection);
4309
4310 changed = new_status != connection->last_dispatch_status;
4311
4312 connection->last_dispatch_status = new_status;
4313
4314 function = connection->dispatch_status_function;
4315 data = connection->dispatch_status_data;
4316
4317 if (connection->disconnected_message_arrived &&
4318 !connection->disconnected_message_processed)
4319 {
4320 connection->disconnected_message_processed = TRUE;
4321
4322 /* this does an unref, but we have a ref
4323 * so we should not run the finalizer here
4324 * inside the lock.
4325 */
4326 connection_forget_shared_unlocked (connection);
4327
4328 if (connection->exit_on_disconnect)
4329 {
4330 CONNECTION_UNLOCK (connection);
4331
4332 _dbus_verbose ("Exiting on Disconnected signal\n");
4333 _dbus_exit (1);
4334 _dbus_assert_not_reached ("Call to exit() returned");
4335 }
4336 }
4337
4338 /* We drop the lock */
4339 CONNECTION_UNLOCK (connection);
4340
4341 if (changed && function)
4342 {
4343 _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
4344 connection, new_status,
4345 DISPATCH_STATUS_NAME (new_status));
4346 (* function) (connection, new_status, data);
4347 }
4348
4349 dbus_connection_unref (connection);
4350 }
4351
4377 DBusDispatchStatus
4378 dbus_connection_get_dispatch_status (DBusConnection *connection)
4379 {
4380 DBusDispatchStatus status;
4381
4382 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
4383
4384 _dbus_verbose ("start\n");
4385
4386 CONNECTION_LOCK (connection);
4387
4388 status = _dbus_connection_get_dispatch_status_unlocked (connection);
4389
4390 CONNECTION_UNLOCK (connection);
4391
4392 return status;
4393 }
4394
4398 static DBusHandlerResult
4399 _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
4400 DBusMessage *message)
4401 {
4402 dbus_bool_t sent = FALSE;
4403 DBusMessage *ret = NULL;
4404 DBusList *expire_link;
4405
4406 if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
4407 {
4408 /* This means we're letting the bus route this message */
4409 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
4410 }
4411
4412 if (!dbus_message_has_interface (message, DBUS_INTERFACE_PEER))
4413 {
4414 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
4415 }
4416
4417 /* Preallocate a linked-list link, so that if we need to dispose of a
4418 * message, we can attach it to the expired list */
4419 expire_link = _dbus_list_alloc_link (NULL);
4420
4421 if (!expire_link)
4422 return DBUS_HANDLER_RESULT_NEED_MEMORY;
4423
4424 if (dbus_message_is_method_call (message,
4425 DBUS_INTERFACE_PEER,
4426 "Ping"))
4427 {
4428 ret = dbus_message_new_method_return (message);
4429 if (ret == NULL)
4430 goto out;
4431
4432 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
4433 }
4434 else if (dbus_message_is_method_call (message,
4435 DBUS_INTERFACE_PEER,
4436 "GetMachineId"))
4437 {
4438 DBusString uuid;
4439 DBusError error = DBUS_ERROR_INIT;
4440
4441 if (!_dbus_string_init (&uuid))
4442 goto out;
4443
4444 if (_dbus_get_local_machine_uuid_encoded (&uuid, &error))
4445 {
4446 const char *v_STRING;
4447
4448 ret = dbus_message_new_method_return (message);
4449
4450 if (ret == NULL)
4451 {
4452 _dbus_string_free (&uuid);
4453 goto out;
4454 }
4455
4456 v_STRING = _dbus_string_get_const_data (&uuid);
4457 if (dbus_message_append_args (ret,
4458 DBUS_TYPE_STRING, &v_STRING,
4459 DBUS_TYPE_INVALID))
4460 {
4461 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
4462 }
4463 }
4464 else if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
4465 {
4466 dbus_error_free (&error);
4467 goto out;
4468 }
4469 else
4470 {
4471 ret = dbus_message_new_error (message, error.name, error.message);
4472 dbus_error_free (&error);
4473
4474 if (ret == NULL)
4475 goto out;
4476
4477 sent = _dbus_connection_send_unlocked_no_update (connection, ret,
4478 NULL);
4479 }
4480
4481 _dbus_string_free (&uuid);
4482 }
4483 else
4484 {
4485 /* We need to bounce anything else with this interface, otherwise apps
4486 * could start extending the interface and when we added extensions
4487 * here to DBusConnection we'd break those apps.
4488 */
4489 ret = dbus_message_new_error (message,
4490 DBUS_ERROR_UNKNOWN_METHOD,
4491 "Unknown method invoked on org.freedesktop.DBus.Peer interface");
4492 if (ret == NULL)
4493 goto out;
4494
4495 sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
4496 }
4497
4498 out:
4499 if (ret == NULL)
4500 {
4501 _dbus_list_free_link (expire_link);
4502 }
4503 else
4504 {
4505 /* It'll be safe to unref the reply when we unlock */
4506 expire_link->data = ret;
4507 _dbus_list_prepend_link (&connection->expired_messages, expire_link);
4508 }
4509
4510 if (!sent)
4511 return DBUS_HANDLER_RESULT_NEED_MEMORY;
4512
4513 return DBUS_HANDLER_RESULT_HANDLED;
4514 }
4515
4522 static DBusHandlerResult
4523 _dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection,
4524 DBusMessage *message)
4525 {
4526 /* We just run one filter for now but have the option to run more
4527 if the spec calls for it in the future */
4528
4529 return _dbus_connection_peer_filter_unlocked_no_update (connection, message);
4530 }
4531
4574 DBusDispatchStatus
4575 dbus_connection_dispatch (DBusConnection *connection)
4576 {
4577 DBusMessage *message;
4578 DBusList *link, *filter_list_copy, *message_link;
4579 DBusHandlerResult result;
4580 DBusPendingCall *pending;
4581 dbus_int32_t reply_serial;
4582 DBusDispatchStatus status;
4583 dbus_bool_t found_object;
4584
4585 _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
4586
4587 _dbus_verbose ("\n");
4588
4589 CONNECTION_LOCK (connection);
4590 status = _dbus_connection_get_dispatch_status_unlocked (connection);
4591 if (status != DBUS_DISPATCH_DATA_REMAINS)
4592 {
4593 /* unlocks and calls out to user code */
4594 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
4595 return status;
4596 }
4597
4598 /* We need to ref the connection since the callback could potentially
4599 * drop the last ref to it
4600 */
4601 _dbus_connection_ref_unlocked (connection);
4602
4603 _dbus_connection_acquire_dispatch (connection);
4604 HAVE_LOCK_CHECK (connection);
4605
4606 message_link = _dbus_connection_pop_message_link_unlocked (connection);
4607 if (message_link == NULL)
4608 {
4609 /* another thread dispatched our stuff */
4610
4611 _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
4612
4613 _dbus_connection_release_dispatch (connection);
4614
4615 status = _dbus_connection_get_dispatch_status_unlocked (connection);
4616
4617 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
4618
4619 dbus_connection_unref (connection);
4620
4621 return status;
4622 }
4623
4624 message = message_link->data;
4625
4626 _dbus_verbose (" dispatching message %p (%s %s %s '%s')\n",
4627 message,
4628 dbus_message_type_to_string (dbus_message_get_type (message)),
4629 dbus_message_get_interface (message) ?
4630 dbus_message_get_interface (message) :
4631 "no interface",
4632 dbus_message_get_member (message) ?
4633 dbus_message_get_member (message) :
4634 "no member",
4635 dbus_message_get_signature (message));
4636
4637 result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
4638
4639 /* Pending call handling must be first, because if you do
4640 * dbus_connection_send_with_reply_and_block() or
4641 * dbus_pending_call_block() then no handlers/filters will be run on
4642 * the reply. We want consistent semantics in the case where we
4643 * dbus_connection_dispatch() the reply.
4644 */
4645
4646 reply_serial = dbus_message_get_reply_serial (message);
4647 pending = _dbus_hash_table_lookup_int (connection->pending_replies,
4648 reply_serial);
4649 if (pending)
4650 {
4651 _dbus_verbose ("Dispatching a pending reply\n");
4652 complete_pending_call_and_unlock (connection, pending, message);
4653 pending = NULL; /* it's probably unref'd */
4654
4655 CONNECTION_LOCK (connection);
4656 _dbus_verbose ("pending call completed in dispatch\n");
4657 result = DBUS_HANDLER_RESULT_HANDLED;
4658 goto out;
4659 }
4660
4661 result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message);
4662 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
4663 goto out;
4664
4665 if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
4666 {
4667 _dbus_connection_release_dispatch (connection);
4668 HAVE_LOCK_CHECK (connection);
4669
4670 _dbus_connection_failed_pop (connection, message_link);
4671
4672 /* unlocks and calls user code */
4673 _dbus_connection_update_dispatch_status_and_unlock (connection,
4674 DBUS_DISPATCH_NEED_MEMORY);
4675 dbus_connection_unref (connection);
4676
4677 return DBUS_DISPATCH_NEED_MEMORY;
4678 }
4679
4680 _dbus_list_foreach (&filter_list_copy,
4681 (DBusForeachFunction)_dbus_message_filter_ref,
4682 NULL);
4683
4684 /* We're still protected from dispatch() reentrancy here
4685 * since we acquired the dispatcher
4686 */
4687 CONNECTION_UNLOCK (connection);
4688
4689 link = _dbus_list_get_first_link (&filter_list_copy);
4690 while (link != NULL)
4691 {
4692 DBusMessageFilter *filter = link->data;
4693 DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
4694
4695 if (filter->function == NULL)
4696 {
4697 _dbus_verbose (" filter was removed in a callback function\n");
4698 link = next;
4699 continue;
4700 }
4701
4702 _dbus_verbose (" running filter on message %p\n", message);
4703 result = (* filter->function) (connection, message, filter->user_data);
4704
4705 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
4706 break;
4707
4708 link = next;
4709 }
4710
4711 _dbus_list_foreach (&filter_list_copy,
4712 (DBusForeachFunction)_dbus_message_filter_unref,
4713 NULL);
4714 _dbus_list_clear (&filter_list_copy);
4715
4716 CONNECTION_LOCK (connection);
4717
4718 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
4719 {
4720 _dbus_verbose ("No memory\n");
4721 goto out;
4722 }
4723 else if (result == DBUS_HANDLER_RESULT_HANDLED)
4724 {
4725 _dbus_verbose ("filter handled message in dispatch\n");
4726 goto out;
4727 }
4728
4729 /* We're still protected from dispatch() reentrancy here
4730 * since we acquired the dispatcher
4731 */
4732 _dbus_verbose (" running object path dispatch on message %p (%s %s %s '%s')\n",
4733 message,
4734 dbus_message_type_to_string (dbus_message_get_type (message)),
4735 dbus_message_get_interface (message) ?
4736 dbus_message_get_interface (message) :
4737 "no interface",
4738 dbus_message_get_member (message) ?
4739 dbus_message_get_member (message) :
4740 "no member",
4741 dbus_message_get_signature (message));
4742
4743 HAVE_LOCK_CHECK (connection);
4744 result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
4745 message,
4746 &found_object);
4747
4748 CONNECTION_LOCK (connection);
4749
4750 if (result != DBUS_HANDLER_RESULT_NOT_YET_HANDLED)
4751 {
4752 _dbus_verbose ("object tree handled message in dispatch\n");
4753 goto out;
4754 }
4755
4756 if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL)
4757 {
4758 DBusMessage *reply;
4759 DBusString str;
4760 DBusPreallocatedSend *preallocated;
4761 DBusList *expire_link;
4762
4763 _dbus_verbose (" sending error %s\n",
4764 DBUS_ERROR_UNKNOWN_METHOD);
4765
4766 if (!_dbus_string_init (&str))
4767 {
4768 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
4769 _dbus_verbose ("no memory for error string in dispatch\n");
4770 goto out;
4771 }
4772
4773 if (!_dbus_string_append_printf (&str,
4774 "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
4775 dbus_message_get_member (message),
4776 dbus_message_get_signature (message),
4777 dbus_message_get_interface (message)))
4778 {
4779 _dbus_string_free (&str);
4780 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
4781 _dbus_verbose ("no memory for error string in dispatch\n");
4782 goto out;
4783 }
4784
4785 reply = dbus_message_new_error (message,
4786 found_object ? DBUS_ERROR_UNKNOWN_METHOD : DBUS_ERROR_UNKNOWN_OBJECT,
4787 _dbus_string_get_const_data (&str));
4788 _dbus_string_free (&str);
4789
4790 if (reply == NULL)
4791 {
4792 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
4793 _dbus_verbose ("no memory for error reply in dispatch\n");
4794 goto out;
4795 }
4796
4797 expire_link = _dbus_list_alloc_link (reply);
4798
4799 if (expire_link == NULL)
4800 {
4801 dbus_message_unref (reply);
4802 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
4803 _dbus_verbose ("no memory for error send in dispatch\n");
4804 goto out;
4805 }
4806
4807 preallocated = _dbus_connection_preallocate_send_unlocked (connection);
4808
4809 if (preallocated == NULL)
4810 {
4811 _dbus_list_free_link (expire_link);
4812 /* It's OK that this is finalized, because it hasn't been seen by
4813 * anything that could attach user callbacks */
4814 dbus_message_unref (reply);
4815 result = DBUS_HANDLER_RESULT_NEED_MEMORY;
4816 _dbus_verbose ("no memory for error send in dispatch\n");
4817 goto out;
4818 }
4819
4820 _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
4821 reply, NULL);
4822 /* reply will be freed when we release the lock */
4823 _dbus_list_prepend_link (&connection->expired_messages, expire_link);
4824
4825 result = DBUS_HANDLER_RESULT_HANDLED;
4826 }
4827
4828 _dbus_verbose (" done dispatching %p (%s %s %s '%s') on connection %p\n", message,
4829 dbus_message_type_to_string (dbus_message_get_type (message)),
4830 dbus_message_get_interface (message) ?
4831 dbus_message_get_interface (message) :
4832 "no interface",
4833 dbus_message_get_member (message) ?
4834 dbus_message_get_member (message) :
4835 "no member",
4836 dbus_message_get_signature (message),
4837 connection);
4838
4839 out:
4840 if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
4841 {
4842 _dbus_verbose ("out of memory\n");
4843
4844 /* Put message back, and we'll start over.
4845 * Yes this means handlers must be idempotent if they
4846 * don't return HANDLED; c'est la vie.
4847 */
4848 _dbus_connection_putback_message_link_unlocked (connection,
4849 message_link);
4850 /* now we don't want to free them */
4851 message_link = NULL;
4852 message = NULL;
4853 }
4854 else
4855 {
4856 _dbus_verbose (" ... done dispatching\n");
4857 }
4858
4859 _dbus_connection_release_dispatch (connection);
4860 HAVE_LOCK_CHECK (connection);
4861
4862 if (message != NULL)
4863 {
4864 /* We don't want this message to count in maximum message limits when
4865 * computing the dispatch status, below. We have to drop the lock
4866 * temporarily, because finalizing a message can trigger callbacks.
4867 *
4868 * We have a reference to the connection, and we don't use any cached
4869 * pointers to the connection's internals below this point, so it should
4870 * be safe to drop the lock and take it back. */
4871 CONNECTION_UNLOCK (connection);
4872 dbus_message_unref (message);
4873 CONNECTION_LOCK (connection);
4874 }
4875
4876 if (message_link != NULL)
4877 _dbus_list_free_link (message_link);
4878
4879 _dbus_verbose ("before final status update\n");
4880 status = _dbus_connection_get_dispatch_status_unlocked (connection);
4881
4882 /* unlocks and calls user code */
4883 _dbus_connection_update_dispatch_status_and_unlock (connection, status);
4884
4885 dbus_connection_unref (connection);
4886
4887 return status;
4888 }
4889
4951 dbus_bool_t
4952 dbus_connection_set_watch_functions (DBusConnection *connection,
4953 DBusAddWatchFunction add_function,
4954 DBusRemoveWatchFunction remove_function,
4955 DBusWatchToggledFunction toggled_function,
4956 void *data,
4957 DBusFreeFunction free_data_function)
4958 {
4959 dbus_bool_t retval;
4960
4961 _dbus_return_val_if_fail (connection != NULL, FALSE);
4962
4963 CONNECTION_LOCK (connection);
4964
4965 retval = _dbus_watch_list_set_functions (connection->watches,
4966 add_function, remove_function,
4967 toggled_function,
4968 data, free_data_function);
4969
4970 CONNECTION_UNLOCK (connection);
4971
4972 return retval;
4973 }
4974
5014 dbus_bool_t
5015 dbus_connection_set_timeout_functions (DBusConnection *connection,
5016 DBusAddTimeoutFunction add_function,
5017 DBusRemoveTimeoutFunction remove_function,
5018 DBusTimeoutToggledFunction toggled_function,
5019 void *data,
5020 DBusFreeFunction free_data_function)
5021 {
5022 dbus_bool_t retval;
5023
5024 _dbus_return_val_if_fail (connection != NULL, FALSE);
5025
5026 CONNECTION_LOCK (connection);
5027
5028 retval = _dbus_timeout_list_set_functions (connection->timeouts,
5029 add_function, remove_function,
5030 toggled_function,
5031 data, free_data_function);
5032
5033 CONNECTION_UNLOCK (connection);
5034
5035 return retval;
5036 }
5037
5052 void
5053 dbus_connection_set_wakeup_main_function (DBusConnection *connection,
5054 DBusWakeupMainFunction wakeup_main_function,
5055 void *data,
5056 DBusFreeFunction free_data_function)
5057 {
5058 void *old_data;
5059 DBusFreeFunction old_free_data;
5060
5061 _dbus_return_if_fail (connection != NULL);
5062
5063 CONNECTION_LOCK (connection);
5064 old_data = connection->wakeup_main_data;
5065 old_free_data = connection->free_wakeup_main_data;
5066
5067 connection->wakeup_main_function = wakeup_main_function;
5068 connection->wakeup_main_data = data;
5069 connection->free_wakeup_main_data = free_data_function;
5070
5071 CONNECTION_UNLOCK (connection);
5072
5073 /* Callback outside the lock */
5074 if (old_free_data)
5075 (*old_free_data) (old_data);
5076 }
5077
5098 void
5099 dbus_connection_set_dispatch_status_function (DBusConnection *connection,
5100 DBusDispatchStatusFunction function,
5101 void *data,
5102 DBusFreeFunction free_data_function)
5103 {
5104 void *old_data;
5105 DBusFreeFunction old_free_data;
5106
5107 _dbus_return_if_fail (connection != NULL);
5108
5109 CONNECTION_LOCK (connection);
5110 old_data = connection->dispatch_status_data;
5111 old_free_data = connection->free_dispatch_status_data;
5112
5113 connection->dispatch_status_function = function;
5114 connection->dispatch_status_data = data;
5115 connection->free_dispatch_status_data = free_data_function;
5116
5117 CONNECTION_UNLOCK (connection);
5118
5119 /* Callback outside the lock */
5120 if (old_free_data)
5121 (*old_free_data) (old_data);
5122 }
5123
5143 dbus_bool_t
5144 dbus_connection_get_unix_fd (DBusConnection *connection,
5145 int *fd)
5146 {
5147 _dbus_return_val_if_fail (connection != NULL, FALSE);
5148 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
5149
5150 #ifdef DBUS_WIN
5151 /* FIXME do this on a lower level */
5152 return FALSE;
5153 #endif
5154
5155 return dbus_connection_get_socket(connection, fd);
5156 }
5157
5173 dbus_bool_t
5174 dbus_connection_get_socket(DBusConnection *connection,
5175 int *fd)
5176 {
5177 dbus_bool_t retval;
5178 DBusSocket s = DBUS_SOCKET_INIT;
5179
5180 _dbus_return_val_if_fail (connection != NULL, FALSE);
5181 _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
5182
5183 CONNECTION_LOCK (connection);
5184
5185 retval = _dbus_transport_get_socket_fd (connection->transport, &s);
5186
5187 if (retval)
5188 {
5189 *fd = _dbus_socket_get_int (s);
5190 }
5191
5192 CONNECTION_UNLOCK (connection);
5193
5194 return retval;
5195 }
5196
5197
5220 dbus_bool_t
5221 dbus_connection_get_unix_user (DBusConnection *connection,
5222 unsigned long *uid)
5223 {
5224 dbus_bool_t result;
5225
5226 _dbus_return_val_if_fail (connection != NULL, FALSE);
5227 _dbus_return_val_if_fail (uid != NULL, FALSE);
5228
5229 CONNECTION_LOCK (connection);
5230
5231 if (!_dbus_transport_try_to_authenticate (connection->transport))
5232 result = FALSE;
5233 else
5234 result = _dbus_transport_get_unix_user (connection->transport,
5235 uid);
5236
5237 #ifdef DBUS_WIN
5238 _dbus_assert (!result);
5239 #endif
5240
5241 CONNECTION_UNLOCK (connection);
5242
5243 return result;
5244 }
5245
5256 dbus_bool_t
5257 dbus_connection_get_unix_process_id (DBusConnection *connection,
5258 unsigned long *pid)
5259 {
5260 dbus_bool_t result;
5261
5262 _dbus_return_val_if_fail (connection != NULL, FALSE);
5263 _dbus_return_val_if_fail (pid != NULL, FALSE);
5264
5265 CONNECTION_LOCK (connection);
5266
5267 if (!_dbus_transport_try_to_authenticate (connection->transport))
5268 result = FALSE;
5269 else
5270 result = _dbus_transport_get_unix_process_id (connection->transport,
5271 pid);
5272
5273 CONNECTION_UNLOCK (connection);
5274
5275 return result;
5276 }
5277
5289 dbus_bool_t
5290 dbus_connection_get_adt_audit_session_data (DBusConnection *connection,
5291 void **data,
5292 dbus_int32_t *data_size)
5293 {
5294 dbus_bool_t result;
5295
5296 _dbus_return_val_if_fail (connection != NULL, FALSE);
5297 _dbus_return_val_if_fail (data != NULL, FALSE);
5298 _dbus_return_val_if_fail (data_size != NULL, FALSE);
5299
5300 CONNECTION_LOCK (connection);
5301
5302 if (!_dbus_transport_try_to_authenticate (connection->transport))
5303 result = FALSE;
5304 else
5305 result = _dbus_transport_get_adt_audit_session_data (connection->transport,
5306 data,
5307 data_size);
5308 CONNECTION_UNLOCK (connection);
5309
5310 return result;
5311 }
5312
5335 void
5336 dbus_connection_set_unix_user_function (DBusConnection *connection,
5337 DBusAllowUnixUserFunction function,
5338 void *data,
5339 DBusFreeFunction free_data_function)
5340 {
5341 void *old_data = NULL;
5342 DBusFreeFunction old_free_function = NULL;
5343
5344 _dbus_return_if_fail (connection != NULL);
5345
5346 CONNECTION_LOCK (connection);
5347 _dbus_transport_set_unix_user_function (connection->transport,
5348 function, data, free_data_function,
5349 &old_data, &old_free_function);
5350 CONNECTION_UNLOCK (connection);
5351
5352 if (old_free_function != NULL)
5353 (* old_free_function) (old_data);
5354 }
5355
5356 /* Same calling convention as dbus_connection_get_windows_user */
5357 dbus_bool_t
5358 _dbus_connection_get_linux_security_label (DBusConnection *connection,
5359 char **label_p)
5360 {
5361 dbus_bool_t result;
5362
5363 _dbus_assert (connection != NULL);
5364 _dbus_assert (label_p != NULL);
5365
5366 CONNECTION_LOCK (connection);
5367
5368 if (!_dbus_transport_try_to_authenticate (connection->transport))
5369 result = FALSE;
5370 else
5371 result = _dbus_transport_get_linux_security_label (connection->transport,
5372 label_p);
5373 #ifndef __linux__
5374 _dbus_assert (!result);
5375 #endif
5376
5377 CONNECTION_UNLOCK (connection);
5378
5379 return result;
5380 }
5381
5413 dbus_bool_t
5414 dbus_connection_get_windows_user (DBusConnection *connection,
5415 char **windows_sid_p)
5416 {
5417 dbus_bool_t result;
5418
5419 _dbus_return_val_if_fail (connection != NULL, FALSE);
5420 _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
5421
5422 CONNECTION_LOCK (connection);
5423
5424 if (!_dbus_transport_try_to_authenticate (connection->transport))
5425 result = FALSE;
5426 else
5427 result = _dbus_transport_get_windows_user (connection->transport,
5428 windows_sid_p);
5429
5430 #ifdef DBUS_UNIX
5431 _dbus_assert (!result);
5432 #endif
5433
5434 CONNECTION_UNLOCK (connection);
5435
5436 return result;
5437 }
5438
5460 void
5461 dbus_connection_set_windows_user_function (DBusConnection *connection,
5462 DBusAllowWindowsUserFunction function,
5463 void *data,
5464 DBusFreeFunction free_data_function)
5465 {
5466 void *old_data = NULL;
5467 DBusFreeFunction old_free_function = NULL;
5468
5469 _dbus_return_if_fail (connection != NULL);
5470
5471 CONNECTION_LOCK (connection);
5472 _dbus_transport_set_windows_user_function (connection->transport,
5473 function, data, free_data_function,
5474 &old_data, &old_free_function);
5475 CONNECTION_UNLOCK (connection);
5476
5477 if (old_free_function != NULL)
5478 (* old_free_function) (old_data);
5479 }
5480
5507 void
5508 dbus_connection_set_allow_anonymous (DBusConnection *connection,
5509 dbus_bool_t value)
5510 {
5511 _dbus_return_if_fail (connection != NULL);
5512
5513 CONNECTION_LOCK (connection);
5514 _dbus_transport_set_allow_anonymous (connection->transport, value);
5515 CONNECTION_UNLOCK (connection);
5516 }
5517
5535 void
5536 dbus_connection_set_route_peer_messages (DBusConnection *connection,
5537 dbus_bool_t value)
5538 {
5539 _dbus_return_if_fail (connection != NULL);
5540
5541 CONNECTION_LOCK (connection);
5542 connection->route_peer_messages = value;
5543 CONNECTION_UNLOCK (connection);
5544 }
5545
5567 dbus_bool_t
5568 dbus_connection_add_filter (DBusConnection *connection,
5569 DBusHandleMessageFunction function,
5570 void *user_data,
5571 DBusFreeFunction free_data_function)
5572 {
5573 DBusMessageFilter *filter;
5574
5575 _dbus_return_val_if_fail (connection != NULL, FALSE);
5576 _dbus_return_val_if_fail (function != NULL, FALSE);
5577
5578 filter = dbus_new0 (DBusMessageFilter, 1);
5579 if (filter == NULL)
5580 return FALSE;
5581
5582 _dbus_atomic_inc (&filter->refcount);
5583
5584 CONNECTION_LOCK (connection);
5585
5586 if (!_dbus_list_append (&connection->filter_list,
5587 filter))
5588 {
5589 _dbus_message_filter_unref (filter);
5590 CONNECTION_UNLOCK (connection);
5591 return FALSE;
5592 }
5593
5594 /* Fill in filter after all memory allocated,
5595 * so we don't run the free_user_data_function
5596 * if the add_filter() fails
5597 */
5598
5599 filter->function = function;
5600 filter->user_data = user_data;
5601 filter->free_user_data_function = free_data_function;
5602
5603 CONNECTION_UNLOCK (connection);
5604 return TRUE;
5605 }
5606
5619 void
5620 dbus_connection_remove_filter (DBusConnection *connection,
5621 DBusHandleMessageFunction function,
5622 void *user_data)
5623 {
5624 DBusList *link;
5625 DBusMessageFilter *filter;
5626
5627 _dbus_return_if_fail (connection != NULL);
5628 _dbus_return_if_fail (function != NULL);
5629
5630 CONNECTION_LOCK (connection);
5631
5632 filter = NULL;
5633
5634 link = _dbus_list_get_last_link (&connection->filter_list);
5635 while (link != NULL)
5636 {
5637 filter = link->data;
5638
5639 if (filter->function == function &&
5640 filter->user_data == user_data)
5641 {
5642 _dbus_list_remove_link (&connection->filter_list, link);
5643 filter->function = NULL;
5644
5645 break;
5646 }
5647
5648 link = _dbus_list_get_prev_link (&connection->filter_list, link);
5649 filter = NULL;
5650 }
5651
5652 CONNECTION_UNLOCK (connection);
5653
5654 #ifndef DBUS_DISABLE_CHECKS
5655 if (filter == NULL)
5656 {
5657 _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
5658 function, user_data);
5659 return;
5660 }
5661 #endif
5662
5663 /* Call application code */
5664 if (filter->free_user_data_function)
5665 (* filter->free_user_data_function) (filter->user_data);
5666
5667 filter->free_user_data_function = NULL;
5668 filter->user_data = NULL;
5669
5670 _dbus_message_filter_unref (filter);
5671 }
5672
5688 static dbus_bool_t
5689 _dbus_connection_register_object_path (DBusConnection *connection,
5690 dbus_bool_t fallback,
5691 const char *path,
5692 const DBusObjectPathVTable *vtable,
5693 void *user_data,
5694 DBusError *error)
5695 {
5696 char **decomposed_path;
5697 dbus_bool_t retval;
5698
5699 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
5700 return FALSE;
5701
5702 CONNECTION_LOCK (connection);
5703
5704 retval = _dbus_object_tree_register (connection->objects,
5705 fallback,
5706 (const char **) decomposed_path, vtable,
5707 user_data, error);
5708
5709 CONNECTION_UNLOCK (connection);
5710
5711 dbus_free_string_array (decomposed_path);
5712
5713 return retval;
5714 }
5715
5728 dbus_bool_t
5729 dbus_connection_try_register_object_path (DBusConnection *connection,
5730 const char *path,
5731 const DBusObjectPathVTable *vtable,
5732 void *user_data,
5733 DBusError *error)
5734 {
5735 _dbus_return_val_if_fail (connection != NULL, FALSE);
5736 _dbus_return_val_if_fail (path != NULL, FALSE);
5737 _dbus_return_val_if_fail (path[0] == '/', FALSE);
5738 _dbus_return_val_if_fail (vtable != NULL, FALSE);
5739
5740 return _dbus_connection_register_object_path (connection, FALSE, path, vtable, user_data, error);
5741 }
5742
5758 dbus_bool_t
5759 dbus_connection_register_object_path (DBusConnection *connection,
5760 const char *path,
5761 const DBusObjectPathVTable *vtable,
5762 void *user_data)
5763 {
5764 dbus_bool_t retval;
5765 DBusError error = DBUS_ERROR_INIT;
5766
5767 _dbus_return_val_if_fail (connection != NULL, FALSE);
5768 _dbus_return_val_if_fail (path != NULL, FALSE);
5769 _dbus_return_val_if_fail (path[0] == '/', FALSE);
5770 _dbus_return_val_if_fail (vtable != NULL, FALSE);
5771
5772 retval = _dbus_connection_register_object_path (connection, FALSE, path, vtable, user_data, &error);
5773
5774 if (dbus_error_has_name (&error, DBUS_ERROR_OBJECT_PATH_IN_USE))
5775 {
5776 _dbus_warn ("%s\n", error.message);
5777 dbus_error_free (&error);
5778 return FALSE;
5779 }
5780
5781 return retval;
5782 }
5783
5798 dbus_bool_t
5799 dbus_connection_try_register_fallback (DBusConnection *connection,
5800 const char *path,
5801 const DBusObjectPathVTable *vtable,
5802 void *user_data,
5803 DBusError *error)
5804 {
5805 _dbus_return_val_if_fail (connection != NULL, FALSE);
5806 _dbus_return_val_if_fail (path != NULL, FALSE);
5807 _dbus_return_val_if_fail (path[0] == '/', FALSE);
5808 _dbus_return_val_if_fail (vtable != NULL, FALSE);
5809
5810 return _dbus_connection_register_object_path (connection, TRUE, path, vtable, user_data, error);
5811 }
5812
5830 dbus_bool_t
5831 dbus_connection_register_fallback (DBusConnection *connection,
5832 const char *path,
5833 const DBusObjectPathVTable *vtable,
5834 void *user_data)
5835 {
5836 dbus_bool_t retval;
5837 DBusError error = DBUS_ERROR_INIT;
5838
5839 _dbus_return_val_if_fail (connection != NULL, FALSE);
5840 _dbus_return_val_if_fail (path != NULL, FALSE);
5841 _dbus_return_val_if_fail (path[0] == '/', FALSE);
5842 _dbus_return_val_if_fail (vtable != NULL, FALSE);
5843
5844 retval = _dbus_connection_register_object_path (connection, TRUE, path, vtable, user_data, &error);
5845
5846 if (dbus_error_has_name (&error, DBUS_ERROR_OBJECT_PATH_IN_USE))
5847 {
5848 _dbus_warn ("%s\n", error.message);
5849 dbus_error_free (&error);
5850 return FALSE;
5851 }
5852
5853 return retval;
5854 }
5855
5865 dbus_bool_t
5866 dbus_connection_unregister_object_path (DBusConnection *connection,
5867 const char *path)
5868 {
5869 char **decomposed_path;
5870
5871 _dbus_return_val_if_fail (connection != NULL, FALSE);
5872 _dbus_return_val_if_fail (path != NULL, FALSE);
5873 _dbus_return_val_if_fail (path[0] == '/', FALSE);
5874
5875 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
5876 return FALSE;
5877
5878 CONNECTION_LOCK (connection);
5879
5880 _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
5881
5882 dbus_free_string_array (decomposed_path);
5883
5884 return TRUE;
5885 }
5886
5897 dbus_bool_t
5898 dbus_connection_get_object_path_data (DBusConnection *connection,
5899 const char *path,
5900 void **data_p)
5901 {
5902 char **decomposed_path;
5903
5904 _dbus_return_val_if_fail (connection != NULL, FALSE);
5905 _dbus_return_val_if_fail (path != NULL, FALSE);
5906 _dbus_return_val_if_fail (data_p != NULL, FALSE);
5907
5908 *data_p = NULL;
5909
5910 if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
5911 return FALSE;
5912
5913 CONNECTION_LOCK (connection);
5914
5915 *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path);
5916
5917 CONNECTION_UNLOCK (connection);
5918
5919 dbus_free_string_array (decomposed_path);
5920
5921 return TRUE;
5922 }
5923
5934 dbus_bool_t
5935 dbus_connection_list_registered (DBusConnection *connection,
5936 const char *parent_path,
5937 char ***child_entries)
5938 {
5939 char **decomposed_path;
5940 dbus_bool_t retval;
5941 _dbus_return_val_if_fail (connection != NULL, FALSE);
5942 _dbus_return_val_if_fail (parent_path != NULL, FALSE);
5943 _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
5944 _dbus_return_val_if_fail (child_entries != NULL, FALSE);
5945
5946 if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
5947 return FALSE;
5948
5949 CONNECTION_LOCK (connection);
5950
5951 retval = _dbus_object_tree_list_registered_and_unlock (connection->objects,
5952 (const char **) decomposed_path,
5953 child_entries);
5954 dbus_free_string_array (decomposed_path);
5955
5956 return retval;
5957 }
5958
5959 static DBusDataSlotAllocator slot_allocator =
5960 _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (connection_slots));
5961
5976 dbus_bool_t
5977 dbus_connection_allocate_data_slot (dbus_int32_t *slot_p)
5978 {
5979 return _dbus_data_slot_allocator_alloc (&slot_allocator,
5980 slot_p);
5981 }
5982
5994 void
5995 dbus_connection_free_data_slot (dbus_int32_t *slot_p)
5996 {
5997 _dbus_return_if_fail (*slot_p >= 0);
5998
5999 _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
6000 }
6001
6024 dbus_bool_t
6025 dbus_connection_set_data (DBusConnection *connection,
6026 dbus_int32_t slot,
6027 void *data,
6028 DBusFreeFunction free_data_func)
6029 {
6030 DBusFreeFunction old_free_func;
6031 void *old_data;
6032 dbus_bool_t retval;
6033
6034 _dbus_return_val_if_fail (connection != NULL, FALSE);
6035 _dbus_return_val_if_fail (slot >= 0, FALSE);
6036
6037 SLOTS_LOCK (connection);
6038
6039 retval = _dbus_data_slot_list_set (&slot_allocator,
6040 &connection->slot_list,
6041 slot, data, free_data_func,
6042 &old_free_func, &old_data);
6043
6044 SLOTS_UNLOCK (connection);
6045
6046 if (retval)
6047 {
6048 /* Do the actual free outside the connection lock */
6049 if (old_free_func)
6050 (* old_free_func) (old_data);
6051 }
6052
6053 return retval;
6054 }
6055
6073 void*
6074 dbus_connection_get_data (DBusConnection *connection,
6075 dbus_int32_t slot)
6076 {
6077 void *res;
6078
6079 _dbus_return_val_if_fail (connection != NULL, NULL);
6080 _dbus_return_val_if_fail (slot >= 0, NULL);
6081
6082 SLOTS_LOCK (connection);
6083
6084 res = _dbus_data_slot_list_get (&slot_allocator,
6085 &connection->slot_list,
6086 slot);
6087
6088 SLOTS_UNLOCK (connection);
6089
6090 return res;
6091 }
6092
6099 void
6100 dbus_connection_set_change_sigpipe (dbus_bool_t will_modify_sigpipe)
6101 {
6102 _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
6103 }
6104
6113 void
6114 dbus_connection_set_max_message_size (DBusConnection *connection,
6115 long size)
6116 {
6117 _dbus_return_if_fail (connection != NULL);
6118
6119 CONNECTION_LOCK (connection);
6120 _dbus_transport_set_max_message_size (connection->transport,
6121 size);
6122 CONNECTION_UNLOCK (connection);
6123 }
6124
6131 long
6132 dbus_connection_get_max_message_size (DBusConnection *connection)
6133 {
6134 long res;
6135
6136 _dbus_return_val_if_fail (connection != NULL, 0);
6137
6138 CONNECTION_LOCK (connection);
6139 res = _dbus_transport_get_max_message_size (connection->transport);
6140 CONNECTION_UNLOCK (connection);
6141 return res;
6142 }
6143
6152 void
6153 dbus_connection_set_max_message_unix_fds (DBusConnection *connection,
6154 long n)
6155 {
6156 _dbus_return_if_fail (connection != NULL);
6157
6158 CONNECTION_LOCK (connection);
6159 _dbus_transport_set_max_message_unix_fds (connection->transport,
6160 n);
6161 CONNECTION_UNLOCK (connection);
6162 }
6163
6170 long
6171 dbus_connection_get_max_message_unix_fds (DBusConnection *connection)
6172 {
6173 long res;
6174
6175 _dbus_return_val_if_fail (connection != NULL, 0);
6176
6177 CONNECTION_LOCK (connection);
6178 res = _dbus_transport_get_max_message_unix_fds (connection->transport);
6179 CONNECTION_UNLOCK (connection);
6180 return res;
6181 }
6182
6208 void
6209 dbus_connection_set_max_received_size (DBusConnection *connection,
6210 long size)
6211 {
6212 _dbus_return_if_fail (connection != NULL);
6213
6214 CONNECTION_LOCK (connection);
6215 _dbus_transport_set_max_received_size (connection->transport,
6216 size);
6217 CONNECTION_UNLOCK (connection);
6218 }
6219
6226 long
6227 dbus_connection_get_max_received_size (DBusConnection *connection)
6228 {
6229 long res;
6230
6231 _dbus_return_val_if_fail (connection != NULL, 0);
6232
6233 CONNECTION_LOCK (connection);
6234 res = _dbus_transport_get_max_received_size (connection->transport);
6235 CONNECTION_UNLOCK (connection);
6236 return res;
6237 }
6238
6250 void
6251 dbus_connection_set_max_received_unix_fds (DBusConnection *connection,
6252 long n)
6253 {
6254 _dbus_return_if_fail (connection != NULL);
6255
6256 CONNECTION_LOCK (connection);
6257 _dbus_transport_set_max_received_unix_fds (connection->transport,
6258 n);
6259 CONNECTION_UNLOCK (connection);
6260 }
6261
6268 long
6269 dbus_connection_get_max_received_unix_fds (DBusConnection *connection)
6270 {
6271 long res;
6272
6273 _dbus_return_val_if_fail (connection != NULL, 0);
6274
6275 CONNECTION_LOCK (connection);
6276 res = _dbus_transport_get_max_received_unix_fds (connection->transport);
6277 CONNECTION_UNLOCK (connection);
6278 return res;
6279 }
6280
6291 long
6292 dbus_connection_get_outgoing_size (DBusConnection *connection)
6293 {
6294 long res;
6295
6296 _dbus_return_val_if_fail (connection != NULL, 0);
6297
6298 CONNECTION_LOCK (connection);
6299 res = _dbus_counter_get_size_value (connection->outgoing_counter);
6300 CONNECTION_UNLOCK (connection);
6301 return res;
6302 }
6303
6304 #ifdef DBUS_ENABLE_STATS
6305 void
6306 _dbus_connection_get_stats (DBusConnection *connection,
6307 dbus_uint32_t *in_messages,
6308 dbus_uint32_t *in_bytes,
6309 dbus_uint32_t *in_fds,
6310 dbus_uint32_t *in_peak_bytes,
6311 dbus_uint32_t *in_peak_fds,
6312 dbus_uint32_t *out_messages,
6313 dbus_uint32_t *out_bytes,
6314 dbus_uint32_t *out_fds,
6315 dbus_uint32_t *out_peak_bytes,
6316 dbus_uint32_t *out_peak_fds)
6317 {
6318 CONNECTION_LOCK (connection);
6319
6320 if (in_messages != NULL)
6321 *in_messages = connection->n_incoming;
6322
6323 _dbus_transport_get_stats (connection->transport,
6324 in_bytes, in_fds, in_peak_bytes, in_peak_fds);
6325
6326 if (out_messages != NULL)
6327 *out_messages = connection->n_outgoing;
6328
6329 if (out_bytes != NULL)
6330 *out_bytes = _dbus_counter_get_size_value (connection->outgoing_counter);
6331
6332 if (out_fds != NULL)
6333 *out_fds = _dbus_counter_get_unix_fd_value (connection->outgoing_counter);
6334
6335 if (out_peak_bytes != NULL)
6336 *out_peak_bytes = _dbus_counter_get_peak_size_value (connection->outgoing_counter);
6337
6338 if (out_peak_fds != NULL)
6339 *out_peak_fds = _dbus_counter_get_peak_unix_fd_value (connection->outgoing_counter);
6340
6341 CONNECTION_UNLOCK (connection);
6342 }
6343 #endif /* DBUS_ENABLE_STATS */
6344
6352 long
6353 dbus_connection_get_outgoing_unix_fds (DBusConnection *connection)
6354 {
6355 long res;
6356
6357 _dbus_return_val_if_fail (connection != NULL, 0);
6358
6359 CONNECTION_LOCK (connection);
6360 res = _dbus_counter_get_unix_fd_value (connection->outgoing_counter);
6361 CONNECTION_UNLOCK (connection);
6362 return res;
6363 }
6364
6365 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
6366
6372 const char*
6373 _dbus_connection_get_address (DBusConnection *connection)
6374 {
6375 return _dbus_transport_get_address (connection->transport);
6376 }
6377 #endif
6378
dbus_error_has_name
dbus_bool_t dbus_error_has_name(const DBusError *error, const char *name)
Checks whether the error is set and has the given name.
Definition: dbus-errors.c:302
dbus_uint32_t
unsigned int dbus_uint32_t
A 32-bit unsigned integer on all platforms.
Definition: dbus-arch-deps.h:43
_dbus_object_tree_dispatch_and_unlock
DBusHandlerResult _dbus_object_tree_dispatch_and_unlock(DBusObjectTree *tree, DBusMessage *message, dbus_bool_t *found_object)
Tries to dispatch a message by directing it to handler for the object path listed in the message head...
Definition: dbus-object-tree.c:905
DBusAtomic
An atomic integer safe to increment or decrement from multiple threads.
Definition: dbus-sysdeps.h:279
_dbus_pending_call_complete
void _dbus_pending_call_complete(DBusPendingCall *pending)
Calls notifier function for the pending call and sets the call to completed.
Definition: dbus-pending-call.c:204
dbus_connection_set_change_sigpipe
void dbus_connection_set_change_sigpipe(dbus_bool_t will_modify_sigpipe)
This function sets a global flag for whether dbus_connection_new() will set SIGPIPE behavior to SIG_I...
Definition: dbus-connection.c:6100
dbus_message_ref
DBusMessage * dbus_message_ref(DBusMessage *message)
Increments the reference count of a DBusMessage.
Definition: dbus-message.c:1694
DBusConnection::filter_list
DBusList * filter_list
List of filters.
Definition: dbus-connection.c:284
_dbus_transport_set_max_received_unix_fds
void _dbus_transport_set_max_received_unix_fds(DBusTransport *transport, long n)
See dbus_connection_set_max_received_unix_fds().
Definition: dbus-transport.c:1267
DBusTimeout
Internals of DBusTimeout.
Definition: dbus-timeout.c:40
DBusMessageFilter::user_data
void * user_data
User data for the function.
Definition: dbus-connection.c:232
dbus_message_lock
void dbus_message_lock(DBusMessage *message)
Locks a message.
Definition: dbus-message.c:407
_dbus_list_get_last
void * _dbus_list_get_last(DBusList **list)
Gets the last data in the list.
Definition: dbus-list.c:596
_dbus_connection_toggle_watch_unlocked
void _dbus_connection_toggle_watch_unlocked(DBusConnection *connection, DBusWatch *watch, dbus_bool_t enabled)
Toggles a watch and notifies app via connection&#39;s DBusWatchToggledFunction if available.
Definition: dbus-connection.c:781
_dbus_transport_get_server_id
const char * _dbus_transport_get_server_id(DBusTransport *transport)
Gets the id of the server we are connected to (see dbus_server_get_id()).
Definition: dbus-transport.c:869
_dbus_list_prepend
dbus_bool_t _dbus_list_prepend(DBusList **list, void *data)
Prepends a value to the list.
Definition: dbus-list.c:292
DBusDispatchStatus
DBusDispatchStatus
Indicates the status of incoming data on a DBusConnection.
Definition: dbus-connection.h:79
DBusError::message
const char * message
public error message field
Definition: dbus-errors.h:51
_dbus_transport_get_address
const char * _dbus_transport_get_address(DBusTransport *transport)
Gets the address of a transport.
Definition: dbus-transport.c:856
DBusConnection::free_wakeup_main_data
DBusFreeFunction free_wakeup_main_data
free wakeup_main_data
Definition: dbus-connection.c:296
DBusWatch
Implementation of DBusWatch.
Definition: dbus-watch.c:40
NULL
#define NULL
A null pointer, defined appropriately for C or C++.
dbus_message_is_method_call
dbus_bool_t dbus_message_is_method_call(DBusMessage *message, const char *iface, const char *method)
Checks whether the message is a method call with the given interface and member fields.
Definition: dbus-message.c:3679
DBusFreeFunction
void(* DBusFreeFunction)(void *memory)
The type of a function which frees a block of memory.
Definition: dbus-memory.h:64
_dbus_connection_add_timeout_unlocked
dbus_bool_t _dbus_connection_add_timeout_unlocked(DBusConnection *connection, DBusTimeout *timeout)
Adds a timeout using the connection&#39;s DBusAddTimeoutFunction if available.
Definition: dbus-connection.c:867
DBusPreallocatedSend::queue_link
DBusList * queue_link
Preallocated link in the queue.
Definition: dbus-connection.c:243
DBusConnection::have_connection_lock
unsigned int have_connection_lock
Used to check locking.
Definition: dbus-connection.c:330
dbus_message_set_no_reply
void dbus_message_set_no_reply(DBusMessage *message, dbus_bool_t no_reply)
Sets a flag indicating that the message does not want a reply; if this flag is set, the other end of the connection may (but is not required to) optimize by not sending method return or error replies.
Definition: dbus-message.c:3061
_dbus_timeout_list_set_functions
dbus_bool_t _dbus_timeout_list_set_functions(DBusTimeoutList *timeout_list, DBusAddTimeoutFunction add_function, DBusRemoveTimeoutFunction remove_function, DBusTimeoutToggledFunction toggled_function, void *data, DBusFreeFunction free_data_function)
Sets the timeout functions.
Definition: dbus-timeout.c:239
_dbus_connection_queue_synthesized_message_link
void _dbus_connection_queue_synthesized_message_link(DBusConnection *connection, DBusList *link)
Adds a link + message to the incoming message queue.
Definition: dbus-connection.c:545
_dbus_pending_call_get_connection_unlocked
DBusConnection * _dbus_pending_call_get_connection_unlocked(DBusPendingCall *pending)
Gets the connection associated with this pending call.
Definition: dbus-pending-call.c:338
_dbus_object_tree_free_all_unlocked
void _dbus_object_tree_free_all_unlocked(DBusObjectTree *tree)
Free all the handlers in the tree.
Definition: dbus-object-tree.c:720
DBUS_DISPATCH_NEED_MEMORY
More memory is needed to continue.
Definition: dbus-connection.h:83
dbus_free
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:701
_dbus_hash_table_insert_int
dbus_bool_t _dbus_hash_table_insert_int(DBusHashTable *table, int key, void *value)
Creates a hash entry with the given key and value.
Definition: dbus-hash.c:1248
dbus_message_get_serial
dbus_uint32_t dbus_message_get_serial(DBusMessage *message)
Returns the serial of a message or 0 if none has been specified.
Definition: dbus-message.c:1150
_dbus_condvar_wait
void _dbus_condvar_wait(DBusCondVar *cond, DBusCMutex *mutex)
Atomically unlocks the mutex and waits for the conditions variable to be signalled.
Definition: dbus-threads.c:240
dbus_connection_set_windows_user_function
void dbus_connection_set_windows_user_function(DBusConnection *connection, DBusAllowWindowsUserFunction function, void *data, DBusFreeFunction free_data_function)
Sets a predicate function used to determine whether a given user ID is allowed to connect...
Definition: dbus-connection.c:5461
_dbus_condvar_wait_timeout
dbus_bool_t _dbus_condvar_wait_timeout(DBusCondVar *cond, DBusCMutex *mutex, int timeout_milliseconds)
Atomically unlocks the mutex and waits for the conditions variable to be signalled, or for a timeout.
Definition: dbus-threads.c:261
_dbus_list_get_last_link
DBusList * _dbus_list_get_last_link(DBusList **list)
Gets the last link in the list.
Definition: dbus-list.c:580
dbus_connection_get_windows_user
dbus_bool_t dbus_connection_get_windows_user(DBusConnection *connection, char **windows_sid_p)
Gets the Windows user SID of the connection if known.
Definition: dbus-connection.c:5414
_dbus_connection_lock
void _dbus_connection_lock(DBusConnection *connection)
Acquires the connection lock.
Definition: dbus-connection.c:388
_dbus_transport_get_socket_fd
dbus_bool_t _dbus_transport_get_socket_fd(DBusTransport *transport, DBusSocket *fd_p)
Get the socket file descriptor, if any.
Definition: dbus-transport.c:951
dbus_pending_call_steal_reply
DBusMessage * dbus_pending_call_steal_reply(DBusPendingCall *pending)
Gets the reply, or returns NULL if none has been received yet.
Definition: dbus-pending-call.c:702
dbus_new
#define dbus_new(type, count)
Safe macro for using dbus_malloc().
Definition: dbus-memory.h:58
DBusConnection::disconnect_message_link
DBusList * disconnect_message_link
Preallocated list node for queueing the disconnection message.
Definition: dbus-connection.c:292
DBusWatchToggledFunction
void(* DBusWatchToggledFunction)(DBusWatch *watch, void *data)
Called when dbus_watch_get_enabled() may return a different value than it did before.
Definition: dbus-connection.h:97
dbus_connection_set_max_message_size
void dbus_connection_set_max_message_size(DBusConnection *connection, long size)
Specifies the maximum size message this connection is allowed to receive.
Definition: dbus-connection.c:6114
dbus_connection_try_register_fallback
dbus_bool_t dbus_connection_try_register_fallback(DBusConnection *connection, const char *path, const DBusObjectPathVTable *vtable, void *user_data, DBusError *error)
Registers a fallback handler for a given subsection of the object hierarchy.
Definition: dbus-connection.c:5799
_dbus_list_remove_link
void _dbus_list_remove_link(DBusList **list, DBusList *link)
Removes a link from the list.
Definition: dbus-list.c:527
_dbus_timeout_list_free
void _dbus_timeout_list_free(DBusTimeoutList *timeout_list)
Frees a DBusTimeoutList.
Definition: dbus-timeout.c:211
dbus_connection_get_outgoing_size
long dbus_connection_get_outgoing_size(DBusConnection *connection)
Gets the approximate size in bytes of all messages in the outgoing message queue. ...
Definition: dbus-connection.c:6292
dbus_connection_ref
DBusConnection * dbus_connection_ref(DBusConnection *connection)
Increments the reference count of a DBusConnection.
Definition: dbus-connection.c:2681
dbus_connection_can_send_type
dbus_bool_t dbus_connection_can_send_type(DBusConnection *connection, int type)
Tests whether a certain type can be send via the connection.
Definition: dbus-connection.c:3105
DBusConnection::message_borrowed
DBusMessage * message_borrowed
Filled in if the first incoming message has been borrowed; dispatch_acquired will be set by the borro...
Definition: dbus-connection.c:271
DBUS_TYPE_STRING
#define DBUS_TYPE_STRING
Type code marking a UTF-8 encoded, nul-terminated Unicode string.
Definition: dbus-protocol.h:102
_dbus_get_local_machine_uuid_encoded
dbus_bool_t _dbus_get_local_machine_uuid_encoded(DBusString *uuid_str, DBusError *error)
Gets the hex-encoded UUID of the machine this function is executed on.
Definition: dbus-internals.c:884
_dbus_timeout_list_new
DBusTimeoutList * _dbus_timeout_list_new(void)
Creates a new timeout list.
Definition: dbus-timeout.c:194
_dbus_assert
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
Definition: dbus-internals.h:148
dbus_connection_read_write
dbus_bool_t dbus_connection_read_write(DBusConnection *connection, int timeout_milliseconds)
This function is intended for use with applications that don&#39;t want to write a main loop and deal wit...
Definition: dbus-connection.c:3801
DBusConnection::shareable
unsigned int shareable
TRUE if libdbus owns a reference to the connection and can return it from dbus_connection_open() more...
Definition: dbus-connection.c:315
_dbus_list_append_link
void _dbus_list_append_link(DBusList **list, DBusList *link)
Appends a link to the list.
Definition: dbus-list.c:315
DBusCounter
Internals of DBusCounter.
Definition: dbus-resources.c:54
DBUS_ERROR_INIT
#define DBUS_ERROR_INIT
Expands to a suitable initializer for a DBusError on the stack.
Definition: dbus-errors.h:62
DBusList::data
void * data
Data stored at this element.
Definition: dbus-list.h:38
DBusConnection::free_dispatch_status_data
DBusFreeFunction free_dispatch_status_data
free dispatch_status_data
Definition: dbus-connection.c:300
dbus_message_new
DBusMessage * dbus_message_new(int message_type)
Constructs a new message of the given message type.
Definition: dbus-message.c:1316
DBusMessageFilter::free_user_data_function
DBusFreeFunction free_user_data_function
Function to free the user data.
Definition: dbus-connection.c:233
DBusConnection::incoming_messages
DBusList * incoming_messages
Queue of messages we have received, end of the list received most recently.
Definition: dbus-connection.c:268
_dbus_warn_check_failed
void _dbus_warn_check_failed(const char *format,...)
Prints a "critical" warning to stderr when an assertion fails; differs from _dbus_warn primarily in t...
Definition: dbus-internals.c:258
_dbus_transport_get_unix_process_id
dbus_bool_t _dbus_transport_get_unix_process_id(DBusTransport *transport, unsigned long *pid)
See dbus_connection_get_unix_process_id().
Definition: dbus-transport.c:1343
dbus_message_get_signature
const char * dbus_message_get_signature(DBusMessage *message)
Gets the type signature of the message, i.e.
Definition: dbus-message.c:3620
_dbus_watch_list_toggle_watch
void _dbus_watch_list_toggle_watch(DBusWatchList *watch_list, DBusWatch *watch, dbus_bool_t enabled)
Sets a watch to the given enabled state, invoking the application&#39;s DBusWatchToggledFunction if appro...
Definition: dbus-watch.c:442
_dbus_transport_queue_messages
dbus_bool_t _dbus_transport_queue_messages(DBusTransport *transport)
Processes data we&#39;ve read while handling a watch, potentially converting some of it to messages and q...
Definition: dbus-transport.c:1140
DBUS_HANDLER_RESULT_NOT_YET_HANDLED
Message has not had any effect - see if other handlers want it.
Definition: dbus-shared.h:69
_dbus_transport_set_unix_user_function
void _dbus_transport_set_unix_user_function(DBusTransport *transport, DBusAllowUnixUserFunction function, void *data, DBusFreeFunction free_data_function, void **old_data, DBusFreeFunction *old_free_data_function)
See dbus_connection_set_unix_user_function().
Definition: dbus-transport.c:1413
dbus_message_iter_init_append
void dbus_message_iter_init_append(DBusMessage *message, DBusMessageIter *iter)
Initializes a DBusMessageIter for appending arguments to the end of a message.
Definition: dbus-message.c:2498
dbus_connection_set_dispatch_status_function
void dbus_connection_set_dispatch_status_function(DBusConnection *connection, DBusDispatchStatusFunction function, void *data, DBusFreeFunction free_data_function)
Set a function to be invoked when the dispatch status changes.
Definition: dbus-connection.c:5099
dbus_connection_set_data
dbus_bool_t dbus_connection_set_data(DBusConnection *connection, dbus_int32_t slot, void *data, DBusFreeFunction free_data_func)
Stores a pointer on a DBusConnection, along with an optional function to be used for freeing the data...
Definition: dbus-connection.c:6025
dbus_error_free
void dbus_error_free(DBusError *error)
Frees an error that&#39;s been set (or just initialized), then reinitializes the error as in dbus_error_i...
Definition: dbus-errors.c:211
_dbus_watch_list_free
void _dbus_watch_list_free(DBusWatchList *watch_list)
Frees a DBusWatchList.
Definition: dbus-watch.c:249
dbus_connection_set_route_peer_messages
void dbus_connection_set_route_peer_messages(DBusConnection *connection, dbus_bool_t value)
Normally DBusConnection automatically handles all messages to the org.freedesktop.DBus.Peer interface.
Definition: dbus-connection.c:5536
_dbus_object_tree_unregister_and_unlock
void _dbus_object_tree_unregister_and_unlock(DBusObjectTree *tree, const char **path)
Unregisters an object subtree that was registered with the same path.
Definition: dbus-object-tree.c:625
DBUS_INTERFACE_PEER
#define DBUS_INTERFACE_PEER
The interface supported by most dbus peers.
Definition: dbus-shared.h:99
_dbus_hash_table_unref
void _dbus_hash_table_unref(DBusHashTable *table)
Decrements the reference count for a hash table, freeing the hash table if the count reaches zero...
Definition: dbus-hash.c:361
_dbus_connection_close_if_only_one_ref
void _dbus_connection_close_if_only_one_ref(DBusConnection *connection)
Used internally to handle the semantics of dbus_server_set_new_connection_function().
Definition: dbus-connection.c:2146
DBUS_INTERFACE_LOCAL
#define DBUS_INTERFACE_LOCAL
This is a special interface whose methods can only be invoked by the local implementation (messages f...
Definition: dbus-shared.h:105
dbus_connection_return_message
void dbus_connection_return_message(DBusConnection *connection, DBusMessage *message)
Used to return a message after peeking at it using dbus_connection_borrow_message().
Definition: dbus-connection.c:3901
DBusConnection::refcount
DBusAtomic refcount
Reference count.
Definition: dbus-connection.c:258
_dbus_counter_ref
DBusCounter * _dbus_counter_ref(DBusCounter *counter)
Increments refcount of the counter.
Definition: dbus-resources.c:116
dbus_address_entries_free
void dbus_address_entries_free(DBusAddressEntry **entries)
Frees a NULL-terminated array of address entries.
Definition: dbus-address.c:189
_dbus_transport_get_windows_user
dbus_bool_t _dbus_transport_get_windows_user(DBusTransport *transport, char **windows_sid_p)
See dbus_connection_get_windows_user().
Definition: dbus-transport.c:1463
DBusPendingCall
Implementation details of DBusPendingCall - all fields are private.
Definition: dbus-pending-call.c:62
_dbus_rmutex_new_at_location
void _dbus_rmutex_new_at_location(DBusRMutex **location_p)
Creates a new mutex or creates a no-op mutex if threads are not initialized.
Definition: dbus-threads.c:53
dbus_connection_set_timeout_functions
dbus_bool_t dbus_connection_set_timeout_functions(DBusConnection *connection, DBusAddTimeoutFunction add_function, DBusRemoveTimeoutFunction remove_function, DBusTimeoutToggledFunction toggled_function, void *data, DBusFreeFunction free_data_function)
Sets the timeout functions for the connection.
Definition: dbus-connection.c:5015
DBusConnection
Implementation details of DBusConnection.
Definition: dbus-connection.c:256
dbus_message_has_interface
dbus_bool_t dbus_message_has_interface(DBusMessage *message, const char *iface)
Checks if the message has an interface.
Definition: dbus-message.c:3326
dbus_connection_remove_filter
void dbus_connection_remove_filter(DBusConnection *connection, DBusHandleMessageFunction function, void *user_data)
Removes a previously-added message filter.
Definition: dbus-connection.c:5620
DBusMutex
struct DBusMutex DBusMutex
An opaque mutex type provided by the DBusThreadFunctions implementation installed by dbus_threads_ini...
Definition: dbus-threads.h:41
_dbus_list_get_prev_link
#define _dbus_list_get_prev_link(list, link)
Gets the previous link in the list, or NULL if there are no more links.
Definition: dbus-list.h:117
_dbus_watch_list_new
DBusWatchList * _dbus_watch_list_new(void)
Creates a new watch list.
Definition: dbus-watch.c:232
DBusConnection::outgoing_counter
DBusCounter * outgoing_counter
Counts size of outgoing messages.
Definition: dbus-connection.c:278
DBusWatchAddFunction
dbus_bool_t(* DBusWatchAddFunction)(DBusWatchList *list, DBusWatch *watch)
Function to be called in protected_change_watch() with refcount held.
Definition: dbus-connection.c:670
DBUS_MESSAGE_TYPE_ERROR
#define DBUS_MESSAGE_TYPE_ERROR
Message type of an error reply message, see dbus_message_get_type()
Definition: dbus-protocol.h:238
_dbus_list_alloc_link
DBusList * _dbus_list_alloc_link(void *data)
Allocates a linked list node.
Definition: dbus-list.c:242
dbus_connection_get_unix_user
dbus_bool_t dbus_connection_get_unix_user(DBusConnection *connection, unsigned long *uid)
Gets the UNIX user ID of the connection if known.
Definition: dbus-connection.c:5221
dbus_connection_list_registered
dbus_bool_t dbus_connection_list_registered(DBusConnection *connection, const char *parent_path, char ***child_entries)
Lists the registered fallback handlers and object path handlers at the given parent_path.
Definition: dbus-connection.c:5935
dbus_message_get_path
const char * dbus_message_get_path(DBusMessage *message)
Gets the object path this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitt...
Definition: dbus-message.c:3173
_dbus_string_init
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
dbus_message_new_signal
DBusMessage * dbus_message_new_signal(const char *path, const char *iface, const char *name)
Constructs a new message representing a signal emission.
Definition: dbus-message.c:1451
_dbus_transport_get_max_message_size
long _dbus_transport_get_max_message_size(DBusTransport *transport)
See dbus_connection_get_max_message_size().
Definition: dbus-transport.c:1225
_dbus_hash_iter_next
dbus_bool_t _dbus_hash_iter_next(DBusHashIter *iter)
Move the hash iterator forward one step, to the next hash entry.
Definition: dbus-hash.c:543
_dbus_list_remove
dbus_bool_t _dbus_list_remove(DBusList **list, void *data)
Removes a value from the list.
Definition: dbus-list.c:415
dbus_connection_set_max_received_size
void dbus_connection_set_max_received_size(DBusConnection *connection, long size)
Sets the maximum total number of bytes that can be used for all messages received on this connection...
Definition: dbus-connection.c:6209
DBusConnection::dispatch_status_function
DBusDispatchStatusFunction dispatch_status_function
Function on dispatch status changes.
Definition: dbus-connection.c:298
DBusHandlerResult
DBusHandlerResult
Results that a message handler can return.
Definition: dbus-shared.h:66
DBUS_HASH_STRING
Hash keys are strings.
Definition: dbus-hash.h:69
_dbus_connection_get_message_to_send
DBusMessage * _dbus_connection_get_message_to_send(DBusConnection *connection)
Gets the next outgoing message.
Definition: dbus-connection.c:609
_dbus_list_pop_first_link
DBusList * _dbus_list_pop_first_link(DBusList **list)
Removes the first link in the list and returns it.
Definition: dbus-list.c:628
DBusHashIter
Hash iterator object.
Definition: dbus-hash.h:49
DBusMessageIter
DBusMessageIter struct; contains no public fields.
Definition: dbus-message.h:51
dbus_connection_steal_borrowed_message
void dbus_connection_steal_borrowed_message(DBusConnection *connection, DBusMessage *message)
Used to keep a message after peeking at it using dbus_connection_borrow_message().
Definition: dbus-connection.c:3935
_dbus_list_get_first
void * _dbus_list_get_first(DBusList **list)
Gets the first data in the list.
Definition: dbus-list.c:612
_dbus_pending_call_get_completed_unlocked
dbus_bool_t _dbus_pending_call_get_completed_unlocked(DBusPendingCall *pending)
Checks whether the pending call has received a reply yet, or not.
Definition: dbus-pending-call.c:480
_dbus_list_get_next_link
#define _dbus_list_get_next_link(list, link)
Gets the next link in the list, or NULL if there are no more links.
Definition: dbus-list.h:116
dbus_connection_free_data_slot
void dbus_connection_free_data_slot(dbus_int32_t *slot_p)
Deallocates a global ID for connection data slots.
Definition: dbus-connection.c:5995
DBUS_ERROR_UNKNOWN_METHOD
#define DBUS_ERROR_UNKNOWN_METHOD
Method name you invoked isn&#39;t known by the object you invoked it on.
Definition: dbus-protocol.h:397
dbus_message_get_destination
const char * dbus_message_get_destination(DBusMessage *message)
Gets the destination of a message or NULL if there is none set.
Definition: dbus-message.c:3527
DBusMessageFilter
Internal struct representing a message filter function.
Definition: dbus-connection.c:228
_dbus_message_add_counter_link
void _dbus_message_add_counter_link(DBusMessage *message, DBusList *link)
Adds a counter to be incremented immediately with the size/unix fds of this message, and decremented by the size/unix fds of this message when this message if finalized.
Definition: dbus-message.c:303
DBUS_PATH_LOCAL
#define DBUS_PATH_LOCAL
The object path used in local/in-process-generated messages.
Definition: dbus-shared.h:82
DBusRemoveTimeoutFunction
void(* DBusRemoveTimeoutFunction)(DBusTimeout *timeout, void *data)
Called when libdbus no longer needs a timeout to be monitored by the main loop.
Definition: dbus-connection.h:123
_dbus_list_copy
dbus_bool_t _dbus_list_copy(DBusList **list, DBusList **dest)
Copies a list.
Definition: dbus-list.c:697
_dbus_connection_block_pending_call
void _dbus_connection_block_pending_call(DBusPendingCall *pending)
Blocks until a pending call times out or gets a reply.
Definition: dbus-connection.c:2379
DBusConnection::watches
DBusWatchList * watches
Stores active watches.
Definition: dbus-connection.c:281
DBusConnection::mutex
DBusRMutex * mutex
Lock on the entire DBusConnection.
Definition: dbus-connection.c:260
_dbus_transport_get_is_connected
dbus_bool_t _dbus_transport_get_is_connected(DBusTransport *transport)
Returns TRUE if the transport has not been disconnected.
Definition: dbus-transport.c:527
_dbus_watch_list_set_functions
dbus_bool_t _dbus_watch_list_set_functions(DBusWatchList *watch_list, DBusAddWatchFunction add_function, DBusRemoveWatchFunction remove_function, DBusWatchToggledFunction toggled_function, void *data, DBusFreeFunction free_data_function)
Sets the watch functions.
Definition: dbus-watch.c:296
_dbus_hash_table_remove_int
dbus_bool_t _dbus_hash_table_remove_int(DBusHashTable *table, int key)
Removes the hash entry for the given key.
Definition: dbus-hash.c:1151
_dbus_connection_get_pending_fds_count
int _dbus_connection_get_pending_fds_count(DBusConnection *connection)
Return how many file descriptors are pending in the loader.
Definition: dbus-connection.c:2558
DBusCMutex
Definition: dbus-sysdeps-pthread.c:52
dbus_message_set_error_name
dbus_bool_t dbus_message_set_error_name(DBusMessage *message, const char *error_name)
Sets the name of the error (DBUS_MESSAGE_TYPE_ERROR).
Definition: dbus-message.c:3448
DBUS_DISPATCH_DATA_REMAINS
There is more data to potentially convert to messages.
Definition: dbus-connection.h:81
DBusSocket
Socket interface.
Definition: dbus-sysdeps.h:148
dbus_connection_send_with_reply_and_block
DBusMessage * dbus_connection_send_with_reply_and_block(DBusConnection *connection, DBusMessage *message, int timeout_milliseconds, DBusError *error)
Sends a message and blocks a certain time period while waiting for a reply.
Definition: dbus-connection.c:3535
dbus_connection_open_private
DBusConnection * dbus_connection_open_private(const char *address, DBusError *error)
Opens a new, dedicated connection to a remote address.
Definition: dbus-connection.c:2659
DBusMessageFilter::refcount
DBusAtomic refcount
Reference count.
Definition: dbus-connection.c:230
dbus_message_get_member
const char * dbus_message_get_member(DBusMessage *message)
Gets the interface member being invoked (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted (DBUS_MESSAGE_TYPE...
Definition: dbus-message.c:3390
dbus_connection_preallocate_send
DBusPreallocatedSend * dbus_connection_preallocate_send(DBusConnection *connection)
Preallocates resources needed to send a message, allowing the message to be sent without the possibil...
Definition: dbus-connection.c:3165
DBusObjectPathVTable
Virtual table that must be implemented to handle a portion of the object path hierarchy.
Definition: dbus-connection.h:384
DBusMessage
Internals of DBusMessage.
Definition: dbus-message-private.h:99
_dbus_pending_call_set_timeout_error_unlocked
dbus_bool_t _dbus_pending_call_set_timeout_error_unlocked(DBusPendingCall *pending, DBusMessage *message, dbus_uint32_t serial)
Sets the reply message associated with the pending call to a timeout error.
Definition: dbus-pending-call.c:354
dbus_pending_call_get_completed
dbus_bool_t dbus_pending_call_get_completed(DBusPendingCall *pending)
Checks whether the pending call has received a reply yet, or not.
Definition: dbus-pending-call.c:679
dbus_address_entry_get_value
const char * dbus_address_entry_get_value(DBusAddressEntry *entry, const char *key)
Returns a value from a key of an entry.
Definition: dbus-address.c:244
_dbus_transport_get_max_received_unix_fds
long _dbus_transport_get_max_received_unix_fds(DBusTransport *transport)
See dbus_connection_set_max_received_unix_fds().
Definition: dbus-transport.c:1297
DBUS_HASH_INT
Hash keys are integers.
Definition: dbus-hash.h:70
_dbus_rmutex_unlock
DBUS_PRIVATE_EXPORT void _dbus_rmutex_unlock(DBusRMutex *mutex)
Unlocks a mutex.
Definition: dbus-threads.c:150
DBUS_ERROR_OBJECT_PATH_IN_USE
#define DBUS_ERROR_OBJECT_PATH_IN_USE
There&#39;s already an object with the requested object path.
Definition: dbus-protocol.h:450
dbus_new0
#define dbus_new0(type, count)
Safe macro for using dbus_malloc0().
Definition: dbus-memory.h:59
_dbus_hash_table_get_n_entries
int _dbus_hash_table_get_n_entries(DBusHashTable *table)
Gets the number of hash entries in a hash table.
Definition: dbus-hash.c:1397
_dbus_timeout_list_add_timeout
dbus_bool_t _dbus_timeout_list_add_timeout(DBusTimeoutList *timeout_list, DBusTimeout *timeout)
Adds a new timeout to the timeout list, invoking the application DBusAddTimeoutFunction if appropriat...
Definition: dbus-timeout.c:310
_dbus_transport_set_windows_user_function
void _dbus_transport_set_windows_user_function(DBusTransport *transport, DBusAllowWindowsUserFunction function, void *data, DBusFreeFunction free_data_function, void **old_data, DBusFreeFunction *old_free_data_function)
See dbus_connection_set_windows_user_function().
Definition: dbus-transport.c:1499
_dbus_connection_remove_watch_unlocked
void _dbus_connection_remove_watch_unlocked(DBusConnection *connection, DBusWatch *watch)
Removes a watch using the connection&#39;s DBusRemoveWatchFunction if available.
Definition: dbus-connection.c:761
_dbus_transport_get_adt_audit_session_data
dbus_bool_t _dbus_transport_get_adt_audit_session_data(DBusTransport *transport, void **data, int *data_size)
See dbus_connection_get_adt_audit_session_data().
Definition: dbus-transport.c:1377
_dbus_pending_call_is_timeout_added_unlocked
dbus_bool_t _dbus_pending_call_is_timeout_added_unlocked(DBusPendingCall *pending)
Checks to see if a timeout has been added.
Definition: dbus-pending-call.c:248
DBusString
Definition: dbus-string.h:42
_dbus_hash_iter_get_value
void * _dbus_hash_iter_get_value(DBusHashIter *iter)
Gets the value of the current entry.
Definition: dbus-hash.c:613
DBusConnection::dispatch_status_data
void * dispatch_status_data
Application data for dispatch_status_function.
Definition: dbus-connection.c:299
dbus_bool_t
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
_dbus_connection_has_messages_to_send_unlocked
dbus_bool_t _dbus_connection_has_messages_to_send_unlocked(DBusConnection *connection)
Checks whether there are messages in the outgoing message queue.
Definition: dbus-connection.c:572
dbus_connection_set_exit_on_disconnect
void dbus_connection_set_exit_on_disconnect(DBusConnection *connection, dbus_bool_t exit_on_disconnect)
Set whether _exit() should be called when the connection receives a disconnect signal.
Definition: dbus-connection.c:3145
dbus_message_is_signal
dbus_bool_t dbus_message_is_signal(DBusMessage *message, const char *iface, const char *signal_name)
Checks whether the message is a signal with the given interface and member fields.
Definition: dbus-message.c:3707
DBusConnection::transport
DBusTransport * transport
Object that sends/receives messages over network.
Definition: dbus-connection.c:280
dbus_connection_dispatch
DBusDispatchStatus dbus_connection_dispatch(DBusConnection *connection)
Processes any incoming data.
Definition: dbus-connection.c:4575
dbus_connection_send
dbus_bool_t dbus_connection_send(DBusConnection *connection, DBusMessage *message, dbus_uint32_t *serial)
Adds a message to the outgoing message queue.
Definition: dbus-connection.c:3302
_dbus_transport_peek_is_authenticated
dbus_bool_t _dbus_transport_peek_is_authenticated(DBusTransport *transport)
Returns TRUE if we have been authenticated.
Definition: dbus-transport.c:701
dbus_connection_get_dispatch_status
DBusDispatchStatus dbus_connection_get_dispatch_status(DBusConnection *connection)
Gets the current state of the incoming message queue.
Definition: dbus-connection.c:4378
DBUS_DISPATCH_COMPLETE
All currently available data has been processed.
Definition: dbus-connection.h:82
DBusAddTimeoutFunction
dbus_bool_t(* DBusAddTimeoutFunction)(DBusTimeout *timeout, void *data)
Called when libdbus needs a new timeout to be monitored by the main loop.
Definition: dbus-connection.h:110
dbus_connection_get_data
void * dbus_connection_get_data(DBusConnection *connection, dbus_int32_t slot)
Retrieves data previously set with dbus_connection_set_data().
Definition: dbus-connection.c:6074
DBusConnection::timeouts
DBusTimeoutList * timeouts
Stores active timeouts.
Definition: dbus-connection.c:282
_dbus_object_tree_list_registered_and_unlock
dbus_bool_t _dbus_object_tree_list_registered_and_unlock(DBusObjectTree *tree, const char **parent_path, char ***child_entries)
Lists the registered fallback handlers and object path handlers at the given parent_path.
Definition: dbus-object-tree.c:1208
DBusTimeoutAddFunction
dbus_bool_t(* DBusTimeoutAddFunction)(DBusTimeoutList *list, DBusTimeout *timeout)
Function to be called in protected_change_timeout() with refcount held.
Definition: dbus-connection.c:794
dbus_connection_get_max_message_size
long dbus_connection_get_max_message_size(DBusConnection *connection)
Gets the value set by dbus_connection_set_max_message_size().
Definition: dbus-connection.c:6132
DBusConnection::pending_replies
DBusHashTable * pending_replies
Hash of message serials to DBusPendingCall.
Definition: dbus-connection.c:289
DBusObjectTree
Internals of DBusObjectTree.
Definition: dbus-object-tree.c:57
_dbus_warn
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
Definition: dbus-internals.c:230
_dbus_counter_unref
void _dbus_counter_unref(DBusCounter *counter)
Decrements refcount of the counter and possibly finalizes the counter.
Definition: dbus-resources.c:136
_dbus_atomic_inc
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
Definition: dbus-sysdeps-unix.c:2753
_dbus_message_remove_counter
void _dbus_message_remove_counter(DBusMessage *message, DBusCounter *counter)
Removes a counter tracking the size/unix fds of this message, and decrements the counter by the size/...
Definition: dbus-message.c:375
_dbus_list_append
dbus_bool_t _dbus_list_append(DBusList **list, void *data)
Appends a value to the list.
Definition: dbus-list.c:270
_dbus_decompose_path
dbus_bool_t _dbus_decompose_path(const char *data, int len, char ***path, int *path_len)
Decompose an object path.
Definition: dbus-object-tree.c:1244
_dbus_hash_table_insert_string
dbus_bool_t _dbus_hash_table_insert_string(DBusHashTable *table, char *key, void *value)
Creates a hash entry with the given key and value.
Definition: dbus-hash.c:1214
dbus_connection_get_unix_process_id
dbus_bool_t dbus_connection_get_unix_process_id(DBusConnection *connection, unsigned long *pid)
Gets the process ID of the connection if any.
Definition: dbus-connection.c:5257
dbus_connection_get_is_authenticated
dbus_bool_t dbus_connection_get_is_authenticated(DBusConnection *connection)
Gets whether the connection was authenticated.
Definition: dbus-connection.c:2995
dbus_connection_close
void dbus_connection_close(DBusConnection *connection)
Closes a private connection, so no further data can be sent or received.
Definition: dbus-connection.c:2932
dbus_connection_allocate_data_slot
dbus_bool_t dbus_connection_allocate_data_slot(dbus_int32_t *slot_p)
Allocates an integer ID to be used for storing application-specific data on any DBusConnection.
Definition: dbus-connection.c:5977
DBusAllowUnixUserFunction
dbus_bool_t(* DBusAllowUnixUserFunction)(DBusConnection *connection, unsigned long uid, void *data)
Called during authentication to check whether the given UNIX user ID is allowed to connect...
Definition: dbus-connection.h:143
_dbus_data_slot_list_set
dbus_bool_t _dbus_data_slot_list_set(DBusDataSlotAllocator *allocator, DBusDataSlotList *list, int slot, void *data, DBusFreeFunction free_data_func, DBusFreeFunction *old_free_func, void **old_data)
Stores a pointer in the data slot list, along with an optional function to be used for freeing the da...
Definition: dbus-dataslot.c:221
DBusConnection::io_path_acquired
dbus_bool_t io_path_acquired
Someone has transport io path (can use the transport to read/write messages)
Definition: dbus-connection.c:313
_dbus_list_foreach
void _dbus_list_foreach(DBusList **list, DBusForeachFunction function, void *data)
Calls the given function for each element in the list.
Definition: dbus-list.c:759
DBusWakeupMainFunction
void(* DBusWakeupMainFunction)(void *data)
Called when the main loop&#39;s thread should be notified that there&#39;s now work to do.
Definition: dbus-connection.h:135
_dbus_string_append_printf
dbus_bool_t _dbus_string_append_printf(DBusString *str, const char *format,...)
Appends a printf-style formatted string to the DBusString.
Definition: dbus-string.c:1114
DBusAddressEntry
Internals of DBusAddressEntry.
Definition: dbus-address.c:43
DBusConnection::outgoing_messages
DBusList * outgoing_messages
Queue of messages we need to send, send the end of the list first.
Definition: dbus-connection.c:267
dbus_connection_register_object_path
dbus_bool_t dbus_connection_register_object_path(DBusConnection *connection, const char *path, const DBusObjectPathVTable *vtable, void *user_data)
Registers a handler for a given path in the object hierarchy.
Definition: dbus-connection.c:5759
dbus_connection_set_max_message_unix_fds
void dbus_connection_set_max_message_unix_fds(DBusConnection *connection, long n)
Specifies the maximum number of unix fds a message on this connection is allowed to receive...
Definition: dbus-connection.c:6153
DBusConnection::objects
DBusObjectTree * objects
Object path handlers registered with this connection.
Definition: dbus-connection.c:304
dbus_connection_get_outgoing_unix_fds
long dbus_connection_get_outgoing_unix_fds(DBusConnection *connection)
Gets the approximate number of uni fds of all messages in the outgoing message queue.
Definition: dbus-connection.c:6353
DBusWatchRemoveFunction
void(* DBusWatchRemoveFunction)(DBusWatchList *list, DBusWatch *watch)
Function to be called in protected_change_watch() with refcount held.
Definition: dbus-connection.c:673
DBusConnection::client_serial
dbus_uint32_t client_serial
Client serial.
Definition: dbus-connection.c:291
dbus_connection_get_max_received_size
long dbus_connection_get_max_received_size(DBusConnection *connection)
Gets the value set by dbus_connection_set_max_received_size().
Definition: dbus-connection.c:6227
DBusConnection::io_path_mutex
DBusCMutex * io_path_mutex
Protects io_path_acquired.
Definition: dbus-connection.c:264
DBUS_MESSAGE_TYPE_METHOD_CALL
#define DBUS_MESSAGE_TYPE_METHOD_CALL
Message type of a method call message, see dbus_message_get_type()
Definition: dbus-protocol.h:234
dbus_connection_open
DBusConnection * dbus_connection_open(const char *address, DBusError *error)
Gets a connection to a remote address.
Definition: dbus-connection.c:2616
_dbus_connection_unref_unlocked
void _dbus_connection_unref_unlocked(DBusConnection *connection)
Decrements the reference count of a DBusConnection.
Definition: dbus-connection.c:1442
_dbus_connection_handle_watch
dbus_bool_t _dbus_connection_handle_watch(DBusWatch *watch, unsigned int condition, void *data)
A callback for use with dbus_watch_new() to create a DBusWatch.
Definition: dbus-connection.c:1486
_dbus_current_generation
int _dbus_current_generation
_dbus_current_generation is used to track each time that dbus_shutdown() is called, so we can reinit things after it&#39;s been called.
Definition: dbus-memory.c:781
dbus_connection_send_with_reply
dbus_bool_t dbus_connection_send_with_reply(DBusConnection *connection, DBusMessage *message, DBusPendingCall **pending_return, int timeout_milliseconds)
Queues a message to send, as with dbus_connection_send(), but also returns a DBusPendingCall used to ...
Definition: dbus-connection.c:3399
DBusError
Object representing an exception.
Definition: dbus-errors.h:48
_dbus_hash_iter_remove_entry
void _dbus_hash_iter_remove_entry(DBusHashIter *iter)
Removes the current entry from the hash table.
Definition: dbus-hash.c:592
_dbus_bus_notify_shared_connection_disconnected_unlocked
void _dbus_bus_notify_shared_connection_disconnected_unlocked(DBusConnection *connection)
Internal function that checks to see if this is a shared connection owned by the bus and if it is unr...
Definition: dbus-bus.c:387
_dbus_get_monotonic_time
void _dbus_get_monotonic_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
Definition: dbus-sysdeps-unix.c:2903
_dbus_disable_sigpipe
void _dbus_disable_sigpipe(void)
signal (SIGPIPE, SIG_IGN);
Definition: dbus-sysdeps-unix.c:3178
_dbus_transport_get_is_anonymous
dbus_bool_t _dbus_transport_get_is_anonymous(DBusTransport *transport)
See dbus_connection_get_is_anonymous().
Definition: dbus-transport.c:821
_dbus_list_pop_first
void * _dbus_list_pop_first(DBusList **list)
Removes the first value in the list and returns it.
Definition: dbus-list.c:649
dbus_connection_get_object_path_data
dbus_bool_t dbus_connection_get_object_path_data(DBusConnection *connection, const char *path, void **data_p)
Gets the user data passed to dbus_connection_register_object_path() or dbus_connection_register_fallb...
Definition: dbus-connection.c:5898
dbus_message_append_args
dbus_bool_t dbus_message_append_args(DBusMessage *message, int first_arg_type,...)
Appends fields to a message given a variable argument list.
Definition: dbus-message.c:1819
DBUS_ERROR_UNKNOWN_OBJECT
#define DBUS_ERROR_UNKNOWN_OBJECT
Object you invoked a method on isn&#39;t known.
Definition: dbus-protocol.h:399
dbus_connection_get_is_anonymous
dbus_bool_t dbus_connection_get_is_anonymous(DBusConnection *connection)
Gets whether the connection is not authenticated as a specific user.
Definition: dbus-connection.c:3029
DBUS_MESSAGE_TYPE_SIGNAL
#define DBUS_MESSAGE_TYPE_SIGNAL
Message type of a signal message, see dbus_message_get_type()
Definition: dbus-protocol.h:240
_dbus_connection_add_watch_unlocked
dbus_bool_t _dbus_connection_add_watch_unlocked(DBusConnection *connection, DBusWatch *watch)
Adds a watch using the connection&#39;s DBusAddWatchFunction if available.
Definition: dbus-connection.c:743
dbus_set_error
void dbus_set_error(DBusError *error, const char *name, const char *format,...)
Assigns an error name and message to a DBusError.
Definition: dbus-errors.c:354
dbus_message_get_reply_serial
dbus_uint32_t dbus_message_get_reply_serial(DBusMessage *message)
Returns the serial that the message is a reply to or 0 if none.
Definition: dbus-message.c:1190
dbus_connection_get_max_message_unix_fds
long dbus_connection_get_max_message_unix_fds(DBusConnection *connection)
Gets the value set by dbus_connection_set_max_message_unix_fds().
Definition: dbus-connection.c:6171
DBusConnection::wakeup_main_function
DBusWakeupMainFunction wakeup_main_function
Function to wake up the mainloop.
Definition: dbus-connection.c:294
_dbus_connection_send_and_unlock
dbus_bool_t _dbus_connection_send_and_unlock(DBusConnection *connection, DBusMessage *message, dbus_uint32_t *client_serial)
Like dbus_connection_send(), but assumes the connection is already locked on function entry...
Definition: dbus-connection.c:2098
_dbus_cmutex_unlock
void _dbus_cmutex_unlock(DBusCMutex *mutex)
Unlocks a mutex.
Definition: dbus-threads.c:164
DBusAllowWindowsUserFunction
dbus_bool_t(* DBusAllowWindowsUserFunction)(DBusConnection *connection, const char *user_sid, void *data)
Called during authentication to check whether the given Windows user ID is allowed to connect...
Definition: dbus-connection.h:153
DBusConnection::slot_list
DBusDataSlotList slot_list
Data stored by allocated integer ID.
Definition: dbus-connection.c:287
dbus_pending_call_ref
DBusPendingCall * dbus_pending_call_ref(DBusPendingCall *pending)
Increments the reference count on a pending call.
Definition: dbus-pending-call.c:577
_dbus_connection_message_sent_unlocked
void _dbus_connection_message_sent_unlocked(DBusConnection *connection, DBusMessage *message)
Notifies the connection that a message has been sent, so the message can be removed from the outgoing...
Definition: dbus-connection.c:625
_dbus_timeout_list_toggle_timeout
void _dbus_timeout_list_toggle_timeout(DBusTimeoutList *timeout_list, DBusTimeout *timeout, dbus_bool_t enabled)
Sets a timeout to the given enabled state, invoking the application&#39;s DBusTimeoutToggledFunction if a...
Definition: dbus-timeout.c:362
_dbus_pending_call_get_reply_serial_unlocked
dbus_uint32_t _dbus_pending_call_get_reply_serial_unlocked(DBusPendingCall *pending)
Gets the reply&#39;s serial number.
Definition: dbus-pending-call.c:293
_dbus_transport_open
DBusTransport * _dbus_transport_open(DBusAddressEntry *entry, DBusError *error)
Try to open a new transport for the given address entry.
Definition: dbus-transport.c:367
_dbus_connection_new_for_transport
DBusConnection * _dbus_connection_new_for_transport(DBusTransport *transport)
Creates a new connection for the given transport.
Definition: dbus-connection.c:1249
_DBUS_UNLOCK
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
Definition: dbus-internals.h:369
DBusConnection::disconnected_message_arrived
unsigned int disconnected_message_arrived
We popped or are dispatching the disconnected message.
Definition: dbus-connection.c:321
_dbus_string_free
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:259
dbus_connection_set_allow_anonymous
void dbus_connection_set_allow_anonymous(DBusConnection *connection, dbus_bool_t value)
This function must be called on the server side of a connection when the connection is first seen in ...
Definition: dbus-connection.c:5508
DBusConnection::disconnected_message_processed
unsigned int disconnected_message_processed
We did our default handling of the disconnected message, such as closing the connection.
Definition: dbus-connection.c:325
_dbus_transport_get_unix_user
dbus_bool_t _dbus_transport_get_unix_user(DBusTransport *transport, unsigned long *uid)
See dbus_connection_get_unix_user().
Definition: dbus-transport.c:1310
_dbus_data_slot_list_get
void * _dbus_data_slot_list_get(DBusDataSlotAllocator *allocator, DBusDataSlotList *list, int slot)
Retrieves data previously set with _dbus_data_slot_list_set_data().
Definition: dbus-dataslot.c:285
CONNECTION_UNLOCK
#define CONNECTION_UNLOCK(connection)
shorter and more visible way to write _dbus_connection_unlock()
Definition: dbus-pending-call.c:57
DBusTimeoutToggledFunction
void(* DBusTimeoutToggledFunction)(DBusTimeout *timeout, void *data)
Called when dbus_timeout_get_enabled() may return a different value than it did before.
Definition: dbus-connection.h:117
DBusConnection::route_peer_messages
unsigned int route_peer_messages
If TRUE, if org.freedesktop.DBus.Peer messages have a bus name, don&#39;t handle them automatically...
Definition: dbus-connection.c:319
TRUE
#define TRUE
Expands to "1".
_dbus_connection_set_pending_fds_function
void _dbus_connection_set_pending_fds_function(DBusConnection *connection, DBusPendingFdsChangeFunction callback, void *data)
Register a function to be called whenever the number of pending file descriptors in the loader change...
Definition: dbus-connection.c:2571
_dbus_data_slot_list_init
void _dbus_data_slot_list_init(DBusDataSlotList *list)
Initializes a slot list.
Definition: dbus-dataslot.c:197
_dbus_assert_not_reached
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
Definition: dbus-internals.h:159
DBusDataSlotList
Data structure that stores the actual user data set at a given slot.
Definition: dbus-dataslot.h:69
DBusConnection::io_path_cond
DBusCondVar * io_path_cond
Notify when io_path_acquired is available.
Definition: dbus-connection.c:265
DBusTimeoutToggleFunction
void(* DBusTimeoutToggleFunction)(DBusTimeoutList *list, DBusTimeout *timeout, dbus_bool_t enabled)
Function to be called in protected_change_timeout() with refcount held.
Definition: dbus-connection.c:800
_dbus_condvar_new_at_location
void _dbus_condvar_new_at_location(DBusCondVar **location_p)
This does the same thing as _dbus_condvar_new.
Definition: dbus-threads.c:199
DBusConnection::last_dispatch_status
DBusDispatchStatus last_dispatch_status
The last dispatch status we reported to the application.
Definition: dbus-connection.c:302
DBusConnection::exit_on_disconnect
unsigned int exit_on_disconnect
If TRUE, exit after handling disconnect signal.
Definition: dbus-connection.c:317
_dbus_transport_set_connection
dbus_bool_t _dbus_transport_set_connection(DBusTransport *transport, DBusConnection *connection)
Sets the connection using this transport.
Definition: dbus-transport.c:927
DBUS_ERROR_FAILED
#define DBUS_ERROR_FAILED
A generic error; "something went wrong" - see the error message for more.
Definition: dbus-protocol.h:355
_dbus_watch_list_add_watch
dbus_bool_t _dbus_watch_list_add_watch(DBusWatchList *watch_list, DBusWatch *watch)
Adds a new watch to the watch list, invoking the application DBusAddWatchFunction if appropriate...
Definition: dbus-watch.c:382
_dbus_list_free_link
void _dbus_list_free_link(DBusList *link)
Frees a linked list node allocated with _dbus_list_alloc_link.
Definition: dbus-list.c:254
dbus_move_error
void dbus_move_error(DBusError *src, DBusError *dest)
Moves an error src into dest, freeing src and overwriting dest.
Definition: dbus-errors.c:279
DBusError::name
const char * name
public error name field
Definition: dbus-errors.h:50
_dbus_object_tree_get_user_data_unlocked
void * _dbus_object_tree_get_user_data_unlocked(DBusObjectTree *tree, const char **path)
Looks up the data passed to _dbus_object_tree_register() for a handler at the given path...
Definition: dbus-object-tree.c:1077
_dbus_object_tree_register
dbus_bool_t _dbus_object_tree_register(DBusObjectTree *tree, dbus_bool_t fallback, const char **path, const DBusObjectPathVTable *vtable, void *user_data, DBusError *error)
Registers a new subtree in the global object tree.
Definition: dbus-object-tree.c:393
dbus_set_error_from_message
dbus_bool_t dbus_set_error_from_message(DBusError *error, DBusMessage *message)
Sets a DBusError based on the contents of the given message.
Definition: dbus-message.c:3873
DBusAddWatchFunction
dbus_bool_t(* DBusAddWatchFunction)(DBusWatch *watch, void *data)
Called when libdbus needs a new watch to be monitored by the main loop.
Definition: dbus-connection.h:91
_dbus_condvar_wake_one
void _dbus_condvar_wake_one(DBusCondVar *cond)
If there are threads waiting on the condition variable, wake up exactly one.
Definition: dbus-threads.c:278
DBUS_TYPE_UNIX_FD
#define DBUS_TYPE_UNIX_FD
Type code marking a unix file descriptor.
Definition: dbus-protocol.h:114
DBusWatchToggleFunction
void(* DBusWatchToggleFunction)(DBusWatchList *list, DBusWatch *watch, dbus_bool_t enabled)
Function to be called in protected_change_watch() with refcount held.
Definition: dbus-connection.c:676
dbus_pending_call_unref
void dbus_pending_call_unref(DBusPendingCall *pending)
Decrements the reference count on a pending call, freeing it if the count reaches 0...
Definition: dbus-pending-call.c:597
DBusTransport
Object representing a transport such as a socket.
Definition: dbus-transport-protected.h:80
DBusRemoveWatchFunction
void(* DBusRemoveWatchFunction)(DBusWatch *watch, void *data)
Called when libdbus no longer needs a watch to be monitored by the main loop.
Definition: dbus-connection.h:103
DBusWatchList
DBusWatchList implementation details.
Definition: dbus-watch.c:214
dbus_message_get_interface
const char * dbus_message_get_interface(DBusMessage *message)
Gets the interface this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitted...
Definition: dbus-message.c:3304
DBusConnection::n_incoming
int n_incoming
Length of incoming queue.
Definition: dbus-connection.c:276
dbus_connection_set_wakeup_main_function
void dbus_connection_set_wakeup_main_function(DBusConnection *connection, DBusWakeupMainFunction wakeup_main_function, void *data, DBusFreeFunction free_data_function)
Sets the mainloop wakeup function for the connection.
Definition: dbus-connection.c:5053
dbus_connection_pop_message
DBusMessage * dbus_connection_pop_message(DBusConnection *connection)
Returns the first-received message from the incoming message queue, removing it from the queue...
Definition: dbus-connection.c:4091
DBusDataSlotAllocator
An allocator that tracks a set of slot IDs.
Definition: dbus-dataslot.h:55
DBUS_TYPE_INVALID
#define DBUS_TYPE_INVALID
Type code that is never equal to a legitimate type code.
Definition: dbus-protocol.h:60
dbus_message_set_reply_serial
dbus_bool_t dbus_message_set_reply_serial(DBusMessage *message, dbus_uint32_t reply_serial)
Sets the reply serial of a message (the serial of the message this is a reply to).
Definition: dbus-message.c:1166
_dbus_exit
void _dbus_exit(int code)
Exit the process, returning the given value.
Definition: dbus-sysdeps-unix.c:3149
_dbus_pending_call_queue_timeout_error_unlocked
void _dbus_pending_call_queue_timeout_error_unlocked(DBusPendingCall *pending, DBusConnection *connection)
If the pending call hasn&#39;t been timed out, add its timeout error reply to the connection&#39;s incoming m...
Definition: dbus-pending-call.c:228
DBusPreallocatedSend
Internals of DBusPreallocatedSend.
Definition: dbus-connection.c:240
dbus_connection_set_unix_user_function
void dbus_connection_set_unix_user_function(DBusConnection *connection, DBusAllowUnixUserFunction function, void *data, DBusFreeFunction free_data_function)
Sets a predicate function used to determine whether a given user ID is allowed to connect...
Definition: dbus-connection.c:5336
DBusDispatchStatusFunction
void(* DBusDispatchStatusFunction)(DBusConnection *connection, DBusDispatchStatus new_status, void *data)
Called when the return value of dbus_connection_get_dispatch_status() may have changed.
Definition: dbus-connection.h:128
_dbus_transport_handle_watch
dbus_bool_t _dbus_transport_handle_watch(DBusTransport *transport, DBusWatch *watch, unsigned int condition)
Handles a watch by reading data, writing data, or disconnecting the transport, as appropriate for the...
Definition: dbus-transport.c:889
DBusPreallocatedSend::counter_link
DBusList * counter_link
Preallocated link in the resource counter.
Definition: dbus-connection.c:244
_dbus_object_tree_new
DBusObjectTree * _dbus_object_tree_new(DBusConnection *connection)
Creates a new object tree, representing a mapping from paths to handler vtables.
Definition: dbus-object-tree.c:92
_dbus_watch_list_remove_watch
void _dbus_watch_list_remove_watch(DBusWatchList *watch_list, DBusWatch *watch)
Removes a watch from the watch list, invoking the application&#39;s DBusRemoveWatchFunction if appropriat...
Definition: dbus-watch.c:415
dbus_pending_call_block
void dbus_pending_call_block(DBusPendingCall *pending)
Block until the pending call is completed.
Definition: dbus-pending-call.c:737
_dbus_hash_table_remove_string
dbus_bool_t _dbus_hash_table_remove_string(DBusHashTable *table, const char *key)
Removes the hash entry for the given key.
Definition: dbus-hash.c:1123
_dbus_timeout_list_remove_timeout
void _dbus_timeout_list_remove_timeout(DBusTimeoutList *timeout_list, DBusTimeout *timeout)
Removes a timeout from the timeout list, invoking the application&#39;s DBusRemoveTimeoutFunction if appr...
Definition: dbus-timeout.c:340
DBusConnection::n_outgoing
int n_outgoing
Length of outgoing queue.
Definition: dbus-connection.c:275
DBusConnection::dispatch_mutex
DBusCMutex * dispatch_mutex
Protects dispatch_acquired.
Definition: dbus-connection.c:262
_dbus_pending_call_new_unlocked
DBUS_PRIVATE_EXPORT DBusPendingCall * _dbus_pending_call_new_unlocked(DBusConnection *connection, int timeout_milliseconds, DBusTimeoutHandler timeout_handler)
Creates a new pending reply object.
Definition: dbus-pending-call.c:109
_dbus_atomic_dec
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
Definition: dbus-sysdeps-unix.c:2776
_dbus_pending_call_set_reply_unlocked
void _dbus_pending_call_set_reply_unlocked(DBusPendingCall *pending, DBusMessage *message)
Sets the reply of a pending call with the given message, or if the message is NULL, by timing out the pending call.
Definition: dbus-pending-call.c:172
DBusTimeoutRemoveFunction
void(* DBusTimeoutRemoveFunction)(DBusTimeoutList *list, DBusTimeout *timeout)
Function to be called in protected_change_timeout() with refcount held.
Definition: dbus-connection.c:797
DBusList
A node in a linked list.
Definition: dbus-list.h:34
dbus_connection_set_watch_functions
dbus_bool_t dbus_connection_set_watch_functions(DBusConnection *connection, DBusAddWatchFunction add_function, DBusRemoveWatchFunction remove_function, DBusWatchToggledFunction toggled_function, void *data, DBusFreeFunction free_data_function)
Sets the watch functions for the connection.
Definition: dbus-connection.c:4952
_dbus_hash_iter_init
void _dbus_hash_iter_init(DBusHashTable *table, DBusHashIter *iter)
Initializes a hash table iterator.
Definition: dbus-hash.c:517
_dbus_list_unlink
void _dbus_list_unlink(DBusList **list, DBusList *link)
Removes the given link from the list, but doesn&#39;t free it.
Definition: dbus-list.c:499
dbus_free_string_array
void dbus_free_string_array(char **str_array)
Frees a NULL-terminated array of strings.
Definition: dbus-memory.c:749
DBusHandleMessageFunction
DBusHandlerResult(* DBusHandleMessageFunction)(DBusConnection *connection, DBusMessage *message, void *user_data)
Called when a message needs to be handled.
Definition: dbus-connection.h:169
_dbus_transport_ref
DBusTransport * _dbus_transport_ref(DBusTransport *transport)
Increments the reference count for the transport.
Definition: dbus-transport.c:460
_dbus_transport_try_to_authenticate
dbus_bool_t _dbus_transport_try_to_authenticate(DBusTransport *transport)
Returns TRUE if we have been authenticated.
Definition: dbus-transport.c:724
DBusConnection::dispatch_cond
DBusCondVar * dispatch_cond
Notify when dispatch_acquired is available.
Definition: dbus-connection.c:263
_dbus_connection_remove_timeout_unlocked
void _dbus_connection_remove_timeout_unlocked(DBusConnection *connection, DBusTimeout *timeout)
Removes a timeout using the connection&#39;s DBusRemoveTimeoutFunction if available.
Definition: dbus-connection.c:885
dbus_connection_register_fallback
dbus_bool_t dbus_connection_register_fallback(DBusConnection *connection, const char *path, const DBusObjectPathVTable *vtable, void *user_data)
Registers a fallback handler for a given subsection of the object hierarchy.
Definition: dbus-connection.c:5831
_dbus_rmutex_free_at_location
void _dbus_rmutex_free_at_location(DBusRMutex **location_p)
Frees a DBusRMutex; does nothing if passed a NULL pointer.
Definition: dbus-threads.c:94
_dbus_transport_do_iteration
void _dbus_transport_do_iteration(DBusTransport *transport, unsigned int flags, int timeout_milliseconds)
Performs a single poll()/select() on the transport&#39;s file descriptors and then reads/writes data as a...
Definition: dbus-transport.c:984
_dbus_transport_get_max_received_size
long _dbus_transport_get_max_received_size(DBusTransport *transport)
See dbus_connection_get_max_received_size().
Definition: dbus-transport.c:1285
dbus_connection_get_adt_audit_session_data
dbus_bool_t dbus_connection_get_adt_audit_session_data(DBusConnection *connection, void **data, dbus_int32_t *data_size)
Gets the ADT audit data of the connection if any.
Definition: dbus-connection.c:5290
_dbus_transport_get_max_message_unix_fds
long _dbus_transport_get_max_message_unix_fds(DBusTransport *transport)
See dbus_connection_get_max_message_unix_fds().
Definition: dbus-transport.c:1237
DBusCondVar
Definition: dbus-sysdeps-pthread.c:56
_dbus_hash_table_lookup_string
void * _dbus_hash_table_lookup_string(DBusHashTable *table, const char *key)
Looks up the value for a given string in a hash table of type DBUS_HASH_STRING.
Definition: dbus-hash.c:1049
_dbus_hash_table_lookup_int
void * _dbus_hash_table_lookup_int(DBusHashTable *table, int key)
Looks up the value for a given integer in a hash table of type DBUS_HASH_INT.
Definition: dbus-hash.c:1074
_dbus_transport_set_pending_fds_function
void _dbus_transport_set_pending_fds_function(DBusTransport *transport, void(*callback)(void *), void *data)
Register a function to be called whenever the number of pending file descriptors in the loader change...
Definition: dbus-transport.c:1561
DBUS_ERROR_DISCONNECTED
#define DBUS_ERROR_DISCONNECTED
The connection is disconnected and you&#39;re trying to use it.
Definition: dbus-protocol.h:389
_dbus_counter_new
DBusCounter * _dbus_counter_new(void)
Creates a new DBusCounter.
Definition: dbus-resources.c:89
_dbus_cmutex_lock
void _dbus_cmutex_lock(DBusCMutex *mutex)
Locks a mutex.
Definition: dbus-threads.c:136
_dbus_connection_queue_received_message_link
void _dbus_connection_queue_received_message_link(DBusConnection *connection, DBusList *link)
Adds a message-containing list link to the incoming message queue, taking ownership of the link and t...
Definition: dbus-connection.c:480
_dbus_transport_set_allow_anonymous
void _dbus_transport_set_allow_anonymous(DBusTransport *transport, dbus_bool_t value)
See dbus_connection_set_allow_anonymous()
Definition: dbus-transport.c:1536
_dbus_connection_close_possibly_shared
void _dbus_connection_close_possibly_shared(DBusConnection *connection)
Closes a shared OR private connection, while dbus_connection_close() can only be used on private conn...
Definition: dbus-connection.c:1948
DBusMessageFilter::function
DBusHandleMessageFunction function
Function to call to filter.
Definition: dbus-connection.c:231
DBUS_ERROR_NO_MEMORY
#define DBUS_ERROR_NO_MEMORY
There was not enough memory to complete an operation.
Definition: dbus-protocol.h:357
_dbus_connection_remove_pending_call
void _dbus_connection_remove_pending_call(DBusConnection *connection, DBusPendingCall *pending)
Removes a pending call from the connection, such that the pending reply will be ignored.
Definition: dbus-connection.c:1044
dbus_message_iter_append_basic
dbus_bool_t dbus_message_iter_append_basic(DBusMessageIter *iter, int type, const void *value)
Appends a basic-typed value to the message.
Definition: dbus-message.c:2733
_dbus_transport_set_max_received_size
void _dbus_transport_set_max_received_size(DBusTransport *transport, long size)
See dbus_connection_set_max_received_size().
Definition: dbus-transport.c:1249
DBusForeachFunction
void(* DBusForeachFunction)(void *element, void *data)
Used to iterate over each item in a collection, such as a DBusList.
Definition: dbus-internals.h:283
DBusConnection::expired_messages
DBusList * expired_messages
Messages that will be released when we next unlock.
Definition: dbus-connection.c:269
_dbus_list_get_first_link
DBusList * _dbus_list_get_first_link(DBusList **list)
Gets the first link in the list.
Definition: dbus-list.c:567
FALSE
#define FALSE
Expands to "0".
dbus_message_get_type
int dbus_message_get_type(DBusMessage *message)
Gets the type of a message.
Definition: dbus-message.c:1749
dbus_connection_get_server_id
char * dbus_connection_get_server_id(DBusConnection *connection)
Gets the ID of the server address we are authenticated to, if this connection is on the client side...
Definition: dbus-connection.c:3074
dbus_connection_get_unix_fd
dbus_bool_t dbus_connection_get_unix_fd(DBusConnection *connection, int *fd)
Get the UNIX file descriptor of the connection, if any.
Definition: dbus-connection.c:5144
_dbus_transport_get_pending_fds_count
int _dbus_transport_get_pending_fds_count(DBusTransport *transport)
Return how many file descriptors are pending in the loader.
Definition: dbus-transport.c:1548
_dbus_list_prepend_link
void _dbus_list_prepend_link(DBusList **list, DBusList *link)
Prepends a link to the list.
Definition: dbus-list.c:333
_dbus_register_shutdown_func
DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_register_shutdown_func(DBusShutdownFunction function, void *data)
Register a cleanup function to be called exactly once the next time dbus_shutdown() is called...
Definition: dbus-memory.c:810
_DBUS_LOCK
#define _DBUS_LOCK(name)
Locks a global lock, initializing it first if necessary.
Definition: dbus-internals.h:368
dbus_parse_address
dbus_bool_t dbus_parse_address(const char *address, DBusAddressEntry ***entry, int *array_len, DBusError *error)
Parses an address string of the form:
Definition: dbus-address.c:363
_DBUS_LOCK_NAME
#define _DBUS_LOCK_NAME(name)
Expands to name of a global lock variable.
Definition: dbus-internals.h:367
_dbus_transport_can_pass_unix_fd
dbus_bool_t _dbus_transport_can_pass_unix_fd(DBusTransport *transport)
Returns TRUE if the transport supports sending unix fds.
Definition: dbus-transport.c:843
_dbus_cmutex_free_at_location
void _dbus_cmutex_free_at_location(DBusCMutex **location_p)
Frees a DBusCMutex; does nothing if passed a NULL pointer.
Definition: dbus-threads.c:107
DBusConnection::server_guid
char * server_guid
GUID of server if we are in shared_connections, NULL if server GUID is unknown or connection is priva...
Definition: dbus-connection.c:306
dbus_connection_get_is_connected
dbus_bool_t dbus_connection_get_is_connected(DBusConnection *connection)
Gets whether the connection is currently open.
Definition: dbus-connection.c:2973
dbus_connection_send_preallocated
void dbus_connection_send_preallocated(DBusConnection *connection, DBusPreallocatedSend *preallocated, DBusMessage *message, dbus_uint32_t *client_serial)
Sends a message using preallocated resources.
Definition: dbus-connection.c:3217
dbus_connection_unref
void dbus_connection_unref(DBusConnection *connection)
Decrements the reference count of a DBusConnection, and finalizes it if the count reaches zero...
Definition: dbus-connection.c:2817
_dbus_atomic_get
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
Definition: dbus-sysdeps-unix.c:2800
DBusRMutex
Definition: dbus-sysdeps-pthread.c:48
DBusHashTable
Internals of DBusHashTable.
Definition: dbus-hash.c:168
_dbus_sleep_milliseconds
void _dbus_sleep_milliseconds(int milliseconds)
Sleeps the given number of milliseconds.
Definition: dbus-sysdeps-unix.c:3064
_dbus_object_tree_unref
void _dbus_object_tree_unref(DBusObjectTree *tree)
Decrement the reference count.
Definition: dbus-object-tree.c:143
_dbus_data_slot_allocator_alloc
dbus_bool_t _dbus_data_slot_allocator_alloc(DBusDataSlotAllocator *allocator, dbus_int32_t *slot_id_p)
Allocates an integer ID to be used for storing data in a DBusDataSlotList.
Definition: dbus-dataslot.c:69
_dbus_pending_call_ref_unlocked
DBUS_PRIVATE_EXPORT DBusPendingCall * _dbus_pending_call_ref_unlocked(DBusPendingCall *pending)
Increments the reference count on a pending call, while the lock on its connection is already held...
Definition: dbus-pending-call.c:394
dbus_connection_borrow_message
DBusMessage * dbus_connection_borrow_message(DBusConnection *connection)
Returns the first-received message from the incoming message queue, leaving it in the queue...
Definition: dbus-connection.c:3850
_dbus_connection_ref_unlocked
DBusConnection * _dbus_connection_ref_unlocked(DBusConnection *connection)
Increments the reference count of a DBusConnection.
Definition: dbus-connection.c:1419
DBUS_HANDLER_RESULT_HANDLED
Message has had its effect - no need to run more handlers.
Definition: dbus-shared.h:68
_dbus_connection_do_iteration_unlocked
void _dbus_connection_do_iteration_unlocked(DBusConnection *connection, DBusPendingCall *pending, unsigned int flags, int timeout_milliseconds)
Queues incoming messages and sends outgoing messages for this connection, optionally blocking in the ...
Definition: dbus-connection.c:1198
dbus_int32_t
int dbus_int32_t
A 32-bit signed integer on all platforms.
Definition: dbus-arch-deps.h:42
_dbus_strdup
char * _dbus_strdup(const char *str)
Duplicates a string.
Definition: dbus-internals.c:537
CONNECTION_LOCK
#define CONNECTION_LOCK(connection)
Internals of DBusPendingCall.
Definition: dbus-pending-call.c:53
DBusConnection::dispatch_acquired
dbus_bool_t dispatch_acquired
Someone has dispatch path (can drain incoming queue)
Definition: dbus-connection.c:312
_dbus_transport_disconnect
void _dbus_transport_disconnect(DBusTransport *transport)
Closes our end of the connection to a remote application.
Definition: dbus-transport.c:502
_dbus_pending_call_get_timeout_unlocked
DBusTimeout * _dbus_pending_call_get_timeout_unlocked(DBusPendingCall *pending)
Retrives the timeout.
Definition: dbus-pending-call.c:279
_dbus_data_slot_allocator_free
void _dbus_data_slot_allocator_free(DBusDataSlotAllocator *allocator, dbus_int32_t *slot_id_p)
Deallocates an ID previously allocated with _dbus_data_slot_allocator_alloc().
Definition: dbus-dataslot.c:154
dbus_connection_add_filter
dbus_bool_t dbus_connection_add_filter(DBusConnection *connection, DBusHandleMessageFunction function, void *user_data, DBusFreeFunction free_data_function)
Adds a message filter.
Definition: dbus-connection.c:5568
dbus_connection_unregister_object_path
dbus_bool_t dbus_connection_unregister_object_path(DBusConnection *connection, const char *path)
Unregisters the handler registered with exactly the given path.
Definition: dbus-connection.c:5866
dbus_connection_get_max_received_unix_fds
long dbus_connection_get_max_received_unix_fds(DBusConnection *connection)
Gets the value set by dbus_connection_set_max_received_unix_fds().
Definition: dbus-connection.c:6269
dbus_connection_try_register_object_path
dbus_bool_t dbus_connection_try_register_object_path(DBusConnection *connection, const char *path, const DBusObjectPathVTable *vtable, void *user_data, DBusError *error)
Registers a handler for a given path in the object hierarchy.
Definition: dbus-connection.c:5729
_dbus_connection_unlock
void _dbus_connection_unlock(DBusConnection *connection)
Releases the connection lock.
Definition: dbus-connection.c:399
dbus_message_type_to_string
const char * dbus_message_type_to_string(int type)
Utility function to convert a D-Bus message type into a machine-readable string (not translated)...
Definition: dbus-message.c:4768
_dbus_transport_set_max_message_size
void _dbus_transport_set_max_message_size(DBusTransport *transport, long size)
See dbus_connection_set_max_message_size().
Definition: dbus-transport.c:1199
dbus_message_unref
void dbus_message_unref(DBusMessage *message)
Decrements the reference count of a DBusMessage, freeing the message if the count reaches 0...
Definition: dbus-message.c:1717
DBusConnection::wakeup_main_data
void * wakeup_main_data
Application data for wakeup_main_function.
Definition: dbus-connection.c:295
DBUS_HANDLER_RESULT_NEED_MEMORY
Need more memory in order to return DBUS_HANDLER_RESULT_HANDLED or DBUS_HANDLER_RESULT_NOT_YET_HANDLE...
Definition: dbus-shared.h:70
dbus_connection_flush
void dbus_connection_flush(DBusConnection *connection)
Blocks until the outgoing message queue is empty.
Definition: dbus-connection.c:3641
_dbus_condvar_free_at_location
void _dbus_condvar_free_at_location(DBusCondVar **location_p)
Frees a condition variable; does nothing if passed a NULL pointer.
Definition: dbus-threads.c:224
dbus_connection_has_messages_to_send
dbus_bool_t dbus_connection_has_messages_to_send(DBusConnection *connection)
Checks whether there are messages in the outgoing message queue.
Definition: dbus-connection.c:588
_dbus_cmutex_new_at_location
void _dbus_cmutex_new_at_location(DBusCMutex **location_p)
Creates a new mutex or creates a no-op mutex if threads are not initialized.
Definition: dbus-threads.c:77
_dbus_pending_call_unref_and_unlock
DBUS_PRIVATE_EXPORT void _dbus_pending_call_unref_and_unlock(DBusPendingCall *pending)
Decrements the reference count on a pending call, freeing it if the count reaches 0...
Definition: dbus-pending-call.c:457
_dbus_transport_get_dispatch_status
DBusDispatchStatus _dbus_transport_get_dispatch_status(DBusTransport *transport)
Reports our current dispatch status (whether there&#39;s buffered data to be queued as messages...
Definition: dbus-transport.c:1101
_dbus_pending_call_set_timeout_added_unlocked
void _dbus_pending_call_set_timeout_added_unlocked(DBusPendingCall *pending, dbus_bool_t is_added)
Sets wether the timeout has been added.
Definition: dbus-pending-call.c:263
DBusPreallocatedSend::connection
DBusConnection * connection
Connection we&#39;d send the message to.
Definition: dbus-connection.c:242
_dbus_pending_call_get_connection_and_lock
DBusConnection * _dbus_pending_call_get_connection_and_lock(DBusPendingCall *pending)
Gets the connection associated with this pending call.
Definition: dbus-pending-call.c:323
_dbus_connection_toggle_timeout_unlocked
void _dbus_connection_toggle_timeout_unlocked(DBusConnection *connection, DBusTimeout *timeout, dbus_bool_t enabled)
Toggles a timeout and notifies app via connection&#39;s DBusTimeoutToggledFunction if available...
Definition: dbus-connection.c:905
dbus_type_is_valid
dbus_bool_t dbus_type_is_valid(int typecode)
Return TRUE if the argument is a valid typecode.
Definition: dbus-signature.c:383
_dbus_transport_set_max_message_unix_fds
void _dbus_transport_set_max_message_unix_fds(DBusTransport *transport, long n)
See dbus_connection_set_max_message_unix_fds().
Definition: dbus-transport.c:1212
dbus_connection_set_max_received_unix_fds
void dbus_connection_set_max_received_unix_fds(DBusConnection *connection, long n)
Sets the maximum total number of unix fds that can be used for all messages received on this connecti...
Definition: dbus-connection.c:6251
_dbus_hash_table_new
DBusHashTable * _dbus_hash_table_new(DBusHashType type, DBusFreeFunction key_free_function, DBusFreeFunction value_free_function)
Constructs a new hash table.
Definition: dbus-hash.c:285
dbus_connection_get_socket
dbus_bool_t dbus_connection_get_socket(DBusConnection *connection, int *fd)
Gets the underlying Windows or UNIX socket file descriptor of the connection, if any.
Definition: dbus-connection.c:5174
dbus_connection_free_preallocated_send
void dbus_connection_free_preallocated_send(DBusConnection *connection, DBusPreallocatedSend *preallocated)
Frees preallocated message-sending resources from dbus_connection_preallocate_send().
Definition: dbus-connection.c:3191
dbus_message_set_serial
void dbus_message_set_serial(DBusMessage *message, dbus_uint32_t serial)
Sets the serial number of a message.
Definition: dbus-message.c:277
DBusTimeoutList
DBusTimeoutList implementation details.
Definition: dbus-timeout.c:176
dbus_message_new_method_return
DBusMessage * dbus_message_new_method_return(DBusMessage *method_call)
Constructs a message that is a reply to a method call.
Definition: dbus-message.c:1400
DBusConnection::slot_mutex
DBusRMutex * slot_mutex
Lock on slot_list so overall connection lock need not be taken.
Definition: dbus-connection.c:286
_dbus_transport_unref
void _dbus_transport_unref(DBusTransport *transport)
Decrements the reference count for the transport.
Definition: dbus-transport.c:477
_dbus_counter_get_unix_fd_value
long _dbus_counter_get_unix_fd_value(DBusCounter *counter)
Gets the current value of the unix fd counter.
Definition: dbus-resources.c:286
_dbus_data_slot_list_free
void _dbus_data_slot_list_free(DBusDataSlotList *list)
Frees the data slot list and all data slots contained in it, calling application-provided free functi...
Definition: dbus-dataslot.c:340
_dbus_list_clear
void _dbus_list_clear(DBusList **list)
Frees all links in the list and sets the list head to NULL.
Definition: dbus-list.c:542
dbus_timeout_get_interval
DBUS_EXPORT int dbus_timeout_get_interval(DBusTimeout *timeout)
Gets the timeout interval.
Definition: dbus-timeout.c:416
dbus_connection_read_write_dispatch
dbus_bool_t dbus_connection_read_write_dispatch(DBusConnection *connection, int timeout_milliseconds)
This function is intended for use with applications that don&#39;t want to write a main loop and deal wit...
Definition: dbus-connection.c:3769
_dbus_counter_get_size_value
long _dbus_counter_get_size_value(DBusCounter *counter)
Gets the current value of the size counter.
Definition: dbus-resources.c:274
dbus_message_new_error
DBusMessage * dbus_message_new_error(DBusMessage *reply_to, const char *error_name, const char *error_message)
Creates a new message that is an error reply to another message.
Definition: dbus-message.c:1497