From: Christopher Davis Date: Thu, 1 Apr 2010 03:30:55 +0000 (-0700) Subject: Add evutil_tv_to_msec for safe conversion of timevals to milliseconds. X-Git-Tag: release-2.0.5-beta~57^2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=850c3ff232659125262bb5e30bef8451fac386bf;p=libevent Add evutil_tv_to_msec for safe conversion of timevals to milliseconds. This is useful for backends that require their timeout values be in milliseconds. --- diff --git a/epoll.c b/epoll.c index 53c1f09a..6c3cf33f 100644 --- a/epoll.c +++ b/epoll.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -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); diff --git a/evutil.c b/evutil.c index 9825a878..3ca9fef9 100644 --- a/evutil.c +++ b/evutil.c @@ -52,6 +52,7 @@ #include #endif #include +#include #include #include #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 84e7944e..abbf90eb 100644 --- a/poll.c +++ b/poll.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -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); diff --git a/util-internal.h b/util-internal.h index f74f323c..f5fff192 100644 --- a/util-internal.h +++ b/util-internal.h @@ -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 diff --git a/win32select.c b/win32select.c index 7dc68c91..a3b8dd7d 100644 --- a/win32select.c +++ b/win32select.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -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); }