diff options
author | Nick Mathewson <nickm@torproject.org> | 2009-07-10 19:34:00 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2009-07-10 19:34:00 +0000 |
commit | a501d6833bae3415381e62acd6e45f4a22fea5b6 (patch) | |
tree | 4bd206b85ff9ca3e7bc7e2ce9af5bd78739c2182 /bufferevent_sock.c | |
parent | 6469598e568a62072c35a3e9322ad09e102b81a7 (diff) | |
download | libevent-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.c | 22 |
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 * |