mirror of
https://github.com/libevent/libevent.git
synced 2025-01-31 09:12:55 +08:00
Merge remote-tracking branch 'origin/patches-2.0'
Conflicts: event.c
This commit is contained in:
commit
2e882a071b
@ -213,6 +213,11 @@ struct event_base {
|
|||||||
int event_gotterm;
|
int event_gotterm;
|
||||||
/** Set if we should terminate the loop immediately */
|
/** Set if we should terminate the loop immediately */
|
||||||
int event_break;
|
int event_break;
|
||||||
|
/** Set if we should start a new instance of the loop immediately. */
|
||||||
|
int event_continue;
|
||||||
|
|
||||||
|
/** The currently running priority of events */
|
||||||
|
int event_running_priority;
|
||||||
|
|
||||||
/** Set if we're running the event_base_loop function, to prevent
|
/** Set if we're running the event_base_loop function, to prevent
|
||||||
* reentrant invocation. */
|
* reentrant invocation. */
|
||||||
|
14
event.c
14
event.c
@ -1534,6 +1534,8 @@ event_process_active_single_queue(struct event_base *base,
|
|||||||
if (evutil_timercmp(&now, endtime, >=))
|
if (evutil_timercmp(&now, endtime, >=))
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
if (base->event_continue)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
@ -1606,6 +1608,7 @@ event_process_active(struct event_base *base)
|
|||||||
|
|
||||||
for (i = 0; i < base->nactivequeues; ++i) {
|
for (i = 0; i < base->nactivequeues; ++i) {
|
||||||
if (TAILQ_FIRST(&base->activequeues[i]) != NULL) {
|
if (TAILQ_FIRST(&base->activequeues[i]) != NULL) {
|
||||||
|
base->event_running_priority = i;
|
||||||
activeq = &base->activequeues[i];
|
activeq = &base->activequeues[i];
|
||||||
if (i < limit_after_prio)
|
if (i < limit_after_prio)
|
||||||
c = event_process_active_single_queue(base, activeq,
|
c = event_process_active_single_queue(base, activeq,
|
||||||
@ -1613,9 +1616,10 @@ event_process_active(struct event_base *base)
|
|||||||
else
|
else
|
||||||
c = event_process_active_single_queue(base, activeq,
|
c = event_process_active_single_queue(base, activeq,
|
||||||
maxcb, endtime);
|
maxcb, endtime);
|
||||||
if (c < 0)
|
if (c < 0) {
|
||||||
|
base->event_running_priority = -1;
|
||||||
return -1;
|
return -1;
|
||||||
else if (c > 0)
|
} else if (c > 0)
|
||||||
break; /* Processed a real event; do not
|
break; /* Processed a real event; do not
|
||||||
* consider lower-priority events */
|
* consider lower-priority events */
|
||||||
/* If we get here, all of the events we processed
|
/* If we get here, all of the events we processed
|
||||||
@ -1625,6 +1629,7 @@ event_process_active(struct event_base *base)
|
|||||||
|
|
||||||
event_process_deferred_callbacks(&base->defer_queue,&base->event_break,
|
event_process_deferred_callbacks(&base->defer_queue,&base->event_break,
|
||||||
maxcb-c, endtime);
|
maxcb-c, endtime);
|
||||||
|
base->event_running_priority = -1;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1762,6 +1767,8 @@ event_base_loop(struct event_base *base, int flags)
|
|||||||
base->event_gotterm = base->event_break = 0;
|
base->event_gotterm = base->event_break = 0;
|
||||||
|
|
||||||
while (!done) {
|
while (!done) {
|
||||||
|
base->event_continue = 0;
|
||||||
|
|
||||||
/* Terminate the loop if we have been asked to */
|
/* Terminate the loop if we have been asked to */
|
||||||
if (base->event_gotterm) {
|
if (base->event_gotterm) {
|
||||||
break;
|
break;
|
||||||
@ -2523,6 +2530,9 @@ event_active_nolock_(struct event *ev, int res, short ncalls)
|
|||||||
|
|
||||||
ev->ev_res = res;
|
ev->ev_res = res;
|
||||||
|
|
||||||
|
if (ev->ev_pri < base->event_running_priority)
|
||||||
|
base->event_continue = 1;
|
||||||
|
|
||||||
if (ev->ev_events & EV_SIGNAL) {
|
if (ev->ev_events & EV_SIGNAL) {
|
||||||
#ifndef EVENT__DISABLE_THREAD_SUPPORT
|
#ifndef EVENT__DISABLE_THREAD_SUPPORT
|
||||||
if (base->current_event == ev && !EVBASE_IN_THREAD(base)) {
|
if (base->current_event == ev && !EVBASE_IN_THREAD(base)) {
|
||||||
|
@ -1645,6 +1645,58 @@ test_priorities(void)
|
|||||||
test_priorities_impl(3);
|
test_priorities_impl(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* priority-active-inversion: activate a higher-priority event, and make sure
|
||||||
|
* it keeps us from running a lower-priority event first. */
|
||||||
|
static int n_pai_calls = 0;
|
||||||
|
static struct event pai_events[3];
|
||||||
|
|
||||||
|
static void
|
||||||
|
prio_active_inversion_cb(evutil_socket_t fd, short what, void *arg)
|
||||||
|
{
|
||||||
|
int *call_order = arg;
|
||||||
|
*call_order = n_pai_calls++;
|
||||||
|
if (n_pai_calls == 1) {
|
||||||
|
/* This should activate later, even though it shares a
|
||||||
|
priority with us. */
|
||||||
|
event_active(&pai_events[1], EV_READ, 1);
|
||||||
|
/* This should activate next, since its priority is higher,
|
||||||
|
even though we activated it second. */
|
||||||
|
event_active(&pai_events[2], EV_TIMEOUT, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_priority_active_inversion(void *data_)
|
||||||
|
{
|
||||||
|
struct basic_test_data *data = data_;
|
||||||
|
struct event_base *base = data->base;
|
||||||
|
int call_order[3];
|
||||||
|
int i;
|
||||||
|
tt_int_op(event_base_priority_init(base, 8), ==, 0);
|
||||||
|
|
||||||
|
n_pai_calls = 0;
|
||||||
|
memset(call_order, 0, sizeof(call_order));
|
||||||
|
|
||||||
|
for (i=0;i<3;++i) {
|
||||||
|
event_assign(&pai_events[i], data->base, -1, 0,
|
||||||
|
prio_active_inversion_cb, &call_order[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
event_priority_set(&pai_events[0], 4);
|
||||||
|
event_priority_set(&pai_events[1], 4);
|
||||||
|
event_priority_set(&pai_events[2], 0);
|
||||||
|
|
||||||
|
event_active(&pai_events[0], EV_WRITE, 1);
|
||||||
|
|
||||||
|
event_base_dispatch(base);
|
||||||
|
tt_int_op(n_pai_calls, ==, 3);
|
||||||
|
tt_int_op(call_order[0], ==, 0);
|
||||||
|
tt_int_op(call_order[1], ==, 2);
|
||||||
|
tt_int_op(call_order[2], ==, 1);
|
||||||
|
end:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_multiple_cb(evutil_socket_t fd, short event, void *arg)
|
test_multiple_cb(evutil_socket_t fd, short event, void *arg)
|
||||||
@ -2421,6 +2473,7 @@ struct testcase_t main_testcases[] = {
|
|||||||
{ "persistent_active_timeout", test_persistent_active_timeout,
|
{ "persistent_active_timeout", test_persistent_active_timeout,
|
||||||
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
|
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
|
||||||
LEGACY(priorities, TT_FORK|TT_NEED_BASE),
|
LEGACY(priorities, TT_FORK|TT_NEED_BASE),
|
||||||
|
BASIC(priority_active_inversion, TT_FORK|TT_NEED_BASE),
|
||||||
{ "common_timeout", test_common_timeout, TT_FORK|TT_NEED_BASE,
|
{ "common_timeout", test_common_timeout, TT_FORK|TT_NEED_BASE,
|
||||||
&basic_setup, NULL },
|
&basic_setup, NULL },
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user