/* private data */
static int kqueue_fd[MAX_THREADS]; // per-thread kqueue_fd
static THREAD_LOCAL struct kevent *kev = NULL;
+static struct kevent *kev_out = NULL; // Trash buffer for kevent() to write the eventlist in
/*
* kqueue() poller
int updt_idx, en;
int changes = 0;
+ timeout.tv_sec = 0;
+ timeout.tv_nsec = 0;
/* first, scan the update list to find changes */
for (updt_idx = 0; updt_idx < fd_nbupdt; updt_idx++) {
fd = fd_updt[updt_idx];
HA_ATOMIC_OR(&fdtab[fd].polled_mask, tid_bit);
}
}
- if (changes)
- kevent(kqueue_fd[tid], kev, changes, NULL, 0, NULL);
+ if (changes) {
+#ifdef EV_RECEIPT
+ kev[0].flags |= EV_RECEIPT;
+#else
+ /* If EV_RECEIPT isn't defined, just add an invalid entry,
+ * so that we get an error and kevent() stops before scanning
+ * the kqueue.
+ */
+ EV_SET(&kev[changes++], -1, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
+#endif
+ kevent(kqueue_fd[tid], kev, changes, kev_out, changes, &timeout);
+ }
fd_nbupdt = 0;
delta_ms = 0;
- timeout.tv_sec = 0;
- timeout.tv_nsec = 0;
if (!exp) {
delta_ms = MAX_DELAY_MS;
{
int fd;
- /* we can have up to two events per fd (*/
- kev = calloc(1, sizeof(struct kevent) * 2 * global.maxsock);
+ /* we can have up to two events per fd, so allocate enough to store
+ * 2*fd event, and an extra one, in case EV_RECEIPT isn't defined,
+ * so that we can add an invalid entry and get an error, to avoid
+ * scanning the kqueue uselessly.
+ */
+ kev = calloc(1, sizeof(struct kevent) * (2 * global.maxsock + 1));
if (kev == NULL)
goto fail_alloc;
{
p->private = NULL;
+ /* we can have up to two events per fd, so allocate enough to store
+ * 2*fd event, and an extra one, in case EV_RECEIPT isn't defined,
+ * so that we can add an invalid entry and get an error, to avoid
+ * scanning the kqueue uselessly.
+ */
+ kev_out = calloc(1, sizeof(struct kevent) * (2 * global.maxsock + 1));
+ if (!kev_out)
+ goto fail_alloc;
+
kqueue_fd[tid] = kqueue();
if (kqueue_fd[tid] < 0)
goto fail_fd;
return 1;
fail_fd:
+ free(kev_out);
+ kev_out = NULL;
+fail_alloc:
p->pref = 0;
return 0;
}
p->private = NULL;
p->pref = 0;
+ if (kev_out) {
+ free(kev_out);
+ kev_out = NULL;
+ }
}
/*