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