]> granicus.if.org Git - libevent/commitdiff
Make max_dispatch_interval able to apply only to low-priority events
authorNick Mathewson <nickm@torproject.org>
Thu, 11 Aug 2011 16:38:47 +0000 (12:38 -0400)
committerNick Mathewson <nickm@torproject.org>
Thu, 18 Aug 2011 02:03:57 +0000 (22:03 -0400)
Suggested by Alexander Drozdov

event-internal.h
event.c
include/event2/event.h

index f495d6d2ad254f6bba27585699321f493f58c75d..a5f4afedb4539ef4a44ecc161500ab9ed4501a23 100644 (file)
@@ -275,6 +275,7 @@ struct event_base {
 
        struct timeval max_dispatch_time;
        int max_dispatch_callbacks;
+       int limit_callbacks_after_prio;
 
        /* Notify main thread to wake up break, etc. */
        /** True if the base already has a pending notify, and we don't need
@@ -304,6 +305,7 @@ struct event_config {
        int n_cpus_hint;
        struct timeval max_dispatch_interval;
        int max_dispatch_callbacks;
+       int limit_callbacks_after_prio;
        enum event_method_feature require_features;
        enum event_base_config_flag flags;
 };
diff --git a/event.c b/event.c
index baaef8cd46dbc1c06cb97ba2307d45986f2f4261..233e8897d3676ddb46c1fd16988b5839c67a064a 100644 (file)
--- a/event.c
+++ b/event.c
@@ -587,16 +587,23 @@ event_base_new_with_config(const struct event_config *cfg)
        should_check_environment =
            !(cfg && (cfg->flags & EVENT_BASE_FLAG_IGNORE_ENV));
 
-       if (cfg)
+       if (cfg) {
                memcpy(&base->max_dispatch_time,
                    &cfg->max_dispatch_interval, sizeof(struct timeval));
-       else
+               base->limit_callbacks_after_prio =
+                   cfg->limit_callbacks_after_prio;
+       } else {
                base->max_dispatch_time.tv_sec = -1;
+               base->limit_callbacks_after_prio = 1;
+       }
        if (cfg && cfg->max_dispatch_callbacks >= 0) {
                base->max_dispatch_callbacks = cfg->max_dispatch_callbacks;
        } else {
                base->max_dispatch_callbacks = INT_MAX;
        }
+       if (base->max_dispatch_callbacks == INT_MAX &&
+           base->max_dispatch_time.tv_sec == -1)
+               base->limit_callbacks_after_prio = INT_MAX;
 
        for (i = 0; eventops[i] && !base->evbase; i++) {
                if (cfg != NULL) {
@@ -924,6 +931,7 @@ event_config_new(void)
        TAILQ_INIT(&cfg->entries);
        cfg->max_dispatch_interval.tv_sec = -1;
        cfg->max_dispatch_callbacks = INT_MAX;
+       cfg->limit_callbacks_after_prio = 1;
 
        return (cfg);
 }
@@ -995,7 +1003,7 @@ event_config_set_num_cpus_hint(struct event_config *cfg, int cpus)
 
 int
 event_config_set_max_dispatch_interval(struct event_config *cfg,
-    const struct timeval *max_interval, int max_callbacks)
+    const struct timeval *max_interval, int max_callbacks, int min_priority)
 {
        if (max_interval)
                memcpy(&cfg->max_dispatch_interval, max_interval,
@@ -1003,7 +1011,10 @@ event_config_set_max_dispatch_interval(struct event_config *cfg,
        else
                cfg->max_dispatch_interval.tv_sec = -1;
        cfg->max_dispatch_callbacks =
-           max_callbacks >= 0 ? max_callbacks : INT_MAX ;
+           max_callbacks >= 0 ? max_callbacks : INT_MAX;
+       if (min_priority <= 0)
+               min_priority = 1;
+       cfg->limit_callbacks_after_prio = min_priority;
        return (0);
 }
 
@@ -1428,6 +1439,7 @@ event_process_active(struct event_base *base)
        const struct timeval *endtime;
        struct timeval tv;
        const int maxcb = base->max_dispatch_callbacks;
+       const int limit_after_prio = base->limit_callbacks_after_prio;
        if (base->max_dispatch_time.tv_sec >= 0) {
                evutil_gettimeofday(&tv, NULL);
                evutil_timeradd(&base->max_dispatch_time, &tv, &tv);
@@ -1439,7 +1451,7 @@ event_process_active(struct event_base *base)
        for (i = 0; i < base->nactivequeues; ++i) {
                if (TAILQ_FIRST(&base->activequeues[i]) != NULL) {
                        activeq = &base->activequeues[i];
-                       if (i == 0)
+                       if (i < limit_after_prio)
                                c = event_process_active_single_queue(base, activeq,
                                    INT_MAX, NULL);
                        else
index 7c2ab600e4cf74621bcafeac5135fad4883f9fe0..fae5bb87a8acdb114f583117955acd51c0650165 100644 (file)
@@ -550,9 +550,23 @@ int event_config_set_num_cpus_hint(struct event_config *cfg, int cpus);
  * avoid priority inversions where multiple low-priority events keep us from
  * polling for high-priority events, but at the expense of slightly decreasing
  * the throughput.  Use it with caution!
+ *
+ * @param cfg The event_base configuration object.
+ * @param max_interval An interval after which Libevent should stop running
+ *     callbacks and check for more events, or NULL if there should be
+ *     no such interval.
+ * @param max_callbacks A number of callbacks after which Libevent should
+ *     stop running callbacks and check for more events, or -1 if there
+ *     should be no such limit.
+ * @param min_priority A priority below which max_interval and max_callbacks
+ *     should not be enforced.  If this is set to 0, they are enforced
+ *     for events of every priority; if it's set to 1, they're enforced
+ *     for events of priority 1 and above, and so on.
+ * @return 0 on success, -1 on failure.
  **/
 int event_config_set_max_dispatch_interval(struct event_config *cfg,
-    const struct timeval *max_interval, int max_callbacks);
+    const struct timeval *max_interval, int max_callbacks,
+    int min_priority);
 
 /**
   Initialize the event API.