mirror of
https://github.com/cuberite/libevent.git
synced 2025-08-04 09:46:23 -04:00
Merge remote-tracking branch 'origin/patches-2.0'
Conflicts: event.c Edits required in: evmap.c
This commit is contained in:
commit
fe0afabb59
@ -356,6 +356,14 @@ void event_active_nolock(struct event *ev, int res, short count);
|
|||||||
void event_base_add_virtual(struct event_base *base);
|
void event_base_add_virtual(struct event_base *base);
|
||||||
void event_base_del_virtual(struct event_base *base);
|
void event_base_del_virtual(struct event_base *base);
|
||||||
|
|
||||||
|
/** For debugging: unless assertions are disabled, verify the referential
|
||||||
|
integrity of the internal data structures of 'base'. This operation can
|
||||||
|
be expensive.
|
||||||
|
|
||||||
|
Returns on success; aborts on failure.
|
||||||
|
*/
|
||||||
|
void event_base_assert_ok(struct event_base *base);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
46
event.c
46
event.c
@ -864,6 +864,10 @@ event_reinit(struct event_base *base)
|
|||||||
event_queue_remove_inserted(base, &base->sig.ev_signal);
|
event_queue_remove_inserted(base, &base->sig.ev_signal);
|
||||||
if (base->sig.ev_signal.ev_flags & EVLIST_ACTIVE)
|
if (base->sig.ev_signal.ev_flags & EVLIST_ACTIVE)
|
||||||
event_queue_remove_active(base, &base->sig.ev_signal);
|
event_queue_remove_active(base, &base->sig.ev_signal);
|
||||||
|
if (base->sig.ev_signal_pair[0] != -1)
|
||||||
|
EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[0]);
|
||||||
|
if (base->sig.ev_signal_pair[1] != -1)
|
||||||
|
EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[1]);
|
||||||
base->sig.ev_signal_added = 0;
|
base->sig.ev_signal_added = 0;
|
||||||
}
|
}
|
||||||
if (base->th_notify_fd[0] != -1) {
|
if (base->th_notify_fd[0] != -1) {
|
||||||
@ -899,6 +903,13 @@ event_reinit(struct event_base *base)
|
|||||||
|
|
||||||
TAILQ_FOREACH(ev, &base->eventqueue, ev_next) {
|
TAILQ_FOREACH(ev, &base->eventqueue, ev_next) {
|
||||||
if (ev->ev_events & (EV_READ|EV_WRITE)) {
|
if (ev->ev_events & (EV_READ|EV_WRITE)) {
|
||||||
|
if (ev == &base->sig.ev_signal) {
|
||||||
|
/* If we run into the ev_signal event, it's only
|
||||||
|
* in eventqueue because some signal event was
|
||||||
|
* added, which made evsig_add re-add ev_signal.
|
||||||
|
* So don't double-add it. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (evmap_io_add(base, ev->ev_fd, ev) == -1)
|
if (evmap_io_add(base, ev->ev_fd, ev) == -1)
|
||||||
res = -1;
|
res = -1;
|
||||||
} else if (ev->ev_events & EV_SIGNAL) {
|
} else if (ev->ev_events & EV_SIGNAL) {
|
||||||
@ -3048,3 +3059,38 @@ event_global_setup_locks_(const int enable_locks)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void
|
||||||
|
event_base_assert_ok(struct event_base *base)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
EVBASE_ACQUIRE_LOCK(base, th_base_lock);
|
||||||
|
evmap_check_integrity(base);
|
||||||
|
|
||||||
|
/* Check the heap property */
|
||||||
|
for (i = 1; i < (int)base->timeheap.n; ++i) {
|
||||||
|
int parent = (i - 1) / 2;
|
||||||
|
struct event *ev, *p_ev;
|
||||||
|
ev = base->timeheap.p[i];
|
||||||
|
p_ev = base->timeheap.p[parent];
|
||||||
|
EVUTIL_ASSERT(ev->ev_flags & EV_TIMEOUT);
|
||||||
|
EVUTIL_ASSERT(evutil_timercmp(&p_ev->ev_timeout, &ev->ev_timeout, <=));
|
||||||
|
EVUTIL_ASSERT(ev->ev_timeout_pos.min_heap_idx == i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check that the common timeouts are fine */
|
||||||
|
for (i = 0; i < base->n_common_timeouts; ++i) {
|
||||||
|
struct common_timeout_list *ctl = base->common_timeout_queues[i];
|
||||||
|
struct event *last=NULL, *ev;
|
||||||
|
TAILQ_FOREACH(ev, &ctl->events, ev_timeout_pos.ev_next_with_common_timeout) {
|
||||||
|
if (last)
|
||||||
|
EVUTIL_ASSERT(evutil_timercmp(&last->ev_timeout, &ev->ev_timeout, <=));
|
||||||
|
EVUTIL_ASSERT(ev->ev_flags & EV_TIMEOUT);
|
||||||
|
EVUTIL_ASSERT(is_common_timeout(&ev->ev_timeout,base));
|
||||||
|
EVUTIL_ASSERT(COMMON_TIMEOUT_IDX(&ev->ev_timeout) == i);
|
||||||
|
last = ev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EVBASE_RELEASE_LOCK(base, th_base_lock);
|
||||||
|
}
|
||||||
|
@ -87,4 +87,6 @@ void evmap_signal_active(struct event_base *base, evutil_socket_t signum, int nc
|
|||||||
|
|
||||||
void *evmap_io_get_fdinfo(struct event_io_map *ctx, evutil_socket_t fd);
|
void *evmap_io_get_fdinfo(struct event_io_map *ctx, evutil_socket_t fd);
|
||||||
|
|
||||||
|
void evmap_check_integrity(struct event_base *base);
|
||||||
|
|
||||||
#endif /* _EVMAP_H_ */
|
#endif /* _EVMAP_H_ */
|
||||||
|
63
evmap.c
63
evmap.c
@ -721,3 +721,66 @@ event_changelist_del(struct event_base *base, evutil_socket_t fd, short old, sho
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
evmap_check_integrity(struct event_base *base)
|
||||||
|
{
|
||||||
|
#define EVLIST_X_SIGFOUND 0x1000
|
||||||
|
#define EVLIST_X_IOFOUND 0x2000
|
||||||
|
|
||||||
|
int i;
|
||||||
|
struct event *ev;
|
||||||
|
struct event_io_map *io = &base->io;
|
||||||
|
struct event_signal_map *sigmap = &base->sigmap;
|
||||||
|
int nsignals, ntimers, nio;
|
||||||
|
nsignals = ntimers = nio = 0;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(ev, &base->eventqueue, ev_next) {
|
||||||
|
EVUTIL_ASSERT(ev->ev_flags & EVLIST_INSERTED);
|
||||||
|
EVUTIL_ASSERT(ev->ev_flags & EVLIST_INIT);
|
||||||
|
ev->ev_flags &= ~(EVLIST_X_SIGFOUND|EVLIST_X_IOFOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0; i < io->nentries; ++i) {
|
||||||
|
struct evmap_io *ctx = io->entries[i];
|
||||||
|
if (!ctx)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
LIST_FOREACH(ev, &ctx->events, ev_io_next) {
|
||||||
|
EVUTIL_ASSERT(!(ev->ev_flags & EVLIST_X_IOFOUND));
|
||||||
|
EVUTIL_ASSERT(ev->ev_fd == i);
|
||||||
|
ev->ev_flags |= EVLIST_X_IOFOUND;
|
||||||
|
nio++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < sigmap->nentries; ++i) {
|
||||||
|
struct evmap_signal *ctx = sigmap->entries[i];
|
||||||
|
if (!ctx)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
LIST_FOREACH(ev, &ctx->events, ev_signal_next) {
|
||||||
|
EVUTIL_ASSERT(!(ev->ev_flags & EVLIST_X_SIGFOUND));
|
||||||
|
EVUTIL_ASSERT(ev->ev_fd == i);
|
||||||
|
ev->ev_flags |= EVLIST_X_SIGFOUND;
|
||||||
|
nsignals++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TAILQ_FOREACH(ev, &base->eventqueue, ev_next) {
|
||||||
|
if (ev->ev_events & (EV_READ|EV_WRITE)) {
|
||||||
|
EVUTIL_ASSERT(ev->ev_flags & EVLIST_X_IOFOUND);
|
||||||
|
--nio;
|
||||||
|
}
|
||||||
|
if (ev->ev_events & EV_SIGNAL) {
|
||||||
|
EVUTIL_ASSERT(ev->ev_flags & EVLIST_X_SIGFOUND);
|
||||||
|
--nsignals;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EVUTIL_ASSERT(nio == 0);
|
||||||
|
EVUTIL_ASSERT(nsignals == 0);
|
||||||
|
/* There is no "EVUTIL_ASSERT(ntimers == 0)": eventqueue is only for
|
||||||
|
* pending signals and io events.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
@ -677,9 +677,11 @@ test_persistent_active_timeout(void *ptr)
|
|||||||
tv_exit.tv_usec = 600 * 1000;
|
tv_exit.tv_usec = 600 * 1000;
|
||||||
event_base_loopexit(base, &tv_exit);
|
event_base_loopexit(base, &tv_exit);
|
||||||
|
|
||||||
|
event_base_assert_ok(base);
|
||||||
evutil_gettimeofday(&start, NULL);
|
evutil_gettimeofday(&start, NULL);
|
||||||
|
|
||||||
event_base_dispatch(base);
|
event_base_dispatch(base);
|
||||||
|
event_base_assert_ok(base);
|
||||||
|
|
||||||
tt_int_op(res.n, ==, 3);
|
tt_int_op(res.n, ==, 3);
|
||||||
tt_int_op(res.events[0], ==, EV_READ);
|
tt_int_op(res.events[0], ==, EV_READ);
|
||||||
@ -748,9 +750,11 @@ test_common_timeout(void *ptr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event_base_assert_ok(base);
|
||||||
event_base_dispatch(base);
|
event_base_dispatch(base);
|
||||||
|
|
||||||
evutil_gettimeofday(&now, NULL);
|
evutil_gettimeofday(&now, NULL);
|
||||||
|
event_base_assert_ok(base);
|
||||||
|
|
||||||
for (i=0; i<10; ++i) {
|
for (i=0; i<10; ++i) {
|
||||||
struct timeval tmp;
|
struct timeval tmp;
|
||||||
@ -824,12 +828,19 @@ test_fork(void)
|
|||||||
evsignal_set(&sig_ev, SIGCHLD, child_signal_cb, &got_sigchld);
|
evsignal_set(&sig_ev, SIGCHLD, child_signal_cb, &got_sigchld);
|
||||||
evsignal_add(&sig_ev, NULL);
|
evsignal_add(&sig_ev, NULL);
|
||||||
|
|
||||||
|
event_base_assert_ok(current_base);
|
||||||
|
TT_BLATHER(("Before fork"));
|
||||||
if ((pid = fork()) == 0) {
|
if ((pid = fork()) == 0) {
|
||||||
/* in the child */
|
/* in the child */
|
||||||
|
TT_BLATHER(("In child, before reinit"));
|
||||||
|
event_base_assert_ok(current_base);
|
||||||
if (event_reinit(current_base) == -1) {
|
if (event_reinit(current_base) == -1) {
|
||||||
fprintf(stdout, "FAILED (reinit)\n");
|
fprintf(stdout, "FAILED (reinit)\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
TT_BLATHER(("After reinit"));
|
||||||
|
event_base_assert_ok(current_base);
|
||||||
|
TT_BLATHER(("After assert-ok"));
|
||||||
|
|
||||||
evsignal_del(&sig_ev);
|
evsignal_del(&sig_ev);
|
||||||
|
|
||||||
@ -852,10 +863,12 @@ test_fork(void)
|
|||||||
tt_fail_perror("write");
|
tt_fail_perror("write");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TT_BLATHER(("Before waitpid"));
|
||||||
if (waitpid(pid, &status, 0) == -1) {
|
if (waitpid(pid, &status, 0) == -1) {
|
||||||
fprintf(stdout, "FAILED (fork)\n");
|
fprintf(stdout, "FAILED (fork)\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
TT_BLATHER(("After waitpid"));
|
||||||
|
|
||||||
if (WEXITSTATUS(status) != 76) {
|
if (WEXITSTATUS(status) != 76) {
|
||||||
fprintf(stdout, "FAILED (exit): %d\n", WEXITSTATUS(status));
|
fprintf(stdout, "FAILED (exit): %d\n", WEXITSTATUS(status));
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
#include "tinytest.h"
|
#include "tinytest.h"
|
||||||
#include "tinytest_macros.h"
|
#include "tinytest_macros.h"
|
||||||
#include "../iocp-internal.h"
|
#include "../iocp-internal.h"
|
||||||
|
#include "../event-internal.h"
|
||||||
|
|
||||||
long
|
long
|
||||||
timeval_msec_diff(const struct timeval *start, const struct timeval *end)
|
timeval_msec_diff(const struct timeval *start, const struct timeval *end)
|
||||||
@ -257,8 +258,10 @@ basic_test_cleanup(const struct testcase_t *testcase, void *ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (testcase->flags & TT_NEED_BASE) {
|
if (testcase->flags & TT_NEED_BASE) {
|
||||||
if (data->base)
|
if (data->base) {
|
||||||
|
event_base_assert_ok(data->base);
|
||||||
event_base_free(data->base);
|
event_base_free(data->base);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(data);
|
free(data);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user