D-Bus  1.4.10
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-pending-call.h"
42 #include "dbus-object-tree.h"
43 #include "dbus-threads-internal.h"
44 #include "dbus-bus.h"
45 #include "dbus-marshal-basic.h"
46 
47 #ifdef DBUS_DISABLE_CHECKS
48 #define TOOK_LOCK_CHECK(connection)
49 #define RELEASING_LOCK_CHECK(connection)
50 #define HAVE_LOCK_CHECK(connection)
51 #else
52 #define TOOK_LOCK_CHECK(connection) do { \
53  _dbus_assert (!(connection)->have_connection_lock); \
54  (connection)->have_connection_lock = TRUE; \
55  } while (0)
56 #define RELEASING_LOCK_CHECK(connection) do { \
57  _dbus_assert ((connection)->have_connection_lock); \
58  (connection)->have_connection_lock = FALSE; \
59  } while (0)
60 #define HAVE_LOCK_CHECK(connection) _dbus_assert ((connection)->have_connection_lock)
61 /* A "DO_NOT_HAVE_LOCK_CHECK" is impossible since we need the lock to check the flag */
62 #endif
63 
64 #define TRACE_LOCKS 1
65 
66 #define CONNECTION_LOCK(connection) do { \
67  if (TRACE_LOCKS) { _dbus_verbose ("LOCK\n"); } \
68  _dbus_mutex_lock ((connection)->mutex); \
69  TOOK_LOCK_CHECK (connection); \
70  } while (0)
71 
72 #define CONNECTION_UNLOCK(connection) do { \
73  if (TRACE_LOCKS) { _dbus_verbose ("UNLOCK\n"); } \
74  RELEASING_LOCK_CHECK (connection); \
75  _dbus_mutex_unlock ((connection)->mutex); \
76  } while (0)
77 
78 #define SLOTS_LOCK(connection) do { \
79  _dbus_mutex_lock ((connection)->slot_mutex); \
80  } while (0)
81 
82 #define SLOTS_UNLOCK(connection) do { \
83  _dbus_mutex_unlock ((connection)->slot_mutex); \
84  } while (0)
85 
86 #define DISPATCH_STATUS_NAME(s) \
87  ((s) == DBUS_DISPATCH_COMPLETE ? "complete" : \
88  (s) == DBUS_DISPATCH_DATA_REMAINS ? "data remains" : \
89  (s) == DBUS_DISPATCH_NEED_MEMORY ? "need memory" : \
90  "???")
91 
213 
218 {
221  void *user_data;
223 };
224 
225 
230 {
234 };
235 
236 #if HAVE_DECL_MSG_NOSIGNAL
237 static dbus_bool_t _dbus_modify_sigpipe = FALSE;
238 #else
239 static dbus_bool_t _dbus_modify_sigpipe = TRUE;
240 #endif
241 
246 {
297  char *server_guid;
299  /* These two MUST be bools and not bitfields, because they are protected by a separate lock
300  * from connection->mutex and all bitfields in a word have to be read/written together.
301  * So you can't have a different lock for different bitfields in the same word.
302  */
306  unsigned int shareable : 1;
308  unsigned int exit_on_disconnect : 1;
310  unsigned int route_peer_messages : 1;
312  unsigned int disconnected_message_arrived : 1;
320 #ifndef DBUS_DISABLE_CHECKS
321  unsigned int have_connection_lock : 1;
322 #endif
323 
324 #ifndef DBUS_DISABLE_CHECKS
326 #endif
327 };
328 
329 static DBusDispatchStatus _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection);
330 static void _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
331  DBusDispatchStatus new_status);
332 static void _dbus_connection_last_unref (DBusConnection *connection);
333 static void _dbus_connection_acquire_dispatch (DBusConnection *connection);
334 static void _dbus_connection_release_dispatch (DBusConnection *connection);
335 static DBusDispatchStatus _dbus_connection_flush_unlocked (DBusConnection *connection);
336 static void _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection);
337 static dbus_bool_t _dbus_connection_get_is_connected_unlocked (DBusConnection *connection);
338 static dbus_bool_t _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection,
339  dbus_uint32_t client_serial);
340 
341 static DBusMessageFilter *
342 _dbus_message_filter_ref (DBusMessageFilter *filter)
343 {
344  _dbus_assert (filter->refcount.value > 0);
345  _dbus_atomic_inc (&filter->refcount);
346 
347  return filter;
348 }
349 
350 static void
351 _dbus_message_filter_unref (DBusMessageFilter *filter)
352 {
353  _dbus_assert (filter->refcount.value > 0);
354 
355  if (_dbus_atomic_dec (&filter->refcount) == 1)
356  {
357  if (filter->free_user_data_function)
358  (* filter->free_user_data_function) (filter->user_data);
359 
360  dbus_free (filter);
361  }
362 }
363 
369 void
371 {
372  CONNECTION_LOCK (connection);
373 }
374 
380 void
382 {
383  CONNECTION_UNLOCK (connection);
384 }
385 
393 static void
394 _dbus_connection_wakeup_mainloop (DBusConnection *connection)
395 {
396  if (connection->wakeup_main_function)
397  (*connection->wakeup_main_function) (connection->wakeup_main_data);
398 }
399 
400 #ifdef DBUS_BUILD_TESTS
401 /* For now this function isn't used */
412 _dbus_connection_queue_received_message (DBusConnection *connection,
413  DBusMessage *message)
414 {
415  DBusList *link;
416 
417  link = _dbus_list_alloc_link (message);
418  if (link == NULL)
419  return FALSE;
420 
421  dbus_message_ref (message);
423 
424  return TRUE;
425 }
426 
439 void
440 _dbus_connection_test_get_locks (DBusConnection *connection,
441  DBusMutex **mutex_loc,
442  DBusMutex **dispatch_mutex_loc,
443  DBusMutex **io_path_mutex_loc,
444  DBusCondVar **dispatch_cond_loc,
445  DBusCondVar **io_path_cond_loc)
446 {
447  *mutex_loc = connection->mutex;
448  *dispatch_mutex_loc = connection->dispatch_mutex;
449  *io_path_mutex_loc = connection->io_path_mutex;
450  *dispatch_cond_loc = connection->dispatch_cond;
451  *io_path_cond_loc = connection->io_path_cond;
452 }
453 #endif
454 
463 void
465  DBusList *link)
466 {
467  DBusPendingCall *pending;
468  dbus_uint32_t reply_serial;
469  DBusMessage *message;
470 
472 
474  link);
475  message = link->data;
476 
477  /* If this is a reply we're waiting on, remove timeout for it */
478  reply_serial = dbus_message_get_reply_serial (message);
479  if (reply_serial != 0)
480  {
481  pending = _dbus_hash_table_lookup_int (connection->pending_replies,
482  reply_serial);
483  if (pending != NULL)
484  {
488 
490  }
491  }
492 
493 
494 
495  connection->n_incoming += 1;
496 
497  _dbus_connection_wakeup_mainloop (connection);
498 
499  _dbus_verbose ("Message %p (%s %s %s %s '%s' reply to %u) added to incoming queue %p, %d incoming\n",
500  message,
502  dbus_message_get_path (message) ?
503  dbus_message_get_path (message) :
504  "no path",
505  dbus_message_get_interface (message) ?
506  dbus_message_get_interface (message) :
507  "no interface",
508  dbus_message_get_member (message) ?
509  dbus_message_get_member (message) :
510  "no member",
511  dbus_message_get_signature (message),
513  connection,
514  connection->n_incoming);}
515 
524 void
526  DBusList *link)
527 {
528  HAVE_LOCK_CHECK (connection);
529 
530  _dbus_list_append_link (&connection->incoming_messages, link);
531 
532  connection->n_incoming += 1;
533 
534  _dbus_connection_wakeup_mainloop (connection);
535 
536  _dbus_verbose ("Synthesized message %p added to incoming queue %p, %d incoming\n",
537  link->data, connection, connection->n_incoming);
538 }
539 
540 
550 {
551  HAVE_LOCK_CHECK (connection);
552  return connection->outgoing_messages != NULL;
553 }
554 
566 {
567  dbus_bool_t v;
568 
569  _dbus_return_val_if_fail (connection != NULL, FALSE);
570 
571  CONNECTION_LOCK (connection);
573  CONNECTION_UNLOCK (connection);
574 
575  return v;
576 }
577 
587 {
588  HAVE_LOCK_CHECK (connection);
589 
590  return _dbus_list_get_last (&connection->outgoing_messages);
591 }
592 
601 void
603  DBusMessage *message)
604 {
605  DBusList *link;
606 
607  HAVE_LOCK_CHECK (connection);
608 
609  /* This can be called before we even complete authentication, since
610  * it's called on disconnect to clean up the outgoing queue.
611  * It's also called as we successfully send each message.
612  */
613 
614  link = _dbus_list_get_last_link (&connection->outgoing_messages);
615  _dbus_assert (link != NULL);
616  _dbus_assert (link->data == message);
617 
618  /* Save this link in the link cache */
619  _dbus_list_unlink (&connection->outgoing_messages,
620  link);
621  _dbus_list_prepend_link (&connection->link_cache, link);
622 
623  connection->n_outgoing -= 1;
624 
625  _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from outgoing queue %p, %d left to send\n",
626  message,
628  dbus_message_get_path (message) ?
629  dbus_message_get_path (message) :
630  "no path",
631  dbus_message_get_interface (message) ?
632  dbus_message_get_interface (message) :
633  "no interface",
634  dbus_message_get_member (message) ?
635  dbus_message_get_member (message) :
636  "no member",
637  dbus_message_get_signature (message),
638  connection, connection->n_outgoing);
639 
640  /* Save this link in the link cache also */
641  _dbus_message_remove_counter (message, connection->outgoing_counter,
642  &link);
643  _dbus_list_prepend_link (&connection->link_cache, link);
644 
645  dbus_message_unref (message);
646 }
647 
650  DBusWatch *watch);
652 typedef void (* DBusWatchRemoveFunction) (DBusWatchList *list,
653  DBusWatch *watch);
655 typedef void (* DBusWatchToggleFunction) (DBusWatchList *list,
656  DBusWatch *watch,
657  dbus_bool_t enabled);
658 
659 static dbus_bool_t
660 protected_change_watch (DBusConnection *connection,
661  DBusWatch *watch,
662  DBusWatchAddFunction add_function,
663  DBusWatchRemoveFunction remove_function,
664  DBusWatchToggleFunction toggle_function,
665  dbus_bool_t enabled)
666 {
667  dbus_bool_t retval;
668 
669  HAVE_LOCK_CHECK (connection);
670 
671  /* The original purpose of protected_change_watch() was to hold a
672  * ref on the connection while dropping the connection lock, then
673  * calling out to the app. This was a broken hack that did not
674  * work, since the connection was in a hosed state (no WatchList
675  * field) while calling out.
676  *
677  * So for now we'll just keep the lock while calling out. This means
678  * apps are not allowed to call DBusConnection methods inside a
679  * watch function or they will deadlock.
680  *
681  * The "real fix" is to use the _and_unlock() pattern found
682  * elsewhere in the code, to defer calling out to the app until
683  * we're about to drop locks and return flow of control to the app
684  * anyway.
685  *
686  * See http://lists.freedesktop.org/archives/dbus/2007-July/thread.html#8144
687  */
688 
689  if (connection->watches)
690  {
691  if (add_function)
692  retval = (* add_function) (connection->watches, watch);
693  else if (remove_function)
694  {
695  retval = TRUE;
696  (* remove_function) (connection->watches, watch);
697  }
698  else
699  {
700  retval = TRUE;
701  (* toggle_function) (connection->watches, watch, enabled);
702  }
703  return retval;
704  }
705  else
706  return FALSE;
707 }
708 
709 
723  DBusWatch *watch)
724 {
725  return protected_change_watch (connection, watch,
727  NULL, NULL, FALSE);
728 }
729 
739 void
741  DBusWatch *watch)
742 {
743  protected_change_watch (connection, watch,
744  NULL,
746  NULL, FALSE);
747 }
748 
759 void
761  DBusWatch *watch,
762  dbus_bool_t enabled)
763 {
764  _dbus_assert (watch != NULL);
765 
766  protected_change_watch (connection, watch,
767  NULL, NULL,
769  enabled);
770 }
771 
774  DBusTimeout *timeout);
777  DBusTimeout *timeout);
780  DBusTimeout *timeout,
781  dbus_bool_t enabled);
782 
783 static dbus_bool_t
784 protected_change_timeout (DBusConnection *connection,
785  DBusTimeout *timeout,
786  DBusTimeoutAddFunction add_function,
787  DBusTimeoutRemoveFunction remove_function,
788  DBusTimeoutToggleFunction toggle_function,
789  dbus_bool_t enabled)
790 {
791  dbus_bool_t retval;
792 
793  HAVE_LOCK_CHECK (connection);
794 
795  /* The original purpose of protected_change_timeout() was to hold a
796  * ref on the connection while dropping the connection lock, then
797  * calling out to the app. This was a broken hack that did not
798  * work, since the connection was in a hosed state (no TimeoutList
799  * field) while calling out.
800  *
801  * So for now we'll just keep the lock while calling out. This means
802  * apps are not allowed to call DBusConnection methods inside a
803  * timeout function or they will deadlock.
804  *
805  * The "real fix" is to use the _and_unlock() pattern found
806  * elsewhere in the code, to defer calling out to the app until
807  * we're about to drop locks and return flow of control to the app
808  * anyway.
809  *
810  * See http://lists.freedesktop.org/archives/dbus/2007-July/thread.html#8144
811  */
812 
813  if (connection->timeouts)
814  {
815  if (add_function)
816  retval = (* add_function) (connection->timeouts, timeout);
817  else if (remove_function)
818  {
819  retval = TRUE;
820  (* remove_function) (connection->timeouts, timeout);
821  }
822  else
823  {
824  retval = TRUE;
825  (* toggle_function) (connection->timeouts, timeout, enabled);
826  }
827  return retval;
828  }
829  else
830  return FALSE;
831 }
832 
847  DBusTimeout *timeout)
848 {
849  return protected_change_timeout (connection, timeout,
851  NULL, NULL, FALSE);
852 }
853 
863 void
865  DBusTimeout *timeout)
866 {
867  protected_change_timeout (connection, timeout,
868  NULL,
870  NULL, FALSE);
871 }
872 
883 void
885  DBusTimeout *timeout,
886  dbus_bool_t enabled)
887 {
888  protected_change_timeout (connection, timeout,
889  NULL, NULL,
891  enabled);
892 }
893 
894 static dbus_bool_t
895 _dbus_connection_attach_pending_call_unlocked (DBusConnection *connection,
896  DBusPendingCall *pending)
897 {
898  dbus_uint32_t reply_serial;
899  DBusTimeout *timeout;
900 
901  HAVE_LOCK_CHECK (connection);
902 
903  reply_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
904 
905  _dbus_assert (reply_serial != 0);
906 
907  timeout = _dbus_pending_call_get_timeout_unlocked (pending);
908 
909  if (timeout)
910  {
911  if (!_dbus_connection_add_timeout_unlocked (connection, timeout))
912  return FALSE;
913 
915  reply_serial,
916  pending))
917  {
918  _dbus_connection_remove_timeout_unlocked (connection, timeout);
919 
921  HAVE_LOCK_CHECK (connection);
922  return FALSE;
923  }
924 
926  }
927  else
928  {
930  reply_serial,
931  pending))
932  {
933  HAVE_LOCK_CHECK (connection);
934  return FALSE;
935  }
936  }
937 
939 
940  HAVE_LOCK_CHECK (connection);
941 
942  return TRUE;
943 }
944 
945 static void
946 free_pending_call_on_hash_removal (void *data)
947 {
948  DBusPendingCall *pending;
949  DBusConnection *connection;
950 
951  if (data == NULL)
952  return;
953 
954  pending = data;
955 
956  connection = _dbus_pending_call_get_connection_unlocked (pending);
957 
958  HAVE_LOCK_CHECK (connection);
959 
961  {
964 
966  }
967 
968  /* FIXME 1.0? this is sort of dangerous and undesirable to drop the lock
969  * here, but the pending call finalizer could in principle call out to
970  * application code so we pretty much have to... some larger code reorg
971  * might be needed.
972  */
973  _dbus_connection_ref_unlocked (connection);
975  CONNECTION_LOCK (connection);
976  _dbus_connection_unref_unlocked (connection);
977 }
978 
979 static void
980 _dbus_connection_detach_pending_call_unlocked (DBusConnection *connection,
981  DBusPendingCall *pending)
982 {
983  /* This ends up unlocking to call the pending call finalizer, which is unexpected to
984  * say the least.
985  */
988 }
989 
990 static void
991 _dbus_connection_detach_pending_call_and_unlock (DBusConnection *connection,
992  DBusPendingCall *pending)
993 {
994  /* The idea here is to avoid finalizing the pending call
995  * with the lock held, since there's a destroy notifier
996  * in pending call that goes out to application code.
997  *
998  * There's an extra unlock inside the hash table
999  * "free pending call" function FIXME...
1000  */
1004 
1008 
1010 
1012 }
1013 
1022 void
1024  DBusPendingCall *pending)
1025 {
1026  CONNECTION_LOCK (connection);
1027  _dbus_connection_detach_pending_call_and_unlock (connection, pending);
1028 }
1029 
1039 static dbus_bool_t
1040 _dbus_connection_acquire_io_path (DBusConnection *connection,
1041  int timeout_milliseconds)
1042 {
1043  dbus_bool_t we_acquired;
1044 
1045  HAVE_LOCK_CHECK (connection);
1046 
1047  /* We don't want the connection to vanish */
1048  _dbus_connection_ref_unlocked (connection);
1049 
1050  /* We will only touch io_path_acquired which is protected by our mutex */
1051  CONNECTION_UNLOCK (connection);
1052 
1053  _dbus_verbose ("locking io_path_mutex\n");
1054  _dbus_mutex_lock (connection->io_path_mutex);
1055 
1056  _dbus_verbose ("start connection->io_path_acquired = %d timeout = %d\n",
1057  connection->io_path_acquired, timeout_milliseconds);
1058 
1059  we_acquired = FALSE;
1060 
1061  if (connection->io_path_acquired)
1062  {
1063  if (timeout_milliseconds != -1)
1064  {
1065  _dbus_verbose ("waiting %d for IO path to be acquirable\n",
1066  timeout_milliseconds);
1067 
1068  if (!_dbus_condvar_wait_timeout (connection->io_path_cond,
1069  connection->io_path_mutex,
1070  timeout_milliseconds))
1071  {
1072  /* We timed out before anyone signaled. */
1073  /* (writing the loop to handle the !timedout case by
1074  * waiting longer if needed is a pain since dbus
1075  * wraps pthread_cond_timedwait to take a relative
1076  * time instead of absolute, something kind of stupid
1077  * on our part. for now it doesn't matter, we will just
1078  * end up back here eventually.)
1079  */
1080  }
1081  }
1082  else
1083  {
1084  while (connection->io_path_acquired)
1085  {
1086  _dbus_verbose ("waiting for IO path to be acquirable\n");
1087  _dbus_condvar_wait (connection->io_path_cond,
1088  connection->io_path_mutex);
1089  }
1090  }
1091  }
1092 
1093  if (!connection->io_path_acquired)
1094  {
1095  we_acquired = TRUE;
1096  connection->io_path_acquired = TRUE;
1097  }
1098 
1099  _dbus_verbose ("end connection->io_path_acquired = %d we_acquired = %d\n",
1100  connection->io_path_acquired, we_acquired);
1101 
1102  _dbus_verbose ("unlocking io_path_mutex\n");
1103  _dbus_mutex_unlock (connection->io_path_mutex);
1104 
1105  CONNECTION_LOCK (connection);
1106 
1107  HAVE_LOCK_CHECK (connection);
1108 
1109  _dbus_connection_unref_unlocked (connection);
1110 
1111  return we_acquired;
1112 }
1113 
1121 static void
1122 _dbus_connection_release_io_path (DBusConnection *connection)
1123 {
1124  HAVE_LOCK_CHECK (connection);
1125 
1126  _dbus_verbose ("locking io_path_mutex\n");
1127  _dbus_mutex_lock (connection->io_path_mutex);
1128 
1129  _dbus_assert (connection->io_path_acquired);
1130 
1131  _dbus_verbose ("start connection->io_path_acquired = %d\n",
1132  connection->io_path_acquired);
1133 
1134  connection->io_path_acquired = FALSE;
1135  _dbus_condvar_wake_one (connection->io_path_cond);
1136 
1137  _dbus_verbose ("unlocking io_path_mutex\n");
1138  _dbus_mutex_unlock (connection->io_path_mutex);
1139 }
1140 
1176 void
1178  DBusPendingCall *pending,
1179  unsigned int flags,
1180  int timeout_milliseconds)
1181 {
1182  _dbus_verbose ("start\n");
1183 
1184  HAVE_LOCK_CHECK (connection);
1185 
1186  if (connection->n_outgoing == 0)
1187  flags &= ~DBUS_ITERATION_DO_WRITING;
1188 
1189  if (_dbus_connection_acquire_io_path (connection,
1190  (flags & DBUS_ITERATION_BLOCK) ? timeout_milliseconds : 0))
1191  {
1192  HAVE_LOCK_CHECK (connection);
1193 
1194  if ( (pending != NULL) && _dbus_pending_call_get_completed_unlocked(pending))
1195  {
1196  _dbus_verbose ("pending call completed while acquiring I/O path");
1197  }
1198  else if ( (pending != NULL) &&
1199  _dbus_connection_peek_for_reply_unlocked (connection,
1201  {
1202  _dbus_verbose ("pending call completed while acquiring I/O path (reply found in queue)");
1203  }
1204  else
1205  {
1207  flags, timeout_milliseconds);
1208  }
1209 
1210  _dbus_connection_release_io_path (connection);
1211  }
1212 
1213  HAVE_LOCK_CHECK (connection);
1214 
1215  _dbus_verbose ("end\n");
1216 }
1217 
1229 {
1230  DBusConnection *connection;
1231  DBusWatchList *watch_list;
1232  DBusTimeoutList *timeout_list;
1233  DBusHashTable *pending_replies;
1234  DBusList *disconnect_link;
1235  DBusMessage *disconnect_message;
1236  DBusCounter *outgoing_counter;
1237  DBusObjectTree *objects;
1238 
1239  watch_list = NULL;
1240  connection = NULL;
1241  pending_replies = NULL;
1242  timeout_list = NULL;
1243  disconnect_link = NULL;
1244  disconnect_message = NULL;
1245  outgoing_counter = NULL;
1246  objects = NULL;
1247 
1248  watch_list = _dbus_watch_list_new ();
1249  if (watch_list == NULL)
1250  goto error;
1251 
1252  timeout_list = _dbus_timeout_list_new ();
1253  if (timeout_list == NULL)
1254  goto error;
1255 
1256  pending_replies =
1258  NULL,
1259  (DBusFreeFunction)free_pending_call_on_hash_removal);
1260  if (pending_replies == NULL)
1261  goto error;
1262 
1263  connection = dbus_new0 (DBusConnection, 1);
1264  if (connection == NULL)
1265  goto error;
1266 
1267  _dbus_mutex_new_at_location (&connection->mutex);
1268  if (connection->mutex == NULL)
1269  goto error;
1270 
1272  if (connection->io_path_mutex == NULL)
1273  goto error;
1274 
1276  if (connection->dispatch_mutex == NULL)
1277  goto error;
1278 
1280  if (connection->dispatch_cond == NULL)
1281  goto error;
1282 
1284  if (connection->io_path_cond == NULL)
1285  goto error;
1286 
1287  _dbus_mutex_new_at_location (&connection->slot_mutex);
1288  if (connection->slot_mutex == NULL)
1289  goto error;
1290 
1291  disconnect_message = dbus_message_new_signal (DBUS_PATH_LOCAL,
1293  "Disconnected");
1294 
1295  if (disconnect_message == NULL)
1296  goto error;
1297 
1298  disconnect_link = _dbus_list_alloc_link (disconnect_message);
1299  if (disconnect_link == NULL)
1300  goto error;
1301 
1302  outgoing_counter = _dbus_counter_new ();
1303  if (outgoing_counter == NULL)
1304  goto error;
1305 
1306  objects = _dbus_object_tree_new (connection);
1307  if (objects == NULL)
1308  goto error;
1309 
1310  if (_dbus_modify_sigpipe)
1312 
1313  connection->refcount.value = 1;
1314  connection->transport = transport;
1315  connection->watches = watch_list;
1316  connection->timeouts = timeout_list;
1317  connection->pending_replies = pending_replies;
1318  connection->outgoing_counter = outgoing_counter;
1319  connection->filter_list = NULL;
1320  connection->last_dispatch_status = DBUS_DISPATCH_COMPLETE; /* so we're notified first time there's data */
1321  connection->objects = objects;
1322  connection->exit_on_disconnect = FALSE;
1323  connection->shareable = FALSE;
1324  connection->route_peer_messages = FALSE;
1325  connection->disconnected_message_arrived = FALSE;
1326  connection->disconnected_message_processed = FALSE;
1327 
1328 #ifndef DBUS_DISABLE_CHECKS
1329  connection->generation = _dbus_current_generation;
1330 #endif
1331 
1332  _dbus_data_slot_list_init (&connection->slot_list);
1333 
1334  connection->client_serial = 1;
1335 
1336  connection->disconnect_message_link = disconnect_link;
1337 
1338  CONNECTION_LOCK (connection);
1339 
1340  if (!_dbus_transport_set_connection (transport, connection))
1341  {
1342  CONNECTION_UNLOCK (connection);
1343 
1344  goto error;
1345  }
1346 
1347  _dbus_transport_ref (transport);
1348 
1349  CONNECTION_UNLOCK (connection);
1350 
1351  return connection;
1352 
1353  error:
1354  if (disconnect_message != NULL)
1355  dbus_message_unref (disconnect_message);
1356 
1357  if (disconnect_link != NULL)
1358  _dbus_list_free_link (disconnect_link);
1359 
1360  if (connection != NULL)
1361  {
1364  _dbus_mutex_free_at_location (&connection->mutex);
1368  dbus_free (connection);
1369  }
1370  if (pending_replies)
1371  _dbus_hash_table_unref (pending_replies);
1372 
1373  if (watch_list)
1374  _dbus_watch_list_free (watch_list);
1375 
1376  if (timeout_list)
1377  _dbus_timeout_list_free (timeout_list);
1378 
1379  if (outgoing_counter)
1380  _dbus_counter_unref (outgoing_counter);
1381 
1382  if (objects)
1383  _dbus_object_tree_unref (objects);
1384 
1385  return NULL;
1386 }
1387 
1397 {
1398  _dbus_assert (connection != NULL);
1400 
1401  HAVE_LOCK_CHECK (connection);
1402 
1403 #ifdef DBUS_HAVE_ATOMIC_INT
1404  _dbus_atomic_inc (&connection->refcount);
1405 #else
1406  _dbus_assert (connection->refcount.value > 0);
1407  connection->refcount.value += 1;
1408 #endif
1409 
1410  return connection;
1411 }
1412 
1419 void
1421 {
1422  dbus_bool_t last_unref;
1423 
1424  HAVE_LOCK_CHECK (connection);
1425 
1426  _dbus_assert (connection != NULL);
1427 
1428  /* The connection lock is better than the global
1429  * lock in the atomic increment fallback
1430  */
1431 
1432 #ifdef DBUS_HAVE_ATOMIC_INT
1433  last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
1434 #else
1435  _dbus_assert (connection->refcount.value > 0);
1436 
1437  connection->refcount.value -= 1;
1438  last_unref = (connection->refcount.value == 0);
1439 #if 0
1440  printf ("unref_unlocked() connection %p count = %d\n", connection, connection->refcount.value);
1441 #endif
1442 #endif
1443 
1444  if (last_unref)
1445  _dbus_connection_last_unref (connection);
1446 }
1447 
1448 static dbus_uint32_t
1449 _dbus_connection_get_next_client_serial (DBusConnection *connection)
1450 {
1451  dbus_uint32_t serial;
1452 
1453  serial = connection->client_serial++;
1454 
1455  if (connection->client_serial == 0)
1456  connection->client_serial = 1;
1457 
1458  return serial;
1459 }
1460 
1476  unsigned int condition,
1477  void *data)
1478 {
1479  DBusConnection *connection;
1480  dbus_bool_t retval;
1481  DBusDispatchStatus status;
1482 
1483  connection = data;
1484 
1485  _dbus_verbose ("start\n");
1486 
1487  CONNECTION_LOCK (connection);
1488 
1489  if (!_dbus_connection_acquire_io_path (connection, 1))
1490  {
1491  /* another thread is handling the message */
1492  CONNECTION_UNLOCK (connection);
1493  return TRUE;
1494  }
1495 
1496  HAVE_LOCK_CHECK (connection);
1497  retval = _dbus_transport_handle_watch (connection->transport,
1498  watch, condition);
1499 
1500  _dbus_connection_release_io_path (connection);
1501 
1502  HAVE_LOCK_CHECK (connection);
1503 
1504  _dbus_verbose ("middle\n");
1505 
1506  status = _dbus_connection_get_dispatch_status_unlocked (connection);
1507 
1508  /* this calls out to user code */
1509  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
1510 
1511  _dbus_verbose ("end\n");
1512 
1513  return retval;
1514 }
1515 
1516 _DBUS_DEFINE_GLOBAL_LOCK (shared_connections);
1517 static DBusHashTable *shared_connections = NULL;
1518 static DBusList *shared_connections_no_guid = NULL;
1519 
1520 static void
1521 close_connection_on_shutdown (DBusConnection *connection)
1522 {
1523  DBusMessage *message;
1524 
1525  dbus_connection_ref (connection);
1527 
1528  /* Churn through to the Disconnected message */
1529  while ((message = dbus_connection_pop_message (connection)))
1530  {
1531  dbus_message_unref (message);
1532  }
1533  dbus_connection_unref (connection);
1534 }
1535 
1536 static void
1537 shared_connections_shutdown (void *data)
1538 {
1539  int n_entries;
1540 
1541  _DBUS_LOCK (shared_connections);
1542 
1543  /* This is a little bit unpleasant... better ideas? */
1544  while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0)
1545  {
1546  DBusConnection *connection;
1547  DBusHashIter iter;
1548 
1549  _dbus_hash_iter_init (shared_connections, &iter);
1550  _dbus_hash_iter_next (&iter);
1551 
1552  connection = _dbus_hash_iter_get_value (&iter);
1553 
1554  _DBUS_UNLOCK (shared_connections);
1555  close_connection_on_shutdown (connection);
1556  _DBUS_LOCK (shared_connections);
1557 
1558  /* The connection should now be dead and not in our hash ... */
1559  _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) < n_entries);
1560  }
1561 
1562  _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) == 0);
1563 
1564  _dbus_hash_table_unref (shared_connections);
1565  shared_connections = NULL;
1566 
1567  if (shared_connections_no_guid != NULL)
1568  {
1569  DBusConnection *connection;
1570  connection = _dbus_list_pop_first (&shared_connections_no_guid);
1571  while (connection != NULL)
1572  {
1573  _DBUS_UNLOCK (shared_connections);
1574  close_connection_on_shutdown (connection);
1575  _DBUS_LOCK (shared_connections);
1576  connection = _dbus_list_pop_first (&shared_connections_no_guid);
1577  }
1578  }
1579 
1580  shared_connections_no_guid = NULL;
1581 
1582  _DBUS_UNLOCK (shared_connections);
1583 }
1584 
1585 static dbus_bool_t
1586 connection_lookup_shared (DBusAddressEntry *entry,
1587  DBusConnection **result)
1588 {
1589  _dbus_verbose ("checking for existing connection\n");
1590 
1591  *result = NULL;
1592 
1593  _DBUS_LOCK (shared_connections);
1594 
1595  if (shared_connections == NULL)
1596  {
1597  _dbus_verbose ("creating shared_connections hash table\n");
1598 
1599  shared_connections = _dbus_hash_table_new (DBUS_HASH_STRING,
1600  dbus_free,
1601  NULL);
1602  if (shared_connections == NULL)
1603  {
1604  _DBUS_UNLOCK (shared_connections);
1605  return FALSE;
1606  }
1607 
1608  if (!_dbus_register_shutdown_func (shared_connections_shutdown, NULL))
1609  {
1610  _dbus_hash_table_unref (shared_connections);
1611  shared_connections = NULL;
1612  _DBUS_UNLOCK (shared_connections);
1613  return FALSE;
1614  }
1615 
1616  _dbus_verbose (" successfully created shared_connections\n");
1617 
1618  _DBUS_UNLOCK (shared_connections);
1619  return TRUE; /* no point looking up in the hash we just made */
1620  }
1621  else
1622  {
1623  const char *guid;
1624 
1625  guid = dbus_address_entry_get_value (entry, "guid");
1626 
1627  if (guid != NULL)
1628  {
1629  DBusConnection *connection;
1630 
1631  connection = _dbus_hash_table_lookup_string (shared_connections,
1632  guid);
1633 
1634  if (connection)
1635  {
1636  /* The DBusConnection can't be finalized without taking
1637  * the shared_connections lock to remove it from the
1638  * hash. So it's safe to ref the connection here.
1639  * However, it may be disconnected if the Disconnected
1640  * message hasn't been processed yet, in which case we
1641  * want to pretend it isn't in the hash and avoid
1642  * returning it.
1643  *
1644  * The idea is to avoid ever returning a disconnected connection
1645  * from dbus_connection_open(). We could just synchronously
1646  * drop our shared ref to the connection on connection disconnect,
1647  * and then assert here that the connection is connected, but
1648  * that causes reentrancy headaches.
1649  */
1650  CONNECTION_LOCK (connection);
1651  if (_dbus_connection_get_is_connected_unlocked (connection))
1652  {
1653  _dbus_connection_ref_unlocked (connection);
1654  *result = connection;
1655  _dbus_verbose ("looked up existing connection to server guid %s\n",
1656  guid);
1657  }
1658  else
1659  {
1660  _dbus_verbose ("looked up existing connection to server guid %s but it was disconnected so ignoring it\n",
1661  guid);
1662  }
1663  CONNECTION_UNLOCK (connection);
1664  }
1665  }
1666 
1667  _DBUS_UNLOCK (shared_connections);
1668  return TRUE;
1669  }
1670 }
1671 
1672 static dbus_bool_t
1673 connection_record_shared_unlocked (DBusConnection *connection,
1674  const char *guid)
1675 {
1676  char *guid_key;
1677  char *guid_in_connection;
1678 
1679  HAVE_LOCK_CHECK (connection);
1680  _dbus_assert (connection->server_guid == NULL);
1681  _dbus_assert (connection->shareable);
1682 
1683  /* get a hard ref on this connection, even if
1684  * we won't in fact store it in the hash, we still
1685  * need to hold a ref on it until it's disconnected.
1686  */
1687  _dbus_connection_ref_unlocked (connection);
1688 
1689  if (guid == NULL)
1690  {
1691  _DBUS_LOCK (shared_connections);
1692 
1693  if (!_dbus_list_prepend (&shared_connections_no_guid, connection))
1694  {
1695  _DBUS_UNLOCK (shared_connections);
1696  return FALSE;
1697  }
1698 
1699  _DBUS_UNLOCK (shared_connections);
1700  return TRUE; /* don't store in the hash */
1701  }
1702 
1703  /* A separate copy of the key is required in the hash table, because
1704  * we don't have a lock on the connection when we are doing a hash
1705  * lookup.
1706  */
1707 
1708  guid_key = _dbus_strdup (guid);
1709  if (guid_key == NULL)
1710  return FALSE;
1711 
1712  guid_in_connection = _dbus_strdup (guid);
1713  if (guid_in_connection == NULL)
1714  {
1715  dbus_free (guid_key);
1716  return FALSE;
1717  }
1718 
1719  _DBUS_LOCK (shared_connections);
1720  _dbus_assert (shared_connections != NULL);
1721 
1722  if (!_dbus_hash_table_insert_string (shared_connections,
1723  guid_key, connection))
1724  {
1725  dbus_free (guid_key);
1726  dbus_free (guid_in_connection);
1727  _DBUS_UNLOCK (shared_connections);
1728  return FALSE;
1729  }
1730 
1731  connection->server_guid = guid_in_connection;
1732 
1733  _dbus_verbose ("stored connection to %s to be shared\n",
1734  connection->server_guid);
1735 
1736  _DBUS_UNLOCK (shared_connections);
1737 
1738  _dbus_assert (connection->server_guid != NULL);
1739 
1740  return TRUE;
1741 }
1742 
1743 static void
1744 connection_forget_shared_unlocked (DBusConnection *connection)
1745 {
1746  HAVE_LOCK_CHECK (connection);
1747 
1748  if (!connection->shareable)
1749  return;
1750 
1751  _DBUS_LOCK (shared_connections);
1752 
1753  if (connection->server_guid != NULL)
1754  {
1755  _dbus_verbose ("dropping connection to %s out of the shared table\n",
1756  connection->server_guid);
1757 
1758  if (!_dbus_hash_table_remove_string (shared_connections,
1759  connection->server_guid))
1760  _dbus_assert_not_reached ("connection was not in the shared table");
1761 
1762  dbus_free (connection->server_guid);
1763  connection->server_guid = NULL;
1764  }
1765  else
1766  {
1767  _dbus_list_remove (&shared_connections_no_guid, connection);
1768  }
1769 
1770  _DBUS_UNLOCK (shared_connections);
1771 
1772  /* remove our reference held on all shareable connections */
1773  _dbus_connection_unref_unlocked (connection);
1774 }
1775 
1776 static DBusConnection*
1777 connection_try_from_address_entry (DBusAddressEntry *entry,
1778  DBusError *error)
1779 {
1780  DBusTransport *transport;
1781  DBusConnection *connection;
1782 
1783  transport = _dbus_transport_open (entry, error);
1784 
1785  if (transport == NULL)
1786  {
1787  _DBUS_ASSERT_ERROR_IS_SET (error);
1788  return NULL;
1789  }
1790 
1791  connection = _dbus_connection_new_for_transport (transport);
1792 
1793  _dbus_transport_unref (transport);
1794 
1795  if (connection == NULL)
1796  {
1797  _DBUS_SET_OOM (error);
1798  return NULL;
1799  }
1800 
1801 #ifndef DBUS_DISABLE_CHECKS
1802  _dbus_assert (!connection->have_connection_lock);
1803 #endif
1804  return connection;
1805 }
1806 
1807 /*
1808  * If the shared parameter is true, then any existing connection will
1809  * be used (and if a new connection is created, it will be available
1810  * for use by others). If the shared parameter is false, a new
1811  * connection will always be created, and the new connection will
1812  * never be returned to other callers.
1813  *
1814  * @param address the address
1815  * @param shared whether the connection is shared or private
1816  * @param error error return
1817  * @returns the connection or #NULL on error
1818  */
1819 static DBusConnection*
1820 _dbus_connection_open_internal (const char *address,
1821  dbus_bool_t shared,
1822  DBusError *error)
1823 {
1824  DBusConnection *connection;
1825  DBusAddressEntry **entries;
1826  DBusError tmp_error = DBUS_ERROR_INIT;
1827  DBusError first_error = DBUS_ERROR_INIT;
1828  int len, i;
1829 
1830  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1831 
1832  _dbus_verbose ("opening %s connection to: %s\n",
1833  shared ? "shared" : "private", address);
1834 
1835  if (!dbus_parse_address (address, &entries, &len, error))
1836  return NULL;
1837 
1838  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1839 
1840  connection = NULL;
1841 
1842  for (i = 0; i < len; i++)
1843  {
1844  if (shared)
1845  {
1846  if (!connection_lookup_shared (entries[i], &connection))
1847  _DBUS_SET_OOM (&tmp_error);
1848  }
1849 
1850  if (connection == NULL)
1851  {
1852  connection = connection_try_from_address_entry (entries[i],
1853  &tmp_error);
1854 
1855  if (connection != NULL && shared)
1856  {
1857  const char *guid;
1858 
1859  connection->shareable = TRUE;
1860 
1861  /* guid may be NULL */
1862  guid = dbus_address_entry_get_value (entries[i], "guid");
1863 
1864  CONNECTION_LOCK (connection);
1865 
1866  if (!connection_record_shared_unlocked (connection, guid))
1867  {
1868  _DBUS_SET_OOM (&tmp_error);
1869  _dbus_connection_close_possibly_shared_and_unlock (connection);
1870  dbus_connection_unref (connection);
1871  connection = NULL;
1872  }
1873  else
1874  CONNECTION_UNLOCK (connection);
1875  }
1876  }
1877 
1878  if (connection)
1879  break;
1880 
1881  _DBUS_ASSERT_ERROR_IS_SET (&tmp_error);
1882 
1883  if (i == 0)
1884  dbus_move_error (&tmp_error, &first_error);
1885  else
1886  dbus_error_free (&tmp_error);
1887  }
1888 
1889  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1890  _DBUS_ASSERT_ERROR_IS_CLEAR (&tmp_error);
1891 
1892  if (connection == NULL)
1893  {
1894  _DBUS_ASSERT_ERROR_IS_SET (&first_error);
1895  dbus_move_error (&first_error, error);
1896  }
1897  else
1898  dbus_error_free (&first_error);
1899 
1900  dbus_address_entries_free (entries);
1901  return connection;
1902 }
1903 
1912 void
1914 {
1915  _dbus_assert (connection != NULL);
1917 
1918  CONNECTION_LOCK (connection);
1919  _dbus_connection_close_possibly_shared_and_unlock (connection);
1920 }
1921 
1922 static DBusPreallocatedSend*
1923 _dbus_connection_preallocate_send_unlocked (DBusConnection *connection)
1924 {
1925  DBusPreallocatedSend *preallocated;
1926 
1927  HAVE_LOCK_CHECK (connection);
1928 
1929  _dbus_assert (connection != NULL);
1930 
1931  preallocated = dbus_new (DBusPreallocatedSend, 1);
1932  if (preallocated == NULL)
1933  return NULL;
1934 
1935  if (connection->link_cache != NULL)
1936  {
1937  preallocated->queue_link =
1938  _dbus_list_pop_first_link (&connection->link_cache);
1939  preallocated->queue_link->data = NULL;
1940  }
1941  else
1942  {
1943  preallocated->queue_link = _dbus_list_alloc_link (NULL);
1944  if (preallocated->queue_link == NULL)
1945  goto failed_0;
1946  }
1947 
1948  if (connection->link_cache != NULL)
1949  {
1950  preallocated->counter_link =
1951  _dbus_list_pop_first_link (&connection->link_cache);
1952  preallocated->counter_link->data = connection->outgoing_counter;
1953  }
1954  else
1955  {
1956  preallocated->counter_link = _dbus_list_alloc_link (connection->outgoing_counter);
1957  if (preallocated->counter_link == NULL)
1958  goto failed_1;
1959  }
1960 
1961  _dbus_counter_ref (preallocated->counter_link->data);
1962 
1963  preallocated->connection = connection;
1964 
1965  return preallocated;
1966 
1967  failed_1:
1968  _dbus_list_free_link (preallocated->queue_link);
1969  failed_0:
1970  dbus_free (preallocated);
1971 
1972  return NULL;
1973 }
1974 
1975 /* Called with lock held, does not update dispatch status */
1976 static void
1977 _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection *connection,
1978  DBusPreallocatedSend *preallocated,
1979  DBusMessage *message,
1980  dbus_uint32_t *client_serial)
1981 {
1982  dbus_uint32_t serial;
1983 
1984  preallocated->queue_link->data = message;
1986  preallocated->queue_link);
1987 
1989  preallocated->counter_link);
1990 
1991  dbus_free (preallocated);
1992  preallocated = NULL;
1993 
1994  dbus_message_ref (message);
1995 
1996  connection->n_outgoing += 1;
1997 
1998  _dbus_verbose ("Message %p (%s %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
1999  message,
2001  dbus_message_get_path (message) ?
2002  dbus_message_get_path (message) :
2003  "no path",
2004  dbus_message_get_interface (message) ?
2005  dbus_message_get_interface (message) :
2006  "no interface",
2007  dbus_message_get_member (message) ?
2008  dbus_message_get_member (message) :
2009  "no member",
2010  dbus_message_get_signature (message),
2011  dbus_message_get_destination (message) ?
2012  dbus_message_get_destination (message) :
2013  "null",
2014  connection,
2015  connection->n_outgoing);
2016 
2017  if (dbus_message_get_serial (message) == 0)
2018  {
2019  serial = _dbus_connection_get_next_client_serial (connection);
2020  dbus_message_set_serial (message, serial);
2021  if (client_serial)
2022  *client_serial = serial;
2023  }
2024  else
2025  {
2026  if (client_serial)
2027  *client_serial = dbus_message_get_serial (message);
2028  }
2029 
2030  _dbus_verbose ("Message %p serial is %u\n",
2031  message, dbus_message_get_serial (message));
2032 
2033  dbus_message_lock (message);
2034 
2035  /* Now we need to run an iteration to hopefully just write the messages
2036  * out immediately, and otherwise get them queued up
2037  */
2039  NULL,
2040  DBUS_ITERATION_DO_WRITING,
2041  -1);
2042 
2043  /* If stuff is still queued up, be sure we wake up the main loop */
2044  if (connection->n_outgoing > 0)
2045  _dbus_connection_wakeup_mainloop (connection);
2046 }
2047 
2048 static void
2049 _dbus_connection_send_preallocated_and_unlock (DBusConnection *connection,
2050  DBusPreallocatedSend *preallocated,
2051  DBusMessage *message,
2052  dbus_uint32_t *client_serial)
2053 {
2054  DBusDispatchStatus status;
2055 
2056  HAVE_LOCK_CHECK (connection);
2057 
2058  _dbus_connection_send_preallocated_unlocked_no_update (connection,
2059  preallocated,
2060  message, client_serial);
2061 
2062  _dbus_verbose ("middle\n");
2063  status = _dbus_connection_get_dispatch_status_unlocked (connection);
2064 
2065  /* this calls out to user code */
2066  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2067 }
2068 
2080  DBusMessage *message,
2081  dbus_uint32_t *client_serial)
2082 {
2083  DBusPreallocatedSend *preallocated;
2084 
2085  _dbus_assert (connection != NULL);
2086  _dbus_assert (message != NULL);
2087 
2088  preallocated = _dbus_connection_preallocate_send_unlocked (connection);
2089  if (preallocated == NULL)
2090  {
2091  CONNECTION_UNLOCK (connection);
2092  return FALSE;
2093  }
2094 
2095  _dbus_connection_send_preallocated_and_unlock (connection,
2096  preallocated,
2097  message,
2098  client_serial);
2099  return TRUE;
2100 }
2101 
2126 void
2128 {
2129  CONNECTION_LOCK (connection);
2130 
2131  _dbus_assert (connection->refcount.value > 0);
2132 
2133  if (connection->refcount.value == 1)
2134  _dbus_connection_close_possibly_shared_and_unlock (connection);
2135  else
2136  CONNECTION_UNLOCK (connection);
2137 }
2138 
2139 
2149 static void
2150 _dbus_memory_pause_based_on_timeout (int timeout_milliseconds)
2151 {
2152  if (timeout_milliseconds == -1)
2153  _dbus_sleep_milliseconds (1000);
2154  else if (timeout_milliseconds < 100)
2155  ; /* just busy loop */
2156  else if (timeout_milliseconds <= 1000)
2157  _dbus_sleep_milliseconds (timeout_milliseconds / 3);
2158  else
2159  _dbus_sleep_milliseconds (1000);
2160 }
2161 
2162 static DBusMessage *
2163 generate_local_error_message (dbus_uint32_t serial,
2164  char *error_name,
2165  char *error_msg)
2166 {
2167  DBusMessage *message;
2169  if (!message)
2170  goto out;
2171 
2172  if (!dbus_message_set_error_name (message, error_name))
2173  {
2174  dbus_message_unref (message);
2175  message = NULL;
2176  goto out;
2177  }
2178 
2179  dbus_message_set_no_reply (message, TRUE);
2180 
2181  if (!dbus_message_set_reply_serial (message,
2182  serial))
2183  {
2184  dbus_message_unref (message);
2185  message = NULL;
2186  goto out;
2187  }
2188 
2189  if (error_msg != NULL)
2190  {
2191  DBusMessageIter iter;
2192 
2193  dbus_message_iter_init_append (message, &iter);
2194  if (!dbus_message_iter_append_basic (&iter,
2196  &error_msg))
2197  {
2198  dbus_message_unref (message);
2199  message = NULL;
2200  goto out;
2201  }
2202  }
2203 
2204  out:
2205  return message;
2206 }
2207 
2208 /*
2209  * Peek the incoming queue to see if we got reply for a specific serial
2210  */
2211 static dbus_bool_t
2212 _dbus_connection_peek_for_reply_unlocked (DBusConnection *connection,
2213  dbus_uint32_t client_serial)
2214 {
2215  DBusList *link;
2216  HAVE_LOCK_CHECK (connection);
2217 
2218  link = _dbus_list_get_first_link (&connection->incoming_messages);
2219 
2220  while (link != NULL)
2221  {
2222  DBusMessage *reply = link->data;
2223 
2224  if (dbus_message_get_reply_serial (reply) == client_serial)
2225  {
2226  _dbus_verbose ("%s reply to %d found in queue\n", _DBUS_FUNCTION_NAME, client_serial);
2227  return TRUE;
2228  }
2229  link = _dbus_list_get_next_link (&connection->incoming_messages, link);
2230  }
2231 
2232  return FALSE;
2233 }
2234 
2235 /* This is slightly strange since we can pop a message here without
2236  * the dispatch lock.
2237  */
2238 static DBusMessage*
2239 check_for_reply_unlocked (DBusConnection *connection,
2240  dbus_uint32_t client_serial)
2241 {
2242  DBusList *link;
2243 
2244  HAVE_LOCK_CHECK (connection);
2245 
2246  link = _dbus_list_get_first_link (&connection->incoming_messages);
2247 
2248  while (link != NULL)
2249  {
2250  DBusMessage *reply = link->data;
2251 
2252  if (dbus_message_get_reply_serial (reply) == client_serial)
2253  {
2254  _dbus_list_remove_link (&connection->incoming_messages, link);
2255  connection->n_incoming -= 1;
2256  return reply;
2257  }
2258  link = _dbus_list_get_next_link (&connection->incoming_messages, link);
2259  }
2260 
2261  return NULL;
2262 }
2263 
2264 static void
2265 connection_timeout_and_complete_all_pending_calls_unlocked (DBusConnection *connection)
2266 {
2267  /* We can't iterate over the hash in the normal way since we'll be
2268  * dropping the lock for each item. So we restart the
2269  * iter each time as we drain the hash table.
2270  */
2271 
2272  while (_dbus_hash_table_get_n_entries (connection->pending_replies) > 0)
2273  {
2274  DBusPendingCall *pending;
2275  DBusHashIter iter;
2276 
2277  _dbus_hash_iter_init (connection->pending_replies, &iter);
2278  _dbus_hash_iter_next (&iter);
2279 
2280  pending = _dbus_hash_iter_get_value (&iter);
2282 
2284  connection);
2285 
2291 
2293  CONNECTION_LOCK (connection);
2294  }
2295  HAVE_LOCK_CHECK (connection);
2296 }
2297 
2298 static void
2299 complete_pending_call_and_unlock (DBusConnection *connection,
2300  DBusPendingCall *pending,
2301  DBusMessage *message)
2302 {
2303  _dbus_pending_call_set_reply_unlocked (pending, message);
2304  _dbus_pending_call_ref_unlocked (pending); /* in case there's no app with a ref held */
2305  _dbus_connection_detach_pending_call_and_unlock (connection, pending);
2306 
2307  /* Must be called unlocked since it invokes app callback */
2308  _dbus_pending_call_complete (pending);
2309  dbus_pending_call_unref (pending);
2310 }
2311 
2312 static dbus_bool_t
2313 check_for_reply_and_update_dispatch_unlocked (DBusConnection *connection,
2314  DBusPendingCall *pending)
2315 {
2316  DBusMessage *reply;
2317  DBusDispatchStatus status;
2318 
2319  reply = check_for_reply_unlocked (connection,
2321  if (reply != NULL)
2322  {
2323  _dbus_verbose ("checked for reply\n");
2324 
2325  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): got reply\n");
2326 
2327  complete_pending_call_and_unlock (connection, pending, reply);
2328  dbus_message_unref (reply);
2329 
2330  CONNECTION_LOCK (connection);
2331  status = _dbus_connection_get_dispatch_status_unlocked (connection);
2332  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2333  dbus_pending_call_unref (pending);
2334 
2335  return TRUE;
2336  }
2337 
2338  return FALSE;
2339 }
2340 
2355 void
2357 {
2358  long start_tv_sec, start_tv_usec;
2359  long tv_sec, tv_usec;
2360  DBusDispatchStatus status;
2361  DBusConnection *connection;
2362  dbus_uint32_t client_serial;
2363  DBusTimeout *timeout;
2364  int timeout_milliseconds, elapsed_milliseconds;
2365 
2366  _dbus_assert (pending != NULL);
2367 
2368  if (dbus_pending_call_get_completed (pending))
2369  return;
2370 
2371  dbus_pending_call_ref (pending); /* necessary because the call could be canceled */
2372 
2373  connection = _dbus_pending_call_get_connection_and_lock (pending);
2374 
2375  /* Flush message queue - note, can affect dispatch status */
2376  _dbus_connection_flush_unlocked (connection);
2377 
2378  client_serial = _dbus_pending_call_get_reply_serial_unlocked (pending);
2379 
2380  /* note that timeout_milliseconds is limited to a smallish value
2381  * in _dbus_pending_call_new() so overflows aren't possible
2382  * below
2383  */
2384  timeout = _dbus_pending_call_get_timeout_unlocked (pending);
2385  _dbus_get_current_time (&start_tv_sec, &start_tv_usec);
2386  if (timeout)
2387  {
2388  timeout_milliseconds = dbus_timeout_get_interval (timeout);
2389 
2390  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec\n",
2391  timeout_milliseconds,
2392  client_serial,
2393  start_tv_sec, start_tv_usec);
2394  }
2395  else
2396  {
2397  timeout_milliseconds = -1;
2398 
2399  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block for reply serial %u\n", client_serial);
2400  }
2401 
2402  /* check to see if we already got the data off the socket */
2403  /* from another blocked pending call */
2404  if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
2405  return;
2406 
2407  /* Now we wait... */
2408  /* always block at least once as we know we don't have the reply yet */
2410  pending,
2411  DBUS_ITERATION_DO_READING |
2412  DBUS_ITERATION_BLOCK,
2413  timeout_milliseconds);
2414 
2415  recheck_status:
2416 
2417  _dbus_verbose ("top of recheck\n");
2418 
2419  HAVE_LOCK_CHECK (connection);
2420 
2421  /* queue messages and get status */
2422 
2423  status = _dbus_connection_get_dispatch_status_unlocked (connection);
2424 
2425  /* the get_completed() is in case a dispatch() while we were blocking
2426  * got the reply instead of us.
2427  */
2429  {
2430  _dbus_verbose ("Pending call completed by dispatch\n");
2431  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2432  dbus_pending_call_unref (pending);
2433  return;
2434  }
2435 
2436  if (status == DBUS_DISPATCH_DATA_REMAINS)
2437  {
2438  if (check_for_reply_and_update_dispatch_unlocked (connection, pending))
2439  return;
2440  }
2441 
2442  _dbus_get_current_time (&tv_sec, &tv_usec);
2443  elapsed_milliseconds = (tv_sec - start_tv_sec) * 1000 +
2444  (tv_usec - start_tv_usec) / 1000;
2445 
2446  if (!_dbus_connection_get_is_connected_unlocked (connection))
2447  {
2448  DBusMessage *error_msg;
2449 
2450  error_msg = generate_local_error_message (client_serial,
2452  "Connection was disconnected before a reply was received");
2453 
2454  /* on OOM error_msg is set to NULL */
2455  complete_pending_call_and_unlock (connection, pending, error_msg);
2456  dbus_pending_call_unref (pending);
2457  return;
2458  }
2459  else if (connection->disconnect_message_link == NULL)
2460  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): disconnected\n");
2461  else if (timeout == NULL)
2462  {
2463  if (status == DBUS_DISPATCH_NEED_MEMORY)
2464  {
2465  /* Try sleeping a bit, as we aren't sure we need to block for reading,
2466  * we may already have a reply in the buffer and just can't process
2467  * it.
2468  */
2469  _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
2470 
2471  _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
2472  }
2473  else
2474  {
2475  /* block again, we don't have the reply buffered yet. */
2477  pending,
2478  DBUS_ITERATION_DO_READING |
2479  DBUS_ITERATION_BLOCK,
2480  timeout_milliseconds - elapsed_milliseconds);
2481  }
2482 
2483  goto recheck_status;
2484  }
2485  else if (tv_sec < start_tv_sec)
2486  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
2487  else if (elapsed_milliseconds < timeout_milliseconds)
2488  {
2489  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds - elapsed_milliseconds);
2490 
2491  if (status == DBUS_DISPATCH_NEED_MEMORY)
2492  {
2493  /* Try sleeping a bit, as we aren't sure we need to block for reading,
2494  * we may already have a reply in the buffer and just can't process
2495  * it.
2496  */
2497  _dbus_verbose ("dbus_connection_send_with_reply_and_block() waiting for more memory\n");
2498 
2499  _dbus_memory_pause_based_on_timeout (timeout_milliseconds - elapsed_milliseconds);
2500  }
2501  else
2502  {
2503  /* block again, we don't have the reply buffered yet. */
2505  NULL,
2506  DBUS_ITERATION_DO_READING |
2507  DBUS_ITERATION_BLOCK,
2508  timeout_milliseconds - elapsed_milliseconds);
2509  }
2510 
2511  goto recheck_status;
2512  }
2513 
2514  _dbus_verbose ("dbus_connection_send_with_reply_and_block(): Waited %d milliseconds and got no reply\n",
2515  elapsed_milliseconds);
2516 
2518 
2519  /* unlock and call user code */
2520  complete_pending_call_and_unlock (connection, pending, NULL);
2521 
2522  /* update user code on dispatch status */
2523  CONNECTION_LOCK (connection);
2524  status = _dbus_connection_get_dispatch_status_unlocked (connection);
2525  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2526  dbus_pending_call_unref (pending);
2527 }
2528 
2566 dbus_connection_open (const char *address,
2567  DBusError *error)
2568 {
2569  DBusConnection *connection;
2570 
2571  _dbus_return_val_if_fail (address != NULL, NULL);
2572  _dbus_return_val_if_error_is_set (error, NULL);
2573 
2574  connection = _dbus_connection_open_internal (address,
2575  TRUE,
2576  error);
2577 
2578  return connection;
2579 }
2580 
2609 dbus_connection_open_private (const char *address,
2610  DBusError *error)
2611 {
2612  DBusConnection *connection;
2613 
2614  _dbus_return_val_if_fail (address != NULL, NULL);
2615  _dbus_return_val_if_error_is_set (error, NULL);
2616 
2617  connection = _dbus_connection_open_internal (address,
2618  FALSE,
2619  error);
2620 
2621  return connection;
2622 }
2623 
2632 {
2633  _dbus_return_val_if_fail (connection != NULL, NULL);
2634  _dbus_return_val_if_fail (connection->generation == _dbus_current_generation, NULL);
2635 
2636  /* The connection lock is better than the global
2637  * lock in the atomic increment fallback
2638  *
2639  * (FIXME but for now we always use the atomic version,
2640  * to avoid taking the connection lock, due to
2641  * the mess with set_timeout_functions()/set_watch_functions()
2642  * calling out to the app without dropping locks)
2643  */
2644 
2645 #if 1
2646  _dbus_atomic_inc (&connection->refcount);
2647 #else
2648  CONNECTION_LOCK (connection);
2649  _dbus_assert (connection->refcount.value > 0);
2650 
2651  connection->refcount.value += 1;
2652  CONNECTION_UNLOCK (connection);
2653 #endif
2654 
2655  return connection;
2656 }
2657 
2658 static void
2659 free_outgoing_message (void *element,
2660  void *data)
2661 {
2662  DBusMessage *message = element;
2663  DBusConnection *connection = data;
2664 
2666  connection->outgoing_counter,
2667  NULL);
2668  dbus_message_unref (message);
2669 }
2670 
2671 /* This is run without the mutex held, but after the last reference
2672  * to the connection has been dropped we should have no thread-related
2673  * problems
2674  */
2675 static void
2676 _dbus_connection_last_unref (DBusConnection *connection)
2677 {
2678  DBusList *link;
2679 
2680  _dbus_verbose ("Finalizing connection %p\n", connection);
2681 
2682  _dbus_assert (connection->refcount.value == 0);
2683 
2684  /* You have to disconnect the connection before unref:ing it. Otherwise
2685  * you won't get the disconnected message.
2686  */
2688  _dbus_assert (connection->server_guid == NULL);
2689 
2690  /* ---- We're going to call various application callbacks here, hope it doesn't break anything... */
2692 
2696 
2697  _dbus_watch_list_free (connection->watches);
2698  connection->watches = NULL;
2699 
2700  _dbus_timeout_list_free (connection->timeouts);
2701  connection->timeouts = NULL;
2702 
2703  _dbus_data_slot_list_free (&connection->slot_list);
2704 
2705  link = _dbus_list_get_first_link (&connection->filter_list);
2706  while (link != NULL)
2707  {
2708  DBusMessageFilter *filter = link->data;
2709  DBusList *next = _dbus_list_get_next_link (&connection->filter_list, link);
2710 
2711  filter->function = NULL;
2712  _dbus_message_filter_unref (filter); /* calls app callback */
2713  link->data = NULL;
2714 
2715  link = next;
2716  }
2717  _dbus_list_clear (&connection->filter_list);
2718 
2719  /* ---- Done with stuff that invokes application callbacks */
2720 
2721  _dbus_object_tree_unref (connection->objects);
2722 
2724  connection->pending_replies = NULL;
2725 
2726  _dbus_list_clear (&connection->filter_list);
2727 
2728  _dbus_list_foreach (&connection->outgoing_messages,
2729  free_outgoing_message,
2730  connection);
2731  _dbus_list_clear (&connection->outgoing_messages);
2732 
2733  _dbus_list_foreach (&connection->incoming_messages,
2735  NULL);
2736  _dbus_list_clear (&connection->incoming_messages);
2737 
2738  _dbus_counter_unref (connection->outgoing_counter);
2739 
2740  _dbus_transport_unref (connection->transport);
2741 
2742  if (connection->disconnect_message_link)
2743  {
2744  DBusMessage *message = connection->disconnect_message_link->data;
2745  dbus_message_unref (message);
2747  }
2748 
2749  _dbus_list_clear (&connection->link_cache);
2750 
2753 
2756 
2758 
2759  _dbus_mutex_free_at_location (&connection->mutex);
2760 
2761  dbus_free (connection);
2762 }
2763 
2783 void
2785 {
2786  dbus_bool_t last_unref;
2787 
2788  _dbus_return_if_fail (connection != NULL);
2789  _dbus_return_if_fail (connection->generation == _dbus_current_generation);
2790 
2791  /* The connection lock is better than the global
2792  * lock in the atomic increment fallback
2793  *
2794  * (FIXME but for now we always use the atomic version,
2795  * to avoid taking the connection lock, due to
2796  * the mess with set_timeout_functions()/set_watch_functions()
2797  * calling out to the app without dropping locks)
2798  */
2799 
2800 #if 1
2801  last_unref = (_dbus_atomic_dec (&connection->refcount) == 1);
2802 #else
2803  CONNECTION_LOCK (connection);
2804 
2805  _dbus_assert (connection->refcount.value > 0);
2806 
2807  connection->refcount.value -= 1;
2808  last_unref = (connection->refcount.value == 0);
2809 
2810 #if 0
2811  printf ("unref() connection %p count = %d\n", connection, connection->refcount.value);
2812 #endif
2813 
2814  CONNECTION_UNLOCK (connection);
2815 #endif
2816 
2817  if (last_unref)
2818  {
2819 #ifndef DBUS_DISABLE_CHECKS
2820  if (_dbus_transport_get_is_connected (connection->transport))
2821  {
2822  _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",
2823  connection->shareable ?
2824  "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" :
2825  "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n");
2826  return;
2827  }
2828 #endif
2829  _dbus_connection_last_unref (connection);
2830  }
2831 }
2832 
2833 /*
2834  * Note that the transport can disconnect itself (other end drops us)
2835  * and in that case this function never runs. So this function must
2836  * not do anything more than disconnect the transport and update the
2837  * dispatch status.
2838  *
2839  * If the transport self-disconnects, then we assume someone will
2840  * dispatch the connection to cause the dispatch status update.
2841  */
2842 static void
2843 _dbus_connection_close_possibly_shared_and_unlock (DBusConnection *connection)
2844 {
2845  DBusDispatchStatus status;
2846 
2847  HAVE_LOCK_CHECK (connection);
2848 
2849  _dbus_verbose ("Disconnecting %p\n", connection);
2850 
2851  /* We need to ref because update_dispatch_status_and_unlock will unref
2852  * the connection if it was shared and libdbus was the only remaining
2853  * refcount holder.
2854  */
2855  _dbus_connection_ref_unlocked (connection);
2856 
2857  _dbus_transport_disconnect (connection->transport);
2858 
2859  /* This has the side effect of queuing the disconnect message link
2860  * (unless we don't have enough memory, possibly, so don't assert it).
2861  * After the disconnect message link is queued, dbus_bus_get/dbus_connection_open
2862  * should never again return the newly-disconnected connection.
2863  *
2864  * However, we only unref the shared connection and exit_on_disconnect when
2865  * the disconnect message reaches the head of the message queue,
2866  * NOT when it's first queued.
2867  */
2868  status = _dbus_connection_get_dispatch_status_unlocked (connection);
2869 
2870  /* This calls out to user code */
2871  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
2872 
2873  /* Could also call out to user code */
2874  dbus_connection_unref (connection);
2875 }
2876 
2919 void
2921 {
2922  _dbus_return_if_fail (connection != NULL);
2923  _dbus_return_if_fail (connection->generation == _dbus_current_generation);
2924 
2925  CONNECTION_LOCK (connection);
2926 
2927 #ifndef DBUS_DISABLE_CHECKS
2928  if (connection->shareable)
2929  {
2930  CONNECTION_UNLOCK (connection);
2931 
2932  _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n");
2933  return;
2934  }
2935 #endif
2936 
2937  _dbus_connection_close_possibly_shared_and_unlock (connection);
2938 }
2939 
2940 static dbus_bool_t
2941 _dbus_connection_get_is_connected_unlocked (DBusConnection *connection)
2942 {
2943  HAVE_LOCK_CHECK (connection);
2944  return _dbus_transport_get_is_connected (connection->transport);
2945 }
2946 
2962 {
2963  dbus_bool_t res;
2964 
2965  _dbus_return_val_if_fail (connection != NULL, FALSE);
2966 
2967  CONNECTION_LOCK (connection);
2968  res = _dbus_connection_get_is_connected_unlocked (connection);
2969  CONNECTION_UNLOCK (connection);
2970 
2971  return res;
2972 }
2973 
2984 {
2985  dbus_bool_t res;
2986 
2987  _dbus_return_val_if_fail (connection != NULL, FALSE);
2988 
2989  CONNECTION_LOCK (connection);
2990  res = _dbus_transport_get_is_authenticated (connection->transport);
2991  CONNECTION_UNLOCK (connection);
2992 
2993  return res;
2994 }
2995 
3018 {
3019  dbus_bool_t res;
3020 
3021  _dbus_return_val_if_fail (connection != NULL, FALSE);
3022 
3023  CONNECTION_LOCK (connection);
3024  res = _dbus_transport_get_is_anonymous (connection->transport);
3025  CONNECTION_UNLOCK (connection);
3026 
3027  return res;
3028 }
3029 
3061 char*
3063 {
3064  char *id;
3065 
3066  _dbus_return_val_if_fail (connection != NULL, NULL);
3067 
3068  CONNECTION_LOCK (connection);
3070  CONNECTION_UNLOCK (connection);
3071 
3072  return id;
3073 }
3074 
3094  int type)
3095 {
3096  _dbus_return_val_if_fail (connection != NULL, FALSE);
3097 
3098  if (!_dbus_type_is_valid(type))
3099  return FALSE;
3100 
3101  if (type != DBUS_TYPE_UNIX_FD)
3102  return TRUE;
3103 
3104 #ifdef HAVE_UNIX_FD_PASSING
3105  {
3106  dbus_bool_t b;
3107 
3108  CONNECTION_LOCK(connection);
3110  CONNECTION_UNLOCK(connection);
3111 
3112  return b;
3113  }
3114 #endif
3115 
3116  return FALSE;
3117 }
3118 
3132 void
3134  dbus_bool_t exit_on_disconnect)
3135 {
3136  _dbus_return_if_fail (connection != NULL);
3137 
3138  CONNECTION_LOCK (connection);
3139  connection->exit_on_disconnect = exit_on_disconnect != FALSE;
3140  CONNECTION_UNLOCK (connection);
3141 }
3142 
3154 {
3155  DBusPreallocatedSend *preallocated;
3156 
3157  _dbus_return_val_if_fail (connection != NULL, NULL);
3158 
3159  CONNECTION_LOCK (connection);
3160 
3161  preallocated =
3162  _dbus_connection_preallocate_send_unlocked (connection);
3163 
3164  CONNECTION_UNLOCK (connection);
3165 
3166  return preallocated;
3167 }
3168 
3178 void
3180  DBusPreallocatedSend *preallocated)
3181 {
3182  _dbus_return_if_fail (connection != NULL);
3183  _dbus_return_if_fail (preallocated != NULL);
3184  _dbus_return_if_fail (connection == preallocated->connection);
3185 
3186  _dbus_list_free_link (preallocated->queue_link);
3187  _dbus_counter_unref (preallocated->counter_link->data);
3188  _dbus_list_free_link (preallocated->counter_link);
3189  dbus_free (preallocated);
3190 }
3191 
3204 void
3206  DBusPreallocatedSend *preallocated,
3207  DBusMessage *message,
3208  dbus_uint32_t *client_serial)
3209 {
3210  _dbus_return_if_fail (connection != NULL);
3211  _dbus_return_if_fail (preallocated != NULL);
3212  _dbus_return_if_fail (message != NULL);
3213  _dbus_return_if_fail (preallocated->connection == connection);
3214  _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL ||
3215  dbus_message_get_member (message) != NULL);
3216  _dbus_return_if_fail (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_SIGNAL ||
3217  (dbus_message_get_interface (message) != NULL &&
3218  dbus_message_get_member (message) != NULL));
3219 
3220  CONNECTION_LOCK (connection);
3221 
3222 #ifdef HAVE_UNIX_FD_PASSING
3223 
3224  if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
3225  message->n_unix_fds > 0)
3226  {
3227  /* Refuse to send fds on a connection that cannot handle
3228  them. Unfortunately we cannot return a proper error here, so
3229  the best we can is just return. */
3230  CONNECTION_UNLOCK (connection);
3231  return;
3232  }
3233 
3234 #endif
3235 
3236  _dbus_connection_send_preallocated_and_unlock (connection,
3237  preallocated,
3238  message, client_serial);
3239 }
3240 
3241 static dbus_bool_t
3242 _dbus_connection_send_unlocked_no_update (DBusConnection *connection,
3243  DBusMessage *message,
3244  dbus_uint32_t *client_serial)
3245 {
3246  DBusPreallocatedSend *preallocated;
3247 
3248  _dbus_assert (connection != NULL);
3249  _dbus_assert (message != NULL);
3250 
3251  preallocated = _dbus_connection_preallocate_send_unlocked (connection);
3252  if (preallocated == NULL)
3253  return FALSE;
3254 
3255  _dbus_connection_send_preallocated_unlocked_no_update (connection,
3256  preallocated,
3257  message,
3258  client_serial);
3259  return TRUE;
3260 }
3261 
3291  DBusMessage *message,
3292  dbus_uint32_t *serial)
3293 {
3294  _dbus_return_val_if_fail (connection != NULL, FALSE);
3295  _dbus_return_val_if_fail (message != NULL, FALSE);
3296 
3297  CONNECTION_LOCK (connection);
3298 
3299 #ifdef HAVE_UNIX_FD_PASSING
3300 
3301  if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
3302  message->n_unix_fds > 0)
3303  {
3304  /* Refuse to send fds on a connection that cannot handle
3305  them. Unfortunately we cannot return a proper error here, so
3306  the best we can is just return. */
3307  CONNECTION_UNLOCK (connection);
3308  return FALSE;
3309  }
3310 
3311 #endif
3312 
3313  return _dbus_connection_send_and_unlock (connection,
3314  message,
3315  serial);
3316 }
3317 
3318 static dbus_bool_t
3319 reply_handler_timeout (void *data)
3320 {
3321  DBusConnection *connection;
3322  DBusDispatchStatus status;
3323  DBusPendingCall *pending = data;
3324 
3325  connection = _dbus_pending_call_get_connection_and_lock (pending);
3326 
3328  connection);
3332 
3333  _dbus_verbose ("middle\n");
3334  status = _dbus_connection_get_dispatch_status_unlocked (connection);
3335 
3336  /* Unlocks, and calls out to user code */
3337  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3338 
3339  return TRUE;
3340 }
3341 
3383  DBusMessage *message,
3384  DBusPendingCall **pending_return,
3385  int timeout_milliseconds)
3386 {
3387  DBusPendingCall *pending;
3388  dbus_int32_t serial = -1;
3389  DBusDispatchStatus status;
3390 
3391  _dbus_return_val_if_fail (connection != NULL, FALSE);
3392  _dbus_return_val_if_fail (message != NULL, FALSE);
3393  _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
3394 
3395  if (pending_return)
3396  *pending_return = NULL;
3397 
3398  CONNECTION_LOCK (connection);
3399 
3400 #ifdef HAVE_UNIX_FD_PASSING
3401 
3402  if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
3403  message->n_unix_fds > 0)
3404  {
3405  /* Refuse to send fds on a connection that cannot handle
3406  them. Unfortunately we cannot return a proper error here, so
3407  the best we can do is return TRUE but leave *pending_return
3408  as NULL. */
3409  CONNECTION_UNLOCK (connection);
3410  return TRUE;
3411  }
3412 
3413 #endif
3414 
3415  if (!_dbus_connection_get_is_connected_unlocked (connection))
3416  {
3417  CONNECTION_UNLOCK (connection);
3418 
3419  return TRUE;
3420  }
3421 
3422  pending = _dbus_pending_call_new_unlocked (connection,
3423  timeout_milliseconds,
3424  reply_handler_timeout);
3425 
3426  if (pending == NULL)
3427  {
3428  CONNECTION_UNLOCK (connection);
3429  return FALSE;
3430  }
3431 
3432  /* Assign a serial to the message */
3433  serial = dbus_message_get_serial (message);
3434  if (serial == 0)
3435  {
3436  serial = _dbus_connection_get_next_client_serial (connection);
3437  dbus_message_set_serial (message, serial);
3438  }
3439 
3440  if (!_dbus_pending_call_set_timeout_error_unlocked (pending, message, serial))
3441  goto error;
3442 
3443  /* Insert the serial in the pending replies hash;
3444  * hash takes a refcount on DBusPendingCall.
3445  * Also, add the timeout.
3446  */
3447  if (!_dbus_connection_attach_pending_call_unlocked (connection,
3448  pending))
3449  goto error;
3450 
3451  if (!_dbus_connection_send_unlocked_no_update (connection, message, NULL))
3452  {
3453  _dbus_connection_detach_pending_call_and_unlock (connection,
3454  pending);
3455  goto error_unlocked;
3456  }
3457 
3458  if (pending_return)
3459  *pending_return = pending; /* hand off refcount */
3460  else
3461  {
3462  _dbus_connection_detach_pending_call_unlocked (connection, pending);
3463  /* we still have a ref to the pending call in this case, we unref
3464  * after unlocking, below
3465  */
3466  }
3467 
3468  status = _dbus_connection_get_dispatch_status_unlocked (connection);
3469 
3470  /* this calls out to user code */
3471  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3472 
3473  if (pending_return == NULL)
3474  dbus_pending_call_unref (pending);
3475 
3476  return TRUE;
3477 
3478  error:
3479  CONNECTION_UNLOCK (connection);
3480  error_unlocked:
3481  dbus_pending_call_unref (pending);
3482  return FALSE;
3483 }
3484 
3515 DBusMessage*
3517  DBusMessage *message,
3518  int timeout_milliseconds,
3519  DBusError *error)
3520 {
3521  DBusMessage *reply;
3522  DBusPendingCall *pending;
3523 
3524  _dbus_return_val_if_fail (connection != NULL, NULL);
3525  _dbus_return_val_if_fail (message != NULL, NULL);
3526  _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL);
3527  _dbus_return_val_if_error_is_set (error, NULL);
3528 
3529 #ifdef HAVE_UNIX_FD_PASSING
3530 
3531  CONNECTION_LOCK (connection);
3532  if (!_dbus_transport_can_pass_unix_fd(connection->transport) &&
3533  message->n_unix_fds > 0)
3534  {
3535  CONNECTION_UNLOCK (connection);
3536  dbus_set_error(error, DBUS_ERROR_FAILED, "Cannot send file descriptors on this connection.");
3537  return NULL;
3538  }
3539  CONNECTION_UNLOCK (connection);
3540 
3541 #endif
3542 
3543  if (!dbus_connection_send_with_reply (connection, message,
3544  &pending, timeout_milliseconds))
3545  {
3546  _DBUS_SET_OOM (error);
3547  return NULL;
3548  }
3549 
3550  if (pending == NULL)
3551  {
3552  dbus_set_error (error, DBUS_ERROR_DISCONNECTED, "Connection is closed");
3553  return NULL;
3554  }
3555 
3556  dbus_pending_call_block (pending);
3557 
3558  reply = dbus_pending_call_steal_reply (pending);
3559  dbus_pending_call_unref (pending);
3560 
3561  /* call_complete_and_unlock() called from pending_call_block() should
3562  * always fill this in.
3563  */
3564  _dbus_assert (reply != NULL);
3565 
3566  if (dbus_set_error_from_message (error, reply))
3567  {
3568  dbus_message_unref (reply);
3569  return NULL;
3570  }
3571  else
3572  return reply;
3573 }
3574 
3583 static DBusDispatchStatus
3584 _dbus_connection_flush_unlocked (DBusConnection *connection)
3585 {
3586  /* We have to specify DBUS_ITERATION_DO_READING here because
3587  * otherwise we could have two apps deadlock if they are both doing
3588  * a flush(), and the kernel buffers fill up. This could change the
3589  * dispatch status.
3590  */
3591  DBusDispatchStatus status;
3592 
3593  HAVE_LOCK_CHECK (connection);
3594 
3595  while (connection->n_outgoing > 0 &&
3596  _dbus_connection_get_is_connected_unlocked (connection))
3597  {
3598  _dbus_verbose ("doing iteration in\n");
3599  HAVE_LOCK_CHECK (connection);
3601  NULL,
3602  DBUS_ITERATION_DO_READING |
3603  DBUS_ITERATION_DO_WRITING |
3604  DBUS_ITERATION_BLOCK,
3605  -1);
3606  }
3607 
3608  HAVE_LOCK_CHECK (connection);
3609  _dbus_verbose ("middle\n");
3610  status = _dbus_connection_get_dispatch_status_unlocked (connection);
3611 
3612  HAVE_LOCK_CHECK (connection);
3613  return status;
3614 }
3615 
3621 void
3623 {
3624  /* We have to specify DBUS_ITERATION_DO_READING here because
3625  * otherwise we could have two apps deadlock if they are both doing
3626  * a flush(), and the kernel buffers fill up. This could change the
3627  * dispatch status.
3628  */
3629  DBusDispatchStatus status;
3630 
3631  _dbus_return_if_fail (connection != NULL);
3632 
3633  CONNECTION_LOCK (connection);
3634 
3635  status = _dbus_connection_flush_unlocked (connection);
3636 
3637  HAVE_LOCK_CHECK (connection);
3638  /* Unlocks and calls out to user code */
3639  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3640 
3641  _dbus_verbose ("end\n");
3642 }
3643 
3654 static dbus_bool_t
3655 _dbus_connection_read_write_dispatch (DBusConnection *connection,
3656  int timeout_milliseconds,
3657  dbus_bool_t dispatch)
3658 {
3659  DBusDispatchStatus dstatus;
3660  dbus_bool_t progress_possible;
3661 
3662  /* Need to grab a ref here in case we're a private connection and
3663  * the user drops the last ref in a handler we call; see bug
3664  * https://bugs.freedesktop.org/show_bug.cgi?id=15635
3665  */
3666  dbus_connection_ref (connection);
3667  dstatus = dbus_connection_get_dispatch_status (connection);
3668 
3669  if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
3670  {
3671  _dbus_verbose ("doing dispatch\n");
3672  dbus_connection_dispatch (connection);
3673  CONNECTION_LOCK (connection);
3674  }
3675  else if (dstatus == DBUS_DISPATCH_NEED_MEMORY)
3676  {
3677  _dbus_verbose ("pausing for memory\n");
3678  _dbus_memory_pause_based_on_timeout (timeout_milliseconds);
3679  CONNECTION_LOCK (connection);
3680  }
3681  else
3682  {
3683  CONNECTION_LOCK (connection);
3684  if (_dbus_connection_get_is_connected_unlocked (connection))
3685  {
3686  _dbus_verbose ("doing iteration\n");
3688  NULL,
3689  DBUS_ITERATION_DO_READING |
3690  DBUS_ITERATION_DO_WRITING |
3691  DBUS_ITERATION_BLOCK,
3692  timeout_milliseconds);
3693  }
3694  }
3695 
3696  HAVE_LOCK_CHECK (connection);
3697  /* If we can dispatch, we can make progress until the Disconnected message
3698  * has been processed; if we can only read/write, we can make progress
3699  * as long as the transport is open.
3700  */
3701  if (dispatch)
3702  progress_possible = connection->n_incoming != 0 ||
3703  connection->disconnect_message_link != NULL;
3704  else
3705  progress_possible = _dbus_connection_get_is_connected_unlocked (connection);
3706 
3707  CONNECTION_UNLOCK (connection);
3708 
3709  dbus_connection_unref (connection);
3710 
3711  return progress_possible; /* TRUE if we can make more progress */
3712 }
3713 
3714 
3751  int timeout_milliseconds)
3752 {
3753  _dbus_return_val_if_fail (connection != NULL, FALSE);
3754  _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
3755  return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, TRUE);
3756 }
3757 
3781 dbus_bool_t
3783  int timeout_milliseconds)
3784 {
3785  _dbus_return_val_if_fail (connection != NULL, FALSE);
3786  _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, FALSE);
3787  return _dbus_connection_read_write_dispatch(connection, timeout_milliseconds, FALSE);
3788 }
3789 
3790 /* We need to call this anytime we pop the head of the queue, and then
3791  * update_dispatch_status_and_unlock needs to be called afterward
3792  * which will "process" the disconnected message and set
3793  * disconnected_message_processed.
3794  */
3795 static void
3796 check_disconnected_message_arrived_unlocked (DBusConnection *connection,
3797  DBusMessage *head_of_queue)
3798 {
3799  HAVE_LOCK_CHECK (connection);
3800 
3801  /* checking that the link is NULL is an optimization to avoid the is_signal call */
3802  if (connection->disconnect_message_link == NULL &&
3803  dbus_message_is_signal (head_of_queue,
3805  "Disconnected"))
3806  {
3807  connection->disconnected_message_arrived = TRUE;
3808  }
3809 }
3810 
3830 DBusMessage*
3832 {
3833  DBusDispatchStatus status;
3834  DBusMessage *message;
3835 
3836  _dbus_return_val_if_fail (connection != NULL, NULL);
3837 
3838  _dbus_verbose ("start\n");
3839 
3840  /* this is called for the side effect that it queues
3841  * up any messages from the transport
3842  */
3843  status = dbus_connection_get_dispatch_status (connection);
3844  if (status != DBUS_DISPATCH_DATA_REMAINS)
3845  return NULL;
3846 
3847  CONNECTION_LOCK (connection);
3848 
3849  _dbus_connection_acquire_dispatch (connection);
3850 
3851  /* While a message is outstanding, the dispatch lock is held */
3852  _dbus_assert (connection->message_borrowed == NULL);
3853 
3854  connection->message_borrowed = _dbus_list_get_first (&connection->incoming_messages);
3855 
3856  message = connection->message_borrowed;
3857 
3858  check_disconnected_message_arrived_unlocked (connection, message);
3859 
3860  /* Note that we KEEP the dispatch lock until the message is returned */
3861  if (message == NULL)
3862  _dbus_connection_release_dispatch (connection);
3863 
3864  CONNECTION_UNLOCK (connection);
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 
3911 void
3913  DBusMessage *message)
3914 {
3915  DBusMessage *pop_message;
3916  DBusDispatchStatus status;
3917 
3918  _dbus_return_if_fail (connection != NULL);
3919  _dbus_return_if_fail (message != NULL);
3920  _dbus_return_if_fail (message == connection->message_borrowed);
3921  _dbus_return_if_fail (connection->dispatch_acquired);
3922 
3923  CONNECTION_LOCK (connection);
3924 
3925  _dbus_assert (message == connection->message_borrowed);
3926 
3927  pop_message = _dbus_list_pop_first (&connection->incoming_messages);
3928  _dbus_assert (message == pop_message);
3929 
3930  connection->n_incoming -= 1;
3931 
3932  _dbus_verbose ("Incoming message %p stolen from queue, %d incoming\n",
3933  message, connection->n_incoming);
3934 
3935  connection->message_borrowed = NULL;
3936 
3937  _dbus_connection_release_dispatch (connection);
3938 
3939  status = _dbus_connection_get_dispatch_status_unlocked (connection);
3940  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
3941 }
3942 
3943 /* See dbus_connection_pop_message, but requires the caller to own
3944  * the lock before calling. May drop the lock while running.
3945  */
3946 static DBusList*
3947 _dbus_connection_pop_message_link_unlocked (DBusConnection *connection)
3948 {
3949  HAVE_LOCK_CHECK (connection);
3950 
3951  _dbus_assert (connection->message_borrowed == NULL);
3952 
3953  if (connection->n_incoming > 0)
3954  {
3955  DBusList *link;
3956 
3957  link = _dbus_list_pop_first_link (&connection->incoming_messages);
3958  connection->n_incoming -= 1;
3959 
3960  _dbus_verbose ("Message %p (%s %s %s %s '%s') removed from incoming queue %p, %d incoming\n",
3961  link->data,
3963  dbus_message_get_path (link->data) ?
3964  dbus_message_get_path (link->data) :
3965  "no path",
3968  "no interface",
3969  dbus_message_get_member (link->data) ?
3970  dbus_message_get_member (link->data) :
3971  "no member",
3973  connection, connection->n_incoming);
3974 
3975  check_disconnected_message_arrived_unlocked (connection, link->data);
3976 
3977  return link;
3978  }
3979  else
3980  return NULL;
3981 }
3982 
3983 /* See dbus_connection_pop_message, but requires the caller to own
3984  * the lock before calling. May drop the lock while running.
3985  */
3986 static DBusMessage*
3987 _dbus_connection_pop_message_unlocked (DBusConnection *connection)
3988 {
3989  DBusList *link;
3990 
3991  HAVE_LOCK_CHECK (connection);
3992 
3993  link = _dbus_connection_pop_message_link_unlocked (connection);
3994 
3995  if (link != NULL)
3996  {
3997  DBusMessage *message;
3998 
3999  message = link->data;
4000 
4001  _dbus_list_free_link (link);
4002 
4003  return message;
4004  }
4005  else
4006  return NULL;
4007 }
4008 
4009 static void
4010 _dbus_connection_putback_message_link_unlocked (DBusConnection *connection,
4011  DBusList *message_link)
4012 {
4013  HAVE_LOCK_CHECK (connection);
4014 
4015  _dbus_assert (message_link != NULL);
4016  /* You can't borrow a message while a link is outstanding */
4017  _dbus_assert (connection->message_borrowed == NULL);
4018  /* We had to have the dispatch lock across the pop/putback */
4019  _dbus_assert (connection->dispatch_acquired);
4020 
4022  message_link);
4023  connection->n_incoming += 1;
4024 
4025  _dbus_verbose ("Message %p (%s %s %s '%s') put back into queue %p, %d incoming\n",
4026  message_link->data,
4028  dbus_message_get_interface (message_link->data) ?
4029  dbus_message_get_interface (message_link->data) :
4030  "no interface",
4031  dbus_message_get_member (message_link->data) ?
4032  dbus_message_get_member (message_link->data) :
4033  "no member",
4034  dbus_message_get_signature (message_link->data),
4035  connection, connection->n_incoming);
4036 }
4037 
4057 DBusMessage*
4059 {
4060  DBusMessage *message;
4061  DBusDispatchStatus status;
4062 
4063  _dbus_verbose ("start\n");
4064 
4065  /* this is called for the side effect that it queues
4066  * up any messages from the transport
4067  */
4068  status = dbus_connection_get_dispatch_status (connection);
4069  if (status != DBUS_DISPATCH_DATA_REMAINS)
4070  return NULL;
4071 
4072  CONNECTION_LOCK (connection);
4073  _dbus_connection_acquire_dispatch (connection);
4074  HAVE_LOCK_CHECK (connection);
4075 
4076  message = _dbus_connection_pop_message_unlocked (connection);
4077 
4078  _dbus_verbose ("Returning popped message %p\n", message);
4079 
4080  _dbus_connection_release_dispatch (connection);
4081 
4082  status = _dbus_connection_get_dispatch_status_unlocked (connection);
4083  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
4084 
4085  return message;
4086 }
4087 
4095 static void
4096 _dbus_connection_acquire_dispatch (DBusConnection *connection)
4097 {
4098  HAVE_LOCK_CHECK (connection);
4099 
4100  _dbus_connection_ref_unlocked (connection);
4101  CONNECTION_UNLOCK (connection);
4102 
4103  _dbus_verbose ("locking dispatch_mutex\n");
4104  _dbus_mutex_lock (connection->dispatch_mutex);
4105 
4106  while (connection->dispatch_acquired)
4107  {
4108  _dbus_verbose ("waiting for dispatch to be acquirable\n");
4109  _dbus_condvar_wait (connection->dispatch_cond,
4110  connection->dispatch_mutex);
4111  }
4112 
4113  _dbus_assert (!connection->dispatch_acquired);
4114 
4115  connection->dispatch_acquired = TRUE;
4116 
4117  _dbus_verbose ("unlocking dispatch_mutex\n");
4118  _dbus_mutex_unlock (connection->dispatch_mutex);
4119 
4120  CONNECTION_LOCK (connection);
4121  _dbus_connection_unref_unlocked (connection);
4122 }
4123 
4131 static void
4132 _dbus_connection_release_dispatch (DBusConnection *connection)
4133 {
4134  HAVE_LOCK_CHECK (connection);
4135 
4136  _dbus_verbose ("locking dispatch_mutex\n");
4137  _dbus_mutex_lock (connection->dispatch_mutex);
4138 
4139  _dbus_assert (connection->dispatch_acquired);
4140 
4141  connection->dispatch_acquired = FALSE;
4142  _dbus_condvar_wake_one (connection->dispatch_cond);
4143 
4144  _dbus_verbose ("unlocking dispatch_mutex\n");
4145  _dbus_mutex_unlock (connection->dispatch_mutex);
4146 }
4147 
4148 static void
4149 _dbus_connection_failed_pop (DBusConnection *connection,
4150  DBusList *message_link)
4151 {
4153  message_link);
4154  connection->n_incoming += 1;
4155 }
4156 
4157 /* Note this may be called multiple times since we don't track whether we already did it */
4158 static void
4159 notify_disconnected_unlocked (DBusConnection *connection)
4160 {
4161  HAVE_LOCK_CHECK (connection);
4162 
4163  /* Set the weakref in dbus-bus.c to NULL, so nobody will get a disconnected
4164  * connection from dbus_bus_get(). We make the same guarantee for
4165  * dbus_connection_open() but in a different way since we don't want to
4166  * unref right here; we instead check for connectedness before returning
4167  * the connection from the hash.
4168  */
4170 
4171  /* Dump the outgoing queue, we aren't going to be able to
4172  * send it now, and we'd like accessors like
4173  * dbus_connection_get_outgoing_size() to be accurate.
4174  */
4175  if (connection->n_outgoing > 0)
4176  {
4177  DBusList *link;
4178 
4179  _dbus_verbose ("Dropping %d outgoing messages since we're disconnected\n",
4180  connection->n_outgoing);
4181 
4182  while ((link = _dbus_list_get_last_link (&connection->outgoing_messages)))
4183  {
4184  _dbus_connection_message_sent (connection, link->data);
4185  }
4186  }
4187 }
4188 
4189 /* Note this may be called multiple times since we don't track whether we already did it */
4190 static DBusDispatchStatus
4191 notify_disconnected_and_dispatch_complete_unlocked (DBusConnection *connection)
4192 {
4193  HAVE_LOCK_CHECK (connection);
4194 
4195  if (connection->disconnect_message_link != NULL)
4196  {
4197  _dbus_verbose ("Sending disconnect message\n");
4198 
4199  /* If we have pending calls, queue their timeouts - we want the Disconnected
4200  * to be the last message, after these timeouts.
4201  */
4202  connection_timeout_and_complete_all_pending_calls_unlocked (connection);
4203 
4204  /* We haven't sent the disconnect message already,
4205  * and all real messages have been queued up.
4206  */
4208  connection->disconnect_message_link);
4209  connection->disconnect_message_link = NULL;
4210 
4212  }
4213 
4214  return DBUS_DISPATCH_COMPLETE;
4215 }
4216 
4217 static DBusDispatchStatus
4218 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
4219 {
4220  HAVE_LOCK_CHECK (connection);
4221 
4222  if (connection->n_incoming > 0)
4224  else if (!_dbus_transport_queue_messages (connection->transport))
4226  else
4227  {
4228  DBusDispatchStatus status;
4229  dbus_bool_t is_connected;
4230 
4231  status = _dbus_transport_get_dispatch_status (connection->transport);
4232  is_connected = _dbus_transport_get_is_connected (connection->transport);
4233 
4234  _dbus_verbose ("dispatch status = %s is_connected = %d\n",
4235  DISPATCH_STATUS_NAME (status), is_connected);
4236 
4237  if (!is_connected)
4238  {
4239  /* It's possible this would be better done by having an explicit
4240  * notification from _dbus_transport_disconnect() that would
4241  * synchronously do this, instead of waiting for the next dispatch
4242  * status check. However, probably not good to change until it causes
4243  * a problem.
4244  */
4245  notify_disconnected_unlocked (connection);
4246 
4247  /* I'm not sure this is needed; the idea is that we want to
4248  * queue the Disconnected only after we've read all the
4249  * messages, but if we're disconnected maybe we are guaranteed
4250  * to have read them all ?
4251  */
4252  if (status == DBUS_DISPATCH_COMPLETE)
4253  status = notify_disconnected_and_dispatch_complete_unlocked (connection);
4254  }
4255 
4256  if (status != DBUS_DISPATCH_COMPLETE)
4257  return status;
4258  else if (connection->n_incoming > 0)
4260  else
4261  return DBUS_DISPATCH_COMPLETE;
4262  }
4263 }
4264 
4265 static void
4266 _dbus_connection_update_dispatch_status_and_unlock (DBusConnection *connection,
4267  DBusDispatchStatus new_status)
4268 {
4269  dbus_bool_t changed;
4270  DBusDispatchStatusFunction function;
4271  void *data;
4272 
4273  HAVE_LOCK_CHECK (connection);
4274 
4275  _dbus_connection_ref_unlocked (connection);
4276 
4277  changed = new_status != connection->last_dispatch_status;
4278 
4279  connection->last_dispatch_status = new_status;
4280 
4281  function = connection->dispatch_status_function;
4282  data = connection->dispatch_status_data;
4283 
4284  if (connection->disconnected_message_arrived &&
4285  !connection->disconnected_message_processed)
4286  {
4287  connection->disconnected_message_processed = TRUE;
4288 
4289  /* this does an unref, but we have a ref
4290  * so we should not run the finalizer here
4291  * inside the lock.
4292  */
4293  connection_forget_shared_unlocked (connection);
4294 
4295  if (connection->exit_on_disconnect)
4296  {
4297  CONNECTION_UNLOCK (connection);
4298 
4299  _dbus_verbose ("Exiting on Disconnected signal\n");
4300  _dbus_exit (1);
4301  _dbus_assert_not_reached ("Call to exit() returned");
4302  }
4303  }
4304 
4305  /* We drop the lock */
4306  CONNECTION_UNLOCK (connection);
4307 
4308  if (changed && function)
4309  {
4310  _dbus_verbose ("Notifying of change to dispatch status of %p now %d (%s)\n",
4311  connection, new_status,
4312  DISPATCH_STATUS_NAME (new_status));
4313  (* function) (connection, new_status, data);
4314  }
4315 
4316  dbus_connection_unref (connection);
4317 }
4318 
4346 {
4347  DBusDispatchStatus status;
4348 
4349  _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
4350 
4351  _dbus_verbose ("start\n");
4352 
4353  CONNECTION_LOCK (connection);
4354 
4355  status = _dbus_connection_get_dispatch_status_unlocked (connection);
4356 
4357  CONNECTION_UNLOCK (connection);
4358 
4359  return status;
4360 }
4361 
4365 static DBusHandlerResult
4366 _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
4367  DBusMessage *message)
4368 {
4369  if (connection->route_peer_messages && dbus_message_get_destination (message) != NULL)
4370  {
4371  /* This means we're letting the bus route this message */
4373  }
4374  else if (dbus_message_is_method_call (message,
4376  "Ping"))
4377  {
4378  DBusMessage *ret;
4379  dbus_bool_t sent;
4380 
4381  ret = dbus_message_new_method_return (message);
4382  if (ret == NULL)
4384 
4385  sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
4386 
4387  dbus_message_unref (ret);
4388 
4389  if (!sent)
4391 
4393  }
4394  else if (dbus_message_is_method_call (message,
4396  "GetMachineId"))
4397  {
4398  DBusMessage *ret;
4399  dbus_bool_t sent;
4400  DBusString uuid;
4401 
4402  ret = dbus_message_new_method_return (message);
4403  if (ret == NULL)
4405 
4406  sent = FALSE;
4407  _dbus_string_init (&uuid);
4409  {
4410  const char *v_STRING = _dbus_string_get_const_data (&uuid);
4411  if (dbus_message_append_args (ret,
4412  DBUS_TYPE_STRING, &v_STRING,
4414  {
4415  sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
4416  }
4417  }
4418  _dbus_string_free (&uuid);
4419 
4420  dbus_message_unref (ret);
4421 
4422  if (!sent)
4424 
4426  }
4427  else if (dbus_message_has_interface (message, DBUS_INTERFACE_PEER))
4428  {
4429  /* We need to bounce anything else with this interface, otherwise apps
4430  * could start extending the interface and when we added extensions
4431  * here to DBusConnection we'd break those apps.
4432  */
4433 
4434  DBusMessage *ret;
4435  dbus_bool_t sent;
4436 
4437  ret = dbus_message_new_error (message,
4439  "Unknown method invoked on org.freedesktop.DBus.Peer interface");
4440  if (ret == NULL)
4442 
4443  sent = _dbus_connection_send_unlocked_no_update (connection, ret, NULL);
4444 
4445  dbus_message_unref (ret);
4446 
4447  if (!sent)
4449 
4451  }
4452  else
4453  {
4455  }
4456 }
4457 
4464 static DBusHandlerResult
4465 _dbus_connection_run_builtin_filters_unlocked_no_update (DBusConnection *connection,
4466  DBusMessage *message)
4467 {
4468  /* We just run one filter for now but have the option to run more
4469  if the spec calls for it in the future */
4470 
4471  return _dbus_connection_peer_filter_unlocked_no_update (connection, message);
4472 }
4473 
4518 {
4519  DBusMessage *message;
4520  DBusList *link, *filter_list_copy, *message_link;
4521  DBusHandlerResult result;
4522  DBusPendingCall *pending;
4523  dbus_int32_t reply_serial;
4524  DBusDispatchStatus status;
4525 
4526  _dbus_return_val_if_fail (connection != NULL, DBUS_DISPATCH_COMPLETE);
4527 
4528  _dbus_verbose ("\n");
4529 
4530  CONNECTION_LOCK (connection);
4531  status = _dbus_connection_get_dispatch_status_unlocked (connection);
4532  if (status != DBUS_DISPATCH_DATA_REMAINS)
4533  {
4534  /* unlocks and calls out to user code */
4535  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
4536  return status;
4537  }
4538 
4539  /* We need to ref the connection since the callback could potentially
4540  * drop the last ref to it
4541  */
4542  _dbus_connection_ref_unlocked (connection);
4543 
4544  _dbus_connection_acquire_dispatch (connection);
4545  HAVE_LOCK_CHECK (connection);
4546 
4547  message_link = _dbus_connection_pop_message_link_unlocked (connection);
4548  if (message_link == NULL)
4549  {
4550  /* another thread dispatched our stuff */
4551 
4552  _dbus_verbose ("another thread dispatched message (during acquire_dispatch above)\n");
4553 
4554  _dbus_connection_release_dispatch (connection);
4555 
4556  status = _dbus_connection_get_dispatch_status_unlocked (connection);
4557 
4558  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
4559 
4560  dbus_connection_unref (connection);
4561 
4562  return status;
4563  }
4564 
4565  message = message_link->data;
4566 
4567  _dbus_verbose (" dispatching message %p (%s %s %s '%s')\n",
4568  message,
4570  dbus_message_get_interface (message) ?
4571  dbus_message_get_interface (message) :
4572  "no interface",
4573  dbus_message_get_member (message) ?
4574  dbus_message_get_member (message) :
4575  "no member",
4576  dbus_message_get_signature (message));
4577 
4579 
4580  /* Pending call handling must be first, because if you do
4581  * dbus_connection_send_with_reply_and_block() or
4582  * dbus_pending_call_block() then no handlers/filters will be run on
4583  * the reply. We want consistent semantics in the case where we
4584  * dbus_connection_dispatch() the reply.
4585  */
4586 
4587  reply_serial = dbus_message_get_reply_serial (message);
4588  pending = _dbus_hash_table_lookup_int (connection->pending_replies,
4589  reply_serial);
4590  if (pending)
4591  {
4592  _dbus_verbose ("Dispatching a pending reply\n");
4593  complete_pending_call_and_unlock (connection, pending, message);
4594  pending = NULL; /* it's probably unref'd */
4595 
4596  CONNECTION_LOCK (connection);
4597  _dbus_verbose ("pending call completed in dispatch\n");
4598  result = DBUS_HANDLER_RESULT_HANDLED;
4599  goto out;
4600  }
4601 
4602  result = _dbus_connection_run_builtin_filters_unlocked_no_update (connection, message);
4604  goto out;
4605 
4606  if (!_dbus_list_copy (&connection->filter_list, &filter_list_copy))
4607  {
4608  _dbus_connection_release_dispatch (connection);
4609  HAVE_LOCK_CHECK (connection);
4610 
4611  _dbus_connection_failed_pop (connection, message_link);
4612 
4613  /* unlocks and calls user code */
4614  _dbus_connection_update_dispatch_status_and_unlock (connection,
4616  dbus_connection_unref (connection);
4617 
4619  }
4620 
4621  _dbus_list_foreach (&filter_list_copy,
4622  (DBusForeachFunction)_dbus_message_filter_ref,
4623  NULL);
4624 
4625  /* We're still protected from dispatch() reentrancy here
4626  * since we acquired the dispatcher
4627  */
4628  CONNECTION_UNLOCK (connection);
4629 
4630  link = _dbus_list_get_first_link (&filter_list_copy);
4631  while (link != NULL)
4632  {
4633  DBusMessageFilter *filter = link->data;
4634  DBusList *next = _dbus_list_get_next_link (&filter_list_copy, link);
4635 
4636  if (filter->function == NULL)
4637  {
4638  _dbus_verbose (" filter was removed in a callback function\n");
4639  link = next;
4640  continue;
4641  }
4642 
4643  _dbus_verbose (" running filter on message %p\n", message);
4644  result = (* filter->function) (connection, message, filter->user_data);
4645 
4647  break;
4648 
4649  link = next;
4650  }
4651 
4652  _dbus_list_foreach (&filter_list_copy,
4653  (DBusForeachFunction)_dbus_message_filter_unref,
4654  NULL);
4655  _dbus_list_clear (&filter_list_copy);
4656 
4657  CONNECTION_LOCK (connection);
4658 
4659  if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
4660  {
4661  _dbus_verbose ("No memory\n");
4662  goto out;
4663  }
4664  else if (result == DBUS_HANDLER_RESULT_HANDLED)
4665  {
4666  _dbus_verbose ("filter handled message in dispatch\n");
4667  goto out;
4668  }
4669 
4670  /* We're still protected from dispatch() reentrancy here
4671  * since we acquired the dispatcher
4672  */
4673  _dbus_verbose (" running object path dispatch on message %p (%s %s %s '%s')\n",
4674  message,
4676  dbus_message_get_interface (message) ?
4677  dbus_message_get_interface (message) :
4678  "no interface",
4679  dbus_message_get_member (message) ?
4680  dbus_message_get_member (message) :
4681  "no member",
4682  dbus_message_get_signature (message));
4683 
4684  HAVE_LOCK_CHECK (connection);
4685  result = _dbus_object_tree_dispatch_and_unlock (connection->objects,
4686  message);
4687 
4688  CONNECTION_LOCK (connection);
4689 
4691  {
4692  _dbus_verbose ("object tree handled message in dispatch\n");
4693  goto out;
4694  }
4695 
4697  {
4698  DBusMessage *reply;
4699  DBusString str;
4700  DBusPreallocatedSend *preallocated;
4701 
4702  _dbus_verbose (" sending error %s\n",
4704 
4705  if (!_dbus_string_init (&str))
4706  {
4708  _dbus_verbose ("no memory for error string in dispatch\n");
4709  goto out;
4710  }
4711 
4712  if (!_dbus_string_append_printf (&str,
4713  "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n",
4714  dbus_message_get_member (message),
4715  dbus_message_get_signature (message),
4716  dbus_message_get_interface (message)))
4717  {
4718  _dbus_string_free (&str);
4720  _dbus_verbose ("no memory for error string in dispatch\n");
4721  goto out;
4722  }
4723 
4724  reply = dbus_message_new_error (message,
4727  _dbus_string_free (&str);
4728 
4729  if (reply == NULL)
4730  {
4732  _dbus_verbose ("no memory for error reply in dispatch\n");
4733  goto out;
4734  }
4735 
4736  preallocated = _dbus_connection_preallocate_send_unlocked (connection);
4737 
4738  if (preallocated == NULL)
4739  {
4740  dbus_message_unref (reply);
4742  _dbus_verbose ("no memory for error send in dispatch\n");
4743  goto out;
4744  }
4745 
4746  _dbus_connection_send_preallocated_unlocked_no_update (connection, preallocated,
4747  reply, NULL);
4748 
4749  dbus_message_unref (reply);
4750 
4751  result = DBUS_HANDLER_RESULT_HANDLED;
4752  }
4753 
4754  _dbus_verbose (" done dispatching %p (%s %s %s '%s') on connection %p\n", message,
4756  dbus_message_get_interface (message) ?
4757  dbus_message_get_interface (message) :
4758  "no interface",
4759  dbus_message_get_member (message) ?
4760  dbus_message_get_member (message) :
4761  "no member",
4762  dbus_message_get_signature (message),
4763  connection);
4764 
4765  out:
4766  if (result == DBUS_HANDLER_RESULT_NEED_MEMORY)
4767  {
4768  _dbus_verbose ("out of memory\n");
4769 
4770  /* Put message back, and we'll start over.
4771  * Yes this means handlers must be idempotent if they
4772  * don't return HANDLED; c'est la vie.
4773  */
4774  _dbus_connection_putback_message_link_unlocked (connection,
4775  message_link);
4776  }
4777  else
4778  {
4779  _dbus_verbose (" ... done dispatching\n");
4780 
4781  _dbus_list_free_link (message_link);
4782  dbus_message_unref (message); /* don't want the message to count in max message limits
4783  * in computing dispatch status below
4784  */
4785  }
4786 
4787  _dbus_connection_release_dispatch (connection);
4788  HAVE_LOCK_CHECK (connection);
4789 
4790  _dbus_verbose ("before final status update\n");
4791  status = _dbus_connection_get_dispatch_status_unlocked (connection);
4792 
4793  /* unlocks and calls user code */
4794  _dbus_connection_update_dispatch_status_and_unlock (connection, status);
4795 
4796  dbus_connection_unref (connection);
4797 
4798  return status;
4799 }
4800 
4864  DBusAddWatchFunction add_function,
4865  DBusRemoveWatchFunction remove_function,
4866  DBusWatchToggledFunction toggled_function,
4867  void *data,
4868  DBusFreeFunction free_data_function)
4869 {
4870  dbus_bool_t retval;
4871 
4872  _dbus_return_val_if_fail (connection != NULL, FALSE);
4873 
4874  CONNECTION_LOCK (connection);
4875 
4876  retval = _dbus_watch_list_set_functions (connection->watches,
4877  add_function, remove_function,
4878  toggled_function,
4879  data, free_data_function);
4880 
4881  CONNECTION_UNLOCK (connection);
4882 
4883  return retval;
4884 }
4885 
4927  DBusAddTimeoutFunction add_function,
4928  DBusRemoveTimeoutFunction remove_function,
4929  DBusTimeoutToggledFunction toggled_function,
4930  void *data,
4931  DBusFreeFunction free_data_function)
4932 {
4933  dbus_bool_t retval;
4934 
4935  _dbus_return_val_if_fail (connection != NULL, FALSE);
4936 
4937  CONNECTION_LOCK (connection);
4938 
4939  retval = _dbus_timeout_list_set_functions (connection->timeouts,
4940  add_function, remove_function,
4941  toggled_function,
4942  data, free_data_function);
4943 
4944  CONNECTION_UNLOCK (connection);
4945 
4946  return retval;
4947 }
4948 
4963 void
4965  DBusWakeupMainFunction wakeup_main_function,
4966  void *data,
4967  DBusFreeFunction free_data_function)
4968 {
4969  void *old_data;
4970  DBusFreeFunction old_free_data;
4971 
4972  _dbus_return_if_fail (connection != NULL);
4973 
4974  CONNECTION_LOCK (connection);
4975  old_data = connection->wakeup_main_data;
4976  old_free_data = connection->free_wakeup_main_data;
4977 
4978  connection->wakeup_main_function = wakeup_main_function;
4979  connection->wakeup_main_data = data;
4980  connection->free_wakeup_main_data = free_data_function;
4981 
4982  CONNECTION_UNLOCK (connection);
4983 
4984  /* Callback outside the lock */
4985  if (old_free_data)
4986  (*old_free_data) (old_data);
4987 }
4988 
5009 void
5011  DBusDispatchStatusFunction function,
5012  void *data,
5013  DBusFreeFunction free_data_function)
5014 {
5015  void *old_data;
5016  DBusFreeFunction old_free_data;
5017 
5018  _dbus_return_if_fail (connection != NULL);
5019 
5020  CONNECTION_LOCK (connection);
5021  old_data = connection->dispatch_status_data;
5022  old_free_data = connection->free_dispatch_status_data;
5023 
5024  connection->dispatch_status_function = function;
5025  connection->dispatch_status_data = data;
5026  connection->free_dispatch_status_data = free_data_function;
5027 
5028  CONNECTION_UNLOCK (connection);
5029 
5030  /* Callback outside the lock */
5031  if (old_free_data)
5032  (*old_free_data) (old_data);
5033 }
5034 
5056  int *fd)
5057 {
5058  _dbus_return_val_if_fail (connection != NULL, FALSE);
5059  _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
5060 
5061 #ifdef DBUS_WIN
5062  /* FIXME do this on a lower level */
5063  return FALSE;
5064 #endif
5065 
5066  return dbus_connection_get_socket(connection, fd);
5067 }
5068 
5086  int *fd)
5087 {
5088  dbus_bool_t retval;
5089 
5090  _dbus_return_val_if_fail (connection != NULL, FALSE);
5091  _dbus_return_val_if_fail (connection->transport != NULL, FALSE);
5092 
5093  CONNECTION_LOCK (connection);
5094 
5095  retval = _dbus_transport_get_socket_fd (connection->transport,
5096  fd);
5097 
5098  CONNECTION_UNLOCK (connection);
5099 
5100  return retval;
5101 }
5102 
5103 
5128  unsigned long *uid)
5129 {
5130  dbus_bool_t result;
5131 
5132  _dbus_return_val_if_fail (connection != NULL, FALSE);
5133  _dbus_return_val_if_fail (uid != NULL, FALSE);
5134 
5135  CONNECTION_LOCK (connection);
5136 
5138  result = FALSE;
5139  else
5140  result = _dbus_transport_get_unix_user (connection->transport,
5141  uid);
5142 
5143 #ifdef DBUS_WIN
5144  _dbus_assert (!result);
5145 #endif
5146 
5147  CONNECTION_UNLOCK (connection);
5148 
5149  return result;
5150 }
5151 
5164  unsigned long *pid)
5165 {
5166  dbus_bool_t result;
5167 
5168  _dbus_return_val_if_fail (connection != NULL, FALSE);
5169  _dbus_return_val_if_fail (pid != NULL, FALSE);
5170 
5171  CONNECTION_LOCK (connection);
5172 
5174  result = FALSE;
5175  else
5176  result = _dbus_transport_get_unix_process_id (connection->transport,
5177  pid);
5178 
5179  CONNECTION_UNLOCK (connection);
5180 
5181  return result;
5182 }
5183 
5196  void **data,
5197  dbus_int32_t *data_size)
5198 {
5199  dbus_bool_t result;
5200 
5201  _dbus_return_val_if_fail (connection != NULL, FALSE);
5202  _dbus_return_val_if_fail (data != NULL, FALSE);
5203  _dbus_return_val_if_fail (data_size != NULL, FALSE);
5204 
5205  CONNECTION_LOCK (connection);
5206 
5208  result = FALSE;
5209  else
5211  data,
5212  data_size);
5213  CONNECTION_UNLOCK (connection);
5214 
5215  return result;
5216 }
5217 
5240 void
5242  DBusAllowUnixUserFunction function,
5243  void *data,
5244  DBusFreeFunction free_data_function)
5245 {
5246  void *old_data = NULL;
5247  DBusFreeFunction old_free_function = NULL;
5248 
5249  _dbus_return_if_fail (connection != NULL);
5250 
5251  CONNECTION_LOCK (connection);
5253  function, data, free_data_function,
5254  &old_data, &old_free_function);
5255  CONNECTION_UNLOCK (connection);
5256 
5257  if (old_free_function != NULL)
5258  (* old_free_function) (old_data);
5259 }
5260 
5294  char **windows_sid_p)
5295 {
5296  dbus_bool_t result;
5297 
5298  _dbus_return_val_if_fail (connection != NULL, FALSE);
5299  _dbus_return_val_if_fail (windows_sid_p != NULL, FALSE);
5300 
5301  CONNECTION_LOCK (connection);
5302 
5304  result = FALSE;
5305  else
5306  result = _dbus_transport_get_windows_user (connection->transport,
5307  windows_sid_p);
5308 
5309 #ifdef DBUS_UNIX
5310  _dbus_assert (!result);
5311 #endif
5312 
5313  CONNECTION_UNLOCK (connection);
5314 
5315  return result;
5316 }
5317 
5339 void
5342  void *data,
5343  DBusFreeFunction free_data_function)
5344 {
5345  void *old_data = NULL;
5346  DBusFreeFunction old_free_function = NULL;
5347 
5348  _dbus_return_if_fail (connection != NULL);
5349 
5350  CONNECTION_LOCK (connection);
5352  function, data, free_data_function,
5353  &old_data, &old_free_function);
5354  CONNECTION_UNLOCK (connection);
5355 
5356  if (old_free_function != NULL)
5357  (* old_free_function) (old_data);
5358 }
5359 
5386 void
5388  dbus_bool_t value)
5389 {
5390  _dbus_return_if_fail (connection != NULL);
5391 
5392  CONNECTION_LOCK (connection);
5393  _dbus_transport_set_allow_anonymous (connection->transport, value);
5394  CONNECTION_UNLOCK (connection);
5395 }
5396 
5414 void
5416  dbus_bool_t value)
5417 {
5418  _dbus_return_if_fail (connection != NULL);
5419 
5420  CONNECTION_LOCK (connection);
5421  connection->route_peer_messages = TRUE;
5422  CONNECTION_UNLOCK (connection);
5423 }
5424 
5448  DBusHandleMessageFunction function,
5449  void *user_data,
5450  DBusFreeFunction free_data_function)
5451 {
5452  DBusMessageFilter *filter;
5453 
5454  _dbus_return_val_if_fail (connection != NULL, FALSE);
5455  _dbus_return_val_if_fail (function != NULL, FALSE);
5456 
5457  filter = dbus_new0 (DBusMessageFilter, 1);
5458  if (filter == NULL)
5459  return FALSE;
5460 
5461  filter->refcount.value = 1;
5462 
5463  CONNECTION_LOCK (connection);
5464 
5465  if (!_dbus_list_append (&connection->filter_list,
5466  filter))
5467  {
5468  _dbus_message_filter_unref (filter);
5469  CONNECTION_UNLOCK (connection);
5470  return FALSE;
5471  }
5472 
5473  /* Fill in filter after all memory allocated,
5474  * so we don't run the free_user_data_function
5475  * if the add_filter() fails
5476  */
5477 
5478  filter->function = function;
5479  filter->user_data = user_data;
5480  filter->free_user_data_function = free_data_function;
5481 
5482  CONNECTION_UNLOCK (connection);
5483  return TRUE;
5484 }
5485 
5498 void
5500  DBusHandleMessageFunction function,
5501  void *user_data)
5502 {
5503  DBusList *link;
5504  DBusMessageFilter *filter;
5505 
5506  _dbus_return_if_fail (connection != NULL);
5507  _dbus_return_if_fail (function != NULL);
5508 
5509  CONNECTION_LOCK (connection);
5510 
5511  filter = NULL;
5512 
5513  link = _dbus_list_get_last_link (&connection->filter_list);
5514  while (link != NULL)
5515  {
5516  filter = link->data;
5517 
5518  if (filter->function == function &&
5519  filter->user_data == user_data)
5520  {
5521  _dbus_list_remove_link (&connection->filter_list, link);
5522  filter->function = NULL;
5523 
5524  break;
5525  }
5526 
5527  link = _dbus_list_get_prev_link (&connection->filter_list, link);
5528  filter = NULL;
5529  }
5530 
5531  CONNECTION_UNLOCK (connection);
5532 
5533 #ifndef DBUS_DISABLE_CHECKS
5534  if (filter == NULL)
5535  {
5536  _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
5537  function, user_data);
5538  return;
5539  }
5540 #endif
5541 
5542  /* Call application code */
5543  if (filter->free_user_data_function)
5544  (* filter->free_user_data_function) (filter->user_data);
5545 
5546  filter->free_user_data_function = NULL;
5547  filter->user_data = NULL;
5548 
5549  _dbus_message_filter_unref (filter);
5550 }
5551 
5566  const char *path,
5567  const DBusObjectPathVTable *vtable,
5568  void *user_data,
5569  DBusError *error)
5570 {
5571  char **decomposed_path;
5572  dbus_bool_t retval;
5573 
5574  _dbus_return_val_if_fail (connection != NULL, FALSE);
5575  _dbus_return_val_if_fail (path != NULL, FALSE);
5576  _dbus_return_val_if_fail (path[0] == '/', FALSE);
5577  _dbus_return_val_if_fail (vtable != NULL, FALSE);
5578 
5579  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
5580  return FALSE;
5581 
5582  CONNECTION_LOCK (connection);
5583 
5584  retval = _dbus_object_tree_register (connection->objects,
5585  FALSE,
5586  (const char **) decomposed_path, vtable,
5587  user_data, error);
5588 
5589  CONNECTION_UNLOCK (connection);
5590 
5591  dbus_free_string_array (decomposed_path);
5592 
5593  return retval;
5594 }
5595 
5612  const char *path,
5613  const DBusObjectPathVTable *vtable,
5614  void *user_data)
5615 {
5616  char **decomposed_path;
5617  dbus_bool_t retval;
5618  DBusError error = DBUS_ERROR_INIT;
5619 
5620  _dbus_return_val_if_fail (connection != NULL, FALSE);
5621  _dbus_return_val_if_fail (path != NULL, FALSE);
5622  _dbus_return_val_if_fail (path[0] == '/', FALSE);
5623  _dbus_return_val_if_fail (vtable != NULL, FALSE);
5624 
5625  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
5626  return FALSE;
5627 
5628  CONNECTION_LOCK (connection);
5629 
5630  retval = _dbus_object_tree_register (connection->objects,
5631  FALSE,
5632  (const char **) decomposed_path, vtable,
5633  user_data, &error);
5634 
5635  CONNECTION_UNLOCK (connection);
5636 
5637  dbus_free_string_array (decomposed_path);
5638 
5640  {
5641  _dbus_warn ("%s\n", error.message);
5642  dbus_error_free (&error);
5643  return FALSE;
5644  }
5645 
5646  return retval;
5647 }
5648 
5665  const char *path,
5666  const DBusObjectPathVTable *vtable,
5667  void *user_data,
5668  DBusError *error)
5669 {
5670  char **decomposed_path;
5671  dbus_bool_t retval;
5672 
5673  _dbus_return_val_if_fail (connection != NULL, FALSE);
5674  _dbus_return_val_if_fail (path != NULL, FALSE);
5675  _dbus_return_val_if_fail (path[0] == '/', FALSE);
5676  _dbus_return_val_if_fail (vtable != NULL, FALSE);
5677 
5678  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
5679  return FALSE;
5680 
5681  CONNECTION_LOCK (connection);
5682 
5683  retval = _dbus_object_tree_register (connection->objects,
5684  TRUE,
5685  (const char **) decomposed_path, vtable,
5686  user_data, error);
5687 
5688  CONNECTION_UNLOCK (connection);
5689 
5690  dbus_free_string_array (decomposed_path);
5691 
5692  return retval;
5693 }
5694 
5713  const char *path,
5714  const DBusObjectPathVTable *vtable,
5715  void *user_data)
5716 {
5717  char **decomposed_path;
5718  dbus_bool_t retval;
5719  DBusError error = DBUS_ERROR_INIT;
5720 
5721  _dbus_return_val_if_fail (connection != NULL, FALSE);
5722  _dbus_return_val_if_fail (path != NULL, FALSE);
5723  _dbus_return_val_if_fail (path[0] == '/', FALSE);
5724  _dbus_return_val_if_fail (vtable != NULL, FALSE);
5725 
5726  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
5727  return FALSE;
5728 
5729  CONNECTION_LOCK (connection);
5730 
5731  retval = _dbus_object_tree_register (connection->objects,
5732  TRUE,
5733  (const char **) decomposed_path, vtable,
5734  user_data, &error);
5735 
5736  CONNECTION_UNLOCK (connection);
5737 
5738  dbus_free_string_array (decomposed_path);
5739 
5741  {
5742  _dbus_warn ("%s\n", error.message);
5743  dbus_error_free (&error);
5744  return FALSE;
5745  }
5746 
5747  return retval;
5748 }
5749 
5761  const char *path)
5762 {
5763  char **decomposed_path;
5764 
5765  _dbus_return_val_if_fail (connection != NULL, FALSE);
5766  _dbus_return_val_if_fail (path != NULL, FALSE);
5767  _dbus_return_val_if_fail (path[0] == '/', FALSE);
5768 
5769  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
5770  return FALSE;
5771 
5772  CONNECTION_LOCK (connection);
5773 
5774  _dbus_object_tree_unregister_and_unlock (connection->objects, (const char **) decomposed_path);
5775 
5776  dbus_free_string_array (decomposed_path);
5777 
5778  return TRUE;
5779 }
5780 
5793  const char *path,
5794  void **data_p)
5795 {
5796  char **decomposed_path;
5797 
5798  _dbus_return_val_if_fail (connection != NULL, FALSE);
5799  _dbus_return_val_if_fail (path != NULL, FALSE);
5800  _dbus_return_val_if_fail (data_p != NULL, FALSE);
5801 
5802  *data_p = NULL;
5803 
5804  if (!_dbus_decompose_path (path, strlen (path), &decomposed_path, NULL))
5805  return FALSE;
5806 
5807  CONNECTION_LOCK (connection);
5808 
5809  *data_p = _dbus_object_tree_get_user_data_unlocked (connection->objects, (const char**) decomposed_path);
5810 
5811  CONNECTION_UNLOCK (connection);
5812 
5813  dbus_free_string_array (decomposed_path);
5814 
5815  return TRUE;
5816 }
5817 
5830  const char *parent_path,
5831  char ***child_entries)
5832 {
5833  char **decomposed_path;
5834  dbus_bool_t retval;
5835  _dbus_return_val_if_fail (connection != NULL, FALSE);
5836  _dbus_return_val_if_fail (parent_path != NULL, FALSE);
5837  _dbus_return_val_if_fail (parent_path[0] == '/', FALSE);
5838  _dbus_return_val_if_fail (child_entries != NULL, FALSE);
5839 
5840  if (!_dbus_decompose_path (parent_path, strlen (parent_path), &decomposed_path, NULL))
5841  return FALSE;
5842 
5843  CONNECTION_LOCK (connection);
5844 
5846  (const char **) decomposed_path,
5847  child_entries);
5848  dbus_free_string_array (decomposed_path);
5849 
5850  return retval;
5851 }
5852 
5853 static DBusDataSlotAllocator slot_allocator;
5854 _DBUS_DEFINE_GLOBAL_LOCK (connection_slots);
5855 
5872 {
5873  return _dbus_data_slot_allocator_alloc (&slot_allocator,
5874  &_DBUS_LOCK_NAME (connection_slots),
5875  slot_p);
5876 }
5877 
5889 void
5891 {
5892  _dbus_return_if_fail (*slot_p >= 0);
5893 
5894  _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
5895 }
5896 
5921  dbus_int32_t slot,
5922  void *data,
5923  DBusFreeFunction free_data_func)
5924 {
5925  DBusFreeFunction old_free_func;
5926  void *old_data;
5927  dbus_bool_t retval;
5928 
5929  _dbus_return_val_if_fail (connection != NULL, FALSE);
5930  _dbus_return_val_if_fail (slot >= 0, FALSE);
5931 
5932  SLOTS_LOCK (connection);
5933 
5934  retval = _dbus_data_slot_list_set (&slot_allocator,
5935  &connection->slot_list,
5936  slot, data, free_data_func,
5937  &old_free_func, &old_data);
5938 
5939  SLOTS_UNLOCK (connection);
5940 
5941  if (retval)
5942  {
5943  /* Do the actual free outside the connection lock */
5944  if (old_free_func)
5945  (* old_free_func) (old_data);
5946  }
5947 
5948  return retval;
5949 }
5950 
5968 void*
5970  dbus_int32_t slot)
5971 {
5972  void *res;
5973 
5974  _dbus_return_val_if_fail (connection != NULL, NULL);
5975 
5976  SLOTS_LOCK (connection);
5977 
5978  res = _dbus_data_slot_list_get (&slot_allocator,
5979  &connection->slot_list,
5980  slot);
5981 
5982  SLOTS_UNLOCK (connection);
5983 
5984  return res;
5985 }
5986 
5993 void
5995 {
5996  _dbus_modify_sigpipe = will_modify_sigpipe != FALSE;
5997 }
5998 
6007 void
6009  long size)
6010 {
6011  _dbus_return_if_fail (connection != NULL);
6012 
6013  CONNECTION_LOCK (connection);
6015  size);
6016  CONNECTION_UNLOCK (connection);
6017 }
6018 
6025 long
6027 {
6028  long res;
6029 
6030  _dbus_return_val_if_fail (connection != NULL, 0);
6031 
6032  CONNECTION_LOCK (connection);
6033  res = _dbus_transport_get_max_message_size (connection->transport);
6034  CONNECTION_UNLOCK (connection);
6035  return res;
6036 }
6037 
6046 void
6048  long n)
6049 {
6050  _dbus_return_if_fail (connection != NULL);
6051 
6052  CONNECTION_LOCK (connection);
6054  n);
6055  CONNECTION_UNLOCK (connection);
6056 }
6057 
6064 long
6066 {
6067  long res;
6068 
6069  _dbus_return_val_if_fail (connection != NULL, 0);
6070 
6071  CONNECTION_LOCK (connection);
6073  CONNECTION_UNLOCK (connection);
6074  return res;
6075 }
6076 
6102 void
6104  long size)
6105 {
6106  _dbus_return_if_fail (connection != NULL);
6107 
6108  CONNECTION_LOCK (connection);
6110  size);
6111  CONNECTION_UNLOCK (connection);
6112 }
6113 
6120 long
6122 {
6123  long res;
6124 
6125  _dbus_return_val_if_fail (connection != NULL, 0);
6126 
6127  CONNECTION_LOCK (connection);
6129  CONNECTION_UNLOCK (connection);
6130  return res;
6131 }
6132 
6144 void
6146  long n)
6147 {
6148  _dbus_return_if_fail (connection != NULL);
6149 
6150  CONNECTION_LOCK (connection);
6152  n);
6153  CONNECTION_UNLOCK (connection);
6154 }
6155 
6162 long
6164 {
6165  long res;
6166 
6167  _dbus_return_val_if_fail (connection != NULL, 0);
6168 
6169  CONNECTION_LOCK (connection);
6171  CONNECTION_UNLOCK (connection);
6172  return res;
6173 }
6174 
6185 long
6187 {
6188  long res;
6189 
6190  _dbus_return_val_if_fail (connection != NULL, 0);
6191 
6192  CONNECTION_LOCK (connection);
6193  res = _dbus_counter_get_size_value (connection->outgoing_counter);
6194  CONNECTION_UNLOCK (connection);
6195  return res;
6196 }
6197 
6205 long
6207 {
6208  long res;
6209 
6210  _dbus_return_val_if_fail (connection != NULL, 0);
6211 
6212  CONNECTION_LOCK (connection);
6214  CONNECTION_UNLOCK (connection);
6215  return res;
6216 }
6217