According to solaris docs:
"One instance of a SIGCHLD signal is queued for each child process whose
status has changed. If waitpid() returns because the status of a child
process is available, and WNOWAIT was not specified in options, any pending
SIGCHLD signal associated with the process ID of that child process is
discarded. Any other pending SIGCHLD signals remain pending."
And interesting thing that it works if you add sleep(1) before waitpid(), and
also if you run with --verbose (some race or what).
But linux doesn't support WNOWAIT in waitpid() so add detection into
cmake/autotools.
Fixes: #387
Link: https://bugzilla.redhat.com/show_bug.cgi?id=840782
#CHECK_FILE_OFFSET_BITS()
#set(EVENT___FILE_OFFSET_BITS _FILE_OFFSET_BITS)
+include(CheckWaitpidSupportWNOWAIT)
+
# Verify kqueue works with pipes.
if (EVENT__HAVE_KQUEUE)
if (CMAKE_CROSSCOMPILING AND NOT EVENT__FORCE_KQUEUE_CHECK)
--- /dev/null
+include(CheckCSourceRuns)
+
+check_c_source_runs(
+"
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdlib.h>
+
+int
+main(int argc, char** argv)
+{
+ pid_t pid;
+ int status;
+ if ((pid = fork()) == 0) _exit(0);
+ _exit(waitpid(pid, &status, WNOWAIT) == -1);
+}"
+EVENT__HAVE_WAITPID_WITH_WNOWAIT)
fi
AM_CONDITIONAL(EPOLL_BACKEND, [test "x$haveepoll" = "xyes"])
+AC_MSG_CHECKING(waitpid support WNOWAIT)
+AC_TRY_RUN(
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdlib.h>
+
+int
+main(int argc, char** argv)
+{
+ pid_t pid;
+ int status;
+ if ((pid = fork()) == 0) _exit(0);
+ _exit(waitpid(pid, &status, WNOWAIT) == -1);
+}, [AC_MSG_RESULT(yes)
+AC_DEFINE(HAVE_WAITPID_WITH_WNOWAIT, 1,
+[Define if waitpid() supports WNOWAIT])
+], AC_MSG_RESULT(no), AC_MSG_RESULT(no))
+
+
haveeventports=no
AC_CHECK_FUNCS(port_create, [haveeventports=yes], )
if test "x$haveeventports" = "xyes" ; then
/* Define to 1 if you have ERR_remove_thread_stat(). */
#cmakedefine EVENT__HAVE_ERR_REMOVE_THREAD_STATE
+/* Define if waitpid() supports WNOWAIT */
+#cmakedefine EVENT__HAVE_WAITPID_WITH_WNOWAIT
+
#endif
int status;
struct event ev, sig_ev, usr_ev, existing_ev;
pid_t pid;
+ int wait_flags = 0;
+
+#ifdef EVENT__HAVE_WAITPID_WITH_WNOWAIT
+ wait_flags |= WNOWAIT;
+#endif
setup_test("After fork: ");
}
TT_BLATHER(("Before waitpid"));
- if (waitpid(pid, &status, 0) == -1) {
- fprintf(stdout, "FAILED (fork)\n");
+ if (waitpid(pid, &status, wait_flags) == -1) {
+ perror("waitpid");
exit(1);
}
TT_BLATHER(("After waitpid"));