summaryrefslogtreecommitdiffstats
path: root/test/name-test/test-threads-init.c
diff options
context:
space:
mode:
authorJohn (J5) Palmieri <johnp@redhat.com>2006-08-16 22:30:15 +0000
committerJohn (J5) Palmieri <johnp@redhat.com>2006-08-16 22:30:15 +0000
commit14cc7d28a8308060428bbc9b3dd357eaea3a4749 (patch)
tree3b2a02f31eb74f3844ad8dcef0fca1d29151a9ed /test/name-test/test-threads-init.c
parent5b5da5297552919578266714fa7abf1e45d1131d (diff)
* dbus/dbus-threads.c: Add static DBusList *uninitialized_mutex_list and
static DBusList *uninitialized_condvar_list to support new late initialization threading model. In this model threads can be initialized even after the D-Bus API has been used but still needs to be initialized before the second thread has been started. Mutexes and condvar addresses are stored in the two static lists and are replaced with actuall locks when threads are initalized. (_dbus_mutex_new_at_location): New method for creating a mutex and placing the location into the static list (_dbus_mutex_free_at_location): New method for removing a mutex location from the static list and freeing the mutex (_dbus_condvar_new_at_location): New method for creating a conditional variable and placing the location into the static list (_dbus_condvar_free_at_location): New method for removing a conditional variable location from the static list and freeing the conditional variable (init_uninitialized_locks): Atomic method which goes through the static lists of mutex and condvar location and updates them with actuall locks (init_global_locks): changed to init_locks * dbus/dbus-connection.c: (_dbus_connection_test_get_locks): New method for tests to check connections (_dbus_connection_new_for_transport): Use the new at_location mutex and condvar API (dbus_connection_allocate_data_slot): Pass in the global lock address to _dbus_data_slot_allocator_alloc * dbus/dbus-dataslot.c: (_dbus_data_slot_allocator_alloc): Use the address of the mutex instead of the mutex itself * dbus/dbus-message.c: (dbus_message_allocate_data_slot): Pass in the global lock address to _dbus_data_slot_allocator_alloc * dbus/dbus-pending-call.c: (dbus_pending_call_allocate_data_slot): Pass in the global lock address to _dbus_data_slot_allocator_alloc * dbus/dbus-server.c: (_dbus_server_init_base): Use the new at_location mutex API (dbus_server_allocate_data_slot): Pass in the global lock address to _dbus_data_slot_allocator_alloc * test/name-test/test-threads-init.c: New test case for late thread initialization
Diffstat (limited to 'test/name-test/test-threads-init.c')
-rw-r--r--test/name-test/test-threads-init.c181
1 files changed, 181 insertions, 0 deletions
diff --git a/test/name-test/test-threads-init.c b/test/name-test/test-threads-init.c
new file mode 100644
index 00000000..e6743cce
--- /dev/null
+++ b/test/name-test/test-threads-init.c
@@ -0,0 +1,181 @@
+/**
+* Test to make sure late thread initialization works
+**/
+
+#include <dbus/dbus.h>
+#include <dbus/dbus-sysdeps.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <dbus/dbus-internals.h>
+
+static void
+_run_iteration (DBusConnection *conn)
+{
+ DBusPendingCall *echo_pending;
+ DBusPendingCall *dbus_pending;
+ DBusMessage *method;
+ DBusMessage *reply;
+ char *echo = "echo";
+
+ /* send the first message */
+ method = dbus_message_new_method_call ("org.freedesktop.DBus.TestSuiteEchoService",
+ "/org/freedesktop/TestSuite",
+ "org.freedesktop.TestSuite",
+ "Echo");
+
+ dbus_message_append_args (method, DBUS_TYPE_STRING, &echo, NULL);
+ dbus_connection_send_with_reply (conn, method, &echo_pending, -1);
+ dbus_message_unref (method);
+
+ /* send the second message */
+ method = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ "org.freedesktop.Introspectable",
+ "Introspect");
+
+ dbus_connection_send_with_reply (conn, method, &dbus_pending, -1);
+ dbus_message_unref (method);
+
+ /* block on the second message (should return immediately) */
+ dbus_pending_call_block (dbus_pending);
+
+ /* block on the first message */
+ /* if it does not return immediately chances
+ are we hit the block in poll bug */
+ dbus_pending_call_block (echo_pending);
+
+ /* check the reply only to make sure we
+ are not getting errors unrelated
+ to the block in poll bug */
+ reply = dbus_pending_call_steal_reply (echo_pending);
+
+ if (reply == NULL)
+ {
+ printf ("Failed: Reply is NULL ***\n");
+ exit (1);
+ }
+
+ if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR)
+ {
+ printf ("Failed: Reply is error: %s ***\n", dbus_message_get_error_name (reply));
+ exit (1);
+ }
+
+ dbus_message_unref (reply);
+ dbus_pending_call_unref (dbus_pending);
+ dbus_pending_call_unref (echo_pending);
+
+}
+static void
+check_mutex_lock (DBusMutex *mutex1,
+ DBusMutex *mutex2,
+ dbus_bool_t is_same)
+{
+ _dbus_assert (mutex1 != NULL);
+ _dbus_assert (mutex2 != NULL);
+
+ if (is_same)
+ {
+ _dbus_assert (mutex1 == mutex2);
+ }
+ else
+ {
+ _dbus_assert (mutex1 != mutex2);
+ }
+}
+
+static void
+check_condvar_lock (DBusCondVar *condvar1,
+ DBusCondVar *condvar2,
+ dbus_bool_t is_same)
+{
+ _dbus_assert (condvar1 != NULL);
+ _dbus_assert (condvar2 != NULL);
+
+ if (is_same)
+ {
+ _dbus_assert (condvar1 == condvar2);
+ }
+ else
+ {
+ _dbus_assert (condvar1 != condvar2);
+ }
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ long start_tv_sec, start_tv_usec;
+ long end_tv_sec, end_tv_usec;
+ int i;
+ DBusMessage *method;
+ DBusConnection *conn;
+ DBusError error;
+ DBusMutex *mutex1, *dispatch_mutex1, *io_path_mutex1;
+ DBusCondVar *dispatch_cond1, *io_path_cond1;
+ DBusMutex *mutex2, *dispatch_mutex2, *io_path_mutex2;
+ DBusCondVar *dispatch_cond2, *io_path_cond2;
+
+ printf ("*** Testing late thread init\n");
+
+ dbus_error_init (&error);
+
+ conn = dbus_bus_get (DBUS_BUS_SESSION, &error);
+
+ _dbus_connection_test_get_locks (conn, &mutex1,
+ &dispatch_mutex1,
+ &io_path_mutex1,
+ &dispatch_cond1,
+ &io_path_cond1);
+ _run_iteration (conn);
+ _dbus_connection_test_get_locks (conn, &mutex2,
+ &dispatch_mutex2,
+ &io_path_mutex2,
+ &dispatch_cond2,
+ &io_path_cond2);
+
+ check_mutex_lock (mutex1, mutex2, TRUE);
+ check_mutex_lock (dispatch_mutex1, dispatch_mutex2, TRUE);
+ check_mutex_lock (io_path_mutex1, io_path_mutex2, TRUE);
+ check_condvar_lock (dispatch_cond1, dispatch_cond2, TRUE);
+ check_condvar_lock (io_path_cond1, io_path_cond2, TRUE);
+
+ _dbus_threads_init_debug ();
+
+ _dbus_connection_test_get_locks (conn, &mutex1,
+ &dispatch_mutex1,
+ &io_path_mutex1,
+ &dispatch_cond1,
+ &io_path_cond1);
+
+ check_mutex_lock (mutex1, mutex2, FALSE);
+ check_mutex_lock (dispatch_mutex1, dispatch_mutex2, FALSE);
+ check_mutex_lock (io_path_mutex1, io_path_mutex2, FALSE);
+ check_condvar_lock (dispatch_cond1, dispatch_cond2, FALSE);
+ check_condvar_lock (io_path_cond1, io_path_cond2, FALSE);
+
+ _run_iteration (conn);
+ _dbus_connection_test_get_locks (conn, &mutex2,
+ &dispatch_mutex2,
+ &io_path_mutex2,
+ &dispatch_cond2,
+ &io_path_cond2);
+
+ check_mutex_lock (mutex1, mutex2, TRUE);
+ check_mutex_lock (dispatch_mutex1, dispatch_mutex2, TRUE);
+ check_mutex_lock (io_path_mutex1, io_path_mutex2, TRUE);
+ check_condvar_lock (dispatch_cond1, dispatch_cond2, TRUE);
+ check_condvar_lock (io_path_cond1, io_path_cond2, TRUE);
+
+ method = dbus_message_new_method_call ("org.freedesktop.TestSuiteEchoService",
+ "/org/freedesktop/TestSuite",
+ "org.freedesktop.TestSuite",
+ "Exit");
+ dbus_connection_send (conn, method, NULL);
+ dbus_message_unref (method);
+
+ printf ("Success ***\n");
+ exit (0);
+}