#include "ircd.h"
#include "ircd_alloc.h"
+#include "ircd_features.h"
#include "ircd_log.h"
#include "s_debug.h"
#define KQUEUE_ERROR_THRESHOLD 20 /* after 20 kqueue errors, restart */
#define ERROR_EXPIRE_TIME 3600 /* expire errors after an hour */
-#define POLLS_PER_KQUEUE 20 /* get 20 kevents per turn */
-
static struct Socket** sockList;
static int kqueue_max;
static int kqueue_id;
i++; /* advance count... */
}
- if (kevent(kqueue_id, chglist, i, 0, 0, 0) < 0)
+ if (kevent(kqueue_id, chglist, i, 0, 0, 0) < 0 && errno != EBADF)
event_generate(ET_ERROR, sock, errno); /* report error */
}
static void
engine_loop(struct Generators* gen)
{
- struct kevent events[POLLS_PER_KQUEUE];
+ struct kevent *events;
+ int events_count;
struct Socket* sock;
struct timespec wait;
int nevs;
int errcode;
size_t codesize;
+ if ((events_count = feature_int(FEAT_POLLS_PER_LOOP)) < 20)
+ events_count = 20;
+ events = (struct kevent *)MyMalloc(sizeof(struct kevent) * events_count);
+
while (running) {
+ if ((i = feature_int(FEAT_POLLS_PER_LOOP)) >= 20 && i != events_count) {
+ events = (struct kevent *)MyRealloc(events, sizeof(struct kevent) * i);
+ events_count = i;
+ }
+
/* set up the sleep time */
wait.tv_sec = timer_next(gen) ? (timer_next(gen) - CurrentTime) : -1;
wait.tv_nsec = 0;
CurrentTime, wait.tv_sec));
/* check for active events */
- nevs = kevent(kqueue_id, 0, 0, events, POLLS_PER_KQUEUE,
+ nevs = kevent(kqueue_id, 0, 0, events, events_count,
wait.tv_sec < 0 ? 0 : &wait);
CurrentTime = time(0); /* set current time... */
/* Log the kqueue error */
log_write(LS_SOCKET, L_ERROR, 0, "kevent() error: %m");
if (!errors++)
- timer_add(&clear_error, error_clear, 0, TT_PERIODIC,
+ timer_add(timer_init(&clear_error), error_clear, 0, TT_PERIODIC,
ERROR_EXPIRE_TIME);
else if (errors > KQUEUE_ERROR_THRESHOLD) /* too many errors... */
server_restart("too many kevent errors");