D-Bus  1.13.7
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 
224 
229 {
232  void *user_data;
234 };
235 
236 
241 {
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 
257 {
291  dbus_uint32_t client_serial;
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  */
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;
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
389 {
390  CONNECTION_LOCK (connection);
391 }
392 
398 void
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
481  DBusList *link)
482 {
483  DBusPendingCall *pending;
484  dbus_uint32_t reply_serial;
485  DBusMessage *message;
486 
488 
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  {
504 
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,
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),
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
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 
573 {
574  HAVE_LOCK_CHECK (connection);
575  return connection->outgoing_messages != NULL;
576 }
577 
589 {
590  dbus_bool_t v;
591 
592  _dbus_return_val_if_fail (connection != NULL, FALSE);
593 
594  CONNECTION_LOCK (connection);
596  CONNECTION_UNLOCK (connection);
597 
598  return v;
599 }
600 
610 {
611  HAVE_LOCK_CHECK (connection);
612 
613  return _dbus_list_get_last (&connection->outgoing_messages);
614 }
615 
624 void
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,
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 
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 
744  DBusWatch *watch)
745 {
746  return protected_change_watch (connection, watch,
748  NULL, NULL, FALSE);
749 }
750 
760 void
762  DBusWatch *watch)
763 {
764  protected_change_watch (connection, watch,
765  NULL,
767  NULL, FALSE);
768 }
769 
780 void
782  DBusWatch *watch,
783  dbus_bool_t enabled)
784 {
785  _dbus_assert (watch != NULL);
786 
787  protected_change_watch (connection, watch,
788  NULL, NULL,
790  enabled);
791 }
792 
795  DBusTimeout *timeout);
798  DBusTimeout *timeout);
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 
868  DBusTimeout *timeout)
869 {
870  return protected_change_timeout (connection, timeout,
872  NULL, NULL, FALSE);
873 }
874 
884 void
886  DBusTimeout *timeout)
887 {
888  protected_change_timeout (connection, timeout,
889  NULL,
891  NULL, FALSE);
892 }
893 
904 void
906  DBusTimeout *timeout,
907  dbus_bool_t enabled)
908 {
909  protected_change_timeout (connection, timeout,
910  NULL, NULL,
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 
936  reply_serial,
937  pending))
938  {
939  _dbus_connection_remove_timeout_unlocked (connection, timeout);
940 
942  HAVE_LOCK_CHECK (connection);
943  return FALSE;
944  }
945 
947  }
948  else
949  {
951  reply_serial,
952  pending))
953  {
954  HAVE_LOCK_CHECK (connection);
955  return FALSE;
956  }
957  }
958 
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 
982  {
985 
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);
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  */
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  */
1025 
1029 
1031 
1033 }
1034 
1043 void
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
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,
1222  {
1223  _dbus_verbose ("pending call completed while acquiring I/O path (reply found in queue)");
1224  }
1225  else
1226  {
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 
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 =
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 
1293  if (connection->io_path_mutex == NULL)
1294  goto error;
1295 
1297  if (connection->dispatch_mutex == NULL)
1298  goto error;
1299 
1301  if (connection->dispatch_cond == NULL)
1302  goto error;
1303 
1305  if (connection->io_path_cond == NULL)
1306  goto error;
1307 
1309  if (connection->slot_mutex == NULL)
1310  goto error;
1311 
1312  disconnect_message = dbus_message_new_signal (DBUS_PATH_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)
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  {
1387  _dbus_rmutex_free_at_location (&connection->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 
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
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 
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);
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
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;
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 */
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,
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  */
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 
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
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  const char *error_name,
2188  const char *error_msg)
2189 {
2190  DBusMessage *message;
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,
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);
2305 
2307  connection);
2308 
2314 
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 */
2329  _dbus_connection_detach_pending_call_and_unlock (connection, pending);
2330 
2331  /* Must be called unlocked since it invokes app callback */
2333  dbus_pending_call_unref (pending);
2334 }
2335 
2336 static dbus_bool_t
2337 check_for_reply_and_update_dispatch_unlocked (DBusConnection *connection,
2338  DBusPendingCall *pending)
2339 {
2340  DBusMessage *reply;
2341  DBusDispatchStatus status;
2342 
2343  reply = check_for_reply_unlocked (connection,
2345  if (reply != NULL)
2346  {
2347  _dbus_verbose ("checked for reply\n");
2348 
2349  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
2350 
2351  complete_pending_call_and_unlock (connection, pending, reply);
2352  dbus_message_unref (reply);
2353 
2354  CONNECTION_LOCK (connection);
2355  status = _dbus_connection_get_dispatch_status_unlocked (connection);
2356  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2357  dbus_pending_call_unref (pending);
2358 
2359  return TRUE;
2360  }
2361 
2362  return FALSE;
2363 }
2364 
2379 void
2381 {
2382  long start_tv_sec, start_tv_usec;
2383  long tv_sec, tv_usec;
2384  DBusDispatchStatus status;
2385  DBusConnection *connection;
2386  dbus_uint32_t client_serial;
2387  DBusTimeout *timeout;
2388  int timeout_milliseconds, elapsed_milliseconds;
2389 
2390  _dbus_assert (pending != NULL);
2391 
2392  if (dbus_pending_call_get_completed (pending))
2393  return;
2394 
2395  dbus_pending_call_ref (pending); /* necessary because the call could be canceled */
2396 
2397  connection = _dbus_pending_call_get_connection_and_lock (pending);
2398 
2399  /* Flush message queue - note, can affect dispatch status */
2400  _dbus_connection_flush_unlocked (connection);
2401 
2402  client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
2403 
2404  /* note that timeout_milliseconds is limited to a smallish value
2405  * in _dbus_pending_call_new() so overflows aren't possible
2406  * below
2407  */
2408  timeout = _dbus_pending_call_get_timeout_unlocked (pending);
2409  _dbus_get_monotonic_time (&start_tv_sec, &start_tv_usec);
2410  if (timeout)
2411  {
2412  timeout_milliseconds = dbus_timeout_get_interval (timeout);
2413 
2414  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec\n",
2415  timeout_milliseconds,
2416  client_serial,
2417  start_tv_sec, start_tv_usec);
2418  }
2419  else
2420  {
2421  timeout_milliseconds = -1;
2422 
2423  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block for reply serial %u\n", client_serial);
2424  }
2425 
2426  /* check to see if we already got the data off the socket */
2427  /* from another blocked pending call */
2428  if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
2429  return;
2430 
2431  /* Now we wait... */
2432  /* always block at least once as we know we don't have the reply yet */
2434  pending,
2435  DBUS_ITERATION_DO_READING |
2436  DBUS_ITERATION_BLOCK,
2437  timeout_milliseconds);
2438 
2439  recheck_status:
2440 
2441  _dbus_verbose ("top of recheck\n");
2442 
2443  HAVE_LOCK_CHECK (connection);
2444 
2445  /* queue messages and get status */
2446 
2447  status = _dbus_connection_get_dispatch_status_unlocked (connection);
2448 
2449  /* the get_completed() is in case a dispatch() while we were blocking
2450  * got the reply instead of us.
2451  */
2453  {
2454  _dbus_verbose ("Pending call completed by dispatch\n");
2455  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2456  dbus_pending_call_unref (pending);
2457  return;
2458  }
2459 
2460  if (status == DBUS_DISPATCH_DATA_REMAINS)
2461  {
2462  if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
2463  return;
2464  }
2465 
2466  _dbus_get_monotonic_time (&tv_sec, &tv_usec);
2467  elapsed_milliseconds = (tv_sec - start_tv_sec) * 1000 +
2468  (tv_usec - start_tv_usec) / 1000;
2469 
2470  if (!_dbus_connection_get_is_connected_unlocked (connection))
2471  {
2472  DBusMessage *error_msg;
2473 
2474  error_msg = generate_local_error_message (client_serial,
2476  "Connection was disconnected before a reply was received");
2477 
2478  /* on OOM error_msg is set to NULL */
2479  complete_pending_call_and_unlock (connection, pending, error_msg);
2480  if (error_msg != NULL)
2481  dbus_message_unref (error_msg);
2482  dbus_pending_call_unref (pending);
2483  return;
2484  }
2485  else if (connection->disconnect_message_link == NULL)
2486  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
2487  else if (timeout == NULL)
2488  {
2489  if (status == DBUS_DISPATCH_NEED_MEMORY)
2490  {
2491  /* Try sleeping a bit, as we aren't sure we need to block for reading,
2492  * we may already have a reply in the buffer and just can't process
2493  * it.
2494  */
2495  _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
2496 
2497  _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
2498  }
2499  else
2500  {
2501  /* block again, we don't have the reply buffered yet. */
2503  pending,
2504  DBUS_ITERATION_DO_READING |
2505  DBUS_ITERATION_BLOCK,
2506  timeout_milliseconds - elapsed_milliseconds);
2507  }
2508 
2509  goto recheck_status;
2510  }
2511  else if (tv_sec < start_tv_sec)
2512  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
2513  else if (elapsed_milliseconds < timeout_milliseconds)
2514  {
2515  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds - elapsed_milliseconds);
2516 
2517  if (status == DBUS_DISPATCH_NEED_MEMORY)
2518  {
2519  /* Try sleeping a bit, as we aren't sure we need to block for reading,
2520  * we may already have a reply in the buffer and just can't process
2521  * it.
2522  */
2523  _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
2524 
2525  _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
2526  }
2527  else
2528  {
2529  /* block again, we don't have the reply buffered yet. */
2531  pending,
2532  DBUS_ITERATION_DO_READING |
2533  DBUS_ITERATION_BLOCK,
2534  timeout_milliseconds - elapsed_milliseconds);
2535  }
2536 
2537  goto recheck_status;
2538  }
2539 
2540  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %d milliseconds and got no reply\n",
2541  elapsed_milliseconds);
2542 
2544 
2545  /* unlock and call user code */
2546  complete_pending_call_and_unlock (connection, pending, NULL);
2547 
2548  /* update user code on dispatch status */
2549  CONNECTION_LOCK (connection);
2550  status = _dbus_connection_get_dispatch_status_unlocked (connection);
2551  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2552  dbus_pending_call_unref (pending);
2553 }
2554 
2560 int
2562 {
2563  return _dbus_transport_get_pending_fds_count (connection->transport);
2564 }
2565 
2573 void
2575  DBusPendingFdsChangeFunction callback,
2576  void *data)
2577 {
2579  callback, data);
2580 }
2581 
2619 dbus_connection_open (const char *address,
2620  DBusError *error)
2621 {
2622  DBusConnection *connection;
2623 
2624  _dbus_return_val_if_fail (address != NULL, NULL);
2625  _dbus_return_val_if_error_is_set (error, NULL);
2626 
2627  connection = _dbus_connection_open_internal (address,
2628  TRUE,
2629  error);
2630 
2631  return connection;
2632 }
2633 
2662 dbus_connection_open_private (const char *address,
2663  DBusError *error)
2664 {
2665  DBusConnection *connection;
2666 
2667  _dbus_return_val_if_fail (address != NULL, NULL);
2668  _dbus_return_val_if_error_is_set (error, NULL);
2669 
2670  connection = _dbus_connection_open_internal (address,
2671  FALSE,
2672  error);
2673 
2674  return connection;
2675 }
2676 
2685 {
2686  dbus_int32_t old_refcount;
2687 
2688  _dbus_return_val_if_fail (connection != NULL, NULL);
2689  _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
2690  old_refcount = _dbus_atomic_inc (&connection->refcount);
2691  _dbus_connection_trace_ref (connection, old_refcount, old_refcount + 1,
2692  "ref");
2693 
2694  return connection;
2695 }
2696 
2697 static void
2698 free_outgoing_message (void *element,
2699  void *data)
2700 {
2701  DBusMessage *message = element;
2702  DBusConnection *connection = data;
2703 
2704  _dbus_message_remove_counter (message, connection->outgoing_counter);
2705  dbus_message_unref (message);
2706 }
2707 
2708 /* This is run without the mutex held, but after the last reference
2709  * to the connection has been dropped we should have no thread-related
2710  * problems
2711  */
2712 static void
2713 _dbus_connection_last_unref (DBusConnection *connection)
2714 {
2715  DBusList *link;
2716 
2717  _dbus_verbose ("Finalizing connection %p\n", connection);
2718 
2719  _dbus_assert (_dbus_atomic_get (&connection->refcount) == 0);
2720 
2721  /* You have to disconnect the connection before unref:ing it. Otherwise
2722  * you won't get the disconnected message.
2723  */
2725  _dbus_assert (connection->server_guid == NULL);
2726 
2727  /* ---- We're going to call various application callbacks here, hope it doesn't break anything... */
2729 
2734 
2735  _dbus_watch_list_free (connection->watches);
2736  connection->watches = NULL;
2737 
2738  _dbus_timeout_list_free (connection->timeouts);
2739  connection->timeouts = NULL;
2740 
2741  _dbus_data_slot_list_free (&connection->slot_list);
2742 
2743  link = _dbus_list_get_first_link (&connection->filter_list);
2744  while (link != NULL)
2745  {
2746  DBusMessageFilter *filter = link->data;
2747  DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
2748 
2749  filter->function = NULL;
2750  _dbus_message_filter_unref (filter); /* calls app callback */
2751  link->data = NULL;
2752 
2753  link = next;
2754  }
2755  _dbus_list_clear (&connection->filter_list);
2756 
2757  /* ---- Done with stuff that invokes application callbacks */
2758 
2759  _dbus_object_tree_unref (connection->objects);
2760 
2762  connection->pending_replies = NULL;
2763 
2764  _dbus_list_foreach (&connection->outgoing_messages,
2765  free_outgoing_message,
2766  connection);
2767  _dbus_list_clear (&connection->outgoing_messages);
2768 
2771 
2772  _dbus_counter_unref (connection->outgoing_counter);
2773 
2774  _dbus_transport_unref (connection->transport);
2775 
2776  if (connection->disconnect_message_link)
2777  {
2778  DBusMessage *message = connection->disconnect_message_link->data;
2779  dbus_message_unref (message);
2781  }
2782 
2785 
2788 
2790 
2791  _dbus_rmutex_free_at_location (&connection->mutex);
2792 
2793  dbus_free (connection);
2794 }
2795 
2815 void
2817 {
2818  dbus_int32_t old_refcount;
2819 
2820  _dbus_return_if_fail (connection != NULL);
2821  _dbus_return_if_fail (connection->generation == _dbus_current_generation);
2822 
2823  old_refcount = _dbus_atomic_dec (&connection->refcount);
2824 
2825  _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1,
2826  "unref");
2827 
2828  if (old_refcount == 1)
2829  {
2830 #ifndef DBUS_DISABLE_CHECKS
2831  if (_dbus_transport_get_is_connected (connection->transport))
2832  {
2833  _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",
2834  connection->shareable ?
2835  "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection." :
2836  "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.");
2837  return;
2838  }
2839 #endif
2840  _dbus_connection_last_unref (connection);
2841  }
2842 }
2843 
2844 /*
2845  * Note that the transport can disconnect itself (other end drops us)
2846  * and in that case this function never runs. So this function must
2847  * not do anything more than disconnect the transport and update the
2848  * dispatch status.
2849  *
2850  * If the transport self-disconnects, then we assume someone will
2851  * dispatch the connection to cause the dispatch status update.
2852  */
2853 static void
2854 _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection)
2855 {
2856  DBusDispatchStatus status;
2857 
2858  HAVE_LOCK_CHECK (connection);
2859 
2860  _dbus_verbose ("Disconnecting %p\n", connection);
2861 
2862  /* We need to ref because update_dispatch_status_and_unlock will unref
2863  * the connection if it was shared and libdbus was the only remaining
2864  * refcount holder.
2865  */
2866  _dbus_connection_ref_unlocked (connection);
2867 
2868  _dbus_transport_disconnect (connection->transport);
2869 
2870  /* This has the side effect of queuing the disconnect message link
2871  * (unless we don't have enough memory, possibly, so don't assert it).
2872  * After the disconnect message link is queued, dbus_bus_get/dbus_connection_open
2873  * should never again return the newly-disconnected connection.
2874  *
2875  * However, we only unref the shared connection and exit_on_disconnect when
2876  * the disconnect message reaches the head of the message queue,
2877  * NOT when it's first queued.
2878  */
2879  status = _dbus_connection_get_dispatch_status_unlocked (connection);
2880 
2881  /* This calls out to user code */
2882  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2883 
2884  /* Could also call out to user code */
2885  dbus_connection_unref (connection);
2886 }
2887 
2930 void
2932 {
2933  _dbus_return_if_fail (connection != NULL);
2934  _dbus_return_if_fail (connection->generation == _dbus_current_generation);
2935 
2936  CONNECTION_LOCK (connection);
2937 
2938 #ifndef DBUS_DISABLE_CHECKS
2939  if (connection->shareable)
2940  {
2941  CONNECTION_UNLOCK (connection);
2942 
2943  _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.");
2944  return;
2945  }
2946 #endif
2947 
2948  _dbus_connection_close_possibly_shared_and_unlock (connection);
2949 }
2950 
2951 static dbus_bool_t
2952 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
2953 {
2954  HAVE_LOCK_CHECK (connection);
2955  return _dbus_transport_get_is_connected (connection->transport);
2956 }
2957 
2973 {
2974  dbus_bool_t res;
2975 
2976  _dbus_return_val_if_fail (connection != NULL, FALSE);
2977 
2978  CONNECTION_LOCK (connection);
2979  res = _dbus_connection_get_is_connected_unlocked (connection);
2980  CONNECTION_UNLOCK (connection);
2981 
2982  return res;
2983 }
2984 
2995 {
2996  dbus_bool_t res;
2997 
2998  _dbus_return_val_if_fail (connection != NULL, FALSE);
2999 
3000  CONNECTION_LOCK (connection);
3001  res = _dbus_transport_try_to_authenticate (connection->transport);
3002  CONNECTION_UNLOCK (connection);
3003 
3004  return res;
3005 }
3006 
3029 {
3030  dbus_bool_t res;
3031 
3032  _dbus_return_val_if_fail (connection != NULL, FALSE);
3033 
3034  CONNECTION_LOCK (connection);
3035  res = _dbus_transport_get_is_anonymous (connection->transport);
3036  CONNECTION_UNLOCK (connection);
3037 
3038  return res;
3039 }
3040 
3072 char*
3074 {
3075  char *id;
3076 
3077  _dbus_return_val_if_fail (connection != NULL, NULL);
3078 
3079  CONNECTION_LOCK (connection);
3081  CONNECTION_UNLOCK (connection);
3082 
3083  return id;
3084 }
3085 
3105  int type)
3106 {
3107  _dbus_return_val_if_fail (connection != NULL, FALSE);
3108 
3109  if (!dbus_type_is_valid (type))
3110  return FALSE;
3111 
3112  if (type != DBUS_TYPE_UNIX_FD)
3113  return TRUE;
3114 
3115 #ifdef HAVE_UNIX_FD_PASSING
3116  {
3117  dbus_bool_t b;
3118 
3119  CONNECTION_LOCK(connection);
3121  CONNECTION_UNLOCK(connection);
3122 
3123  return b;
3124  }
3125 #endif
3126 
3127  return FALSE;
3128 }
3129 
3143 void
3145  dbus_bool_t exit_on_disconnect)
3146 {
3147  _dbus_return_if_fail (connection != NULL);
3148 
3149  CONNECTION_LOCK (connection);
3150  connection->exit_on_disconnect = exit_on_disconnect != FALSE;
3151  CONNECTION_UNLOCK (connection);
3152 }
3153 
3165 {
3166  DBusPreallocatedSend *preallocated;
3167 
3168  _dbus_return_val_if_fail (connection != NULL, NULL);
3169 
3170  CONNECTION_LOCK (connection);
3171 
3172  preallocated =
3173  _dbus_connection_preallocate_send_unlocked (connection);
3174 
3175  CONNECTION_UNLOCK (connection);
3176 
3177  return preallocated;
3178 }
3179 
3189 void
3191  DBusPreallocatedSend *preallocated)
3192 {
3193  _dbus_return_if_fail (connection != NULL);
3194  _dbus_return_if_fail (preallocated != NULL);
3195  _dbus_return_if_fail (connection == preallocated->connection);
3196 
3197  _dbus_list_free_link (preallocated->queue_link);
3198  _dbus_counter_unref (preallocated->counter_link->data);
3199  _dbus_list_free_link (preallocated->counter_link);
3200  dbus_free (preallocated);
3201 }
3202 
3215 void
3217  DBusPreallocatedSend *preallocated,
3218  DBusMessage *message,
3219  dbus_uint32_t *client_serial)
3220 {
3221  _dbus_return_if_fail (connection != NULL);
3222  _dbus_return_if_fail (preallocated != NULL);
3223  _dbus_return_if_fail (message != NULL);
3224  _dbus_return_if_fail (preallocated->connection == connection);
3225  _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
3226  dbus_message_get_member (message) != NULL);
3227  _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
3228  (dbus_message_get_interface (message) != NULL &&
3229  dbus_message_get_member (message) != NULL));
3230 
3231  CONNECTION_LOCK (connection);
3232 
3233 #ifdef HAVE_UNIX_FD_PASSING
3234 
3235  if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
3236  message->n_unix_fds > 0)
3237  {
3238  /* Refuse to send fds on a connection that cannot handle
3239  them. Unfortunately we cannot return a proper error here, so
3240  the best we can is just return. */
3241  CONNECTION_UNLOCK (connection);
3242  return;
3243  }
3244 
3245 #endif
3246 
3247  _dbus_connection_send_preallocated_and_unlock (connection,
3248  preallocated,
3249  message, client_serial);
3250 }
3251 
3252 static dbus_bool_t
3253 _dbus_connection_send_unlocked_no_update (DBusConnection *connection,
3254  DBusMessage *message,
3255  dbus_uint32_t *client_serial)
3256 {
3257  DBusPreallocatedSend *preallocated;
3258 
3259  _dbus_assert (connection != NULL);
3260  _dbus_assert (message != NULL);
3261 
3262  preallocated = _dbus_connection_preallocate_send_unlocked (connection);
3263  if (preallocated == NULL)
3264  return FALSE;
3265 
3266  _dbus_connection_send_preallocated_unlocked_no_update (connection,
3267  preallocated,
3268  message,
3269  client_serial);
3270  return TRUE;
3271 }
3272 
3302  DBusMessage *message,
3303  dbus_uint32_t *serial)
3304 {
3305  _dbus_return_val_if_fail (connection != NULL, FALSE);
3306  _dbus_return_val_if_fail (message != NULL, FALSE);
3307 
3308  CONNECTION_LOCK (connection);
3309 
3310 #ifdef HAVE_UNIX_FD_PASSING
3311 
3312  if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
3313  message->n_unix_fds > 0)
3314  {
3315  /* Refuse to send fds on a connection that cannot handle
3316  them. Unfortunately we cannot return a proper error here, so
3317  the best we can is just return. */
3318  CONNECTION_UNLOCK (connection);
3319  return FALSE;
3320  }
3321 
3322 #endif
3323 
3324  return _dbus_connection_send_and_unlock (connection,
3325  message,
3326  serial);
3327 }
3328 
3329 static dbus_bool_t
3330 reply_handler_timeout (void *data)
3331 {
3332  DBusConnection *connection;
3333  DBusDispatchStatus status;
3334  DBusPendingCall *pending = data;
3335 
3336  connection = _dbus_pending_call_get_connection_and_lock (pending);
3337  _dbus_connection_ref_unlocked (connection);
3338 
3340  connection);
3344 
3345  _dbus_verbose ("middle\n");
3346  status = _dbus_connection_get_dispatch_status_unlocked (connection);
3347 
3348  /* Unlocks, and calls out to user code */
3349  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3350  dbus_connection_unref (connection);
3351 
3352  return TRUE;
3353 }
3354 
3399  DBusMessage *message,
3400  DBusPendingCall **pending_return,
3401  int timeout_milliseconds)
3402 {
3403  DBusPendingCall *pending;
3404  dbus_int32_t serial = -1;
3405  DBusDispatchStatus status;
3406 
3407  _dbus_return_val_if_fail (connection != NULL, FALSE);
3408  _dbus_return_val_if_fail (message != NULL, FALSE);
3409  _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
3410 
3411  if (pending_return)
3412  *pending_return = NULL;
3413 
3414  CONNECTION_LOCK (connection);
3415 
3416 #ifdef HAVE_UNIX_FD_PASSING
3417 
3418  if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
3419  message->n_unix_fds > 0)
3420  {
3421  /* Refuse to send fds on a connection that cannot handle
3422  them. Unfortunately we cannot return a proper error here, so
3423  the best we can do is return TRUE but leave *pending_return
3424  as NULL. */
3425  CONNECTION_UNLOCK (connection);
3426  return TRUE;
3427  }
3428 
3429 #endif
3430 
3431  if (!_dbus_connection_get_is_connected_unlocked (connection))
3432  {
3433  CONNECTION_UNLOCK (connection);
3434 
3435  return TRUE;
3436  }
3437 
3438  pending = _dbus_pending_call_new_unlocked (connection,
3439  timeout_milliseconds,
3440  reply_handler_timeout);
3441 
3442  if (pending == NULL)
3443  {
3444  CONNECTION_UNLOCK (connection);
3445  return FALSE;
3446  }
3447 
3448  /* Assign a serial to the message */
3449  serial = dbus_message_get_serial (message);
3450  if (serial == 0)
3451  {
3452  serial = _dbus_connection_get_next_client_serial (connection);
3453  dbus_message_set_serial (message, serial);
3454  }
3455 
3456  if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
3457  goto error;
3458 
3459  /* Insert the serial in the pending replies hash;
3460  * hash takes a refcount on DBusPendingCall.
3461  * Also, add the timeout.
3462  */
3463  if (!_dbus_connection_attach_pending_call_unlocked (connection,
3464  pending))
3465  goto error;
3466 
3467  if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
3468  {
3469  _dbus_connection_detach_pending_call_and_unlock (connection,
3470  pending);
3471  goto error_unlocked;
3472  }
3473 
3474  if (pending_return)
3475  *pending_return = pending; /* hand off refcount */
3476  else
3477  {
3478  _dbus_connection_detach_pending_call_unlocked (connection, pending);
3479  /* we still have a ref to the pending call in this case, we unref
3480  * after unlocking, below
3481  */
3482  }
3483 
3484  status = _dbus_connection_get_dispatch_status_unlocked (connection);
3485 
3486  /* this calls out to user code */
3487  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3488 
3489  if (pending_return == NULL)
3490  dbus_pending_call_unref (pending);
3491 
3492  return TRUE;
3493 
3494  error:
3495  CONNECTION_UNLOCK (connection);
3496  error_unlocked:
3497  dbus_pending_call_unref (pending);
3498  return FALSE;
3499 }
3500 
3533 DBusMessage*
3535  DBusMessage *message,
3536  int timeout_milliseconds,
3537  DBusError *error)
3538 {
3539  DBusMessage *reply;
3540  DBusPendingCall *pending;
3541 
3542  _dbus_return_val_if_fail (connection != NULL, NULL);
3543  _dbus_return_val_if_fail (message != NULL, NULL);
3544  _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL);
3545  _dbus_return_val_if_error_is_set (error, NULL);
3546 
3547 #ifdef HAVE_UNIX_FD_PASSING
3548 
3549  CONNECTION_LOCK (connection);
3550  if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
3551  message->n_unix_fds > 0)
3552  {
3553  CONNECTION_UNLOCK (connection);
3554  dbus_set_error(error, DBUS_ERROR_FAILED, "Cannot send file descriptors on this connection.");
3555  return NULL;
3556  }
3557  CONNECTION_UNLOCK (connection);
3558 
3559 #endif
3560 
3561  if (!dbus_connection_send_with_reply (connection, message,
3562  &pending, timeout_milliseconds))
3563  {
3564  _DBUS_SET_OOM (error);
3565  return NULL;
3566  }
3567 
3568  if (pending == NULL)
3569  {
3570  dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Connection is closed");
3571  return NULL;
3572  }
3573 
3574  dbus_pending_call_block (pending);
3575 
3576  reply = dbus_pending_call_steal_reply (pending);
3577  dbus_pending_call_unref (pending);
3578 
3579  /* call_complete_and_unlock() called from pending_call_block() should
3580  * always fill this in.
3581  */
3582  _dbus_assert (reply != NULL);
3583 
3584  if (dbus_set_error_from_message (error, reply))
3585  {
3586  dbus_message_unref (reply);
3587  return NULL;
3588  }
3589  else
3590  return reply;
3591 }
3592 
3601 static DBusDispatchStatus
3602 _dbus_connection_flush_unlocked (DBusConnection *connection)
3603 {
3604  /* We have to specify DBUS_ITERATION_DO_READING here because
3605  * otherwise we could have two apps deadlock if they are both doing
3606  * a flush(), and the kernel buffers fill up. This could change the
3607  * dispatch status.
3608  */
3609  DBusDispatchStatus status;
3610 
3611  HAVE_LOCK_CHECK (connection);
3612 
3613  while (connection->n_outgoing > 0 &&
3614  _dbus_connection_get_is_connected_unlocked (connection))
3615  {
3616  _dbus_verbose ("doing iteration in\n");
3617  HAVE_LOCK_CHECK (connection);
3619  NULL,
3620  DBUS_ITERATION_DO_READING |
3621  DBUS_ITERATION_DO_WRITING |
3622  DBUS_ITERATION_BLOCK,
3623  -1);
3624  }
3625 
3626  HAVE_LOCK_CHECK (connection);
3627  _dbus_verbose ("middle\n");
3628  status = _dbus_connection_get_dispatch_status_unlocked (connection);
3629 
3630  HAVE_LOCK_CHECK (connection);
3631  return status;
3632 }
3633 
3639 void
3641 {
3642  /* We have to specify DBUS_ITERATION_DO_READING here because
3643  * otherwise we could have two apps deadlock if they are both doing
3644  * a flush(), and the kernel buffers fill up. This could change the
3645  * dispatch status.
3646  */
3647  DBusDispatchStatus status;
3648 
3649  _dbus_return_if_fail (connection != NULL);
3650 
3651  CONNECTION_LOCK (connection);
3652 
3653  status = _dbus_connection_flush_unlocked (connection);
3654 
3655  HAVE_LOCK_CHECK (connection);
3656  /* Unlocks and calls out to user code */
3657  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3658 
3659  _dbus_verbose ("end\n");
3660 }
3661 
3672 static dbus_bool_t
3673 _dbus_connection_read_write_dispatch (DBusConnection *connection,
3674  int timeout_milliseconds,
3675  dbus_bool_t dispatch)
3676 {
3677  DBusDispatchStatus dstatus;
3678  dbus_bool_t progress_possible;
3679 
3680  /* Need to grab a ref here in case we're a private connection and
3681  * the user drops the last ref in a handler we call; see bug
3682  * https://bugs.freedesktop.org/show_bug.cgi?id=15635
3683  */
3684  dbus_connection_ref (connection);
3685  dstatus = dbus_connection_get_dispatch_status (connection);
3686 
3687  if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
3688  {
3689  _dbus_verbose ("doing dispatch\n");
3690  dbus_connection_dispatch (connection);
3691  CONNECTION_LOCK (connection);
3692  }
3693  else if (dstatus == DBUS_DISPATCH_NEED_MEMORY)
3694  {
3695  _dbus_verbose ("pausing for memory\n");
3696  _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
3697  CONNECTION_LOCK (connection);
3698  }
3699  else
3700  {
3701  CONNECTION_LOCK (connection);
3702  if (_dbus_connection_get_is_connected_unlocked (connection))
3703  {
3704  _dbus_verbose ("doing iteration\n");
3706  NULL,
3707  DBUS_ITERATION_DO_READING |
3708  DBUS_ITERATION_DO_WRITING |
3709  DBUS_ITERATION_BLOCK,
3710  timeout_milliseconds);
3711  }
3712  }
3713 
3714  HAVE_LOCK_CHECK (connection);
3715  /* If we can dispatch, we can make progress until the Disconnected message
3716  * has been processed; if we can only read/write, we can make progress
3717  * as long as the transport is open.
3718  */
3719  if (dispatch)
3720  progress_possible = connection->n_incoming != 0 ||
3721  connection->disconnect_message_link != NULL;
3722  else
3723  progress_possible = _dbus_connection_get_is_connected_unlocked (connection);
3724 
3725  CONNECTION_UNLOCK (connection);
3726 
3727  dbus_connection_unref (connection);
3728 
3729  return progress_possible; /* TRUE if we can make more progress */
3730 }
3731 
3732 
3769  int timeout_milliseconds)
3770 {
3771  _dbus_return_val_if_fail (connection != NULL, FALSE);
3772  _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
3773  return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE);
3774 }
3775 
3799 dbus_bool_t
3801  int timeout_milliseconds)
3802 {
3803  _dbus_return_val_if_fail (connection != NULL, FALSE);
3804  _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
3805  return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE);
3806 }
3807 
3808 /* We need to call this anytime we pop the head of the queue, and then
3809  * update_dispatch_status_and_unlock needs to be called afterward
3810  * which will "process" the disconnected message and set
3811  * disconnected_message_processed.
3812  */
3813 static void
3814 check_disconnected_message_arrived_unlocked (DBusConnection *connection,
3815  DBusMessage *head_of_queue)
3816 {
3817  HAVE_LOCK_CHECK (connection);
3818 
3819  /* checking that the link is NULL is an optimization to avoid the is_signal call */
3820  if (connection->disconnect_message_link == NULL &&
3821  dbus_message_is_signal (head_of_queue,
3823  "Disconnected"))
3824  {
3825  connection->disconnected_message_arrived = TRUE;
3826  }
3827 }
3828 
3848 DBusMessage*
3850 {
3851  DBusDispatchStatus status;
3852  DBusMessage *message;
3853 
3854  _dbus_return_val_if_fail (connection != NULL, NULL);
3855 
3856  _dbus_verbose ("start\n");
3857 
3858  /* this is called for the side effect that it queues
3859  * up any messages from the transport
3860  */
3861  status = dbus_connection_get_dispatch_status (connection);
3862  if (status != DBUS_DISPATCH_DATA_REMAINS)
3863  return NULL;
3864 
3865  CONNECTION_LOCK (connection);
3866 
3867  _dbus_connection_acquire_dispatch (connection);
3868 
3869  /* While a message is outstanding, the dispatch lock is held */
3870  _dbus_assert (connection->message_borrowed == NULL);
3871 
3872  connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
3873 
3874  message = connection->message_borrowed;
3875 
3876  check_disconnected_message_arrived_unlocked (connection, message);
3877 
3878  /* Note that we KEEP the dispatch lock until the message is returned */
3879  if (message == NULL)
3880  _dbus_connection_release_dispatch (connection);
3881 
3882  CONNECTION_UNLOCK (connection);
3883 
3884  _dbus_message_trace_ref (message, -1, -1, "dbus_connection_borrow_message");
3885 
3886  /* We don't update dispatch status until it's returned or stolen */
3887 
3888  return message;
3889 }
3890 
3899 void
3901  DBusMessage *message)
3902 {
3903  DBusDispatchStatus status;
3904 
3905  _dbus_return_if_fail (connection != NULL);
3906  _dbus_return_if_fail (message != NULL);
3907  _dbus_return_if_fail (message == connection->message_borrowed);
3908  _dbus_return_if_fail (connection->dispatch_acquired);
3909 
3910  CONNECTION_LOCK (connection);
3911 
3912  _dbus_assert (message == connection->message_borrowed);
3913 
3914  connection->message_borrowed = NULL;
3915 
3916  _dbus_connection_release_dispatch (connection);
3917 
3918  status = _dbus_connection_get_dispatch_status_unlocked (connection);
3919  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3920 
3921  _dbus_message_trace_ref (message, -1, -1, "dbus_connection_return_message");
3922 }
3923 
3933 void
3935  DBusMessage *message)
3936 {
3937  DBusMessage *pop_message;
3938  DBusDispatchStatus status;
3939 
3940  _dbus_return_if_fail (connection != NULL);
3941  _dbus_return_if_fail (message != NULL);
3942  _dbus_return_if_fail (message == connection->message_borrowed);
3943  _dbus_return_if_fail (connection->dispatch_acquired);
3944 
3945  CONNECTION_LOCK (connection);
3946 
3947  _dbus_assert (message == connection->message_borrowed);
3948 
3949  pop_message = _dbus_list_pop_first (&connection->incoming_messages);
3950  _dbus_assert (message == pop_message);
3951  (void) pop_message; /* unused unless asserting */
3952 
3953  connection->n_incoming -= 1;
3954 
3955  _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
3956  message, connection->n_incoming);
3957 
3958  connection->message_borrowed = NULL;
3959 
3960  _dbus_connection_release_dispatch (connection);
3961 
3962  status = _dbus_connection_get_dispatch_status_unlocked (connection);
3963  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3964  _dbus_message_trace_ref (message, -1, -1,
3965  "dbus_connection_steal_borrowed_message");
3966 }
3967 
3968 /* See dbus_connection_pop_message, but requires the caller to own
3969  * the lock before calling. May drop the lock while running.
3970  */
3971 static DBusList*
3972 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
3973 {
3974  HAVE_LOCK_CHECK (connection);
3975 
3976  _dbus_assert (connection->message_borrowed == NULL);
3977 
3978  if (connection->n_incoming > 0)
3979  {
3980  DBusList *link;
3981 
3982  link = _dbus_list_pop_first_link (&connection->incoming_messages);
3983  connection->n_incoming -= 1;
3984 
3985  _dbus_verbose ("Message %p (%s %s %s %s sig:'%s' serial:%u) removed from incoming queue %p, %d incoming\n",
3986  link->data,
3988  dbus_message_get_path (link->data) ?
3989  dbus_message_get_path (link->data) :
3990  "no path",
3993  "no interface",
3994  dbus_message_get_member (link->data) ?
3995  dbus_message_get_member (link->data) :
3996  "no member",
3998  dbus_message_get_serial (link->data),
3999  connection, connection->n_incoming);
4000 
4001  _dbus_message_trace_ref (link->data, -1, -1,
4002  "_dbus_connection_pop_message_link_unlocked");
4003 
4004  check_disconnected_message_arrived_unlocked (connection, link->data);
4005 
4006  return link;
4007  }
4008  else
4009  return NULL;
4010 }
4011 
4012 /* See dbus_connection_pop_message, but requires the caller to own
4013  * the lock before calling. May drop the lock while running.
4014  */
4015 static DBusMessage*
4016 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
4017 {
4018  DBusList *link;
4019 
4020  HAVE_LOCK_CHECK (connection);
4021 
4022  link = _dbus_connection_pop_message_link_unlocked (connection);
4023 
4024  if (link != NULL)
4025  {
4026  DBusMessage *message;
4027 
4028  message = link->data;
4029 
4030  _dbus_list_free_link (link);
4031 
4032  return message;
4033  }
4034  else
4035  return NULL;
4036 }
4037 
4038 static void
4039 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
4040  DBusList *message_link)
4041 {
4042  HAVE_LOCK_CHECK (connection);
4043 
4044  _dbus_assert (message_link != NULL);
4045  /* You can't borrow a message while a link is outstanding */
4046  _dbus_assert (connection->message_borrowed == NULL);
4047  /* We had to have the dispatch lock across the pop/putback */
4048  _dbus_assert (connection->dispatch_acquired);
4049 
4051  message_link);
4052  connection->n_incoming += 1;
4053 
4054  _dbus_verbose ("Message %p (%s %s %s '%s') put back into queue %p, %d incoming\n",
4055  message_link->data,
4057  dbus_message_get_interface (message_link->data) ?
4058  dbus_message_get_interface (message_link->data) :
4059  "no interface",
4060  dbus_message_get_member (message_link->data) ?
4061  dbus_message_get_member (message_link->data) :
4062  "no member",
4063  dbus_message_get_signature (message_link->data),
4064  connection, connection->n_incoming);
4065 
4066  _dbus_message_trace_ref (message_link->data, -1, -1,
4067  "_dbus_connection_putback_message_link_unlocked");
4068 }
4069 
4089 DBusMessage*
4091 {
4092  DBusMessage *message;
4093  DBusDispatchStatus status;
4094 
4095  _dbus_verbose ("start\n");
4096 
4097  /* this is called for the side effect that it queues
4098  * up any messages from the transport
4099  */
4100  status = dbus_connection_get_dispatch_status (connection);
4101  if (status != DBUS_DISPATCH_DATA_REMAINS)
4102  return NULL;
4103 
4104  CONNECTION_LOCK (connection);
4105  _dbus_connection_acquire_dispatch (connection);
4106  HAVE_LOCK_CHECK (connection);
4107 
4108  message = _dbus_connection_pop_message_unlocked (connection);
4109 
4110  _dbus_verbose ("Returning popped message %p\n", message);
4111 
4112  _dbus_connection_release_dispatch (connection);
4113 
4114  status = _dbus_connection_get_dispatch_status_unlocked (connection);
4115  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
4116 
4117  return message;
4118 }
4119 
4127 static void
4128 _dbus_connection_acquire_dispatch (DBusConnection *connection)
4129 {
4130  HAVE_LOCK_CHECK (connection);
4131 
4132  _dbus_connection_ref_unlocked (connection);
4133  CONNECTION_UNLOCK (connection);
4134 
4135  _dbus_verbose ("locking dispatch_mutex\n");
4136  _dbus_cmutex_lock (connection->dispatch_mutex);
4137 
4138  while (connection->dispatch_acquired)
4139  {
4140  _dbus_verbose ("waiting for dispatch to be acquirable\n");
4141  _dbus_condvar_wait (connection->dispatch_cond,
4142  connection->dispatch_mutex);
4143  }
4144 
4145  _dbus_assert (!connection->dispatch_acquired);
4146 
4147  connection->dispatch_acquired = TRUE;
4148 
4149  _dbus_verbose ("unlocking dispatch_mutex\n");
4150  _dbus_cmutex_unlock (connection->dispatch_mutex);
4151 
4152  CONNECTION_LOCK (connection);
4153  _dbus_connection_unref_unlocked (connection);
4154 }
4155 
4163 static void
4164 _dbus_connection_release_dispatch (DBusConnection *connection)
4165 {
4166  HAVE_LOCK_CHECK (connection);
4167 
4168  _dbus_verbose ("locking dispatch_mutex\n");
4169  _dbus_cmutex_lock (connection->dispatch_mutex);
4170 
4171  _dbus_assert (connection->dispatch_acquired);
4172 
4173  connection->dispatch_acquired = FALSE;
4174  _dbus_condvar_wake_one (connection->dispatch_cond);
4175 
4176  _dbus_verbose ("unlocking dispatch_mutex\n");
4177  _dbus_cmutex_unlock (connection->dispatch_mutex);
4178 }
4179 
4180 static void
4181 _dbus_connection_failed_pop (DBusConnection *connection,
4182  DBusList *message_link)
4183 {
4185  message_link);
4186  connection->n_incoming += 1;
4187 }
4188 
4189 /* Note this may be called multiple times since we don't track whether we already did it */
4190 static void
4191 notify_disconnected_unlocked (DBusConnection *connection)
4192 {
4193  HAVE_LOCK_CHECK (connection);
4194 
4195  /* Set the weakref in dbus-bus.c to NULL, so nobody will get a disconnected
4196  * connection from dbus_bus_get(). We make the same guarantee for
4197  * dbus_connection_open() but in a different way since we don't want to
4198  * unref right here; we instead check for connectedness before returning
4199  * the connection from the hash.
4200  */
4202 
4203  /* Dump the outgoing queue, we aren't going to be able to
4204  * send it now, and we'd like accessors like
4205  * dbus_connection_get_outgoing_size() to be accurate.
4206  */
4207  if (connection->n_outgoing > 0)
4208  {
4209  DBusList *link;
4210 
4211  _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
4212  connection->n_outgoing);
4213 
4214  while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
4215  {
4216  _dbus_connection_message_sent_unlocked (connection, link->data);
4217  }
4218  }
4219 }
4220 
4221 /* Note this may be called multiple times since we don't track whether we already did it */
4222 static DBusDispatchStatus
4223 notify_disconnected_and_dispatch_complete_unlocked (DBusConnection *connection)
4224 {
4225  HAVE_LOCK_CHECK (connection);
4226 
4227  if (connection->disconnect_message_link != NULL)
4228  {
4229  _dbus_verbose ("Sending disconnect message\n");
4230 
4231  /* If we have pending calls, queue their timeouts - we want the Disconnected
4232  * to be the last message, after these timeouts.
4233  */
4234  connection_timeout_and_complete_all_pending_calls_unlocked (connection);
4235 
4236  /* We haven't sent the disconnect message already,
4237  * and all real messages have been queued up.
4238  */
4240  connection->disconnect_message_link);
4241  connection->disconnect_message_link = NULL;
4242 
4244  }
4245 
4246  return DBUS_DISPATCH_COMPLETE;
4247 }
4248 
4249 static DBusDispatchStatus
4250 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
4251 {
4252  HAVE_LOCK_CHECK (connection);
4253 
4254  if (connection->n_incoming > 0)
4256  else if (!_dbus_transport_queue_messages (connection->transport))
4258  else
4259  {
4260  DBusDispatchStatus status;
4261  dbus_bool_t is_connected;
4262 
4263  status = _dbus_transport_get_dispatch_status (connection->transport);
4264  is_connected = _dbus_transport_get_is_connected (connection->transport);
4265 
4266  _dbus_verbose ("dispatch status = %s is_connected = %d\n",
4267  DISPATCH_STATUS_NAME (status), is_connected);
4268 
4269  if (!is_connected)
4270  {
4271  /* It's possible this would be better done by having an explicit
4272  * notification from _dbus_transport_disconnect() that would
4273  * synchronously do this, instead of waiting for the next dispatch
4274  * status check. However, probably not good to change until it causes
4275  * a problem.
4276  */
4277  notify_disconnected_unlocked (connection);
4278 
4279  /* I'm not sure this is needed; the idea is that we want to
4280  * queue the Disconnected only after we've read all the
4281  * messages, but if we're disconnected maybe we are guaranteed
4282  * to have read them all ?
4283  */
4284  if (status == DBUS_DISPATCH_COMPLETE)
4285  status = notify_disconnected_and_dispatch_complete_unlocked (connection);
4286  }
4287 
4288  if (status != DBUS_DISPATCH_COMPLETE)
4289  return status;
4290  else if (connection->n_incoming > 0)
4292  else
4293  return DBUS_DISPATCH_COMPLETE;
4294  }
4295 }
4296 
4297 static void
4298 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
4299  DBusDispatchStatus new_status)
4300 {
4301  dbus_bool_t changed;
4302  DBusDispatchStatusFunction function;
4303  void *data;
4304 
4305  HAVE_LOCK_CHECK (connection);
4306 
4307  _dbus_connection_ref_unlocked (connection);
4308 
4309  changed = new_status != connection->last_dispatch_status;
4310 
4311  connection->last_dispatch_status = new_status;
4312 
4313  function = connection->dispatch_status_function;
4314  data = connection->dispatch_status_data;
4315 
4316  if (connection->disconnected_message_arrived &&
4317  !connection->disconnected_message_processed)
4318  {
4319  connection->disconnected_message_processed = TRUE;
4320 
4321  /* this does an unref, but we have a ref
4322  * so we should not run the finalizer here
4323  * inside the lock.
4324  */
4325  connection_forget_shared_unlocked (connection);
4326 
4327  if (connection->exit_on_disconnect)
4328  {
4329  CONNECTION_UNLOCK (connection);
4330 
4331  _dbus_verbose ("Exiting on Disconnected signal\n");
4332  _dbus_exit (1);
4333  _dbus_assert_not_reached ("Call to exit() returned");
4334  }
4335  }
4336 
4337  /* We drop the lock */
4338  CONNECTION_UNLOCK (connection);
4339 
4340  if (changed && function)
4341  {
4342  _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
4343  connection, new_status,
4344  DISPATCH_STATUS_NAME (new_status));
4345  (* function) (connection, new_status, data);
4346  }
4347 
4348  dbus_connection_unref (connection);
4349 }
4350 
4378 {
4379  DBusDispatchStatus status;
4380 
4381  _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
4382 
4383  _dbus_verbose ("start\n");
4384 
4385  CONNECTION_LOCK (connection);
4386 
4387  status = _dbus_connection_get_dispatch_status_unlocked (connection);
4388 
4389  CONNECTION_UNLOCK (connection);
4390 
4391  return status;
4392 }
4393 
4397 static DBusHandlerResult
4398 _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
4399  DBusMessage *message)
4400 {
4401  dbus_bool_t sent = FALSE;
4402  DBusMessage *ret = NULL;
4403  DBusList *expire_link;
4404 
4405  if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
4406  {
4407  /* This means we're letting the bus route this message */
4409  }
4410 
4412  {
4414  }
4415 
4416  /* Preallocate a linked-list link, so that if we need to dispose of a
4417  * message, we can attach it to the expired list */
4418  expire_link = _dbus_list_alloc_link (NULL);
4419 
4420  if (!expire_link)
4422 
4423  if (dbus_message_is_method_call (message,
4425  "Ping"))
4426  {
4427  ret = dbus_message_new_method_return (message);
4428  if (ret == NULL)
4429  goto out;
4430 
4431  sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
4432  }
4433  else if (dbus_message_is_method_call (message,
4435  "GetMachineId"))
4436  {
4437  DBusString uuid;
4438  DBusError error = DBUS_ERROR_INIT;
4439 
4440  if (!_dbus_string_init (&uuid))
4441  goto out;
4442 
4443  if (_dbus_get_local_machine_uuid_encoded (&uuid, &error))
4444  {
4445  const char *v_STRING;
4446 
4447  ret = dbus_message_new_method_return (message);
4448 
4449  if (ret == NULL)
4450  {
4451  _dbus_string_free (&uuid);
4452  goto out;
4453  }
4454 
4455  v_STRING = _dbus_string_get_const_data (&uuid);
4456  if (dbus_message_append_args (ret,
4457  DBUS_TYPE_STRING, &v_STRING,
4459  {
4460  sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
4461  }
4462  }
4463  else if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
4464  {
4465  dbus_error_free (&error);
4466  goto out;
4467  }
4468  else
4469  {
4470  ret = dbus_message_new_error (message, error.name, error.message);
4471  dbus_error_free (&error);
4472 
4473  if (ret == NULL)
4474  goto out;
4475 
4476  sent = _dbus_connection_send_unlocked_no_update (connection, ret,
4477  NULL);
4478  }
4479 
4480  _dbus_string_free (&uuid);
4481  }
4482  else
4483  {
4484  /* We need to bounce anything else with this interface, otherwise apps
4485  * could start extending the interface and when we added extensions
4486  * here to DBusConnection we'd break those apps.
4487  */
4488  ret = dbus_message_new_error (message,
4490  "Unknown method invoked on org.freedesktop.DBus.Peer interface");
4491  if (ret == NULL)
4492  goto out;
4493 
4494  sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
4495  }
4496 
4497 out:
4498  if (ret == NULL)
4499  {
4500  _dbus_list_free_link (expire_link);
4501  }
4502  else
4503  {
4504  /* It'll be safe to unref the reply when we unlock */
4505  expire_link->data = ret;
4506  _dbus_list_prepend_link (&connection->expired_messages, expire_link);
4507  }
4508 
4509  if (!sent)
4511 
4513 }
4514 
4521 static DBusHandlerResult
4522 _dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection,
4523  DBusMessage *message)
4524 {
4525  /* We just run one filter for now but have the option to run more
4526  if the spec calls for it in the future */
4527 
4528  return _dbus_connection_peer_filter_unlocked_no_update (connection, message);
4529 }
4530 
4575 {
4576  DBusMessage *message;
4577  DBusList *link, *filter_list_copy, *message_link;
4578  DBusHandlerResult result;
4579  DBusPendingCall *pending;
4580  dbus_int32_t reply_serial;
4581  DBusDispatchStatus status;
4582  dbus_bool_t found_object;
4583 
4584  _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
4585 
4586  _dbus_verbose ("\n");
4587 
4588  CONNECTION_LOCK (connection);
4589  status = _dbus_connection_get_dispatch_status_unlocked (connection);
4590  if (status != DBUS_DISPATCH_DATA_REMAINS)
4591  {
4592  /* unlocks and calls out to user code */
4593  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
4594  return status;
4595  }
4596 
4597  /* We need to ref the connection since the callback could potentially
4598  * drop the last ref to it
4599  */
4600  _dbus_connection_ref_unlocked (connection);
4601 
4602  _dbus_connection_acquire_dispatch (connection);
4603  HAVE_LOCK_CHECK (connection);
4604 
4605  message_link = _dbus_connection_pop_message_link_unlocked (connection);
4606  if (message_link == NULL)
4607  {
4608  /* another thread dispatched our stuff */
4609 
4610  _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
4611 
4612  _dbus_connection_release_dispatch (connection);
4613 
4614  status = _dbus_connection_get_dispatch_status_unlocked (connection);
4615 
4616  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
4617 
4618  dbus_connection_unref (connection);
4619 
4620  return status;
4621  }
4622 
4623  message = message_link->data;
4624 
4625  _dbus_verbose (" dispatching message %p (%s %s %s '%s')\n",
4626  message,
4628  dbus_message_get_interface (message) ?
4629  dbus_message_get_interface (message) :
4630  "no interface",
4631  dbus_message_get_member (message) ?
4632  dbus_message_get_member (message) :
4633  "no member",
4634  dbus_message_get_signature (message));
4635 
4637 
4638  /* Pending call handling must be first, because if you do
4639  * dbus_connection_send_with_reply_and_block() or
4640  * dbus_pending_call_block() then no handlers/filters will be run on
4641  * the reply. We want consistent semantics in the case where we
4642  * dbus_connection_dispatch() the reply.
4643  */
4644 
4645  reply_serial = dbus_message_get_reply_serial (message);
4646  pending = _dbus_hash_table_lookup_int (connection->pending_replies,
4647  reply_serial);
4648  if (pending)
4649  {
4650  _dbus_verbose ("Dispatching a pending reply\n");
4651  complete_pending_call_and_unlock (connection, pending, message);
4652  pending = NULL; /* it's probably unref'd */
4653 
4654  CONNECTION_LOCK (connection);
4655  _dbus_verbose ("pending call completed in dispatch\n");
4656  result = DBUS_HANDLER_RESULT_HANDLED;
4657  goto out;
4658  }
4659 
4660  result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message);
4662  goto out;
4663 
4664  if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
4665  {
4666  _dbus_connection_release_dispatch (connection);
4667  HAVE_LOCK_CHECK (connection);
4668 
4669  _dbus_connection_failed_pop (connection, message_link);
4670 
4671  /* unlocks and calls user code */
4672  _dbus_connection_update_dispatch_status_and_unlock (connection,
4674  dbus_connection_unref (connection);
4675 
4677  }
4678 
4679  for (link = _dbus_list_get_first_link (&filter_list_copy);
4680  link != NULL;
4681  link = _dbus_list_get_next_link (&filter_list_copy, link))
4682  _dbus_message_filter_ref (link->data);
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 
4706  break;
4707 
4708  link = next;
4709  }
4710 
4711  _dbus_list_clear_full (&filter_list_copy,
4712  (DBusFreeFunction) _dbus_message_filter_unref);
4713 
4714  CONNECTION_LOCK (connection);
4715 
4716  if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
4717  {
4718  _dbus_verbose ("No memory\n");
4719  goto out;
4720  }
4721  else if (result == DBUS_HANDLER_RESULT_HANDLED)
4722  {
4723  _dbus_verbose ("filter handled message in dispatch\n");
4724  goto out;
4725  }
4726 
4727  /* We're still protected from dispatch() reentrancy here
4728  * since we acquired the dispatcher
4729  */
4730  _dbus_verbose (" running object path dispatch on message %p (%s %s %s '%s')\n",
4731  message,
4733  dbus_message_get_interface (message) ?
4734  dbus_message_get_interface (message) :
4735  "no interface",
4736  dbus_message_get_member (message) ?
4737  dbus_message_get_member (message) :
4738  "no member",
4739  dbus_message_get_signature (message));
4740 
4741  HAVE_LOCK_CHECK (connection);
4742  result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
4743  message,
4744  &found_object);
4745 
4746  CONNECTION_LOCK (connection);
4747 
4749  {
4750  _dbus_verbose ("object tree handled message in dispatch\n");
4751  goto out;
4752  }
4753 
4755  {
4756  DBusMessage *reply;
4757  DBusString str;
4758  DBusPreallocatedSend *preallocated;
4759  DBusList *expire_link;
4760 
4761  _dbus_verbose (" sending error %s\n",
4763 
4764  if (!_dbus_string_init (&str))
4765  {
4767  _dbus_verbose ("no memory for error string in dispatch\n");
4768  goto out;
4769  }
4770 
4771  if (!_dbus_string_append_printf (&str,
4772  "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
4773  dbus_message_get_member (message),
4774  dbus_message_get_signature (message),
4775  dbus_message_get_interface (message)))
4776  {
4777  _dbus_string_free (&str);
4779  _dbus_verbose ("no memory for error string in dispatch\n");
4780  goto out;
4781  }
4782 
4783  reply = dbus_message_new_error (message,
4785  _dbus_string_get_const_data (&str));
4786  _dbus_string_free (&str);
4787 
4788  if (reply == NULL)
4789  {
4791  _dbus_verbose ("no memory for error reply in dispatch\n");
4792  goto out;
4793  }
4794 
4795  expire_link = _dbus_list_alloc_link (reply);
4796 
4797  if (expire_link == NULL)
4798  {
4799  dbus_message_unref (reply);
4801  _dbus_verbose ("no memory for error send in dispatch\n");
4802  goto out;
4803  }
4804 
4805  preallocated = _dbus_connection_preallocate_send_unlocked (connection);
4806 
4807  if (preallocated == NULL)
4808  {
4809  _dbus_list_free_link (expire_link);
4810  /* It's OK that this is finalized, because it hasn't been seen by
4811  * anything that could attach user callbacks */
4812  dbus_message_unref (reply);
4814  _dbus_verbose ("no memory for error send in dispatch\n");
4815  goto out;
4816  }
4817 
4818  _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
4819  reply, NULL);
4820  /* reply will be freed when we release the lock */
4821  _dbus_list_prepend_link (&connection->expired_messages, expire_link);
4822 
4823  result = DBUS_HANDLER_RESULT_HANDLED;
4824  }
4825 
4826  _dbus_verbose (" done dispatching %p (%s %s %s '%s') on connection %p\n", message,
4828  dbus_message_get_interface (message) ?
4829  dbus_message_get_interface (message) :
4830  "no interface",
4831  dbus_message_get_member (message) ?
4832  dbus_message_get_member (message) :
4833  "no member",
4834  dbus_message_get_signature (message),
4835  connection);
4836 
4837  out:
4838  if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
4839  {
4840  _dbus_verbose ("out of memory\n");
4841 
4842  /* Put message back, and we'll start over.
4843  * Yes this means handlers must be idempotent if they
4844  * don't return HANDLED; c'est la vie.
4845  */
4846  _dbus_connection_putback_message_link_unlocked (connection,
4847  message_link);
4848  /* now we don't want to free them */
4849  message_link = NULL;
4850  message = NULL;
4851  }
4852  else
4853  {
4854  _dbus_verbose (" ... done dispatching\n");
4855  }
4856 
4857  _dbus_connection_release_dispatch (connection);
4858  HAVE_LOCK_CHECK (connection);
4859 
4860  if (message != NULL)
4861  {
4862  /* We don't want this message to count in maximum message limits when
4863  * computing the dispatch status, below. We have to drop the lock
4864  * temporarily, because finalizing a message can trigger callbacks.
4865  *
4866  * We have a reference to the connection, and we don't use any cached
4867  * pointers to the connection's internals below this point, so it should
4868  * be safe to drop the lock and take it back. */
4869  CONNECTION_UNLOCK (connection);
4870  dbus_message_unref (message);
4871  CONNECTION_LOCK (connection);
4872  }
4873 
4874  if (message_link != NULL)
4875  _dbus_list_free_link (message_link);
4876 
4877  _dbus_verbose ("before final status update\n");
4878  status = _dbus_connection_get_dispatch_status_unlocked (connection);
4879 
4880  /* unlocks and calls user code */
4881  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
4882 
4883  dbus_connection_unref (connection);
4884 
4885  return status;
4886 }
4887 
4951  DBusAddWatchFunction add_function,
4952  DBusRemoveWatchFunction remove_function,
4953  DBusWatchToggledFunction toggled_function,
4954  void *data,
4955  DBusFreeFunction free_data_function)
4956 {
4957  dbus_bool_t retval;
4958 
4959  _dbus_return_val_if_fail (connection != NULL, FALSE);
4960 
4961  CONNECTION_LOCK (connection);
4962 
4963  retval = _dbus_watch_list_set_functions (connection->watches,
4964  add_function, remove_function,
4965  toggled_function,
4966  data, free_data_function);
4967 
4968  CONNECTION_UNLOCK (connection);
4969 
4970  return retval;
4971 }
4972 
5014  DBusAddTimeoutFunction add_function,
5015  DBusRemoveTimeoutFunction remove_function,
5016  DBusTimeoutToggledFunction toggled_function,
5017  void *data,
5018  DBusFreeFunction free_data_function)
5019 {
5020  dbus_bool_t retval;
5021 
5022  _dbus_return_val_if_fail (connection != NULL, FALSE);
5023 
5024  CONNECTION_LOCK (connection);
5025 
5026  retval = _dbus_timeout_list_set_functions (connection->timeouts,
5027  add_function, remove_function,
5028  toggled_function,
5029  data, free_data_function);
5030 
5031  CONNECTION_UNLOCK (connection);
5032 
5033  return retval;
5034 }
5035 
5050 void
5052  DBusWakeupMainFunction wakeup_main_function,
5053  void *data,
5054  DBusFreeFunction free_data_function)
5055 {
5056  void *old_data;
5057  DBusFreeFunction old_free_data;
5058 
5059  _dbus_return_if_fail (connection != NULL);
5060 
5061  CONNECTION_LOCK (connection);
5062  old_data = connection->wakeup_main_data;
5063  old_free_data = connection->free_wakeup_main_data;
5064 
5065  connection->wakeup_main_function = wakeup_main_function;
5066  connection->wakeup_main_data = data;
5067  connection->free_wakeup_main_data = free_data_function;
5068 
5069  CONNECTION_UNLOCK (connection);
5070 
5071  /* Callback outside the lock */
5072  if (old_free_data)
5073  (*old_free_data) (old_data);
5074 }
5075 
5096 void
5098  DBusDispatchStatusFunction function,
5099  void *data,
5100  DBusFreeFunction free_data_function)
5101 {
5102  void *old_data;
5103  DBusFreeFunction old_free_data;
5104 
5105  _dbus_return_if_fail (connection != NULL);
5106 
5107  CONNECTION_LOCK (connection);
5108  old_data = connection->dispatch_status_data;
5109  old_free_data = connection->free_dispatch_status_data;
5110 
5111  connection->dispatch_status_function = function;
5112  connection->dispatch_status_data = data;
5113  connection->free_dispatch_status_data = free_data_function;
5114 
5115  CONNECTION_UNLOCK (connection);
5116 
5117  /* Callback outside the lock */
5118  if (old_free_data)
5119  (*old_free_data) (old_data);
5120 }
5121 
5143  int *fd)
5144 {
5145  _dbus_return_val_if_fail (connection != NULL, FALSE);
5146  _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
5147 
5148 #ifdef DBUS_WIN
5149  /* FIXME do this on a lower level */
5150  return FALSE;
5151 #endif
5152 
5153  return dbus_connection_get_socket(connection, fd);
5154 }
5155 
5173  int *fd)
5174 {
5175  dbus_bool_t retval;
5176  DBusSocket s = DBUS_SOCKET_INIT;
5177 
5178  _dbus_return_val_if_fail (connection != NULL, FALSE);
5179  _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
5180 
5181  CONNECTION_LOCK (connection);
5182 
5183  retval = _dbus_transport_get_socket_fd (connection->transport, &s);
5184 
5185  if (retval)
5186  {
5187  *fd = _dbus_socket_get_int (s);
5188  }
5189 
5190  CONNECTION_UNLOCK (connection);
5191 
5192  return retval;
5193 }
5194 
5195 
5220  unsigned long *uid)
5221 {
5222  dbus_bool_t result;
5223 
5224  _dbus_return_val_if_fail (connection != NULL, FALSE);
5225  _dbus_return_val_if_fail (uid != NULL, FALSE);
5226 
5227  CONNECTION_LOCK (connection);
5228 
5230  result = FALSE;
5231  else
5232  result = _dbus_transport_get_unix_user (connection->transport,
5233  uid);
5234 
5235 #ifdef DBUS_WIN
5236  _dbus_assert (!result);
5237 #endif
5238 
5239  CONNECTION_UNLOCK (connection);
5240 
5241  return result;
5242 }
5243 
5256  unsigned long *pid)
5257 {
5258  dbus_bool_t result;
5259 
5260  _dbus_return_val_if_fail (connection != NULL, FALSE);
5261  _dbus_return_val_if_fail (pid != NULL, FALSE);
5262 
5263  CONNECTION_LOCK (connection);
5264 
5266  result = FALSE;
5267  else
5268  result = _dbus_transport_get_unix_process_id (connection->transport,
5269  pid);
5270 
5271  CONNECTION_UNLOCK (connection);
5272 
5273  return result;
5274 }
5275 
5289  void **data,
5290  dbus_int32_t *data_size)
5291 {
5292  dbus_bool_t result;
5293 
5294  _dbus_return_val_if_fail (connection != NULL, FALSE);
5295  _dbus_return_val_if_fail (data != NULL, FALSE);
5296  _dbus_return_val_if_fail (data_size != NULL, FALSE);
5297 
5298  CONNECTION_LOCK (connection);
5299 
5301  result = FALSE;
5302  else
5304  data,
5305  data_size);
5306  CONNECTION_UNLOCK (connection);
5307 
5308  return result;
5309 }
5310 
5333 void
5335  DBusAllowUnixUserFunction function,
5336  void *data,
5337  DBusFreeFunction free_data_function)
5338 {
5339  void *old_data = NULL;
5340  DBusFreeFunction old_free_function = NULL;
5341 
5342  _dbus_return_if_fail (connection != NULL);
5343 
5344  CONNECTION_LOCK (connection);
5346  function, data, free_data_function,
5347  &old_data, &old_free_function);
5348  CONNECTION_UNLOCK (connection);
5349 
5350  if (old_free_function != NULL)
5351  (* old_free_function) (old_data);
5352 }
5353 
5354 /* Same calling convention as dbus_connection_get_windows_user */
5356 _dbus_connection_get_linux_security_label (DBusConnection *connection,
5357  char **label_p)
5358 {
5359  dbus_bool_t result;
5360 
5361  _dbus_assert (connection != NULL);
5362  _dbus_assert (label_p != NULL);
5363 
5364  CONNECTION_LOCK (connection);
5365 
5367  result = FALSE;
5368  else
5369  result = _dbus_transport_get_linux_security_label (connection->transport,
5370  label_p);
5371 #ifndef __linux__
5372  _dbus_assert (!result);
5373 #endif
5374 
5375  CONNECTION_UNLOCK (connection);
5376 
5377  return result;
5378 }
5379 
5381 _dbus_connection_get_credentials (DBusConnection *connection)
5382 {
5383  DBusCredentials *result;
5384 
5385  _dbus_assert (connection != NULL);
5386 
5387  CONNECTION_LOCK (connection);
5388 
5390  result = NULL;
5391  else
5392  result = _dbus_transport_get_credentials (connection->transport);
5393 
5394  CONNECTION_UNLOCK (connection);
5395 
5396  return result;
5397 }
5398 
5432  char **windows_sid_p)
5433 {
5434  dbus_bool_t result;
5435 
5436  _dbus_return_val_if_fail (connection != NULL, FALSE);
5437  _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
5438 
5439  CONNECTION_LOCK (connection);
5440 
5442  result = FALSE;
5443  else
5444  result = _dbus_transport_get_windows_user (connection->transport,
5445  windows_sid_p);
5446 
5447 #ifdef DBUS_UNIX
5448  _dbus_assert (!result);
5449 #endif
5450 
5451  CONNECTION_UNLOCK (connection);
5452 
5453  return result;
5454 }
5455 
5477 void
5480  void *data,
5481  DBusFreeFunction free_data_function)
5482 {
5483  void *old_data = NULL;
5484  DBusFreeFunction old_free_function = NULL;
5485 
5486  _dbus_return_if_fail (connection != NULL);
5487 
5488  CONNECTION_LOCK (connection);
5490  function, data, free_data_function,
5491  &old_data, &old_free_function);
5492  CONNECTION_UNLOCK (connection);
5493 
5494  if (old_free_function != NULL)
5495  (* old_free_function) (old_data);
5496 }
5497 
5524 void
5526  dbus_bool_t value)
5527 {
5528  _dbus_return_if_fail (connection != NULL);
5529 
5530  CONNECTION_LOCK (connection);
5531  _dbus_transport_set_allow_anonymous (connection->transport, value);
5532  CONNECTION_UNLOCK (connection);
5533 }
5534 
5552 void
5554  dbus_bool_t value)
5555 {
5556  _dbus_return_if_fail (connection != NULL);
5557 
5558  CONNECTION_LOCK (connection);
5559  connection->route_peer_messages = value;
5560  CONNECTION_UNLOCK (connection);
5561 }
5562 
5586  DBusHandleMessageFunction function,
5587  void *user_data,
5588  DBusFreeFunction free_data_function)
5589 {
5590  DBusMessageFilter *filter;
5591 
5592  _dbus_return_val_if_fail (connection != NULL, FALSE);
5593  _dbus_return_val_if_fail (function != NULL, FALSE);
5594 
5595  filter = dbus_new0 (DBusMessageFilter, 1);
5596  if (filter == NULL)
5597  return FALSE;
5598 
5599  _dbus_atomic_inc (&filter->refcount);
5600 
5601  CONNECTION_LOCK (connection);
5602 
5603  if (!_dbus_list_append (&connection->filter_list,
5604  filter))
5605  {
5606  _dbus_message_filter_unref (filter);
5607  CONNECTION_UNLOCK (connection);
5608  return FALSE;
5609  }
5610 
5611  /* Fill in filter after all memory allocated,
5612  * so we don't run the free_user_data_function
5613  * if the add_filter() fails
5614  */
5615 
5616  filter->function = function;
5617  filter->user_data = user_data;
5618  filter->free_user_data_function = free_data_function;
5619 
5620  CONNECTION_UNLOCK (connection);
5621  return TRUE;
5622 }
5623 
5636 void
5638  DBusHandleMessageFunction function,
5639  void *user_data)
5640 {
5641  DBusList *link;
5642  DBusMessageFilter *filter;
5643 
5644  _dbus_return_if_fail (connection != NULL);
5645  _dbus_return_if_fail (function != NULL);
5646 
5647  CONNECTION_LOCK (connection);
5648 
5649  filter = NULL;
5650 
5651  link = _dbus_list_get_last_link (&connection->filter_list);
5652  while (link != NULL)
5653  {
5654  filter = link->data;
5655 
5656  if (filter->function == function &&
5657  filter->user_data == user_data)
5658  {
5659  _dbus_list_remove_link (&connection->filter_list, link);
5660  filter->function = NULL;
5661 
5662  break;
5663  }
5664 
5665  link = _dbus_list_get_prev_link (&connection->filter_list, link);
5666  filter = NULL;
5667  }
5668 
5669  CONNECTION_UNLOCK (connection);
5670 
5671 #ifndef DBUS_DISABLE_CHECKS
5672  if (filter == NULL)
5673  {
5674  _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added",
5675  function, user_data);
5676  return;
5677  }
5678 #endif
5679 
5680  /* Call application code */
5681  if (filter->free_user_data_function)
5682  (* filter->free_user_data_function) (filter->user_data);
5683 
5684  filter->free_user_data_function = NULL;
5685  filter->user_data = NULL;
5686 
5687  _dbus_message_filter_unref (filter);
5688 }
5689 
5705 static dbus_bool_t
5706 _dbus_connection_register_object_path (DBusConnection *connection,
5707  dbus_bool_t fallback,
5708  const char *path,
5709  const DBusObjectPathVTable *vtable,
5710  void *user_data,
5711  DBusError *error)
5712 {
5713  char **decomposed_path;
5714  dbus_bool_t retval;
5715 
5716  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
5717  return FALSE;
5718 
5719  CONNECTION_LOCK (connection);
5720 
5721  retval = _dbus_object_tree_register (connection->objects,
5722  fallback,
5723  (const char **) decomposed_path, vtable,
5724  user_data, error);
5725 
5726  CONNECTION_UNLOCK (connection);
5727 
5728  dbus_free_string_array (decomposed_path);
5729 
5730  return retval;
5731 }
5732 
5747  const char *path,
5748  const DBusObjectPathVTable *vtable,
5749  void *user_data,
5750  DBusError *error)
5751 {
5752  _dbus_return_val_if_fail (connection != NULL, FALSE);
5753  _dbus_return_val_if_fail (path != NULL, FALSE);
5754  _dbus_return_val_if_fail (path[0] == '/', FALSE);
5755  _dbus_return_val_if_fail (vtable != NULL, FALSE);
5756 
5757  return _dbus_connection_register_object_path (connection, FALSE, path, vtable, user_data, error);
5758 }
5759 
5777  const char *path,
5778  const DBusObjectPathVTable *vtable,
5779  void *user_data)
5780 {
5781  dbus_bool_t retval;
5782  DBusError error = DBUS_ERROR_INIT;
5783 
5784  _dbus_return_val_if_fail (connection != NULL, FALSE);
5785  _dbus_return_val_if_fail (path != NULL, FALSE);
5786  _dbus_return_val_if_fail (path[0] == '/', FALSE);
5787  _dbus_return_val_if_fail (vtable != NULL, FALSE);
5788 
5789  retval = _dbus_connection_register_object_path (connection, FALSE, path, vtable, user_data, &error);
5790 
5792  {
5793  _dbus_warn ("%s", error.message);
5794  dbus_error_free (&error);
5795  return FALSE;
5796  }
5797 
5798  return retval;
5799 }
5800 
5817  const char *path,
5818  const DBusObjectPathVTable *vtable,
5819  void *user_data,
5820  DBusError *error)
5821 {
5822  _dbus_return_val_if_fail (connection != NULL, FALSE);
5823  _dbus_return_val_if_fail (path != NULL, FALSE);
5824  _dbus_return_val_if_fail (path[0] == '/', FALSE);
5825  _dbus_return_val_if_fail (vtable != NULL, FALSE);
5826 
5827  return _dbus_connection_register_object_path (connection, TRUE, path, vtable, user_data, error);
5828 }
5829 
5849  const char *path,
5850  const DBusObjectPathVTable *vtable,
5851  void *user_data)
5852 {
5853  dbus_bool_t retval;
5854  DBusError error = DBUS_ERROR_INIT;
5855 
5856  _dbus_return_val_if_fail (connection != NULL, FALSE);
5857  _dbus_return_val_if_fail (path != NULL, FALSE);
5858  _dbus_return_val_if_fail (path[0] == '/', FALSE);
5859  _dbus_return_val_if_fail (vtable != NULL, FALSE);
5860 
5861  retval = _dbus_connection_register_object_path (connection, TRUE, path, vtable, user_data, &error);
5862 
5864  {
5865  _dbus_warn ("%s", error.message);
5866  dbus_error_free (&error);
5867  return FALSE;
5868  }
5869 
5870  return retval;
5871 }
5872 
5884  const char *path)
5885 {
5886  char **decomposed_path;
5887 
5888  _dbus_return_val_if_fail (connection != NULL, FALSE);
5889  _dbus_return_val_if_fail (path != NULL, FALSE);
5890  _dbus_return_val_if_fail (path[0] == '/', FALSE);
5891 
5892  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
5893  return FALSE;
5894 
5895  CONNECTION_LOCK (connection);
5896 
5897  _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
5898 
5899  dbus_free_string_array (decomposed_path);
5900 
5901  return TRUE;
5902 }
5903 
5916  const char *path,
5917  void **data_p)
5918 {
5919  char **decomposed_path;
5920 
5921  _dbus_return_val_if_fail (connection != NULL, FALSE);
5922  _dbus_return_val_if_fail (path != NULL, FALSE);
5923  _dbus_return_val_if_fail (data_p != NULL, FALSE);
5924 
5925  *data_p = NULL;
5926 
5927  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
5928  return FALSE;
5929 
5930  CONNECTION_LOCK (connection);
5931 
5932  *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path);
5933 
5934  CONNECTION_UNLOCK (connection);
5935 
5936  dbus_free_string_array (decomposed_path);
5937 
5938  return TRUE;
5939 }
5940 
5953  const char *parent_path,
5954  char ***child_entries)
5955 {
5956  char **decomposed_path;
5957  dbus_bool_t retval;
5958  _dbus_return_val_if_fail (connection != NULL, FALSE);
5959  _dbus_return_val_if_fail (parent_path != NULL, FALSE);
5960  _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
5961  _dbus_return_val_if_fail (child_entries != NULL, FALSE);
5962 
5963  if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
5964  return FALSE;
5965 
5966  CONNECTION_LOCK (connection);
5967 
5969  (const char **) decomposed_path,
5970  child_entries);
5971  dbus_free_string_array (decomposed_path);
5972 
5973  return retval;
5974 }
5975 
5976 static DBusDataSlotAllocator slot_allocator =
5977  _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (connection_slots));
5978 
5995 {
5996  return _dbus_data_slot_allocator_alloc (&slot_allocator,
5997  slot_p);
5998 }
5999 
6011 void
6012 dbus_connection_free_data_slot (dbus_int32_t *slot_p)
6013 {
6014  _dbus_return_if_fail (*slot_p >= 0);
6015 
6016  _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
6017 }
6018 
6043  dbus_int32_t slot,
6044  void *data,
6045  DBusFreeFunction free_data_func)
6046 {
6047  DBusFreeFunction old_free_func;
6048  void *old_data;
6049  dbus_bool_t retval;
6050 
6051  _dbus_return_val_if_fail (connection != NULL, FALSE);
6052  _dbus_return_val_if_fail (slot >= 0, FALSE);
6053 
6054  SLOTS_LOCK (connection);
6055 
6056  retval = _dbus_data_slot_list_set (&slot_allocator,
6057  &connection->slot_list,
6058  slot, data, free_data_func,
6059  &old_free_func, &old_data);
6060 
6061  SLOTS_UNLOCK (connection);
6062 
6063  if (retval)
6064  {
6065  /* Do the actual free outside the connection lock */
6066  if (old_free_func)
6067  (* old_free_func) (old_data);
6068  }
6069 
6070  return retval;
6071 }
6072 
6090 void*
6092  dbus_int32_t slot)
6093 {
6094  void *res;
6095 
6096  _dbus_return_val_if_fail (connection != NULL, NULL);
6097  _dbus_return_val_if_fail (slot >= 0, NULL);
6098 
6099  SLOTS_LOCK (connection);
6100 
6101  res = _dbus_data_slot_list_get (&slot_allocator,
6102  &connection->slot_list,
6103  slot);
6104 
6105  SLOTS_UNLOCK (connection);
6106 
6107  return res;
6108 }
6109 
6116 void
6118 {
6119  _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
6120 }
6121 
6130 void
6132  long size)
6133 {
6134  _dbus_return_if_fail (connection != NULL);
6135 
6136  CONNECTION_LOCK (connection);
6138  size);
6139  CONNECTION_UNLOCK (connection);
6140 }
6141 
6148 long
6150 {
6151  long res;
6152 
6153  _dbus_return_val_if_fail (connection != NULL, 0);
6154 
6155  CONNECTION_LOCK (connection);
6156  res = _dbus_transport_get_max_message_size (connection->transport);
6157  CONNECTION_UNLOCK (connection);
6158  return res;
6159 }
6160 
6169 void
6171  long n)
6172 {
6173  _dbus_return_if_fail (connection != NULL);
6174 
6175  CONNECTION_LOCK (connection);
6177  n);
6178  CONNECTION_UNLOCK (connection);
6179 }
6180 
6187 long
6189 {
6190  long res;
6191 
6192  _dbus_return_val_if_fail (connection != NULL, 0);
6193 
6194  CONNECTION_LOCK (connection);
6196  CONNECTION_UNLOCK (connection);
6197  return res;
6198 }
6199 
6225 void
6227  long size)
6228 {
6229  _dbus_return_if_fail (connection != NULL);
6230 
6231  CONNECTION_LOCK (connection);
6233  size);
6234  CONNECTION_UNLOCK (connection);
6235 }
6236 
6243 long
6245 {
6246  long res;
6247 
6248  _dbus_return_val_if_fail (connection != NULL, 0);
6249 
6250  CONNECTION_LOCK (connection);
6252  CONNECTION_UNLOCK (connection);
6253  return res;
6254 }
6255 
6267 void
6269  long n)
6270 {
6271  _dbus_return_if_fail (connection != NULL);
6272 
6273  CONNECTION_LOCK (connection);
6275  n);
6276  CONNECTION_UNLOCK (connection);
6277 }
6278 
6285 long
6287 {
6288  long res;
6289 
6290  _dbus_return_val_if_fail (connection != NULL, 0);
6291 
6292  CONNECTION_LOCK (connection);
6294  CONNECTION_UNLOCK (connection);
6295  return res;
6296 }
6297 
6308 long
6310 {
6311  long res;
6312 
6313  _dbus_return_val_if_fail (connection != NULL, 0);
6314 
6315  CONNECTION_LOCK (connection);
6316  res = _dbus_counter_get_size_value (connection->outgoing_counter);
6317  CONNECTION_UNLOCK (connection);
6318  return res;
6319 }
6320 
6321 #ifdef DBUS_ENABLE_STATS
6322 void
6323 _dbus_connection_get_stats (DBusConnection *connection,
6324  dbus_uint32_t *in_messages,
6325  dbus_uint32_t *in_bytes,
6326  dbus_uint32_t *in_fds,
6327  dbus_uint32_t *in_peak_bytes,
6328  dbus_uint32_t *in_peak_fds,
6329  dbus_uint32_t *out_messages,
6330  dbus_uint32_t *out_bytes,
6331  dbus_uint32_t *out_fds,
6332  dbus_uint32_t *out_peak_bytes,
6333  dbus_uint32_t *out_peak_fds)
6334 {
6335  CONNECTION_LOCK (connection);
6336 
6337  if (in_messages != NULL)
6338  *in_messages = connection->n_incoming;
6339 
6340  _dbus_transport_get_stats (connection->transport,
6341  in_bytes, in_fds, in_peak_bytes, in_peak_fds);
6342 
6343  if (out_messages != NULL)
6344  *out_messages = connection->n_outgoing;
6345 
6346  if (out_bytes != NULL)
6347  *out_bytes = _dbus_counter_get_size_value (connection->outgoing_counter);
6348 
6349  if (out_fds != NULL)
6350  *out_fds = _dbus_counter_get_unix_fd_value (connection->outgoing_counter);
6351 
6352  if (out_peak_bytes != NULL)
6353  *out_peak_bytes = _dbus_counter_get_peak_size_value (connection->outgoing_counter);
6354 
6355  if (out_peak_fds != NULL)
6356  *out_peak_fds = _dbus_counter_get_peak_unix_fd_value (connection->outgoing_counter);
6357 
6358  CONNECTION_UNLOCK (connection);
6359 }
6360 #endif /* DBUS_ENABLE_STATS */
6361 
6369 long
6371 {
6372  long res;
6373 
6374  _dbus_return_val_if_fail (connection != NULL, 0);
6375 
6376  CONNECTION_LOCK (connection);
6378  CONNECTION_UNLOCK (connection);
6379  return res;
6380 }
6381 
6382 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
6383 
6389 const char*
6390 _dbus_connection_get_address (DBusConnection *connection)
6391 {
6392  return _dbus_transport_get_address (connection->transport);
6393 }
6394 #endif
6395 
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
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...
An atomic integer safe to increment or decrement from multiple threads.
Definition: dbus-sysdeps.h:323
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...
DBusMessage * dbus_message_ref(DBusMessage *message)
Increments the reference count of a DBusMessage.
DBusList * filter_list
List of filters.
void _dbus_transport_set_max_received_unix_fds(DBusTransport *transport, long n)
See dbus_connection_set_max_received_unix_fds().
Internals of DBusTimeout.
Definition: dbus-timeout.c:40
void * user_data
User data for the function.
void dbus_message_lock(DBusMessage *message)
Locks a message.
Definition: dbus-message.c:419
void * _dbus_list_get_last(DBusList **list)
Gets the last data in the list.
Definition: dbus-list.c:624
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.
const char * _dbus_transport_get_server_id(DBusTransport *transport)
Gets the id of the server we are connected to (see dbus_server_get_id()).
dbus_bool_t _dbus_list_prepend(DBusList **list, void *data)
Prepends a value to the list.
Definition: dbus-list.c:293
DBusDispatchStatus
Indicates the status of incoming data on a DBusConnection.
const char * message
public error message field
Definition: dbus-errors.h:51
const char * _dbus_transport_get_address(DBusTransport *transport)
Gets the address of a transport.
DBusFreeFunction free_wakeup_main_data
free wakeup_main_data
Implementation of DBusWatch.
Definition: dbus-watch.c:40
#define NULL
A null pointer, defined appropriately for C or C++.
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.
void(* DBusFreeFunction)(void *memory)
The type of a function which frees a block of memory.
Definition: dbus-memory.h:63
dbus_bool_t _dbus_connection_add_timeout_unlocked(DBusConnection *connection, DBusTimeout *timeout)
Adds a timeout using the connection&#39;s DBusAddTimeoutFunction if available.
DBusList * queue_link
Preallocated link in the queue.
unsigned int have_connection_lock
Used to check locking.
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.
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:241
void _dbus_connection_queue_synthesized_message_link(DBusConnection *connection, DBusList *link)
Adds a link + message to the incoming message queue.
DBusConnection * _dbus_pending_call_get_connection_unlocked(DBusPendingCall *pending)
Gets the connection associated with this pending call.
void _dbus_object_tree_free_all_unlocked(DBusObjectTree *tree)
Free all the handlers in the tree.
More memory is needed to continue.
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:703
void _dbus_pending_call_finish_completion(DBusPendingCall *pending)
Call the notifier function for the pending call.
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:1259
dbus_uint32_t dbus_message_get_serial(DBusMessage *message)
Returns the serial of a message or 0 if none has been specified.
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
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...
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
DBusList * _dbus_list_get_last_link(DBusList **list)
Gets the last link in the list.
Definition: dbus-list.c:608
dbus_bool_t dbus_connection_get_windows_user(DBusConnection *connection, char **windows_sid_p)
Gets the Windows user SID of the connection if known.
void _dbus_connection_lock(DBusConnection *connection)
Acquires the connection lock.
dbus_bool_t _dbus_transport_get_socket_fd(DBusTransport *transport, DBusSocket *fd_p)
Get the socket file descriptor, if any.
DBusMessage * dbus_pending_call_steal_reply(DBusPendingCall *pending)
Gets the reply, or returns NULL if none has been received yet.
#define dbus_new(type, count)
Safe macro for using dbus_malloc().
Definition: dbus-memory.h:57
DBusList * disconnect_message_link
Preallocated list node for queueing the disconnection message.
void(* DBusWatchToggledFunction)(DBusWatch *watch, void *data)
Called when dbus_watch_get_enabled() may return a different value than it did before.
void dbus_connection_set_max_message_size(DBusConnection *connection, long size)
Specifies the maximum size message this connection is allowed to receive.
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.
void _dbus_list_remove_link(DBusList **list, DBusList *link)
Removes a link from the list.
Definition: dbus-list.c:528
void _dbus_timeout_list_free(DBusTimeoutList *timeout_list)
Frees a DBusTimeoutList.
Definition: dbus-timeout.c:215
long dbus_connection_get_outgoing_size(DBusConnection *connection)
Gets the approximate size in bytes of all messages in the outgoing message queue. ...
DBusConnection * dbus_connection_ref(DBusConnection *connection)
Increments the reference count of a DBusConnection.
dbus_bool_t dbus_connection_can_send_type(DBusConnection *connection, int type)
Tests whether a certain type can be send via the connection.
DBusMessage * message_borrowed
Filled in if the first incoming message has been borrowed; dispatch_acquired will be set by the borro...
#define DBUS_TYPE_STRING
Type code marking a UTF-8 encoded, nul-terminated Unicode string.
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.
DBusTimeoutList * _dbus_timeout_list_new(void)
Creates a new timeout list.
Definition: dbus-timeout.c:198
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
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...
unsigned int shareable
TRUE if libdbus owns a reference to the connection and can return it from dbus_connection_open() more...
void _dbus_list_append_link(DBusList **list, DBusList *link)
Appends a link to the list.
Definition: dbus-list.c:316
Internals of DBusCounter.
#define DBUS_ERROR_INIT
Expands to a suitable initializer for a DBusError on the stack.
Definition: dbus-errors.h:62
void * data
Data stored at this element.
Definition: dbus-list.h:38
DBusFreeFunction free_dispatch_status_data
free dispatch_status_data
DBusMessage * dbus_message_new(int message_type)
Constructs a new message of the given message type.
DBusFreeFunction free_user_data_function
Function to free the user data.
DBusList * incoming_messages
Queue of messages we have received, end of the list received most recently.
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...
dbus_bool_t _dbus_transport_get_unix_process_id(DBusTransport *transport, unsigned long *pid)
See dbus_connection_get_unix_process_id().
const char * dbus_message_get_signature(DBusMessage *message)
Gets the type signature of the message, i.e.
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:441
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...
Message has not had any effect - see if other handlers want it.
Definition: dbus-shared.h:69
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().
void dbus_message_iter_init_append(DBusMessage *message, DBusMessageIter *iter)
Initializes a DBusMessageIter for appending arguments to the end of a message.
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.
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...
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
void _dbus_watch_list_free(DBusWatchList *watch_list)
Frees a DBusWatchList.
Definition: dbus-watch.c:249
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.
void _dbus_object_tree_unregister_and_unlock(DBusObjectTree *tree, const char **path)
Unregisters an object subtree that was registered with the same path.
#define DBUS_INTERFACE_PEER
The interface supported by most dbus peers.
Definition: dbus-shared.h:101
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:362
void _dbus_connection_close_if_only_one_ref(DBusConnection *connection)
Used internally to handle the semantics of dbus_server_set_new_connection_function().
#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:107
void dbus_connection_return_message(DBusConnection *connection, DBusMessage *message)
Used to return a message after peeking at it using dbus_connection_borrow_message().
DBusAtomic refcount
Reference count.
DBusCounter * _dbus_counter_ref(DBusCounter *counter)
Increments refcount of the counter.
void dbus_address_entries_free(DBusAddressEntry **entries)
Frees a NULL-terminated array of address entries.
Definition: dbus-address.c:190
dbus_bool_t _dbus_transport_get_windows_user(DBusTransport *transport, char **windows_sid_p)
See dbus_connection_get_windows_user().
Implementation details of DBusPendingCall - all fields are private.
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_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.
Implementation details of DBusConnection.
dbus_bool_t dbus_message_has_interface(DBusMessage *message, const char *iface)
Checks if the message has an interface.
void dbus_connection_remove_filter(DBusConnection *connection, DBusHandleMessageFunction function, void *user_data)
Removes a previously-added message filter.
void _dbus_list_clear_full(DBusList **list, DBusFreeFunction function)
Free every link and every element in the list.
Definition: dbus-list.c:568
struct DBusMutex DBusMutex
An opaque mutex type provided by the DBusThreadFunctions implementation installed by dbus_threads_ini...
Definition: dbus-threads.h:41
#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:120
DBusWatchList * _dbus_watch_list_new(void)
Creates a new watch list.
Definition: dbus-watch.c:232
DBusCounter * outgoing_counter
Counts size of outgoing messages.
dbus_bool_t(* DBusWatchAddFunction)(DBusWatchList *list, DBusWatch *watch)
Function to be called in protected_change_watch() with refcount held.
#define DBUS_MESSAGE_TYPE_ERROR
Message type of an error reply message, see dbus_message_get_type()
DBusList * _dbus_list_alloc_link(void *data)
Allocates a linked list node.
Definition: dbus-list.c:243
dbus_bool_t dbus_connection_get_unix_user(DBusConnection *connection, unsigned long *uid)
Gets the UNIX user ID of the connection if known.
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.
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...
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
DBusMessage * dbus_message_new_signal(const char *path, const char *iface, const char *name)
Constructs a new message representing a signal emission.
long _dbus_transport_get_max_message_size(DBusTransport *transport)
See dbus_connection_get_max_message_size().
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:544
dbus_bool_t _dbus_list_remove(DBusList **list, void *data)
Removes a value from the list.
Definition: dbus-list.c:416
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...
DBusDispatchStatusFunction dispatch_status_function
Function on dispatch status changes.
DBusHandlerResult
Results that a message handler can return.
Definition: dbus-shared.h:66
Hash keys are strings.
Definition: dbus-hash.h:69
DBusMessage * _dbus_connection_get_message_to_send(DBusConnection *connection)
Gets the next outgoing message.
DBusList * _dbus_list_pop_first_link(DBusList **list)
Removes the first link in the list and returns it.
Definition: dbus-list.c:656
Hash iterator object.
Definition: dbus-hash.h:49
DBusMessageIter struct; contains no public fields.
Definition: dbus-message.h:61
void dbus_connection_steal_borrowed_message(DBusConnection *connection, DBusMessage *message)
Used to keep a message after peeking at it using dbus_connection_borrow_message().
void * _dbus_list_get_first(DBusList **list)
Gets the first data in the list.
Definition: dbus-list.c:640
dbus_bool_t _dbus_pending_call_get_completed_unlocked(DBusPendingCall *pending)
Checks whether the pending call has received a reply yet, or not.
#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:119
void dbus_connection_free_data_slot(dbus_int32_t *slot_p)
Deallocates a global ID for connection data slots.
#define DBUS_ERROR_UNKNOWN_METHOD
Method name you invoked isn&#39;t known by the object you invoked it on.
const char * dbus_message_get_destination(DBusMessage *message)
Gets the destination of a message or NULL if there is none set.
Internal struct representing a message filter function.
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:315
#define DBUS_PATH_LOCAL
The object path used in local/in-process-generated messages.
Definition: dbus-shared.h:82
void(* DBusRemoveTimeoutFunction)(DBusTimeout *timeout, void *data)
Called when libdbus no longer needs a timeout to be monitored by the main loop.
dbus_bool_t _dbus_list_copy(DBusList **list, DBusList **dest)
Copies a list.
Definition: dbus-list.c:725
void _dbus_connection_block_pending_call(DBusPendingCall *pending)
Blocks until a pending call times out or gets a reply.
DBusWatchList * watches
Stores active watches.
DBusRMutex * mutex
Lock on the entire DBusConnection.
dbus_bool_t _dbus_transport_get_is_connected(DBusTransport *transport)
Returns TRUE if the transport has not been disconnected.
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:295
dbus_bool_t _dbus_hash_table_remove_int(DBusHashTable *table, int key)
Removes the hash entry for the given key.
Definition: dbus-hash.c:1162
int _dbus_connection_get_pending_fds_count(DBusConnection *connection)
Return how many file descriptors are pending in the loader.
dbus_bool_t dbus_message_set_error_name(DBusMessage *message, const char *error_name)
Sets the name of the error (DBUS_MESSAGE_TYPE_ERROR).
There is more data to potentially convert to messages.
Socket interface.
Definition: dbus-sysdeps.h:178
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.
DBusConnection * dbus_connection_open_private(const char *address, DBusError *error)
Opens a new, dedicated connection to a remote address.
DBusAtomic refcount
Reference count.
const char * dbus_message_get_member(DBusMessage *message)
Gets the interface member being invoked (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted (DBUS_MESSAGE_TYPE...
DBusPreallocatedSend * dbus_connection_preallocate_send(DBusConnection *connection)
Preallocates resources needed to send a message, allowing the message to be sent without the possibil...
Virtual table that must be implemented to handle a portion of the object path hierarchy.
Internals of DBusMessage.
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.
dbus_bool_t dbus_pending_call_get_completed(DBusPendingCall *pending)
Checks whether the pending call has received a reply yet, or not.
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:245
long _dbus_transport_get_max_received_unix_fds(DBusTransport *transport)
See dbus_connection_set_max_received_unix_fds().
Hash keys are integers.
Definition: dbus-hash.h:70
DBUS_PRIVATE_EXPORT void _dbus_rmutex_unlock(DBusRMutex *mutex)
Unlocks a mutex.
Definition: dbus-threads.c:150
#define DBUS_ERROR_OBJECT_PATH_IN_USE
There&#39;s already an object with the requested object path.
#define dbus_new0(type, count)
Safe macro for using dbus_malloc0().
Definition: dbus-memory.h:58
int _dbus_hash_table_get_n_entries(DBusHashTable *table)
Gets the number of hash entries in a hash table.
Definition: dbus-hash.c:1408
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:312
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().
void _dbus_connection_remove_watch_unlocked(DBusConnection *connection, DBusWatch *watch)
Removes a watch using the connection&#39;s DBusRemoveWatchFunction if available.
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().
dbus_bool_t _dbus_pending_call_is_timeout_added_unlocked(DBusPendingCall *pending)
Checks to see if a timeout has been added.
void * _dbus_hash_iter_get_value(DBusHashIter *iter)
Gets the value of the current entry.
Definition: dbus-hash.c:614
void * dispatch_status_data
Application data for dispatch_status_function.
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
dbus_bool_t _dbus_connection_has_messages_to_send_unlocked(DBusConnection *connection)
Checks whether there are messages in the outgoing message queue.
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.
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.
DBusTransport * transport
Object that sends/receives messages over network.
DBusDispatchStatus dbus_connection_dispatch(DBusConnection *connection)
Processes any incoming data.
dbus_bool_t dbus_connection_send(DBusConnection *connection, DBusMessage *message, dbus_uint32_t *serial)
Adds a message to the outgoing message queue.
dbus_bool_t _dbus_transport_peek_is_authenticated(DBusTransport *transport)
Returns TRUE if we have been authenticated.
DBusDispatchStatus dbus_connection_get_dispatch_status(DBusConnection *connection)
Gets the current state of the incoming message queue.
All currently available data has been processed.
dbus_bool_t(* DBusAddTimeoutFunction)(DBusTimeout *timeout, void *data)
Called when libdbus needs a new timeout to be monitored by the main loop.
void * dbus_connection_get_data(DBusConnection *connection, dbus_int32_t slot)
Retrieves data previously set with dbus_connection_set_data().
DBusTimeoutList * timeouts
Stores active timeouts.
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.
dbus_bool_t(* DBusTimeoutAddFunction)(DBusTimeoutList *list, DBusTimeout *timeout)
Function to be called in protected_change_timeout() with refcount held.
long dbus_connection_get_max_message_size(DBusConnection *connection)
Gets the value set by dbus_connection_set_max_message_size().
DBusHashTable * pending_replies
Hash of message serials to DBusPendingCall.
Internals of DBusObjectTree.
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
void _dbus_counter_unref(DBusCounter *counter)
Decrements refcount of the counter and possibly finalizes the counter.
dbus_int32_t _dbus_atomic_inc(DBusAtomic *atomic)
Atomically increments an integer.
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:387
dbus_bool_t _dbus_list_append(DBusList **list, void *data)
Appends a value to the list.
Definition: dbus-list.c:271
dbus_bool_t _dbus_decompose_path(const char *data, int len, char ***path, int *path_len)
Decompose an object path.
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:1225
dbus_bool_t dbus_connection_get_unix_process_id(DBusConnection *connection, unsigned long *pid)
Gets the process ID of the connection if any.
dbus_bool_t dbus_connection_get_is_authenticated(DBusConnection *connection)
Gets whether the connection was authenticated.
void dbus_connection_close(DBusConnection *connection)
Closes a private connection, so no further data can be sent or received.
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.
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...
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...
dbus_bool_t io_path_acquired
Someone has transport io path (can use the transport to read/write messages)
void _dbus_list_foreach(DBusList **list, DBusForeachFunction function, void *data)
Calls the given function for each element in the list.
Definition: dbus-list.c:787
void(* DBusWakeupMainFunction)(void *data)
Called when the main loop&#39;s thread should be notified that there&#39;s now work to do.
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:1131
Internals of DBusAddressEntry.
Definition: dbus-address.c:44
DBusList * outgoing_messages
Queue of messages we need to send, send the end of the list first.
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.
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...
DBusObjectTree * objects
Object path handlers registered with this connection.
long dbus_connection_get_outgoing_unix_fds(DBusConnection *connection)
Gets the approximate number of uni fds of all messages in the outgoing message queue.
void(* DBusWatchRemoveFunction)(DBusWatchList *list, DBusWatch *watch)
Function to be called in protected_change_watch() with refcount held.
dbus_uint32_t client_serial
Client serial.
long dbus_connection_get_max_received_size(DBusConnection *connection)
Gets the value set by dbus_connection_set_max_received_size().
DBusCMutex * io_path_mutex
Protects io_path_acquired.
#define DBUS_MESSAGE_TYPE_METHOD_CALL
Message type of a method call message, see dbus_message_get_type()
DBusConnection * dbus_connection_open(const char *address, DBusError *error)
Gets a connection to a remote address.
void _dbus_connection_unref_unlocked(DBusConnection *connection)
Decrements the reference count of a DBusConnection.
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.
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:783
DBusCredentials * _dbus_transport_get_credentials(DBusTransport *transport)
If the transport has already been authenticated, return its credentials.
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 ...
Object representing an exception.
Definition: dbus-errors.h:48
void _dbus_hash_iter_remove_entry(DBusHashIter *iter)
Removes the current entry from the hash table.
Definition: dbus-hash.c:593
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
void _dbus_get_monotonic_time(long *tv_sec, long *tv_usec)
Get current time, as in gettimeofday().
void _dbus_disable_sigpipe(void)
signal (SIGPIPE, SIG_IGN);
dbus_bool_t _dbus_transport_get_is_anonymous(DBusTransport *transport)
See dbus_connection_get_is_anonymous().
void * _dbus_list_pop_first(DBusList **list)
Removes the first value in the list and returns it.
Definition: dbus-list.c:677
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...
dbus_bool_t dbus_message_append_args(DBusMessage *message, int first_arg_type,...)
Appends fields to a message given a variable argument list.
#define DBUS_ERROR_UNKNOWN_OBJECT
Object you invoked a method on isn&#39;t known.
dbus_bool_t dbus_connection_get_is_anonymous(DBusConnection *connection)
Gets whether the connection is not authenticated as a specific user.
#define DBUS_MESSAGE_TYPE_SIGNAL
Message type of a signal message, see dbus_message_get_type()
dbus_bool_t _dbus_connection_add_watch_unlocked(DBusConnection *connection, DBusWatch *watch)
Adds a watch using the connection&#39;s DBusAddWatchFunction if available.
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_uint32_t dbus_message_get_reply_serial(DBusMessage *message)
Returns the serial that the message is a reply to or 0 if none.
long dbus_connection_get_max_message_unix_fds(DBusConnection *connection)
Gets the value set by dbus_connection_set_max_message_unix_fds().
DBusWakeupMainFunction wakeup_main_function
Function to wake up the mainloop.
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...
void _dbus_cmutex_unlock(DBusCMutex *mutex)
Unlocks a mutex.
Definition: dbus-threads.c:164
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...
DBusDataSlotList slot_list
Data stored by allocated integer ID.
DBusPendingCall * dbus_pending_call_ref(DBusPendingCall *pending)
Increments the reference count on a pending call.
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...
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:364
dbus_uint32_t _dbus_pending_call_get_reply_serial_unlocked(DBusPendingCall *pending)
Gets the reply&#39;s serial number.
DBusTransport * _dbus_transport_open(DBusAddressEntry *entry, DBusError *error)
Try to open a new transport for the given address entry.
DBusConnection * _dbus_connection_new_for_transport(DBusTransport *transport)
Creates a new connection for the given transport.
#define _DBUS_UNLOCK(name)
Unlocks a global lock.
unsigned int disconnected_message_arrived
We popped or are dispatching the disconnected message.
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init(), and fills it with the same contents as #_DBUS_STRING_I...
Definition: dbus-string.c:264
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 ...
unsigned int disconnected_message_processed
We did our default handling of the disconnected message, such as closing the connection.
dbus_bool_t _dbus_transport_get_unix_user(DBusTransport *transport, unsigned long *uid)
See dbus_connection_get_unix_user().
void * _dbus_data_slot_list_get(DBusDataSlotAllocator *allocator, DBusDataSlotList *list, int slot)
Retrieves data previously set with _dbus_data_slot_list_set_data().
#define CONNECTION_UNLOCK(connection)
shorter and more visible way to write _dbus_connection_unlock()
void(* DBusTimeoutToggledFunction)(DBusTimeout *timeout, void *data)
Called when dbus_timeout_get_enabled() may return a different value than it did before.
unsigned int route_peer_messages
If TRUE, if org.freedesktop.DBus.Peer messages have a bus name, don&#39;t handle them automatically...
#define TRUE
Expands to "1".
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...
void _dbus_data_slot_list_init(DBusDataSlotList *list)
Initializes a slot list.
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
Data structure that stores the actual user data set at a given slot.
Definition: dbus-dataslot.h:69
DBusCondVar * io_path_cond
Notify when io_path_acquired is available.
void(* DBusTimeoutToggleFunction)(DBusTimeoutList *list, DBusTimeout *timeout, dbus_bool_t enabled)
Function to be called in protected_change_timeout() with refcount held.
void _dbus_condvar_new_at_location(DBusCondVar **location_p)
This does the same thing as _dbus_condvar_new.
Definition: dbus-threads.c:199
DBusDispatchStatus last_dispatch_status
The last dispatch status we reported to the application.
unsigned int exit_on_disconnect
If TRUE, exit after handling disconnect signal.
dbus_bool_t _dbus_transport_set_connection(DBusTransport *transport, DBusConnection *connection)
Sets the connection using this transport.
#define DBUS_ERROR_FAILED
A generic error; "something went wrong" - see the error message for more.
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:381
void _dbus_list_free_link(DBusList *link)
Frees a linked list node allocated with _dbus_list_alloc_link.
Definition: dbus-list.c:255
void dbus_move_error(DBusError *src, DBusError *dest)
Moves an error src into dest, freeing src and overwriting dest.
Definition: dbus-errors.c:279
const char * name
public error name field
Definition: dbus-errors.h:50
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...
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.
dbus_bool_t dbus_set_error_from_message(DBusError *error, DBusMessage *message)
Sets a DBusError based on the contents of the given message.
dbus_bool_t(* DBusAddWatchFunction)(DBusWatch *watch, void *data)
Called when libdbus needs a new watch to be monitored by the main loop.
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
#define DBUS_TYPE_UNIX_FD
Type code marking a unix file descriptor.
void(* DBusWatchToggleFunction)(DBusWatchList *list, DBusWatch *watch, dbus_bool_t enabled)
Function to be called in protected_change_watch() with refcount held.
void dbus_pending_call_unref(DBusPendingCall *pending)
Decrements the reference count on a pending call, freeing it if the count reaches 0...
Object representing a transport such as a socket.
void(* DBusRemoveWatchFunction)(DBusWatch *watch, void *data)
Called when libdbus no longer needs a watch to be monitored by the main loop.
DBusWatchList implementation details.
Definition: dbus-watch.c:214
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...
int n_incoming
Length of incoming queue.
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.
DBusMessage * dbus_connection_pop_message(DBusConnection *connection)
Returns the first-received message from the incoming message queue, removing it from the queue...
An allocator that tracks a set of slot IDs.
Definition: dbus-dataslot.h:55
#define DBUS_TYPE_INVALID
Type code that is never equal to a legitimate type code.
Definition: dbus-protocol.h:60
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).
void _dbus_exit(int code)
Exit the process, returning the given value.
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...
Internals of DBusPreallocatedSend.
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...
void(* DBusDispatchStatusFunction)(DBusConnection *connection, DBusDispatchStatus new_status, void *data)
Called when the return value of dbus_connection_get_dispatch_status() may have changed.
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...
DBusList * counter_link
Preallocated link in the resource counter.
DBusObjectTree * _dbus_object_tree_new(DBusConnection *connection)
Creates a new object tree, representing a mapping from paths to handler vtables.
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:414
void dbus_pending_call_block(DBusPendingCall *pending)
Block until the pending call is completed.
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:1134
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:342
int n_outgoing
Length of outgoing queue.
DBusCMutex * dispatch_mutex
Protects dispatch_acquired.
DBUS_PRIVATE_EXPORT DBusPendingCall * _dbus_pending_call_new_unlocked(DBusConnection *connection, int timeout_milliseconds, DBusTimeoutHandler timeout_handler)
Creates a new pending reply object.
dbus_int32_t _dbus_atomic_dec(DBusAtomic *atomic)
Atomically decrement an integer.
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.
void(* DBusTimeoutRemoveFunction)(DBusTimeoutList *list, DBusTimeout *timeout)
Function to be called in protected_change_timeout() with refcount held.
A node in a linked list.
Definition: dbus-list.h:34
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.
void _dbus_hash_iter_init(DBusHashTable *table, DBusHashIter *iter)
Initializes a hash table iterator.
Definition: dbus-hash.c:518
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:500
void dbus_free_string_array(char **str_array)
Frees a NULL-terminated array of strings.
Definition: dbus-memory.c:751
DBusHandlerResult(* DBusHandleMessageFunction)(DBusConnection *connection, DBusMessage *message, void *user_data)
Called when a message needs to be handled.
DBusTransport * _dbus_transport_ref(DBusTransport *transport)
Increments the reference count for the transport.
dbus_bool_t _dbus_transport_try_to_authenticate(DBusTransport *transport)
Returns TRUE if we have been authenticated.
DBusCondVar * dispatch_cond
Notify when dispatch_acquired is available.
void _dbus_connection_remove_timeout_unlocked(DBusConnection *connection, DBusTimeout *timeout)
Removes a timeout using the connection&#39;s DBusRemoveTimeoutFunction if available.
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.
void _dbus_rmutex_free_at_location(DBusRMutex **location_p)
Frees a DBusRMutex; does nothing if passed a NULL pointer.
Definition: dbus-threads.c:94
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...
long _dbus_transport_get_max_received_size(DBusTransport *transport)
See dbus_connection_get_max_received_size().
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.
long _dbus_transport_get_max_message_unix_fds(DBusTransport *transport)
See dbus_connection_get_max_message_unix_fds().
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:1060
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:1085
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...
#define DBUS_ERROR_DISCONNECTED
The connection is disconnected and you&#39;re trying to use it.
DBusCounter * _dbus_counter_new(void)
Creates a new DBusCounter.
void _dbus_cmutex_lock(DBusCMutex *mutex)
Locks a mutex.
Definition: dbus-threads.c:136
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...
void _dbus_transport_set_allow_anonymous(DBusTransport *transport, dbus_bool_t value)
See dbus_connection_set_allow_anonymous()
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...
DBusHandleMessageFunction function
Function to call to filter.
#define DBUS_ERROR_NO_MEMORY
There was not enough memory to complete an operation.
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.
dbus_bool_t dbus_message_iter_append_basic(DBusMessageIter *iter, int type, const void *value)
Appends a basic-typed value to the message.
void _dbus_transport_set_max_received_size(DBusTransport *transport, long size)
See dbus_connection_set_max_received_size().
DBusList * expired_messages
Messages that will be released when we next unlock.
DBusList * _dbus_list_get_first_link(DBusList **list)
Gets the first link in the list.
Definition: dbus-list.c:595
#define FALSE
Expands to "0".
int dbus_message_get_type(DBusMessage *message)
Gets the type of a message.
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...
dbus_bool_t dbus_connection_get_unix_fd(DBusConnection *connection, int *fd)
Get the UNIX file descriptor of the connection, if any.
int _dbus_transport_get_pending_fds_count(DBusTransport *transport)
Return how many file descriptors are pending in the loader.
void _dbus_list_prepend_link(DBusList **list, DBusList *link)
Prepends a link to the list.
Definition: dbus-list.c:334
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:812
#define _DBUS_LOCK(name)
Locks a global lock, initializing it first if necessary.
#define _DBUS_LOCK_NAME(name)
Expands to name of a global lock variable.
dbus_bool_t _dbus_transport_can_pass_unix_fd(DBusTransport *transport)
Returns TRUE if the transport supports sending unix fds.
void _dbus_cmutex_free_at_location(DBusCMutex **location_p)
Frees a DBusCMutex; does nothing if passed a NULL pointer.
Definition: dbus-threads.c:107
char * server_guid
GUID of server if we are in shared_connections, NULL if server GUID is unknown or connection is priva...
dbus_bool_t dbus_connection_get_is_connected(DBusConnection *connection)
Gets whether the connection is currently open.
void dbus_connection_send_preallocated(DBusConnection *connection, DBusPreallocatedSend *preallocated, DBusMessage *message, dbus_uint32_t *client_serial)
Sends a message using preallocated resources.
void dbus_connection_unref(DBusConnection *connection)
Decrements the reference count of a DBusConnection, and finalizes it if the count reaches zero...
dbus_int32_t _dbus_atomic_get(DBusAtomic *atomic)
Atomically get the value of an integer.
Internals of DBusHashTable.
Definition: dbus-hash.c:169
void _dbus_sleep_milliseconds(int milliseconds)
Sleeps the given number of milliseconds.
void _dbus_object_tree_unref(DBusObjectTree *tree)
Decrement the reference count.
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:70
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...
DBusMessage * dbus_connection_borrow_message(DBusConnection *connection)
Returns the first-received message from the incoming message queue, leaving it in the queue...
DBusConnection * _dbus_connection_ref_unlocked(DBusConnection *connection)
Increments the reference count of a DBusConnection.
Message has had its effect - no need to run more handlers.
Definition: dbus-shared.h:68
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 ...
char * _dbus_strdup(const char *str)
Duplicates a string.
#define CONNECTION_LOCK(connection)
Internals of DBusPendingCall.
dbus_bool_t dispatch_acquired
Someone has dispatch path (can drain incoming queue)
void _dbus_transport_disconnect(DBusTransport *transport)
Closes our end of the connection to a remote application.
DBusTimeout * _dbus_pending_call_get_timeout_unlocked(DBusPendingCall *pending)
Retrives the timeout.
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().
dbus_bool_t dbus_connection_add_filter(DBusConnection *connection, DBusHandleMessageFunction function, void *user_data, DBusFreeFunction free_data_function)
Adds a message filter.
dbus_bool_t dbus_connection_unregister_object_path(DBusConnection *connection, const char *path)
Unregisters the handler registered with exactly the given path.
long dbus_connection_get_max_received_unix_fds(DBusConnection *connection)
Gets the value set by dbus_connection_set_max_received_unix_fds().
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.
void _dbus_connection_unlock(DBusConnection *connection)
Releases the connection lock.
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)...
void _dbus_transport_set_max_message_size(DBusTransport *transport, long size)
See dbus_connection_set_max_message_size().
void dbus_message_unref(DBusMessage *message)
Decrements the reference count of a DBusMessage, freeing the message if the count reaches 0...
void * wakeup_main_data
Application data for wakeup_main_function.
Need more memory in order to return DBUS_HANDLER_RESULT_HANDLED or DBUS_HANDLER_RESULT_NOT_YET_HANDLE...
Definition: dbus-shared.h:70
void dbus_connection_flush(DBusConnection *connection)
Blocks until the outgoing message queue is empty.
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_bool_t dbus_connection_has_messages_to_send(DBusConnection *connection)
Checks whether there are messages in the outgoing message queue.
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_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...
DBusDispatchStatus _dbus_transport_get_dispatch_status(DBusTransport *transport)
Reports our current dispatch status (whether there&#39;s buffered data to be queued as messages...
void _dbus_pending_call_start_completion_unlocked(DBusPendingCall *pending)
Sets the pending call to completed.
void _dbus_pending_call_set_timeout_added_unlocked(DBusPendingCall *pending, dbus_bool_t is_added)
Sets wether the timeout has been added.
DBusConnection * connection
Connection we&#39;d send the message to.
DBusConnection * _dbus_pending_call_get_connection_and_lock(DBusPendingCall *pending)
Gets the connection associated with this pending call.
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...
dbus_bool_t dbus_type_is_valid(int typecode)
Return TRUE if the argument is a valid typecode.
void _dbus_transport_set_max_message_unix_fds(DBusTransport *transport, long n)
See dbus_connection_set_max_message_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...
DBusHashTable * _dbus_hash_table_new(DBusHashType type, DBusFreeFunction key_free_function, DBusFreeFunction value_free_function)
Constructs a new hash table.
Definition: dbus-hash.c:286
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.
void dbus_connection_free_preallocated_send(DBusConnection *connection, DBusPreallocatedSend *preallocated)
Frees preallocated message-sending resources from dbus_connection_preallocate_send().
void dbus_message_set_serial(DBusMessage *message, dbus_uint32_t serial)
Sets the serial number of a message.
Definition: dbus-message.c:289
DBusTimeoutList implementation details.
Definition: dbus-timeout.c:180
dbus_bool_t dbus_parse_address(const char *address, DBusAddressEntry ***entry_result, int *array_len, DBusError *error)
Parses an address string of the form:
Definition: dbus-address.c:364
DBusMessage * dbus_message_new_method_return(DBusMessage *method_call)
Constructs a message that is a reply to a method call.
DBusRMutex * slot_mutex
Lock on slot_list so overall connection lock need not be taken.
void _dbus_transport_unref(DBusTransport *transport)
Decrements the reference count for the transport.
long _dbus_counter_get_unix_fd_value(DBusCounter *counter)
Gets the current value of the unix fd counter.
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...
void _dbus_list_clear(DBusList **list)
Frees all links in the list and sets the list head to NULL.
Definition: dbus-list.c:543
DBUS_EXPORT int dbus_timeout_get_interval(DBusTimeout *timeout)
Gets the timeout interval.
Definition: dbus-timeout.c:442
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...
long _dbus_counter_get_size_value(DBusCounter *counter)
Gets the current value of the size counter.
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.