#include "portab.h"
-static char UNUSED id[] = "$Id: io.c,v 1.23 2006/12/26 16:00:46 alex Exp $";
+static char UNUSED id[] = "$Id: io.c,v 1.28 2008/01/02 10:29:51 fw Exp $";
#include <assert.h>
#include <stdlib.h>
/* #define DEBUG_IO */
typedef struct {
+#ifdef PROTOTYPES
void (*callback)(int, short);
+#else
+ void (*callback)();
+#endif
short what;
} io_event;
static array pollfds;
static int poll_maxfd;
-static bool io_event_change_poll(int fd, short what);
+static bool io_event_change_poll PARAMS((int fd, short what));
#endif
#ifdef IO_USE_DEVPOLL
io_event *i = io_event_get(fd);
if (!i) return false;
- if (i->what == what) return true;
+
+ if ((i->what & what) == what) /* event type is already registered */
+ return true;
#ifdef DEBUG_IO
- Log(LOG_DEBUG, "io_event_add(): fd %d (arg: %d), what %d.", i->fd, fd, what);
+ Log(LOG_DEBUG, "io_event_add(): fd %d, what %d.", fd, what);
#endif
i->what |= what;
#ifdef IO_USE_EPOLL
write(io_masterfd, &p, sizeof p);
}
#else
-static inline void io_close_devpoll(int UNUSED x) { /* NOTHING */ }
+static inline void
+io_close_devpoll(int UNUSED x)
+{
+ /* NOTHING */
+}
#endif
}
}
#else
-static inline void io_close_select(int UNUSED x) { /* NOTHING */ }
+static inline void
+io_close_select(int UNUSED x)
+{
+ /* NOTHING */
+}
#endif
#endif
if (!i) return false;
+ if (!(i->what & what)) /* event is already disabled */
+ return true;
+
i->what &= ~what;
#ifdef IO_USE_DEVPOLL
newevents_len = (int) array_length(&io_evcache, sizeof (struct kevent));
newevents = (newevents_len > 0) ? array_start(&io_evcache) : NULL;
assert(newevents_len >= 0);
- if (newevents_len < 0)
- newevents_len = 0;
-#ifdef DEBUG
- if (newevents_len)
- assert(newevents != NULL);
-#endif
- ret = kevent(io_masterfd, newevents, newevents_len, kev,
- 100, &ts);
- if ((newevents_len>0) && ret != -1)
+
+ ret = kevent(io_masterfd, newevents, newevents_len, kev, 100, &ts);
+ if (newevents && ret != -1)
array_trunc(&io_evcache);
total += ret;
return total;
for (i = 0; i < ret; i++) {
- if (kev[i].flags & EV_EOF) {
-#ifdef DEBUG
- LogDebug("kev.flag has EV_EOF set, setting IO_ERROR",
- kev[i].filter, kev[i].ident);
+#ifdef DEBUG_IO
+ LogDebug("fd %d, kev.flags: %x", (int)kev[i].ident, kev[i].flags);
#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);
continue;
}
switch (kev[i].filter) {
- case EVFILT_READ:
- io_docallback((int)kev[i].ident, IO_WANTREAD);
- break;
- case EVFILT_WRITE:
- io_docallback((int)kev[i].ident, IO_WANTWRITE);
- break;
- default:
-#ifdef DEBUG
- LogDebug("Unknown kev.filter number %d for fd %d",
- kev[i].filter, kev[i].ident); /* Fall through */
-#endif
- case EV_ERROR:
- io_docallback((int)kev[i].ident, IO_ERROR);
- break;
+ case EVFILT_READ:
+ io_docallback((int)kev[i].ident, IO_WANTREAD);
+ break;
+ case EVFILT_WRITE:
+ io_docallback((int)kev[i].ident, IO_WANTWRITE);
+ break;
+ default:
+ LogDebug("Unknown kev.filter number %d for fd %d",
+ kev[i].filter, kev[i].ident);
+ /* Fall through */
+ case EV_ERROR:
+ io_docallback((int)kev[i].ident, IO_ERROR);
+ break;
}
}
ts.tv_sec = 0;