D-Bus  1.8.2
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_ENABLE_SMACK
49 #include <sys/smack.h>
50 #include <stdlib.h>
51 #endif
52 
53 #ifdef DBUS_DISABLE_CHECKS
54 #define TOOK_LOCK_CHECK(connection)
55 #define RELEASING_LOCK_CHECK(connection)
56 #define HAVE_LOCK_CHECK(connection)
57 #else
58 #define TOOK_LOCK_CHECK(connection) do { \
59  _dbus_assert (!(connection)->have_connection_lock); \
60  (connection)->have_connection_lock = TRUE; \
61  } while (0)
62 #define RELEASING_LOCK_CHECK(connection) do { \
63  _dbus_assert ((connection)->have_connection_lock); \
64  (connection)->have_connection_lock = FALSE; \
65  } while (0)
66 #define HAVE_LOCK_CHECK(connection) _dbus_assert ((connection)->have_connection_lock)
67 /* A "DO_NOT_HAVE_LOCK_CHECK" is impossible since we need the lock to check the flag */
68 #endif
69 
70 #define TRACE_LOCKS 1
71 
72 #define CONNECTION_LOCK(connection) do { \
73  if (TRACE_LOCKS) { _dbus_verbose ("LOCK\n"); } \
74  _dbus_rmutex_lock ((connection)->mutex); \
75  TOOK_LOCK_CHECK (connection); \
76  } while (0)
77 
78 #define CONNECTION_UNLOCK(connection) _dbus_connection_unlock (connection)
79 
80 #define SLOTS_LOCK(connection) do { \
81  _dbus_rmutex_lock ((connection)->slot_mutex); \
82  } while (0)
83 
84 #define SLOTS_UNLOCK(connection) do { \
85  _dbus_rmutex_unlock ((connection)->slot_mutex); \
86  } while (0)
87 
88 #define DISPATCH_STATUS_NAME(s) \
89  ((s) == DBUS_DISPATCH_COMPLETE ? "complete" : \
90  (s) == DBUS_DISPATCH_DATA_REMAINS ? "data remains" : \
91  (s) == DBUS_DISPATCH_NEED_MEMORY ? "need memory" : \
92  "???")
93 
211 static void
212 _dbus_connection_trace_ref (DBusConnection *connection,
213  int old_refcount,
214  int new_refcount,
215  const char *why)
216 {
217 #ifdef DBUS_ENABLE_VERBOSE_MODE
218  static int enabled = -1;
219 
220  _dbus_trace_ref ("DBusConnection", connection, old_refcount, new_refcount,
221  why, "DBUS_CONNECTION_TRACE", &enabled);
222 #endif
223 }
224 
229 
234 {
237  void *user_data;
239 };
240 
241 
246 {
250 };
251 
252 #if HAVE_DECL_MSG_NOSIGNAL
253 static dbus_bool_t _dbus_modify_sigpipe = FALSE;
254 #else
255 static dbus_bool_t _dbus_modify_sigpipe = TRUE;
256 #endif
257 
262 {
311  char *server_guid;
312 #ifdef DBUS_ENABLE_SMACK
313  char *peer_smack_label;
314 #endif
315 
316  /* These two MUST be bools and not bitfields, because they are protected by a separate lock
317  * from connection->mutex and all bitfields in a word have to be read/written together.
318  * So you can't have a different lock for different bitfields in the same word.
319  */
323  unsigned int dispatch_disabled : 1;
324  unsigned int shareable : 1;
326  unsigned int exit_on_disconnect : 1;
328  unsigned int route_peer_messages : 1;
330  unsigned int disconnected_message_arrived : 1;
338 #ifndef DBUS_DISABLE_CHECKS
339  unsigned int have_connection_lock : 1;
340 #endif
341 
342 #if defined(DBUS_ENABLE_CHECKS) || defined(DBUS_ENABLE_ASSERT)
343  int generation;
344 #endif
345 };
346 
347 static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection);
348 static void _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
349  DBusDispatchStatus new_status);
350 static void _dbus_connection_last_unref (DBusConnection *connection);
351 static void _dbus_connection_acquire_dispatch (DBusConnection *connection);
352 static void _dbus_connection_release_dispatch (DBusConnection *connection);
353 static DBusDispatchStatus _dbus_connection_flush_unlocked (DBusConnection *connection);
354 static void _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection);
355 static dbus_bool_t _dbus_connection_get_is_connected_unlocked (DBusConnection *connection);
356 static dbus_bool_t _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection,
357  dbus_uint32_t client_serial);
358 
359 static DBusMessageFilter *
360 _dbus_message_filter_ref (DBusMessageFilter *filter)
361 {
362 #ifdef DBUS_DISABLE_ASSERT
363  _dbus_atomic_inc (&filter->refcount);
364 #else
365  dbus_int32_t old_value;
366 
367  old_value = _dbus_atomic_inc (&filter->refcount);
368  _dbus_assert (old_value > 0);
369 #endif
370 
371  return filter;
372 }
373 
374 static void
375 _dbus_message_filter_unref (DBusMessageFilter *filter)
376 {
377  dbus_int32_t old_value;
378 
379  old_value = _dbus_atomic_dec (&filter->refcount);
380  _dbus_assert (old_value > 0);
381 
382  if (old_value == 1)
383  {
384  if (filter->free_user_data_function)
385  (* filter->free_user_data_function) (filter->user_data);
386 
387  dbus_free (filter);
388  }
389 }
390 
396 void
398 {
399  CONNECTION_LOCK (connection);
400 }
401 
407 void
409 {
410  DBusList *expired_messages;
411  DBusList *iter;
412 
413  if (TRACE_LOCKS)
414  {
415  _dbus_verbose ("UNLOCK\n");
416  }
417 
418  /* If we had messages that expired (fell off the incoming or outgoing
419  * queues) while we were locked, actually release them now */
420  expired_messages = connection->expired_messages;
421  connection->expired_messages = NULL;
422 
423  RELEASING_LOCK_CHECK (connection);
424  _dbus_rmutex_unlock (connection->mutex);
425 
426  for (iter = _dbus_list_pop_first_link (&expired_messages);
427  iter != NULL;
428  iter = _dbus_list_pop_first_link (&expired_messages))
429  {
430  DBusMessage *message = iter->data;
431 
432  dbus_message_unref (message);
433  _dbus_list_free_link (iter);
434  }
435 }
436 
444 static void
445 _dbus_connection_wakeup_mainloop (DBusConnection *connection)
446 {
447  if (connection->wakeup_main_function)
448  (*connection->wakeup_main_function) (connection->wakeup_main_data);
449 }
450 
451 static void
452 _dbus_connection_set_dispatch(DBusConnection *connection,
453  dbus_bool_t disabled)
454 {
455  CONNECTION_LOCK (connection);
456  if (connection->dispatch_disabled != disabled)
457  {
458  DBusDispatchStatus status;
459 
460  connection->dispatch_disabled = disabled;
461  status = _dbus_connection_get_dispatch_status_unlocked (connection);
462  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
463  }
464  else
465  {
466  CONNECTION_UNLOCK (connection);
467  }
468 }
469 
470 
471 void
472 _dbus_connection_enable_dispatch (DBusConnection *connection)
473 {
474  _dbus_connection_set_dispatch (connection, FALSE);
475 }
476 
477 void
478  _dbus_connection_disable_dispatch (DBusConnection *connection)
479 {
480  _dbus_connection_set_dispatch (connection, TRUE);
481 }
482 
483 
484 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
485 
497 void
498 _dbus_connection_test_get_locks (DBusConnection *connection,
499  DBusMutex **mutex_loc,
500  DBusMutex **dispatch_mutex_loc,
501  DBusMutex **io_path_mutex_loc,
502  DBusCondVar **dispatch_cond_loc,
503  DBusCondVar **io_path_cond_loc)
504 {
505  *mutex_loc = (DBusMutex *) connection->mutex;
506  *dispatch_mutex_loc = (DBusMutex *) connection->dispatch_mutex;
507  *io_path_mutex_loc = (DBusMutex *) connection->io_path_mutex;
508  *dispatch_cond_loc = connection->dispatch_cond;
509  *io_path_cond_loc = connection->io_path_cond;
510 }
511 #endif
512 
521 void
523  DBusList *link)
524 {
525  DBusPendingCall *pending;
526  dbus_uint32_t reply_serial;
527  DBusMessage *message;
528 
530 
532  link);
533  message = link->data;
534 
535  /* If this is a reply we're waiting on, remove timeout for it */
536  reply_serial = dbus_message_get_reply_serial (message);
537  if (reply_serial != 0)
538  {
539  pending = _dbus_hash_table_lookup_int (connection->pending_replies,
540  reply_serial);
541  if (pending != NULL)
542  {
546 
548  }
549  }
550 
551 
552 
553  connection->n_incoming += 1;
554 
555  _dbus_connection_wakeup_mainloop (connection);
556 
557  _dbus_verbose ("Message %p (%s %s %s %s '%s' reply to %u) added to incoming queue %p, %d incoming\n",
558  message,
560  dbus_message_get_path (message) ?
561  dbus_message_get_path (message) :
562  "no path",
563  dbus_message_get_interface (message) ?
564  dbus_message_get_interface (message) :
565  "no interface",
566  dbus_message_get_member (message) ?
567  dbus_message_get_member (message) :
568  "no member",
569  dbus_message_get_signature (message),
571  connection,
572  connection->n_incoming);
573 
574  _dbus_message_trace_ref (message, -1, -1,
575  "_dbus_conection_queue_received_message_link");
576 }
577 
586 void
588  DBusList *link)
589 {
590  HAVE_LOCK_CHECK (connection);
591 
592  _dbus_list_append_link (&connection->incoming_messages, link);
593 
594  connection->n_incoming += 1;
595 
596  _dbus_connection_wakeup_mainloop (connection);
597 
598  _dbus_message_trace_ref (link->data, -1, -1,
599  "_dbus_connection_queue_synthesized_message_link");
600 
601  _dbus_verbose ("Synthesized message %p added to incoming queue %p, %d incoming\n",
602  link->data, connection, connection->n_incoming);
603 }
604 
605 
615 {
616  HAVE_LOCK_CHECK (connection);
617  return connection->outgoing_messages != NULL;
618 }
619 
631 {
632  dbus_bool_t v;
633 
634  _dbus_return_val_if_fail (connection != NULL, FALSE);
635 
636  CONNECTION_LOCK (connection);
638  CONNECTION_UNLOCK (connection);
639 
640  return v;
641 }
642 
652 {
653  HAVE_LOCK_CHECK (connection);
654 
655  return _dbus_list_get_last (&connection->outgoing_messages);
656 }
657 
666 void
668  DBusMessage *message)
669 {
670  DBusList *link;
671 
672  HAVE_LOCK_CHECK (connection);
673 
674  /* This can be called before we even complete authentication, since
675  * it's called on disconnect to clean up the outgoing queue.
676  * It's also called as we successfully send each message.
677  */
678 
679  link = _dbus_list_get_last_link (&connection->outgoing_messages);
680  _dbus_assert (link != NULL);
681  _dbus_assert (link->data == message);
682 
683  _dbus_list_unlink (&connection->outgoing_messages,
684  link);
685  _dbus_list_prepend_link (&connection->expired_messages, link);
686 
687  connection->n_outgoing -= 1;
688 
689  _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from outgoing queue %p, %d left to send\n",
690  message,
692  dbus_message_get_path (message) ?
693  dbus_message_get_path (message) :
694  "no path",
695  dbus_message_get_interface (message) ?
696  dbus_message_get_interface (message) :
697  "no interface",
698  dbus_message_get_member (message) ?
699  dbus_message_get_member (message) :
700  "no member",
701  dbus_message_get_signature (message),
702  connection, connection->n_outgoing);
703 
704  /* It's OK that in principle we call the notify function, because for the
705  * outgoing limit, there isn't one */
706  _dbus_message_remove_counter (message, connection->outgoing_counter);
707 
708  /* The message will actually be unreffed when we unlock */
709 }
710 
713  DBusWatch *watch);
715 typedef void (* DBusWatchRemoveFunction) (DBusWatchList *list,
716  DBusWatch *watch);
718 typedef void (* DBusWatchToggleFunction) (DBusWatchList *list,
719  DBusWatch *watch,
720  dbus_bool_t enabled);
721 
722 static dbus_bool_t
723 protected_change_watch (DBusConnection *connection,
724  DBusWatch *watch,
725  DBusWatchAddFunction add_function,
726  DBusWatchRemoveFunction remove_function,
727  DBusWatchToggleFunction toggle_function,
728  dbus_bool_t enabled)
729 {
730  dbus_bool_t retval;
731 
732  HAVE_LOCK_CHECK (connection);
733 
734  /* The original purpose of protected_change_watch() was to hold a
735  * ref on the connection while dropping the connection lock, then
736  * calling out to the app. This was a broken hack that did not
737  * work, since the connection was in a hosed state (no WatchList
738  * field) while calling out.
739  *
740  * So for now we'll just keep the lock while calling out. This means
741  * apps are not allowed to call DBusConnection methods inside a
742  * watch function or they will deadlock.
743  *
744  * The "real fix" is to use the _and_unlock() pattern found
745  * elsewhere in the code, to defer calling out to the app until
746  * we're about to drop locks and return flow of control to the app
747  * anyway.
748  *
749  * See http://lists.freedesktop.org/archives/dbus/2007-July/thread.html#8144
750  */
751 
752  if (connection->watches)
753  {
754  if (add_function)
755  retval = (* add_function) (connection->watches, watch);
756  else if (remove_function)
757  {
758  retval = TRUE;
759  (* remove_function) (connection->watches, watch);
760  }
761  else
762  {
763  retval = TRUE;
764  (* toggle_function) (connection->watches, watch, enabled);
765  }
766  return retval;
767  }
768  else
769  return FALSE;
770 }
771 
772 
786  DBusWatch *watch)
787 {
788  return protected_change_watch (connection, watch,
790  NULL, NULL, FALSE);
791 }
792 
802 void
804  DBusWatch *watch)
805 {
806  protected_change_watch (connection, watch,
807  NULL,
809  NULL, FALSE);
810 }
811 
822 void
824  DBusWatch *watch,
825  dbus_bool_t enabled)
826 {
827  _dbus_assert (watch != NULL);
828 
829  protected_change_watch (connection, watch,
830  NULL, NULL,
832  enabled);
833 }
834 
837  DBusTimeout *timeout);
840  DBusTimeout *timeout);
843  DBusTimeout *timeout,
844  dbus_bool_t enabled);
845 
846 static dbus_bool_t
847 protected_change_timeout (DBusConnection *connection,
848  DBusTimeout *timeout,
849  DBusTimeoutAddFunction add_function,
850  DBusTimeoutRemoveFunction remove_function,
851  DBusTimeoutToggleFunction toggle_function,
852  dbus_bool_t enabled)
853 {
854  dbus_bool_t retval;
855 
856  HAVE_LOCK_CHECK (connection);
857 
858  /* The original purpose of protected_change_timeout() was to hold a
859  * ref on the connection while dropping the connection lock, then
860  * calling out to the app. This was a broken hack that did not
861  * work, since the connection was in a hosed state (no TimeoutList
862  * field) while calling out.
863  *
864  * So for now we'll just keep the lock while calling out. This means
865  * apps are not allowed to call DBusConnection methods inside a
866  * timeout function or they will deadlock.
867  *
868  * The "real fix" is to use the _and_unlock() pattern found
869  * elsewhere in the code, to defer calling out to the app until
870  * we're about to drop locks and return flow of control to the app
871  * anyway.
872  *
873  * See http://lists.freedesktop.org/archives/dbus/2007-July/thread.html#8144
874  */
875 
876  if (connection->timeouts)
877  {
878  if (add_function)
879  retval = (* add_function) (connection->timeouts, timeout);
880  else if (remove_function)
881  {
882  retval = TRUE;
883  (* remove_function) (connection->timeouts, timeout);
884  }
885  else
886  {
887  retval = TRUE;
888  (* toggle_function) (connection->timeouts, timeout, enabled);
889  }
890  return retval;
891  }
892  else
893  return FALSE;
894 }
895 
910  DBusTimeout *timeout)
911 {
912  return protected_change_timeout (connection, timeout,
914  NULL, NULL, FALSE);
915 }
916 
926 void
928  DBusTimeout *timeout)
929 {
930  protected_change_timeout (connection, timeout,
931  NULL,
933  NULL, FALSE);
934 }
935 
946 void
948  DBusTimeout *timeout,
949  dbus_bool_t enabled)
950 {
951  protected_change_timeout (connection, timeout,
952  NULL, NULL,
954  enabled);
955 }
956 
957 static dbus_bool_t
958 _dbus_connection_attach_pending_call_unlocked (DBusConnection *connection,
959  DBusPendingCall *pending)
960 {
961  dbus_uint32_t reply_serial;
962  DBusTimeout *timeout;
963 
964  HAVE_LOCK_CHECK (connection);
965 
966  reply_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
967 
968  _dbus_assert (reply_serial != 0);
969 
970  timeout = _dbus_pending_call_get_timeout_unlocked (pending);
971 
972  if (timeout)
973  {
974  if (!_dbus_connection_add_timeout_unlocked (connection, timeout))
975  return FALSE;
976 
978  reply_serial,
979  pending))
980  {
981  _dbus_connection_remove_timeout_unlocked (connection, timeout);
982 
984  HAVE_LOCK_CHECK (connection);
985  return FALSE;
986  }
987 
989  }
990  else
991  {
993  reply_serial,
994  pending))
995  {
996  HAVE_LOCK_CHECK (connection);
997  return FALSE;
998  }
999  }
1000 
1002 
1003  HAVE_LOCK_CHECK (connection);
1004 
1005  return TRUE;
1006 }
1007 
1008 static void
1009 free_pending_call_on_hash_removal (void *data)
1010 {
1011  DBusPendingCall *pending;
1012  DBusConnection *connection;
1013 
1014  if (data == NULL)
1015  return;
1016 
1017  pending = data;
1018 
1019  connection = _dbus_pending_call_get_connection_unlocked (pending);
1020 
1021  HAVE_LOCK_CHECK (connection);
1022 
1024  {
1027 
1029  }
1030 
1031  /* FIXME 1.0? this is sort of dangerous and undesirable to drop the lock
1032  * here, but the pending call finalizer could in principle call out to
1033  * application code so we pretty much have to... some larger code reorg
1034  * might be needed.
1035  */
1036  _dbus_connection_ref_unlocked (connection);
1038  CONNECTION_LOCK (connection);
1039  _dbus_connection_unref_unlocked (connection);
1040 }
1041 
1042 static void
1043 _dbus_connection_detach_pending_call_unlocked (DBusConnection *connection,
1044  DBusPendingCall *pending)
1045 {
1046  /* This ends up unlocking to call the pending call finalizer, which is unexpected to
1047  * say the least.
1048  */
1051 }
1052 
1053 static void
1054 _dbus_connection_detach_pending_call_and_unlock (DBusConnection *connection,
1055  DBusPendingCall *pending)
1056 {
1057  /* The idea here is to avoid finalizing the pending call
1058  * with the lock held, since there's a destroy notifier
1059  * in pending call that goes out to application code.
1060  *
1061  * There's an extra unlock inside the hash table
1062  * "free pending call" function FIXME...
1063  */
1067 
1071 
1073 
1075 }
1076 
1085 void
1087  DBusPendingCall *pending)
1088 {
1089  CONNECTION_LOCK (connection);
1090  _dbus_connection_detach_pending_call_and_unlock (connection, pending);
1091 }
1092 
1102 static dbus_bool_t
1103 _dbus_connection_acquire_io_path (DBusConnection *connection,
1104  int timeout_milliseconds)
1105 {
1106  dbus_bool_t we_acquired;
1107 
1108  HAVE_LOCK_CHECK (connection);
1109 
1110  /* We don't want the connection to vanish */
1111  _dbus_connection_ref_unlocked (connection);
1112 
1113  /* We will only touch io_path_acquired which is protected by our mutex */
1114  CONNECTION_UNLOCK (connection);
1115 
1116  _dbus_verbose ("locking io_path_mutex\n");
1117  _dbus_cmutex_lock (connection->io_path_mutex);
1118 
1119  _dbus_verbose ("start connection->io_path_acquired = %d timeout = %d\n",
1120  connection->io_path_acquired, timeout_milliseconds);
1121 
1122  we_acquired = FALSE;
1123 
1124  if (connection->io_path_acquired)
1125  {
1126  if (timeout_milliseconds != -1)
1127  {
1128  _dbus_verbose ("waiting %d for IO path to be acquirable\n",
1129  timeout_milliseconds);
1130 
1131  if (!_dbus_condvar_wait_timeout (connection->io_path_cond,
1132  connection->io_path_mutex,
1133  timeout_milliseconds))
1134  {
1135  /* We timed out before anyone signaled. */
1136  /* (writing the loop to handle the !timedout case by
1137  * waiting longer if needed is a pain since dbus
1138  * wraps pthread_cond_timedwait to take a relative
1139  * time instead of absolute, something kind of stupid
1140  * on our part. for now it doesn't matter, we will just
1141  * end up back here eventually.)
1142  */
1143  }
1144  }
1145  else
1146  {
1147  while (connection->io_path_acquired)
1148  {
1149  _dbus_verbose ("waiting for IO path to be acquirable\n");
1150  _dbus_condvar_wait (connection->io_path_cond,
1151  connection->io_path_mutex);
1152  }
1153  }
1154  }
1155 
1156  if (!connection->io_path_acquired)
1157  {
1158  we_acquired = TRUE;
1159  connection->io_path_acquired = TRUE;
1160  }
1161 
1162  _dbus_verbose ("end connection->io_path_acquired = %d we_acquired = %d\n",
1163  connection->io_path_acquired, we_acquired);
1164 
1165  _dbus_verbose ("unlocking io_path_mutex\n");
1166  _dbus_cmutex_unlock (connection->io_path_mutex);
1167 
1168  CONNECTION_LOCK (connection);
1169 
1170  HAVE_LOCK_CHECK (connection);
1171 
1172  _dbus_connection_unref_unlocked (connection);
1173 
1174  return we_acquired;
1175 }
1176 
1184 static void
1185 _dbus_connection_release_io_path (DBusConnection *connection)
1186 {
1187  HAVE_LOCK_CHECK (connection);
1188 
1189  _dbus_verbose ("locking io_path_mutex\n");
1190  _dbus_cmutex_lock (connection->io_path_mutex);
1191 
1192  _dbus_assert (connection->io_path_acquired);
1193 
1194  _dbus_verbose ("start connection->io_path_acquired = %d\n",
1195  connection->io_path_acquired);
1196 
1197  connection->io_path_acquired = FALSE;
1198  _dbus_condvar_wake_one (connection->io_path_cond);
1199 
1200  _dbus_verbose ("unlocking io_path_mutex\n");
1201  _dbus_cmutex_unlock (connection->io_path_mutex);
1202 }
1203 
1239 void
1241  DBusPendingCall *pending,
1242  unsigned int flags,
1243  int timeout_milliseconds)
1244 {
1245  _dbus_verbose ("start\n");
1246 
1247  HAVE_LOCK_CHECK (connection);
1248 
1249  if (connection->n_outgoing == 0)
1250  flags &= ~DBUS_ITERATION_DO_WRITING;
1251 
1252  if (_dbus_connection_acquire_io_path (connection,
1253  (flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0))
1254  {
1255  HAVE_LOCK_CHECK (connection);
1256 
1257  if ( (pending != NULL) && _dbus_pending_call_get_completed_unlocked(pending))
1258  {
1259  _dbus_verbose ("pending call completed while acquiring I/O path");
1260  }
1261  else if ( (pending != NULL) &&
1262  _dbus_connection_peek_for_reply_unlocked (connection,
1264  {
1265  _dbus_verbose ("pending call completed while acquiring I/O path (reply found in queue)");
1266  }
1267  else
1268  {
1270  flags, timeout_milliseconds);
1271  }
1272 
1273  _dbus_connection_release_io_path (connection);
1274  }
1275 
1276  HAVE_LOCK_CHECK (connection);
1277 
1278  _dbus_verbose ("end\n");
1279 }
1280 
1292 {
1293  DBusConnection *connection;
1294  DBusWatchList *watch_list;
1295  DBusTimeoutList *timeout_list;
1296  DBusHashTable *pending_replies;
1297  DBusList *disconnect_link;
1298  DBusMessage *disconnect_message;
1299  DBusCounter *outgoing_counter;
1300  DBusObjectTree *objects;
1301 
1302  watch_list = NULL;
1303  connection = NULL;
1304  pending_replies = NULL;
1305  timeout_list = NULL;
1306  disconnect_link = NULL;
1307  disconnect_message = NULL;
1308  outgoing_counter = NULL;
1309  objects = NULL;
1310 
1311  watch_list = _dbus_watch_list_new ();
1312  if (watch_list == NULL)
1313  goto error;
1314 
1315  timeout_list = _dbus_timeout_list_new ();
1316  if (timeout_list == NULL)
1317  goto error;
1318 
1319  pending_replies =
1321  NULL,
1322  (DBusFreeFunction)free_pending_call_on_hash_removal);
1323  if (pending_replies == NULL)
1324  goto error;
1325 
1326  connection = dbus_new0 (DBusConnection, 1);
1327  if (connection == NULL)
1328  goto error;
1329 
1330 #ifdef DBUS_ENABLE_SMACK
1331  /* If we cannot get the Smack label, proceed without. */
1332  {
1333  int sock_fd;
1334  if (_dbus_transport_get_socket_fd(transport, &sock_fd)) {
1335  char *label;
1336  if (smack_new_label_from_socket(sock_fd, &label) >= 0) {
1337  connection->peer_smack_label = label;
1338  }
1339  }
1340  }
1341 #endif
1342 
1343  _dbus_rmutex_new_at_location (&connection->mutex);
1344  if (connection->mutex == NULL)
1345  goto error;
1346 
1348  if (connection->io_path_mutex == NULL)
1349  goto error;
1350 
1352  if (connection->dispatch_mutex == NULL)
1353  goto error;
1354 
1356  if (connection->dispatch_cond == NULL)
1357  goto error;
1358 
1360  if (connection->io_path_cond == NULL)
1361  goto error;
1362 
1364  if (connection->slot_mutex == NULL)
1365  goto error;
1366 
1367  disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL,
1369  "Disconnected");
1370 
1371  if (disconnect_message == NULL)
1372  goto error;
1373 
1374  disconnect_link = _dbus_list_alloc_link (disconnect_message);
1375  if (disconnect_link == NULL)
1376  goto error;
1377 
1378  outgoing_counter = _dbus_counter_new ();
1379  if (outgoing_counter == NULL)
1380  goto error;
1381 
1382  objects = _dbus_object_tree_new (connection);
1383  if (objects == NULL)
1384  goto error;
1385 
1386  if (_dbus_modify_sigpipe)
1388 
1389  /* initialized to 0: use atomic op to avoid mixing atomic and non-atomic */
1390  _dbus_atomic_inc (&connection->refcount);
1391  connection->transport = transport;
1392  connection->watches = watch_list;
1393  connection->timeouts = timeout_list;
1394  connection->pending_replies = pending_replies;
1395  connection->outgoing_counter = outgoing_counter;
1396  connection->filter_list = NULL;
1397  connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE; /* so we're notified first time there's data */
1398  connection->objects = objects;
1399  connection->exit_on_disconnect = FALSE;
1400  connection->shareable = FALSE;
1401  connection->route_peer_messages = FALSE;
1402  connection->disconnected_message_arrived = FALSE;
1403  connection->disconnected_message_processed = FALSE;
1404 
1405 #if defined(DBUS_ENABLE_CHECKS) || defined(DBUS_ENABLE_ASSERT)
1406  connection->generation = _dbus_current_generation;
1407 #endif
1408 
1409  _dbus_data_slot_list_init (&connection->slot_list);
1410 
1411  connection->client_serial = 1;
1412 
1413  connection->disconnect_message_link = disconnect_link;
1414 
1415  CONNECTION_LOCK (connection);
1416 
1417  if (!_dbus_transport_set_connection (transport, connection))
1418  {
1419  CONNECTION_UNLOCK (connection);
1420 
1421  goto error;
1422  }
1423 
1424  _dbus_transport_ref (transport);
1425 
1426  CONNECTION_UNLOCK (connection);
1427 
1428  _dbus_connection_trace_ref (connection, 0, 1, "new_for_transport");
1429  return connection;
1430 
1431  error:
1432  if (disconnect_message != NULL)
1433  dbus_message_unref (disconnect_message);
1434 
1435  if (disconnect_link != NULL)
1436  _dbus_list_free_link (disconnect_link);
1437 
1438  if (connection != NULL)
1439  {
1442  _dbus_rmutex_free_at_location (&connection->mutex);
1446  dbus_free (connection);
1447  }
1448  if (pending_replies)
1449  _dbus_hash_table_unref (pending_replies);
1450 
1451  if (watch_list)
1452  _dbus_watch_list_free (watch_list);
1453 
1454  if (timeout_list)
1455  _dbus_timeout_list_free (timeout_list);
1456 
1457  if (outgoing_counter)
1458  _dbus_counter_unref (outgoing_counter);
1459 
1460  if (objects)
1461  _dbus_object_tree_unref (objects);
1462 
1463  return NULL;
1464 }
1465 
1475 {
1476  dbus_int32_t old_refcount;
1477 
1478  _dbus_assert (connection != NULL);
1479  _dbus_assert (connection->generation == _dbus_current_generation);
1480 
1481  HAVE_LOCK_CHECK (connection);
1482 
1483  old_refcount = _dbus_atomic_inc (&connection->refcount);
1484  _dbus_connection_trace_ref (connection, old_refcount, old_refcount + 1,
1485  "ref_unlocked");
1486 
1487  return connection;
1488 }
1489 
1496 void
1498 {
1499  dbus_int32_t old_refcount;
1500 
1501  HAVE_LOCK_CHECK (connection);
1502 
1503  _dbus_assert (connection != NULL);
1504 
1505  old_refcount = _dbus_atomic_dec (&connection->refcount);
1506 
1507  _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1,
1508  "unref_unlocked");
1509 
1510  if (old_refcount == 1)
1511  _dbus_connection_last_unref (connection);
1512 }
1513 
1514 static dbus_uint32_t
1515 _dbus_connection_get_next_client_serial (DBusConnection *connection)
1516 {
1517  dbus_uint32_t serial;
1518 
1519  serial = connection->client_serial++;
1520 
1521  if (connection->client_serial == 0)
1522  connection->client_serial = 1;
1523 
1524  return serial;
1525 }
1526 
1542  unsigned int condition,
1543  void *data)
1544 {
1545  DBusConnection *connection;
1546  dbus_bool_t retval;
1547  DBusDispatchStatus status;
1548 
1549  connection = data;
1550 
1551  _dbus_verbose ("start\n");
1552 
1553  CONNECTION_LOCK (connection);
1554 
1555  if (!_dbus_connection_acquire_io_path (connection, 1))
1556  {
1557  /* another thread is handling the message */
1558  CONNECTION_UNLOCK (connection);
1559  return TRUE;
1560  }
1561 
1562  HAVE_LOCK_CHECK (connection);
1563  retval = _dbus_transport_handle_watch (connection->transport,
1564  watch, condition);
1565 
1566  _dbus_connection_release_io_path (connection);
1567 
1568  HAVE_LOCK_CHECK (connection);
1569 
1570  _dbus_verbose ("middle\n");
1571 
1572  status = _dbus_connection_get_dispatch_status_unlocked (connection);
1573 
1574  /* this calls out to user code */
1575  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
1576 
1577  _dbus_verbose ("end\n");
1578 
1579  return retval;
1580 }
1581 
1582 /* Protected by _DBUS_LOCK (shared_connections) */
1583 static DBusHashTable *shared_connections = NULL;
1584 static DBusList *shared_connections_no_guid = NULL;
1585 
1586 static void
1587 close_connection_on_shutdown (DBusConnection *connection)
1588 {
1589  DBusMessage *message;
1590 
1591  dbus_connection_ref (connection);
1593 
1594  /* Churn through to the Disconnected message */
1595  while ((message = dbus_connection_pop_message (connection)))
1596  {
1597  dbus_message_unref (message);
1598  }
1599  dbus_connection_unref (connection);
1600 }
1601 
1602 static void
1603 shared_connections_shutdown (void *data)
1604 {
1605  int n_entries;
1606 
1607  if (!_DBUS_LOCK (shared_connections))
1608  {
1609  /* We'd have initialized locks before adding anything, so there
1610  * can't be anything there. */
1611  return;
1612  }
1613 
1614  /* This is a little bit unpleasant... better ideas? */
1615  while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0)
1616  {
1617  DBusConnection *connection;
1618  DBusHashIter iter;
1619 
1620  _dbus_hash_iter_init (shared_connections, &iter);
1621  _dbus_hash_iter_next (&iter);
1622 
1623  connection = _dbus_hash_iter_get_value (&iter);
1624 
1625  _DBUS_UNLOCK (shared_connections);
1626  close_connection_on_shutdown (connection);
1627  if (!_DBUS_LOCK (shared_connections))
1628  _dbus_assert_not_reached ("global locks were already initialized");
1629 
1630  /* The connection should now be dead and not in our hash ... */
1631  _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) < n_entries);
1632  }
1633 
1634  _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) == 0);
1635 
1636  _dbus_hash_table_unref (shared_connections);
1637  shared_connections = NULL;
1638 
1639  if (shared_connections_no_guid != NULL)
1640  {
1641  DBusConnection *connection;
1642  connection = _dbus_list_pop_first (&shared_connections_no_guid);
1643  while (connection != NULL)
1644  {
1645  _DBUS_UNLOCK (shared_connections);
1646  close_connection_on_shutdown (connection);
1647  if (!_DBUS_LOCK (shared_connections))
1648  _dbus_assert_not_reached ("global locks were already initialized");
1649  connection = _dbus_list_pop_first (&shared_connections_no_guid);
1650  }
1651  }
1652 
1653  shared_connections_no_guid = NULL;
1654 
1655  _DBUS_UNLOCK (shared_connections);
1656 }
1657 
1658 static dbus_bool_t
1659 connection_lookup_shared (DBusAddressEntry *entry,
1660  DBusConnection **result)
1661 {
1662  _dbus_verbose ("checking for existing connection\n");
1663 
1664  *result = NULL;
1665 
1666  if (!_DBUS_LOCK (shared_connections))
1667  {
1668  /* If it was shared, we'd have initialized global locks when we put
1669  * it in shared_connections. */
1670  return FALSE;
1671  }
1672 
1673  if (shared_connections == NULL)
1674  {
1675  _dbus_verbose ("creating shared_connections hash table\n");
1676 
1677  shared_connections = _dbus_hash_table_new (DBUS_HASH_STRING,
1678  dbus_free,
1679  NULL);
1680  if (shared_connections == NULL)
1681  {
1682  _DBUS_UNLOCK (shared_connections);
1683  return FALSE;
1684  }
1685 
1686  if (!_dbus_register_shutdown_func (shared_connections_shutdown, NULL))
1687  {
1688  _dbus_hash_table_unref (shared_connections);
1689  shared_connections = NULL;
1690  _DBUS_UNLOCK (shared_connections);
1691  return FALSE;
1692  }
1693 
1694  _dbus_verbose (" successfully created shared_connections\n");
1695 
1696  _DBUS_UNLOCK (shared_connections);
1697  return TRUE; /* no point looking up in the hash we just made */
1698  }
1699  else
1700  {
1701  const char *guid;
1702 
1703  guid = dbus_address_entry_get_value (entry, "guid");
1704 
1705  if (guid != NULL)
1706  {
1707  DBusConnection *connection;
1708 
1709  connection = _dbus_hash_table_lookup_string (shared_connections,
1710  guid);
1711 
1712  if (connection)
1713  {
1714  /* The DBusConnection can't be finalized without taking
1715  * the shared_connections lock to remove it from the
1716  * hash. So it's safe to ref the connection here.
1717  * However, it may be disconnected if the Disconnected
1718  * message hasn't been processed yet, in which case we
1719  * want to pretend it isn't in the hash and avoid
1720  * returning it.
1721  *
1722  * The idea is to avoid ever returning a disconnected connection
1723  * from dbus_connection_open(). We could just synchronously
1724  * drop our shared ref to the connection on connection disconnect,
1725  * and then assert here that the connection is connected, but
1726  * that causes reentrancy headaches.
1727  */
1728  CONNECTION_LOCK (connection);
1729  if (_dbus_connection_get_is_connected_unlocked (connection))
1730  {
1731  _dbus_connection_ref_unlocked (connection);
1732  *result = connection;
1733  _dbus_verbose ("looked up existing connection to server guid %s\n",
1734  guid);
1735  }
1736  else
1737  {
1738  _dbus_verbose ("looked up existing connection to server guid %s but it was disconnected so ignoring it\n",
1739  guid);
1740  }
1741  CONNECTION_UNLOCK (connection);
1742  }
1743  }
1744 
1745  _DBUS_UNLOCK (shared_connections);
1746  return TRUE;
1747  }
1748 }
1749 
1750 static dbus_bool_t
1751 connection_record_shared_unlocked (DBusConnection *connection,
1752  const char *guid)
1753 {
1754  char *guid_key;
1755  char *guid_in_connection;
1756 
1757  HAVE_LOCK_CHECK (connection);
1758  _dbus_assert (connection->server_guid == NULL);
1759  _dbus_assert (connection->shareable);
1760 
1761  /* get a hard ref on this connection, even if
1762  * we won't in fact store it in the hash, we still
1763  * need to hold a ref on it until it's disconnected.
1764  */
1765  _dbus_connection_ref_unlocked (connection);
1766 
1767  if (guid == NULL)
1768  {
1769  if (!_DBUS_LOCK (shared_connections))
1770  return FALSE;
1771 
1772  if (!_dbus_list_prepend (&shared_connections_no_guid, connection))
1773  {
1774  _DBUS_UNLOCK (shared_connections);
1775  return FALSE;
1776  }
1777 
1778  _DBUS_UNLOCK (shared_connections);
1779  return TRUE; /* don't store in the hash */
1780  }
1781 
1782  /* A separate copy of the key is required in the hash table, because
1783  * we don't have a lock on the connection when we are doing a hash
1784  * lookup.
1785  */
1786 
1787  guid_key = _dbus_strdup (guid);
1788  if (guid_key == NULL)
1789  return FALSE;
1790 
1791  guid_in_connection = _dbus_strdup (guid);
1792  if (guid_in_connection == NULL)
1793  {
1794  dbus_free (guid_key);
1795  return FALSE;
1796  }
1797 
1798  if (!_DBUS_LOCK (shared_connections))
1799  {
1800  dbus_free (guid_in_connection);
1801  dbus_free (guid_key);
1802  return FALSE;
1803  }
1804 
1805  _dbus_assert (shared_connections != NULL);
1806 
1807  if (!_dbus_hash_table_insert_string (shared_connections,
1808  guid_key, connection))
1809  {
1810  dbus_free (guid_key);
1811  dbus_free (guid_in_connection);
1812  _DBUS_UNLOCK (shared_connections);
1813  return FALSE;
1814  }
1815 
1816  connection->server_guid = guid_in_connection;
1817 
1818  _dbus_verbose ("stored connection to %s to be shared\n",
1819  connection->server_guid);
1820 
1821  _DBUS_UNLOCK (shared_connections);
1822 
1823  _dbus_assert (connection->server_guid != NULL);
1824 
1825  return TRUE;
1826 }
1827 
1828 static void
1829 connection_forget_shared_unlocked (DBusConnection *connection)
1830 {
1831  HAVE_LOCK_CHECK (connection);
1832 
1833  if (!connection->shareable)
1834  return;
1835 
1836  if (!_DBUS_LOCK (shared_connections))
1837  {
1838  /* If it was shared, we'd have initialized global locks when we put
1839  * it in the table; so it can't be there. */
1840  return;
1841  }
1842 
1843  if (connection->server_guid != NULL)
1844  {
1845  _dbus_verbose ("dropping connection to %s out of the shared table\n",
1846  connection->server_guid);
1847 
1848  if (!_dbus_hash_table_remove_string (shared_connections,
1849  connection->server_guid))
1850  _dbus_assert_not_reached ("connection was not in the shared table");
1851 
1852  dbus_free (connection->server_guid);
1853  connection->server_guid = NULL;
1854  }
1855  else
1856  {
1857  _dbus_list_remove (&shared_connections_no_guid, connection);
1858  }
1859 
1860  _DBUS_UNLOCK (shared_connections);
1861 
1862  /* remove our reference held on all shareable connections */
1863  _dbus_connection_unref_unlocked (connection);
1864 }
1865 
1866 static DBusConnection*
1867 connection_try_from_address_entry (DBusAddressEntry *entry,
1868  DBusError *error)
1869 {
1870  DBusTransport *transport;
1871  DBusConnection *connection;
1872 
1873  transport = _dbus_transport_open (entry, error);
1874 
1875  if (transport == NULL)
1876  {
1877  _DBUS_ASSERT_ERROR_IS_SET (error);
1878  return NULL;
1879  }
1880 
1881  connection = _dbus_connection_new_for_transport (transport);
1882 
1883  _dbus_transport_unref (transport);
1884 
1885  if (connection == NULL)
1886  {
1887  _DBUS_SET_OOM (error);
1888  return NULL;
1889  }
1890 
1891 #ifndef DBUS_DISABLE_CHECKS
1892  _dbus_assert (!connection->have_connection_lock);
1893 #endif
1894  return connection;
1895 }
1896 
1897 /*
1898  * If the shared parameter is true, then any existing connection will
1899  * be used (and if a new connection is created, it will be available
1900  * for use by others). If the shared parameter is false, a new
1901  * connection will always be created, and the new connection will
1902  * never be returned to other callers.
1903  *
1904  * @param address the address
1905  * @param shared whether the connection is shared or private
1906  * @param error error return
1907  * @returns the connection or #NULL on error
1908  */
1909 static DBusConnection*
1910 _dbus_connection_open_internal (const char *address,
1911  dbus_bool_t shared,
1912  DBusError *error)
1913 {
1914  DBusConnection *connection;
1915  DBusAddressEntry **entries;
1916  DBusError tmp_error = DBUS_ERROR_INIT;
1917  DBusError first_error = DBUS_ERROR_INIT;
1918  int len, i;
1919 
1920  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1921 
1922  _dbus_verbose ("opening %s connection to: %s\n",
1923  shared ? "shared" : "private", address);
1924 
1925  if (!dbus_parse_address (address, &entries, &len, error))
1926  return NULL;
1927 
1928  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1929 
1930  connection = NULL;
1931 
1932  for (i = 0; i < len; i++)
1933  {
1934  if (shared)
1935  {
1936  if (!connection_lookup_shared (entries[i], &connection))
1937  _DBUS_SET_OOM (&tmp_error);
1938  }
1939 
1940  if (connection == NULL)
1941  {
1942  connection = connection_try_from_address_entry (entries[i],
1943  &tmp_error);
1944 
1945  if (connection != NULL && shared)
1946  {
1947  const char *guid;
1948 
1949  connection->shareable = TRUE;
1950 
1951  /* guid may be NULL */
1952  guid = dbus_address_entry_get_value (entries[i], "guid");
1953 
1954  CONNECTION_LOCK (connection);
1955 
1956  if (!connection_record_shared_unlocked (connection, guid))
1957  {
1958  _DBUS_SET_OOM (&tmp_error);
1959  _dbus_connection_close_possibly_shared_and_unlock (connection);
1960  dbus_connection_unref (connection);
1961  connection = NULL;
1962  }
1963  else
1964  CONNECTION_UNLOCK (connection);
1965  }
1966  }
1967 
1968  if (connection)
1969  break;
1970 
1971  _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
1972 
1973  if (i == 0)
1974  dbus_move_error (&tmp_error, &first_error);
1975  else
1976  dbus_error_free (&tmp_error);
1977  }
1978 
1979  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1980  _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
1981 
1982  if (connection == NULL)
1983  {
1984  _DBUS_ASSERT_ERROR_IS_SET (&first_error);
1985  dbus_move_error (&first_error, error);
1986  }
1987  else
1988  dbus_error_free (&first_error);
1989 
1990  dbus_address_entries_free (entries);
1991  return connection;
1992 }
1993 
2002 void
2004 {
2005  _dbus_assert (connection != NULL);
2006  _dbus_assert (connection->generation == _dbus_current_generation);
2007 
2008  CONNECTION_LOCK (connection);
2009  _dbus_connection_close_possibly_shared_and_unlock (connection);
2010 }
2011 
2012 static DBusPreallocatedSend*
2013 _dbus_connection_preallocate_send_unlocked (DBusConnection *connection)
2014 {
2015  DBusPreallocatedSend *preallocated;
2016 
2017  HAVE_LOCK_CHECK (connection);
2018 
2019  _dbus_assert (connection != NULL);
2020 
2021  preallocated = dbus_new (DBusPreallocatedSend, 1);
2022  if (preallocated == NULL)
2023  return NULL;
2024 
2025  preallocated->queue_link = _dbus_list_alloc_link (NULL);
2026  if (preallocated->queue_link == NULL)
2027  goto failed_0;
2028 
2029  preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter);
2030  if (preallocated->counter_link == NULL)
2031  goto failed_1;
2032 
2033  _dbus_counter_ref (preallocated->counter_link->data);
2034 
2035  preallocated->connection = connection;
2036 
2037  return preallocated;
2038 
2039  failed_1:
2040  _dbus_list_free_link (preallocated->queue_link);
2041  failed_0:
2042  dbus_free (preallocated);
2043 
2044  return NULL;
2045 }
2046 
2047 /* Called with lock held, does not update dispatch status */
2048 static void
2049 _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *connection,
2050  DBusPreallocatedSend *preallocated,
2051  DBusMessage *message,
2052  dbus_uint32_t *client_serial)
2053 {
2054  dbus_uint32_t serial;
2055 
2056  preallocated->queue_link->data = message;
2058  preallocated->queue_link);
2059 
2060  /* It's OK that we'll never call the notify function, because for the
2061  * outgoing limit, there isn't one */
2063  preallocated->counter_link);
2064 
2065  dbus_free (preallocated);
2066  preallocated = NULL;
2067 
2068  dbus_message_ref (message);
2069 
2070  connection->n_outgoing += 1;
2071 
2072  _dbus_verbose ("Message %p (%s %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
2073  message,
2075  dbus_message_get_path (message) ?
2076  dbus_message_get_path (message) :
2077  "no path",
2078  dbus_message_get_interface (message) ?
2079  dbus_message_get_interface (message) :
2080  "no interface",
2081  dbus_message_get_member (message) ?
2082  dbus_message_get_member (message) :
2083  "no member",
2084  dbus_message_get_signature (message),
2085  dbus_message_get_destination (message) ?
2086  dbus_message_get_destination (message) :
2087  "null",
2088  connection,
2089  connection->n_outgoing);
2090 
2091  if (dbus_message_get_serial (message) == 0)
2092  {
2093  serial = _dbus_connection_get_next_client_serial (connection);
2094  dbus_message_set_serial (message, serial);
2095  if (client_serial)
2096  *client_serial = serial;
2097  }
2098  else
2099  {
2100  if (client_serial)
2101  *client_serial = dbus_message_get_serial (message);
2102  }
2103 
2104  _dbus_verbose ("Message %p serial is %u\n",
2105  message, dbus_message_get_serial (message));
2106 
2107  dbus_message_lock (message);
2108 
2109  /* Now we need to run an iteration to hopefully just write the messages
2110  * out immediately, and otherwise get them queued up
2111  */
2113  NULL,
2114  DBUS_ITERATION_DO_WRITING,
2115  -1);
2116 
2117  /* If stuff is still queued up, be sure we wake up the main loop */
2118  if (connection->n_outgoing > 0)
2119  _dbus_connection_wakeup_mainloop (connection);
2120 }
2121 
2122 static void
2123 _dbus_connection_send_preallocated_and_unlock (DBusConnection *connection,
2124  DBusPreallocatedSend *preallocated,
2125  DBusMessage *message,
2126  dbus_uint32_t *client_serial)
2127 {
2128  DBusDispatchStatus status;
2129 
2130  HAVE_LOCK_CHECK (connection);
2131 
2132  _dbus_connection_send_preallocated_unlocked_no_update (connection,
2133  preallocated,
2134  message, client_serial);
2135 
2136  _dbus_verbose ("middle\n");
2137  status = _dbus_connection_get_dispatch_status_unlocked (connection);
2138 
2139  /* this calls out to user code */
2140  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2141 }
2142 
2154  DBusMessage *message,
2155  dbus_uint32_t *client_serial)
2156 {
2157  DBusPreallocatedSend *preallocated;
2158 
2159  _dbus_assert (connection != NULL);
2160  _dbus_assert (message != NULL);
2161 
2162  preallocated = _dbus_connection_preallocate_send_unlocked (connection);
2163  if (preallocated == NULL)
2164  {
2165  CONNECTION_UNLOCK (connection);
2166  return FALSE;
2167  }
2168 
2169  _dbus_connection_send_preallocated_and_unlock (connection,
2170  preallocated,
2171  message,
2172  client_serial);
2173  return TRUE;
2174 }
2175 
2200 void
2202 {
2203  dbus_int32_t refcount;
2204 
2205  CONNECTION_LOCK (connection);
2206 
2207  refcount = _dbus_atomic_get (&connection->refcount);
2208  /* The caller should have at least one ref */
2209  _dbus_assert (refcount >= 1);
2210 
2211  if (refcount == 1)
2212  _dbus_connection_close_possibly_shared_and_unlock (connection);
2213  else
2214  CONNECTION_UNLOCK (connection);
2215 }
2216 
2217 
2227 static void
2228 _dbus_memory_pause_based_on_timeout (int timeout_milliseconds)
2229 {
2230  if (timeout_milliseconds == -1)
2231  _dbus_sleep_milliseconds (1000);
2232  else if (timeout_milliseconds < 100)
2233  ; /* just busy loop */
2234  else if (timeout_milliseconds <= 1000)
2235  _dbus_sleep_milliseconds (timeout_milliseconds / 3);
2236  else
2237  _dbus_sleep_milliseconds (1000);
2238 }
2239 
2240 static DBusMessage *
2241 generate_local_error_message (dbus_uint32_t serial,
2242  char *error_name,
2243  char *error_msg)
2244 {
2245  DBusMessage *message;
2247  if (!message)
2248  goto out;
2249 
2250  if (!dbus_message_set_error_name (message, error_name))
2251  {
2252  dbus_message_unref (message);
2253  message = NULL;
2254  goto out;
2255  }
2256 
2257  dbus_message_set_no_reply (message, TRUE);
2258 
2259  if (!dbus_message_set_reply_serial (message,
2260  serial))
2261  {
2262  dbus_message_unref (message);
2263  message = NULL;
2264  goto out;
2265  }
2266 
2267  if (error_msg != NULL)
2268  {
2269  DBusMessageIter iter;
2270 
2271  dbus_message_iter_init_append (message, &iter);
2272  if (!dbus_message_iter_append_basic (&iter,
2274  &error_msg))
2275  {
2276  dbus_message_unref (message);
2277  message = NULL;
2278  goto out;
2279  }
2280  }
2281 
2282  out:
2283  return message;
2284 }
2285 
2286 /*
2287  * Peek the incoming queue to see if we got reply for a specific serial
2288  */
2289 static dbus_bool_t
2290 _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection,
2291  dbus_uint32_t client_serial)
2292 {
2293  DBusList *link;
2294  HAVE_LOCK_CHECK (connection);
2295 
2296  link = _dbus_list_get_first_link (&connection->incoming_messages);
2297 
2298  while (link != NULL)
2299  {
2300  DBusMessage *reply = link->data;
2301 
2302  if (dbus_message_get_reply_serial (reply) == client_serial)
2303  {
2304  _dbus_verbose ("%s reply to %d found in queue\n", _DBUS_FUNCTION_NAME, client_serial);
2305  return TRUE;
2306  }
2307  link = _dbus_list_get_next_link (&connection->incoming_messages, link);
2308  }
2309 
2310  return FALSE;
2311 }
2312 
2313 /* This is slightly strange since we can pop a message here without
2314  * the dispatch lock.
2315  */
2316 static DBusMessage*
2317 check_for_reply_unlocked (DBusConnection *connection,
2318  dbus_uint32_t client_serial)
2319 {
2320  DBusList *link;
2321 
2322  HAVE_LOCK_CHECK (connection);
2323 
2324  link = _dbus_list_get_first_link (&connection->incoming_messages);
2325 
2326  while (link != NULL)
2327  {
2328  DBusMessage *reply = link->data;
2329 
2330  if (dbus_message_get_reply_serial (reply) == client_serial)
2331  {
2332  _dbus_list_remove_link (&connection->incoming_messages, link);
2333  connection->n_incoming -= 1;
2334  return reply;
2335  }
2336  link = _dbus_list_get_next_link (&connection->incoming_messages, link);
2337  }
2338 
2339  return NULL;
2340 }
2341 
2342 static void
2343 connection_timeout_and_complete_all_pending_calls_unlocked (DBusConnection *connection)
2344 {
2345  /* We can't iterate over the hash in the normal way since we'll be
2346  * dropping the lock for each item. So we restart the
2347  * iter each time as we drain the hash table.
2348  */
2349 
2350  while (_dbus_hash_table_get_n_entries (connection->pending_replies) > 0)
2351  {
2352  DBusPendingCall *pending;
2353  DBusHashIter iter;
2354 
2355  _dbus_hash_iter_init (connection->pending_replies, &iter);
2356  _dbus_hash_iter_next (&iter);
2357 
2358  pending = _dbus_hash_iter_get_value (&iter);
2360 
2362  connection);
2363 
2369 
2371  CONNECTION_LOCK (connection);
2372  }
2373  HAVE_LOCK_CHECK (connection);
2374 }
2375 
2376 static void
2377 complete_pending_call_and_unlock (DBusConnection *connection,
2378  DBusPendingCall *pending,
2379  DBusMessage *message)
2380 {
2381  _dbus_pending_call_set_reply_unlocked (pending, message);
2382  _dbus_pending_call_ref_unlocked (pending); /* in case there's no app with a ref held */
2383  _dbus_connection_detach_pending_call_and_unlock (connection, pending);
2384 
2385  /* Must be called unlocked since it invokes app callback */
2386  _dbus_pending_call_complete (pending);
2387  dbus_pending_call_unref (pending);
2388 }
2389 
2390 static dbus_bool_t
2391 check_for_reply_and_update_dispatch_unlocked (DBusConnection *connection,
2392  DBusPendingCall *pending)
2393 {
2394  DBusMessage *reply;
2395  DBusDispatchStatus status;
2396 
2397  reply = check_for_reply_unlocked (connection,
2399  if (reply != NULL)
2400  {
2401  _dbus_verbose ("checked for reply\n");
2402 
2403  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
2404 
2405  complete_pending_call_and_unlock (connection, pending, reply);
2406  dbus_message_unref (reply);
2407 
2408  CONNECTION_LOCK (connection);
2409  status = _dbus_connection_get_dispatch_status_unlocked (connection);
2410  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2411  dbus_pending_call_unref (pending);
2412 
2413  return TRUE;
2414  }
2415 
2416  return FALSE;
2417 }
2418 
2433 void
2435 {
2436  long start_tv_sec, start_tv_usec;
2437  long tv_sec, tv_usec;
2438  DBusDispatchStatus status;
2439  DBusConnection *connection;
2440  dbus_uint32_t client_serial;
2441  DBusTimeout *timeout;
2442  int timeout_milliseconds, elapsed_milliseconds;
2443 
2444  _dbus_assert (pending != NULL);
2445 
2446  if (dbus_pending_call_get_completed (pending))
2447  return;
2448 
2449  dbus_pending_call_ref (pending); /* necessary because the call could be canceled */
2450 
2451  connection = _dbus_pending_call_get_connection_and_lock (pending);
2452 
2453  /* Flush message queue - note, can affect dispatch status */
2454  _dbus_connection_flush_unlocked (connection);
2455 
2456  client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
2457 
2458  /* note that timeout_milliseconds is limited to a smallish value
2459  * in _dbus_pending_call_new() so overflows aren't possible
2460  * below
2461  */
2462  timeout = _dbus_pending_call_get_timeout_unlocked (pending);
2463  _dbus_get_monotonic_time (&start_tv_sec, &start_tv_usec);
2464  if (timeout)
2465  {
2466  timeout_milliseconds = dbus_timeout_get_interval (timeout);
2467 
2468  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec\n",
2469  timeout_milliseconds,
2470  client_serial,
2471  start_tv_sec, start_tv_usec);
2472  }
2473  else
2474  {
2475  timeout_milliseconds = -1;
2476 
2477  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block for reply serial %u\n", client_serial);
2478  }
2479 
2480  /* check to see if we already got the data off the socket */
2481  /* from another blocked pending call */
2482  if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
2483  return;
2484 
2485  /* Now we wait... */
2486  /* always block at least once as we know we don't have the reply yet */
2488  pending,
2489  DBUS_ITERATION_DO_READING |
2490  DBUS_ITERATION_BLOCK,
2491  timeout_milliseconds);
2492 
2493  recheck_status:
2494 
2495  _dbus_verbose ("top of recheck\n");
2496 
2497  HAVE_LOCK_CHECK (connection);
2498 
2499  /* queue messages and get status */
2500 
2501  status = _dbus_connection_get_dispatch_status_unlocked (connection);
2502 
2503  /* the get_completed() is in case a dispatch() while we were blocking
2504  * got the reply instead of us.
2505  */
2507  {
2508  _dbus_verbose ("Pending call completed by dispatch\n");
2509  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2510  dbus_pending_call_unref (pending);
2511  return;
2512  }
2513 
2514  if (status == DBUS_DISPATCH_DATA_REMAINS)
2515  {
2516  if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
2517  return;
2518  }
2519 
2520  _dbus_get_monotonic_time (&tv_sec, &tv_usec);
2521  elapsed_milliseconds = (tv_sec - start_tv_sec) * 1000 +
2522  (tv_usec - start_tv_usec) / 1000;
2523 
2524  if (!_dbus_connection_get_is_connected_unlocked (connection))
2525  {
2526  DBusMessage *error_msg;
2527 
2528  error_msg = generate_local_error_message (client_serial,
2530  "Connection was disconnected before a reply was received");
2531 
2532  /* on OOM error_msg is set to NULL */
2533  complete_pending_call_and_unlock (connection, pending, error_msg);
2534  dbus_pending_call_unref (pending);
2535  return;
2536  }
2537  else if (connection->disconnect_message_link == NULL)
2538  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
2539  else if (timeout == NULL)
2540  {
2541  if (status == DBUS_DISPATCH_NEED_MEMORY)
2542  {
2543  /* Try sleeping a bit, as we aren't sure we need to block for reading,
2544  * we may already have a reply in the buffer and just can't process
2545  * it.
2546  */
2547  _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
2548 
2549  _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
2550  }
2551  else
2552  {
2553  /* block again, we don't have the reply buffered yet. */
2555  pending,
2556  DBUS_ITERATION_DO_READING |
2557  DBUS_ITERATION_BLOCK,
2558  timeout_milliseconds - elapsed_milliseconds);
2559  }
2560 
2561  goto recheck_status;
2562  }
2563  else if (tv_sec < start_tv_sec)
2564  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
2565  else if (elapsed_milliseconds < timeout_milliseconds)
2566  {
2567  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds - elapsed_milliseconds);
2568 
2569  if (status == DBUS_DISPATCH_NEED_MEMORY)
2570  {
2571  /* Try sleeping a bit, as we aren't sure we need to block for reading,
2572  * we may already have a reply in the buffer and just can't process
2573  * it.
2574  */
2575  _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
2576 
2577  _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
2578  }
2579  else
2580  {
2581  /* block again, we don't have the reply buffered yet. */
2583  NULL,
2584  DBUS_ITERATION_DO_READING |
2585  DBUS_ITERATION_BLOCK,
2586  timeout_milliseconds - elapsed_milliseconds);
2587  }
2588 
2589  goto recheck_status;
2590  }
2591 
2592  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %d milliseconds and got no reply\n",
2593  elapsed_milliseconds);
2594 
2596 
2597  /* unlock and call user code */
2598  complete_pending_call_and_unlock (connection, pending, NULL);
2599 
2600  /* update user code on dispatch status */
2601  CONNECTION_LOCK (connection);
2602  status = _dbus_connection_get_dispatch_status_unlocked (connection);
2603  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2604  dbus_pending_call_unref (pending);
2605 }
2606 
2644 dbus_connection_open (const char *address,
2645  DBusError *error)
2646 {
2647  DBusConnection *connection;
2648 
2649  _dbus_return_val_if_fail (address != NULL, NULL);
2650  _dbus_return_val_if_error_is_set (error, NULL);
2651 
2652  connection = _dbus_connection_open_internal (address,
2653  TRUE,
2654  error);
2655 
2656  return connection;
2657 }
2658 
2687 dbus_connection_open_private (const char *address,
2688  DBusError *error)
2689 {
2690  DBusConnection *connection;
2691 
2692  _dbus_return_val_if_fail (address != NULL, NULL);
2693  _dbus_return_val_if_error_is_set (error, NULL);
2694 
2695  connection = _dbus_connection_open_internal (address,
2696  FALSE,
2697  error);
2698 
2699  return connection;
2700 }
2701 
2710 {
2711  dbus_int32_t old_refcount;
2712 
2713  _dbus_return_val_if_fail (connection != NULL, NULL);
2714  _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
2715  old_refcount = _dbus_atomic_inc (&connection->refcount);
2716  _dbus_connection_trace_ref (connection, old_refcount, old_refcount + 1,
2717  "ref");
2718 
2719  return connection;
2720 }
2721 
2722 static void
2723 free_outgoing_message (void *element,
2724  void *data)
2725 {
2726  DBusMessage *message = element;
2727  DBusConnection *connection = data;
2728 
2729  _dbus_message_remove_counter (message, connection->outgoing_counter);
2730  dbus_message_unref (message);
2731 }
2732 
2733 /* This is run without the mutex held, but after the last reference
2734  * to the connection has been dropped we should have no thread-related
2735  * problems
2736  */
2737 static void
2738 _dbus_connection_last_unref (DBusConnection *connection)
2739 {
2740  DBusList *link;
2741 
2742  _dbus_verbose ("Finalizing connection %p\n", connection);
2743 
2744  _dbus_assert (_dbus_atomic_get (&connection->refcount) == 0);
2745 
2746  /* You have to disconnect the connection before unref:ing it. Otherwise
2747  * you won't get the disconnected message.
2748  */
2750  _dbus_assert (connection->server_guid == NULL);
2751 
2752  /* ---- We're going to call various application callbacks here, hope it doesn't break anything... */
2754 
2759 
2760  _dbus_watch_list_free (connection->watches);
2761  connection->watches = NULL;
2762 
2763  _dbus_timeout_list_free (connection->timeouts);
2764  connection->timeouts = NULL;
2765 
2766  _dbus_data_slot_list_free (&connection->slot_list);
2767 
2768  link = _dbus_list_get_first_link (&connection->filter_list);
2769  while (link != NULL)
2770  {
2771  DBusMessageFilter *filter = link->data;
2772  DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
2773 
2774  filter->function = NULL;
2775  _dbus_message_filter_unref (filter); /* calls app callback */
2776  link->data = NULL;
2777 
2778  link = next;
2779  }
2780  _dbus_list_clear (&connection->filter_list);
2781 
2782  /* ---- Done with stuff that invokes application callbacks */
2783 
2784  _dbus_object_tree_unref (connection->objects);
2785 
2787  connection->pending_replies = NULL;
2788 
2789  _dbus_list_clear (&connection->filter_list);
2790 
2791  _dbus_list_foreach (&connection->outgoing_messages,
2792  free_outgoing_message,
2793  connection);
2794  _dbus_list_clear (&connection->outgoing_messages);
2795 
2796  _dbus_list_foreach (&connection->incoming_messages,
2798  NULL);
2799  _dbus_list_clear (&connection->incoming_messages);
2800 
2801  _dbus_counter_unref (connection->outgoing_counter);
2802 
2803  _dbus_transport_unref (connection->transport);
2804 
2805  if (connection->disconnect_message_link)
2806  {
2807  DBusMessage *message = connection->disconnect_message_link->data;
2808  dbus_message_unref (message);
2810  }
2811 
2814 
2817 
2819 
2820  _dbus_rmutex_free_at_location (&connection->mutex);
2821 
2822 #ifdef DBUS_ENABLE_SMACK
2823  if (connection->peer_smack_label)
2824  free (connection->peer_smack_label);
2825 #endif
2826 
2827  dbus_free (connection);
2828 }
2829 
2849 void
2851 {
2852  dbus_int32_t old_refcount;
2853 
2854  _dbus_return_if_fail (connection != NULL);
2855  _dbus_return_if_fail (connection->generation == _dbus_current_generation);
2856 
2857  old_refcount = _dbus_atomic_dec (&connection->refcount);
2858 
2859  _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1,
2860  "unref");
2861 
2862  if (old_refcount == 1)
2863  {
2864 #ifndef DBUS_DISABLE_CHECKS
2865  if (_dbus_transport_get_is_connected (connection->transport))
2866  {
2867  _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",
2868  connection->shareable ?
2869  "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" :
2870  "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n");
2871  return;
2872  }
2873 #endif
2874  _dbus_connection_last_unref (connection);
2875  }
2876 }
2877 
2878 /*
2879  * Note that the transport can disconnect itself (other end drops us)
2880  * and in that case this function never runs. So this function must
2881  * not do anything more than disconnect the transport and update the
2882  * dispatch status.
2883  *
2884  * If the transport self-disconnects, then we assume someone will
2885  * dispatch the connection to cause the dispatch status update.
2886  */
2887 static void
2888 _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection)
2889 {
2890  DBusDispatchStatus status;
2891 
2892  HAVE_LOCK_CHECK (connection);
2893 
2894  _dbus_verbose ("Disconnecting %p\n", connection);
2895 
2896  /* We need to ref because update_dispatch_status_and_unlock will unref
2897  * the connection if it was shared and libdbus was the only remaining
2898  * refcount holder.
2899  */
2900  _dbus_connection_ref_unlocked (connection);
2901 
2902  _dbus_transport_disconnect (connection->transport);
2903 
2904  /* This has the side effect of queuing the disconnect message link
2905  * (unless we don't have enough memory, possibly, so don't assert it).
2906  * After the disconnect message link is queued, dbus_bus_get/dbus_connection_open
2907  * should never again return the newly-disconnected connection.
2908  *
2909  * However, we only unref the shared connection and exit_on_disconnect when
2910  * the disconnect message reaches the head of the message queue,
2911  * NOT when it's first queued.
2912  */
2913  status = _dbus_connection_get_dispatch_status_unlocked (connection);
2914 
2915  /* This calls out to user code */
2916  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2917 
2918  /* Could also call out to user code */
2919  dbus_connection_unref (connection);
2920 }
2921 
2964 void
2966 {
2967  _dbus_return_if_fail (connection != NULL);
2968  _dbus_return_if_fail (connection->generation == _dbus_current_generation);
2969 
2970  CONNECTION_LOCK (connection);
2971 
2972 #ifndef DBUS_DISABLE_CHECKS
2973  if (connection->shareable)
2974  {
2975  CONNECTION_UNLOCK (connection);
2976 
2977  _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n");
2978  return;
2979  }
2980 #endif
2981 
2982  _dbus_connection_close_possibly_shared_and_unlock (connection);
2983 }
2984 
2985 static dbus_bool_t
2986 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
2987 {
2988  HAVE_LOCK_CHECK (connection);
2989  return _dbus_transport_get_is_connected (connection->transport);
2990 }
2991 
3007 {
3008  dbus_bool_t res;
3009 
3010  _dbus_return_val_if_fail (connection != NULL, FALSE);
3011 
3012  CONNECTION_LOCK (connection);
3013  res = _dbus_connection_get_is_connected_unlocked (connection);
3014  CONNECTION_UNLOCK (connection);
3015 
3016  return res;
3017 }
3018 
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_try_to_authenticate (connection->transport);
3036  CONNECTION_UNLOCK (connection);
3037 
3038  return res;
3039 }
3040 
3063 {
3064  dbus_bool_t res;
3065 
3066  _dbus_return_val_if_fail (connection != NULL, FALSE);
3067 
3068  CONNECTION_LOCK (connection);
3069  res = _dbus_transport_get_is_anonymous (connection->transport);
3070  CONNECTION_UNLOCK (connection);
3071 
3072  return res;
3073 }
3074 
3106 char*
3108 {
3109  char *id;
3110 
3111  _dbus_return_val_if_fail (connection != NULL, NULL);
3112 
3113  CONNECTION_LOCK (connection);
3115  CONNECTION_UNLOCK (connection);
3116 
3117  return id;
3118 }
3119 
3139  int type)
3140 {
3141  _dbus_return_val_if_fail (connection != NULL, FALSE);
3142 
3143  if (!dbus_type_is_valid (type))
3144  return FALSE;
3145 
3146  if (type != DBUS_TYPE_UNIX_FD)
3147  return TRUE;
3148 
3149 #ifdef HAVE_UNIX_FD_PASSING
3150  {
3151  dbus_bool_t b;
3152 
3153  CONNECTION_LOCK(connection);
3155  CONNECTION_UNLOCK(connection);
3156 
3157  return b;
3158  }
3159 #endif
3160 
3161  return FALSE;
3162 }
3163 
3177 void
3179  dbus_bool_t exit_on_disconnect)
3180 {
3181  _dbus_return_if_fail (connection != NULL);
3182 
3183  CONNECTION_LOCK (connection);
3184  connection->exit_on_disconnect = exit_on_disconnect != FALSE;
3185  CONNECTION_UNLOCK (connection);
3186 }
3187 
3199 {
3200  DBusPreallocatedSend *preallocated;
3201 
3202  _dbus_return_val_if_fail (connection != NULL, NULL);
3203 
3204  CONNECTION_LOCK (connection);
3205 
3206  preallocated =
3207  _dbus_connection_preallocate_send_unlocked (connection);
3208 
3209  CONNECTION_UNLOCK (connection);
3210 
3211  return preallocated;
3212 }
3213 
3223 void
3225  DBusPreallocatedSend *preallocated)
3226 {
3227  _dbus_return_if_fail (connection != NULL);
3228  _dbus_return_if_fail (preallocated != NULL);
3229  _dbus_return_if_fail (connection == preallocated->connection);
3230 
3231  _dbus_list_free_link (preallocated->queue_link);
3232  _dbus_counter_unref (preallocated->counter_link->data);
3233  _dbus_list_free_link (preallocated->counter_link);
3234  dbus_free (preallocated);
3235 }
3236 
3249 void
3251  DBusPreallocatedSend *preallocated,
3252  DBusMessage *message,
3253  dbus_uint32_t *client_serial)
3254 {
3255  _dbus_return_if_fail (connection != NULL);
3256  _dbus_return_if_fail (preallocated != NULL);
3257  _dbus_return_if_fail (message != NULL);
3258  _dbus_return_if_fail (preallocated->connection == connection);
3259  _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
3260  dbus_message_get_member (message) != NULL);
3261  _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
3262  (dbus_message_get_interface (message) != NULL &&
3263  dbus_message_get_member (message) != NULL));
3264 
3265  CONNECTION_LOCK (connection);
3266 
3267 #ifdef HAVE_UNIX_FD_PASSING
3268 
3269  if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
3270  message->n_unix_fds > 0)
3271  {
3272  /* Refuse to send fds on a connection that cannot handle
3273  them. Unfortunately we cannot return a proper error here, so
3274  the best we can is just return. */
3275  CONNECTION_UNLOCK (connection);
3276  return;
3277  }
3278 
3279 #endif
3280 
3281  _dbus_connection_send_preallocated_and_unlock (connection,
3282  preallocated,
3283  message, client_serial);
3284 }
3285 
3286 static dbus_bool_t
3287 _dbus_connection_send_unlocked_no_update (DBusConnection *connection,
3288  DBusMessage *message,
3289  dbus_uint32_t *client_serial)
3290 {
3291  DBusPreallocatedSend *preallocated;
3292 
3293  _dbus_assert (connection != NULL);
3294  _dbus_assert (message != NULL);
3295 
3296  preallocated = _dbus_connection_preallocate_send_unlocked (connection);
3297  if (preallocated == NULL)
3298  return FALSE;
3299 
3300  _dbus_connection_send_preallocated_unlocked_no_update (connection,
3301  preallocated,
3302  message,
3303  client_serial);
3304  return TRUE;
3305 }
3306 
3336  DBusMessage *message,
3337  dbus_uint32_t *serial)
3338 {
3339  _dbus_return_val_if_fail (connection != NULL, FALSE);
3340  _dbus_return_val_if_fail (message != NULL, FALSE);
3341 
3342  CONNECTION_LOCK (connection);
3343 
3344 #ifdef HAVE_UNIX_FD_PASSING
3345 
3346  if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
3347  message->n_unix_fds > 0)
3348  {
3349  /* Refuse to send fds on a connection that cannot handle
3350  them. Unfortunately we cannot return a proper error here, so
3351  the best we can is just return. */
3352  CONNECTION_UNLOCK (connection);
3353  return FALSE;
3354  }
3355 
3356 #endif
3357 
3358  return _dbus_connection_send_and_unlock (connection,
3359  message,
3360  serial);
3361 }
3362 
3363 static dbus_bool_t
3364 reply_handler_timeout (void *data)
3365 {
3366  DBusConnection *connection;
3367  DBusDispatchStatus status;
3368  DBusPendingCall *pending = data;
3369 
3370  connection = _dbus_pending_call_get_connection_and_lock (pending);
3371  _dbus_connection_ref_unlocked (connection);
3372 
3374  connection);
3378 
3379  _dbus_verbose ("middle\n");
3380  status = _dbus_connection_get_dispatch_status_unlocked (connection);
3381 
3382  /* Unlocks, and calls out to user code */
3383  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3384  dbus_connection_unref (connection);
3385 
3386  return TRUE;
3387 }
3388 
3433  DBusMessage *message,
3434  DBusPendingCall **pending_return,
3435  int timeout_milliseconds)
3436 {
3437  DBusPendingCall *pending;
3438  dbus_int32_t serial = -1;
3439  DBusDispatchStatus status;
3440 
3441  _dbus_return_val_if_fail (connection != NULL, FALSE);
3442  _dbus_return_val_if_fail (message != NULL, FALSE);
3443  _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
3444 
3445  if (pending_return)
3446  *pending_return = NULL;
3447 
3448  CONNECTION_LOCK (connection);
3449 
3450 #ifdef HAVE_UNIX_FD_PASSING
3451 
3452  if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
3453  message->n_unix_fds > 0)
3454  {
3455  /* Refuse to send fds on a connection that cannot handle
3456  them. Unfortunately we cannot return a proper error here, so
3457  the best we can do is return TRUE but leave *pending_return
3458  as NULL. */
3459  CONNECTION_UNLOCK (connection);
3460  return TRUE;
3461  }
3462 
3463 #endif
3464 
3465  if (!_dbus_connection_get_is_connected_unlocked (connection))
3466  {
3467  CONNECTION_UNLOCK (connection);
3468 
3469  return TRUE;
3470  }
3471 
3472  pending = _dbus_pending_call_new_unlocked (connection,
3473  timeout_milliseconds,
3474  reply_handler_timeout);
3475 
3476  if (pending == NULL)
3477  {
3478  CONNECTION_UNLOCK (connection);
3479  return FALSE;
3480  }
3481 
3482  /* Assign a serial to the message */
3483  serial = dbus_message_get_serial (message);
3484  if (serial == 0)
3485  {
3486  serial = _dbus_connection_get_next_client_serial (connection);
3487  dbus_message_set_serial (message, serial);
3488  }
3489 
3490  if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
3491  goto error;
3492 
3493  /* Insert the serial in the pending replies hash;
3494  * hash takes a refcount on DBusPendingCall.
3495  * Also, add the timeout.
3496  */
3497  if (!_dbus_connection_attach_pending_call_unlocked (connection,
3498  pending))
3499  goto error;
3500 
3501  if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
3502  {
3503  _dbus_connection_detach_pending_call_and_unlock (connection,
3504  pending);
3505  goto error_unlocked;
3506  }
3507 
3508  if (pending_return)
3509  *pending_return = pending; /* hand off refcount */
3510  else
3511  {
3512  _dbus_connection_detach_pending_call_unlocked (connection, pending);
3513  /* we still have a ref to the pending call in this case, we unref
3514  * after unlocking, below
3515  */
3516  }
3517 
3518  status = _dbus_connection_get_dispatch_status_unlocked (connection);
3519 
3520  /* this calls out to user code */
3521  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3522 
3523  if (pending_return == NULL)
3524  dbus_pending_call_unref (pending);
3525 
3526  return TRUE;
3527 
3528  error:
3529  CONNECTION_UNLOCK (connection);
3530  error_unlocked:
3531  dbus_pending_call_unref (pending);
3532  return FALSE;
3533 }
3534 
3567 DBusMessage*
3569  DBusMessage *message,
3570  int timeout_milliseconds,
3571  DBusError *error)
3572 {
3573  DBusMessage *reply;
3574  DBusPendingCall *pending;
3575 
3576  _dbus_return_val_if_fail (connection != NULL, NULL);
3577  _dbus_return_val_if_fail (message != NULL, NULL);
3578  _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL);
3579  _dbus_return_val_if_error_is_set (error, NULL);
3580 
3581 #ifdef HAVE_UNIX_FD_PASSING
3582 
3583  CONNECTION_LOCK (connection);
3584  if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
3585  message->n_unix_fds > 0)
3586  {
3587  CONNECTION_UNLOCK (connection);
3588  dbus_set_error(error, DBUS_ERROR_FAILED, "Cannot send file descriptors on this connection.");
3589  return NULL;
3590  }
3591  CONNECTION_UNLOCK (connection);
3592 
3593 #endif
3594 
3595  if (!dbus_connection_send_with_reply (connection, message,
3596  &pending, timeout_milliseconds))
3597  {
3598  _DBUS_SET_OOM (error);
3599  return NULL;
3600  }
3601 
3602  if (pending == NULL)
3603  {
3604  dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Connection is closed");
3605  return NULL;
3606  }
3607 
3608  dbus_pending_call_block (pending);
3609 
3610  reply = dbus_pending_call_steal_reply (pending);
3611  dbus_pending_call_unref (pending);
3612 
3613  /* call_complete_and_unlock() called from pending_call_block() should
3614  * always fill this in.
3615  */
3616  _dbus_assert (reply != NULL);
3617 
3618  if (dbus_set_error_from_message (error, reply))
3619  {
3620  dbus_message_unref (reply);
3621  return NULL;
3622  }
3623  else
3624  return reply;
3625 }
3626 
3635 static DBusDispatchStatus
3636 _dbus_connection_flush_unlocked (DBusConnection *connection)
3637 {
3638  /* We have to specify DBUS_ITERATION_DO_READING here because
3639  * otherwise we could have two apps deadlock if they are both doing
3640  * a flush(), and the kernel buffers fill up. This could change the
3641  * dispatch status.
3642  */
3643  DBusDispatchStatus status;
3644 
3645  HAVE_LOCK_CHECK (connection);
3646 
3647  while (connection->n_outgoing > 0 &&
3648  _dbus_connection_get_is_connected_unlocked (connection))
3649  {
3650  _dbus_verbose ("doing iteration in\n");
3651  HAVE_LOCK_CHECK (connection);
3653  NULL,
3654  DBUS_ITERATION_DO_READING |
3655  DBUS_ITERATION_DO_WRITING |
3656  DBUS_ITERATION_BLOCK,
3657  -1);
3658  }
3659 
3660  HAVE_LOCK_CHECK (connection);
3661  _dbus_verbose ("middle\n");
3662  status = _dbus_connection_get_dispatch_status_unlocked (connection);
3663 
3664  HAVE_LOCK_CHECK (connection);
3665  return status;
3666 }
3667 
3673 void
3675 {
3676  /* We have to specify DBUS_ITERATION_DO_READING here because
3677  * otherwise we could have two apps deadlock if they are both doing
3678  * a flush(), and the kernel buffers fill up. This could change the
3679  * dispatch status.
3680  */
3681  DBusDispatchStatus status;
3682 
3683  _dbus_return_if_fail (connection != NULL);
3684 
3685  CONNECTION_LOCK (connection);
3686 
3687  status = _dbus_connection_flush_unlocked (connection);
3688 
3689  HAVE_LOCK_CHECK (connection);
3690  /* Unlocks and calls out to user code */
3691  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3692 
3693  _dbus_verbose ("end\n");
3694 }
3695 
3706 static dbus_bool_t
3707 _dbus_connection_read_write_dispatch (DBusConnection *connection,
3708  int timeout_milliseconds,
3709  dbus_bool_t dispatch)
3710 {
3711  DBusDispatchStatus dstatus;
3712  dbus_bool_t progress_possible;
3713 
3714  /* Need to grab a ref here in case we're a private connection and
3715  * the user drops the last ref in a handler we call; see bug
3716  * https://bugs.freedesktop.org/show_bug.cgi?id=15635
3717  */
3718  dbus_connection_ref (connection);
3719  dstatus = dbus_connection_get_dispatch_status (connection);
3720 
3721  if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
3722  {
3723  _dbus_verbose ("doing dispatch\n");
3724  dbus_connection_dispatch (connection);
3725  CONNECTION_LOCK (connection);
3726  }
3727  else if (dstatus == DBUS_DISPATCH_NEED_MEMORY)
3728  {
3729  _dbus_verbose ("pausing for memory\n");
3730  _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
3731  CONNECTION_LOCK (connection);
3732  }
3733  else
3734  {
3735  CONNECTION_LOCK (connection);
3736  if (_dbus_connection_get_is_connected_unlocked (connection))
3737  {
3738  _dbus_verbose ("doing iteration\n");
3740  NULL,
3741  DBUS_ITERATION_DO_READING |
3742  DBUS_ITERATION_DO_WRITING |
3743  DBUS_ITERATION_BLOCK,
3744  timeout_milliseconds);
3745  }
3746  }
3747 
3748  HAVE_LOCK_CHECK (connection);
3749  /* If we can dispatch, we can make progress until the Disconnected message
3750  * has been processed; if we can only read/write, we can make progress
3751  * as long as the transport is open.
3752  */
3753  if (dispatch)
3754  progress_possible = connection->n_incoming != 0 ||
3755  connection->disconnect_message_link != NULL;
3756  else
3757  progress_possible = _dbus_connection_get_is_connected_unlocked (connection);
3758 
3759  CONNECTION_UNLOCK (connection);
3760 
3761  dbus_connection_unref (connection);
3762 
3763  return progress_possible; /* TRUE if we can make more progress */
3764 }
3765 
3766 
3803  int timeout_milliseconds)
3804 {
3805  _dbus_return_val_if_fail (connection != NULL, FALSE);
3806  _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
3807  return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE);
3808 }
3809 
3833 dbus_bool_t
3835  int timeout_milliseconds)
3836 {
3837  _dbus_return_val_if_fail (connection != NULL, FALSE);
3838  _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
3839  return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE);
3840 }
3841 
3842 /* We need to call this anytime we pop the head of the queue, and then
3843  * update_dispatch_status_and_unlock needs to be called afterward
3844  * which will "process" the disconnected message and set
3845  * disconnected_message_processed.
3846  */
3847 static void
3848 check_disconnected_message_arrived_unlocked (DBusConnection *connection,
3849  DBusMessage *head_of_queue)
3850 {
3851  HAVE_LOCK_CHECK (connection);
3852 
3853  /* checking that the link is NULL is an optimization to avoid the is_signal call */
3854  if (connection->disconnect_message_link == NULL &&
3855  dbus_message_is_signal (head_of_queue,
3857  "Disconnected"))
3858  {
3859  connection->disconnected_message_arrived = TRUE;
3860  }
3861 }
3862 
3882 DBusMessage*
3884 {
3885  DBusDispatchStatus status;
3886  DBusMessage *message;
3887 
3888  _dbus_return_val_if_fail (connection != NULL, NULL);
3889 
3890  _dbus_verbose ("start\n");
3891 
3892  /* this is called for the side effect that it queues
3893  * up any messages from the transport
3894  */
3895  status = dbus_connection_get_dispatch_status (connection);
3896  if (status != DBUS_DISPATCH_DATA_REMAINS)
3897  return NULL;
3898 
3899  CONNECTION_LOCK (connection);
3900 
3901  _dbus_connection_acquire_dispatch (connection);
3902 
3903  /* While a message is outstanding, the dispatch lock is held */
3904  _dbus_assert (connection->message_borrowed == NULL);
3905 
3906  connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
3907 
3908  message = connection->message_borrowed;
3909 
3910  check_disconnected_message_arrived_unlocked (connection, message);
3911 
3912  /* Note that we KEEP the dispatch lock until the message is returned */
3913  if (message == NULL)
3914  _dbus_connection_release_dispatch (connection);
3915 
3916  CONNECTION_UNLOCK (connection);
3917 
3918  _dbus_message_trace_ref (message, -1, -1, "dbus_connection_borrow_message");
3919 
3920  /* We don't update dispatch status until it's returned or stolen */
3921 
3922  return message;
3923 }
3924 
3933 void
3935  DBusMessage *message)
3936 {
3937  DBusDispatchStatus status;
3938 
3939  _dbus_return_if_fail (connection != NULL);
3940  _dbus_return_if_fail (message != NULL);
3941  _dbus_return_if_fail (message == connection->message_borrowed);
3942  _dbus_return_if_fail (connection->dispatch_acquired);
3943 
3944  CONNECTION_LOCK (connection);
3945 
3946  _dbus_assert (message == connection->message_borrowed);
3947 
3948  connection->message_borrowed = NULL;
3949 
3950  _dbus_connection_release_dispatch (connection);
3951 
3952  status = _dbus_connection_get_dispatch_status_unlocked (connection);
3953  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3954 
3955  _dbus_message_trace_ref (message, -1, -1, "dbus_connection_return_message");
3956 }
3957 
3967 void
3969  DBusMessage *message)
3970 {
3971  DBusMessage *pop_message;
3972  DBusDispatchStatus status;
3973 
3974  _dbus_return_if_fail (connection != NULL);
3975  _dbus_return_if_fail (message != NULL);
3976  _dbus_return_if_fail (message == connection->message_borrowed);
3977  _dbus_return_if_fail (connection->dispatch_acquired);
3978 
3979  CONNECTION_LOCK (connection);
3980 
3981  _dbus_assert (message == connection->message_borrowed);
3982 
3983  pop_message = _dbus_list_pop_first (&connection->incoming_messages);
3984  _dbus_assert (message == pop_message);
3985  (void) pop_message; /* unused unless asserting */
3986 
3987  connection->n_incoming -= 1;
3988 
3989  _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
3990  message, connection->n_incoming);
3991 
3992  connection->message_borrowed = NULL;
3993 
3994  _dbus_connection_release_dispatch (connection);
3995 
3996  status = _dbus_connection_get_dispatch_status_unlocked (connection);
3997  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3998  _dbus_message_trace_ref (message, -1, -1,
3999  "dbus_connection_steal_borrowed_message");
4000 }
4001 
4002 /* See dbus_connection_pop_message, but requires the caller to own
4003  * the lock before calling. May drop the lock while running.
4004  */
4005 static DBusList*
4006 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
4007 {
4008  HAVE_LOCK_CHECK (connection);
4009 
4010  _dbus_assert (connection->message_borrowed == NULL);
4011 
4012  if (connection->n_incoming > 0)
4013  {
4014  DBusList *link;
4015 
4016  link = _dbus_list_pop_first_link (&connection->incoming_messages);
4017  connection->n_incoming -= 1;
4018 
4019  _dbus_verbose ("Message %p (%s %s %s %s sig:'%s' serial:%u) removed from incoming queue %p, %d incoming\n",
4020  link->data,
4022  dbus_message_get_path (link->data) ?
4023  dbus_message_get_path (link->data) :
4024  "no path",
4027  "no interface",
4028  dbus_message_get_member (link->data) ?
4029  dbus_message_get_member (link->data) :
4030  "no member",
4032  dbus_message_get_serial (link->data),
4033  connection, connection->n_incoming);
4034 
4035  _dbus_message_trace_ref (link->data, -1, -1,
4036  "_dbus_connection_pop_message_link_unlocked");
4037 
4038  check_disconnected_message_arrived_unlocked (connection, link->data);
4039 
4040  return link;
4041  }
4042  else
4043  return NULL;
4044 }
4045 
4046 /* See dbus_connection_pop_message, but requires the caller to own
4047  * the lock before calling. May drop the lock while running.
4048  */
4049 static DBusMessage*
4050 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
4051 {
4052  DBusList *link;
4053 
4054  HAVE_LOCK_CHECK (connection);
4055 
4056  link = _dbus_connection_pop_message_link_unlocked (connection);
4057 
4058  if (link != NULL)
4059  {
4060  DBusMessage *message;
4061 
4062  message = link->data;
4063 
4064  _dbus_list_free_link (link);
4065 
4066  return message;
4067  }
4068  else
4069  return NULL;
4070 }
4071 
4072 static void
4073 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
4074  DBusList *message_link)
4075 {
4076  HAVE_LOCK_CHECK (connection);
4077 
4078  _dbus_assert (message_link != NULL);
4079  /* You can't borrow a message while a link is outstanding */
4080  _dbus_assert (connection->message_borrowed == NULL);
4081  /* We had to have the dispatch lock across the pop/putback */
4082  _dbus_assert (connection->dispatch_acquired);
4083 
4085  message_link);
4086  connection->n_incoming += 1;
4087 
4088  _dbus_verbose ("Message %p (%s %s %s '%s') put back into queue %p, %d incoming\n",
4089  message_link->data,
4091  dbus_message_get_interface (message_link->data) ?
4092  dbus_message_get_interface (message_link->data) :
4093  "no interface",
4094  dbus_message_get_member (message_link->data) ?
4095  dbus_message_get_member (message_link->data) :
4096  "no member",
4097  dbus_message_get_signature (message_link->data),
4098  connection, connection->n_incoming);
4099 
4100  _dbus_message_trace_ref (message_link->data, -1, -1,
4101  "_dbus_connection_putback_message_link_unlocked");
4102 }
4103 
4105 _dbus_connection_putback_message (DBusConnection *connection,
4106  DBusMessage *after_message,
4107  DBusMessage *message,
4108  DBusError *error)
4109 {
4110  DBusDispatchStatus status;
4111  DBusList *message_link = _dbus_list_alloc_link (message);
4112  DBusList *after_link;
4113  if (message_link == NULL)
4114  {
4115  _DBUS_SET_OOM (error);
4116  return FALSE;
4117  }
4118  dbus_message_ref (message);
4119 
4120  CONNECTION_LOCK (connection);
4121  _dbus_connection_acquire_dispatch (connection);
4122  HAVE_LOCK_CHECK (connection);
4123 
4124  after_link = _dbus_list_find_first(&connection->incoming_messages, after_message);
4125  _dbus_list_insert_after_link (&connection->incoming_messages, after_link, message_link);
4126  connection->n_incoming += 1;
4127 
4128  _dbus_verbose ("Message %p (%s %s %s '%s') put back into queue %p, %d incoming\n",
4129  message_link->data,
4131  dbus_message_get_interface (message_link->data) ?
4132  dbus_message_get_interface (message_link->data) :
4133  "no interface",
4134  dbus_message_get_member (message_link->data) ?
4135  dbus_message_get_member (message_link->data) :
4136  "no member",
4137  dbus_message_get_signature (message_link->data),
4138  connection, connection->n_incoming);
4139 
4140  _dbus_message_trace_ref (message_link->data, -1, -1,
4141  "_dbus_connection_putback_message");
4142 
4143  _dbus_connection_release_dispatch (connection);
4144 
4145  status = _dbus_connection_get_dispatch_status_unlocked (connection);
4146  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
4147 
4148  return TRUE;
4149 }
4150 
4152 _dbus_connection_remove_message (DBusConnection *connection,
4153  DBusMessage *message)
4154 {
4155  DBusDispatchStatus status;
4156  dbus_bool_t removed;
4157 
4158  CONNECTION_LOCK (connection);
4159  _dbus_connection_acquire_dispatch (connection);
4160  HAVE_LOCK_CHECK (connection);
4161 
4162  removed = _dbus_list_remove(&connection->incoming_messages, message);
4163 
4164  if (removed)
4165  {
4166  connection->n_incoming -= 1;
4167  dbus_message_unref(message);
4168  _dbus_verbose ("Message %p removed from incoming queue\n", message);
4169  }
4170  else
4171  _dbus_verbose ("Message %p not found in the incoming queue\n", message);
4172 
4173  _dbus_connection_release_dispatch (connection);
4174 
4175  status = _dbus_connection_get_dispatch_status_unlocked (connection);
4176  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
4177  return removed;
4178 }
4179 
4199 DBusMessage*
4201 {
4202  DBusMessage *message;
4203  DBusDispatchStatus status;
4204 
4205  _dbus_verbose ("start\n");
4206 
4207  /* this is called for the side effect that it queues
4208  * up any messages from the transport
4209  */
4210  status = dbus_connection_get_dispatch_status (connection);
4211  if (status != DBUS_DISPATCH_DATA_REMAINS)
4212  return NULL;
4213 
4214  CONNECTION_LOCK (connection);
4215  _dbus_connection_acquire_dispatch (connection);
4216  HAVE_LOCK_CHECK (connection);
4217 
4218  message = _dbus_connection_pop_message_unlocked (connection);
4219 
4220  _dbus_verbose ("Returning popped message %p\n", message);
4221 
4222  _dbus_connection_release_dispatch (connection);
4223 
4224  status = _dbus_connection_get_dispatch_status_unlocked (connection);
4225  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
4226 
4227  return message;
4228 }
4229 
4237 static void
4238 _dbus_connection_acquire_dispatch (DBusConnection *connection)
4239 {
4240  HAVE_LOCK_CHECK (connection);
4241 
4242  _dbus_connection_ref_unlocked (connection);
4243  CONNECTION_UNLOCK (connection);
4244 
4245  _dbus_verbose ("locking dispatch_mutex\n");
4246  _dbus_cmutex_lock (connection->dispatch_mutex);
4247 
4248  while (connection->dispatch_acquired)
4249  {
4250  _dbus_verbose ("waiting for dispatch to be acquirable\n");
4251  _dbus_condvar_wait (connection->dispatch_cond,
4252  connection->dispatch_mutex);
4253  }
4254 
4255  _dbus_assert (!connection->dispatch_acquired);
4256 
4257  connection->dispatch_acquired = TRUE;
4258 
4259  _dbus_verbose ("unlocking dispatch_mutex\n");
4260  _dbus_cmutex_unlock (connection->dispatch_mutex);
4261 
4262  CONNECTION_LOCK (connection);
4263  _dbus_connection_unref_unlocked (connection);
4264 }
4265 
4273 static void
4274 _dbus_connection_release_dispatch (DBusConnection *connection)
4275 {
4276  HAVE_LOCK_CHECK (connection);
4277 
4278  _dbus_verbose ("locking dispatch_mutex\n");
4279  _dbus_cmutex_lock (connection->dispatch_mutex);
4280 
4281  _dbus_assert (connection->dispatch_acquired);
4282 
4283  connection->dispatch_acquired = FALSE;
4284  _dbus_condvar_wake_one (connection->dispatch_cond);
4285 
4286  _dbus_verbose ("unlocking dispatch_mutex\n");
4287  _dbus_cmutex_unlock (connection->dispatch_mutex);
4288 }
4289 
4290 static void
4291 _dbus_connection_failed_pop (DBusConnection *connection,
4292  DBusList *message_link)
4293 {
4295  message_link);
4296  connection->n_incoming += 1;
4297 }
4298 
4299 /* Note this may be called multiple times since we don't track whether we already did it */
4300 static void
4301 notify_disconnected_unlocked (DBusConnection *connection)
4302 {
4303  HAVE_LOCK_CHECK (connection);
4304 
4305  /* Set the weakref in dbus-bus.c to NULL, so nobody will get a disconnected
4306  * connection from dbus_bus_get(). We make the same guarantee for
4307  * dbus_connection_open() but in a different way since we don't want to
4308  * unref right here; we instead check for connectedness before returning
4309  * the connection from the hash.
4310  */
4312 
4313  /* Dump the outgoing queue, we aren't going to be able to
4314  * send it now, and we'd like accessors like
4315  * dbus_connection_get_outgoing_size() to be accurate.
4316  */
4317  if (connection->n_outgoing > 0)
4318  {
4319  DBusList *link;
4320 
4321  _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
4322  connection->n_outgoing);
4323 
4324  while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
4325  {
4326  _dbus_connection_message_sent_unlocked (connection, link->data);
4327  }
4328  }
4329 }
4330 
4331 /* Note this may be called multiple times since we don't track whether we already did it */
4332 static DBusDispatchStatus
4333 notify_disconnected_and_dispatch_complete_unlocked (DBusConnection *connection)
4334 {
4335  HAVE_LOCK_CHECK (connection);
4336 
4337  if (connection->disconnect_message_link != NULL)
4338  {
4339  _dbus_verbose ("Sending disconnect message\n");
4340 
4341  /* If we have pending calls, queue their timeouts - we want the Disconnected
4342  * to be the last message, after these timeouts.
4343  */
4344  connection_timeout_and_complete_all_pending_calls_unlocked (connection);
4345 
4346  /* We haven't sent the disconnect message already,
4347  * and all real messages have been queued up.
4348  */
4350  connection->disconnect_message_link);
4351  connection->disconnect_message_link = NULL;
4352 
4354  }
4355 
4356  return DBUS_DISPATCH_COMPLETE;
4357 }
4358 
4359 static DBusDispatchStatus
4360 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
4361 {
4362  HAVE_LOCK_CHECK (connection);
4363  if (connection->dispatch_disabled && dbus_connection_get_is_connected(connection))
4364  return DBUS_DISPATCH_COMPLETE;
4365  else if (connection->n_incoming > 0)
4367  else if (!_dbus_transport_queue_messages (connection->transport))
4369  else
4370  {
4371  DBusDispatchStatus status;
4372  dbus_bool_t is_connected;
4373 
4374  status = _dbus_transport_get_dispatch_status (connection->transport);
4375  is_connected = _dbus_transport_get_is_connected (connection->transport);
4376 
4377  _dbus_verbose ("dispatch status = %s is_connected = %d\n",
4378  DISPATCH_STATUS_NAME (status), is_connected);
4379 
4380  if (!is_connected)
4381  {
4382  /* It's possible this would be better done by having an explicit
4383  * notification from _dbus_transport_disconnect() that would
4384  * synchronously do this, instead of waiting for the next dispatch
4385  * status check. However, probably not good to change until it causes
4386  * a problem.
4387  */
4388  notify_disconnected_unlocked (connection);
4389 
4390  /* I'm not sure this is needed; the idea is that we want to
4391  * queue the Disconnected only after we've read all the
4392  * messages, but if we're disconnected maybe we are guaranteed
4393  * to have read them all ?
4394  */
4395  if (status == DBUS_DISPATCH_COMPLETE)
4396  status = notify_disconnected_and_dispatch_complete_unlocked (connection);
4397  }
4398 
4399  if (status != DBUS_DISPATCH_COMPLETE)
4400  return status;
4401  else if (connection->n_incoming > 0)
4403  else
4404  return DBUS_DISPATCH_COMPLETE;
4405  }
4406 }
4407 
4408 static void
4409 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
4410  DBusDispatchStatus new_status)
4411 {
4412  dbus_bool_t changed;
4413  DBusDispatchStatusFunction function;
4414  void *data;
4415 
4416  HAVE_LOCK_CHECK (connection);
4417 
4418  _dbus_connection_ref_unlocked (connection);
4419 
4420  changed = new_status != connection->last_dispatch_status;
4421 
4422  connection->last_dispatch_status = new_status;
4423 
4424  function = connection->dispatch_status_function;
4425  data = connection->dispatch_status_data;
4426 
4427  if (connection->disconnected_message_arrived &&
4428  !connection->disconnected_message_processed)
4429  {
4430  connection->disconnected_message_processed = TRUE;
4431 
4432  /* this does an unref, but we have a ref
4433  * so we should not run the finalizer here
4434  * inside the lock.
4435  */
4436  connection_forget_shared_unlocked (connection);
4437 
4438  if (connection->exit_on_disconnect)
4439  {
4440  CONNECTION_UNLOCK (connection);
4441 
4442  _dbus_verbose ("Exiting on Disconnected signal\n");
4443  _dbus_exit (1);
4444  _dbus_assert_not_reached ("Call to exit() returned");
4445  }
4446  }
4447 
4448  /* We drop the lock */
4449  CONNECTION_UNLOCK (connection);
4450 
4451  if (changed && function)
4452  {
4453  _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
4454  connection, new_status,
4455  DISPATCH_STATUS_NAME (new_status));
4456  (* function) (connection, new_status, data);
4457  }
4458 
4459  dbus_connection_unref (connection);
4460 }
4461 
4489 {
4490  DBusDispatchStatus status;
4491 
4492  _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
4493 
4494  _dbus_verbose ("start\n");
4495 
4496  CONNECTION_LOCK (connection);
4497 
4498  status = _dbus_connection_get_dispatch_status_unlocked (connection);
4499 
4500  CONNECTION_UNLOCK (connection);
4501 
4502  return status;
4503 }
4504 
4508 static DBusHandlerResult
4509 _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
4510  DBusMessage *message)
4511 {
4512  dbus_bool_t sent = FALSE;
4513  DBusMessage *ret = NULL;
4514  DBusList *expire_link;
4515 
4516  if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
4517  {
4518  /* This means we're letting the bus route this message */
4520  }
4521 
4523  {
4525  }
4526 
4527  /* Preallocate a linked-list link, so that if we need to dispose of a
4528  * message, we can attach it to the expired list */
4529  expire_link = _dbus_list_alloc_link (NULL);
4530 
4531  if (!expire_link)
4533 
4534  if (dbus_message_is_method_call (message,
4536  "Ping"))
4537  {
4538  ret = dbus_message_new_method_return (message);
4539  if (ret == NULL)
4540  goto out;
4541 
4542  sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
4543  }
4544  else if (dbus_message_is_method_call (message,
4546  "GetMachineId"))
4547  {
4548  DBusString uuid;
4549 
4550  ret = dbus_message_new_method_return (message);
4551  if (ret == NULL)
4552  goto out;
4553 
4554  _dbus_string_init (&uuid);
4556  {
4557  const char *v_STRING = _dbus_string_get_const_data (&uuid);
4558  if (dbus_message_append_args (ret,
4559  DBUS_TYPE_STRING, &v_STRING,
4561  {
4562  sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
4563  }
4564  }
4565  _dbus_string_free (&uuid);
4566  }
4567  else
4568  {
4569  /* We need to bounce anything else with this interface, otherwise apps
4570  * could start extending the interface and when we added extensions
4571  * here to DBusConnection we'd break those apps.
4572  */
4573  ret = dbus_message_new_error (message,
4575  "Unknown method invoked on org.freedesktop.DBus.Peer interface");
4576  if (ret == NULL)
4577  goto out;
4578 
4579  sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
4580  }
4581 
4582 out:
4583  if (ret == NULL)
4584  {
4585  _dbus_list_free_link (expire_link);
4586  }
4587  else
4588  {
4589  /* It'll be safe to unref the reply when we unlock */
4590  expire_link->data = ret;
4591  _dbus_list_prepend_link (&connection->expired_messages, expire_link);
4592  }
4593 
4594  if (!sent)
4596 
4598 }
4599 
4606 static DBusHandlerResult
4607 _dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection,
4608  DBusMessage *message)
4609 {
4610  /* We just run one filter for now but have the option to run more
4611  if the spec calls for it in the future */
4612 
4613  return _dbus_connection_peer_filter_unlocked_no_update (connection, message);
4614 }
4615 
4660 {
4661  DBusMessage *message;
4662  DBusList *link, *filter_list_copy, *message_link;
4663  DBusHandlerResult result;
4664  DBusPendingCall *pending;
4665  dbus_int32_t reply_serial;
4666  DBusDispatchStatus status;
4667  dbus_bool_t found_object;
4668 
4669  _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
4670 
4671  _dbus_verbose ("\n");
4672 
4673  CONNECTION_LOCK (connection);
4674  status = _dbus_connection_get_dispatch_status_unlocked (connection);
4675  if (status != DBUS_DISPATCH_DATA_REMAINS)
4676  {
4677  /* unlocks and calls out to user code */
4678  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
4679  return status;
4680  }
4681 
4682  /* We need to ref the connection since the callback could potentially
4683  * drop the last ref to it
4684  */
4685  _dbus_connection_ref_unlocked (connection);
4686 
4687  _dbus_connection_acquire_dispatch (connection);
4688  HAVE_LOCK_CHECK (connection);
4689 
4690  message_link = _dbus_connection_pop_message_link_unlocked (connection);
4691  if (message_link == NULL)
4692  {
4693  /* another thread dispatched our stuff */
4694 
4695  _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
4696 
4697  _dbus_connection_release_dispatch (connection);
4698 
4699  status = _dbus_connection_get_dispatch_status_unlocked (connection);
4700 
4701  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
4702 
4703  dbus_connection_unref (connection);
4704 
4705  return status;
4706  }
4707 
4708  message = message_link->data;
4709 
4710  _dbus_verbose (" dispatching message %p (%s %s %s '%s')\n",
4711  message,
4713  dbus_message_get_interface (message) ?
4714  dbus_message_get_interface (message) :
4715  "no interface",
4716  dbus_message_get_member (message) ?
4717  dbus_message_get_member (message) :
4718  "no member",
4719  dbus_message_get_signature (message));
4720 
4722 
4723  /* Pending call handling must be first, because if you do
4724  * dbus_connection_send_with_reply_and_block() or
4725  * dbus_pending_call_block() then no handlers/filters will be run on
4726  * the reply. We want consistent semantics in the case where we
4727  * dbus_connection_dispatch() the reply.
4728  */
4729 
4730  reply_serial = dbus_message_get_reply_serial (message);
4731  pending = _dbus_hash_table_lookup_int (connection->pending_replies,
4732  reply_serial);
4733  if (pending)
4734  {
4735  _dbus_verbose ("Dispatching a pending reply\n");
4736  complete_pending_call_and_unlock (connection, pending, message);
4737  pending = NULL; /* it's probably unref'd */
4738 
4739  CONNECTION_LOCK (connection);
4740  _dbus_verbose ("pending call completed in dispatch\n");
4741  result = DBUS_HANDLER_RESULT_HANDLED;
4742  goto out;
4743  }
4744 
4745  result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message);
4747  goto out;
4748 
4749  if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
4750  {
4751  _dbus_connection_release_dispatch (connection);
4752  HAVE_LOCK_CHECK (connection);
4753 
4754  _dbus_connection_failed_pop (connection, message_link);
4755 
4756  /* unlocks and calls user code */
4757  _dbus_connection_update_dispatch_status_and_unlock (connection,
4759  dbus_connection_unref (connection);
4760 
4762  }
4763 
4764  _dbus_list_foreach (&filter_list_copy,
4765  (DBusForeachFunction)_dbus_message_filter_ref,
4766  NULL);
4767 
4768  /* We're still protected from dispatch() reentrancy here
4769  * since we acquired the dispatcher
4770  */
4771  CONNECTION_UNLOCK (connection);
4772 
4773  link = _dbus_list_get_first_link (&filter_list_copy);
4774  while (link != NULL)
4775  {
4776  DBusMessageFilter *filter = link->data;
4777  DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
4778 
4779  if (filter->function == NULL)
4780  {
4781  _dbus_verbose (" filter was removed in a callback function\n");
4782  link = next;
4783  continue;
4784  }
4785 
4786  _dbus_verbose (" running filter on message %p\n", message);
4787  result = (* filter->function) (connection, message, filter->user_data);
4788 
4790  break;
4791 
4792  link = next;
4793  }
4794 
4795  _dbus_list_foreach (&filter_list_copy,
4796  (DBusForeachFunction)_dbus_message_filter_unref,
4797  NULL);
4798  _dbus_list_clear (&filter_list_copy);
4799 
4800  CONNECTION_LOCK (connection);
4801 
4802  if (result == DBUS_HANDLER_RESULT_LATER)
4803  goto out;
4804  if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
4805  {
4806  _dbus_verbose ("No memory\n");
4807  goto out;
4808  }
4809  else if (result == DBUS_HANDLER_RESULT_HANDLED)
4810  {
4811  _dbus_verbose ("filter handled message in dispatch\n");
4812  goto out;
4813  }
4814 
4815  /* We're still protected from dispatch() reentrancy here
4816  * since we acquired the dispatcher
4817  */
4818  _dbus_verbose (" running object path dispatch on message %p (%s %s %s '%s')\n",
4819  message,
4821  dbus_message_get_interface (message) ?
4822  dbus_message_get_interface (message) :
4823  "no interface",
4824  dbus_message_get_member (message) ?
4825  dbus_message_get_member (message) :
4826  "no member",
4827  dbus_message_get_signature (message));
4828 
4829  HAVE_LOCK_CHECK (connection);
4830  result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
4831  message,
4832  &found_object);
4833 
4834  CONNECTION_LOCK (connection);
4835 
4837  {
4838  _dbus_verbose ("object tree handled message in dispatch\n");
4839  goto out;
4840  }
4841 
4843  {
4844  DBusMessage *reply;
4845  DBusString str;
4846  DBusPreallocatedSend *preallocated;
4847  DBusList *expire_link;
4848 
4849  _dbus_verbose (" sending error %s\n",
4851 
4852  if (!_dbus_string_init (&str))
4853  {
4855  _dbus_verbose ("no memory for error string in dispatch\n");
4856  goto out;
4857  }
4858 
4859  if (!_dbus_string_append_printf (&str,
4860  "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
4861  dbus_message_get_member (message),
4862  dbus_message_get_signature (message),
4863  dbus_message_get_interface (message)))
4864  {
4865  _dbus_string_free (&str);
4867  _dbus_verbose ("no memory for error string in dispatch\n");
4868  goto out;
4869  }
4870 
4871  reply = dbus_message_new_error (message,
4874  _dbus_string_free (&str);
4875 
4876  if (reply == NULL)
4877  {
4879  _dbus_verbose ("no memory for error reply in dispatch\n");
4880  goto out;
4881  }
4882 
4883  expire_link = _dbus_list_alloc_link (reply);
4884 
4885  if (expire_link == NULL)
4886  {
4887  dbus_message_unref (reply);
4889  _dbus_verbose ("no memory for error send in dispatch\n");
4890  goto out;
4891  }
4892 
4893  preallocated = _dbus_connection_preallocate_send_unlocked (connection);
4894 
4895  if (preallocated == NULL)
4896  {
4897  _dbus_list_free_link (expire_link);
4898  /* It's OK that this is finalized, because it hasn't been seen by
4899  * anything that could attach user callbacks */
4900  dbus_message_unref (reply);
4902  _dbus_verbose ("no memory for error send in dispatch\n");
4903  goto out;
4904  }
4905 
4906  _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
4907  reply, NULL);
4908  /* reply will be freed when we release the lock */
4909  _dbus_list_prepend_link (&connection->expired_messages, expire_link);
4910 
4911  result = DBUS_HANDLER_RESULT_HANDLED;
4912  }
4913 
4914  _dbus_verbose (" done dispatching %p (%s %s %s '%s') on connection %p\n", message,
4916  dbus_message_get_interface (message) ?
4917  dbus_message_get_interface (message) :
4918  "no interface",
4919  dbus_message_get_member (message) ?
4920  dbus_message_get_member (message) :
4921  "no member",
4922  dbus_message_get_signature (message),
4923  connection);
4924 
4925  out:
4926  if (result == DBUS_HANDLER_RESULT_LATER ||
4928  {
4929  if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
4930  _dbus_verbose ("out of memory\n");
4931 
4932  /* Put message back, and we'll start over.
4933  * Yes this means handlers must be idempotent if they
4934  * don't return HANDLED; c'est la vie.
4935  */
4936  _dbus_connection_putback_message_link_unlocked (connection,
4937  message_link);
4938  /* now we don't want to free them */
4939  message_link = NULL;
4940  message = NULL;
4941  }
4942  else
4943  {
4944  _dbus_verbose (" ... done dispatching\n");
4945  }
4946 
4947  _dbus_connection_release_dispatch (connection);
4948  HAVE_LOCK_CHECK (connection);
4949 
4950  if (message != NULL)
4951  {
4952  /* We don't want this message to count in maximum message limits when
4953  * computing the dispatch status, below. We have to drop the lock
4954  * temporarily, because finalizing a message can trigger callbacks.
4955  *
4956  * We have a reference to the connection, and we don't use any cached
4957  * pointers to the connection's internals below this point, so it should
4958  * be safe to drop the lock and take it back. */
4959  CONNECTION_UNLOCK (connection);
4960  dbus_message_unref (message);
4961  CONNECTION_LOCK (connection);
4962  }
4963 
4964  if (message_link != NULL)
4965  _dbus_list_free_link (message_link);
4966 
4967  _dbus_verbose ("before final status update\n");
4968  status = _dbus_connection_get_dispatch_status_unlocked (connection);
4969 
4970  /* unlocks and calls user code */
4971  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
4972 
4973  dbus_connection_unref (connection);
4974 
4975  return status;
4976 }
4977 
5041  DBusAddWatchFunction add_function,
5042  DBusRemoveWatchFunction remove_function,
5043  DBusWatchToggledFunction toggled_function,
5044  void *data,
5045  DBusFreeFunction free_data_function)
5046 {
5047  dbus_bool_t retval;
5048 
5049  _dbus_return_val_if_fail (connection != NULL, FALSE);
5050 
5051  CONNECTION_LOCK (connection);
5052 
5053  retval = _dbus_watch_list_set_functions (connection->watches,
5054  add_function, remove_function,
5055  toggled_function,
5056  data, free_data_function);
5057 
5058  CONNECTION_UNLOCK (connection);
5059 
5060  return retval;
5061 }
5062 
5104  DBusAddTimeoutFunction add_function,
5105  DBusRemoveTimeoutFunction remove_function,
5106  DBusTimeoutToggledFunction toggled_function,
5107  void *data,
5108  DBusFreeFunction free_data_function)
5109 {
5110  dbus_bool_t retval;
5111 
5112  _dbus_return_val_if_fail (connection != NULL, FALSE);
5113 
5114  CONNECTION_LOCK (connection);
5115 
5116  retval = _dbus_timeout_list_set_functions (connection->timeouts,
5117  add_function, remove_function,
5118  toggled_function,
5119  data, free_data_function);
5120 
5121  CONNECTION_UNLOCK (connection);
5122 
5123  return retval;
5124 }
5125 
5140 void
5142  DBusWakeupMainFunction wakeup_main_function,
5143  void *data,
5144  DBusFreeFunction free_data_function)
5145 {
5146  void *old_data;
5147  DBusFreeFunction old_free_data;
5148 
5149  _dbus_return_if_fail (connection != NULL);
5150 
5151  CONNECTION_LOCK (connection);
5152  old_data = connection->wakeup_main_data;
5153  old_free_data = connection->free_wakeup_main_data;
5154 
5155  connection->wakeup_main_function = wakeup_main_function;
5156  connection->wakeup_main_data = data;
5157  connection->free_wakeup_main_data = free_data_function;
5158 
5159  CONNECTION_UNLOCK (connection);
5160 
5161  /* Callback outside the lock */
5162  if (old_free_data)
5163  (*old_free_data) (old_data);
5164 }
5165 
5186 void
5188  DBusDispatchStatusFunction function,
5189  void *data,
5190  DBusFreeFunction free_data_function)
5191 {
5192  void *old_data;
5193  DBusFreeFunction old_free_data;
5194 
5195  _dbus_return_if_fail (connection != NULL);
5196 
5197  CONNECTION_LOCK (connection);
5198  old_data = connection->dispatch_status_data;
5199  old_free_data = connection->free_dispatch_status_data;
5200 
5201  connection->dispatch_status_function = function;
5202  connection->dispatch_status_data = data;
5203  connection->free_dispatch_status_data = free_data_function;
5204 
5205  CONNECTION_UNLOCK (connection);
5206 
5207  /* Callback outside the lock */
5208  if (old_free_data)
5209  (*old_free_data) (old_data);
5210 }
5211 
5233  int *fd)
5234 {
5235  _dbus_return_val_if_fail (connection != NULL, FALSE);
5236  _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
5237 
5238 #ifdef DBUS_WIN
5239  /* FIXME do this on a lower level */
5240  return FALSE;
5241 #endif
5242 
5243  return dbus_connection_get_socket(connection, fd);
5244 }
5245 
5263  int *fd)
5264 {
5265  dbus_bool_t retval;
5266 
5267  _dbus_return_val_if_fail (connection != NULL, FALSE);
5268  _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
5269 
5270  CONNECTION_LOCK (connection);
5271 
5272  retval = _dbus_transport_get_socket_fd (connection->transport,
5273  fd);
5274 
5275  CONNECTION_UNLOCK (connection);
5276 
5277  return retval;
5278 }
5279 
5280 
5305  unsigned long *uid)
5306 {
5307  dbus_bool_t result;
5308 
5309  _dbus_return_val_if_fail (connection != NULL, FALSE);
5310  _dbus_return_val_if_fail (uid != NULL, FALSE);
5311 
5312  CONNECTION_LOCK (connection);
5313 
5315  result = FALSE;
5316  else
5317  result = _dbus_transport_get_unix_user (connection->transport,
5318  uid);
5319 
5320 #ifdef DBUS_WIN
5321  _dbus_assert (!result);
5322 #endif
5323 
5324  CONNECTION_UNLOCK (connection);
5325 
5326  return result;
5327 }
5328 
5341  unsigned long *pid)
5342 {
5343  dbus_bool_t result;
5344 
5345  _dbus_return_val_if_fail (connection != NULL, FALSE);
5346  _dbus_return_val_if_fail (pid != NULL, FALSE);
5347 
5348  CONNECTION_LOCK (connection);
5349 
5351  result = FALSE;
5352  else
5353  result = _dbus_transport_get_unix_process_id (connection->transport,
5354  pid);
5355 
5356  CONNECTION_UNLOCK (connection);
5357 
5358  return result;
5359 }
5360 
5361 #ifdef DBUS_ENABLE_SMACK
5362 
5371 dbus_connection_get_smack_label (DBusConnection *connection,
5372  const char **label)
5373 {
5374  _dbus_return_val_if_fail (connection != NULL, FALSE);
5375  _dbus_return_val_if_fail (label != NULL, FALSE);
5376 
5377  *label = connection->peer_smack_label;
5378  return *label != NULL;
5379 }
5380 #endif
5381 
5395  void **data,
5396  dbus_int32_t *data_size)
5397 {
5398  dbus_bool_t result;
5399 
5400  _dbus_return_val_if_fail (connection != NULL, FALSE);
5401  _dbus_return_val_if_fail (data != NULL, FALSE);
5402  _dbus_return_val_if_fail (data_size != NULL, FALSE);
5403 
5404  CONNECTION_LOCK (connection);
5405 
5407  result = FALSE;
5408  else
5410  data,
5411  data_size);
5412  CONNECTION_UNLOCK (connection);
5413 
5414  return result;
5415 }
5416 
5439 void
5441  DBusAllowUnixUserFunction function,
5442  void *data,
5443  DBusFreeFunction free_data_function)
5444 {
5445  void *old_data = NULL;
5446  DBusFreeFunction old_free_function = NULL;
5447 
5448  _dbus_return_if_fail (connection != NULL);
5449 
5450  CONNECTION_LOCK (connection);
5452  function, data, free_data_function,
5453  &old_data, &old_free_function);
5454  CONNECTION_UNLOCK (connection);
5455 
5456  if (old_free_function != NULL)
5457  (* old_free_function) (old_data);
5458 }
5459 
5493  char **windows_sid_p)
5494 {
5495  dbus_bool_t result;
5496 
5497  _dbus_return_val_if_fail (connection != NULL, FALSE);
5498  _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
5499 
5500  CONNECTION_LOCK (connection);
5501 
5503  result = FALSE;
5504  else
5505  result = _dbus_transport_get_windows_user (connection->transport,
5506  windows_sid_p);
5507 
5508 #ifdef DBUS_UNIX
5509  _dbus_assert (!result);
5510 #endif
5511 
5512  CONNECTION_UNLOCK (connection);
5513 
5514  return result;
5515 }
5516 
5538 void
5541  void *data,
5542  DBusFreeFunction free_data_function)
5543 {
5544  void *old_data = NULL;
5545  DBusFreeFunction old_free_function = NULL;
5546 
5547  _dbus_return_if_fail (connection != NULL);
5548 
5549  CONNECTION_LOCK (connection);
5551  function, data, free_data_function,
5552  &old_data, &old_free_function);
5553  CONNECTION_UNLOCK (connection);
5554 
5555  if (old_free_function != NULL)
5556  (* old_free_function) (old_data);
5557 }
5558 
5585 void
5587  dbus_bool_t value)
5588 {
5589  _dbus_return_if_fail (connection != NULL);
5590 
5591  CONNECTION_LOCK (connection);
5592  _dbus_transport_set_allow_anonymous (connection->transport, value);
5593  CONNECTION_UNLOCK (connection);
5594 }
5595 
5613 void
5615  dbus_bool_t value)
5616 {
5617  _dbus_return_if_fail (connection != NULL);
5618 
5619  CONNECTION_LOCK (connection);
5620  connection->route_peer_messages = value;
5621  CONNECTION_UNLOCK (connection);
5622 }
5623 
5647  DBusHandleMessageFunction function,
5648  void *user_data,
5649  DBusFreeFunction free_data_function)
5650 {
5651  DBusMessageFilter *filter;
5652 
5653  _dbus_return_val_if_fail (connection != NULL, FALSE);
5654  _dbus_return_val_if_fail (function != NULL, FALSE);
5655 
5656  filter = dbus_new0 (DBusMessageFilter, 1);
5657  if (filter == NULL)
5658  return FALSE;
5659 
5660  _dbus_atomic_inc (&filter->refcount);
5661 
5662  CONNECTION_LOCK (connection);
5663 
5664  if (!_dbus_list_append (&connection->filter_list,
5665  filter))
5666  {
5667  _dbus_message_filter_unref (filter);
5668  CONNECTION_UNLOCK (connection);
5669  return FALSE;
5670  }
5671 
5672  /* Fill in filter after all memory allocated,
5673  * so we don't run the free_user_data_function
5674  * if the add_filter() fails
5675  */
5676 
5677  filter->function = function;
5678  filter->user_data = user_data;
5679  filter->free_user_data_function = free_data_function;
5680 
5681  CONNECTION_UNLOCK (connection);
5682  return TRUE;
5683 }
5684 
5697 void
5699  DBusHandleMessageFunction function,
5700  void *user_data)
5701 {
5702  DBusList *link;
5703  DBusMessageFilter *filter;
5704 
5705  _dbus_return_if_fail (connection != NULL);
5706  _dbus_return_if_fail (function != NULL);
5707 
5708  CONNECTION_LOCK (connection);
5709 
5710  filter = NULL;
5711 
5712  link = _dbus_list_get_last_link (&connection->filter_list);
5713  while (link != NULL)
5714  {
5715  filter = link->data;
5716 
5717  if (filter->function == function &&
5718  filter->user_data == user_data)
5719  {
5720  _dbus_list_remove_link (&connection->filter_list, link);
5721  filter->function = NULL;
5722 
5723  break;
5724  }
5725 
5726  link = _dbus_list_get_prev_link (&connection->filter_list, link);
5727  filter = NULL;
5728  }
5729 
5730  CONNECTION_UNLOCK (connection);
5731 
5732 #ifndef DBUS_DISABLE_CHECKS
5733  if (filter == NULL)
5734  {
5735  _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
5736  function, user_data);
5737  return;
5738  }
5739 #endif
5740 
5741  /* Call application code */
5742  if (filter->free_user_data_function)
5743  (* filter->free_user_data_function) (filter->user_data);
5744 
5745  filter->free_user_data_function = NULL;
5746  filter->user_data = NULL;
5747 
5748  _dbus_message_filter_unref (filter);
5749 }
5750 
5766 static dbus_bool_t
5767 _dbus_connection_register_object_path (DBusConnection *connection,
5768  dbus_bool_t fallback,
5769  const char *path,
5770  const DBusObjectPathVTable *vtable,
5771  void *user_data,
5772  DBusError *error)
5773 {
5774  char **decomposed_path;
5775  dbus_bool_t retval;
5776 
5777  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
5778  return FALSE;
5779 
5780  CONNECTION_LOCK (connection);
5781 
5782  retval = _dbus_object_tree_register (connection->objects,
5783  fallback,
5784  (const char **) decomposed_path, vtable,
5785  user_data, error);
5786 
5787  CONNECTION_UNLOCK (connection);
5788 
5789  dbus_free_string_array (decomposed_path);
5790 
5791  return retval;
5792 }
5793 
5808  const char *path,
5809  const DBusObjectPathVTable *vtable,
5810  void *user_data,
5811  DBusError *error)
5812 {
5813  _dbus_return_val_if_fail (connection != NULL, FALSE);
5814  _dbus_return_val_if_fail (path != NULL, FALSE);
5815  _dbus_return_val_if_fail (path[0] == '/', FALSE);
5816  _dbus_return_val_if_fail (vtable != NULL, FALSE);
5817 
5818  return _dbus_connection_register_object_path (connection, FALSE, path, vtable, user_data, error);
5819 }
5820 
5838  const char *path,
5839  const DBusObjectPathVTable *vtable,
5840  void *user_data)
5841 {
5842  dbus_bool_t retval;
5843  DBusError error = DBUS_ERROR_INIT;
5844 
5845  _dbus_return_val_if_fail (connection != NULL, FALSE);
5846  _dbus_return_val_if_fail (path != NULL, FALSE);
5847  _dbus_return_val_if_fail (path[0] == '/', FALSE);
5848  _dbus_return_val_if_fail (vtable != NULL, FALSE);
5849 
5850  retval = _dbus_connection_register_object_path (connection, FALSE, path, vtable, user_data, &error);
5851 
5853  {
5854  _dbus_warn ("%s\n", error.message);
5855  dbus_error_free (&error);
5856  return FALSE;
5857  }
5858 
5859  return retval;
5860 }
5861 
5878  const char *path,
5879  const DBusObjectPathVTable *vtable,
5880  void *user_data,
5881  DBusError *error)
5882 {
5883  _dbus_return_val_if_fail (connection != NULL, FALSE);
5884  _dbus_return_val_if_fail (path != NULL, FALSE);
5885  _dbus_return_val_if_fail (path[0] == '/', FALSE);
5886  _dbus_return_val_if_fail (vtable != NULL, FALSE);
5887 
5888  return _dbus_connection_register_object_path (connection, TRUE, path, vtable, user_data, error);
5889 }
5890 
5910  const char *path,
5911  const DBusObjectPathVTable *vtable,
5912  void *user_data)
5913 {
5914  dbus_bool_t retval;
5915  DBusError error = DBUS_ERROR_INIT;
5916 
5917  _dbus_return_val_if_fail (connection != NULL, FALSE);
5918  _dbus_return_val_if_fail (path != NULL, FALSE);
5919  _dbus_return_val_if_fail (path[0] == '/', FALSE);
5920  _dbus_return_val_if_fail (vtable != NULL, FALSE);
5921 
5922  retval = _dbus_connection_register_object_path (connection, TRUE, path, vtable, user_data, &error);
5923 
5925  {
5926  _dbus_warn ("%s\n", error.message);
5927  dbus_error_free (&error);
5928  return FALSE;
5929  }
5930 
5931  return retval;
5932 }
5933 
5945  const char *path)
5946 {
5947  char **decomposed_path;
5948 
5949  _dbus_return_val_if_fail (connection != NULL, FALSE);
5950  _dbus_return_val_if_fail (path != NULL, FALSE);
5951  _dbus_return_val_if_fail (path[0] == '/', FALSE);
5952 
5953  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
5954  return FALSE;
5955 
5956  CONNECTION_LOCK (connection);
5957 
5958  _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
5959 
5960  dbus_free_string_array (decomposed_path);
5961 
5962  return TRUE;
5963 }
5964 
5977  const char *path,
5978  void **data_p)
5979 {
5980  char **decomposed_path;
5981 
5982  _dbus_return_val_if_fail (connection != NULL, FALSE);
5983  _dbus_return_val_if_fail (path != NULL, FALSE);
5984  _dbus_return_val_if_fail (data_p != NULL, FALSE);
5985 
5986  *data_p = NULL;
5987 
5988  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
5989  return FALSE;
5990 
5991  CONNECTION_LOCK (connection);
5992 
5993  *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path);
5994 
5995  CONNECTION_UNLOCK (connection);
5996 
5997  dbus_free_string_array (decomposed_path);
5998 
5999  return TRUE;
6000 }
6001 
6014  const char *parent_path,
6015  char ***child_entries)
6016 {
6017  char **decomposed_path;
6018  dbus_bool_t retval;
6019  _dbus_return_val_if_fail (connection != NULL, FALSE);
6020  _dbus_return_val_if_fail (parent_path != NULL, FALSE);
6021  _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
6022  _dbus_return_val_if_fail (child_entries != NULL, FALSE);
6023 
6024  if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
6025  return FALSE;
6026 
6027  CONNECTION_LOCK (connection);
6028 
6030  (const char **) decomposed_path,
6031  child_entries);
6032  dbus_free_string_array (decomposed_path);
6033 
6034  return retval;
6035 }
6036 
6037 static DBusDataSlotAllocator slot_allocator =
6038  _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (connection_slots));
6039 
6056 {
6057  return _dbus_data_slot_allocator_alloc (&slot_allocator,
6058  slot_p);
6059 }
6060 
6072 void
6074 {
6075  _dbus_return_if_fail (*slot_p >= 0);
6076 
6077  _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
6078 }
6079 
6104  dbus_int32_t slot,
6105  void *data,
6106  DBusFreeFunction free_data_func)
6107 {
6108  DBusFreeFunction old_free_func;
6109  void *old_data;
6110  dbus_bool_t retval;
6111 
6112  _dbus_return_val_if_fail (connection != NULL, FALSE);
6113  _dbus_return_val_if_fail (slot >= 0, FALSE);
6114 
6115  SLOTS_LOCK (connection);
6116 
6117  retval = _dbus_data_slot_list_set (&slot_allocator,
6118  &connection->slot_list,
6119  slot, data, free_data_func,
6120  &old_free_func, &old_data);
6121 
6122  SLOTS_UNLOCK (connection);
6123 
6124  if (retval)
6125  {
6126  /* Do the actual free outside the connection lock */
6127  if (old_free_func)
6128  (* old_free_func) (old_data);
6129  }
6130 
6131  return retval;
6132 }
6133 
6151 void*
6153  dbus_int32_t slot)
6154 {
6155  void *res;
6156 
6157  _dbus_return_val_if_fail (connection != NULL, NULL);
6158  _dbus_return_val_if_fail (slot >= 0, NULL);
6159 
6160  SLOTS_LOCK (connection);
6161 
6162  res = _dbus_data_slot_list_get (&slot_allocator,
6163  &connection->slot_list,
6164  slot);
6165 
6166  SLOTS_UNLOCK (connection);
6167 
6168  return res;
6169 }
6170 
6177 void
6179 {
6180  _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
6181 }
6182 
6191 void
6193  long size)
6194 {
6195  _dbus_return_if_fail (connection != NULL);
6196 
6197  CONNECTION_LOCK (connection);
6199  size);
6200  CONNECTION_UNLOCK (connection);
6201 }
6202 
6209 long
6211 {
6212  long res;
6213 
6214  _dbus_return_val_if_fail (connection != NULL, 0);
6215 
6216  CONNECTION_LOCK (connection);
6217  res = _dbus_transport_get_max_message_size (connection->transport);
6218  CONNECTION_UNLOCK (connection);
6219  return res;
6220 }
6221 
6230 void
6232  long n)
6233 {
6234  _dbus_return_if_fail (connection != NULL);
6235 
6236  CONNECTION_LOCK (connection);
6238  n);
6239  CONNECTION_UNLOCK (connection);
6240 }
6241 
6248 long
6250 {
6251  long res;
6252 
6253  _dbus_return_val_if_fail (connection != NULL, 0);
6254 
6255  CONNECTION_LOCK (connection);
6257  CONNECTION_UNLOCK (connection);
6258  return res;
6259 }
6260 
6286 void
6288  long size)
6289 {
6290  _dbus_return_if_fail (connection != NULL);
6291 
6292  CONNECTION_LOCK (connection);
6294  size);
6295  CONNECTION_UNLOCK (connection);
6296 }
6297 
6304 long
6306 {
6307  long res;
6308 
6309  _dbus_return_val_if_fail (connection != NULL, 0);
6310 
6311  CONNECTION_LOCK (connection);
6313  CONNECTION_UNLOCK (connection);
6314  return res;
6315 }
6316 
6328 void
6330  long n)
6331 {
6332  _dbus_return_if_fail (connection != NULL);
6333 
6334  CONNECTION_LOCK (connection);
6336  n);
6337  CONNECTION_UNLOCK (connection);
6338 }
6339 
6346 long
6348 {
6349  long res;
6350 
6351  _dbus_return_val_if_fail (connection != NULL, 0);
6352 
6353  CONNECTION_LOCK (connection);
6355  CONNECTION_UNLOCK (connection);
6356  return res;
6357 }
6358 
6369 long
6371 {
6372  long res;
6373 
6374  _dbus_return_val_if_fail (connection != NULL, 0);
6375 
6376  CONNECTION_LOCK (connection);
6377  res = _dbus_counter_get_size_value (connection->outgoing_counter);
6378  CONNECTION_UNLOCK (connection);
6379  return res;
6380 }
6381 
6382 #ifdef DBUS_ENABLE_STATS
6383 void
6384 _dbus_connection_get_stats (DBusConnection *connection,
6385  dbus_uint32_t *in_messages,
6386  dbus_uint32_t *in_bytes,
6387  dbus_uint32_t *in_fds,
6388  dbus_uint32_t *in_peak_bytes,
6389  dbus_uint32_t *in_peak_fds,
6390  dbus_uint32_t *out_messages,
6391  dbus_uint32_t *out_bytes,
6392  dbus_uint32_t *out_fds,
6393  dbus_uint32_t *out_peak_bytes,
6394  dbus_uint32_t *out_peak_fds)
6395 {
6396  CONNECTION_LOCK (connection);
6397 
6398  if (in_messages != NULL)
6399  *in_messages = connection->n_incoming;
6400 
6401  _dbus_transport_get_stats (connection->transport,
6402  in_bytes, in_fds, in_peak_bytes, in_peak_fds);
6403 
6404  if (out_messages != NULL)
6405  *out_messages = connection->n_outgoing;
6406 
6407  if (out_bytes != NULL)
6408  *out_bytes = _dbus_counter_get_size_value (connection->outgoing_counter);
6409 
6410  if (out_fds != NULL)
6411  *out_fds = _dbus_counter_get_unix_fd_value (connection->outgoing_counter);
6412 
6413  if (out_peak_bytes != NULL)
6414  *out_peak_bytes = _dbus_counter_get_peak_size_value (connection->outgoing_counter);
6415 
6416  if (out_peak_fds != NULL)
6417  *out_peak_fds = _dbus_counter_get_peak_unix_fd_value (connection->outgoing_counter);
6418 
6419  CONNECTION_UNLOCK (connection);
6420 }
6421 #endif /* DBUS_ENABLE_STATS */
6422 
6430 long
6432 {
6433  long res;
6434 
6435  _dbus_return_val_if_fail (connection != NULL, 0);
6436 
6437  CONNECTION_LOCK (connection);
6439  CONNECTION_UNLOCK (connection);
6440  return res;
6441 }
6442 
6443 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
6444 
6450 const char*
6451 _dbus_connection_get_address (DBusConnection *connection)
6452 {
6453  return _dbus_transport_get_address (connection->transport);
6454 }
6455 #endif
6456