#include <glib.h>

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 GStaticPrivate sp;

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;
}

int
main (void)
{
	g_thread_init (NULL);

	mutex = g_mutex_new ();
	cond = g_cond_new ();

	g_mutex_lock (mutex);

	for (i = 0; i < 100000; 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);

		g_static_private_free (&sp);
		g_thread_join (t1);
	}

	g_cond_free (cond);
	g_mutex_unlock (mutex);
	g_mutex_free (mutex);
	return 0;
}
