diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2012-11-23 14:20:31 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2012-11-23 14:20:31 -0800 |
commit | 6d4e8f62e93b575a1da2cd2b4abeb9dce56e1e52 (patch) | |
tree | 2d3564ca26405db0e887bea037dcc175d85cc753 /src/process.h | |
parent | 002c019c34eeb1cad4ce8f5ae721b1cdf22f0946 (diff) | |
download | emacs-6d4e8f62e93b575a1da2cd2b4abeb9dce56e1e52.tar.gz |
Fix a race condition with glib (Bug#8855).
This is a backport from the trunk, consisting of:
2012-11-17 Eli Zaretskii <eliz@gnu.org>
* nt/inc/sys/wait.h: New file, with prototype of waitpid and
definitions of macros it needs.
* nt/inc/ms-w32.h (wait): Don't define, 'wait' is not used anymore.
(sys_wait): Remove prototype.
* nt/config.nt (HAVE_SYS_WAIT_H): Define to 1.
* src/w32proc.c (create_child): Don't clip the PID of the child
process to fit into an Emacs integer, as this is no longer a
restriction.
(waitpid): Rename from sys_wait. Emulate a Posix 'waitpid' by
reaping only the process specified by PID argument, if that is
positive. Use PID instead of dead_child to know which process to
reap. Wait for the child to die only if WNOHANG is not in
OPTIONS.
(sys_select): Don't set dead_child.
* src/sysdep.c (wait_for_termination_1): Remove the WINDOWSNT portion,
as it is no longer needed.
* src/process.c (waitpid, WUNTRACED) [!WNOHANG]: Remove definitions,
no longer needed.
(record_child_status_change): Remove the setting of
record_at_most_one_child for the !WNOHANG case.
2012-11-03 Paul Eggert <eggert@cs.ucla.edu>
Fix a race condition that causes Emacs to mess up glib (Bug#8855).
This is a backport from the trunk.
The symptom is a diagnostic "GLib-WARNING **: In call to
g_spawn_sync(), exit status of a child process was requested but
SIGCHLD action was set to SIG_IGN and ECHILD was received by
waitpid(), so exit status can't be returned." The diagnostic
is partly wrong, as the SIGCHLD action is not set to SIG_IGN.
The real bug is a race condition between Emacs and glib: Emacs
does a waitpid (-1, ...) and reaps glib's subprocess by mistake,
so that glib can't find it. Work around the bug by invoking
waitpid only on subprocesses that Emacs itself creates.
* src/process.c (create_process, record_child_status_change):
Don't use special value -1 in pid field, as the caller now must
know the pid rather than having the callee infer it. The
inference was sometimes incorrect anyway, due to another race.
(create_process): Set new 'alive' member if child is created.
(process_status_retrieved): New function.
(record_child_status_change): Use it.
Accept negative 1st argument, which means to wait for the
processes that Emacs already knows about. Move special-case code
for DOS_NT (which lacks WNOHANG) here, from caller. Keep track of
processes that have already been waited for, by testing and
clearing new 'alive' member.
(CAN_HANDLE_MULTIPLE_CHILDREN): Remove, as record_child_status_change
now does this internally.
(handle_child_signal): Let record_child_status_change do all
the work, since we do not want to reap all exited child processes,
only the child processes that Emacs itself created.
* src/process.h (Lisp_Process): New boolean member 'alive'.
Diffstat (limited to 'src/process.h')
-rw-r--r-- | src/process.h | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/src/process.h b/src/process.h index ce3d2e702cc..74d1a124060 100644 --- a/src/process.h +++ b/src/process.h @@ -142,6 +142,9 @@ struct Lisp_Process /* Flag to set coding-system of the process buffer from the coding_system used to decode process output. */ unsigned int inherit_coding_system_flag : 1; + /* Whether the process is alive, i.e., can be waited for. Running + processes can be waited for, but exited and fake processes cannot. */ + unsigned int alive : 1; /* Record the process status in the raw form in which it comes from `wait'. This is to avoid consing in a signal handler. The `raw_status_new' flag indicates that `raw_status' contains a new status that still |