summaryrefslogtreecommitdiff
path: root/bufferevent.c
diff options
context:
space:
mode:
authorChristopher Davis <chrisd@torproject.org>2010-09-01 11:04:57 -0700
committerChristopher Davis <chrisd@torproject.org>2010-09-08 01:22:22 -0700
commit17a14f1af2ace0201baa1b5bbba031296e62d879 (patch)
treeca5537e32f73d77f0942a65f21a0fc14fb2b5a6f /bufferevent.c
parent2447fe88860c40e968261ad8ea059166cb84a280 (diff)
downloadlibevent-17a14f1af2ace0201baa1b5bbba031296e62d879.tar.gz
Only process up to MAX_DEFERRED deferred_cbs at a time.
If threads queue callbacks while event_process_deferred_callbacks is running, the loop may spin long enough to significantly skew timers. A unit test stressing this behavior is also in this commit.
Diffstat (limited to 'bufferevent.c')
-rw-r--r--bufferevent.c15
1 files changed, 5 insertions, 10 deletions
diff --git a/bufferevent.c b/bufferevent.c
index 9923bbe0..53b07f1f 100644
--- a/bufferevent.c
+++ b/bufferevent.c
@@ -206,10 +206,11 @@ bufferevent_run_deferred_callbacks_unlocked(struct deferred_cb *_, void *arg)
#define SCHEDULE_DEFERRED(bevp) \
do { \
+ bufferevent_incref(&(bevp)->bev); \
event_deferred_cb_schedule( \
event_base_get_deferred_cb_queue((bevp)->bev.ev_base), \
&(bevp)->deferred); \
- } while (0);
+ } while (0)
void
@@ -222,10 +223,8 @@ _bufferevent_run_readcb(struct bufferevent *bufev)
return;
if (p->options & BEV_OPT_DEFER_CALLBACKS) {
p->readcb_pending = 1;
- if (!p->deferred.queued) {
- bufferevent_incref(bufev);
+ if (!p->deferred.queued)
SCHEDULE_DEFERRED(p);
- }
} else {
bufev->readcb(bufev, bufev->cbarg);
}
@@ -241,10 +240,8 @@ _bufferevent_run_writecb(struct bufferevent *bufev)
return;
if (p->options & BEV_OPT_DEFER_CALLBACKS) {
p->writecb_pending = 1;
- if (!p->deferred.queued) {
- bufferevent_incref(bufev);
+ if (!p->deferred.queued)
SCHEDULE_DEFERRED(p);
- }
} else {
bufev->writecb(bufev, bufev->cbarg);
}
@@ -261,10 +258,8 @@ _bufferevent_run_eventcb(struct bufferevent *bufev, short what)
if (p->options & BEV_OPT_DEFER_CALLBACKS) {
p->eventcb_pending |= what;
p->errno_pending = EVUTIL_SOCKET_ERROR();
- if (!p->deferred.queued) {
- bufferevent_incref(bufev);
+ if (!p->deferred.queued)
SCHEDULE_DEFERRED(p);
- }
} else {
bufev->errorcb(bufev, what, bufev->cbarg);
}