<commit_before>/*
 * $Id$
 *
 * XXX: We need to pass sessions back into the event engine when they are
 * reused.  Not sure what the most efficient way is for that.  For now
 * write the session pointer to a pipe which the event engine monitors.
 */

#if defined(HAVE_KQUEUE)

#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>

#include <sys/event.h>

#include "heritage.h"
#include "shmlog.h"
#include "cache.h"
#include "cache_acceptor.h"

static pthread_t vca_kqueue_thread;
static int kq = -1;

static TAILQ_HEAD(,sess) sesshead = TAILQ_HEAD_INITIALIZER(sesshead);
static int pipes[2];

#define NKEV	100

static struct kevent ki[NKEV];
static unsigned nki;

static void
vca_kq_sess(struct sess *sp, int arm)
{

	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
	if (sp->fd < 0)
		return;
	EV_SET(&ki[nki], sp->fd, EVFILT_READ, arm, 0, 0, sp);
	if (++nki == NKEV) {
		AZ(kevent(kq, ki, nki, NULL, 0, NULL));
		nki = 0;
	}
}

static void
vca_kev(struct kevent *kp)
{
	int i, j;
	struct sess *sp;
	struct sess *ss[NKEV];

	AN(kp->udata);
	if (kp->udata == pipes) {
		j = 0;
		i = read(pipes[0], ss, sizeof ss);
		if (i == -1 && errno == EAGAIN)
			return;
		while (i >= sizeof ss[0]) {
			CHECK_OBJ_NOTNULL(ss[j], SESS_MAGIC);
			assert(ss[j]->fd >= 0);
			TAILQ_INSERT_TAIL(&sesshead, ss[j], list);
			vca_kq_sess(ss[j], EV_ADD);
			j++;
			i -= sizeof ss[0];
		}
		assert(i == 0);
		assert(j > 0);
		assert(j <= NKEV);
		return;
	}
	CAST_OBJ_NOTNULL(sp, kp->udata, SESS_MAGIC);
	if (kp->data > 0) {
		i = vca_pollsession(sp);
		if (i == -1)
			return;
		TAILQ_REMOVE(&sesshead, sp, list);
		if (i == 0) {
			vca_kq_sess(sp, EV_DELETE);
			vca_handover(sp, i);
		} else {
			SES_Delete(sp);
		}
		return;
	}
	if (kp->flags == EV_EOF) {
		TAILQ_REMOVE(&sesshead, sp, list);
		vca_close_session(sp, "EOF");
		SES_Delete(sp);
		return;
	}
	INCOMPL();
}

/*--------------------------------------------------------------------*/

static void *
vca_kqueue_main(void *arg)
{
	struct kevent ke[NKEV], *kp;
	int j, n, dotimer;
	struct timespec ts;
	struct sess *sp;

	(void)arg;

	kq = kqueue();
	assert(kq >= 0);

	j = 0;
	EV_SET(&ke[j++], 0, EVFILT_TIMER, EV_ADD, 0, 100, NULL);
	EV_SET(&ke[j++], pipes[0], EVFILT_READ, EV_ADD, 0, 0, pipes);
	AZ(kevent(kq, ke, j, NULL, 0, NULL));

	nki = 0;
	while (1) {
		dotimer = 0;
		n = kevent(kq, ki, nki, ke, NKEV, NULL);
		assert(n >= 1 && n <= NKEV);
		nki = 0;
		for (kp = ke, j = 0; j < n; j++, kp++) {
			if (kp->filter == EVFILT_TIMER) {
				dotimer = 1;
				continue; 
			}
			assert(kp->filter == EVFILT_READ);
			vca_kev(kp);
		}<commit_msg>Ignore kevent error return entries<commit_after>/*
 * $Id$
 *
 * XXX: We need to pass sessions back into the event engine when they are
 * reused.  Not sure what the most efficient way is for that.  For now
 * write the session pointer to a pipe which the event engine monitors.
 */

#if defined(HAVE_KQUEUE)

#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>

#include <sys/event.h>

#include "heritage.h"
#include "shmlog.h"
#include "cache.h"
#include "cache_acceptor.h"

static pthread_t vca_kqueue_thread;
static int kq = -1;

static TAILQ_HEAD(,sess) sesshead = TAILQ_HEAD_INITIALIZER(sesshead);
static int pipes[2];

#define NKEV	100

static struct kevent ki[NKEV];
static unsigned nki;

static void
vca_kq_sess(struct sess *sp, int arm)
{

	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
	if (sp->fd < 0)
		return;
	EV_SET(&ki[nki], sp->fd, EVFILT_READ, arm, 0, 0, sp);
	if (++nki == NKEV) {
		AZ(kevent(kq, ki, nki, NULL, 0, NULL));
		nki = 0;
	}
}

static void
vca_kev(struct kevent *kp)
{
	int i, j;
	struct sess *sp;
	struct sess *ss[NKEV];

	AN(kp->udata);
	if (kp->udata == pipes) {
		j = 0;
		i = read(pipes[0], ss, sizeof ss);
		if (i == -1 && errno == EAGAIN)
			return;
		while (i >= sizeof ss[0]) {
			CHECK_OBJ_NOTNULL(ss[j], SESS_MAGIC);
			assert(ss[j]->fd >= 0);
			TAILQ_INSERT_TAIL(&sesshead, ss[j], list);
			vca_kq_sess(ss[j], EV_ADD);
			j++;
			i -= sizeof ss[0];
		}
		assert(i == 0);
		return;
	}
	CAST_OBJ_NOTNULL(sp, kp->udata, SESS_MAGIC);
	if (kp->data > 0) {
		i = vca_pollsession(sp);
		if (i == -1)
			return;
		TAILQ_REMOVE(&sesshead, sp, list);
		if (i == 0) {
			vca_kq_sess(sp, EV_DELETE);
			vca_handover(sp, i);
		} else {
			SES_Delete(sp);
		}
		return;
	}
	if (kp->flags == EV_EOF) {
		TAILQ_REMOVE(&sesshead, sp, list);
		vca_close_session(sp, "EOF");
		SES_Delete(sp);
		return;
	}
	INCOMPL();
}

/*--------------------------------------------------------------------*/

static void *
vca_kqueue_main(void *arg)
{
	struct kevent ke[NKEV], *kp;
	int j, n, dotimer;
	struct timespec ts;
	struct sess *sp;

	(void)arg;

	kq = kqueue();
	assert(kq >= 0);

	j = 0;
	EV_SET(&ke[j++], 0, EVFILT_TIMER, EV_ADD, 0, 100, NULL);
	EV_SET(&ke[j++], pipes[0], EVFILT_READ, EV_ADD, 0, 0, pipes);
	AZ(kevent(kq, ke, j, NULL, 0, NULL));

	nki = 0;
	while (1) {
		dotimer = 0;
		n = kevent(kq, ki, nki, ke, NKEV, NULL);
		assert(n >= 1 && n <= NKEV);
		nki = 0;
		for (kp = ke, j = 0; j < n; j++, kp++) {
			if (kp->flags & EV_ERROR)
				continue;
			if (kp->filter == EVFILT_TIMER) {
				dotimer = 1;
				continue; 
			}
			assert(kp->filter == EVFILT_READ);
			vca_kev(kp);
		}
{'fraction_non_alphanumeric': 0.19661854103343465, 'fraction_numerical': 0.014627659574468085, 'mean_word_length': 3.1653481012658227, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2215256', 'n_tokens_mistral': 2585, 'n_tokens_neox': 2320, 'n_words': 586}