]> granicus.if.org Git - libevent/commitdiff
Add evutil_tv_to_msec for safe conversion of timevals to milliseconds.
authorChristopher Davis <chrisd@mangrin.org>
Thu, 1 Apr 2010 03:30:55 +0000 (20:30 -0700)
committerChristopher Davis <chrisd@mangrin.org>
Thu, 1 Apr 2010 06:38:34 +0000 (23:38 -0700)
This is useful for backends that require their timeout values be in
milliseconds.

epoll.c
evutil.c
poll.c
util-internal.h
win32select.c

diff --git a/epoll.c b/epoll.c
index 53c1f09a3f75ccf41a04fc6e767b68df165b3c42..6c3cf33f1d159cf292876451e8486e501c1c1102 100644 (file)
--- a/epoll.c
+++ b/epoll.c
@@ -35,6 +35,7 @@
 #include <sys/queue.h>
 #include <sys/epoll.h>
 #include <signal.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -269,15 +270,16 @@ epoll_dispatch(struct event_base *base, struct timeval *tv)
 {
        struct epollop *epollop = base->evbase;
        struct epoll_event *events = epollop->events;
-       int i, res, timeout = -1;
-
-       if (tv != NULL)
-               timeout = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
-
-       if (timeout > MAX_EPOLL_TIMEOUT_MSEC) {
-               /* Linux kernels can wait forever if the timeout is too big;
-                * see comment on MAX_EPOLL_TIMEOUT_MSEC. */
-               timeout = MAX_EPOLL_TIMEOUT_MSEC;
+       int i, res;
+       long timeout = -1;
+
+       if (tv != NULL) {
+               timeout = evutil_tv_to_msec(tv);
+               if (timeout < 0 || timeout > MAX_EPOLL_TIMEOUT_MSEC) {
+                       /* Linux kernels can wait forever if the timeout is
+                        * too big; see comment on MAX_EPOLL_TIMEOUT_MSEC. */
+                       timeout = MAX_EPOLL_TIMEOUT_MSEC;
+               }
        }
 
        epoll_apply_changes(base);
index 9825a878b182b13fab466c5d9a93cb14ff00ab92..3ca9fef9fb77caeab2b30e0227e602c4ac6c904f 100644 (file)
--- a/evutil.c
+++ b/evutil.c
@@ -52,6 +52,7 @@
 #include <stdlib.h>
 #endif
 #include <errno.h>
+#include <limits.h>
 #include <stdio.h>
 #include <string.h>
 #ifdef _EVENT_HAVE_ARPA_INET_H
@@ -1894,3 +1895,15 @@ evutil_sockaddr_is_loopback(const struct sockaddr *addr)
        return 0;
 }
 
+#define MAX_SECONDS_IN_MSEC_LONG \
+       (((LONG_MAX) - 999) / 1000) 
+                            
+long
+evutil_tv_to_msec(const struct timeval *tv)
+{
+       if (tv->tv_usec > 1000000 || tv->tv_sec > MAX_SECONDS_IN_MSEC_LONG)
+               return -1;
+
+       return (tv->tv_sec * 1000) + (tv->tv_usec / 1000);
+}
+
diff --git a/poll.c b/poll.c
index 84e7944ec237c0afd012a9fe652d3412478b67c0..abbf90eb2f9d7d1c4ec49a84ac0c24f613910a99 100644 (file)
--- a/poll.c
+++ b/poll.c
@@ -35,6 +35,7 @@
 #include <sys/queue.h>
 #include <poll.h>
 #include <signal.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -117,7 +118,8 @@ poll_check_ok(struct pollop *pop)
 static int
 poll_dispatch(struct event_base *base, struct timeval *tv)
 {
-       int res, i, j, msec = -1, nfds;
+       int res, i, j, nfds;
+       long msec = -1;
        struct pollop *pop = base->evbase;
        struct pollfd *event_set;
 
@@ -152,8 +154,11 @@ poll_dispatch(struct event_base *base, struct timeval *tv)
        event_set = pop->event_set;
 #endif
 
-       if (tv != NULL)
-               msec = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
+       if (tv != NULL) {
+               msec = evutil_tv_to_msec(tv);
+               if (msec < 0 || msec > INT_MAX)
+                       msec = INT_MAX;
+       }
 
        EVBASE_RELEASE_LOCK(base, th_base_lock);
 
index f74f323ce446435dcf2090d873c3005e604633de..f5fff192f444ed042f2d282827ec1b10f9f2ca26 100644 (file)
@@ -213,6 +213,8 @@ int evutil_getaddrinfo_async(struct evdns_base *dns_base,
  * ::1). */
 int evutil_sockaddr_is_loopback(const struct sockaddr *sa);
 
+long evutil_tv_to_msec(const struct timeval *tv);
+
 #ifdef __cplusplus
 }
 #endif
index 7dc68c912f4517877e314900c930d6cceb991286..a3b8dd7dbc9cecb76c7f36eb35ad2bfffd18a253 100644 (file)
@@ -30,6 +30,7 @@
 #include <windows.h>
 #include <sys/types.h>
 #include <sys/queue.h>
+#include <limits.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -114,12 +115,6 @@ realloc_fd_sets(struct win32op *op, size_t new_size)
        return (0);
 }
 
-static int
-timeval_to_ms(struct timeval *tv)
-{
-       return ((tv->tv_sec * 1000) + (tv->tv_usec / 1000));
-}
-
 static int
 do_fd_set(struct win32op *op, struct idx_info *ent, evutil_socket_t s, int read)
 {
@@ -303,8 +298,12 @@ win32_dispatch(struct event_base *base, struct timeval *tv)
            win32op->readset_out->fd_count : win32op->writeset_out->fd_count;
 
        if (!fd_count) {
+               long msec = evutil_tv_to_msec(tv);
+               /* Sleep's DWORD argument is unsigned long */
+               if (msec < 0)
+                       msec = LONG_MAX;
                /* Windows doesn't like you to call select() with no sockets */
-               Sleep(timeval_to_ms(tv));
+               Sleep(msec);
                evsig_process(base);
                return (0);
        }