aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew J. Schorr <aschorr@telemetry-investments.com>2013-07-04 16:26:51 -0400
committerAndrew J. Schorr <aschorr@telemetry-investments.com>2013-07-04 16:26:51 -0400
commitad5c8d1f818c96579fa9e7f3c691739e9761e1e7 (patch)
treee46d7c0d5492318cf7eacd60ae36036fd030f927
parentd8bd9f5261761dd4ffca331d9c6055c48a0a332b (diff)
downloadegawk-ad5c8d1f818c96579fa9e7f3c691739e9761e1e7.tar.gz
egawk-ad5c8d1f818c96579fa9e7f3c691739e9761e1e7.tar.bz2
egawk-ad5c8d1f818c96579fa9e7f3c691739e9761e1e7.zip
Revert incorrect patch to wait_any and instead use waitpid to avoid blocking.
-rw-r--r--ChangeLog10
-rw-r--r--configh.in3
-rwxr-xr-xconfigure2
-rw-r--r--configure.ac2
-rw-r--r--io.c20
5 files changed, 31 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 5d293bf8..a692e5b1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2013-07-04 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * configure.ac (AC_CHECK_FUNCS): Add a check for waitpid.
+ * io.c (wait_any): Enhance comment to explain why we loop reaping all
+ exited children when the argument is zero. When available, use waitpid
+ with WNOHANG to avoid blocking. Remove my previous incorrect patch to
+ exit after reaping the first child. The function is intended to
+ wait for all children, since we are not careful about reaping children
+ as soon as they die.
+
2013-07-02 Andrew J. Schorr <aschorr@telemetry-investments.com>
* gawkapi.h (gawk_api): Remove unused api_lookup_file hook.
diff --git a/configh.in b/configh.in
index f6540a45..68d5bf76 100644
--- a/configh.in
+++ b/configh.in
@@ -296,6 +296,9 @@
/* Define to 1 if you have the `vprintf' function. */
#undef HAVE_VPRINTF
+/* Define to 1 if you have the `waitpid' function. */
+#undef HAVE_WAITPID
+
/* Define to 1 if you have the <wchar.h> header file. */
#undef HAVE_WCHAR_H
diff --git a/configure b/configure
index 0e5a9303..fccfcea0 100755
--- a/configure
+++ b/configure
@@ -10020,7 +10020,7 @@ for ac_func in atexit btowc fmod getgrent getgroups grantpt \
memcmp memcpy memcpy_ulong memmove memset \
memset_ulong mkstemp posix_openpt setenv setlocale setsid snprintf strchr \
strerror strftime strncasecmp strcoll strtod strtoul \
- system tmpfile towlower towupper tzset usleep wcrtomb \
+ system tmpfile towlower towupper tzset usleep waitpid wcrtomb \
wcscoll wctype
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
diff --git a/configure.ac b/configure.ac
index b401cb40..ba242c51 100644
--- a/configure.ac
+++ b/configure.ac
@@ -276,7 +276,7 @@ AC_CHECK_FUNCS(atexit btowc fmod getgrent getgroups grantpt \
memcmp memcpy memcpy_ulong memmove memset \
memset_ulong mkstemp posix_openpt setenv setlocale setsid snprintf strchr \
strerror strftime strncasecmp strcoll strtod strtoul \
- system tmpfile towlower towupper tzset usleep wcrtomb \
+ system tmpfile towlower towupper tzset usleep waitpid wcrtomb \
wcscoll wctype)
dnl this check is for both mbrtowc and the mbstate_t type, which is good
AC_FUNC_MBRTOWC
diff --git a/io.c b/io.c
index 0ba36451..42c92e47 100644
--- a/io.c
+++ b/io.c
@@ -2168,7 +2168,16 @@ use_pipes:
#ifndef PIPES_SIMULATED /* real pipes */
-/* wait_any --- wait for a child process, close associated pipe */
+/*
+ * wait_any --- if the argument pid is 0, wait for all child processes that
+ * have exited. We loop to make sure to reap all children that have exited to
+ * minimize the risk of running out of process slots. Since we don't process
+ * SIGCHLD, we do not immediately reap exited children. So when we get here,
+ * we want to reap any that have piled up.
+ *
+ * Note: on platforms that do not support waitpid with WNOHANG, when called with
+ * a zero argument, this function will hang until all children have exited.
+ */
static int
wait_any(int interesting) /* pid of interest, if any */
@@ -2198,7 +2207,11 @@ wait_any(int interesting) /* pid of interest, if any */
hstat = signal(SIGHUP, SIG_IGN);
qstat = signal(SIGQUIT, SIG_IGN);
for (;;) {
-# ifdef HAVE_SYS_WAIT_H /* POSIX compatible sys/wait.h */
+# if defined(HAVE_WAITPID) && defined(WNOHANG)
+ if ((pid = waitpid(-1, & status, WNOHANG)) == 0)
+ /* No children have exited */
+ break;
+# elif defined(HAVE_SYS_WAIT_H) /* POSIX compatible sys/wait.h */
pid = wait(& status);
# else
pid = wait((union wait *) & status);
@@ -2210,13 +2223,12 @@ wait_any(int interesting) /* pid of interest, if any */
if (pid == redp->pid) {
redp->pid = -1;
redp->status = status;
- goto finished;
+ break;
}
}
if (pid == -1 && errno == ECHILD)
break;
}
-finished:
signal(SIGHUP, hstat);
signal(SIGQUIT, qstat);
#endif