from trunk: fix a problem with epoll() and reinit; repoted by Alexander Drozdov

svn:r919
This commit is contained in:
Niels Provos 2008-07-25 00:53:17 +00:00
parent 730c7132bd
commit 7c7ab27960
4 changed files with 48 additions and 5 deletions

View File

@ -12,6 +12,7 @@ Changes in 1.4.6-stable:
o Fix a bug where setting the timeout on a bufferevent would take not effect if the event was already pending.
o Fix a memory leak when using signals for some event bases; reported by Alexander Drozdov.
o Add libevent.vcproj file to distribution to help with Windows build.
o Fix a problem with epoll() and reinit; problem report by Alexander Drozdov.
Changes in 1.4.5-stable:
o Fix connection keep-alive behavior for HTTP/1.0
@ -89,7 +90,6 @@ Changes in 1.4.1-beta:
o The configure script now takes an --enable-gcc-warnigns option that turns on many optional gcc warnings. (Nick has been building with these for a while, but they might be useful to other developers.)
o When building with GCC, use the "format" attribute to verify type correctness of calls to printf-like functions.
o removed linger from http server socket; reported by Ilya Martynov
o Rewrite win32.c backend to be O(n lg n) rather than O(n^2)
o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr.
o demote most http warnings to debug messages
o Fix Solaris compilation; from Magne Mahre

20
event.c
View File

@ -237,9 +237,20 @@ event_base_free(struct event_base *base)
++n_deleted;
}
for (i = 0; i < base->nactivequeues; ++i) {
for (ev = TAILQ_FIRST(base->activequeues[i]); ev; ) {
struct event *next = TAILQ_NEXT(ev, ev_active_next);
if (!(ev->ev_flags & EVLIST_INTERNAL)) {
event_del(ev);
++n_deleted;
}
ev = next;
}
}
if (n_deleted)
event_debug(("%s: %d events were still set in base",
__func__, n_deleted));
__func__, n_deleted));
if (base->evsel->dealloc != NULL)
base->evsel->dealloc(base, base->evbase);
@ -272,6 +283,13 @@ event_reinit(struct event_base *base)
if (!evsel->need_reinit)
return (0);
/* prevent internal delete */
if (base->sig.ev_signal_added) {
event_queue_remove(base, &base->sig.ev_signal,
EVLIST_INSERTED);
base->sig.ev_signal_added = 0;
}
if (base->evsel->dealloc != NULL)
base->evsel->dealloc(base, base->evbase);
evbase = base->evbase = evsel->init(base);

View File

@ -334,7 +334,6 @@ evsignal_dealloc(struct event_base *base)
for (i = 0; i < NSIG; ++i) {
if (i < base->sig.sh_old_max && base->sig.sh_old[i] != NULL)
_evsignal_restore_handler(base, i);
assert(TAILQ_EMPTY(&base->sig.evsigevents[0]));
}
EVUTIL_CLOSESOCKET(base->sig.ev_signal_pair[0]);

View File

@ -452,11 +452,25 @@ test_simpletimeout(void)
#ifndef WIN32
extern struct event_base *current_base;
static void
child_signal_cb(int fd, short event, void *arg)
{
struct timeval tv;
int *pint = arg;
*pint = 1;
tv.tv_usec = 500000;
tv.tv_sec = 0;
event_loopexit(&tv);
}
static void
test_fork(void)
{
int status;
struct event ev;
int status, got_sigchld = 0;
struct event ev, sig_ev;
pid_t pid;
setup_test("After fork: ");
@ -467,6 +481,9 @@ test_fork(void)
if (event_add(&ev, NULL) == -1)
exit(1);
signal_set(&sig_ev, SIGCHLD, child_signal_cb, &got_sigchld);
signal_add(&sig_ev, NULL);
if ((pid = fork()) == 0) {
/* in the child */
if (event_reinit(current_base) == -1) {
@ -474,6 +491,8 @@ test_fork(void)
exit(1);
}
signal_del(&sig_ev);
called = 0;
event_dispatch();
@ -505,6 +524,13 @@ test_fork(void)
event_dispatch();
if (!got_sigchld) {
fprintf(stdout, "FAILED (sigchld)\n");
exit(1);
}
signal_del(&sig_ev);
cleanup_test();
}