diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/test-io-stream-common.c | 66 | ||||
-rw-r--r-- | tests/test-io-stream-common.h | 8 |
2 files changed, 61 insertions, 13 deletions
diff --git a/tests/test-io-stream-common.c b/tests/test-io-stream-common.c index b74e9d9..5856d69 100644 --- a/tests/test-io-stream-common.c +++ b/tests/test-io-stream-common.c @@ -45,6 +45,10 @@ #include <unistd.h> #endif +GMutex start_mutex; +GCond start_cond; +gboolean started; + static gboolean timer_cb (gpointer pointer) { g_debug ("test-thread:%s: %p", G_STRFUNC, pointer); @@ -54,6 +58,17 @@ static gboolean timer_cb (gpointer pointer) exit (-1); } +static void +wait_for_start (TestIOStreamThreadData *data) +{ + g_mutex_lock (data->start_mutex); + (*data->start_count)--; + g_cond_broadcast (data->start_cond); + while (*data->start_count > 0) + g_cond_wait (data->start_cond, data->start_mutex); + g_mutex_unlock (data->start_mutex); +} + static gpointer write_thread_cb (gpointer user_data) { @@ -65,7 +80,7 @@ write_thread_cb (gpointer user_data) g_main_context_push_thread_default (main_context); /* Synchronise thread starting. */ - while (!g_main_loop_is_running (data->error_loop)); + wait_for_start (data); /* Wait for the stream to be writeable. */ g_mutex_lock (&data->write_mutex); @@ -94,7 +109,7 @@ read_thread_cb (gpointer user_data) g_main_context_push_thread_default (main_context); /* Synchronise thread starting. */ - while (!g_main_loop_is_running (data->error_loop)); + wait_for_start (data); if (data->reliable) input_stream = g_io_stream_get_input_stream (data->io_stream); @@ -114,7 +129,7 @@ main_thread_cb (gpointer user_data) g_main_context_push_thread_default (data->main_context); /* Synchronise thread starting. */ - while (!g_main_loop_is_running (data->error_loop)); + wait_for_start (data); /* Run the main context. */ g_main_loop_run (data->main_loop); @@ -316,14 +331,6 @@ spawn_thread (const gchar *thread_name, GThreadFunc thread_func, return thread; } -static void -join_main_loop (GMainLoop *main_loop) -{ - while (!g_main_loop_is_running (main_loop)); - while (g_main_loop_is_running (main_loop)) - g_main_loop_quit (main_loop); -} - void run_io_stream_test (guint deadlock_timeout, gboolean reliable, const TestIOStreamCallbacks *callbacks, @@ -334,6 +341,12 @@ run_io_stream_test (guint deadlock_timeout, gboolean reliable, GThread *l_main_thread, *r_main_thread; GThread *l_write_thread, *l_read_thread, *r_write_thread, *r_read_thread; TestIOStreamThreadData l_data, r_data; + GMutex mutex; + GCond cond; + guint start_count = 6; + + g_mutex_init (&mutex); + g_cond_init (&cond); error_loop = g_main_loop_new (NULL, FALSE); @@ -348,6 +361,9 @@ run_io_stream_test (guint deadlock_timeout, gboolean reliable, g_mutex_init (&l_data.write_mutex); l_data.stream_open = FALSE; l_data.stream_ready = FALSE; + l_data.start_mutex = &mutex; + l_data.start_cond = &cond; + l_data.start_count = &start_count; r_data.reliable = reliable; r_data.error_loop = error_loop; @@ -359,6 +375,12 @@ run_io_stream_test (guint deadlock_timeout, gboolean reliable, g_mutex_init (&r_data.write_mutex); r_data.stream_open = FALSE; r_data.stream_ready = FALSE; + r_data.start_mutex = &mutex; + r_data.start_cond = &cond; + r_data.start_count = &start_count; + + l_data.other = &r_data; + r_data.other = &l_data; /* Create the L and R agents. */ l_data.agent = create_agent (TRUE, &l_data, @@ -387,6 +409,11 @@ run_io_stream_test (guint deadlock_timeout, gboolean reliable, l_write_thread = spawn_thread ("libnice L write", write_thread_cb, &l_data); r_write_thread = spawn_thread ("libnice R write", write_thread_cb, &r_data); } else { + g_mutex_lock (&mutex); + start_count -= 2; + g_cond_broadcast (&cond); + g_mutex_unlock (&mutex); + l_write_thread = NULL; r_write_thread = NULL; } @@ -395,8 +422,8 @@ run_io_stream_test (guint deadlock_timeout, gboolean reliable, g_main_loop_run (error_loop); /* Clean up the main loops and threads. */ - join_main_loop (l_data.main_loop); - join_main_loop (r_data.main_loop); + stop_main_loop (l_data.main_loop); + stop_main_loop (r_data.main_loop); g_thread_join (l_read_thread); g_thread_join (r_read_thread); @@ -434,6 +461,9 @@ run_io_stream_test (guint deadlock_timeout, gboolean reliable, g_main_context_unref (l_data.main_context); g_main_loop_unref (error_loop); + + g_mutex_clear (&mutex); + g_cond_clear (&cond); } /* Once we’ve received all the expected bytes, wait to finish sending all bytes, @@ -485,3 +515,13 @@ check_for_termination (TestIOStreamThreadData *data, gsize *recv_count, g_main_loop_quit (data->error_loop); } } + +void +stop_main_loop (GMainLoop *loop) +{ + GSource *src = g_idle_source_new (); + g_source_set_callback (src, (GSourceFunc) g_main_loop_quit, + g_main_loop_ref (loop), (GDestroyNotify) g_main_loop_unref); + g_source_attach (src, g_main_loop_get_context (loop)); + g_source_unref (src); +} diff --git a/tests/test-io-stream-common.h b/tests/test-io-stream-common.h index afc6495..8f7bac1 100644 --- a/tests/test-io-stream-common.h +++ b/tests/test-io-stream-common.h @@ -79,6 +79,8 @@ struct _TestIOStreamThreadData { gpointer user_data; GDestroyNotify user_data_free; + TestIOStreamThreadData *other; + /*< private >*/ const TestIOStreamCallbacks *callbacks; @@ -87,6 +89,10 @@ struct _TestIOStreamThreadData { gboolean stream_ready; GCond write_cond; GMutex write_mutex; + + GMutex *start_mutex; + GCond *start_cond; + guint *start_count; }; GThread *spawn_thread (const gchar *thread_name, GThreadFunc thread_func, @@ -97,3 +103,5 @@ void run_io_stream_test (guint deadlock_timeout, gboolean reliable, gpointer r_user_data, GDestroyNotify r_user_data_free); void check_for_termination (TestIOStreamThreadData *data, gsize *recv_count, gsize *other_recv_count, gsize *send_count, gsize expected_recv_count); + +void stop_main_loop (GMainLoop *loop); |