#include <glib.h>

static gint p = 0;

/* notify main() when mainloop has started */
static gboolean
started (gpointer user_data)
{
  g_print ("main loop started\n");
  g_atomic_int_set (&p, 1);
  return FALSE;
}

static gboolean
do_quit (GMainLoop * loop)
{
  g_main_loop_quit (loop);
  return FALSE;
}

static gpointer
do_loop (gpointer loop)
{
  g_main_loop_run (loop);
  return NULL;
}

static gpointer
dummy (gpointer user_data)
{
  g_print ("unreffing main loop            1\n");
  g_main_loop_unref (user_data);
  return NULL;
}

int main ()
{
  GSource *source;
  GMainLoop *loop;
  GThread *thread;
  GMainContext *context;

  context = g_main_context_new ();
  loop = g_main_loop_new (context, FALSE);
  g_main_context_unref (context);

  thread = g_thread_new (NULL, do_loop, loop);
  g_assert (thread != NULL);

  /* wait for main loop to start */
  source = g_idle_source_new ();
  g_source_set_callback (source, (GSourceFunc) started, NULL, NULL);
  g_source_attach (source, context);
  g_source_unref (source);
  while (!g_atomic_int_get (&p));
  /* main loop has started, do the test now */

  source = g_idle_source_new ();
  g_source_set_callback (source, (GSourceFunc) do_quit, loop,
      (GDestroyNotify) dummy);
  g_source_attach (source, context);
  g_source_unref (source); /* g_source_unref_internal() locks context mutex
                            * but context might be freed already from
                            * g_main_loop_unref() */
  g_print ("source unreffed               2\n");

  g_assert (g_thread_join (thread) == NULL);
  g_print ("we are now done!\n");

  return 0;
}
