diff --git a/ChangeLog b/ChangeLog index 6dd51b66..edc10261 100644 --- a/ChangeLog +++ b/ChangeLog @@ -71,6 +71,7 @@ Changes in current version: o Rename internal memory management functions. o New functions (event_assign, event_new, event_free) for use by apps that want to be safely threadsafe, or want to remain ignorant of the contents of struct event. o introduce bufferevent_read_buffer; allows reading without memory copy. + o expose bufferevent_setwatermark via header files and fix high watermark on read Changes in 1.4.0: o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr. diff --git a/evbuffer.c b/evbuffer.c index bb719b3c..51ee6c06 100644 --- a/evbuffer.c +++ b/evbuffer.c @@ -56,7 +56,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 @@ -112,8 +111,17 @@ bufferevent_readcb(evutil_socket_t 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) { @@ -135,7 +143,7 @@ bufferevent_readcb(evutil_socket_t 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/include/event2/bufferevent.h b/include/event2/bufferevent.h index 7ef7e17d..2377ca35 100644 --- a/include/event2/bufferevent.h +++ b/include/event2/bufferevent.h @@ -223,6 +223,24 @@ int bufferevent_disable(struct bufferevent *bufev, short event); 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_INPUT(x) (x)->input #define EVBUFFER_OUTPUT(x) (x)->output