* Fix a bug that prevented a knote with the EV_DISPATCH flag from

being re-enabled after an event had been triggered. 
    [Credit to Julien Blache for finding and researching this bug]



git-svn-id: svn://svn.code.sf.net/p/libkqueue/code/trunk@252 fb4e3144-bc1c-4b72-a658-5bcd248dd7f7
This commit is contained in:
mheily 2010-07-22 02:59:28 +00:00
parent 2b5999dd18
commit 18ad3e9bc0
4 changed files with 27 additions and 3 deletions

View File

@ -1,3 +1,10 @@
2010-07-21 HEAD
------------------------------------------------------------------------
* Fix a bug that prevented a knote with the EV_DISPATCH flag from
being re-enabled after an event had been triggered.
[Credit to Julien Blache for finding and researching this bug]
2010-06-08 v0.7 r248
------------------------------------------------------------------------

View File

@ -127,6 +127,11 @@ kevent_copyin_one(struct kqueue *kq, const struct kevent *src)
struct filter *filt;
int rv;
if (src->flags & EV_DISPATCH && src->flags & EV_ONESHOT) {
errno = EINVAL;
return (-1);
}
if (filter_lookup(&filt, kq, src->filter) < 0)
return (-1);

View File

@ -138,9 +138,10 @@ evfilt_socket_copyout(struct filter *filt,
dst->data = 0;
}
if (kn->kev.flags & EV_DISPATCH)
if (kn->kev.flags & EV_DISPATCH) {
socket_knote_delete(filt->kf_pfd, kn->kev.ident);
KNOTE_DISABLE(kn);
if (kn->kev.flags & EV_ONESHOT) {
} else if (kn->kev.flags & EV_ONESHOT) {
socket_knote_delete(filt->kf_pfd, kn->kev.ident);
knote_free(filt, kn);
}
@ -185,7 +186,10 @@ evfilt_socket_knote_modify(struct filter *filt, struct knote *kn,
int
evfilt_socket_knote_delete(struct filter *filt, struct knote *kn)
{
return epoll_update(EPOLL_CTL_DEL, filt, kn, NULL);
if (kn->kev.flags & EV_DISABLE)
return (0);
else
return epoll_update(EPOLL_CTL_DEL, filt, kn, NULL);
}
int

View File

@ -201,6 +201,14 @@ test_kevent_socket_dispatch(void)
kevent_cmp(&kev, kevent_get(kqfd));
test_no_kevents(kqfd);
/* Re-enable the kevent */
/* FIXME- is EV_DISPATCH needed when rearming ? */
kevent_add(kqfd, &kev, sockfd[0], EVFILT_READ, EV_ENABLE | EV_DISPATCH, 0, 0, &sockfd[0]);
kev.data = 1;
kev.flags = EV_ADD | EV_DISPATCH; /* FIXME: may not be portable */
kevent_cmp(&kev, kevent_get(kqfd));
test_no_kevents(kqfd);
/* Since the knote is disabled, the EV_DELETE operation succeeds. */
kevent_add(kqfd, &kev, sockfd[0], EVFILT_READ, EV_DELETE, 0, 0, &sockfd[0]);