diff --git a/ChangeLog b/ChangeLog index 84d65cf2..517759a4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,7 @@ Changes in 1.4.4-stable: o Don't warn on unimplemented epoll_create(): this isn't a problem, just a reason to fall back to poll or select. o Correctly handle timeouts larger than 35 minutes on Linux with epoll.c. This is probably a kernel defect, but we'll have to support old kernels anyway even if it gets fixed. o Fix a potential stack corruption bug in tagging on 64-bit CPUs. + o expose bufferevent_setwatermark via header files and fix high watermark on read Changes in 1.4.3-stable: diff --git a/evbuffer.c b/evbuffer.c index 073c8658..ca2dcf19 100644 --- a/evbuffer.c +++ b/evbuffer.c @@ -52,7 +52,6 @@ /* prototypes */ -void bufferevent_setwatermark(struct bufferevent *, short, size_t, size_t); void bufferevent_read_pressure_cb(struct evbuffer *, size_t, size_t, void *); static int @@ -108,8 +107,17 @@ bufferevent_readcb(int fd, short event, void *arg) * 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; + if (bufev->wm_read.high != 0) { + howmuch = bufev->wm_read.high - EVBUFFER_LENGTH(bufev->input); + /* we might have lowered the watermark, stop reading */ + if (howmuch <= 0) { + struct evbuffer *buf = bufev->input; + event_del(&bufev->ev_read); + evbuffer_setcb(buf, + bufferevent_read_pressure_cb, bufev); + return; + } + } res = evbuffer_read(bufev->input, fd, howmuch); if (res == -1) { @@ -131,7 +139,7 @@ bufferevent_readcb(int fd, short event, void *arg) len = EVBUFFER_LENGTH(bufev->input); if (bufev->wm_read.low != 0 && len < bufev->wm_read.low) return; - if (bufev->wm_read.high != 0 && len > bufev->wm_read.high) { + if (bufev->wm_read.high != 0 && len >= bufev->wm_read.high) { struct evbuffer *buf = bufev->input; event_del(&bufev->ev_read); diff --git a/event.h b/event.h index 98b153f1..6efe8dba 100644 --- a/event.h +++ b/event.h @@ -907,6 +907,25 @@ void bufferevent_settimeout(struct bufferevent *bufev, int timeout_read, int timeout_write); +/** + Sets the watermarks for read and write events. + + On input, a bufferevent does not invoke the user read callback unless + there is at least low watermark data in the buffer. If the read buffer + is beyond the high watermark, the buffevent stops reading from the network. + + On output, the user write callback is invoked whenever the buffered data + falls below the low watermark. + + @param bufev the bufferevent to be modified + @param events EV_READ, EV_WRITE or both + @param lowmark the lower watermark to set + @param highmark the high watermark to set +*/ + +void bufferevent_setwatermark(struct bufferevent *bufev, short events, + size_t lowmark, size_t highmark); + #define EVBUFFER_LENGTH(x) (x)->off #define EVBUFFER_DATA(x) (x)->buffer #define EVBUFFER_INPUT(x) (x)->input