From: Azat Khuzhin Date: Thu, 11 Aug 2016 13:15:45 +0000 (+0300) Subject: tests: use waitpid(..., WNOWAIT) to fix failing of main/fork under solaris X-Git-Tag: release-2.1.6-beta~4 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=43eb56c7c738e3642f0981e3dd6ab9e082eec798;p=libevent tests: use waitpid(..., WNOWAIT) to fix failing of main/fork under solaris 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 --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 81d3ce14..0323be13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -486,6 +486,8 @@ CHECK_TYPE_SIZE("void *" EVENT__SIZEOF_VOID_P) #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) diff --git a/cmake/CheckWaitpidSupportWNOWAIT.cmake b/cmake/CheckWaitpidSupportWNOWAIT.cmake new file mode 100644 index 00000000..1a73db37 --- /dev/null +++ b/cmake/CheckWaitpidSupportWNOWAIT.cmake @@ -0,0 +1,18 @@ +include(CheckCSourceRuns) + +check_c_source_runs( +" +#include +#include +#include +#include + +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) diff --git a/configure.ac b/configure.ac index 315d97a5..0c41de65 100644 --- a/configure.ac +++ b/configure.ac @@ -605,6 +605,26 @@ main(int argc, char **argv) fi AM_CONDITIONAL(EPOLL_BACKEND, [test "x$haveepoll" = "xyes"]) +AC_MSG_CHECKING(waitpid support WNOWAIT) +AC_TRY_RUN( +#include +#include +#include +#include + +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 diff --git a/event-config.h.cmake b/event-config.h.cmake index b47a7c4c..6a322a69 100644 --- a/event-config.h.cmake +++ b/event-config.h.cmake @@ -535,4 +535,7 @@ /* 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 diff --git a/test/regress.c b/test/regress.c index 8879d161..6b6ca9f4 100644 --- a/test/regress.c +++ b/test/regress.c @@ -855,6 +855,11 @@ test_fork(void) 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: "); @@ -929,8 +934,8 @@ test_fork(void) } 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"));