mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-18 08:49:57 -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 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 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 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:
|
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)
|
bufferevent_generic_read_timeout_cb(evutil_socket_t fd, short event, void *ctx)
|
||||||
{
|
{
|
||||||
struct bufferevent *bev = ctx;
|
struct bufferevent *bev = ctx;
|
||||||
|
BEV_LOCK(bev);
|
||||||
_bufferevent_run_eventcb(bev, BEV_EVENT_TIMEOUT|BEV_EVENT_READING);
|
_bufferevent_run_eventcb(bev, BEV_EVENT_TIMEOUT|BEV_EVENT_READING);
|
||||||
|
BEV_UNLOCK(bev);
|
||||||
}
|
}
|
||||||
static void
|
static void
|
||||||
bufferevent_generic_write_timeout_cb(evutil_socket_t fd, short event, void *ctx)
|
bufferevent_generic_write_timeout_cb(evutil_socket_t fd, short event, void *ctx)
|
||||||
{
|
{
|
||||||
struct bufferevent *bev = ctx;
|
struct bufferevent *bev = ctx;
|
||||||
|
BEV_LOCK(bev);
|
||||||
_bufferevent_run_eventcb(bev, BEV_EVENT_TIMEOUT|BEV_EVENT_WRITING);
|
_bufferevent_run_eventcb(bev, BEV_EVENT_TIMEOUT|BEV_EVENT_WRITING);
|
||||||
|
BEV_UNLOCK(bev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -122,6 +122,8 @@ bufferevent_readcb(evutil_socket_t fd, short event, void *arg)
|
|||||||
short what = BEV_EVENT_READING;
|
short what = BEV_EVENT_READING;
|
||||||
int howmuch = -1;
|
int howmuch = -1;
|
||||||
|
|
||||||
|
BEV_LOCK(arg);
|
||||||
|
|
||||||
if (event == EV_TIMEOUT) {
|
if (event == EV_TIMEOUT) {
|
||||||
what |= BEV_EVENT_TIMEOUT;
|
what |= BEV_EVENT_TIMEOUT;
|
||||||
goto error;
|
goto error;
|
||||||
@ -138,7 +140,7 @@ bufferevent_readcb(evutil_socket_t fd, short event, void *arg)
|
|||||||
/* we somehow lowered the watermark, stop reading */
|
/* we somehow lowered the watermark, stop reading */
|
||||||
if (howmuch <= 0) {
|
if (howmuch <= 0) {
|
||||||
bufferevent_wm_suspend_read(bufev);
|
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)
|
bufev->readcb != NULL)
|
||||||
_bufferevent_run_readcb(bufev);
|
_bufferevent_run_readcb(bufev);
|
||||||
|
|
||||||
return;
|
goto done;
|
||||||
|
|
||||||
reschedule:
|
reschedule:
|
||||||
return;
|
goto done;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
event_del(&bufev->ev_read);
|
event_del(&bufev->ev_read);
|
||||||
_bufferevent_run_eventcb(bufev, what);
|
_bufferevent_run_eventcb(bufev, what);
|
||||||
|
|
||||||
|
done:
|
||||||
|
BEV_UNLOCK(bufev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -185,6 +190,8 @@ bufferevent_writecb(evutil_socket_t fd, short event, void *arg)
|
|||||||
int res = 0;
|
int res = 0;
|
||||||
short what = BEV_EVENT_WRITING;
|
short what = BEV_EVENT_WRITING;
|
||||||
|
|
||||||
|
BEV_LOCK(bufev);
|
||||||
|
|
||||||
if (event == EV_TIMEOUT) {
|
if (event == EV_TIMEOUT) {
|
||||||
what |= BEV_EVENT_TIMEOUT;
|
what |= BEV_EVENT_TIMEOUT;
|
||||||
goto error;
|
goto error;
|
||||||
@ -194,7 +201,7 @@ bufferevent_writecb(evutil_socket_t fd, short event, void *arg)
|
|||||||
_bufferevent_run_eventcb(bufev, BEV_EVENT_CONNECTED);
|
_bufferevent_run_eventcb(bufev, BEV_EVENT_CONNECTED);
|
||||||
if (!(bufev->enabled & EV_WRITE)) {
|
if (!(bufev->enabled & EV_WRITE)) {
|
||||||
event_del(&bufev->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)
|
evbuffer_get_length(bufev->output) <= bufev->wm_write.low)
|
||||||
_bufferevent_run_writecb(bufev);
|
_bufferevent_run_writecb(bufev);
|
||||||
|
|
||||||
return;
|
goto done;
|
||||||
|
|
||||||
reschedule:
|
reschedule:
|
||||||
if (evbuffer_get_length(bufev->output) == 0)
|
if (evbuffer_get_length(bufev->output) == 0)
|
||||||
event_del(&bufev->ev_write);
|
event_del(&bufev->ev_write);
|
||||||
return;
|
goto done;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
event_del(&bufev->ev_write);
|
event_del(&bufev->ev_write);
|
||||||
_bufferevent_run_eventcb(bufev, what);
|
_bufferevent_run_eventcb(bufev, what);
|
||||||
|
|
||||||
|
done:
|
||||||
|
BEV_UNLOCK(bufev);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct bufferevent *
|
struct bufferevent *
|
||||||
|
Loading…
x
Reference in New Issue
Block a user