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
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;
};
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) {
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);
}
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,
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);
}
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);
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
* 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.