You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by yl...@apache.org on 2023/04/21 17:49:59 UTC

svn commit: r1909334 - in /apr/apr/branches/1.8.x: ./ configure.in poll/os2/poll.c poll/os2/pollset.c poll/unix/epoll.c poll/unix/poll.c poll/unix/z_asio.c support/unix/waitio.c test/testpoll.c

Author: ylavic
Date: Fri Apr 21 17:49:59 2023
New Revision: 1909334

URL: http://svn.apache.org/viewvc?rev=1909334&view=rev
Log:
poll: Round up milliseconds timeouts.

When converting appr_interval_time_t (usecs) to system call's msecs, round up.
apr_*poll() calls should wait *at least* the given timeout, not less.


poll: Follow up to r1902236: Fix poll() sleeps cases.

Don't convert timeout to milliseconds before potentially callig apr_sleep().

Tests for "poll() didn't sleep" now use the real timeout as lower limit.


tests: check whether epoll_wait() timeout is reliable and adjust justsleep().

* configure.in:
  Small epoll_wait() loop to check timeout reliability and set
  HAVE_EPOLL_WAIT_RELIABLE_TIMEOUT.

* test/testpoll.c(justsleep):
  Allow some jiffy is !HAVE_EPOLL_WAIT_RELIABLE_TIMEOUT.


tests: Follow up to r1908616: Simplify epoll_wait() check.


Merges r1902236, r1902258, r1908616, r1908618 from trunk.
Submitted by: ylavic

Modified:
    apr/apr/branches/1.8.x/   (props changed)
    apr/apr/branches/1.8.x/configure.in
    apr/apr/branches/1.8.x/poll/os2/poll.c
    apr/apr/branches/1.8.x/poll/os2/pollset.c
    apr/apr/branches/1.8.x/poll/unix/epoll.c
    apr/apr/branches/1.8.x/poll/unix/poll.c
    apr/apr/branches/1.8.x/poll/unix/z_asio.c
    apr/apr/branches/1.8.x/support/unix/waitio.c
    apr/apr/branches/1.8.x/test/testpoll.c

Propchange: apr/apr/branches/1.8.x/
------------------------------------------------------------------------------
  Merged /apr/apr/trunk:r1902236,1902258,1908616,1908618

Modified: apr/apr/branches/1.8.x/configure.in
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.8.x/configure.in?rev=1909334&r1=1909333&r2=1909334&view=diff
==============================================================================
--- apr/apr/branches/1.8.x/configure.in (original)
+++ apr/apr/branches/1.8.x/configure.in Fri Apr 21 17:49:59 2023
@@ -1055,7 +1055,7 @@ AC_CACHE_CHECK([for epoll support], [apr
 #include <sys/epoll.h>
 #include <unistd.h>
 
-int main()
+int main(int argc, const char *argv[])
 {
     return epoll_create(5) == -1;
 }], [apr_cv_epoll=yes], [apr_cv_epoll=no], [apr_cv_epoll=no])])
@@ -1071,7 +1071,7 @@ AC_CACHE_CHECK([for epoll_create1 suppor
 #include <sys/epoll.h>
 #include <unistd.h>
 
-int main()
+int main(int argc, const char *argv[])
 {
     return epoll_create1(0) == -1;
 }], [apr_cv_epoll_create1=yes], [apr_cv_epoll_create1=no], [apr_cv_epoll_create1=no])])
@@ -1080,6 +1080,47 @@ if test "$apr_cv_epoll_create1" = "yes";
    AC_DEFINE([HAVE_EPOLL_CREATE1], 1, [Define if epoll_create1 function is supported])
 fi
 
+AC_CACHE_CHECK([whether epoll_wait has a reliable timeout (min)],
+               [apr_cv_epoll_wait_has_reliable_timeout],
+[AC_TRY_RUN([
+#include <unistd.h>
+#include <sys/epoll.h>
+#include <sys/time.h>   /* for gettimeofday */
+
+#define TV2US(tv) ((tv).tv_sec * 1000000LL + (tv).tv_usec)
+
+int main(int argc, const char *argv[])
+{
+    struct epoll_event events[1];
+    int fd, i;
+#ifdef HAVE_EPOLL_CREATE1
+    fd = epoll_create1(0);
+#else
+    fd = epoll_create(1);
+#endif
+    if (fd < 0) {
+        return 1;
+    }
+    for (i = 0; i < 10; ++i) {
+        struct timeval t1 = {0,},
+                       t2 = {0,};
+        (void)gettimeofday(&t1, NULL);
+        (void)epoll_wait(fd, events, 1, 100);  /* ms */
+        (void)gettimeofday(&t2, NULL);
+        if (TV2US(t2) - TV2US(t1) < 100000) {  /* us */
+            return 1;
+        }
+    }
+    return 0;
+}], [apr_cv_epoll_wait_has_reliable_timeout=yes],
+    [apr_cv_epoll_wait_has_reliable_timeout=no],
+    [apr_cv_epoll_wait_has_reliable_timeout=no])])
+
+if test "$apr_cv_epoll_wait_has_reliable_timeout" = "yes"; then
+   AC_DEFINE([HAVE_EPOLL_WAIT_RELIABLE_TIMEOUT], 1,
+             [Define if epoll_wait has a reliable timeout (min)])
+fi
+
 # test for dup3
 AC_CACHE_CHECK([for dup3 support], [apr_cv_dup3],
 [AC_TRY_RUN([

Modified: apr/apr/branches/1.8.x/poll/os2/poll.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.8.x/poll/os2/poll.c?rev=1909334&r1=1909333&r2=1909334&view=diff
==============================================================================
--- apr/apr/branches/1.8.x/poll/os2/poll.c (original)
+++ apr/apr/branches/1.8.x/poll/os2/poll.c Fri Apr 21 17:49:59 2023
@@ -61,7 +61,8 @@ APR_DECLARE(apr_status_t) apr_poll(apr_p
     }
 
     if (timeout > 0) {
-        timeout /= 1000; /* convert microseconds to milliseconds */
+        /* convert microseconds to milliseconds (round up) */
+        timeout = (timeout + 999) / 1000;
     }
 
     i = select(pollset, num_read, num_write, num_except, timeout);

Modified: apr/apr/branches/1.8.x/poll/os2/pollset.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.8.x/poll/os2/pollset.c?rev=1909334&r1=1909333&r2=1909334&view=diff
==============================================================================
--- apr/apr/branches/1.8.x/poll/os2/pollset.c (original)
+++ apr/apr/branches/1.8.x/poll/os2/pollset.c Fri Apr 21 17:49:59 2023
@@ -223,7 +223,7 @@ APR_DECLARE(apr_status_t) apr_pollset_po
     (*num) = 0;
 
     if (timeout > 0) {
-        timeout /= 1000;
+        timeout = (timeout + 999) / 1000;
     }
 
     rv = select(pollresult, pollset->num_read, pollset->num_write, pollset->num_except, timeout);

Modified: apr/apr/branches/1.8.x/poll/unix/epoll.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.8.x/poll/unix/epoll.c?rev=1909334&r1=1909333&r2=1909334&view=diff
==============================================================================
--- apr/apr/branches/1.8.x/poll/unix/epoll.c (original)
+++ apr/apr/branches/1.8.x/poll/unix/epoll.c Fri Apr 21 17:49:59 2023
@@ -265,7 +265,7 @@ static apr_status_t impl_pollset_poll(ap
     *num = 0;
 
     if (timeout > 0) {
-        timeout /= 1000;
+        timeout = (timeout + 999) / 1000;
     }
 
     ret = epoll_wait(pollset->p->epoll_fd, pollset->p->pollset, pollset->nalloc,
@@ -446,7 +446,7 @@ static apr_status_t impl_pollcb_poll(apr
     apr_status_t rv = APR_SUCCESS;
     
     if (timeout > 0) {
-        timeout /= 1000;
+        timeout = (timeout + 999) / 1000;
     }
     
     ret = epoll_wait(pollcb->fd, pollcb->pollset.epoll, pollcb->nalloc,

Modified: apr/apr/branches/1.8.x/poll/unix/poll.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.8.x/poll/unix/poll.c?rev=1909334&r1=1909333&r2=1909334&view=diff
==============================================================================
--- apr/apr/branches/1.8.x/poll/unix/poll.c (original)
+++ apr/apr/branches/1.8.x/poll/unix/poll.c Fri Apr 21 17:49:59 2023
@@ -114,7 +114,8 @@ APR_DECLARE(apr_status_t) apr_poll(apr_p
     num_to_poll = i;
 
     if (timeout > 0) {
-        timeout /= 1000; /* convert microseconds to milliseconds */
+        /* convert microseconds to milliseconds (round up) */
+        timeout = (timeout + 999) / 1000;
     }
 
     i = poll(pollset, num_to_poll, timeout);
@@ -248,14 +249,15 @@ static apr_status_t impl_pollset_poll(ap
         }
         return APR_SUCCESS;
     }
+#endif
+
     if (timeout > 0) {
-        timeout /= 1000;
+        timeout = (timeout + 999) / 1000;
     }
+
+#ifdef WIN32
     ret = WSAPoll(pollset->p->pollset, pollset->nelts, (int)timeout);
 #else
-    if (timeout > 0) {
-        timeout /= 1000;
-    }
     ret = poll(pollset->p->pollset, pollset->nelts, timeout);
 #endif
     if (ret < 0) {
@@ -412,14 +414,15 @@ static apr_status_t impl_pollcb_poll(apr
         }
         return APR_SUCCESS;
     }
+#endif
+
     if (timeout > 0) {
-        timeout /= 1000;
+        timeout = (timeout + 999) / 1000;
     }
+
+#ifdef WIN32
     ret = WSAPoll(pollcb->pollset.ps, pollcb->nelts, (int)timeout);
 #else
-    if (timeout > 0) {
-        timeout /= 1000;
-    }
     ret = poll(pollcb->pollset.ps, pollcb->nelts, timeout);
 #endif
     if (ret < 0) {

Modified: apr/apr/branches/1.8.x/poll/unix/z_asio.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.8.x/poll/unix/z_asio.c?rev=1909334&r1=1909333&r2=1909334&view=diff
==============================================================================
--- apr/apr/branches/1.8.x/poll/unix/z_asio.c (original)
+++ apr/apr/branches/1.8.x/poll/unix/z_asio.c Fri Apr 21 17:49:59 2023
@@ -554,7 +554,7 @@ static posix_poll(apr_pollset_t *pollset
     DBG(4, "entered\n");
 
     if (timeout > 0) {
-        timeout /= 1000;
+        timeout = (timeout + 999) / 1000;
     }
     rv = poll(priv->pollset, pollset->nelts, timeout);
     (*num) = rv;
@@ -698,6 +698,7 @@ static apr_status_t asio_pollset_poll(ap
             tv.tv_nsec = apr_time_usec(timeout) * 1000;
         } else {
             tv.tv_sec = INT_MAX;  /* block until something is ready */
+            tv.tv_nsec = 0;
         }
 
         DBG2(6, "nothing on the ready ring "

Modified: apr/apr/branches/1.8.x/support/unix/waitio.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.8.x/support/unix/waitio.c?rev=1909334&r1=1909333&r2=1909334&view=diff
==============================================================================
--- apr/apr/branches/1.8.x/support/unix/waitio.c (original)
+++ apr/apr/branches/1.8.x/support/unix/waitio.c Fri Apr 21 17:49:59 2023
@@ -42,10 +42,13 @@ apr_status_t apr_wait_for_io_or_timeout(
     struct pollfd pfd;
     int rc, timeout;
 
-    timeout    = f        ? f->timeout / 1000 : s->timeout / 1000;
+    timeout    = f        ? f->timeout        : s->timeout;
     pfd.fd     = f        ? f->filedes        : s->socketdes;
     pfd.events = for_read ? POLLIN            : POLLOUT;
 
+    if (timeout > 0) {
+        timeout = (timeout + 999) / 1000;
+    }
     do {
         rc = poll(&pfd, 1, timeout);
     } while (rc == -1 && errno == EINTR);

Modified: apr/apr/branches/1.8.x/test/testpoll.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.8.x/test/testpoll.c?rev=1909334&r1=1909333&r2=1909334&view=diff
==============================================================================
--- apr/apr/branches/1.8.x/test/testpoll.c (original)
+++ apr/apr/branches/1.8.x/test/testpoll.c Fri Apr 21 17:49:59 2023
@@ -22,6 +22,13 @@
 #include "apr_network_io.h"
 #include "apr_poll.h"
 
+#if defined(__linux__)
+#include "arch/unix/apr_private.h"
+#endif
+#ifndef HAVE_EPOLL_WAIT_RELIABLE_TIMEOUT
+#define HAVE_EPOLL_WAIT_RELIABLE_TIMEOUT 0
+#endif
+
 #define SMALL_NUM_SOCKETS 3
 /* We can't use 64 here, because some platforms *ahem* Solaris *ahem* have
  * a default limit of 64 open file descriptors per process.  If we use
@@ -854,6 +861,16 @@ static void pollcb_wakeup(abts_case *tc,
     ABTS_INT_EQUAL(tc, APR_EINTR, rv);
 }
 
+#define JUSTSLEEP_DELAY apr_time_from_msec(200)
+#if HAVE_EPOLL_WAIT_RELIABLE_TIMEOUT
+#define JUSTSLEEP_ENOUGH(ts, te) \
+    ((te) - (ts) >= JUSTSLEEP_DELAY)
+#else
+#define JUSTSLEEP_JIFFY apr_time_from_msec(10)
+#define JUSTSLEEP_ENOUGH(ts, te) \
+    ((te) - (ts) >= JUSTSLEEP_DELAY - JUSTSLEEP_JIFFY)
+#endif
+
 static void justsleep(abts_case *tc, void *data)
 {
     apr_int32_t nsds;
@@ -872,13 +889,13 @@ static void justsleep(abts_case *tc, voi
 
     nsds = 1;
     t1 = apr_time_now();
-    rv = apr_poll(NULL, 0, &nsds, apr_time_from_msec(200));
+    rv = apr_poll(NULL, 0, &nsds, JUSTSLEEP_DELAY);
     t2 = apr_time_now();
     ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
     ABTS_INT_EQUAL(tc, 0, nsds);
     ABTS_ASSERT(tc,
                 "apr_poll() didn't sleep",
-                (t2 - t1) > apr_time_from_msec(100));
+                JUSTSLEEP_ENOUGH(t1, t2));
 
     for (i = 0; i < sizeof methods / sizeof methods[0]; i++) {
         rv = apr_pollset_create_ex(&pollset, 5, p, 0, methods[i]);
@@ -887,14 +904,13 @@ static void justsleep(abts_case *tc, voi
 
             nsds = 1;
             t1 = apr_time_now();
-            rv = apr_pollset_poll(pollset, apr_time_from_msec(200), &nsds,
-                                  &hot_files);
+            rv = apr_pollset_poll(pollset, JUSTSLEEP_DELAY, &nsds, &hot_files);
             t2 = apr_time_now();
             ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
             ABTS_INT_EQUAL(tc, 0, nsds);
             ABTS_ASSERT(tc,
                         "apr_pollset_poll() didn't sleep",
-                        (t2 - t1) > apr_time_from_msec(100));
+                        JUSTSLEEP_ENOUGH(t1, t2));
 
             rv = apr_pollset_destroy(pollset);
             ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
@@ -905,12 +921,12 @@ static void justsleep(abts_case *tc, voi
             ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
 
             t1 = apr_time_now();
-            rv = apr_pollcb_poll(pollcb, apr_time_from_msec(200), NULL, NULL);
+            rv = apr_pollcb_poll(pollcb, JUSTSLEEP_DELAY, NULL, NULL);
             t2 = apr_time_now();
             ABTS_INT_EQUAL(tc, 1, APR_STATUS_IS_TIMEUP(rv));
             ABTS_ASSERT(tc,
                         "apr_pollcb_poll() didn't sleep",
-                        (t2 - t1) > apr_time_from_msec(100));
+                        JUSTSLEEP_ENOUGH(t1, t2));
 
             /* no apr_pollcb_destroy() */
         }



Re: Out of tree build broken for APR 1.7.x and 1.8.x

Posted by Yann Ylavic <yl...@gmail.com>.
On Mon, Oct 16, 2023 at 11:41 AM Rainer Jung <ra...@kippdata.de> wrote:
>
> This problem is in 1.7.x and 1.8.x. I did not check apr trunk.

Looks like apr_private_common.h does not exist in trunk (anymore?).

>
> Unfortunately I have no idea how to make autoheader to use
>
> #include "arch/apr_private_common.h"
>
> instead of
>
> #include "../apr_private_common.h"
>
> in the generated arch/unix/apr_private.h.in.
>
> Maybe someone has an idea?

The below seems to do it (and pass `make check` for me):

Index: configure.in
===================================================================
--- configure.in    (revision 1910349)
+++ configure.in    (working copy)
@@ -100,7 +100,7 @@ AH_BOTTOM([
 /*
  * Include common private declarations.
  */
-#include "../apr_private_common.h"
+#include "arch/apr_private_common.h"
 #endif /* APR_PRIVATE_H */
 ])

Index: include/arch/netware/apr_private.h
===================================================================
--- include/arch/netware/apr_private.h    (revision 1910349)
+++ include/arch/netware/apr_private.h    (working copy)
@@ -199,7 +199,7 @@ void* getStatCache();
 /*
  * Include common private declarations.
  */
-#include "../apr_private_common.h"
+#include "arch/apr_private_common.h"

 #endif  /*APR_PRIVATE_H*/
 #endif  /*NETWARE*/
Index: include/arch/win32/apr_private.h
===================================================================
--- include/arch/win32/apr_private.h    (revision 1910349)
+++ include/arch/win32/apr_private.h    (working copy)
@@ -169,7 +169,7 @@ APR_DECLARE_DATA int errno;
 /*
  * Include common private declarations.
  */
-#include "../apr_private_common.h"
+#include "arch/apr_private_common.h"

 #endif  /*APR_PRIVATE_H*/
 #endif  /*WIN32*/
--


Regards;
Yann.

Out of tree build broken for APR 1.7.x and 1.8.x

Posted by Rainer Jung <ra...@kippdata.de>.
More precisely "make check" is broken for out of tree builds, although 
the core reason is not restricted to "make check". It was observed after 
r1909334 / r1909335, which introduce a dependency on 
arch/unix/apr_private.h to testpoll.c.

The header file arch/unix/apr_private.h (build tree) is generated from 
arch/unix/apr_private.h.in (source tree). But is contains

#include "../apr_private_common.h"

which will be looked up due to the relative path in the build tree, but 
actually is located in the source tree.

Currently arch/unix/apr_private.h is only used in testpoll.h, therefore 
the problem only shows up during make check. But in fact 
arch/unix/apr_private.h is broken for any potential use.

This problem is in 1.7.x and 1.8.x. I did not check apr trunk.

Unfortunately I have no idea how to make autoheader to use

#include "arch/apr_private_common.h"

instead of

#include "../apr_private_common.h"

in the generated arch/unix/apr_private.h.in.

Maybe someone has an idea?

Thanks and regards,

Rainer