D-Bus  1.6.12
dbus-connection.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-connection.c DBusConnection object
3  *
4  * Copyright (C) 2002-2006 Red Hat Inc.
5  *
6  * Licensed under the Academic Free License version 2.1
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  */
23 
24 #include <config.h>
25 #include "dbus-shared.h"
26 #include "dbus-connection.h"
27 #include "dbus-list.h"
28 #include "dbus-timeout.h"
29 #include "dbus-transport.h"
30 #include "dbus-watch.h"
31 #include "dbus-connection-internal.h"
32 #include "dbus-pending-call-internal.h"
33 #include "dbus-list.h"
34 #include "dbus-hash.h"
35 #include "dbus-message-internal.h"
36 #include "dbus-message-private.h"
37 #include "dbus-threads.h"
38 #include "dbus-protocol.h"
39 #include "dbus-dataslot.h"
40 #include "dbus-string.h"
41 #include "dbus-signature.h"
42 #include "dbus-pending-call.h"
43 #include "dbus-object-tree.h"
44 #include "dbus-threads-internal.h"
45 #include "dbus-bus.h"
46 #include "dbus-marshal-basic.h"
47 
48 #ifdef DBUS_DISABLE_CHECKS
49 #define TOOK_LOCK_CHECK(connection)
50 #define RELEASING_LOCK_CHECK(connection)
51 #define HAVE_LOCK_CHECK(connection)
52 #else
53 #define TOOK_LOCK_CHECK(connection) do { \
54  _dbus_assert (!(connection)->have_connection_lock); \
55  (connection)->have_connection_lock = TRUE; \
56  } while (0)
57 #define RELEASING_LOCK_CHECK(connection) do { \
58  _dbus_assert ((connection)->have_connection_lock); \
59  (connection)->have_connection_lock = FALSE; \
60  } while (0)
61 #define HAVE_LOCK_CHECK(connection) _dbus_assert ((connection)->have_connection_lock)
62 /* A "DO_NOT_HAVE_LOCK_CHECK" is impossible since we need the lock to check the flag */
63 #endif
64 
65 #define TRACE_LOCKS 1
66 
67 #define CONNECTION_LOCK(connection) do { \
68  if (TRACE_LOCKS) { _dbus_verbose ("LOCK\n"); } \
69  _dbus_rmutex_lock ((connection)->mutex); \
70  TOOK_LOCK_CHECK (connection); \
71  } while (0)
72 
73 #define CONNECTION_UNLOCK(connection) _dbus_connection_unlock (connection)
74 
75 #define SLOTS_LOCK(connection) do { \
76  _dbus_rmutex_lock ((connection)->slot_mutex); \
77  } while (0)
78 
79 #define SLOTS_UNLOCK(connection) do { \
80  _dbus_rmutex_unlock ((connection)->slot_mutex); \
81  } while (0)
82 
83 #define DISPATCH_STATUS_NAME(s) \
84  ((s) == DBUS_DISPATCH_COMPLETE ? "complete" : \
85  (s) == DBUS_DISPATCH_DATA_REMAINS ? "data remains" : \
86  (s) == DBUS_DISPATCH_NEED_MEMORY ? "need memory" : \
87  "???")
88 
206 #ifdef DBUS_ENABLE_VERBOSE_MODE
207 static void
208 _dbus_connection_trace_ref (DBusConnection *connection,
209  int old_refcount,
210  int new_refcount,
211  const char *why)
212 {
213  static int enabled = -1;
214 
215  _dbus_trace_ref ("DBusConnection", connection, old_refcount, new_refcount,
216  why, "DBUS_CONNECTION_TRACE", &enabled);
217 }
218 #else
219 #define _dbus_connection_trace_ref(c,o,n,w) \
220  do \
221  {\
222  (void) (o); \
223  (void) (n); \
224  } while (0)
225 #endif
226 
231 
236 {
239  void *user_data;
241 };
242 
243 
248 {
252 };
253 
254 #if HAVE_DECL_MSG_NOSIGNAL
255 static dbus_bool_t _dbus_modify_sigpipe = FALSE;
256 #else
257 static dbus_bool_t _dbus_modify_sigpipe = TRUE;
258 #endif
259 
264 {
313  char *server_guid;
315  /* These two MUST be bools and not bitfields, because they are protected by a separate lock
316  * from connection->mutex and all bitfields in a word have to be read/written together.
317  * So you can't have a different lock for different bitfields in the same word.
318  */
322  unsigned int shareable : 1;
324  unsigned int exit_on_disconnect : 1;
326  unsigned int route_peer_messages : 1;
328  unsigned int disconnected_message_arrived : 1;
336 #ifndef DBUS_DISABLE_CHECKS
337  unsigned int have_connection_lock : 1;
338 #endif
339 
340 #ifndef DBUS_DISABLE_CHECKS
342 #endif
343 };
344 
345 static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection);
346 static void _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
347  DBusDispatchStatus new_status);
348 static void _dbus_connection_last_unref (DBusConnection *connection);
349 static void _dbus_connection_acquire_dispatch (DBusConnection *connection);
350 static void _dbus_connection_release_dispatch (DBusConnection *connection);
351 static DBusDispatchStatus _dbus_connection_flush_unlocked (DBusConnection *connection);
352 static void _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection);
353 static dbus_bool_t _dbus_connection_get_is_connected_unlocked (DBusConnection *connection);
354 static dbus_bool_t _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection,
355  dbus_uint32_t client_serial);
356 
357 static DBusMessageFilter *
358 _dbus_message_filter_ref (DBusMessageFilter *filter)
359 {
360 #ifdef DBUS_DISABLE_ASSERT
361  _dbus_atomic_inc (&filter->refcount);
362 #else
363  dbus_int32_t old_value;
364 
365  old_value = _dbus_atomic_inc (&filter->refcount);
366  _dbus_assert (old_value > 0);
367 #endif
368 
369  return filter;
370 }
371 
372 static void
373 _dbus_message_filter_unref (DBusMessageFilter *filter)
374 {
375  dbus_int32_t old_value;
376 
377  old_value = _dbus_atomic_dec (&filter->refcount);
378  _dbus_assert (old_value > 0);
379 
380  if (old_value == 1)
381  {
382  if (filter->free_user_data_function)
383  (* filter->free_user_data_function) (filter->user_data);
384 
385  dbus_free (filter);
386  }
387 }
388 
394 void
396 {
397  CONNECTION_LOCK (connection);
398 }
399 
405 void
407 {
408  DBusList *expired_messages;
409  DBusList *iter;
410 
411  if (TRACE_LOCKS)
412  {
413  _dbus_verbose ("UNLOCK\n");
414  }
415 
416  /* If we had messages that expired (fell off the incoming or outgoing
417  * queues) while we were locked, actually release them now */
418  expired_messages = connection->expired_messages;
419  connection->expired_messages = NULL;
420 
421  RELEASING_LOCK_CHECK (connection);
422  _dbus_rmutex_unlock (connection->mutex);
423 
424  for (iter = _dbus_list_pop_first_link (&expired_messages);
425  iter != NULL;
426  iter = _dbus_list_pop_first_link (&expired_messages))
427  {
428  DBusMessage *message = iter->data;
429 
430  dbus_message_unref (message);
431  _dbus_list_free_link (iter);
432  }
433 }
434 
442 static void
443 _dbus_connection_wakeup_mainloop (DBusConnection *connection)
444 {
445  if (connection->wakeup_main_function)
446  (*connection->wakeup_main_function) (connection->wakeup_main_data);
447 }
448 
449 #ifdef DBUS_BUILD_TESTS
450 
462 void
463 _dbus_connection_test_get_locks (DBusConnection *connection,
464  DBusMutex **mutex_loc,
465  DBusMutex **dispatch_mutex_loc,
466  DBusMutex **io_path_mutex_loc,
467  DBusCondVar **dispatch_cond_loc,
468  DBusCondVar **io_path_cond_loc)
469 {
470  *mutex_loc = (DBusMutex *) connection->mutex;
471  *dispatch_mutex_loc = (DBusMutex *) connection->dispatch_mutex;
472  *io_path_mutex_loc = (DBusMutex *) connection->io_path_mutex;
473  *dispatch_cond_loc = connection->dispatch_cond;
474  *io_path_cond_loc = connection->io_path_cond;
475 }
476 #endif
477 
486 void
488  DBusList *link)
489 {
490  DBusPendingCall *pending;
491  dbus_uint32_t reply_serial;
492  DBusMessage *message;
493 
495 
497  link);
498  message = link->data;
499 
500  /* If this is a reply we're waiting on, remove timeout for it */
501  reply_serial = dbus_message_get_reply_serial (message);
502  if (reply_serial != 0)
503  {
504  pending = _dbus_hash_table_lookup_int (connection->pending_replies,
505  reply_serial);
506  if (pending != NULL)
507  {
511 
513  }
514  }
515 
516 
517 
518  connection->n_incoming += 1;
519 
520  _dbus_connection_wakeup_mainloop (connection);
521 
522  _dbus_verbose ("Message %p (%s %s %s %s '%s' reply to %u) added to incoming queue %p, %d incoming\n",
523  message,
525  dbus_message_get_path (message) ?
526  dbus_message_get_path (message) :
527  "no path",
528  dbus_message_get_interface (message) ?
529  dbus_message_get_interface (message) :
530  "no interface",
531  dbus_message_get_member (message) ?
532  dbus_message_get_member (message) :
533  "no member",
534  dbus_message_get_signature (message),
536  connection,
537  connection->n_incoming);
538 
539  _dbus_message_trace_ref (message, -1, -1,
540  "_dbus_conection_queue_received_message_link");
541 }
542 
551 void
553  DBusList *link)
554 {
555  HAVE_LOCK_CHECK (connection);
556 
557  _dbus_list_append_link (&connection->incoming_messages, link);
558 
559  connection->n_incoming += 1;
560 
561  _dbus_connection_wakeup_mainloop (connection);
562 
563  _dbus_message_trace_ref (link->data, -1, -1,
564  "_dbus_connection_queue_synthesized_message_link");
565 
566  _dbus_verbose ("Synthesized message %p added to incoming queue %p, %d incoming\n",
567  link->data, connection, connection->n_incoming);
568 }
569 
570 
580 {
581  HAVE_LOCK_CHECK (connection);
582  return connection->outgoing_messages != NULL;
583 }
584 
596 {
597  dbus_bool_t v;
598 
599  _dbus_return_val_if_fail (connection != NULL, FALSE);
600 
601  CONNECTION_LOCK (connection);
603  CONNECTION_UNLOCK (connection);
604 
605  return v;
606 }
607 
617 {
618  HAVE_LOCK_CHECK (connection);
619 
620  return _dbus_list_get_last (&connection->outgoing_messages);
621 }
622 
631 void
633  DBusMessage *message)
634 {
635  DBusList *link;
636 
637  HAVE_LOCK_CHECK (connection);
638 
639  /* This can be called before we even complete authentication, since
640  * it's called on disconnect to clean up the outgoing queue.
641  * It's also called as we successfully send each message.
642  */
643 
644  link = _dbus_list_get_last_link (&connection->outgoing_messages);
645  _dbus_assert (link != NULL);
646  _dbus_assert (link->data == message);
647 
648  _dbus_list_unlink (&connection->outgoing_messages,
649  link);
650  _dbus_list_prepend_link (&connection->expired_messages, link);
651 
652  connection->n_outgoing -= 1;
653 
654  _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from outgoing queue %p, %d left to send\n",
655  message,
657  dbus_message_get_path (message) ?
658  dbus_message_get_path (message) :
659  "no path",
660  dbus_message_get_interface (message) ?
661  dbus_message_get_interface (message) :
662  "no interface",
663  dbus_message_get_member (message) ?
664  dbus_message_get_member (message) :
665  "no member",
666  dbus_message_get_signature (message),
667  connection, connection->n_outgoing);
668 
669  /* It's OK that in principle we call the notify function, because for the
670  * outgoing limit, there isn't one */
671  _dbus_message_remove_counter (message, connection->outgoing_counter);
672 
673  /* The message will actually be unreffed when we unlock */
674 }
675 
678  DBusWatch *watch);
680 typedef void (* DBusWatchRemoveFunction) (DBusWatchList *list,
681  DBusWatch *watch);
683 typedef void (* DBusWatchToggleFunction) (DBusWatchList *list,
684  DBusWatch *watch,
685  dbus_bool_t enabled);
686 
687 static dbus_bool_t
688 protected_change_watch (DBusConnection *connection,
689  DBusWatch *watch,
690  DBusWatchAddFunction add_function,
691  DBusWatchRemoveFunction remove_function,
692  DBusWatchToggleFunction toggle_function,
693  dbus_bool_t enabled)
694 {
695  dbus_bool_t retval;
696 
697  HAVE_LOCK_CHECK (connection);
698 
699  /* The original purpose of protected_change_watch() was to hold a
700  * ref on the connection while dropping the connection lock, then
701  * calling out to the app. This was a broken hack that did not
702  * work, since the connection was in a hosed state (no WatchList
703  * field) while calling out.
704  *
705  * So for now we'll just keep the lock while calling out. This means
706  * apps are not allowed to call DBusConnection methods inside a
707  * watch function or they will deadlock.
708  *
709  * The "real fix" is to use the _and_unlock() pattern found
710  * elsewhere in the code, to defer calling out to the app until
711  * we're about to drop locks and return flow of control to the app
712  * anyway.
713  *
714  * See http://lists.freedesktop.org/archives/dbus/2007-July/thread.html#8144
715  */
716 
717  if (connection->watches)
718  {
719  if (add_function)
720  retval = (* add_function) (connection->watches, watch);
721  else if (remove_function)
722  {
723  retval = TRUE;
724  (* remove_function) (connection->watches, watch);
725  }
726  else
727  {
728  retval = TRUE;
729  (* toggle_function) (connection->watches, watch, enabled);
730  }
731  return retval;
732  }
733  else
734  return FALSE;
735 }
736 
737 
751  DBusWatch *watch)
752 {
753  return protected_change_watch (connection, watch,
755  NULL, NULL, FALSE);
756 }
757 
767 void
769  DBusWatch *watch)
770 {
771  protected_change_watch (connection, watch,
772  NULL,
774  NULL, FALSE);
775 }
776 
787 void
789  DBusWatch *watch,
790  dbus_bool_t enabled)
791 {
792  _dbus_assert (watch != NULL);
793 
794  protected_change_watch (connection, watch,
795  NULL, NULL,
797  enabled);
798 }
799 
802  DBusTimeout *timeout);
805  DBusTimeout *timeout);
808  DBusTimeout *timeout,
809  dbus_bool_t enabled);
810 
811 static dbus_bool_t
812 protected_change_timeout (DBusConnection *connection,
813  DBusTimeout *timeout,
814  DBusTimeoutAddFunction add_function,
815  DBusTimeoutRemoveFunction remove_function,
816  DBusTimeoutToggleFunction toggle_function,
817  dbus_bool_t enabled)
818 {
819  dbus_bool_t retval;
820 
821  HAVE_LOCK_CHECK (connection);
822 
823  /* The original purpose of protected_change_timeout() was to hold a
824  * ref on the connection while dropping the connection lock, then
825  * calling out to the app. This was a broken hack that did not
826  * work, since the connection was in a hosed state (no TimeoutList
827  * field) while calling out.
828  *
829  * So for now we'll just keep the lock while calling out. This means
830  * apps are not allowed to call DBusConnection methods inside a
831  * timeout function or they will deadlock.
832  *
833  * The "real fix" is to use the _and_unlock() pattern found
834  * elsewhere in the code, to defer calling out to the app until
835  * we're about to drop locks and return flow of control to the app
836  * anyway.
837  *
838  * See http://lists.freedesktop.org/archives/dbus/2007-July/thread.html#8144
839  */
840 
841  if (connection->timeouts)
842  {
843  if (add_function)
844  retval = (* add_function) (connection->timeouts, timeout);
845  else if (remove_function)
846  {
847  retval = TRUE;
848  (* remove_function) (connection->timeouts, timeout);
849  }
850  else
851  {
852  retval = TRUE;
853  (* toggle_function) (connection->timeouts, timeout, enabled);
854  }
855  return retval;
856  }
857  else
858  return FALSE;
859 }
860 
875  DBusTimeout *timeout)
876 {
877  return protected_change_timeout (connection, timeout,
879  NULL, NULL, FALSE);
880 }
881 
891 void
893  DBusTimeout *timeout)
894 {
895  protected_change_timeout (connection, timeout,
896  NULL,
898  NULL, FALSE);
899 }
900 
911 void
913  DBusTimeout *timeout,
914  dbus_bool_t enabled)
915 {
916  protected_change_timeout (connection, timeout,
917  NULL, NULL,
919  enabled);
920 }
921 
922 static dbus_bool_t
923 _dbus_connection_attach_pending_call_unlocked (DBusConnection *connection,
924  DBusPendingCall *pending)
925 {
926  dbus_uint32_t reply_serial;
927  DBusTimeout *timeout;
928 
929  HAVE_LOCK_CHECK (connection);
930 
931  reply_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
932 
933  _dbus_assert (reply_serial != 0);
934 
935  timeout = _dbus_pending_call_get_timeout_unlocked (pending);
936 
937  if (timeout)
938  {
939  if (!_dbus_connection_add_timeout_unlocked (connection, timeout))
940  return FALSE;
941 
943  reply_serial,
944  pending))
945  {
946  _dbus_connection_remove_timeout_unlocked (connection, timeout);
947 
949  HAVE_LOCK_CHECK (connection);
950  return FALSE;
951  }
952 
954  }
955  else
956  {
958  reply_serial,
959  pending))
960  {
961  HAVE_LOCK_CHECK (connection);
962  return FALSE;
963  }
964  }
965 
967 
968  HAVE_LOCK_CHECK (connection);
969 
970  return TRUE;
971 }
972 
973 static void
974 free_pending_call_on_hash_removal (void *data)
975 {
976  DBusPendingCall *pending;
977  DBusConnection *connection;
978 
979  if (data == NULL)
980  return;
981 
982  pending = data;
983 
984  connection = _dbus_pending_call_get_connection_unlocked (pending);
985 
986  HAVE_LOCK_CHECK (connection);
987 
989  {
992 
994  }
995 
996  /* FIXME 1.0? this is sort of dangerous and undesirable to drop the lock
997  * here, but the pending call finalizer could in principle call out to
998  * application code so we pretty much have to... some larger code reorg
999  * might be needed.
1000  */
1001  _dbus_connection_ref_unlocked (connection);
1003  CONNECTION_LOCK (connection);
1004  _dbus_connection_unref_unlocked (connection);
1005 }
1006 
1007 static void
1008 _dbus_connection_detach_pending_call_unlocked (DBusConnection *connection,
1009  DBusPendingCall *pending)
1010 {
1011  /* This ends up unlocking to call the pending call finalizer, which is unexpected to
1012  * say the least.
1013  */
1016 }
1017 
1018 static void
1019 _dbus_connection_detach_pending_call_and_unlock (DBusConnection *connection,
1020  DBusPendingCall *pending)
1021 {
1022  /* The idea here is to avoid finalizing the pending call
1023  * with the lock held, since there's a destroy notifier
1024  * in pending call that goes out to application code.
1025  *
1026  * There's an extra unlock inside the hash table
1027  * "free pending call" function FIXME...
1028  */
1032 
1036 
1038 
1040 }
1041 
1050 void
1052  DBusPendingCall *pending)
1053 {
1054  CONNECTION_LOCK (connection);
1055  _dbus_connection_detach_pending_call_and_unlock (connection, pending);
1056 }
1057 
1067 static dbus_bool_t
1068 _dbus_connection_acquire_io_path (DBusConnection *connection,
1069  int timeout_milliseconds)
1070 {
1071  dbus_bool_t we_acquired;
1072 
1073  HAVE_LOCK_CHECK (connection);
1074 
1075  /* We don't want the connection to vanish */
1076  _dbus_connection_ref_unlocked (connection);
1077 
1078  /* We will only touch io_path_acquired which is protected by our mutex */
1079  CONNECTION_UNLOCK (connection);
1080 
1081  _dbus_verbose ("locking io_path_mutex\n");
1082  _dbus_cmutex_lock (connection->io_path_mutex);
1083 
1084  _dbus_verbose ("start connection->io_path_acquired = %d timeout = %d\n",
1085  connection->io_path_acquired, timeout_milliseconds);
1086 
1087  we_acquired = FALSE;
1088 
1089  if (connection->io_path_acquired)
1090  {
1091  if (timeout_milliseconds != -1)
1092  {
1093  _dbus_verbose ("waiting %d for IO path to be acquirable\n",
1094  timeout_milliseconds);
1095 
1096  if (!_dbus_condvar_wait_timeout (connection->io_path_cond,
1097  connection->io_path_mutex,
1098  timeout_milliseconds))
1099  {
1100  /* We timed out before anyone signaled. */
1101  /* (writing the loop to handle the !timedout case by
1102  * waiting longer if needed is a pain since dbus
1103  * wraps pthread_cond_timedwait to take a relative
1104  * time instead of absolute, something kind of stupid
1105  * on our part. for now it doesn't matter, we will just
1106  * end up back here eventually.)
1107  */
1108  }
1109  }
1110  else
1111  {
1112  while (connection->io_path_acquired)
1113  {
1114  _dbus_verbose ("waiting for IO path to be acquirable\n");
1115  _dbus_condvar_wait (connection->io_path_cond,
1116  connection->io_path_mutex);
1117  }
1118  }
1119  }
1120 
1121  if (!connection->io_path_acquired)
1122  {
1123  we_acquired = TRUE;
1124  connection->io_path_acquired = TRUE;
1125  }
1126 
1127  _dbus_verbose ("end connection->io_path_acquired = %d we_acquired = %d\n",
1128  connection->io_path_acquired, we_acquired);
1129 
1130  _dbus_verbose ("unlocking io_path_mutex\n");
1131  _dbus_cmutex_unlock (connection->io_path_mutex);
1132 
1133  CONNECTION_LOCK (connection);
1134 
1135  HAVE_LOCK_CHECK (connection);
1136 
1137  _dbus_connection_unref_unlocked (connection);
1138 
1139  return we_acquired;
1140 }
1141 
1149 static void
1150 _dbus_connection_release_io_path (DBusConnection *connection)
1151 {
1152  HAVE_LOCK_CHECK (connection);
1153 
1154  _dbus_verbose ("locking io_path_mutex\n");
1155  _dbus_cmutex_lock (connection->io_path_mutex);
1156 
1157  _dbus_assert (connection->io_path_acquired);
1158 
1159  _dbus_verbose ("start connection->io_path_acquired = %d\n",
1160  connection->io_path_acquired);
1161 
1162  connection->io_path_acquired = FALSE;
1163  _dbus_condvar_wake_one (connection->io_path_cond);
1164 
1165  _dbus_verbose ("unlocking io_path_mutex\n");
1166  _dbus_cmutex_unlock (connection->io_path_mutex);
1167 }
1168 
1204 void
1206  DBusPendingCall *pending,
1207  unsigned int flags,
1208  int timeout_milliseconds)
1209 {
1210  _dbus_verbose ("start\n");
1211 
1212  HAVE_LOCK_CHECK (connection);
1213 
1214  if (connection->n_outgoing == 0)
1215  flags &= ~DBUS_ITERATION_DO_WRITING;
1216 
1217  if (_dbus_connection_acquire_io_path (connection,
1218  (flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0))
1219  {
1220  HAVE_LOCK_CHECK (connection);
1221 
1222  if ( (pending != NULL) && _dbus_pending_call_get_completed_unlocked(pending))
1223  {
1224  _dbus_verbose ("pending call completed while acquiring I/O path");
1225  }
1226  else if ( (pending != NULL) &&
1227  _dbus_connection_peek_for_reply_unlocked (connection,
1229  {
1230  _dbus_verbose ("pending call completed while acquiring I/O path (reply found in queue)");
1231  }
1232  else
1233  {
1235  flags, timeout_milliseconds);
1236  }
1237 
1238  _dbus_connection_release_io_path (connection);
1239  }
1240 
1241  HAVE_LOCK_CHECK (connection);
1242 
1243  _dbus_verbose ("end\n");
1244 }
1245 
1257 {
1258  DBusConnection *connection;
1259  DBusWatchList *watch_list;
1260  DBusTimeoutList *timeout_list;
1261  DBusHashTable *pending_replies;
1262  DBusList *disconnect_link;
1263  DBusMessage *disconnect_message;
1264  DBusCounter *outgoing_counter;
1265  DBusObjectTree *objects;
1266 
1267  watch_list = NULL;
1268  connection = NULL;
1269  pending_replies = NULL;
1270  timeout_list = NULL;
1271  disconnect_link = NULL;
1272  disconnect_message = NULL;
1273  outgoing_counter = NULL;
1274  objects = NULL;
1275 
1276  watch_list = _dbus_watch_list_new ();
1277  if (watch_list == NULL)
1278  goto error;
1279 
1280  timeout_list = _dbus_timeout_list_new ();
1281  if (timeout_list == NULL)
1282  goto error;
1283 
1284  pending_replies =
1286  NULL,
1287  (DBusFreeFunction)free_pending_call_on_hash_removal);
1288  if (pending_replies == NULL)
1289  goto error;
1290 
1291  connection = dbus_new0 (DBusConnection, 1);
1292  if (connection == NULL)
1293  goto error;
1294 
1295  _dbus_rmutex_new_at_location (&connection->mutex);
1296  if (connection->mutex == NULL)
1297  goto error;
1298 
1300  if (connection->io_path_mutex == NULL)
1301  goto error;
1302 
1304  if (connection->dispatch_mutex == NULL)
1305  goto error;
1306 
1308  if (connection->dispatch_cond == NULL)
1309  goto error;
1310 
1312  if (connection->io_path_cond == NULL)
1313  goto error;
1314 
1316  if (connection->slot_mutex == NULL)
1317  goto error;
1318 
1319  disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL,
1321  "Disconnected");
1322 
1323  if (disconnect_message == NULL)
1324  goto error;
1325 
1326  disconnect_link = _dbus_list_alloc_link (disconnect_message);
1327  if (disconnect_link == NULL)
1328  goto error;
1329 
1330  outgoing_counter = _dbus_counter_new ();
1331  if (outgoing_counter == NULL)
1332  goto error;
1333 
1334  objects = _dbus_object_tree_new (connection);
1335  if (objects == NULL)
1336  goto error;
1337 
1338  if (_dbus_modify_sigpipe)
1340 
1341  /* initialized to 0: use atomic op to avoid mixing atomic and non-atomic */
1342  _dbus_atomic_inc (&connection->refcount);
1343  connection->transport = transport;
1344  connection->watches = watch_list;
1345  connection->timeouts = timeout_list;
1346  connection->pending_replies = pending_replies;
1347  connection->outgoing_counter = outgoing_counter;
1348  connection->filter_list = NULL;
1349  connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE; /* so we're notified first time there's data */
1350  connection->objects = objects;
1351  connection->exit_on_disconnect = FALSE;
1352  connection->shareable = FALSE;
1353  connection->route_peer_messages = FALSE;
1354  connection->disconnected_message_arrived = FALSE;
1355  connection->disconnected_message_processed = FALSE;
1356 
1357 #ifndef DBUS_DISABLE_CHECKS
1358  connection->generation = _dbus_current_generation;
1359 #endif
1360 
1361  _dbus_data_slot_list_init (&connection->slot_list);
1362 
1363  connection->client_serial = 1;
1364 
1365  connection->disconnect_message_link = disconnect_link;
1366 
1367  CONNECTION_LOCK (connection);
1368 
1369  if (!_dbus_transport_set_connection (transport, connection))
1370  {
1371  CONNECTION_UNLOCK (connection);
1372 
1373  goto error;
1374  }
1375 
1376  _dbus_transport_ref (transport);
1377 
1378  CONNECTION_UNLOCK (connection);
1379 
1380  _dbus_connection_trace_ref (connection, 0, 1, "new_for_transport");
1381  return connection;
1382 
1383  error:
1384  if (disconnect_message != NULL)
1385  dbus_message_unref (disconnect_message);
1386 
1387  if (disconnect_link != NULL)
1388  _dbus_list_free_link (disconnect_link);
1389 
1390  if (connection != NULL)
1391  {
1394  _dbus_rmutex_free_at_location (&connection->mutex);
1398  dbus_free (connection);
1399  }
1400  if (pending_replies)
1401  _dbus_hash_table_unref (pending_replies);
1402 
1403  if (watch_list)
1404  _dbus_watch_list_free (watch_list);
1405 
1406  if (timeout_list)
1407  _dbus_timeout_list_free (timeout_list);
1408 
1409  if (outgoing_counter)
1410  _dbus_counter_unref (outgoing_counter);
1411 
1412  if (objects)
1413  _dbus_object_tree_unref (objects);
1414 
1415  return NULL;
1416 }
1417 
1427 {
1428  dbus_int32_t old_refcount;
1429 
1430  _dbus_assert (connection != NULL);
1432 
1433  HAVE_LOCK_CHECK (connection);
1434 
1435  old_refcount = _dbus_atomic_inc (&connection->refcount);
1436  _dbus_connection_trace_ref (connection, old_refcount, old_refcount + 1,
1437  "ref_unlocked");
1438 
1439  return connection;
1440 }
1441 
1448 void
1450 {
1451  dbus_int32_t old_refcount;
1452 
1453  HAVE_LOCK_CHECK (connection);
1454 
1455  _dbus_assert (connection != NULL);
1456 
1457  old_refcount = _dbus_atomic_dec (&connection->refcount);
1458 
1459  _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1,
1460  "unref_unlocked");
1461 
1462  if (old_refcount == 1)
1463  _dbus_connection_last_unref (connection);
1464 }
1465 
1466 static dbus_uint32_t
1467 _dbus_connection_get_next_client_serial (DBusConnection *connection)
1468 {
1469  dbus_uint32_t serial;
1470 
1471  serial = connection->client_serial++;
1472 
1473  if (connection->client_serial == 0)
1474  connection->client_serial = 1;
1475 
1476  return serial;
1477 }
1478 
1494  unsigned int condition,
1495  void *data)
1496 {
1497  DBusConnection *connection;
1498  dbus_bool_t retval;
1499  DBusDispatchStatus status;
1500 
1501  connection = data;
1502 
1503  _dbus_verbose ("start\n");
1504 
1505  CONNECTION_LOCK (connection);
1506 
1507  if (!_dbus_connection_acquire_io_path (connection, 1))
1508  {
1509  /* another thread is handling the message */
1510  CONNECTION_UNLOCK (connection);
1511  return TRUE;
1512  }
1513 
1514  HAVE_LOCK_CHECK (connection);
1515  retval = _dbus_transport_handle_watch (connection->transport,
1516  watch, condition);
1517 
1518  _dbus_connection_release_io_path (connection);
1519 
1520  HAVE_LOCK_CHECK (connection);
1521 
1522  _dbus_verbose ("middle\n");
1523 
1524  status = _dbus_connection_get_dispatch_status_unlocked (connection);
1525 
1526  /* this calls out to user code */
1527  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
1528 
1529  _dbus_verbose ("end\n");
1530 
1531  return retval;
1532 }
1533 
1534 /* Protected by _DBUS_LOCK (shared_connections) */
1535 static DBusHashTable *shared_connections = NULL;
1536 static DBusList *shared_connections_no_guid = NULL;
1537 
1538 static void
1539 close_connection_on_shutdown (DBusConnection *connection)
1540 {
1541  DBusMessage *message;
1542 
1543  dbus_connection_ref (connection);
1545 
1546  /* Churn through to the Disconnected message */
1547  while ((message = dbus_connection_pop_message (connection)))
1548  {
1549  dbus_message_unref (message);
1550  }
1551  dbus_connection_unref (connection);
1552 }
1553 
1554 static void
1555 shared_connections_shutdown (void *data)
1556 {
1557  int n_entries;
1558 
1559  if (!_DBUS_LOCK (shared_connections))
1560  {
1561  /* We'd have initialized locks before adding anything, so there
1562  * can't be anything there. */
1563  return;
1564  }
1565 
1566  /* This is a little bit unpleasant... better ideas? */
1567  while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0)
1568  {
1569  DBusConnection *connection;
1570  DBusHashIter iter;
1571 
1572  _dbus_hash_iter_init (shared_connections, &iter);
1573  _dbus_hash_iter_next (&iter);
1574 
1575  connection = _dbus_hash_iter_get_value (&iter);
1576 
1577  _DBUS_UNLOCK (shared_connections);
1578  close_connection_on_shutdown (connection);
1579  if (!_DBUS_LOCK (shared_connections))
1580  _dbus_assert_not_reached ("global locks were already initialized");
1581 
1582  /* The connection should now be dead and not in our hash ... */
1583  _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) < n_entries);
1584  }
1585 
1586  _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) == 0);
1587 
1588  _dbus_hash_table_unref (shared_connections);
1589  shared_connections = NULL;
1590 
1591  if (shared_connections_no_guid != NULL)
1592  {
1593  DBusConnection *connection;
1594  connection = _dbus_list_pop_first (&shared_connections_no_guid);
1595  while (connection != NULL)
1596  {
1597  _DBUS_UNLOCK (shared_connections);
1598  close_connection_on_shutdown (connection);
1599  if (!_DBUS_LOCK (shared_connections))
1600  _dbus_assert_not_reached ("global locks were already initialized");
1601  connection = _dbus_list_pop_first (&shared_connections_no_guid);
1602  }
1603  }
1604 
1605  shared_connections_no_guid = NULL;
1606 
1607  _DBUS_UNLOCK (shared_connections);
1608 }
1609 
1610 static dbus_bool_t
1611 connection_lookup_shared (DBusAddressEntry *entry,
1612  DBusConnection **result)
1613 {
1614  _dbus_verbose ("checking for existing connection\n");
1615 
1616  *result = NULL;
1617 
1618  if (!_DBUS_LOCK (shared_connections))
1619  {
1620  /* If it was shared, we'd have initialized global locks when we put
1621  * it in shared_connections. */
1622  return FALSE;
1623  }
1624 
1625  if (shared_connections == NULL)
1626  {
1627  _dbus_verbose ("creating shared_connections hash table\n");
1628 
1629  shared_connections = _dbus_hash_table_new (DBUS_HASH_STRING,
1630  dbus_free,
1631  NULL);
1632  if (shared_connections == NULL)
1633  {
1634  _DBUS_UNLOCK (shared_connections);
1635  return FALSE;
1636  }
1637 
1638  if (!_dbus_register_shutdown_func (shared_connections_shutdown, NULL))
1639  {
1640  _dbus_hash_table_unref (shared_connections);
1641  shared_connections = NULL;
1642  _DBUS_UNLOCK (shared_connections);
1643  return FALSE;
1644  }
1645 
1646  _dbus_verbose (" successfully created shared_connections\n");
1647 
1648  _DBUS_UNLOCK (shared_connections);
1649  return TRUE; /* no point looking up in the hash we just made */
1650  }
1651  else
1652  {
1653  const char *guid;
1654 
1655  guid = dbus_address_entry_get_value (entry, "guid");
1656 
1657  if (guid != NULL)
1658  {
1659  DBusConnection *connection;
1660 
1661  connection = _dbus_hash_table_lookup_string (shared_connections,
1662  guid);
1663 
1664  if (connection)
1665  {
1666  /* The DBusConnection can't be finalized without taking
1667  * the shared_connections lock to remove it from the
1668  * hash. So it's safe to ref the connection here.
1669  * However, it may be disconnected if the Disconnected
1670  * message hasn't been processed yet, in which case we
1671  * want to pretend it isn't in the hash and avoid
1672  * returning it.
1673  *
1674  * The idea is to avoid ever returning a disconnected connection
1675  * from dbus_connection_open(). We could just synchronously
1676  * drop our shared ref to the connection on connection disconnect,
1677  * and then assert here that the connection is connected, but
1678  * that causes reentrancy headaches.
1679  */
1680  CONNECTION_LOCK (connection);
1681  if (_dbus_connection_get_is_connected_unlocked (connection))
1682  {
1683  _dbus_connection_ref_unlocked (connection);
1684  *result = connection;
1685  _dbus_verbose ("looked up existing connection to server guid %s\n",
1686  guid);
1687  }
1688  else
1689  {
1690  _dbus_verbose ("looked up existing connection to server guid %s but it was disconnected so ignoring it\n",
1691  guid);
1692  }
1693  CONNECTION_UNLOCK (connection);
1694  }
1695  }
1696 
1697  _DBUS_UNLOCK (shared_connections);
1698  return TRUE;
1699  }
1700 }
1701 
1702 static dbus_bool_t
1703 connection_record_shared_unlocked (DBusConnection *connection,
1704  const char *guid)
1705 {
1706  char *guid_key;
1707  char *guid_in_connection;
1708 
1709  HAVE_LOCK_CHECK (connection);
1710  _dbus_assert (connection->server_guid == NULL);
1711  _dbus_assert (connection->shareable);
1712 
1713  /* get a hard ref on this connection, even if
1714  * we won't in fact store it in the hash, we still
1715  * need to hold a ref on it until it's disconnected.
1716  */
1717  _dbus_connection_ref_unlocked (connection);
1718 
1719  if (guid == NULL)
1720  {
1721  if (!_DBUS_LOCK (shared_connections))
1722  return FALSE;
1723 
1724  if (!_dbus_list_prepend (&shared_connections_no_guid, connection))
1725  {
1726  _DBUS_UNLOCK (shared_connections);
1727  return FALSE;
1728  }
1729 
1730  _DBUS_UNLOCK (shared_connections);
1731  return TRUE; /* don't store in the hash */
1732  }
1733 
1734  /* A separate copy of the key is required in the hash table, because
1735  * we don't have a lock on the connection when we are doing a hash
1736  * lookup.
1737  */
1738 
1739  guid_key = _dbus_strdup (guid);
1740  if (guid_key == NULL)
1741  return FALSE;
1742 
1743  guid_in_connection = _dbus_strdup (guid);
1744  if (guid_in_connection == NULL)
1745  {
1746  dbus_free (guid_key);
1747  return FALSE;
1748  }
1749 
1750  if (!_DBUS_LOCK (shared_connections))
1751  {
1752  dbus_free (guid_in_connection);
1753  dbus_free (guid_key);
1754  return FALSE;
1755  }
1756 
1757  _dbus_assert (shared_connections != NULL);
1758 
1759  if (!_dbus_hash_table_insert_string (shared_connections,
1760  guid_key, connection))
1761  {
1762  dbus_free (guid_key);
1763  dbus_free (guid_in_connection);
1764  _DBUS_UNLOCK (shared_connections);
1765  return FALSE;
1766  }
1767 
1768  connection->server_guid = guid_in_connection;
1769 
1770  _dbus_verbose ("stored connection to %s to be shared\n",
1771  connection->server_guid);
1772 
1773  _DBUS_UNLOCK (shared_connections);
1774 
1775  _dbus_assert (connection->server_guid != NULL);
1776 
1777  return TRUE;
1778 }
1779 
1780 static void
1781 connection_forget_shared_unlocked (DBusConnection *connection)
1782 {
1783  HAVE_LOCK_CHECK (connection);
1784 
1785  if (!connection->shareable)
1786  return;
1787 
1788  if (!_DBUS_LOCK (shared_connections))
1789  {
1790  /* If it was shared, we'd have initialized global locks when we put
1791  * it in the table; so it can't be there. */
1792  return;
1793  }
1794 
1795  if (connection->server_guid != NULL)
1796  {
1797  _dbus_verbose ("dropping connection to %s out of the shared table\n",
1798  connection->server_guid);
1799 
1800  if (!_dbus_hash_table_remove_string (shared_connections,
1801  connection->server_guid))
1802  _dbus_assert_not_reached ("connection was not in the shared table");
1803 
1804  dbus_free (connection->server_guid);
1805  connection->server_guid = NULL;
1806  }
1807  else
1808  {
1809  _dbus_list_remove (&shared_connections_no_guid, connection);
1810  }
1811 
1812  _DBUS_UNLOCK (shared_connections);
1813 
1814  /* remove our reference held on all shareable connections */
1815  _dbus_connection_unref_unlocked (connection);
1816 }
1817 
1818 static DBusConnection*
1819 connection_try_from_address_entry (DBusAddressEntry *entry,
1820  DBusError *error)
1821 {
1822  DBusTransport *transport;
1823  DBusConnection *connection;
1824 
1825  transport = _dbus_transport_open (entry, error);
1826 
1827  if (transport == NULL)
1828  {
1829  _DBUS_ASSERT_ERROR_IS_SET (error);
1830  return NULL;
1831  }
1832 
1833  connection = _dbus_connection_new_for_transport (transport);
1834 
1835  _dbus_transport_unref (transport);
1836 
1837  if (connection == NULL)
1838  {
1839  _DBUS_SET_OOM (error);
1840  return NULL;
1841  }
1842 
1843 #ifndef DBUS_DISABLE_CHECKS
1844  _dbus_assert (!connection->have_connection_lock);
1845 #endif
1846  return connection;
1847 }
1848 
1849 /*
1850  * If the shared parameter is true, then any existing connection will
1851  * be used (and if a new connection is created, it will be available
1852  * for use by others). If the shared parameter is false, a new
1853  * connection will always be created, and the new connection will
1854  * never be returned to other callers.
1855  *
1856  * @param address the address
1857  * @param shared whether the connection is shared or private
1858  * @param error error return
1859  * @returns the connection or #NULL on error
1860  */
1861 static DBusConnection*
1862 _dbus_connection_open_internal (const char *address,
1863  dbus_bool_t shared,
1864  DBusError *error)
1865 {
1866  DBusConnection *connection;
1867  DBusAddressEntry **entries;
1868  DBusError tmp_error = DBUS_ERROR_INIT;
1869  DBusError first_error = DBUS_ERROR_INIT;
1870  int len, i;
1871 
1872  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1873 
1874  _dbus_verbose ("opening %s connection to: %s\n",
1875  shared ? "shared" : "private", address);
1876 
1877  if (!dbus_parse_address (address, &entries, &len, error))
1878  return NULL;
1879 
1880  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1881 
1882  connection = NULL;
1883 
1884  for (i = 0; i < len; i++)
1885  {
1886  if (shared)
1887  {
1888  if (!connection_lookup_shared (entries[i], &connection))
1889  _DBUS_SET_OOM (&tmp_error);
1890  }
1891 
1892  if (connection == NULL)
1893  {
1894  connection = connection_try_from_address_entry (entries[i],
1895  &tmp_error);
1896 
1897  if (connection != NULL && shared)
1898  {
1899  const char *guid;
1900 
1901  connection->shareable = TRUE;
1902 
1903  /* guid may be NULL */
1904  guid = dbus_address_entry_get_value (entries[i], "guid");
1905 
1906  CONNECTION_LOCK (connection);
1907 
1908  if (!connection_record_shared_unlocked (connection, guid))
1909  {
1910  _DBUS_SET_OOM (&tmp_error);
1911  _dbus_connection_close_possibly_shared_and_unlock (connection);
1912  dbus_connection_unref (connection);
1913  connection = NULL;
1914  }
1915  else
1916  CONNECTION_UNLOCK (connection);
1917  }
1918  }
1919 
1920  if (connection)
1921  break;
1922 
1923  _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
1924 
1925  if (i == 0)
1926  dbus_move_error (&tmp_error, &first_error);
1927  else
1928  dbus_error_free (&tmp_error);
1929  }
1930 
1931  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1932  _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
1933 
1934  if (connection == NULL)
1935  {
1936  _DBUS_ASSERT_ERROR_IS_SET (&first_error);
1937  dbus_move_error (&first_error, error);
1938  }
1939  else
1940  dbus_error_free (&first_error);
1941 
1942  dbus_address_entries_free (entries);
1943  return connection;
1944 }
1945 
1954 void
1956 {
1957  _dbus_assert (connection != NULL);
1959 
1960  CONNECTION_LOCK (connection);
1961  _dbus_connection_close_possibly_shared_and_unlock (connection);
1962 }
1963 
1964 static DBusPreallocatedSend*
1965 _dbus_connection_preallocate_send_unlocked (DBusConnection *connection)
1966 {
1967  DBusPreallocatedSend *preallocated;
1968 
1969  HAVE_LOCK_CHECK (connection);
1970 
1971  _dbus_assert (connection != NULL);
1972 
1973  preallocated = dbus_new (DBusPreallocatedSend, 1);
1974  if (preallocated == NULL)
1975  return NULL;
1976 
1977  preallocated->queue_link = _dbus_list_alloc_link (NULL);
1978  if (preallocated->queue_link == NULL)
1979  goto failed_0;
1980 
1981  preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter);
1982  if (preallocated->counter_link == NULL)
1983  goto failed_1;
1984 
1985  _dbus_counter_ref (preallocated->counter_link->data);
1986 
1987  preallocated->connection = connection;
1988 
1989  return preallocated;
1990 
1991  failed_1:
1992  _dbus_list_free_link (preallocated->queue_link);
1993  failed_0:
1994  dbus_free (preallocated);
1995 
1996  return NULL;
1997 }
1998 
1999 /* Called with lock held, does not update dispatch status */
2000 static void
2001 _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *connection,
2002  DBusPreallocatedSend *preallocated,
2003  DBusMessage *message,
2004  dbus_uint32_t *client_serial)
2005 {
2006  dbus_uint32_t serial;
2007 
2008  preallocated->queue_link->data = message;
2010  preallocated->queue_link);
2011 
2012  /* It's OK that we'll never call the notify function, because for the
2013  * outgoing limit, there isn't one */
2015  preallocated->counter_link);
2016 
2017  dbus_free (preallocated);
2018  preallocated = NULL;
2019 
2020  dbus_message_ref (message);
2021 
2022  connection->n_outgoing += 1;
2023 
2024  _dbus_verbose ("Message %p (%s %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
2025  message,
2027  dbus_message_get_path (message) ?
2028  dbus_message_get_path (message) :
2029  "no path",
2030  dbus_message_get_interface (message) ?
2031  dbus_message_get_interface (message) :
2032  "no interface",
2033  dbus_message_get_member (message) ?
2034  dbus_message_get_member (message) :
2035  "no member",
2036  dbus_message_get_signature (message),
2037  dbus_message_get_destination (message) ?
2038  dbus_message_get_destination (message) :
2039  "null",
2040  connection,
2041  connection->n_outgoing);
2042 
2043  if (dbus_message_get_serial (message) == 0)
2044  {
2045  serial = _dbus_connection_get_next_client_serial (connection);
2046  dbus_message_set_serial (message, serial);
2047  if (client_serial)
2048  *client_serial = serial;
2049  }
2050  else
2051  {
2052  if (client_serial)
2053  *client_serial = dbus_message_get_serial (message);
2054  }
2055 
2056  _dbus_verbose ("Message %p serial is %u\n",
2057  message, dbus_message_get_serial (message));
2058 
2059  dbus_message_lock (message);
2060 
2061  /* Now we need to run an iteration to hopefully just write the messages
2062  * out immediately, and otherwise get them queued up
2063  */
2065  NULL,
2066  DBUS_ITERATION_DO_WRITING,
2067  -1);
2068 
2069  /* If stuff is still queued up, be sure we wake up the main loop */
2070  if (connection->n_outgoing > 0)
2071  _dbus_connection_wakeup_mainloop (connection);
2072 }
2073 
2074 static void
2075 _dbus_connection_send_preallocated_and_unlock (DBusConnection *connection,
2076  DBusPreallocatedSend *preallocated,
2077  DBusMessage *message,
2078  dbus_uint32_t *client_serial)
2079 {
2080  DBusDispatchStatus status;
2081 
2082  HAVE_LOCK_CHECK (connection);
2083 
2084  _dbus_connection_send_preallocated_unlocked_no_update (connection,
2085  preallocated,
2086  message, client_serial);
2087 
2088  _dbus_verbose ("middle\n");
2089  status = _dbus_connection_get_dispatch_status_unlocked (connection);
2090 
2091  /* this calls out to user code */
2092  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2093 }
2094 
2106  DBusMessage *message,
2107  dbus_uint32_t *client_serial)
2108 {
2109  DBusPreallocatedSend *preallocated;
2110 
2111  _dbus_assert (connection != NULL);
2112  _dbus_assert (message != NULL);
2113 
2114  preallocated = _dbus_connection_preallocate_send_unlocked (connection);
2115  if (preallocated == NULL)
2116  {
2117  CONNECTION_UNLOCK (connection);
2118  return FALSE;
2119  }
2120 
2121  _dbus_connection_send_preallocated_and_unlock (connection,
2122  preallocated,
2123  message,
2124  client_serial);
2125  return TRUE;
2126 }
2127 
2152 void
2154 {
2155  dbus_int32_t refcount;
2156 
2157  CONNECTION_LOCK (connection);
2158 
2159  refcount = _dbus_atomic_get (&connection->refcount);
2160  /* The caller should have at least one ref */
2161  _dbus_assert (refcount >= 1);
2162 
2163  if (refcount == 1)
2164  _dbus_connection_close_possibly_shared_and_unlock (connection);
2165  else
2166  CONNECTION_UNLOCK (connection);
2167 }
2168 
2169 
2179 static void
2180 _dbus_memory_pause_based_on_timeout (int timeout_milliseconds)
2181 {
2182  if (timeout_milliseconds == -1)
2183  _dbus_sleep_milliseconds (1000);
2184  else if (timeout_milliseconds < 100)
2185  ; /* just busy loop */
2186  else if (timeout_milliseconds <= 1000)
2187  _dbus_sleep_milliseconds (timeout_milliseconds / 3);
2188  else
2189  _dbus_sleep_milliseconds (1000);
2190 }
2191 
2192 static DBusMessage *
2193 generate_local_error_message (dbus_uint32_t serial,
2194  char *error_name,
2195  char *error_msg)
2196 {
2197  DBusMessage *message;
2199  if (!message)
2200  goto out;
2201 
2202  if (!dbus_message_set_error_name (message, error_name))
2203  {
2204  dbus_message_unref (message);
2205  message = NULL;
2206  goto out;
2207  }
2208 
2209  dbus_message_set_no_reply (message, TRUE);
2210 
2211  if (!dbus_message_set_reply_serial (message,
2212  serial))
2213  {
2214  dbus_message_unref (message);
2215  message = NULL;
2216  goto out;
2217  }
2218 
2219  if (error_msg != NULL)
2220  {
2221  DBusMessageIter iter;
2222 
2223  dbus_message_iter_init_append (message, &iter);
2224  if (!dbus_message_iter_append_basic (&iter,
2226  &error_msg))
2227  {
2228  dbus_message_unref (message);
2229  message = NULL;
2230  goto out;
2231  }
2232  }
2233 
2234  out:
2235  return message;
2236 }
2237 
2238 /*
2239  * Peek the incoming queue to see if we got reply for a specific serial
2240  */
2241 static dbus_bool_t
2242 _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection,
2243  dbus_uint32_t client_serial)
2244 {
2245  DBusList *link;
2246  HAVE_LOCK_CHECK (connection);
2247 
2248  link = _dbus_list_get_first_link (&connection->incoming_messages);
2249 
2250  while (link != NULL)
2251  {
2252  DBusMessage *reply = link->data;
2253 
2254  if (dbus_message_get_reply_serial (reply) == client_serial)
2255  {
2256  _dbus_verbose ("%s reply to %d found in queue\n", _DBUS_FUNCTION_NAME, client_serial);
2257  return TRUE;
2258  }
2259  link = _dbus_list_get_next_link (&connection->incoming_messages, link);
2260  }
2261 
2262  return FALSE;
2263 }
2264 
2265 /* This is slightly strange since we can pop a message here without
2266  * the dispatch lock.
2267  */
2268 static DBusMessage*
2269 check_for_reply_unlocked (DBusConnection *connection,
2270  dbus_uint32_t client_serial)
2271 {
2272  DBusList *link;
2273 
2274  HAVE_LOCK_CHECK (connection);
2275 
2276  link = _dbus_list_get_first_link (&connection->incoming_messages);
2277 
2278  while (link != NULL)
2279  {
2280  DBusMessage *reply = link->data;
2281 
2282  if (dbus_message_get_reply_serial (reply) == client_serial)
2283  {
2284  _dbus_list_remove_link (&connection->incoming_messages, link);
2285  connection->n_incoming -= 1;
2286  return reply;
2287  }
2288  link = _dbus_list_get_next_link (&connection->incoming_messages, link);
2289  }
2290 
2291  return NULL;
2292 }
2293 
2294 static void
2295 connection_timeout_and_complete_all_pending_calls_unlocked (DBusConnection *connection)
2296 {
2297  /* We can't iterate over the hash in the normal way since we'll be
2298  * dropping the lock for each item. So we restart the
2299  * iter each time as we drain the hash table.
2300  */
2301 
2302  while (_dbus_hash_table_get_n_entries (connection->pending_replies) > 0)
2303  {
2304  DBusPendingCall *pending;
2305  DBusHashIter iter;
2306 
2307  _dbus_hash_iter_init (connection->pending_replies, &iter);
2308  _dbus_hash_iter_next (&iter);
2309 
2310  pending = _dbus_hash_iter_get_value (&iter);
2312 
2314  connection);
2315 
2321 
2323  CONNECTION_LOCK (connection);
2324  }
2325  HAVE_LOCK_CHECK (connection);
2326 }
2327 
2328 static void
2329 complete_pending_call_and_unlock (DBusConnection *connection,
2330  DBusPendingCall *pending,
2331  DBusMessage *message)
2332 {
2333  _dbus_pending_call_set_reply_unlocked (pending, message);
2334  _dbus_pending_call_ref_unlocked (pending); /* in case there's no app with a ref held */
2335  _dbus_connection_detach_pending_call_and_unlock (connection, pending);
2336 
2337  /* Must be called unlocked since it invokes app callback */
2338  _dbus_pending_call_complete (pending);
2339  dbus_pending_call_unref (pending);
2340 }
2341 
2342 static dbus_bool_t
2343 check_for_reply_and_update_dispatch_unlocked (DBusConnection *connection,
2344  DBusPendingCall *pending)
2345 {
2346  DBusMessage *reply;
2347  DBusDispatchStatus status;
2348 
2349  reply = check_for_reply_unlocked (connection,
2351  if (reply != NULL)
2352  {
2353  _dbus_verbose ("checked for reply\n");
2354 
2355  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
2356 
2357  complete_pending_call_and_unlock (connection, pending, reply);
2358  dbus_message_unref (reply);
2359 
2360  CONNECTION_LOCK (connection);
2361  status = _dbus_connection_get_dispatch_status_unlocked (connection);
2362  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2363  dbus_pending_call_unref (pending);
2364 
2365  return TRUE;
2366  }
2367 
2368  return FALSE;
2369 }
2370 
2385 void
2387 {
2388  long start_tv_sec, start_tv_usec;
2389  long tv_sec, tv_usec;
2390  DBusDispatchStatus status;
2391  DBusConnection *connection;
2392  dbus_uint32_t client_serial;
2393  DBusTimeout *timeout;
2394  int timeout_milliseconds, elapsed_milliseconds;
2395 
2396  _dbus_assert (pending != NULL);
2397 
2398  if (dbus_pending_call_get_completed (pending))
2399  return;
2400 
2401  dbus_pending_call_ref (pending); /* necessary because the call could be canceled */
2402 
2403  connection = _dbus_pending_call_get_connection_and_lock (pending);
2404 
2405  /* Flush message queue - note, can affect dispatch status */
2406  _dbus_connection_flush_unlocked (connection);
2407 
2408  client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
2409 
2410  /* note that timeout_milliseconds is limited to a smallish value
2411  * in _dbus_pending_call_new() so overflows aren't possible
2412  * below
2413  */
2414  timeout = _dbus_pending_call_get_timeout_unlocked (pending);
2415  _dbus_get_monotonic_time (&start_tv_sec, &start_tv_usec);
2416  if (timeout)
2417  {
2418  timeout_milliseconds = dbus_timeout_get_interval (timeout);
2419 
2420  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec\n",
2421  timeout_milliseconds,
2422  client_serial,
2423  start_tv_sec, start_tv_usec);
2424  }
2425  else
2426  {
2427  timeout_milliseconds = -1;
2428 
2429  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block for reply serial %u\n", client_serial);
2430  }
2431 
2432  /* check to see if we already got the data off the socket */
2433  /* from another blocked pending call */
2434  if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
2435  return;
2436 
2437  /* Now we wait... */
2438  /* always block at least once as we know we don't have the reply yet */
2440  pending,
2441  DBUS_ITERATION_DO_READING |
2442  DBUS_ITERATION_BLOCK,
2443  timeout_milliseconds);
2444 
2445  recheck_status:
2446 
2447  _dbus_verbose ("top of recheck\n");
2448 
2449  HAVE_LOCK_CHECK (connection);
2450 
2451  /* queue messages and get status */
2452 
2453  status = _dbus_connection_get_dispatch_status_unlocked (connection);
2454 
2455  /* the get_completed() is in case a dispatch() while we were blocking
2456  * got the reply instead of us.
2457  */
2459  {
2460  _dbus_verbose ("Pending call completed by dispatch\n");
2461  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2462  dbus_pending_call_unref (pending);
2463  return;
2464  }
2465 
2466  if (status == DBUS_DISPATCH_DATA_REMAINS)
2467  {
2468  if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
2469  return;
2470  }
2471 
2472  _dbus_get_monotonic_time (&tv_sec, &tv_usec);
2473  elapsed_milliseconds = (tv_sec - start_tv_sec) * 1000 +
2474  (tv_usec - start_tv_usec) / 1000;
2475 
2476  if (!_dbus_connection_get_is_connected_unlocked (connection))
2477  {
2478  DBusMessage *error_msg;
2479 
2480  error_msg = generate_local_error_message (client_serial,
2482  "Connection was disconnected before a reply was received");
2483 
2484  /* on OOM error_msg is set to NULL */
2485  complete_pending_call_and_unlock (connection, pending, error_msg);
2486  dbus_pending_call_unref (pending);
2487  return;
2488  }
2489  else if (connection->disconnect_message_link == NULL)
2490  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
2491  else if (timeout == NULL)
2492  {
2493  if (status == DBUS_DISPATCH_NEED_MEMORY)
2494  {
2495  /* Try sleeping a bit, as we aren't sure we need to block for reading,
2496  * we may already have a reply in the buffer and just can't process
2497  * it.
2498  */
2499  _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
2500 
2501  _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
2502  }
2503  else
2504  {
2505  /* block again, we don't have the reply buffered yet. */
2507  pending,
2508  DBUS_ITERATION_DO_READING |
2509  DBUS_ITERATION_BLOCK,
2510  timeout_milliseconds - elapsed_milliseconds);
2511  }
2512 
2513  goto recheck_status;
2514  }
2515  else if (tv_sec < start_tv_sec)
2516  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
2517  else if (elapsed_milliseconds < timeout_milliseconds)
2518  {
2519  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds - elapsed_milliseconds);
2520 
2521  if (status == DBUS_DISPATCH_NEED_MEMORY)
2522  {
2523  /* Try sleeping a bit, as we aren't sure we need to block for reading,
2524  * we may already have a reply in the buffer and just can't process
2525  * it.
2526  */
2527  _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
2528 
2529  _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
2530  }
2531  else
2532  {
2533  /* block again, we don't have the reply buffered yet. */
2535  NULL,
2536  DBUS_ITERATION_DO_READING |
2537  DBUS_ITERATION_BLOCK,
2538  timeout_milliseconds - elapsed_milliseconds);
2539  }
2540 
2541  goto recheck_status;
2542  }
2543 
2544  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %d milliseconds and got no reply\n",
2545  elapsed_milliseconds);
2546 
2548 
2549  /* unlock and call user code */
2550  complete_pending_call_and_unlock (connection, pending, NULL);
2551 
2552  /* update user code on dispatch status */
2553  CONNECTION_LOCK (connection);
2554  status = _dbus_connection_get_dispatch_status_unlocked (connection);
2555  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2556  dbus_pending_call_unref (pending);
2557 }
2558 
2596 dbus_connection_open (const char *address,
2597  DBusError *error)
2598 {
2599  DBusConnection *connection;
2600 
2601  _dbus_return_val_if_fail (address != NULL, NULL);
2602  _dbus_return_val_if_error_is_set (error, NULL);
2603 
2604  connection = _dbus_connection_open_internal (address,
2605  TRUE,
2606  error);
2607 
2608  return connection;
2609 }
2610 
2639 dbus_connection_open_private (const char *address,
2640  DBusError *error)
2641 {
2642  DBusConnection *connection;
2643 
2644  _dbus_return_val_if_fail (address != NULL, NULL);
2645  _dbus_return_val_if_error_is_set (error, NULL);
2646 
2647  connection = _dbus_connection_open_internal (address,
2648  FALSE,
2649  error);
2650 
2651  return connection;
2652 }
2653 
2662 {
2663  dbus_int32_t old_refcount;
2664 
2665  _dbus_return_val_if_fail (connection != NULL, NULL);
2666  _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
2667  old_refcount = _dbus_atomic_inc (&connection->refcount);
2668  _dbus_connection_trace_ref (connection, old_refcount, old_refcount + 1,
2669  "ref");
2670 
2671  return connection;
2672 }
2673 
2674 static void
2675 free_outgoing_message (void *element,
2676  void *data)
2677 {
2678  DBusMessage *message = element;
2679  DBusConnection *connection = data;
2680 
2681  _dbus_message_remove_counter (message, connection->outgoing_counter);
2682  dbus_message_unref (message);
2683 }
2684 
2685 /* This is run without the mutex held, but after the last reference
2686  * to the connection has been dropped we should have no thread-related
2687  * problems
2688  */
2689 static void
2690 _dbus_connection_last_unref (DBusConnection *connection)
2691 {
2692  DBusList *link;
2693 
2694  _dbus_verbose ("Finalizing connection %p\n", connection);
2695 
2696  _dbus_assert (_dbus_atomic_get (&connection->refcount) == 0);
2697 
2698  /* You have to disconnect the connection before unref:ing it. Otherwise
2699  * you won't get the disconnected message.
2700  */
2702  _dbus_assert (connection->server_guid == NULL);
2703 
2704  /* ---- We're going to call various application callbacks here, hope it doesn't break anything... */
2706 
2710 
2711  _dbus_watch_list_free (connection->watches);
2712  connection->watches = NULL;
2713 
2714  _dbus_timeout_list_free (connection->timeouts);
2715  connection->timeouts = NULL;
2716 
2717  _dbus_data_slot_list_free (&connection->slot_list);
2718 
2719  link = _dbus_list_get_first_link (&connection->filter_list);
2720  while (link != NULL)
2721  {
2722  DBusMessageFilter *filter = link->data;
2723  DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
2724 
2725  filter->function = NULL;
2726  _dbus_message_filter_unref (filter); /* calls app callback */
2727  link->data = NULL;
2728 
2729  link = next;
2730  }
2731  _dbus_list_clear (&connection->filter_list);
2732 
2733  /* ---- Done with stuff that invokes application callbacks */
2734 
2735  _dbus_object_tree_unref (connection->objects);
2736 
2738  connection->pending_replies = NULL;
2739 
2740  _dbus_list_clear (&connection->filter_list);
2741 
2742  _dbus_list_foreach (&connection->outgoing_messages,
2743  free_outgoing_message,
2744  connection);
2745  _dbus_list_clear (&connection->outgoing_messages);
2746 
2747  _dbus_list_foreach (&connection->incoming_messages,
2749  NULL);
2750  _dbus_list_clear (&connection->incoming_messages);
2751 
2752  _dbus_counter_unref (connection->outgoing_counter);
2753 
2754  _dbus_transport_unref (connection->transport);
2755 
2756  if (connection->disconnect_message_link)
2757  {
2758  DBusMessage *message = connection->disconnect_message_link->data;
2759  dbus_message_unref (message);
2761  }
2762 
2765 
2768 
2770 
2771  _dbus_rmutex_free_at_location (&connection->mutex);
2772 
2773  dbus_free (connection);
2774 }
2775 
2795 void
2797 {
2798  dbus_int32_t old_refcount;
2799 
2800  _dbus_return_if_fail (connection != NULL);
2801  _dbus_return_if_fail (connection->generation == _dbus_current_generation);
2802 
2803  old_refcount = _dbus_atomic_dec (&connection->refcount);
2804 
2805  _dbus_connection_trace_ref (connection, old_refcount, old_refcount - 1,
2806  "unref");
2807 
2808  if (old_refcount == 1)
2809  {
2810 #ifndef DBUS_DISABLE_CHECKS
2811  if (_dbus_transport_get_is_connected (connection->transport))
2812  {
2813  _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",
2814  connection->shareable ?
2815  "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" :
2816  "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n");
2817  return;
2818  }
2819 #endif
2820  _dbus_connection_last_unref (connection);
2821  }
2822 }
2823 
2824 /*
2825  * Note that the transport can disconnect itself (other end drops us)
2826  * and in that case this function never runs. So this function must
2827  * not do anything more than disconnect the transport and update the
2828  * dispatch status.
2829  *
2830  * If the transport self-disconnects, then we assume someone will
2831  * dispatch the connection to cause the dispatch status update.
2832  */
2833 static void
2834 _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection)
2835 {
2836  DBusDispatchStatus status;
2837 
2838  HAVE_LOCK_CHECK (connection);
2839 
2840  _dbus_verbose ("Disconnecting %p\n", connection);
2841 
2842  /* We need to ref because update_dispatch_status_and_unlock will unref
2843  * the connection if it was shared and libdbus was the only remaining
2844  * refcount holder.
2845  */
2846  _dbus_connection_ref_unlocked (connection);
2847 
2848  _dbus_transport_disconnect (connection->transport);
2849 
2850  /* This has the side effect of queuing the disconnect message link
2851  * (unless we don't have enough memory, possibly, so don't assert it).
2852  * After the disconnect message link is queued, dbus_bus_get/dbus_connection_open
2853  * should never again return the newly-disconnected connection.
2854  *
2855  * However, we only unref the shared connection and exit_on_disconnect when
2856  * the disconnect message reaches the head of the message queue,
2857  * NOT when it's first queued.
2858  */
2859  status = _dbus_connection_get_dispatch_status_unlocked (connection);
2860 
2861  /* This calls out to user code */
2862  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2863 
2864  /* Could also call out to user code */
2865  dbus_connection_unref (connection);
2866 }
2867 
2910 void
2912 {
2913  _dbus_return_if_fail (connection != NULL);
2914  _dbus_return_if_fail (connection->generation == _dbus_current_generation);
2915 
2916  CONNECTION_LOCK (connection);
2917 
2918 #ifndef DBUS_DISABLE_CHECKS
2919  if (connection->shareable)
2920  {
2921  CONNECTION_UNLOCK (connection);
2922 
2923  _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n");
2924  return;
2925  }
2926 #endif
2927 
2928  _dbus_connection_close_possibly_shared_and_unlock (connection);
2929 }
2930 
2931 static dbus_bool_t
2932 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
2933 {
2934  HAVE_LOCK_CHECK (connection);
2935  return _dbus_transport_get_is_connected (connection->transport);
2936 }
2937 
2953 {
2954  dbus_bool_t res;
2955 
2956  _dbus_return_val_if_fail (connection != NULL, FALSE);
2957 
2958  CONNECTION_LOCK (connection);
2959  res = _dbus_connection_get_is_connected_unlocked (connection);
2960  CONNECTION_UNLOCK (connection);
2961 
2962  return res;
2963 }
2964 
2975 {
2976  dbus_bool_t res;
2977 
2978  _dbus_return_val_if_fail (connection != NULL, FALSE);
2979 
2980  CONNECTION_LOCK (connection);
2981  res = _dbus_transport_get_is_authenticated (connection->transport);
2982  CONNECTION_UNLOCK (connection);
2983 
2984  return res;
2985 }
2986 
3009 {
3010  dbus_bool_t res;
3011 
3012  _dbus_return_val_if_fail (connection != NULL, FALSE);
3013 
3014  CONNECTION_LOCK (connection);
3015  res = _dbus_transport_get_is_anonymous (connection->transport);
3016  CONNECTION_UNLOCK (connection);
3017 
3018  return res;
3019 }
3020 
3052 char*
3054 {
3055  char *id;
3056 
3057  _dbus_return_val_if_fail (connection != NULL, NULL);
3058 
3059  CONNECTION_LOCK (connection);
3061  CONNECTION_UNLOCK (connection);
3062 
3063  return id;
3064 }
3065 
3085  int type)
3086 {
3087  _dbus_return_val_if_fail (connection != NULL, FALSE);
3088 
3089  if (!dbus_type_is_valid (type))
3090  return FALSE;
3091 
3092  if (type != DBUS_TYPE_UNIX_FD)
3093  return TRUE;
3094 
3095 #ifdef HAVE_UNIX_FD_PASSING
3096  {
3097  dbus_bool_t b;
3098 
3099  CONNECTION_LOCK(connection);
3101  CONNECTION_UNLOCK(connection);
3102 
3103  return b;
3104  }
3105 #endif
3106 
3107  return FALSE;
3108 }
3109 
3123 void
3125  dbus_bool_t exit_on_disconnect)
3126 {
3127  _dbus_return_if_fail (connection != NULL);
3128 
3129  CONNECTION_LOCK (connection);
3130  connection->exit_on_disconnect = exit_on_disconnect != FALSE;
3131  CONNECTION_UNLOCK (connection);
3132 }
3133 
3145 {
3146  DBusPreallocatedSend *preallocated;
3147 
3148  _dbus_return_val_if_fail (connection != NULL, NULL);
3149 
3150  CONNECTION_LOCK (connection);
3151 
3152  preallocated =
3153  _dbus_connection_preallocate_send_unlocked (connection);
3154 
3155  CONNECTION_UNLOCK (connection);
3156 
3157  return preallocated;
3158 }
3159 
3169 void
3171  DBusPreallocatedSend *preallocated)
3172 {
3173  _dbus_return_if_fail (connection != NULL);
3174  _dbus_return_if_fail (preallocated != NULL);
3175  _dbus_return_if_fail (connection == preallocated->connection);
3176 
3177  _dbus_list_free_link (preallocated->queue_link);
3178  _dbus_counter_unref (preallocated->counter_link->data);
3179  _dbus_list_free_link (preallocated->counter_link);
3180  dbus_free (preallocated);
3181 }
3182 
3195 void
3197  DBusPreallocatedSend *preallocated,
3198  DBusMessage *message,
3199  dbus_uint32_t *client_serial)
3200 {
3201  _dbus_return_if_fail (connection != NULL);
3202  _dbus_return_if_fail (preallocated != NULL);
3203  _dbus_return_if_fail (message != NULL);
3204  _dbus_return_if_fail (preallocated->connection == connection);
3205  _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
3206  dbus_message_get_member (message) != NULL);
3207  _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
3208  (dbus_message_get_interface (message) != NULL &&
3209  dbus_message_get_member (message) != NULL));
3210 
3211  CONNECTION_LOCK (connection);
3212 
3213 #ifdef HAVE_UNIX_FD_PASSING
3214 
3215  if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
3216  message->n_unix_fds > 0)
3217  {
3218  /* Refuse to send fds on a connection that cannot handle
3219  them. Unfortunately we cannot return a proper error here, so
3220  the best we can is just return. */
3221  CONNECTION_UNLOCK (connection);
3222  return;
3223  }
3224 
3225 #endif
3226 
3227  _dbus_connection_send_preallocated_and_unlock (connection,
3228  preallocated,
3229  message, client_serial);
3230 }
3231 
3232 static dbus_bool_t
3233 _dbus_connection_send_unlocked_no_update (DBusConnection *connection,
3234  DBusMessage *message,
3235  dbus_uint32_t *client_serial)
3236 {
3237  DBusPreallocatedSend *preallocated;
3238 
3239  _dbus_assert (connection != NULL);
3240  _dbus_assert (message != NULL);
3241 
3242  preallocated = _dbus_connection_preallocate_send_unlocked (connection);
3243  if (preallocated == NULL)
3244  return FALSE;
3245 
3246  _dbus_connection_send_preallocated_unlocked_no_update (connection,
3247  preallocated,
3248  message,
3249  client_serial);
3250  return TRUE;
3251 }
3252 
3282  DBusMessage *message,
3283  dbus_uint32_t *serial)
3284 {
3285  _dbus_return_val_if_fail (connection != NULL, FALSE);
3286  _dbus_return_val_if_fail (message != NULL, FALSE);
3287 
3288  CONNECTION_LOCK (connection);
3289 
3290 #ifdef HAVE_UNIX_FD_PASSING
3291 
3292  if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
3293  message->n_unix_fds > 0)
3294  {
3295  /* Refuse to send fds on a connection that cannot handle
3296  them. Unfortunately we cannot return a proper error here, so
3297  the best we can is just return. */
3298  CONNECTION_UNLOCK (connection);
3299  return FALSE;
3300  }
3301 
3302 #endif
3303 
3304  return _dbus_connection_send_and_unlock (connection,
3305  message,
3306  serial);
3307 }
3308 
3309 static dbus_bool_t
3310 reply_handler_timeout (void *data)
3311 {
3312  DBusConnection *connection;
3313  DBusDispatchStatus status;
3314  DBusPendingCall *pending = data;
3315 
3316  connection = _dbus_pending_call_get_connection_and_lock (pending);
3317  _dbus_connection_ref_unlocked (connection);
3318 
3320  connection);
3324 
3325  _dbus_verbose ("middle\n");
3326  status = _dbus_connection_get_dispatch_status_unlocked (connection);
3327 
3328  /* Unlocks, and calls out to user code */
3329  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3330  dbus_connection_unref (connection);
3331 
3332  return TRUE;
3333 }
3334 
3379  DBusMessage *message,
3380  DBusPendingCall **pending_return,
3381  int timeout_milliseconds)
3382 {
3383  DBusPendingCall *pending;
3384  dbus_int32_t serial = -1;
3385  DBusDispatchStatus status;
3386 
3387  _dbus_return_val_if_fail (connection != NULL, FALSE);
3388  _dbus_return_val_if_fail (message != NULL, FALSE);
3389  _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
3390 
3391  if (pending_return)
3392  *pending_return = NULL;
3393 
3394  CONNECTION_LOCK (connection);
3395 
3396 #ifdef HAVE_UNIX_FD_PASSING
3397 
3398  if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
3399  message->n_unix_fds > 0)
3400  {
3401  /* Refuse to send fds on a connection that cannot handle
3402  them. Unfortunately we cannot return a proper error here, so
3403  the best we can do is return TRUE but leave *pending_return
3404  as NULL. */
3405  CONNECTION_UNLOCK (connection);
3406  return TRUE;
3407  }
3408 
3409 #endif
3410 
3411  if (!_dbus_connection_get_is_connected_unlocked (connection))
3412  {
3413  CONNECTION_UNLOCK (connection);
3414 
3415  return TRUE;
3416  }
3417 
3418  pending = _dbus_pending_call_new_unlocked (connection,
3419  timeout_milliseconds,
3420  reply_handler_timeout);
3421 
3422  if (pending == NULL)
3423  {
3424  CONNECTION_UNLOCK (connection);
3425  return FALSE;
3426  }
3427 
3428  /* Assign a serial to the message */
3429  serial = dbus_message_get_serial (message);
3430  if (serial == 0)
3431  {
3432  serial = _dbus_connection_get_next_client_serial (connection);
3433  dbus_message_set_serial (message, serial);
3434  }
3435 
3436  if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
3437  goto error;
3438 
3439  /* Insert the serial in the pending replies hash;
3440  * hash takes a refcount on DBusPendingCall.
3441  * Also, add the timeout.
3442  */
3443  if (!_dbus_connection_attach_pending_call_unlocked (connection,
3444  pending))
3445  goto error;
3446 
3447  if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
3448  {
3449  _dbus_connection_detach_pending_call_and_unlock (connection,
3450  pending);
3451  goto error_unlocked;
3452  }
3453 
3454  if (pending_return)
3455  *pending_return = pending; /* hand off refcount */
3456  else
3457  {
3458  _dbus_connection_detach_pending_call_unlocked (connection, pending);
3459  /* we still have a ref to the pending call in this case, we unref
3460  * after unlocking, below
3461  */
3462  }
3463 
3464  status = _dbus_connection_get_dispatch_status_unlocked (connection);
3465 
3466  /* this calls out to user code */
3467  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3468 
3469  if (pending_return == NULL)
3470  dbus_pending_call_unref (pending);
3471 
3472  return TRUE;
3473 
3474  error:
3475  CONNECTION_UNLOCK (connection);
3476  error_unlocked:
3477  dbus_pending_call_unref (pending);
3478  return FALSE;
3479 }
3480 
3513 DBusMessage*
3515  DBusMessage *message,
3516  int timeout_milliseconds,
3517  DBusError *error)
3518 {
3519  DBusMessage *reply;
3520  DBusPendingCall *pending;
3521 
3522  _dbus_return_val_if_fail (connection != NULL, NULL);
3523  _dbus_return_val_if_fail (message != NULL, NULL);
3524  _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL);
3525  _dbus_return_val_if_error_is_set (error, NULL);
3526 
3527 #ifdef HAVE_UNIX_FD_PASSING
3528 
3529  CONNECTION_LOCK (connection);
3530  if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
3531  message->n_unix_fds > 0)
3532  {
3533  CONNECTION_UNLOCK (connection);
3534  dbus_set_error(error, DBUS_ERROR_FAILED, "Cannot send file descriptors on this connection.");
3535  return NULL;
3536  }
3537  CONNECTION_UNLOCK (connection);
3538 
3539 #endif
3540 
3541  if (!dbus_connection_send_with_reply (connection, message,
3542  &pending, timeout_milliseconds))
3543  {
3544  _DBUS_SET_OOM (error);
3545  return NULL;
3546  }
3547 
3548  if (pending == NULL)
3549  {
3550  dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Connection is closed");
3551  return NULL;
3552  }
3553 
3554  dbus_pending_call_block (pending);
3555 
3556  reply = dbus_pending_call_steal_reply (pending);
3557  dbus_pending_call_unref (pending);
3558 
3559  /* call_complete_and_unlock() called from pending_call_block() should
3560  * always fill this in.
3561  */
3562  _dbus_assert (reply != NULL);
3563 
3564  if (dbus_set_error_from_message (error, reply))
3565  {
3566  dbus_message_unref (reply);
3567  return NULL;
3568  }
3569  else
3570  return reply;
3571 }
3572 
3581 static DBusDispatchStatus
3582 _dbus_connection_flush_unlocked (DBusConnection *connection)
3583 {
3584  /* We have to specify DBUS_ITERATION_DO_READING here because
3585  * otherwise we could have two apps deadlock if they are both doing
3586  * a flush(), and the kernel buffers fill up. This could change the
3587  * dispatch status.
3588  */
3589  DBusDispatchStatus status;
3590 
3591  HAVE_LOCK_CHECK (connection);
3592 
3593  while (connection->n_outgoing > 0 &&
3594  _dbus_connection_get_is_connected_unlocked (connection))
3595  {
3596  _dbus_verbose ("doing iteration in\n");
3597  HAVE_LOCK_CHECK (connection);
3599  NULL,
3600  DBUS_ITERATION_DO_READING |
3601  DBUS_ITERATION_DO_WRITING |
3602  DBUS_ITERATION_BLOCK,
3603  -1);
3604  }
3605 
3606  HAVE_LOCK_CHECK (connection);
3607  _dbus_verbose ("middle\n");
3608  status = _dbus_connection_get_dispatch_status_unlocked (connection);
3609 
3610  HAVE_LOCK_CHECK (connection);
3611  return status;
3612 }
3613 
3619 void
3621 {
3622  /* We have to specify DBUS_ITERATION_DO_READING here because
3623  * otherwise we could have two apps deadlock if they are both doing
3624  * a flush(), and the kernel buffers fill up. This could change the
3625  * dispatch status.
3626  */
3627  DBusDispatchStatus status;
3628 
3629  _dbus_return_if_fail (connection != NULL);
3630 
3631  CONNECTION_LOCK (connection);
3632 
3633  status = _dbus_connection_flush_unlocked (connection);
3634 
3635  HAVE_LOCK_CHECK (connection);
3636  /* Unlocks and calls out to user code */
3637  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3638 
3639  _dbus_verbose ("end\n");
3640 }
3641 
3652 static dbus_bool_t
3653 _dbus_connection_read_write_dispatch (DBusConnection *connection,
3654  int timeout_milliseconds,
3655  dbus_bool_t dispatch)
3656 {
3657  DBusDispatchStatus dstatus;
3658  dbus_bool_t progress_possible;
3659 
3660  /* Need to grab a ref here in case we're a private connection and
3661  * the user drops the last ref in a handler we call; see bug
3662  * https://bugs.freedesktop.org/show_bug.cgi?id=15635
3663  */
3664  dbus_connection_ref (connection);
3665  dstatus = dbus_connection_get_dispatch_status (connection);
3666 
3667  if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
3668  {
3669  _dbus_verbose ("doing dispatch\n");
3670  dbus_connection_dispatch (connection);
3671  CONNECTION_LOCK (connection);
3672  }
3673  else if (dstatus == DBUS_DISPATCH_NEED_MEMORY)
3674  {
3675  _dbus_verbose ("pausing for memory\n");
3676  _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
3677  CONNECTION_LOCK (connection);
3678  }
3679  else
3680  {
3681  CONNECTION_LOCK (connection);
3682  if (_dbus_connection_get_is_connected_unlocked (connection))
3683  {
3684  _dbus_verbose ("doing iteration\n");
3686  NULL,
3687  DBUS_ITERATION_DO_READING |
3688  DBUS_ITERATION_DO_WRITING |
3689  DBUS_ITERATION_BLOCK,
3690  timeout_milliseconds);
3691  }
3692  }
3693 
3694  HAVE_LOCK_CHECK (connection);
3695  /* If we can dispatch, we can make progress until the Disconnected message
3696  * has been processed; if we can only read/write, we can make progress
3697  * as long as the transport is open.
3698  */
3699  if (dispatch)
3700  progress_possible = connection->n_incoming != 0 ||
3701  connection->disconnect_message_link != NULL;
3702  else
3703  progress_possible = _dbus_connection_get_is_connected_unlocked (connection);
3704 
3705  CONNECTION_UNLOCK (connection);
3706 
3707  dbus_connection_unref (connection);
3708 
3709  return progress_possible; /* TRUE if we can make more progress */
3710 }
3711 
3712 
3749  int timeout_milliseconds)
3750 {
3751  _dbus_return_val_if_fail (connection != NULL, FALSE);
3752  _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
3753  return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE);
3754 }
3755 
3779 dbus_bool_t
3781  int timeout_milliseconds)
3782 {
3783  _dbus_return_val_if_fail (connection != NULL, FALSE);
3784  _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
3785  return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE);
3786 }
3787 
3788 /* We need to call this anytime we pop the head of the queue, and then
3789  * update_dispatch_status_and_unlock needs to be called afterward
3790  * which will "process" the disconnected message and set
3791  * disconnected_message_processed.
3792  */
3793 static void
3794 check_disconnected_message_arrived_unlocked (DBusConnection *connection,
3795  DBusMessage *head_of_queue)
3796 {
3797  HAVE_LOCK_CHECK (connection);
3798 
3799  /* checking that the link is NULL is an optimization to avoid the is_signal call */
3800  if (connection->disconnect_message_link == NULL &&
3801  dbus_message_is_signal (head_of_queue,
3803  "Disconnected"))
3804  {
3805  connection->disconnected_message_arrived = TRUE;
3806  }
3807 }
3808 
3828 DBusMessage*
3830 {
3831  DBusDispatchStatus status;
3832  DBusMessage *message;
3833 
3834  _dbus_return_val_if_fail (connection != NULL, NULL);
3835 
3836  _dbus_verbose ("start\n");
3837 
3838  /* this is called for the side effect that it queues
3839  * up any messages from the transport
3840  */
3841  status = dbus_connection_get_dispatch_status (connection);
3842  if (status != DBUS_DISPATCH_DATA_REMAINS)
3843  return NULL;
3844 
3845  CONNECTION_LOCK (connection);
3846 
3847  _dbus_connection_acquire_dispatch (connection);
3848 
3849  /* While a message is outstanding, the dispatch lock is held */
3850  _dbus_assert (connection->message_borrowed == NULL);
3851 
3852  connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
3853 
3854  message = connection->message_borrowed;
3855 
3856  check_disconnected_message_arrived_unlocked (connection, message);
3857 
3858  /* Note that we KEEP the dispatch lock until the message is returned */
3859  if (message == NULL)
3860  _dbus_connection_release_dispatch (connection);
3861 
3862  CONNECTION_UNLOCK (connection);
3863 
3864  _dbus_message_trace_ref (message, -1, -1, "dbus_connection_borrow_message");
3865 
3866  /* We don't update dispatch status until it's returned or stolen */
3867 
3868  return message;
3869 }
3870 
3879 void
3881  DBusMessage *message)
3882 {
3883  DBusDispatchStatus status;
3884 
3885  _dbus_return_if_fail (connection != NULL);
3886  _dbus_return_if_fail (message != NULL);
3887  _dbus_return_if_fail (message == connection->message_borrowed);
3888  _dbus_return_if_fail (connection->dispatch_acquired);
3889 
3890  CONNECTION_LOCK (connection);
3891 
3892  _dbus_assert (message == connection->message_borrowed);
3893 
3894  connection->message_borrowed = NULL;
3895 
3896  _dbus_connection_release_dispatch (connection);
3897 
3898  status = _dbus_connection_get_dispatch_status_unlocked (connection);
3899  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3900 
3901  _dbus_message_trace_ref (message, -1, -1, "dbus_connection_return_message");
3902 }
3903 
3913 void
3915  DBusMessage *message)
3916 {
3917  DBusMessage *pop_message;
3918  DBusDispatchStatus status;
3919 
3920  _dbus_return_if_fail (connection != NULL);
3921  _dbus_return_if_fail (message != NULL);
3922  _dbus_return_if_fail (message == connection->message_borrowed);
3923  _dbus_return_if_fail (connection->dispatch_acquired);
3924 
3925  CONNECTION_LOCK (connection);
3926 
3927  _dbus_assert (message == connection->message_borrowed);
3928 
3929  pop_message = _dbus_list_pop_first (&connection->incoming_messages);
3930  _dbus_assert (message == pop_message);
3931  (void) pop_message; /* unused unless asserting */
3932 
3933  connection->n_incoming -= 1;
3934 
3935  _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
3936  message, connection->n_incoming);
3937 
3938  connection->message_borrowed = NULL;
3939 
3940  _dbus_connection_release_dispatch (connection);
3941 
3942  status = _dbus_connection_get_dispatch_status_unlocked (connection);
3943  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3944  _dbus_message_trace_ref (message, -1, -1,
3945  "dbus_connection_steal_borrowed_message");
3946 }
3947 
3948 /* See dbus_connection_pop_message, but requires the caller to own
3949  * the lock before calling. May drop the lock while running.
3950  */
3951 static DBusList*
3952 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
3953 {
3954  HAVE_LOCK_CHECK (connection);
3955 
3956  _dbus_assert (connection->message_borrowed == NULL);
3957 
3958  if (connection->n_incoming > 0)
3959  {
3960  DBusList *link;
3961 
3962  link = _dbus_list_pop_first_link (&connection->incoming_messages);
3963  connection->n_incoming -= 1;
3964 
3965  _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from incoming queue %p, %d incoming\n",
3966  link->data,
3968  dbus_message_get_path (link->data) ?
3969  dbus_message_get_path (link->data) :
3970  "no path",
3973  "no interface",
3974  dbus_message_get_member (link->data) ?
3975  dbus_message_get_member (link->data) :
3976  "no member",
3978  connection, connection->n_incoming);
3979 
3980  _dbus_message_trace_ref (link->data, -1, -1,
3981  "_dbus_connection_pop_message_link_unlocked");
3982 
3983  check_disconnected_message_arrived_unlocked (connection, link->data);
3984 
3985  return link;
3986  }
3987  else
3988  return NULL;
3989 }
3990 
3991 /* See dbus_connection_pop_message, but requires the caller to own
3992  * the lock before calling. May drop the lock while running.
3993  */
3994 static DBusMessage*
3995 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
3996 {
3997  DBusList *link;
3998 
3999  HAVE_LOCK_CHECK (connection);
4000 
4001  link = _dbus_connection_pop_message_link_unlocked (connection);
4002 
4003  if (link != NULL)
4004  {
4005  DBusMessage *message;
4006 
4007  message = link->data;
4008 
4009  _dbus_list_free_link (link);
4010 
4011  return message;
4012  }
4013  else
4014  return NULL;
4015 }
4016 
4017 static void
4018 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
4019  DBusList *message_link)
4020 {
4021  HAVE_LOCK_CHECK (connection);
4022 
4023  _dbus_assert (message_link != NULL);
4024  /* You can't borrow a message while a link is outstanding */
4025  _dbus_assert (connection->message_borrowed == NULL);
4026  /* We had to have the dispatch lock across the pop/putback */
4027  _dbus_assert (connection->dispatch_acquired);
4028 
4030  message_link);
4031  connection->n_incoming += 1;
4032 
4033  _dbus_verbose ("Message %p (%s %s %s '%s') put back into queue %p, %d incoming\n",
4034  message_link->data,
4036  dbus_message_get_interface (message_link->data) ?
4037  dbus_message_get_interface (message_link->data) :
4038  "no interface",
4039  dbus_message_get_member (message_link->data) ?
4040  dbus_message_get_member (message_link->data) :
4041  "no member",
4042  dbus_message_get_signature (message_link->data),
4043  connection, connection->n_incoming);
4044 
4045  _dbus_message_trace_ref (message_link->data, -1, -1,
4046  "_dbus_connection_putback_message_link_unlocked");
4047 }
4048 
4068 DBusMessage*
4070 {
4071  DBusMessage *message;
4072  DBusDispatchStatus status;
4073 
4074  _dbus_verbose ("start\n");
4075 
4076  /* this is called for the side effect that it queues
4077  * up any messages from the transport
4078  */
4079  status = dbus_connection_get_dispatch_status (connection);
4080  if (status != DBUS_DISPATCH_DATA_REMAINS)
4081  return NULL;
4082 
4083  CONNECTION_LOCK (connection);
4084  _dbus_connection_acquire_dispatch (connection);
4085  HAVE_LOCK_CHECK (connection);
4086 
4087  message = _dbus_connection_pop_message_unlocked (connection);
4088 
4089  _dbus_verbose ("Returning popped message %p\n", message);
4090 
4091  _dbus_connection_release_dispatch (connection);
4092 
4093  status = _dbus_connection_get_dispatch_status_unlocked (connection);
4094  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
4095 
4096  return message;
4097 }
4098 
4106 static void
4107 _dbus_connection_acquire_dispatch (DBusConnection *connection)
4108 {
4109  HAVE_LOCK_CHECK (connection);
4110 
4111  _dbus_connection_ref_unlocked (connection);
4112  CONNECTION_UNLOCK (connection);
4113 
4114  _dbus_verbose ("locking dispatch_mutex\n");
4115  _dbus_cmutex_lock (connection->dispatch_mutex);
4116 
4117  while (connection->dispatch_acquired)
4118  {
4119  _dbus_verbose ("waiting for dispatch to be acquirable\n");
4120  _dbus_condvar_wait (connection->dispatch_cond,
4121  connection->dispatch_mutex);
4122  }
4123 
4124  _dbus_assert (!connection->dispatch_acquired);
4125 
4126  connection->dispatch_acquired = TRUE;
4127 
4128  _dbus_verbose ("unlocking dispatch_mutex\n");
4129  _dbus_cmutex_unlock (connection->dispatch_mutex);
4130 
4131  CONNECTION_LOCK (connection);
4132  _dbus_connection_unref_unlocked (connection);
4133 }
4134 
4142 static void
4143 _dbus_connection_release_dispatch (DBusConnection *connection)
4144 {
4145  HAVE_LOCK_CHECK (connection);
4146 
4147  _dbus_verbose ("locking dispatch_mutex\n");
4148  _dbus_cmutex_lock (connection->dispatch_mutex);
4149 
4150  _dbus_assert (connection->dispatch_acquired);
4151 
4152  connection->dispatch_acquired = FALSE;
4153  _dbus_condvar_wake_one (connection->dispatch_cond);
4154 
4155  _dbus_verbose ("unlocking dispatch_mutex\n");
4156  _dbus_cmutex_unlock (connection->dispatch_mutex);
4157 }
4158 
4159 static void
4160 _dbus_connection_failed_pop (DBusConnection *connection,
4161  DBusList *message_link)
4162 {
4164  message_link);
4165  connection->n_incoming += 1;
4166 }
4167 
4168 /* Note this may be called multiple times since we don't track whether we already did it */
4169 static void
4170 notify_disconnected_unlocked (DBusConnection *connection)
4171 {
4172  HAVE_LOCK_CHECK (connection);
4173 
4174  /* Set the weakref in dbus-bus.c to NULL, so nobody will get a disconnected
4175  * connection from dbus_bus_get(). We make the same guarantee for
4176  * dbus_connection_open() but in a different way since we don't want to
4177  * unref right here; we instead check for connectedness before returning
4178  * the connection from the hash.
4179  */
4181 
4182  /* Dump the outgoing queue, we aren't going to be able to
4183  * send it now, and we'd like accessors like
4184  * dbus_connection_get_outgoing_size() to be accurate.
4185  */
4186  if (connection->n_outgoing > 0)
4187  {
4188  DBusList *link;
4189 
4190  _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
4191  connection->n_outgoing);
4192 
4193  while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
4194  {
4195  _dbus_connection_message_sent_unlocked (connection, link->data);
4196  }
4197  }
4198 }
4199 
4200 /* Note this may be called multiple times since we don't track whether we already did it */
4201 static DBusDispatchStatus
4202 notify_disconnected_and_dispatch_complete_unlocked (DBusConnection *connection)
4203 {
4204  HAVE_LOCK_CHECK (connection);
4205 
4206  if (connection->disconnect_message_link != NULL)
4207  {
4208  _dbus_verbose ("Sending disconnect message\n");
4209 
4210  /* If we have pending calls, queue their timeouts - we want the Disconnected
4211  * to be the last message, after these timeouts.
4212  */
4213  connection_timeout_and_complete_all_pending_calls_unlocked (connection);
4214 
4215  /* We haven't sent the disconnect message already,
4216  * and all real messages have been queued up.
4217  */
4219  connection->disconnect_message_link);
4220  connection->disconnect_message_link = NULL;
4221 
4223  }
4224 
4225  return DBUS_DISPATCH_COMPLETE;
4226 }
4227 
4228 static DBusDispatchStatus
4229 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
4230 {
4231  HAVE_LOCK_CHECK (connection);
4232 
4233  if (connection->n_incoming > 0)
4235  else if (!_dbus_transport_queue_messages (connection->transport))
4237  else
4238  {
4239  DBusDispatchStatus status;
4240  dbus_bool_t is_connected;
4241 
4242  status = _dbus_transport_get_dispatch_status (connection->transport);
4243  is_connected = _dbus_transport_get_is_connected (connection->transport);
4244 
4245  _dbus_verbose ("dispatch status = %s is_connected = %d\n",
4246  DISPATCH_STATUS_NAME (status), is_connected);
4247 
4248  if (!is_connected)
4249  {
4250  /* It's possible this would be better done by having an explicit
4251  * notification from _dbus_transport_disconnect() that would
4252  * synchronously do this, instead of waiting for the next dispatch
4253  * status check. However, probably not good to change until it causes
4254  * a problem.
4255  */
4256  notify_disconnected_unlocked (connection);
4257 
4258  /* I'm not sure this is needed; the idea is that we want to
4259  * queue the Disconnected only after we've read all the
4260  * messages, but if we're disconnected maybe we are guaranteed
4261  * to have read them all ?
4262  */
4263  if (status == DBUS_DISPATCH_COMPLETE)
4264  status = notify_disconnected_and_dispatch_complete_unlocked (connection);
4265  }
4266 
4267  if (status != DBUS_DISPATCH_COMPLETE)
4268  return status;
4269  else if (connection->n_incoming > 0)
4271  else
4272  return DBUS_DISPATCH_COMPLETE;
4273  }
4274 }
4275 
4276 static void
4277 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
4278  DBusDispatchStatus new_status)
4279 {
4280  dbus_bool_t changed;
4281  DBusDispatchStatusFunction function;
4282  void *data;
4283 
4284  HAVE_LOCK_CHECK (connection);
4285 
4286  _dbus_connection_ref_unlocked (connection);
4287 
4288  changed = new_status != connection->last_dispatch_status;
4289 
4290  connection->last_dispatch_status = new_status;
4291 
4292  function = connection->dispatch_status_function;
4293  data = connection->dispatch_status_data;
4294 
4295  if (connection->disconnected_message_arrived &&
4296  !connection->disconnected_message_processed)
4297  {
4298  connection->disconnected_message_processed = TRUE;
4299 
4300  /* this does an unref, but we have a ref
4301  * so we should not run the finalizer here
4302  * inside the lock.
4303  */
4304  connection_forget_shared_unlocked (connection);
4305 
4306  if (connection->exit_on_disconnect)
4307  {
4308  CONNECTION_UNLOCK (connection);
4309 
4310  _dbus_verbose ("Exiting on Disconnected signal\n");
4311  _dbus_exit (1);
4312  _dbus_assert_not_reached ("Call to exit() returned");
4313  }
4314  }
4315 
4316  /* We drop the lock */
4317  CONNECTION_UNLOCK (connection);
4318 
4319  if (changed && function)
4320  {
4321  _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
4322  connection, new_status,
4323  DISPATCH_STATUS_NAME (new_status));
4324  (* function) (connection, new_status, data);
4325  }
4326 
4327  dbus_connection_unref (connection);
4328 }
4329 
4357 {
4358  DBusDispatchStatus status;
4359 
4360  _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
4361 
4362  _dbus_verbose ("start\n");
4363 
4364  CONNECTION_LOCK (connection);
4365 
4366  status = _dbus_connection_get_dispatch_status_unlocked (connection);
4367 
4368  CONNECTION_UNLOCK (connection);
4369 
4370  return status;
4371 }
4372 
4376 static DBusHandlerResult
4377 _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
4378  DBusMessage *message)
4379 {
4380  dbus_bool_t sent = FALSE;
4381  DBusMessage *ret = NULL;
4382  DBusList *expire_link;
4383 
4384  if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
4385  {
4386  /* This means we're letting the bus route this message */
4388  }
4389 
4391  {
4393  }
4394 
4395  /* Preallocate a linked-list link, so that if we need to dispose of a
4396  * message, we can attach it to the expired list */
4397  expire_link = _dbus_list_alloc_link (NULL);
4398 
4399  if (!expire_link)
4401 
4402  if (dbus_message_is_method_call (message,
4404  "Ping"))
4405  {
4406  ret = dbus_message_new_method_return (message);
4407  if (ret == NULL)
4408  goto out;
4409 
4410  sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
4411  }
4412  else if (dbus_message_is_method_call (message,
4414  "GetMachineId"))
4415  {
4416  DBusString uuid;
4417 
4418  ret = dbus_message_new_method_return (message);
4419  if (ret == NULL)
4420  goto out;
4421 
4422  _dbus_string_init (&uuid);
4424  {
4425  const char *v_STRING = _dbus_string_get_const_data (&uuid);
4426  if (dbus_message_append_args (ret,
4427  DBUS_TYPE_STRING, &v_STRING,
4429  {
4430  sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
4431  }
4432  }
4433  _dbus_string_free (&uuid);
4434  }
4435  else
4436  {
4437  /* We need to bounce anything else with this interface, otherwise apps
4438  * could start extending the interface and when we added extensions
4439  * here to DBusConnection we'd break those apps.
4440  */
4441  ret = dbus_message_new_error (message,
4443  "Unknown method invoked on org.freedesktop.DBus.Peer interface");
4444  if (ret == NULL)
4445  goto out;
4446 
4447  sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
4448  }
4449 
4450 out:
4451  if (ret == NULL)
4452  {
4453  _dbus_list_free_link (expire_link);
4454  }
4455  else
4456  {
4457  /* It'll be safe to unref the reply when we unlock */
4458  expire_link->data = ret;
4459  _dbus_list_prepend_link (&connection->expired_messages, expire_link);
4460  }
4461 
4462  if (!sent)
4464 
4466 }
4467 
4474 static DBusHandlerResult
4475 _dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection,
4476  DBusMessage *message)
4477 {
4478  /* We just run one filter for now but have the option to run more
4479  if the spec calls for it in the future */
4480 
4481  return _dbus_connection_peer_filter_unlocked_no_update (connection, message);
4482 }
4483 
4528 {
4529  DBusMessage *message;
4530  DBusList *link, *filter_list_copy, *message_link;
4531  DBusHandlerResult result;
4532  DBusPendingCall *pending;
4533  dbus_int32_t reply_serial;
4534  DBusDispatchStatus status;
4535  dbus_bool_t found_object;
4536 
4537  _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
4538 
4539  _dbus_verbose ("\n");
4540 
4541  CONNECTION_LOCK (connection);
4542  status = _dbus_connection_get_dispatch_status_unlocked (connection);
4543  if (status != DBUS_DISPATCH_DATA_REMAINS)
4544  {
4545  /* unlocks and calls out to user code */
4546  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
4547  return status;
4548  }
4549 
4550  /* We need to ref the connection since the callback could potentially
4551  * drop the last ref to it
4552  */
4553  _dbus_connection_ref_unlocked (connection);
4554 
4555  _dbus_connection_acquire_dispatch (connection);
4556  HAVE_LOCK_CHECK (connection);
4557 
4558  message_link = _dbus_connection_pop_message_link_unlocked (connection);
4559  if (message_link == NULL)
4560  {
4561  /* another thread dispatched our stuff */
4562 
4563  _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
4564 
4565  _dbus_connection_release_dispatch (connection);
4566 
4567  status = _dbus_connection_get_dispatch_status_unlocked (connection);
4568 
4569  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
4570 
4571  dbus_connection_unref (connection);
4572 
4573  return status;
4574  }
4575 
4576  message = message_link->data;
4577 
4578  _dbus_verbose (" dispatching message %p (%s %s %s '%s')\n",
4579  message,
4581  dbus_message_get_interface (message) ?
4582  dbus_message_get_interface (message) :
4583  "no interface",
4584  dbus_message_get_member (message) ?
4585  dbus_message_get_member (message) :
4586  "no member",
4587  dbus_message_get_signature (message));
4588 
4590 
4591  /* Pending call handling must be first, because if you do
4592  * dbus_connection_send_with_reply_and_block() or
4593  * dbus_pending_call_block() then no handlers/filters will be run on
4594  * the reply. We want consistent semantics in the case where we
4595  * dbus_connection_dispatch() the reply.
4596  */
4597 
4598  reply_serial = dbus_message_get_reply_serial (message);
4599  pending = _dbus_hash_table_lookup_int (connection->pending_replies,
4600  reply_serial);
4601  if (pending)
4602  {
4603  _dbus_verbose ("Dispatching a pending reply\n");
4604  complete_pending_call_and_unlock (connection, pending, message);
4605  pending = NULL; /* it's probably unref'd */
4606 
4607  CONNECTION_LOCK (connection);
4608  _dbus_verbose ("pending call completed in dispatch\n");
4609  result = DBUS_HANDLER_RESULT_HANDLED;
4610  goto out;
4611  }
4612 
4613  result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message);
4615  goto out;
4616 
4617  if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
4618  {
4619  _dbus_connection_release_dispatch (connection);
4620  HAVE_LOCK_CHECK (connection);
4621 
4622  _dbus_connection_failed_pop (connection, message_link);
4623 
4624  /* unlocks and calls user code */
4625  _dbus_connection_update_dispatch_status_and_unlock (connection,
4627  dbus_connection_unref (connection);
4628 
4630  }
4631 
4632  _dbus_list_foreach (&filter_list_copy,
4633  (DBusForeachFunction)_dbus_message_filter_ref,
4634  NULL);
4635 
4636  /* We're still protected from dispatch() reentrancy here
4637  * since we acquired the dispatcher
4638  */
4639  CONNECTION_UNLOCK (connection);
4640 
4641  link = _dbus_list_get_first_link (&filter_list_copy);
4642  while (link != NULL)
4643  {
4644  DBusMessageFilter *filter = link->data;
4645  DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
4646 
4647  if (filter->function == NULL)
4648  {
4649  _dbus_verbose (" filter was removed in a callback function\n");
4650  link = next;
4651  continue;
4652  }
4653 
4654  _dbus_verbose (" running filter on message %p\n", message);
4655  result = (* filter->function) (connection, message, filter->user_data);
4656 
4658  break;
4659 
4660  link = next;
4661  }
4662 
4663  _dbus_list_foreach (&filter_list_copy,
4664  (DBusForeachFunction)_dbus_message_filter_unref,
4665  NULL);
4666  _dbus_list_clear (&filter_list_copy);
4667 
4668  CONNECTION_LOCK (connection);
4669 
4670  if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
4671  {
4672  _dbus_verbose ("No memory\n");
4673  goto out;
4674  }
4675  else if (result == DBUS_HANDLER_RESULT_HANDLED)
4676  {
4677  _dbus_verbose ("filter handled message in dispatch\n");
4678  goto out;
4679  }
4680 
4681  /* We're still protected from dispatch() reentrancy here
4682  * since we acquired the dispatcher
4683  */
4684  _dbus_verbose (" running object path dispatch on message %p (%s %s %s '%s')\n",
4685  message,
4687  dbus_message_get_interface (message) ?
4688  dbus_message_get_interface (message) :
4689  "no interface",
4690  dbus_message_get_member (message) ?
4691  dbus_message_get_member (message) :
4692  "no member",
4693  dbus_message_get_signature (message));
4694 
4695  HAVE_LOCK_CHECK (connection);
4696  result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
4697  message,
4698  &found_object);
4699 
4700  CONNECTION_LOCK (connection);
4701 
4703  {
4704  _dbus_verbose ("object tree handled message in dispatch\n");
4705  goto out;
4706  }
4707 
4709  {
4710  DBusMessage *reply;
4711  DBusString str;
4712  DBusPreallocatedSend *preallocated;
4713  DBusList *expire_link;
4714 
4715  _dbus_verbose (" sending error %s\n",
4717 
4718  if (!_dbus_string_init (&str))
4719  {
4721  _dbus_verbose ("no memory for error string in dispatch\n");
4722  goto out;
4723  }
4724 
4725  if (!_dbus_string_append_printf (&str,
4726  "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
4727  dbus_message_get_member (message),
4728  dbus_message_get_signature (message),
4729  dbus_message_get_interface (message)))
4730  {
4731  _dbus_string_free (&str);
4733  _dbus_verbose ("no memory for error string in dispatch\n");
4734  goto out;
4735  }
4736 
4737  reply = dbus_message_new_error (message,
4740  _dbus_string_free (&str);
4741 
4742  if (reply == NULL)
4743  {
4745  _dbus_verbose ("no memory for error reply in dispatch\n");
4746  goto out;
4747  }
4748 
4749  expire_link = _dbus_list_alloc_link (reply);
4750 
4751  if (expire_link == NULL)
4752  {
4753  dbus_message_unref (reply);
4755  _dbus_verbose ("no memory for error send in dispatch\n");
4756  goto out;
4757  }
4758 
4759  preallocated = _dbus_connection_preallocate_send_unlocked (connection);
4760 
4761  if (preallocated == NULL)
4762  {
4763  _dbus_list_free_link (expire_link);
4764  /* It's OK that this is finalized, because it hasn't been seen by
4765  * anything that could attach user callbacks */
4766  dbus_message_unref (reply);
4768  _dbus_verbose ("no memory for error send in dispatch\n");
4769  goto out;
4770  }
4771 
4772  _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
4773  reply, NULL);
4774  /* reply will be freed when we release the lock */
4775  _dbus_list_prepend_link (&connection->expired_messages, expire_link);
4776 
4777  result = DBUS_HANDLER_RESULT_HANDLED;
4778  }
4779 
4780  _dbus_verbose (" done dispatching %p (%s %s %s '%s') on connection %p\n", message,
4782  dbus_message_get_interface (message) ?
4783  dbus_message_get_interface (message) :
4784  "no interface",
4785  dbus_message_get_member (message) ?
4786  dbus_message_get_member (message) :
4787  "no member",
4788  dbus_message_get_signature (message),
4789  connection);
4790 
4791  out:
4792  if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
4793  {
4794  _dbus_verbose ("out of memory\n");
4795 
4796  /* Put message back, and we'll start over.
4797  * Yes this means handlers must be idempotent if they
4798  * don't return HANDLED; c'est la vie.
4799  */
4800  _dbus_connection_putback_message_link_unlocked (connection,
4801  message_link);
4802  /* now we don't want to free them */
4803  message_link = NULL;
4804  message = NULL;
4805  }
4806  else
4807  {
4808  _dbus_verbose (" ... done dispatching\n");
4809  }
4810 
4811  _dbus_connection_release_dispatch (connection);
4812  HAVE_LOCK_CHECK (connection);
4813 
4814  if (message != NULL)
4815  {
4816  /* We don't want this message to count in maximum message limits when
4817  * computing the dispatch status, below. We have to drop the lock
4818  * temporarily, because finalizing a message can trigger callbacks.
4819  *
4820  * We have a reference to the connection, and we don't use any cached
4821  * pointers to the connection's internals below this point, so it should
4822  * be safe to drop the lock and take it back. */
4823  CONNECTION_UNLOCK (connection);
4824  dbus_message_unref (message);
4825  CONNECTION_LOCK (connection);
4826  }
4827 
4828  if (message_link != NULL)
4829  _dbus_list_free_link (message_link);
4830 
4831  _dbus_verbose ("before final status update\n");
4832  status = _dbus_connection_get_dispatch_status_unlocked (connection);
4833 
4834  /* unlocks and calls user code */
4835  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
4836 
4837  dbus_connection_unref (connection);
4838 
4839  return status;
4840 }
4841 
4905  DBusAddWatchFunction add_function,
4906  DBusRemoveWatchFunction remove_function,
4907  DBusWatchToggledFunction toggled_function,
4908  void *data,
4909  DBusFreeFunction free_data_function)
4910 {
4911  dbus_bool_t retval;
4912 
4913  _dbus_return_val_if_fail (connection != NULL, FALSE);
4914 
4915  CONNECTION_LOCK (connection);
4916 
4917  retval = _dbus_watch_list_set_functions (connection->watches,
4918  add_function, remove_function,
4919  toggled_function,
4920  data, free_data_function);
4921 
4922  CONNECTION_UNLOCK (connection);
4923 
4924  return retval;
4925 }
4926 
4968  DBusAddTimeoutFunction add_function,
4969  DBusRemoveTimeoutFunction remove_function,
4970  DBusTimeoutToggledFunction toggled_function,
4971  void *data,
4972  DBusFreeFunction free_data_function)
4973 {
4974  dbus_bool_t retval;
4975 
4976  _dbus_return_val_if_fail (connection != NULL, FALSE);
4977 
4978  CONNECTION_LOCK (connection);
4979 
4980  retval = _dbus_timeout_list_set_functions (connection->timeouts,
4981  add_function, remove_function,
4982  toggled_function,
4983  data, free_data_function);
4984 
4985  CONNECTION_UNLOCK (connection);
4986 
4987  return retval;
4988 }
4989 
5004 void
5006  DBusWakeupMainFunction wakeup_main_function,
5007  void *data,
5008  DBusFreeFunction free_data_function)
5009 {
5010  void *old_data;
5011  DBusFreeFunction old_free_data;
5012 
5013  _dbus_return_if_fail (connection != NULL);
5014 
5015  CONNECTION_LOCK (connection);
5016  old_data = connection->wakeup_main_data;
5017  old_free_data = connection->free_wakeup_main_data;
5018 
5019  connection->wakeup_main_function = wakeup_main_function;
5020  connection->wakeup_main_data = data;
5021  connection->free_wakeup_main_data = free_data_function;
5022 
5023  CONNECTION_UNLOCK (connection);
5024 
5025  /* Callback outside the lock */
5026  if (old_free_data)
5027  (*old_free_data) (old_data);
5028 }
5029 
5050 void
5052  DBusDispatchStatusFunction function,
5053  void *data,
5054  DBusFreeFunction free_data_function)
5055 {
5056  void *old_data;
5057  DBusFreeFunction old_free_data;
5058 
5059  _dbus_return_if_fail (connection != NULL);
5060 
5061  CONNECTION_LOCK (connection);
5062  old_data = connection->dispatch_status_data;
5063  old_free_data = connection->free_dispatch_status_data;
5064 
5065  connection->dispatch_status_function = function;
5066  connection->dispatch_status_data = data;
5067  connection->free_dispatch_status_data = free_data_function;
5068 
5069  CONNECTION_UNLOCK (connection);
5070 
5071  /* Callback outside the lock */
5072  if (old_free_data)
5073  (*old_free_data) (old_data);
5074 }
5075 
5097  int *fd)
5098 {
5099  _dbus_return_val_if_fail (connection != NULL, FALSE);
5100  _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
5101 
5102 #ifdef DBUS_WIN
5103  /* FIXME do this on a lower level */
5104  return FALSE;
5105 #endif
5106 
5107  return dbus_connection_get_socket(connection, fd);
5108 }
5109 
5127  int *fd)
5128 {
5129  dbus_bool_t retval;
5130 
5131  _dbus_return_val_if_fail (connection != NULL, FALSE);
5132  _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
5133 
5134  CONNECTION_LOCK (connection);
5135 
5136  retval = _dbus_transport_get_socket_fd (connection->transport,
5137  fd);
5138 
5139  CONNECTION_UNLOCK (connection);
5140 
5141  return retval;
5142 }
5143 
5144 
5169  unsigned long *uid)
5170 {
5171  dbus_bool_t result;
5172 
5173  _dbus_return_val_if_fail (connection != NULL, FALSE);
5174  _dbus_return_val_if_fail (uid != NULL, FALSE);
5175 
5176  CONNECTION_LOCK (connection);
5177 
5179  result = FALSE;
5180  else
5181  result = _dbus_transport_get_unix_user (connection->transport,
5182  uid);
5183 
5184 #ifdef DBUS_WIN
5185  _dbus_assert (!result);
5186 #endif
5187 
5188  CONNECTION_UNLOCK (connection);
5189 
5190  return result;
5191 }
5192 
5205  unsigned long *pid)
5206 {
5207  dbus_bool_t result;
5208 
5209  _dbus_return_val_if_fail (connection != NULL, FALSE);
5210  _dbus_return_val_if_fail (pid != NULL, FALSE);
5211 
5212  CONNECTION_LOCK (connection);
5213 
5215  result = FALSE;
5216  else
5217  result = _dbus_transport_get_unix_process_id (connection->transport,
5218  pid);
5219 
5220  CONNECTION_UNLOCK (connection);
5221 
5222  return result;
5223 }
5224 
5237  void **data,
5238  dbus_int32_t *data_size)
5239 {
5240  dbus_bool_t result;
5241 
5242  _dbus_return_val_if_fail (connection != NULL, FALSE);
5243  _dbus_return_val_if_fail (data != NULL, FALSE);
5244  _dbus_return_val_if_fail (data_size != NULL, FALSE);
5245 
5246  CONNECTION_LOCK (connection);
5247 
5249  result = FALSE;
5250  else
5252  data,
5253  data_size);
5254  CONNECTION_UNLOCK (connection);
5255 
5256  return result;
5257 }
5258 
5281 void
5283  DBusAllowUnixUserFunction function,
5284  void *data,
5285  DBusFreeFunction free_data_function)
5286 {
5287  void *old_data = NULL;
5288  DBusFreeFunction old_free_function = NULL;
5289 
5290  _dbus_return_if_fail (connection != NULL);
5291 
5292  CONNECTION_LOCK (connection);
5294  function, data, free_data_function,
5295  &old_data, &old_free_function);
5296  CONNECTION_UNLOCK (connection);
5297 
5298  if (old_free_function != NULL)
5299  (* old_free_function) (old_data);
5300 }
5301 
5335  char **windows_sid_p)
5336 {
5337  dbus_bool_t result;
5338 
5339  _dbus_return_val_if_fail (connection != NULL, FALSE);
5340  _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
5341 
5342  CONNECTION_LOCK (connection);
5343 
5345  result = FALSE;
5346  else
5347  result = _dbus_transport_get_windows_user (connection->transport,
5348  windows_sid_p);
5349 
5350 #ifdef DBUS_UNIX
5351  _dbus_assert (!result);
5352 #endif
5353 
5354  CONNECTION_UNLOCK (connection);
5355 
5356  return result;
5357 }
5358 
5380 void
5383  void *data,
5384  DBusFreeFunction free_data_function)
5385 {
5386  void *old_data = NULL;
5387  DBusFreeFunction old_free_function = NULL;
5388 
5389  _dbus_return_if_fail (connection != NULL);
5390 
5391  CONNECTION_LOCK (connection);
5393  function, data, free_data_function,
5394  &old_data, &old_free_function);
5395  CONNECTION_UNLOCK (connection);
5396 
5397  if (old_free_function != NULL)
5398  (* old_free_function) (old_data);
5399 }
5400 
5427 void
5429  dbus_bool_t value)
5430 {
5431  _dbus_return_if_fail (connection != NULL);
5432 
5433  CONNECTION_LOCK (connection);
5434  _dbus_transport_set_allow_anonymous (connection->transport, value);
5435  CONNECTION_UNLOCK (connection);
5436 }
5437 
5455 void
5457  dbus_bool_t value)
5458 {
5459  _dbus_return_if_fail (connection != NULL);
5460 
5461  CONNECTION_LOCK (connection);
5462  connection->route_peer_messages = TRUE;
5463  CONNECTION_UNLOCK (connection);
5464 }
5465 
5489  DBusHandleMessageFunction function,
5490  void *user_data,
5491  DBusFreeFunction free_data_function)
5492 {
5493  DBusMessageFilter *filter;
5494 
5495  _dbus_return_val_if_fail (connection != NULL, FALSE);
5496  _dbus_return_val_if_fail (function != NULL, FALSE);
5497 
5498  filter = dbus_new0 (DBusMessageFilter, 1);
5499  if (filter == NULL)
5500  return FALSE;
5501 
5502  _dbus_atomic_inc (&filter->refcount);
5503 
5504  CONNECTION_LOCK (connection);
5505 
5506  if (!_dbus_list_append (&connection->filter_list,
5507  filter))
5508  {
5509  _dbus_message_filter_unref (filter);
5510  CONNECTION_UNLOCK (connection);
5511  return FALSE;
5512  }
5513 
5514  /* Fill in filter after all memory allocated,
5515  * so we don't run the free_user_data_function
5516  * if the add_filter() fails
5517  */
5518 
5519  filter->function = function;
5520  filter->user_data = user_data;
5521  filter->free_user_data_function = free_data_function;
5522 
5523  CONNECTION_UNLOCK (connection);
5524  return TRUE;
5525 }
5526 
5539 void
5541  DBusHandleMessageFunction function,
5542  void *user_data)
5543 {
5544  DBusList *link;
5545  DBusMessageFilter *filter;
5546 
5547  _dbus_return_if_fail (connection != NULL);
5548  _dbus_return_if_fail (function != NULL);
5549 
5550  CONNECTION_LOCK (connection);
5551 
5552  filter = NULL;
5553 
5554  link = _dbus_list_get_last_link (&connection->filter_list);
5555  while (link != NULL)
5556  {
5557  filter = link->data;
5558 
5559  if (filter->function == function &&
5560  filter->user_data == user_data)
5561  {
5562  _dbus_list_remove_link (&connection->filter_list, link);
5563  filter->function = NULL;
5564 
5565  break;
5566  }
5567 
5568  link = _dbus_list_get_prev_link (&connection->filter_list, link);
5569  filter = NULL;
5570  }
5571 
5572  CONNECTION_UNLOCK (connection);
5573 
5574 #ifndef DBUS_DISABLE_CHECKS
5575  if (filter == NULL)
5576  {
5577  _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
5578  function, user_data);
5579  return;
5580  }
5581 #endif
5582 
5583  /* Call application code */
5584  if (filter->free_user_data_function)
5585  (* filter->free_user_data_function) (filter->user_data);
5586 
5587  filter->free_user_data_function = NULL;
5588  filter->user_data = NULL;
5589 
5590  _dbus_message_filter_unref (filter);
5591 }
5592 
5608 static dbus_bool_t
5609 _dbus_connection_register_object_path (DBusConnection *connection,
5610  dbus_bool_t fallback,
5611  const char *path,
5612  const DBusObjectPathVTable *vtable,
5613  void *user_data,
5614  DBusError *error)
5615 {
5616  char **decomposed_path;
5617  dbus_bool_t retval;
5618 
5619  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
5620  return FALSE;
5621 
5622  CONNECTION_LOCK (connection);
5623 
5624  retval = _dbus_object_tree_register (connection->objects,
5625  fallback,
5626  (const char **) decomposed_path, vtable,
5627  user_data, error);
5628 
5629  CONNECTION_UNLOCK (connection);
5630 
5631  dbus_free_string_array (decomposed_path);
5632 
5633  return retval;
5634 }
5635 
5650  const char *path,
5651  const DBusObjectPathVTable *vtable,
5652  void *user_data,
5653  DBusError *error)
5654 {
5655  _dbus_return_val_if_fail (connection != NULL, FALSE);
5656  _dbus_return_val_if_fail (path != NULL, FALSE);
5657  _dbus_return_val_if_fail (path[0] == '/', FALSE);
5658  _dbus_return_val_if_fail (vtable != NULL, FALSE);
5659 
5660  return _dbus_connection_register_object_path (connection, FALSE, path, vtable, user_data, error);
5661 }
5662 
5680  const char *path,
5681  const DBusObjectPathVTable *vtable,
5682  void *user_data)
5683 {
5684  dbus_bool_t retval;
5685  DBusError error = DBUS_ERROR_INIT;
5686 
5687  _dbus_return_val_if_fail (connection != NULL, FALSE);
5688  _dbus_return_val_if_fail (path != NULL, FALSE);
5689  _dbus_return_val_if_fail (path[0] == '/', FALSE);
5690  _dbus_return_val_if_fail (vtable != NULL, FALSE);
5691 
5692  retval = _dbus_connection_register_object_path (connection, FALSE, path, vtable, user_data, &error);
5693 
5695  {
5696  _dbus_warn ("%s\n", error.message);
5697  dbus_error_free (&error);
5698  return FALSE;
5699  }
5700 
5701  return retval;
5702 }
5703 
5720  const char *path,
5721  const DBusObjectPathVTable *vtable,
5722  void *user_data,
5723  DBusError *error)
5724 {
5725  _dbus_return_val_if_fail (connection != NULL, FALSE);
5726  _dbus_return_val_if_fail (path != NULL, FALSE);
5727  _dbus_return_val_if_fail (path[0] == '/', FALSE);
5728  _dbus_return_val_if_fail (vtable != NULL, FALSE);
5729 
5730  return _dbus_connection_register_object_path (connection, TRUE, path, vtable, user_data, error);
5731 }
5732 
5752  const char *path,
5753  const DBusObjectPathVTable *vtable,
5754  void *user_data)
5755 {
5756  dbus_bool_t retval;
5757  DBusError error = DBUS_ERROR_INIT;
5758 
5759  _dbus_return_val_if_fail (connection != NULL, FALSE);
5760  _dbus_return_val_if_fail (path != NULL, FALSE);
5761  _dbus_return_val_if_fail (path[0] == '/', FALSE);
5762  _dbus_return_val_if_fail (vtable != NULL, FALSE);
5763 
5764  retval = _dbus_connection_register_object_path (connection, TRUE, path, vtable, user_data, &error);
5765 
5767  {
5768  _dbus_warn ("%s\n", error.message);
5769  dbus_error_free (&error);
5770  return FALSE;
5771  }
5772 
5773  return retval;
5774 }
5775 
5787  const char *path)
5788 {
5789  char **decomposed_path;
5790 
5791  _dbus_return_val_if_fail (connection != NULL, FALSE);
5792  _dbus_return_val_if_fail (path != NULL, FALSE);
5793  _dbus_return_val_if_fail (path[0] == '/', FALSE);
5794 
5795  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
5796  return FALSE;
5797 
5798  CONNECTION_LOCK (connection);
5799 
5800  _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
5801 
5802  dbus_free_string_array (decomposed_path);
5803 
5804  return TRUE;
5805 }
5806 
5819  const char *path,
5820  void **data_p)
5821 {
5822  char **decomposed_path;
5823 
5824  _dbus_return_val_if_fail (connection != NULL, FALSE);
5825  _dbus_return_val_if_fail (path != NULL, FALSE);
5826  _dbus_return_val_if_fail (data_p != NULL, FALSE);
5827 
5828  *data_p = NULL;
5829 
5830  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
5831  return FALSE;
5832 
5833  CONNECTION_LOCK (connection);
5834 
5835  *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path);
5836 
5837  CONNECTION_UNLOCK (connection);
5838 
5839  dbus_free_string_array (decomposed_path);
5840 
5841  return TRUE;
5842 }
5843 
5856  const char *parent_path,
5857  char ***child_entries)
5858 {
5859  char **decomposed_path;
5860  dbus_bool_t retval;
5861  _dbus_return_val_if_fail (connection != NULL, FALSE);
5862  _dbus_return_val_if_fail (parent_path != NULL, FALSE);
5863  _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
5864  _dbus_return_val_if_fail (child_entries != NULL, FALSE);
5865 
5866  if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
5867  return FALSE;
5868 
5869  CONNECTION_LOCK (connection);
5870 
5872  (const char **) decomposed_path,
5873  child_entries);
5874  dbus_free_string_array (decomposed_path);
5875 
5876  return retval;
5877 }
5878 
5879 static DBusDataSlotAllocator slot_allocator =
5880  _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (connection_slots));
5881 
5898 {
5899  return _dbus_data_slot_allocator_alloc (&slot_allocator,
5900  slot_p);
5901 }
5902 
5914 void
5916 {
5917  _dbus_return_if_fail (*slot_p >= 0);
5918 
5919  _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
5920 }
5921 
5946  dbus_int32_t slot,
5947  void *data,
5948  DBusFreeFunction free_data_func)
5949 {
5950  DBusFreeFunction old_free_func;
5951  void *old_data;
5952  dbus_bool_t retval;
5953 
5954  _dbus_return_val_if_fail (connection != NULL, FALSE);
5955  _dbus_return_val_if_fail (slot >= 0, FALSE);
5956 
5957  SLOTS_LOCK (connection);
5958 
5959  retval = _dbus_data_slot_list_set (&slot_allocator,
5960  &connection->slot_list,
5961  slot, data, free_data_func,
5962  &old_free_func, &old_data);
5963 
5964  SLOTS_UNLOCK (connection);
5965 
5966  if (retval)
5967  {
5968  /* Do the actual free outside the connection lock */
5969  if (old_free_func)
5970  (* old_free_func) (old_data);
5971  }
5972 
5973  return retval;
5974 }
5975 
5993 void*
5995  dbus_int32_t slot)
5996 {
5997  void *res;
5998 
5999  _dbus_return_val_if_fail (connection != NULL, NULL);
6000  _dbus_return_val_if_fail (slot >= 0, NULL);
6001 
6002  SLOTS_LOCK (connection);
6003 
6004  res = _dbus_data_slot_list_get (&slot_allocator,
6005  &connection->slot_list,
6006  slot);
6007 
6008  SLOTS_UNLOCK (connection);
6009 
6010  return res;
6011 }
6012 
6019 void
6021 {
6022  _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
6023 }
6024 
6033 void
6035  long size)
6036 {
6037  _dbus_return_if_fail (connection != NULL);
6038 
6039  CONNECTION_LOCK (connection);
6041  size);
6042  CONNECTION_UNLOCK (connection);
6043 }
6044 
6051 long
6053 {
6054  long res;
6055 
6056  _dbus_return_val_if_fail (connection != NULL, 0);
6057 
6058  CONNECTION_LOCK (connection);
6059  res = _dbus_transport_get_max_message_size (connection->transport);
6060  CONNECTION_UNLOCK (connection);
6061  return res;
6062 }
6063 
6072 void
6074  long n)
6075 {
6076  _dbus_return_if_fail (connection != NULL);
6077 
6078  CONNECTION_LOCK (connection);
6080  n);
6081  CONNECTION_UNLOCK (connection);
6082 }
6083 
6090 long
6092 {
6093  long res;
6094 
6095  _dbus_return_val_if_fail (connection != NULL, 0);
6096 
6097  CONNECTION_LOCK (connection);
6099  CONNECTION_UNLOCK (connection);
6100  return res;
6101 }
6102 
6128 void
6130  long size)
6131 {
6132  _dbus_return_if_fail (connection != NULL);
6133 
6134  CONNECTION_LOCK (connection);
6136  size);
6137  CONNECTION_UNLOCK (connection);
6138 }
6139 
6146 long
6148 {
6149  long res;
6150 
6151  _dbus_return_val_if_fail (connection != NULL, 0);
6152 
6153  CONNECTION_LOCK (connection);
6155  CONNECTION_UNLOCK (connection);
6156  return res;
6157 }
6158 
6170 void
6172  long n)
6173 {
6174  _dbus_return_if_fail (connection != NULL);
6175 
6176  CONNECTION_LOCK (connection);
6178  n);
6179  CONNECTION_UNLOCK (connection);
6180 }
6181 
6188 long
6190 {
6191  long res;
6192 
6193  _dbus_return_val_if_fail (connection != NULL, 0);
6194 
6195  CONNECTION_LOCK (connection);
6197  CONNECTION_UNLOCK (connection);
6198  return res;
6199 }
6200 
6211 long
6213 {
6214  long res;
6215 
6216  _dbus_return_val_if_fail (connection != NULL, 0);
6217 
6218  CONNECTION_LOCK (connection);
6219  res = _dbus_counter_get_size_value (connection->outgoing_counter);
6220  CONNECTION_UNLOCK (connection);
6221  return res;
6222 }
6223 
6224 #ifdef DBUS_ENABLE_STATS
6225 void
6226 _dbus_connection_get_stats (DBusConnection *connection,
6227  dbus_uint32_t *in_messages,
6228  dbus_uint32_t *in_bytes,
6229  dbus_uint32_t *in_fds,
6230  dbus_uint32_t *in_peak_bytes,
6231  dbus_uint32_t *in_peak_fds,
6232  dbus_uint32_t *out_messages,
6233  dbus_uint32_t *out_bytes,
6234  dbus_uint32_t *out_fds,
6235  dbus_uint32_t *out_peak_bytes,
6236  dbus_uint32_t *out_peak_fds)
6237 {
6238  CONNECTION_LOCK (connection);
6239 
6240  if (in_messages != NULL)
6241  *in_messages = connection->n_incoming;
6242 
6243  _dbus_transport_get_stats (connection->transport,
6244  in_bytes, in_fds, in_peak_bytes, in_peak_fds);
6245 
6246  if (out_messages != NULL)
6247  *out_messages = connection->n_outgoing;
6248 
6249  if (out_bytes != NULL)
6250  *out_bytes = _dbus_counter_get_size_value (connection->outgoing_counter);
6251 
6252  if (out_fds != NULL)
6253  *out_fds = _dbus_counter_get_unix_fd_value (connection->outgoing_counter);
6254 
6255  if (out_peak_bytes != NULL)
6256  *out_peak_bytes = _dbus_counter_get_peak_size_value (connection->outgoing_counter);
6257 
6258  if (out_peak_fds != NULL)
6259  *out_peak_fds = _dbus_counter_get_peak_unix_fd_value (connection->outgoing_counter);
6260 
6261  CONNECTION_UNLOCK (connection);
6262 }
6263 #endif /* DBUS_ENABLE_STATS */
6264 
6272 long
6274 {
6275  long res;
6276 
6277  _dbus_return_val_if_fail (connection != NULL, 0);
6278 
6279  CONNECTION_LOCK (connection);
6281  CONNECTION_UNLOCK (connection);
6282  return res;
6283 }
6284 
6285 #ifdef DBUS_BUILD_TESTS
6286 
6292 const char*
6293 _dbus_connection_get_address (DBusConnection *connection)
6294 {
6295  return _dbus_transport_get_address (connection->transport);
6296 }
6297 #endif
6298