mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-17 00:07:04 -04:00
Add a lock/unlock pair inside the event callbacks in bufferevents.
This fixes part of bug 2800642, I believe, though there is still a general race condition in multithreaded use of events that we need to think about. svn:r1337
This commit is contained in:
parent
6469598e56
commit
a501d6833b
@ -40,6 +40,7 @@ Changes in 2.0.2-alpha:
|
||||
o Fix preamble of rpcgen-generated files to rely on event2 includes; based on work by jmansion; patch from Zack Weinberg.
|
||||
o Allow specifying the output filename for rpcgen; based on work by jmansion; patch from Zack Weinberg.
|
||||
o Allow C identifiers as struct names; allow multiple comments in .rpc files; from Zack Weinberg
|
||||
o Mitigate a race condition when using socket bufferevents in multiple threads.
|
||||
|
||||
|
||||
Changes in 2.0.1-alpha:
|
||||
|
@ -574,13 +574,17 @@ static void
|
||||
bufferevent_generic_read_timeout_cb(evutil_socket_t fd, short event, void *ctx)
|
||||
{
|
||||
struct bufferevent *bev = ctx;
|
||||
BEV_LOCK(bev);
|
||||
_bufferevent_run_eventcb(bev, BEV_EVENT_TIMEOUT|BEV_EVENT_READING);
|
||||
BEV_UNLOCK(bev);
|
||||
}
|
||||
static void
|
||||
bufferevent_generic_write_timeout_cb(evutil_socket_t fd, short event, void *ctx)
|
||||
{
|
||||
struct bufferevent *bev = ctx;
|
||||
BEV_LOCK(bev);
|
||||
_bufferevent_run_eventcb(bev, BEV_EVENT_TIMEOUT|BEV_EVENT_WRITING);
|
||||
BEV_UNLOCK(bev);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -122,6 +122,8 @@ bufferevent_readcb(evutil_socket_t fd, short event, void *arg)
|
||||
short what = BEV_EVENT_READING;
|
||||
int howmuch = -1;
|
||||
|
||||
BEV_LOCK(arg);
|
||||
|
||||
if (event == EV_TIMEOUT) {
|
||||
what |= BEV_EVENT_TIMEOUT;
|
||||
goto error;
|
||||
@ -138,7 +140,7 @@ bufferevent_readcb(evutil_socket_t fd, short event, void *arg)
|
||||
/* we somehow lowered the watermark, stop reading */
|
||||
if (howmuch <= 0) {
|
||||
bufferevent_wm_suspend_read(bufev);
|
||||
return;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,14 +168,17 @@ bufferevent_readcb(evutil_socket_t fd, short event, void *arg)
|
||||
bufev->readcb != NULL)
|
||||
_bufferevent_run_readcb(bufev);
|
||||
|
||||
return;
|
||||
goto done;
|
||||
|
||||
reschedule:
|
||||
return;
|
||||
goto done;
|
||||
|
||||
error:
|
||||
event_del(&bufev->ev_read);
|
||||
_bufferevent_run_eventcb(bufev, what);
|
||||
|
||||
done:
|
||||
BEV_UNLOCK(bufev);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -185,6 +190,8 @@ bufferevent_writecb(evutil_socket_t fd, short event, void *arg)
|
||||
int res = 0;
|
||||
short what = BEV_EVENT_WRITING;
|
||||
|
||||
BEV_LOCK(bufev);
|
||||
|
||||
if (event == EV_TIMEOUT) {
|
||||
what |= BEV_EVENT_TIMEOUT;
|
||||
goto error;
|
||||
@ -194,7 +201,7 @@ bufferevent_writecb(evutil_socket_t fd, short event, void *arg)
|
||||
_bufferevent_run_eventcb(bufev, BEV_EVENT_CONNECTED);
|
||||
if (!(bufev->enabled & EV_WRITE)) {
|
||||
event_del(&bufev->ev_write);
|
||||
return;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,16 +233,19 @@ bufferevent_writecb(evutil_socket_t fd, short event, void *arg)
|
||||
evbuffer_get_length(bufev->output) <= bufev->wm_write.low)
|
||||
_bufferevent_run_writecb(bufev);
|
||||
|
||||
return;
|
||||
goto done;
|
||||
|
||||
reschedule:
|
||||
if (evbuffer_get_length(bufev->output) == 0)
|
||||
event_del(&bufev->ev_write);
|
||||
return;
|
||||
goto done;
|
||||
|
||||
error:
|
||||
event_del(&bufev->ev_write);
|
||||
_bufferevent_run_eventcb(bufev, what);
|
||||
|
||||
done:
|
||||
BEV_UNLOCK(bufev);
|
||||
}
|
||||
|
||||
struct bufferevent *
|
||||
|
Loading…
x
Reference in New Issue
Block a user