glib/glib/tests/642026.c
Philip Withnall 26409f19cd Add SPDX license headers for LGPL-2.1-or-later to various files
These have all been added manually, as I’ve finished all the files which
I can automatically detect.

All the license headers in this commit are for LGPL-2.1-or-later, and
all have been double-checked against the license paragraph in the file
header.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Helps: #1415
2022-06-01 12:44:23 +01:00

105 lines
2.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Author: Simon McVittie <simon.mcvittie@collabora.co.uk>
* Copyright © 2011 Nokia Corporation
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* 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.1 of the License, or (at your option) any later version.
*
* See the included COPYING file for more information.
*/
#ifndef GLIB_DISABLE_DEPRECATION_WARNINGS
#define GLIB_DISABLE_DEPRECATION_WARNINGS
#endif
#include <glib.h>
static GStaticPrivate sp;
static GMutex *mutex;
static GCond *cond;
static guint i;
static gint freed = 0; /* (atomic) */
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;
}
static void
testcase (void)
{
/* On smcv's laptop, 1e4 iterations didn't always exhibit the bug, but 1e5
* iterations exhibited it 10/10 times in practice. YMMV.
*
* If running with `-m slow` we want to try hard to reproduce the bug 10/10
* times. However, as of 2022 this takes around 240s on a CI machine, which
* is a long time to tie up those resources to verify that a bug fixed 10
* years ago is still fixed.
*
* So if running without `-m slow`, try 100× less hard to reproduce the bug,
* and rely on the fact that this is run under CI often enough to have a good
* chance of reproducing the bug in 1% of CI runs. */
const guint n_iterations = g_test_slow () ? 100000 : 1000;
g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=642026");
mutex = g_mutex_new ();
cond = g_cond_new ();
g_mutex_lock (mutex);
for (i = 0; i < n_iterations; i++)
{
GThread *t1;
g_static_private_init (&sp);
g_atomic_int_set (&freed, 0);
t1 = g_thread_create (thread_func, NULL, TRUE, NULL);
g_assert (t1 != 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_add_func ("/glib/642026", testcase);
return g_test_run ();
}