summaryrefslogtreecommitdiff
path: root/bufferevent_sock.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2009-07-10 19:34:00 +0000
committerNick Mathewson <nickm@torproject.org>2009-07-10 19:34:00 +0000
commita501d6833bae3415381e62acd6e45f4a22fea5b6 (patch)
tree4bd206b85ff9ca3e7bc7e2ce9af5bd78739c2182 /bufferevent_sock.c
parent6469598e568a62072c35a3e9322ad09e102b81a7 (diff)
downloadlibevent-a501d6833bae3415381e62acd6e45f4a22fea5b6.tar.gz
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
Diffstat (limited to 'bufferevent_sock.c')
-rw-r--r--bufferevent_sock.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/bufferevent_sock.c b/bufferevent_sock.c
index e8e5f473..e4b0836f 100644
--- a/bufferevent_sock.c
+++ b/bufferevent_sock.c
@@ -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 *