diff options
author | Ryan Lortie <desrt@desrt.ca> | 2011-10-16 19:08:59 -0400 |
---|---|---|
committer | Ryan Lortie <desrt@desrt.ca> | 2011-10-16 19:08:59 -0400 |
commit | a9a1c97904aeed96bcb248e16cb495e6907b7126 (patch) | |
tree | 03dbab0eb0026178138fe591834364ce9db65d9f /gthread | |
parent | fb4e120d88777affc4a8fbeb73312b1e810e2431 (diff) | |
download | glib-a9a1c97904aeed96bcb248e16cb495e6907b7126.tar.gz |
gthread: move test cases to glib/
Diffstat (limited to 'gthread')
-rw-r--r-- | gthread/Makefile.am | 3 | ||||
-rw-r--r-- | gthread/tests/.gitignore | 11 | ||||
-rw-r--r-- | gthread/tests/1bit-mutex.c | 157 | ||||
-rw-r--r-- | gthread/tests/642026.c | 91 | ||||
-rw-r--r-- | gthread/tests/Makefile.am | 52 | ||||
-rw-r--r-- | gthread/tests/gwakeuptest.c | 272 | ||||
-rw-r--r-- | gthread/tests/spawn-multithreaded.c | 236 | ||||
-rw-r--r-- | gthread/tests/spawn-singlethread.c | 190 | ||||
-rw-r--r-- | gthread/tests/test-spawn-echo.c | 39 |
9 files changed, 0 insertions, 1051 deletions
diff --git a/gthread/Makefile.am b/gthread/Makefile.am index 00e62a564..7ff1c5b74 100644 --- a/gthread/Makefile.am +++ b/gthread/Makefile.am @@ -1,9 +1,6 @@ ## Process this file with automake to produce Makefile.in include $(top_srcdir)/Makefile.decl -SUBDIRS = . tests -DIST_SUBDIRS = tests - AM_CPPFLAGS = \ $(glib_INCLUDES) \ -DG_LOG_DOMAIN=\"GThread\" \ diff --git a/gthread/tests/.gitignore b/gthread/tests/.gitignore deleted file mode 100644 index e4e9995ce..000000000 --- a/gthread/tests/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -1bit-emufutex -1bit-mutex -642026 -642026-ec -atomic -gwakeup -gwakeup-fallback -spawn-multithreaded -spawn-singlethread -test-spawn-echo -unix-multithreaded diff --git a/gthread/tests/1bit-mutex.c b/gthread/tests/1bit-mutex.c deleted file mode 100644 index c1ec41c95..000000000 --- a/gthread/tests/1bit-mutex.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright © 2008 Ryan Lortie - * Copyright © 2010 Codethink Limited - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * See the included COPYING file for more information. - */ - -/* LOCKS should be more than the number of contention - * counters in gthread.c in order to ensure we exercise - * the case where they overlap. - */ -#define LOCKS 48 -#define ITERATIONS 10000 -#define THREADS 100 - -#include <glib.h> - -#if TEST_EMULATED_FUTEX - /* this is defined for the 1bit-mutex-emufutex test. - * - * we want to test the emulated futex even if futex(2) is available. - */ - - /* side-step some glib build stuff */ - #define GLIB_COMPILATION - - /* rebuild gbitlock.c without futex support, - defining our own version of the g_bit_*lock symbols - */ - #undef g_pointer_bit_lock - #undef g_pointer_bit_trylock - #undef g_pointer_bit_unlock - - #define g_bit_lock _emufutex_g_bit_lock - #define g_bit_trylock _emufutex_g_bit_trylock - #define g_bit_unlock _emufutex_g_bit_unlock - #define g_pointer_bit_lock _emufutex_g_pointer_bit_lock - #define g_pointer_bit_trylock _emufutex_g_pointer_bit_trylock - #define g_pointer_bit_unlock _emufutex_g_pointer_bit_unlock - - #define G_BIT_LOCK_FORCE_FUTEX_EMULATION - - #include <glib/gbitlock.c> -#endif - -volatile GThread *owners[LOCKS]; -volatile gint locks[LOCKS]; -volatile gpointer ptrs[LOCKS]; -volatile gint bits[LOCKS]; - -static void -acquire (int nr, - gboolean use_pointers) -{ - GThread *self; - - self = g_thread_self (); - - g_assert_cmpint (((gsize) ptrs) % 8, ==, 0); - - if (!(use_pointers ? - g_pointer_bit_trylock (&ptrs[nr], bits[nr]) - : g_bit_trylock (&locks[nr], bits[nr]))) - { - if (g_test_verbose ()) - g_print ("thread %p going to block on lock %d\n", self, nr); - - if (use_pointers) - g_pointer_bit_lock (&ptrs[nr], bits[nr]); - else - g_bit_lock (&locks[nr], bits[nr]); - } - - g_assert (owners[nr] == NULL); /* hopefully nobody else is here */ - owners[nr] = self; - - /* let some other threads try to ruin our day */ - g_thread_yield (); - g_thread_yield (); - g_thread_yield (); - - g_assert (owners[nr] == self); /* hopefully this is still us... */ - owners[nr] = NULL; /* make way for the next guy */ - - if (use_pointers) - g_pointer_bit_unlock (&ptrs[nr], bits[nr]); - else - g_bit_unlock (&locks[nr], bits[nr]); -} - -static gpointer -thread_func (gpointer data) -{ - gboolean use_pointers = GPOINTER_TO_INT (data); - gint i; - GRand *rand; - - rand = g_rand_new (); - - for (i = 0; i < ITERATIONS; i++) - acquire (g_rand_int_range (rand, 0, LOCKS), use_pointers); - - g_rand_free (rand); - - return NULL; -} - -static void -testcase (gconstpointer data) -{ - gboolean use_pointers = GPOINTER_TO_INT (data); - GThread *threads[THREADS]; - int i; - -#ifdef TEST_EMULATED_FUTEX - #define SUFFIX "-emufutex" - - /* ensure that we are using the emulated futex by checking - * (at compile-time) for the existance of 'g_futex_address_list' - */ - g_assert (g_futex_address_list == NULL); -#else - #define SUFFIX "" -#endif - - for (i = 0; i < LOCKS; i++) - bits[i] = g_random_int () % 32; - - for (i = 0; i < THREADS; i++) - threads[i] = g_thread_new ("foo", thread_func, - GINT_TO_POINTER (use_pointers)); - - for (i = 0; i < THREADS; i++) - g_thread_join (threads[i]); - - for (i = 0; i < LOCKS; i++) - { - g_assert (owners[i] == NULL); - g_assert (locks[i] == 0); - } -} - -int -main (int argc, char **argv) -{ - g_test_init (&argc, &argv, NULL); - - g_test_add_data_func ("/glib/1bit-mutex" SUFFIX "/int", (gpointer) 0, testcase); - g_test_add_data_func ("/glib/1bit-mutex" SUFFIX "/pointer", (gpointer) 1, testcase); - - return g_test_run (); -} diff --git a/gthread/tests/642026.c b/gthread/tests/642026.c deleted file mode 100644 index 476468050..000000000 --- a/gthread/tests/642026.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Author: Simon McVittie <simon.mcvittie@collabora.co.uk> - * Copyright © 2011 Nokia Corporation - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * See the included COPYING file for more information. - */ - -#define GLIB_DISABLE_DEPRECATION_WARNINGS - -#include <glib.h> - -/* On smcv's laptop, 1e4 iterations didn't always exhibit the bug, but 1e5 - * iterations exhibited it 10/10 times in practice. YMMV. */ -#define ITERATIONS 100000 - -static GStaticPrivate sp; -static GMutex *mutex; -static GCond *cond; -static guint i; - -static volatile gint freed = 0; - -static void -notify (gpointer p) -{ - if (!g_atomic_int_compare_and_exchange (&freed, 0, 1)) - { - g_error ("someone already freed it after %u iterations", i); - } -} - -static gpointer thread_func (gpointer nil) -{ - /* wait for main thread to reach its g_cond_wait call */ - g_mutex_lock (mutex); - - g_static_private_set (&sp, &sp, notify); - g_cond_broadcast (cond); - g_mutex_unlock (mutex); - - return nil; -} - -void -testcase (void) -{ - g_test_bug ("642026"); - - mutex = g_mutex_new (); - cond = g_cond_new (); - - g_mutex_lock (mutex); - - for (i = 0; i < ITERATIONS; i++) - { - GThread *t1; - - g_static_private_init (&sp); - freed = 0; - - t1 = g_thread_create (thread_func, NULL, TRUE, NULL); - - /* wait for t1 to set up its thread-private data */ - g_cond_wait (cond, mutex); - - /* exercise the bug, by racing with t1 to free the private data */ - g_static_private_free (&sp); - g_thread_join (t1); - } - - g_cond_free (cond); - g_mutex_unlock (mutex); - g_mutex_free (mutex); -} - -int -main (int argc, - char **argv) -{ - g_test_init (&argc, &argv, NULL); - g_test_bug_base ("https://bugzilla.gnome.org/show_bug.cgi?id="); - - g_test_add_func ("/glib/642026", testcase); - - return g_test_run (); -} diff --git a/gthread/tests/Makefile.am b/gthread/tests/Makefile.am deleted file mode 100644 index 7f2229f31..000000000 --- a/gthread/tests/Makefile.am +++ /dev/null @@ -1,52 +0,0 @@ -include $(top_srcdir)/Makefile.decl - -INCLUDES = -g $(gthread_INCLUDES) $(GLIB_DEBUG_FLAGS) - -noinst_PROGRAMS = $(TEST_PROGS) test-spawn-echo -progs_ldadd = $(top_builddir)/glib/libglib-2.0.la \ - $(top_builddir)/gthread/libgthread-2.0.la - -test_spawn_echo_SOURCES = test-spawn-echo.c -test_spawn_echo_LDADD = $(progs_ldadd) - -TEST_PROGS += 1bit-mutex -1bit_mutex_LDADD = $(progs_ldadd) $(top_builddir)/gthread/libgthread-2.0.la - -TEST_PROGS += 642026 -642026_LDADD = $(progs_ldadd) - -TEST_PROGS += 642026-ec -642026_ec_SOURCES = 642026.c -642026_ec_LDADD = $(progs_ldadd) -642026_ec_CFLAGS = -DG_ERRORCHECK_MUTEXES - -TEST_PROGS += 1bit-emufutex -1bit_emufutex_SOURCES = 1bit-mutex.c -1bit_emufutex_CFLAGS = -DTEST_EMULATED_FUTEX -1bit_emufutex_LDADD = $(progs_ldadd) $(top_builddir)/gthread/libgthread-2.0.la - -if OS_UNIX -TEST_PROGS += unix-multithreaded -unix_multithreaded_SOURCES = $(top_srcdir)/glib/tests/unix.c -unix_multithreaded_CFLAGS = -DTEST_THREADED -unix_multithreaded_LDADD = $(progs_ldadd) $(top_builddir)/gthread/libgthread-2.0.la -endif - -TEST_PROGS += spawn-multithreaded -spawn_multithreaded_SOURCES = spawn-multithreaded.c -spawn_multithreaded_LDADD = $(progs_ldadd) $(top_builddir)/gthread/libgthread-2.0.la - -TEST_PROGS += spawn-singlethread -spawn_singlethread_SOURCES = spawn-singlethread.c -spawn_singlethread_LDADD = $(progs_ldadd) $(top_builddir)/gthread/libgthread-2.0.la - -TEST_PROGS += gwakeup -gwakeup_SOURCES = gwakeuptest.c ../../glib/gwakeup.c -gwakeup_LDADD = $(progs_ldadd) $(top_builddir)/gthread/libgthread-2.0.la - -if HAVE_EVENTFD -TEST_PROGS += gwakeup-fallback -gwakeup_fallback_SOURCES = gwakeuptest.c ../../glib/gwakeup.c -gwakeup_fallback_CFLAGS = $(AM_CFLAGS) -DTEST_EVENTFD_FALLBACK -gwakeup_fallback_LDADD = $(progs_ldadd) $(top_builddir)/gthread/libgthread-2.0.la -endif diff --git a/gthread/tests/gwakeuptest.c b/gthread/tests/gwakeuptest.c deleted file mode 100644 index c15dcdc62..000000000 --- a/gthread/tests/gwakeuptest.c +++ /dev/null @@ -1,272 +0,0 @@ -#include <unistd.h> -#include <glib.h> -#include <glib/gwakeup.h> - -#ifdef _WIN32 -void alarm (int sec) { } -#endif - -static gboolean -check_signaled (GWakeup *wakeup) -{ - GPollFD fd; - - g_wakeup_get_pollfd (wakeup, &fd); - return g_poll (&fd, 1, 0); -} - -static void -wait_for_signaled (GWakeup *wakeup) -{ - GPollFD fd; - - g_wakeup_get_pollfd (wakeup, &fd); - g_poll (&fd, 1, -1); -} - -static void -test_semantics (void) -{ - GWakeup *wakeup; - gint i; - - /* prevent the test from deadlocking */ - alarm (30); - - wakeup = g_wakeup_new (); - g_assert (!check_signaled (wakeup)); - - g_wakeup_signal (wakeup); - g_assert (check_signaled (wakeup)); - - g_wakeup_acknowledge (wakeup); - g_assert (!check_signaled (wakeup)); - - g_wakeup_free (wakeup); - - /* free unused */ - wakeup = g_wakeup_new (); - g_wakeup_free (wakeup); - - /* free while signaled */ - wakeup = g_wakeup_new (); - g_wakeup_signal (wakeup); - g_wakeup_free (wakeup); - - /* ensure excessive signalling doesn't deadlock */ - wakeup = g_wakeup_new (); - for (i = 0; i < 1000000; i++) - g_wakeup_signal (wakeup); - g_assert (check_signaled (wakeup)); - - /* ensure a single acknowledgement is sufficient */ - g_wakeup_acknowledge (wakeup); - g_assert (!check_signaled (wakeup)); - - g_wakeup_free (wakeup); - - /* cancel the alarm */ - alarm (0); -} - -struct token -{ - gpointer owner; - gint ttl; -}; - -struct context -{ - GSList *pending_tokens; - GMutex lock; - GWakeup *wakeup; - gboolean quit; -}; - -#define NUM_THREADS 50 -#define NUM_TOKENS 5 -#define TOKEN_TTL 100000 - -static struct context contexts[NUM_THREADS]; -static GThread *threads[NUM_THREADS]; -static GWakeup *last_token_wakeup; -static volatile gint tokens_alive; - -static void -context_init (struct context *ctx) -{ - ctx->pending_tokens = NULL; - g_mutex_init (&ctx->lock); - ctx->wakeup = g_wakeup_new (); - ctx->quit = FALSE; -} - -static void -context_clear (struct context *ctx) -{ - g_assert (ctx->pending_tokens == NULL); - g_assert (ctx->quit); - - g_wakeup_free (ctx->wakeup); -} - -static void -context_quit (struct context *ctx) -{ - ctx->quit = TRUE; - g_wakeup_signal (ctx->wakeup); -} - -static struct token * -context_pop_token (struct context *ctx) -{ - struct token *token; - - g_mutex_lock (&ctx->lock); - token = ctx->pending_tokens->data; - ctx->pending_tokens = g_slist_remove_link (ctx->pending_tokens, - ctx->pending_tokens); - g_mutex_unlock (&ctx->lock); - - return token; -} - -static void -context_push_token (struct context *ctx, - struct token *token) -{ - g_assert (token->owner == ctx); - - g_mutex_lock (&ctx->lock); - ctx->pending_tokens = g_slist_prepend (ctx->pending_tokens, token); - g_mutex_unlock (&ctx->lock); - - g_wakeup_signal (ctx->wakeup); -} - -static void -dispatch_token (struct token *token) -{ - if (token->ttl > 0) - { - struct context *ctx; - gint next_ctx; - - next_ctx = g_test_rand_int_range (0, NUM_THREADS); - ctx = &contexts[next_ctx]; - token->owner = ctx; - token->ttl--; - - context_push_token (ctx, token); - } - else - { - g_slice_free (struct token, token); - - if (g_atomic_int_dec_and_test (&tokens_alive)) - g_wakeup_signal (last_token_wakeup); - } -} - -static struct token * -token_new (int ttl) -{ - struct token *token; - - token = g_slice_new (struct token); - token->ttl = ttl; - - g_atomic_int_inc (&tokens_alive); - - return token; -} - -static gpointer -thread_func (gpointer data) -{ - struct context *ctx = data; - - while (!ctx->quit) - { - wait_for_signaled (ctx->wakeup); - g_wakeup_acknowledge (ctx->wakeup); - - while (ctx->pending_tokens) - { - struct token *token; - - token = context_pop_token (ctx); - g_assert (token->owner == ctx); - dispatch_token (token); - } - } - - return NULL; -} - -static void -test_threaded (void) -{ - gint i; - - /* make sure we don't block forever */ - alarm (30); - - /* simple mainloop test based on GWakeup. - * - * create a bunch of contexts and a thread to 'run' each one. create - * some tokens and randomly pass them between the threads, until the - * TTL on each token is zero. - * - * when no tokens are left, signal that we are done. the mainthread - * will then signal each worker thread to exit and join them to make - * sure that works. - */ - - last_token_wakeup = g_wakeup_new (); - - /* create contexts, assign to threads */ - for (i = 0; i < NUM_THREADS; i++) - { - context_init (&contexts[i]); - threads[i] = g_thread_new ("test", thread_func, &contexts[i]); - } - - /* dispatch tokens */ - for (i = 0; i < NUM_TOKENS; i++) - dispatch_token (token_new (TOKEN_TTL)); - - /* wait until all tokens are gone */ - wait_for_signaled (last_token_wakeup); - - /* ask threads to quit, join them, cleanup */ - for (i = 0; i < NUM_THREADS; i++) - { - context_quit (&contexts[i]); - g_thread_join (threads[i]); - context_clear (&contexts[i]); - } - - g_wakeup_free (last_token_wakeup); - - /* cancel alarm */ - alarm (0); -} - -int -main (int argc, char **argv) -{ - g_test_init (&argc, &argv, NULL); - -#ifdef TEST_EVENTFD_FALLBACK -#define TESTNAME_SUFFIX "-fallback" -#else -#define TESTNAME_SUFFIX -#endif - - - g_test_add_func ("/gwakeup/semantics" TESTNAME_SUFFIX, test_semantics); - g_test_add_func ("/gwakeup/threaded" TESTNAME_SUFFIX, test_threaded); - - return g_test_run (); -} diff --git a/gthread/tests/spawn-multithreaded.c b/gthread/tests/spawn-multithreaded.c deleted file mode 100644 index 534766b2a..000000000 --- a/gthread/tests/spawn-multithreaded.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (C) 2011 Red Hat, Inc. - * - * This work is provided "as is"; redistribution and modification - * in whole or in part, in any medium, physical or electronic is - * permitted without restriction. - * - * This work is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * In no event shall the authors or contributors be liable for any - * direct, indirect, incidental, special, exemplary, or consequential - * damages (including, but not limited to, procurement of substitute - * goods or services; loss of use, data, or profits; or business - * interruption) however caused and on any theory of liability, whether - * in contract, strict liability, or tort (including negligence or - * otherwise) arising in any way out of the use of this software, even - * if advised of the possibility of such damage. - * - * Author: Colin Walters <walters@verbum.org> - */ - -#include "config.h" - -#include <glib.h> -#include <string.h> - -#define N_THREADS (100) - -static char *echo_prog_path; - -static void -multithreaded_test_run (GThreadFunc function) -{ - int i; - GPtrArray *threads = g_ptr_array_new (); - - for (i = 0; i < N_THREADS; i++) - { - GThread *thread; - - thread = g_thread_new ("test", function, GINT_TO_POINTER (i)); - g_ptr_array_add (threads, thread); - } - - for (i = 0; i < N_THREADS; i++) - { - gpointer ret; - ret = g_thread_join (g_ptr_array_index (threads, i)); - g_assert_cmpint (GPOINTER_TO_INT (ret), ==, i); - } - g_ptr_array_free (threads, TRUE); -} - -static gpointer -test_spawn_sync_multithreaded_instance (gpointer data) -{ - int tnum = GPOINTER_TO_INT (data); - GError *error = NULL; - GPtrArray *argv; - char *arg; - char *stdout_str; - int estatus; - - arg = g_strdup_printf ("thread %d", tnum); - - argv = g_ptr_array_new (); - g_ptr_array_add (argv, echo_prog_path); - g_ptr_array_add (argv, arg); - g_ptr_array_add (argv, NULL); - - g_spawn_sync (NULL, (char**)argv->pdata, NULL, 0, NULL, NULL, &stdout_str, NULL, &estatus, &error); - g_assert_no_error (error); - g_assert_cmpstr (arg, ==, stdout_str); - g_free (arg); - g_free (stdout_str); - g_ptr_array_free (argv, TRUE); - - return GINT_TO_POINTER (tnum); -} - -static void -test_spawn_sync_multithreaded (void) -{ - multithreaded_test_run (test_spawn_sync_multithreaded_instance); -} - -typedef struct { - GMainLoop *loop; - gboolean child_exited; - gboolean stdout_done; - GString *stdout_buf; -} SpawnAsyncMultithreadedData; - -static gboolean -on_child_exited (GPid pid, - gint status, - gpointer datap) -{ - SpawnAsyncMultithreadedData *data = datap; - - data->child_exited = TRUE; - if (data->child_exited && data->stdout_done) - g_main_loop_quit (data->loop); - - return FALSE; -} - -static gboolean -on_child_stdout (GIOChannel *channel, - GIOCondition condition, - gpointer datap) -{ - char buf[1024]; - GError *error = NULL; - gsize bytes_read; - GIOStatus status; - SpawnAsyncMultithreadedData *data = datap; - - read: - status = g_io_channel_read_chars (channel, buf, sizeof (buf), &bytes_read, &error); - if (status == G_IO_STATUS_NORMAL) - { - g_string_append_len (data->stdout_buf, buf, (gssize) bytes_read); - if (bytes_read == sizeof (buf)) - goto read; - } - else if (status == G_IO_STATUS_EOF) - { - g_string_append_len (data->stdout_buf, buf, (gssize) bytes_read); - data->stdout_done = TRUE; - } - else if (status == G_IO_STATUS_ERROR) - { - g_error ("Error reading from child stdin: %s", error->message); - } - - if (data->child_exited && data->stdout_done) - g_main_loop_quit (data->loop); - - return !data->stdout_done; -} - -static gpointer -test_spawn_async_multithreaded_instance (gpointer thread_data) -{ - int tnum = GPOINTER_TO_INT (thread_data); - GError *error = NULL; - GPtrArray *argv; - char *arg; - GPid pid; - GMainContext *context; - GMainLoop *loop; - GIOChannel *channel; - GSource *source; - int child_stdout_fd; - SpawnAsyncMultithreadedData data; - - context = g_main_context_new (); - loop = g_main_loop_new (context, TRUE); - - arg = g_strdup_printf ("thread %d", tnum); - - argv = g_ptr_array_new (); - g_ptr_array_add (argv, echo_prog_path); - g_ptr_array_add (argv, arg); - g_ptr_array_add (argv, NULL); - - g_spawn_async_with_pipes (NULL, (char**)argv->pdata, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, NULL, - &child_stdout_fd, NULL, &error); - g_assert_no_error (error); - g_ptr_array_free (argv, TRUE); - - data.loop = loop; - data.stdout_done = FALSE; - data.child_exited = FALSE; - data.stdout_buf = g_string_new (0); - - source = g_child_watch_source_new (pid); - g_source_set_callback (source, (GSourceFunc)on_child_exited, &data, NULL); - g_source_attach (source, context); - g_source_unref (source); - - channel = g_io_channel_unix_new (child_stdout_fd); - source = g_io_create_watch (channel, G_IO_IN | G_IO_HUP); - g_source_set_callback (source, (GSourceFunc)on_child_stdout, &data, NULL); - g_source_attach (source, context); - g_source_unref (source); - - g_main_loop_run (loop); - - g_assert (data.child_exited); - g_assert (data.stdout_done); - g_assert_cmpstr (data.stdout_buf->str, ==, arg); - g_string_free (data.stdout_buf, TRUE); - - g_io_channel_unref (channel); - g_main_context_unref (context); - g_main_loop_unref (loop); - - g_free (arg); - - return GINT_TO_POINTER (tnum); -} - -static void -test_spawn_async_multithreaded (void) -{ - multithreaded_test_run (test_spawn_async_multithreaded_instance); -} - -int -main (int argc, - char *argv[]) -{ - char *dirname; - - g_test_init (&argc, &argv, NULL); - - dirname = g_path_get_dirname (argv[0]); - echo_prog_path = g_build_filename (dirname, "test-spawn-echo", NULL); - if (!g_file_test (echo_prog_path, G_FILE_TEST_EXISTS)) - { - g_free (echo_prog_path); - echo_prog_path = g_build_filename (dirname, "lt-test-spawn-echo", NULL); - } - g_free (dirname); - - g_assert (g_file_test (echo_prog_path, G_FILE_TEST_EXISTS)); - - g_test_add_func ("/gthread/spawn-sync", test_spawn_sync_multithreaded); - g_test_add_func ("/gthread/spawn-async", test_spawn_async_multithreaded); - - return g_test_run(); -} diff --git a/gthread/tests/spawn-singlethread.c b/gthread/tests/spawn-singlethread.c deleted file mode 100644 index f29ecb8ab..000000000 --- a/gthread/tests/spawn-singlethread.c +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (C) 2011 Red Hat, Inc. - * - * This work is provided "as is"; redistribution and modification - * in whole or in part, in any medium, physical or electronic is - * permitted without restriction. - * - * This work is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * In no event shall the authors or contributors be liable for any - * direct, indirect, incidental, special, exemplary, or consequential - * damages (including, but not limited to, procurement of substitute - * goods or services; loss of use, data, or profits; or business - * interruption) however caused and on any theory of liability, whether - * in contract, strict liability, or tort (including negligence or - * otherwise) arising in any way out of the use of this software, even - * if advised of the possibility of such damage. - * - * Author: Colin Walters <walters@verbum.org> - */ - -#include "config.h" - -#include <glib.h> -#include <string.h> - -static char *echo_prog_path; - -typedef struct { - GMainLoop *loop; - gboolean child_exited; - gboolean stdout_done; - GString *stdout_buf; -} SpawnAsyncMultithreadedData; - -static gboolean -on_child_exited (GPid pid, - gint status, - gpointer datap) -{ - SpawnAsyncMultithreadedData *data = datap; - - data->child_exited = TRUE; - if (data->child_exited && data->stdout_done) - g_main_loop_quit (data->loop); - - return FALSE; -} - -static gboolean -on_child_stdout (GIOChannel *channel, - GIOCondition condition, - gpointer datap) -{ - char buf[1024]; - GError *error = NULL; - gsize bytes_read; - SpawnAsyncMultithreadedData *data = datap; - - if (condition & G_IO_IN) - { - GIOStatus status; - status = g_io_channel_read_chars (channel, buf, sizeof (buf), &bytes_read, &error); - g_assert_no_error (error); - g_string_append_len (data->stdout_buf, buf, (gssize) bytes_read); - if (status == G_IO_STATUS_EOF) - data->stdout_done = TRUE; - } - if (condition & G_IO_HUP) - data->stdout_done = TRUE; - if (condition & G_IO_ERR) - g_error ("Error reading from child stdin"); - - if (data->child_exited && data->stdout_done) - g_main_loop_quit (data->loop); - - return !data->stdout_done; -} - -static void -test_spawn_async (void) -{ - int tnum = 1; - GError *error = NULL; - GPtrArray *argv; - char *arg; - GPid pid; - GMainContext *context; - GMainLoop *loop; - GIOChannel *channel; - GSource *source; - int child_stdout_fd; - SpawnAsyncMultithreadedData data; - - context = g_main_context_new (); - loop = g_main_loop_new (context, TRUE); - - arg = g_strdup_printf ("thread %d", tnum); - - argv = g_ptr_array_new (); - g_ptr_array_add (argv, echo_prog_path); - g_ptr_array_add (argv, arg); - g_ptr_array_add (argv, NULL); - - g_spawn_async_with_pipes (NULL, (char**)argv->pdata, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, NULL, - &child_stdout_fd, NULL, &error); - g_assert_no_error (error); - g_ptr_array_free (argv, TRUE); - - data.loop = loop; - data.stdout_done = FALSE; - data.child_exited = FALSE; - data.stdout_buf = g_string_new (0); - - source = g_child_watch_source_new (pid); - g_source_set_callback (source, (GSourceFunc)on_child_exited, &data, NULL); - g_source_attach (source, context); - g_source_unref (source); - - channel = g_io_channel_unix_new (child_stdout_fd); - source = g_io_create_watch (channel, G_IO_IN | G_IO_HUP | G_IO_ERR); - g_source_set_callback (source, (GSourceFunc)on_child_stdout, &data, NULL); - g_source_attach (source, context); - g_source_unref (source); - - g_main_loop_run (loop); - - g_assert (data.child_exited); - g_assert (data.stdout_done); - g_assert_cmpstr (data.stdout_buf->str, ==, arg); - g_string_free (data.stdout_buf, TRUE); - - g_io_channel_unref (channel); - g_main_context_unref (context); - g_main_loop_unref (loop); - - g_free (arg); -} - -static void -test_spawn_sync (void) -{ - int tnum = 1; - GError *error = NULL; - GPtrArray *argv; - char *arg; - char *stdout_str; - int estatus; - - arg = g_strdup_printf ("thread %d", tnum); - - argv = g_ptr_array_new (); - g_ptr_array_add (argv, echo_prog_path); - g_ptr_array_add (argv, arg); - g_ptr_array_add (argv, NULL); - - g_spawn_sync (NULL, (char**)argv->pdata, NULL, 0, NULL, NULL, &stdout_str, NULL, &estatus, &error); - g_assert_no_error (error); - g_assert_cmpstr (arg, ==, stdout_str); - g_free (arg); - g_free (stdout_str); - g_ptr_array_free (argv, TRUE); -} - -int -main (int argc, - char *argv[]) -{ - char *dirname; - - g_test_init (&argc, &argv, NULL); - - dirname = g_path_get_dirname (argv[0]); - echo_prog_path = g_build_filename (dirname, "test-spawn-echo", NULL); - if (!g_file_test (echo_prog_path, G_FILE_TEST_EXISTS)) - { - g_free (echo_prog_path); - echo_prog_path = g_build_filename (dirname, "lt-test-spawn-echo", NULL); - } - g_free (dirname); - - g_assert (g_file_test (echo_prog_path, G_FILE_TEST_EXISTS)); - - g_test_add_func ("/gthread/spawn-single-sync", test_spawn_sync); - g_test_add_func ("/gthread/spawn-single-async", test_spawn_async); - - return g_test_run(); -} diff --git a/gthread/tests/test-spawn-echo.c b/gthread/tests/test-spawn-echo.c deleted file mode 100644 index cb387ba84..000000000 --- a/gthread/tests/test-spawn-echo.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2011 Red Hat, Inc. - * - * This work is provided "as is"; redistribution and modification - * in whole or in part, in any medium, physical or electronic is - * permitted without restriction. - * - * This work is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * In no event shall the authors or contributors be liable for any - * direct, indirect, incidental, special, exemplary, or consequential - * damages (including, but not limited to, procurement of substitute - * goods or services; loss of use, data, or profits; or business - * interruption) however caused and on any theory of liability, whether - * in contract, strict liability, or tort (including negligence or - * otherwise) arising in any way out of the use of this software, even - * if advised of the possibility of such damage. - * - * Author: Colin Walters <walters@verbum.org> - */ - -#include "config.h" - -#include "glib.h" - -int -main (int argc, - char *argv[]) -{ - int i; - for (i = 1; i < argc; i++) - { - g_print ("%s", argv[i]); - } - - return 0; -} |