diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2006-03-18 20:23:43 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2006-03-18 20:23:43 +0000 |
commit | 67092fb0b4f670759fe368d504a5393fde2d6c57 (patch) | |
tree | e43ae77f2dbc4fcefcc5fd51b7cb82c9dc002828 /lib/libevent | |
parent | aa453a0c31a4662f565dc06b82d641c008a5513e (diff) |
- limit the amount of data bufferevents are going to consume to something
reasonable; in some circumstances it could happen that libevent happily
allocated 100MB in read buffers without telling the user; found by
christopher maxwell - parts of these changes are from his patch.
- allow setting an event base for bufferevents; from phil oleson
- improved manpage from Phil Oleson
From libevent CVS
Diffstat (limited to 'lib/libevent')
-rw-r--r-- | lib/libevent/buffer.c | 21 | ||||
-rw-r--r-- | lib/libevent/evbuffer.c | 32 | ||||
-rw-r--r-- | lib/libevent/event.3 | 34 | ||||
-rw-r--r-- | lib/libevent/shlib_version | 2 |
4 files changed, 76 insertions, 13 deletions
diff --git a/lib/libevent/buffer.c b/lib/libevent/buffer.c index 404c62bf9ad..36d04599005 100644 --- a/lib/libevent/buffer.c +++ b/lib/libevent/buffer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: buffer.c,v 1.9 2006/01/25 05:25:33 brad Exp $ */ +/* $OpenBSD: buffer.c,v 1.10 2006/03/18 20:23:42 brad Exp $ */ /* * Copyright (c) 2002, 2003 Niels Provos <provos@citi.umich.edu> @@ -119,8 +119,10 @@ evbuffer_add_buffer(struct evbuffer *outbuf, struct evbuffer *inbuf) } res = evbuffer_add(outbuf, inbuf->buffer, inbuf->off); - if (res == 0) + if (res == 0) { + /* We drain the input buffer on success */ evbuffer_drain(inbuf, inbuf->off); + } return (res); } @@ -342,8 +344,21 @@ evbuffer_read(struct evbuffer *buf, int fd, int howmuch) #endif #ifdef FIONREAD - if (ioctl(fd, FIONREAD, &n) == -1 || n == 0) + if (ioctl(fd, FIONREAD, &n) == -1 || n == 0) { 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 artifically limit it. + */ + if (n > buf->totallen << 2) + n = buf->totallen << 2; + if (n < EVBUFFER_MAX_READ) + n = EVBUFFER_MAX_READ; + } #endif if (howmuch < 0 || howmuch > n) howmuch = n; diff --git a/lib/libevent/evbuffer.c b/lib/libevent/evbuffer.c index fd16a132877..9a0a2a96381 100644 --- a/lib/libevent/evbuffer.c +++ b/lib/libevent/evbuffer.c @@ -1,4 +1,4 @@ -/* $OpenBSD: evbuffer.c,v 1.7 2006/02/09 06:18:18 brad Exp $ */ +/* $OpenBSD: evbuffer.c,v 1.8 2006/03/18 20:23:42 brad Exp $ */ /* * Copyright (c) 2002-2004 Niels Provos <provos@citi.umich.edu> @@ -94,13 +94,21 @@ bufferevent_readcb(int fd, short event, void *arg) int res = 0; short what = EVBUFFER_READ; size_t len; + int howmuch = -1; if (event == EV_TIMEOUT) { what |= EVBUFFER_TIMEOUT; goto error; } - res = evbuffer_read(bufev->input, fd, -1); + /* + * If we have a high watermark configured then we don't want to + * read more data than would make us reach the watermark. + */ + if (bufev->wm_read.high != 0) + howmuch = bufev->wm_read.high; + + res = evbuffer_read(bufev->input, fd, howmuch); if (res == -1) { if (errno == EAGAIN || errno == EINTR) goto reschedule; @@ -228,7 +236,12 @@ bufferevent_new(int fd, evbuffercb readcb, evbuffercb writecb, bufev->cbarg = cbarg; - bufev->enabled = EV_READ | EV_WRITE; + /* + * Set to EV_WRITE so that using bufferevent_write is going to + * trigger a callback. Reading needs to be explicitly enabled + * because otherwise no data will be available. + */ + bufev->enabled = EV_WRITE; return (bufev); } @@ -374,3 +387,16 @@ bufferevent_setwatermark(struct bufferevent *bufev, short events, bufferevent_read_pressure_cb(bufev->input, 0, EVBUFFER_LENGTH(bufev->input), bufev); } + +int +bufferevent_base_set(struct event_base *base, struct bufferevent *bufev) +{ + int res; + + res = event_base_set(base, &bufev->ev_read); + if (res == -1) + return (res); + + res = event_base_set(base, &bufev->ev_write); + return (res); +} diff --git a/lib/libevent/event.3 b/lib/libevent/event.3 index 11651af2ff1..9c9d6b7a059 100644 --- a/lib/libevent/event.3 +++ b/lib/libevent/event.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: event.3,v 1.24 2006/01/25 05:25:34 brad Exp $ +.\" $OpenBSD: event.3,v 1.25 2006/03/18 20:23:42 brad Exp $ .\" .\" Copyright (c) 2000 Artur Grabowski <art@openbsd.org> .\" All rights reserved. @@ -61,6 +61,7 @@ .Nm bufferevent_enable , .Nm bufferevent_disable , .Nm bufferevent_settimeout , +.Nm bufferevent_base_set , .Nm evbuffer_new , .Nm evbuffer_free , .Nm evbuffer_add , @@ -144,6 +145,8 @@ .Fn "bufferevent_disable" "struct bufferevent *bufev" "short event" .Ft void .Fn "bufferevent_settimeout" "struct bufferevent *bufev" "int timeout_read" "int timeout_write" +.Ft int +.Fn "bufferevent_base_set" "struct event_base *base" "struct bufferevent *bufev" .Ft "struct evbuffer *" .Fn "evbuffer_new" "void" .Ft void @@ -440,14 +443,18 @@ This event base can be used in conjunction with calls to .Fn event_base_set , .Fn event_base_dispatch , .Fn event_base_loop , +.Fn event_base_loopexit , and -.Fn event_base_loopexit . +.Fn bufferevent_base_set . .Fn event_base_set should be called after preparing an event with .Fn event_set , as .Fn event_set assigns the provided event to the most recently created event base. +.Fn bufferevent_base_set +should be called after preparing a bufferevent with +.Fn bufferevent_new . .Sh BUFFERED EVENTS .Nm libevent provides an abstraction on top of the regular event callbacks. @@ -469,13 +476,25 @@ The next three parameters are callbacks. The read and write callback have the following form: .Ft void .Fn "(*cb)" "struct bufferevent *bufev" "void *arg" . +The error callback has the following form: +.Ft void +.Fn "(*cb)" "struct bufferevent *bufev" "short what" "void *arg" . The argument is specified by the fourth parameter .Fa "cbarg" . +A +.Fa bufferevent struct +pointer is returned on success, NULL on error. .Pp -By default the buffered event is read enabled and will try to read -from the file descriptor. -The write callback is executed whenever the output buffer is drained -below the write low watermark, which is +Once initialized, the bufferevent structure can be used repeatedly with +bufferevent_enable() and bufferevent_disable(). The flags parameter can +be a combination of +.Va EV_READ +and +.Va EV_WRITE . +When read enabled the bufferevent will try to read from the file +descriptor and call the read callback. The write callback is executed +whenever the output buffer is drained below the write low watermark, +which is .Va 0 by default. .Pp @@ -488,6 +507,9 @@ The .Fn bufferevent_read function is used to read data from the input buffer. Both functions return the amount of data written or read. +.Pp +If multiple bases are in use, bufferevent_base_set() must be called before +enabling the bufferevent for the first time. .Sh RETURN VALUES Upon successful completion .Fn event_add diff --git a/lib/libevent/shlib_version b/lib/libevent/shlib_version index 893819d18ff..c8860078e50 100644 --- a/lib/libevent/shlib_version +++ b/lib/libevent/shlib_version @@ -1,2 +1,2 @@ major=1 -minor=1 +minor=2 |