From 158a0366be6ea2af574f13208068104adb7ea2e7 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 23 Sep 2011 21:10:40 -0400 Subject: [PATCH] Add GOnce tests --- glib/tests/Makefile.am | 3 ++ glib/tests/once.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 glib/tests/once.c diff --git a/glib/tests/Makefile.am b/glib/tests/Makefile.am index 6a9ca57..7fe68e5 100644 --- a/glib/tests/Makefile.am +++ b/glib/tests/Makefile.am @@ -209,6 +209,9 @@ rec_mutex_LDADD = $(progs_ldadd) TEST_PROGS += rwlock rwlock_LDADD = $(progs_ldadd) +TEST_PROGS += once +once_LDADD = $(progs_ldadd) + # some testing of gtester funcitonality XMLLINT=xmllint gtester-xmllint-check: # check testreport xml with xmllint if present diff --git a/glib/tests/once.c b/glib/tests/once.c new file mode 100644 index 0000000..588754c --- /dev/null +++ b/glib/tests/once.c @@ -0,0 +1,125 @@ + +/* Unit tests for GOnce and friends + * Copyright (C) 2011 Red Hat, Inc + * Author: Matthias Clasen + * + * 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. + */ + +#include + +static gpointer +do_once (gpointer data) +{ + static gint i = 0; + + i++; + + return GINT_TO_POINTER (i); +} + +static void +test_once1 (void) +{ + GOnce once = G_ONCE_INIT; + gpointer res; + + g_assert (once.status == G_ONCE_STATUS_NOTCALLED); + + res = g_once (&once, do_once, NULL); + g_assert_cmpint (GPOINTER_TO_INT (res), ==, 1); + + g_assert (once.status == G_ONCE_STATUS_READY); + + res = g_once (&once, do_once, NULL); + g_assert_cmpint (GPOINTER_TO_INT (res), ==, 1); +} + +static void +test_once2 (void) +{ + static gsize init = 0; + + if (g_once_init_enter (&init)) + { + g_assert (TRUE); + g_once_init_leave (&init, 1); + } + + g_assert_cmpint (init, ==, 1); + if (g_once_init_enter (&init)) + { + g_assert_not_reached (); + g_once_init_leave (&init, 2); + } + g_assert_cmpint (init, ==, 1); +} + +#define THREADS 100 + +static gint64 shared; + +static void +init_shared (void) +{ + static gsize init = 0; + + if (g_once_init_enter (&init)) + { + shared += 42; + + g_once_init_leave (&init, 1); + } +} + +static gpointer +thread_func (gpointer data) +{ + init_shared (); + + return NULL; +} + +static void +test_once3 (void) +{ + gint i; + GThread *threads[THREADS]; + + shared = 0; + + for (i = 0; i < THREADS; i++) + threads[i] = g_thread_create (thread_func, NULL, TRUE, NULL); + + for (i = 0; i < THREADS; i++) + g_thread_join (threads[i]); + + g_assert_cmpint (shared, ==, 42); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/thread/once1", test_once1); + g_test_add_func ("/thread/once2", test_once2); + g_test_add_func ("/thread/once3", test_once3); + + return g_test_run (); +} -- 2.7.4