]> granicus.if.org Git - libevent/commitdiff
tests: use waitpid(..., WNOWAIT) to fix failing of main/fork under solaris
authorAzat Khuzhin <a3at.mail@gmail.com>
Thu, 11 Aug 2016 13:15:45 +0000 (16:15 +0300)
committerAzat Khuzhin <a3at.mail@gmail.com>
Thu, 11 Aug 2016 14:08:35 +0000 (17:08 +0300)
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
CMakeLists.txt
cmake/CheckWaitpidSupportWNOWAIT.cmake [new file with mode: 0644]
configure.ac
event-config.h.cmake
test/regress.c

index 81d3ce1492aa676c1d343a10f81e7b6bca1172ef..0323be13b0a893e4889e4a95c5103171dc8aa90c 100644 (file)
@@ -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 (file)
index 0000000..1a73db3
--- /dev/null
@@ -0,0 +1,18 @@
+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)
index 315d97a5469d3df1d875fbc998c4262e104e5bfd..0c41de652ca4d6500487e999b0c48df392095a89 100644 (file)
@@ -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 <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
index b47a7c4c29c95ad1cd6cf5603d388ba18eeb33a4..6a322a69468ccda5a69cc7ead7ac73fbed84b054 100644 (file)
 /* 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
index 8879d1610a6df00fbcc00a1d5f091f182fcbbc6f..6b6ca9f40006ca2100c9cef2b45bbfcbd53c0fd6 100644 (file)
@@ -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"));