diff options
| author | Paul Eggert | 2012-11-23 14:20:31 -0800 |
|---|---|---|
| committer | Paul Eggert | 2012-11-23 14:20:31 -0800 |
| commit | 6d4e8f62e93b575a1da2cd2b4abeb9dce56e1e52 (patch) | |
| tree | 2d3564ca26405db0e887bea037dcc175d85cc753 /nt | |
| parent | 002c019c34eeb1cad4ce8f5ae721b1cdf22f0946 (diff) | |
| download | emacs-6d4e8f62e93b575a1da2cd2b4abeb9dce56e1e52.tar.gz emacs-6d4e8f62e93b575a1da2cd2b4abeb9dce56e1e52.zip | |
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 'nt')
| -rw-r--r-- | nt/ChangeLog | 13 | ||||
| -rw-r--r-- | nt/config.nt | 2 | ||||
| -rw-r--r-- | nt/inc/ms-w32.h | 3 | ||||
| -rw-r--r-- | nt/inc/sys/wait.h | 33 |
4 files changed, 47 insertions, 4 deletions
diff --git a/nt/ChangeLog b/nt/ChangeLog index f11f1fc5fc5..b4537de0d4f 100644 --- a/nt/ChangeLog +++ b/nt/ChangeLog | |||
| @@ -1,3 +1,16 @@ | |||
| 1 | 2012-11-23 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | Fix a race condition with glib (Bug#8855). | ||
| 4 | This is a backport from the trunk, consisting of: | ||
| 5 | |||
| 6 | 2012-11-17 Eli Zaretskii <eliz@gnu.org> | ||
| 7 | |||
| 8 | * inc/sys/wait.h: New file, with prototype of waitpid and | ||
| 9 | definitions of macros it needs. | ||
| 10 | * inc/ms-w32.h (wait): Don't define, 'wait' is not used anymore. | ||
| 11 | (sys_wait): Remove prototype. | ||
| 12 | * config.nt (HAVE_SYS_WAIT_H): Define to 1. | ||
| 13 | |||
| 1 | 2012-11-20 Eli Zaretskii <eliz@gnu.org> | 14 | 2012-11-20 Eli Zaretskii <eliz@gnu.org> |
| 2 | 15 | ||
| 3 | * nmake.defs: Use !if, not !ifdef. See | 16 | * nmake.defs: Use !if, not !ifdef. See |
diff --git a/nt/config.nt b/nt/config.nt index ed1cddf1e12..7e82283b41a 100644 --- a/nt/config.nt +++ b/nt/config.nt | |||
| @@ -963,7 +963,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 963 | #undef HAVE_SYS_VLIMIT_H | 963 | #undef HAVE_SYS_VLIMIT_H |
| 964 | 964 | ||
| 965 | /* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */ | 965 | /* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */ |
| 966 | #undef HAVE_SYS_WAIT_H | 966 | #define HAVE_SYS_WAIT_H 1 |
| 967 | 967 | ||
| 968 | /* Define to 1 if you have the <term.h> header file. */ | 968 | /* Define to 1 if you have the <term.h> header file. */ |
| 969 | #undef HAVE_TERM_H | 969 | #undef HAVE_TERM_H |
diff --git a/nt/inc/ms-w32.h b/nt/inc/ms-w32.h index dd2ae781cb8..a9a3049f9b0 100644 --- a/nt/inc/ms-w32.h +++ b/nt/inc/ms-w32.h | |||
| @@ -185,15 +185,12 @@ extern char *getenv (); | |||
| 185 | 185 | ||
| 186 | /* Subprocess calls that are emulated. */ | 186 | /* Subprocess calls that are emulated. */ |
| 187 | #define spawnve sys_spawnve | 187 | #define spawnve sys_spawnve |
| 188 | #define wait sys_wait | ||
| 189 | #define kill sys_kill | 188 | #define kill sys_kill |
| 190 | #define signal sys_signal | 189 | #define signal sys_signal |
| 191 | 190 | ||
| 192 | /* Internal signals. */ | 191 | /* Internal signals. */ |
| 193 | #define emacs_raise(sig) emacs_abort() | 192 | #define emacs_raise(sig) emacs_abort() |
| 194 | 193 | ||
| 195 | extern int sys_wait (int *); | ||
| 196 | |||
| 197 | /* termcap.c calls that are emulated. */ | 194 | /* termcap.c calls that are emulated. */ |
| 198 | #define tputs sys_tputs | 195 | #define tputs sys_tputs |
| 199 | #define tgetstr sys_tgetstr | 196 | #define tgetstr sys_tgetstr |
diff --git a/nt/inc/sys/wait.h b/nt/inc/sys/wait.h new file mode 100644 index 00000000000..8d890c9e175 --- /dev/null +++ b/nt/inc/sys/wait.h | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | /* A limited emulation of sys/wait.h on Posix systems. | ||
| 2 | |||
| 3 | Copyright (C) 2012 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | This file is part of GNU Emacs. | ||
| 6 | |||
| 7 | GNU Emacs is free software: you can redistribute it and/or modify | ||
| 8 | it under the terms of the GNU General Public License as published by | ||
| 9 | the Free Software Foundation, either version 3 of the License, or | ||
| 10 | (at your option) any later version. | ||
| 11 | |||
| 12 | GNU Emacs is distributed in the hope that it will be useful, | ||
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | GNU General Public License for more details. | ||
| 16 | |||
| 17 | You should have received a copy of the GNU General Public License | ||
| 18 | along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | ||
| 19 | |||
| 20 | #ifndef INC_SYS_WAIT_H_ | ||
| 21 | #define INC_SYS_WAIT_H_ | ||
| 22 | |||
| 23 | #define WNOHANG 1 | ||
| 24 | #define WUNTRACED 2 | ||
| 25 | #define WSTOPPED 2 /* same as WUNTRACED */ | ||
| 26 | #define WEXITED 4 | ||
| 27 | #define WCONTINUED 8 | ||
| 28 | |||
| 29 | /* The various WIF* macros are defined in src/syswait.h. */ | ||
| 30 | |||
| 31 | extern pid_t waitpid (pid_t, int *, int); | ||
| 32 | |||
| 33 | #endif /* INC_SYS_WAIT_H_ */ | ||