mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-07-22 09:57:52 +02:00
Merge waitpid() from g_spawn_sync into gmain()
This is preparatory work for a future commit which will add a "catchall" waitpid API. If we don't synchronize here with the worker thread, race conditions are possible. This also ensures we have an error message if someone adds a child watch for a nonexistent pid, etc. Previously, we'd simply keep calling waitpid() getting ECHILD, and ignoring it until the source was removed. Now, we g_warning() and fire the source. Thirdly, this ensures that the waitpid() call in gmain handles EINTR, like the g_spawn_sync() one did. https://bugzilla.gnome.org/show_bug.cgi?id=687061
This commit is contained in:
20
glib/gmain.c
20
glib/gmain.c
@@ -4421,12 +4421,24 @@ dispatch_unix_signals (void)
|
||||
|
||||
if (!source->child_exited)
|
||||
{
|
||||
if (waitpid (source->pid, &source->child_status, WNOHANG) > 0)
|
||||
pid_t pid;
|
||||
do
|
||||
{
|
||||
source->child_exited = TRUE;
|
||||
|
||||
wake_source ((GSource *) source);
|
||||
pid = waitpid (source->pid, &source->child_status, WNOHANG);
|
||||
if (pid > 0)
|
||||
{
|
||||
source->child_exited = TRUE;
|
||||
wake_source ((GSource *) source);
|
||||
}
|
||||
else if (pid == -1 && errno == ECHILD)
|
||||
{
|
||||
g_warning ("GChildWatchSource: Exit status of a child process was requested but ECHILD was received by waitpid(). Most likely the process is ignoring SIGCHLD, or some other thread is invoking waitpid() with a nonpositive first argument; either behavior can break applications that use g_child_watch_add()/g_spawn_sync() either directly or indirectly.");
|
||||
source->child_exited = TRUE;
|
||||
source->child_status = 0;
|
||||
wake_source ((GSource *) source);
|
||||
}
|
||||
}
|
||||
while (pid == -1 && errno == EINTR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user