kqueue: check for EV_ERROR in .flags

if kevent() returns events, check for EV_ERROR in event flags, too.
This commit is contained in:
Florian Westphal 2007-12-27 18:25:26 +00:00
parent f99f9a8f02
commit 2ce5b734bd
1 changed files with 23 additions and 28 deletions

View File

@ -12,7 +12,7 @@
#include "portab.h" #include "portab.h"
static char UNUSED id[] = "$Id: io.c,v 1.26 2007/11/18 15:05:35 alex Exp $"; static char UNUSED id[] = "$Id: io.c,v 1.27 2007/12/27 18:25:26 fw Exp $";
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
@ -842,15 +842,9 @@ io_dispatch_kqueue(struct timeval *tv)
newevents_len = (int) array_length(&io_evcache, sizeof (struct kevent)); newevents_len = (int) array_length(&io_evcache, sizeof (struct kevent));
newevents = (newevents_len > 0) ? array_start(&io_evcache) : NULL; newevents = (newevents_len > 0) ? array_start(&io_evcache) : NULL;
assert(newevents_len >= 0); assert(newevents_len >= 0);
if (newevents_len < 0)
newevents_len = 0; ret = kevent(io_masterfd, newevents, newevents_len, kev, 100, &ts);
#ifdef DEBUG if (newevents && ret != -1)
if (newevents_len)
assert(newevents != NULL);
#endif
ret = kevent(io_masterfd, newevents, newevents_len, kev,
100, &ts);
if ((newevents_len>0) && ret != -1)
array_trunc(&io_evcache); array_trunc(&io_evcache);
total += ret; total += ret;
@ -858,30 +852,31 @@ io_dispatch_kqueue(struct timeval *tv)
return total; return total;
for (i = 0; i < ret; i++) { for (i = 0; i < ret; i++) {
if (kev[i].flags & EV_EOF) { #ifdef DEBUG_IO
#ifdef DEBUG LogDebug("fd %d, kev.flags: %x", (int)kev[i].ident, kev[i].flags);
LogDebug("kev.flag has EV_EOF set, setting IO_ERROR",
kev[i].filter, kev[i].ident);
#endif #endif
if (kev[i].flags & (EV_EOF|EV_ERROR)) {
if (kev[i].flags & EV_ERROR)
Log(LOG_ERR, "kevent fd %d: EV_ERROR (%s)",
(int)kev[i].ident, strerror((int)kev[i].data));
io_docallback((int)kev[i].ident, IO_ERROR); io_docallback((int)kev[i].ident, IO_ERROR);
continue; continue;
} }
switch (kev[i].filter) { switch (kev[i].filter) {
case EVFILT_READ: case EVFILT_READ:
io_docallback((int)kev[i].ident, IO_WANTREAD); io_docallback((int)kev[i].ident, IO_WANTREAD);
break; break;
case EVFILT_WRITE: case EVFILT_WRITE:
io_docallback((int)kev[i].ident, IO_WANTWRITE); io_docallback((int)kev[i].ident, IO_WANTWRITE);
break; break;
default: default:
#ifdef DEBUG LogDebug("Unknown kev.filter number %d for fd %d",
LogDebug("Unknown kev.filter number %d for fd %d", kev[i].filter, kev[i].ident);
kev[i].filter, kev[i].ident); /* Fall through */ /* Fall through */
#endif case EV_ERROR:
case EV_ERROR: io_docallback((int)kev[i].ident, IO_ERROR);
io_docallback((int)kev[i].ident, IO_ERROR); break;
break;
} }
} }
ts.tv_sec = 0; ts.tv_sec = 0;