mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-17 16:29:28 -04:00
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.
This commit is contained in:
parent
0798dd1247
commit
3467f2fa3b
45
buffer.c
45
buffer.c
@ -1856,13 +1856,31 @@ _evbuffer_read_setup_vecs(struct evbuffer *buf, ev_ssize_t howmuch,
|
|||||||
return i;
|
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
|
/* TODO(niels): should this function return ev_ssize_t and take ev_ssize_t
|
||||||
* as howmuch? */
|
* as howmuch? */
|
||||||
int
|
int
|
||||||
evbuffer_read(struct evbuffer *buf, evutil_socket_t fd, int howmuch)
|
evbuffer_read(struct evbuffer *buf, evutil_socket_t fd, int howmuch)
|
||||||
{
|
{
|
||||||
struct evbuffer_chain *chain, **chainp;
|
struct evbuffer_chain *chain, **chainp;
|
||||||
int n = EVBUFFER_MAX_READ;
|
int n;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
#ifdef USE_IOVEC_IMPL
|
#ifdef USE_IOVEC_IMPL
|
||||||
@ -1870,9 +1888,6 @@ evbuffer_read(struct evbuffer *buf, evutil_socket_t fd, int howmuch)
|
|||||||
#else
|
#else
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
#endif
|
#endif
|
||||||
#if defined(FIONREAD) && defined(WIN32)
|
|
||||||
unsigned long lng = EVBUFFER_MAX_READ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
EVBUFFER_LOCK(buf);
|
EVBUFFER_LOCK(buf);
|
||||||
|
|
||||||
@ -1883,27 +1898,9 @@ evbuffer_read(struct evbuffer *buf, evutil_socket_t fd, int howmuch)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(FIONREAD)
|
n = get_n_bytes_readable_on_socket(fd);
|
||||||
#ifdef WIN32
|
if (n <= 0 || n > EVBUFFER_MAX_READ)
|
||||||
if (ioctlsocket(fd, FIONREAD, &lng) == -1 || (n=lng) <= 0) {
|
|
||||||
#else
|
|
||||||
if (ioctl(fd, FIONREAD, &n) == -1 || n <= 0) {
|
|
||||||
#endif
|
|
||||||
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)
|
if (howmuch < 0 || howmuch > n)
|
||||||
howmuch = n;
|
howmuch = n;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user