From c0e425abdcfc883fa70b6deafdf7327bfb75f02d Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 9 May 2012 11:06:06 -0400 Subject: 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. --- bufferevent.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'bufferevent.c') diff --git a/bufferevent.c b/bufferevent.c index f47153c9..98003ac7 100644 --- a/bufferevent.c +++ b/bufferevent.c @@ -324,14 +324,14 @@ bufferevent_init_common_(struct bufferevent_private *bufev_private, if (options & BEV_OPT_DEFER_CALLBACKS) { if (options & BEV_OPT_UNLOCK_CALLBACKS) event_deferred_cb_init_( - bufev->ev_base, &bufev_private->deferred, + event_base_get_npriorities(base) / 2, bufferevent_run_deferred_callbacks_unlocked, bufev_private); else event_deferred_cb_init_( - bufev->ev_base, &bufev_private->deferred, + event_base_get_npriorities(base) / 2, bufferevent_run_deferred_callbacks_locked, bufev_private); } -- cgit v1.2.1