summaryrefslogtreecommitdiff
path: root/buffer.c
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2012-05-09 11:06:06 -0400
committerNick Mathewson <nickm@torproject.org>2012-05-09 12:06:00 -0400
commitc0e425abdcfc883fa70b6deafdf7327bfb75f02d (patch)
treed47ac72fa6388e0354bc9e18a2112b309c27a5d0 /buffer.c
parent581b5beb98f45ec73ade6c8026f4fadef4325d4b (diff)
downloadlibevent-c0e425abdcfc883fa70b6deafdf7327bfb75f02d.tar.gz
Restore our priority-inversion-prevention code with deferreds
Back when deferred_cb stuff had its own queue, the queue was always executed, but we never ran more than 16 callbacks per iteration. That made for two problems: 1: Because deferred_cb stuff would always run, and had no priority, it could cause priority inversion. 2: It doesn't respect the max_dispatch_interval code. Then, when I refactored deferred_cb to be a special case of event_callback, that solved the above issues, but made for two more issues: 3: Because deferred_cb stuff would always get the default priority, it could could low-priority bufferevents to get too much priority. 4: With code like bufferevent_pair, it's easy to get into a situation where two deferreds keep adding one another, preventing the event loop from ever actually scanning for more events. This commit fixes the above by giving deferreds a better notion of priorities, and by limiting the number of deferreds that can be added to the _current_ loop iteration's active queues. (Extra deferreds are put into the active_later state.) That isn't an all-purpose priority inversion solution, of course: for that, you may need to mess around with max_dispatch_interval.
Diffstat (limited to 'buffer.c')
-rw-r--r--buffer.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/buffer.c b/buffer.c
index 99aa1d58..19897296 100644
--- a/buffer.c
+++ b/buffer.c
@@ -404,7 +404,8 @@ evbuffer_defer_callbacks(struct evbuffer *buffer, struct event_base *base)
EVBUFFER_LOCK(buffer);
buffer->cb_queue = base;
buffer->deferred_cbs = 1;
- event_deferred_cb_init_(base, &buffer->deferred,
+ event_deferred_cb_init_(&buffer->deferred,
+ event_base_get_npriorities(base) / 2,
evbuffer_deferred_callback, buffer);
EVBUFFER_UNLOCK(buffer);
return 0;