make event_add not change any state if it fails; repoted by Ian Bell

svn:r923
This commit is contained in:
Niels Provos 2008-07-25 01:29:54 +00:00
parent 1aa6826f62
commit cca2f8fa0e
2 changed files with 27 additions and 11 deletions

View File

@ -120,6 +120,7 @@ Changes in current version:
o Support multiple events listening on the same signal; make signals regular events that go on the same event queue; problem report by Alexander Drozdov.
o Fix a problem with epoll() and reinit; problem report by Alexander Drozdov.
o Fix off-by-one errors in devpoll; from Ian Bell
o Make event_add not change any state if it fails; reported by Ian Bell.
Changes in 1.4.0:
o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr.

37
event.c
View File

@ -1027,14 +1027,36 @@ event_add_internal(struct event *ev, const struct timeval *tv)
assert(!(ev->ev_flags & ~EVLIST_ALL));
if (tv != NULL) {
/*
* prepare for timeout insertion further below, if we get a
* failure on any step, we should not change any state.
*/
if (tv != NULL && !(ev->ev_flags & EVLIST_TIMEOUT)) {
if (min_heap_reserve(&base->timeheap,
1 + min_heap_size(&base->timeheap)) == -1)
return (-1); /* ENOMEM == errno */
}
if ((ev->ev_events & (EV_READ|EV_WRITE|EV_SIGNAL)) &&
!(ev->ev_flags & (EVLIST_INSERTED|EVLIST_ACTIVE))) {
res = evsel->add(evbase, ev);
if (res != -1)
event_queue_insert(base, ev, EVLIST_INSERTED);
}
/*
* we should change the timout state only if the previous event
* addition succeeded.
*/
if (res != -1 && tv != NULL) {
struct timeval now;
/*
* we already reserved memory above for the case where we
* are not replacing an exisiting timeout.
*/
if (ev->ev_flags & EVLIST_TIMEOUT)
event_queue_remove(base, ev, EVLIST_TIMEOUT);
else if (min_heap_reserve(&base->timeheap,
1 + min_heap_size(&base->timeheap)) == -1)
return (-1); /* ENOMEM == errno */
/* Check if it is active due to a timeout. Rescheduling
* this timeout before the callback can be executed
@ -1064,13 +1086,6 @@ event_add_internal(struct event *ev, const struct timeval *tv)
event_queue_insert(base, ev, EVLIST_TIMEOUT);
}
if ((ev->ev_events & (EV_READ|EV_WRITE|EV_SIGNAL)) &&
!(ev->ev_flags & (EVLIST_INSERTED|EVLIST_ACTIVE))) {
res = evsel->add(evbase, ev);
if (res != -1)
event_queue_insert(base, ev, EVLIST_INSERTED);
}
/* if we are not in the right thread, we need to wake up the loop */
if (res != -1 && !EVTHREAD_IN_THREAD(base))
send(base->th_notify_fd[1], "", 1, 0);