/* handle GChildWatchSource instances */
if (unix_signal_pending[SIGCHLD])
{
- unix_signal_pending[SIGCHLD] = FALSE;
-
/* The only way we can do this is to scan all of the children.
*
* The docs promise that we will not reap children that we are not
{
if (unix_signal_pending[source->signum])
{
- unix_signal_pending[source->signum] = FALSE;
source->pending = TRUE;
wake_source ((GSource *) source);
}
}
+ memset ((void*)unix_signal_pending, 0, sizeof (unix_signal_pending));
+
G_UNLOCK(unix_signal_lock);
}
unix_signal_watches = g_slist_prepend (unix_signal_watches, unix_signal_source);
if (unix_signal_pending[signum])
unix_signal_source->pending = TRUE;
- unix_signal_pending[signum] = FALSE;
G_UNLOCK (unix_signal_lock);
return source;
}
static gboolean sig_received = FALSE;
+static int sig_counter = 0;
static gboolean
on_sig_received (gpointer user_data)
GMainLoop *loop = user_data;
g_main_loop_quit (loop);
sig_received = TRUE;
+ sig_counter ++;
return G_SOURCE_REMOVE;
}
return G_SOURCE_REMOVE;
}
+static gboolean
+on_sig_received_2 (gpointer data)
+{
+ GMainLoop *loop = data;
+
+ sig_counter ++;
+ if (sig_counter == 2)
+ g_main_loop_quit (loop);
+ return G_SOURCE_REMOVE;
+}
+
static void
test_signal (int signum)
{
mainloop = g_main_loop_new (NULL, FALSE);
sig_received = FALSE;
+ sig_counter = 0;
g_unix_signal_add (signum, on_sig_received, mainloop);
kill (getpid (), signum);
g_assert (!sig_received);
g_timeout_add (500, exit_mainloop, mainloop);
g_main_loop_run (mainloop);
g_assert (!sig_received);
- g_main_loop_unref (mainloop);
+ /* Ensure that two sources for the same signal get it */
+ sig_counter = 0;
+ g_unix_signal_add (signum, on_sig_received_2, mainloop);
+ g_unix_signal_add (signum, on_sig_received_2, mainloop);
+ id = g_timeout_add (500, sig_not_received, mainloop);
+
+ kill (getpid (), signum);
+ g_main_loop_run (mainloop);
+ g_assert_cmpint (sig_counter, ==, 2);
+ g_source_remove (id);
+
+ g_main_loop_unref (mainloop);
}
static void
}
+static gboolean
+nested_idle (gpointer data)
+{
+ GMainLoop *parent, *nested;
+ GMainContext *context;
+ GSource *source;
+
+ context = g_main_context_new ();
+ nested = g_main_loop_new (context, FALSE);
+
+ source = g_unix_signal_source_new (SIGHUP);
+ g_source_set_callback (source, on_sig_received, nested, NULL);
+ g_source_attach (source, context);
+
+ kill (getpid (), SIGHUP);
+ g_main_loop_run (nested);
+ g_assert_cmpint (sig_counter, ==, 1);
+
+ g_main_loop_unref (nested);
+ g_main_context_unref (context);
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+test_sighup_nested (void)
+{
+ GMainLoop *mainloop;
+
+ mainloop = g_main_loop_new (NULL, FALSE);
+
+ sig_counter = 0;
+ sig_received = FALSE;
+ g_unix_signal_add (SIGHUP, on_sig_received, mainloop);
+ g_idle_add (nested_idle, mainloop);
+
+ g_main_loop_run (mainloop);
+ g_assert_cmpint (sig_counter, ==, 2);
+
+ g_main_loop_unref (mainloop);
+}
+
int
main (int argc,
char *argv[])
g_test_add_func ("/glib-unix/sigterm", test_sigterm);
g_test_add_func ("/glib-unix/sighup_again", test_sighup);
g_test_add_func ("/glib-unix/sighup_add_remove", test_sighup_add_remove);
+ g_test_add_func ("/glib-unix/sighup_nested", test_sighup_nested);
return g_test_run();
}