From: Nick Mathewson Date: Fri, 28 May 2010 19:05:32 +0000 (-0400) Subject: Fix logic in correcting high values from FIONREAD X-Git-Tag: release-2.0.6-rc~49 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3467f2fa3bbff0dab6865a0ed08475ed3573c230;p=libevent Fix logic in correcting high values from FIONREAD The old logic made sense back when buffer.c was an enormous linear buffer, but it doesn't make any sense for the chain-based implementation. This patch also refactors the ioctl{socket}? call into its own function. --- diff --git a/buffer.c b/buffer.c index 6e0a8380..7b0262f3 100644 --- a/buffer.c +++ b/buffer.c @@ -1856,13 +1856,31 @@ _evbuffer_read_setup_vecs(struct evbuffer *buf, ev_ssize_t howmuch, return i; } +static int +get_n_bytes_readable_on_socket(evutil_socket_t fd) +{ +#if defined(FIONREAD) && defined(WIN32) + unsigned long lng = EVBUFFER_MAX_READ; + if (ioctlsocket(fd, FIONREAD, &lng) < 0) + return -1; + return (int)lng; +#elif defined(FIONREAD) + int n = EVBUFFER_MAX_READ; + if (ioctl(fd, FIONREAD, &n) < 0) + return -1; + return n; +#else + return EVBUFFER_MAX_READ; +#endif +} + /* TODO(niels): should this function return ev_ssize_t and take ev_ssize_t * as howmuch? */ int evbuffer_read(struct evbuffer *buf, evutil_socket_t fd, int howmuch) { struct evbuffer_chain *chain, **chainp; - int n = EVBUFFER_MAX_READ; + int n; int result; #ifdef USE_IOVEC_IMPL @@ -1870,9 +1888,6 @@ evbuffer_read(struct evbuffer *buf, evutil_socket_t fd, int howmuch) #else unsigned char *p; #endif -#if defined(FIONREAD) && defined(WIN32) - unsigned long lng = EVBUFFER_MAX_READ; -#endif EVBUFFER_LOCK(buf); @@ -1883,27 +1898,9 @@ evbuffer_read(struct evbuffer *buf, evutil_socket_t fd, int howmuch) goto done; } -#if defined(FIONREAD) -#ifdef WIN32 - if (ioctlsocket(fd, FIONREAD, &lng) == -1 || (n=lng) <= 0) { -#else - if (ioctl(fd, FIONREAD, &n) == -1 || n <= 0) { -#endif + n = get_n_bytes_readable_on_socket(fd); + if (n <= 0 || n > EVBUFFER_MAX_READ) n = EVBUFFER_MAX_READ; - } else if (n > EVBUFFER_MAX_READ && n > howmuch) { - /* - * It's possible that a lot of data is available for - * reading. We do not want to exhaust resources - * before the reader has a chance to do something - * about it. If the reader does not tell us how much - * data we should read, we artificially limit it. - */ - if (chain == NULL || n < EVBUFFER_MAX_READ) - n = EVBUFFER_MAX_READ; - else if ((size_t)n > chain->buffer_len << 2) - n = chain->buffer_len << 2; - } -#endif if (howmuch < 0 || howmuch > n) howmuch = n;