/*
 * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "event2/event-config.h"
#include "evconfig-private.h"

#ifdef _WIN32
#include <winsock2.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#endif
#include <sys/types.h>
#if !defined(_WIN32) && defined(EVENT__HAVE_SYS_TIME_H)
#include <sys/time.h>
#endif
#include <sys/queue.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef _WIN32
#include <unistd.h>
#endif
#include <errno.h>
#include <limits.h>
#include <signal.h>
#include <string.h>
#include <time.h>

#include "event-internal.h"
#include "evmap-internal.h"
#include "mm-internal.h"
#include "changelist-internal.h"

/** An entry for an evmap_io list: notes all the events that want to read or
	write on a given fd, and the number of each.
  */
struct evmap_io {
	struct event_dlist events;
	ev_uint16_t nread;
	ev_uint16_t nwrite;
	ev_uint16_t nclose;
};

/* An entry for an evmap_signal list: notes all the events that want to know
   when a signal triggers. */
struct evmap_signal {
	struct event_dlist events;
};

/* On some platforms, fds start at 0 and increment by 1 as they are
   allocated, and old numbers get used.  For these platforms, we
   implement io maps just like signal maps: as an array of pointers to
   struct evmap_io.  But on other platforms (windows), sockets are not
   0-indexed, not necessarily consecutive, and not necessarily reused.
   There, we use a hashtable to implement evmap_io.
*/
#ifdef EVMAP_USE_HT
struct event_map_entry {
	HT_ENTRY(event_map_entry) map_node;
	evutil_socket_t fd;
	union { /* This is a union in case we need to make more things that can
			   be in the hashtable. */
		struct evmap_io evmap_io;
	} ent;
};

/* Helper used by the event_io_map hashtable code; tries to return a good hash
 * of the fd in e->fd. */
static inline unsigned
hashsocket(struct event_map_entry *e)
{
	/* On win32, in practice, the low 2-3 bits of a SOCKET seem not to
	 * matter.  Our hashtable implementation really likes low-order bits,
	 * though, so let's do the rotate-and-add trick. */
	unsigned h = (unsigned) e->fd;
	h += (h >> 2) | (h << 30);
	return h;
}

/* Helper used by the event_io_map hashtable code; returns true iff e1 and e2
 * have the same e->fd. */
static inline int
eqsocket(struct event_map_entry *e1, struct event_map_entry *e2)
{
	return e1->fd == e2->fd;
}

HT_PROTOTYPE(event_io_map, event_map_entry, map_node, hashsocket, eqsocket)
HT_GENERATE(event_io_map, event_map_entry, map_node, hashsocket, eqsocket,
			0.5, mm_malloc, mm_realloc, mm_free)

#define GET_IO_SLOT(x, map, slot, type)					\
	do {								\
		struct event_map_entry key_, *ent_;			\
		key_.fd = slot;						\
		ent_ = HT_FIND(event_io_map, map, &key_);		\
		(x) = ent_ ? &ent_->ent.type : NULL;			\
	} while (0);

#define GET_IO_SLOT_AND_CTOR(x, map, slot, type, ctor, fdinfo_len)	\
	do {								\
		struct event_map_entry key_, *ent_;			\
		key_.fd = slot;						\
		HT_FIND_OR_INSERT_(event_io_map, map_node, hashsocket, map, \
		    event_map_entry, &key_, ptr,			\
		    {							\
			    ent_ = *ptr;				\
		    },							\
		    {							\
			    ent_ = mm_calloc(1,sizeof(struct event_map_entry)+fdinfo_len); \
			    if (EVUTIL_UNLIKELY(ent_ == NULL))		\
				    return (-1);			\
			    ent_->fd = slot;				\
			    (ctor)(&ent_->ent.type);			\
			    HT_FOI_INSERT_(map_node, map, &key_, ent_, ptr) \
				});					\
		(x) = &ent_->ent.type;					\
	} while (0)

void evmap_io_initmap_(struct event_io_map *ctx)
{
	HT_INIT(event_io_map, ctx);
}

void evmap_io_clear_(struct event_io_map *ctx)
{
	struct event_map_entry **ent, **next, *this;
	for (ent = HT_START(event_io_map, ctx); ent; ent = next) {
		this = *ent;
		next = HT_NEXT_RMV(event_io_map, ctx, ent);
		mm_free(this);
	}
	HT_CLEAR(event_io_map, ctx); /* remove all storage held by the ctx. */
}
#endif

/* Set the variable 'x' to the field in event_map 'map' with fields of type
   'struct type *' corresponding to the fd or signal 'slot'.  Set 'x' to NULL
   if there are no entries for 'slot'.  Does no bounds-checking. */
#define GET_SIGNAL_SLOT(x, map, slot, type)			\
	(x) = (struct type *)((map)->entries[slot])
/* As GET_SLOT, but construct the entry for 'slot' if it is not present,
   by allocating enough memory for a 'struct type', and initializing the new
   value by calling the function 'ctor' on it.  Makes the function
   return -1 on allocation failure.
 */
#define GET_SIGNAL_SLOT_AND_CTOR(x, map, slot, type, ctor, fdinfo_len)	\
	do {								\
		if ((map)->entries[slot] == NULL) {			\
			(map)->entries[slot] =				\
			    mm_calloc(1,sizeof(struct type)+fdinfo_len); \
			if (EVUTIL_UNLIKELY((map)->entries[slot] == NULL)) \
				return (-1);				\
			(ctor)((struct type *)(map)->entries[slot]);	\
		}							\
		(x) = (struct type *)((map)->entries[slot]);		\
	} while (0)

/* If we aren't using hashtables, then define the IO_SLOT macros and functions
   as thin aliases over the SIGNAL_SLOT versions. */
#ifndef EVMAP_USE_HT
#define GET_IO_SLOT(x,map,slot,type) GET_SIGNAL_SLOT(x,map,slot,type)
#define GET_IO_SLOT_AND_CTOR(x,map,slot,type,ctor,fdinfo_len)	\
	GET_SIGNAL_SLOT_AND_CTOR(x,map,slot,type,ctor,fdinfo_len)
#define FDINFO_OFFSET sizeof(struct evmap_io)
void
evmap_io_initmap_(struct event_io_map* ctx)
{
	evmap_signal_initmap_(ctx);
}
void
evmap_io_clear_(struct event_io_map* ctx)
{
	evmap_signal_clear_(ctx);
}
#endif


/** Expand 'map' with new entries of width 'msize' until it is big enough
	to store a value in 'slot'.
 */
static int
evmap_make_space(struct event_signal_map *map, int slot, int msize)
{
	if (map->nentries <= slot) {
		int nentries = map->nentries ? map->nentries : 32;
		void **tmp;

		if (slot > INT_MAX / 2)
			return (-1);

		while (nentries <= slot)
			nentries <<= 1;

		if (nentries > INT_MAX / msize)
			return (-1);

		tmp = (void **)mm_realloc(map->entries, nentries * msize);
		if (tmp == NULL)
			return (-1);

		memset(&tmp[map->nentries], 0,
		    (nentries - map->nentries) * msize);

		map->nentries = nentries;
		map->entries = tmp;
	}

	return (0);
}

void
evmap_signal_initmap_(struct event_signal_map *ctx)
{
	ctx->nentries = 0;
	ctx->entries = NULL;
}

void
evmap_signal_clear_(struct event_signal_map *ctx)
{
	if (ctx->entries != NULL) {
		int i;
		for (i = 0; i < ctx->nentries; ++i) {
			if (ctx->entries[i] != NULL)
				mm_free(ctx->entries[i]);
		}
		mm_free(ctx->entries);
		ctx->entries = NULL;
	}
	ctx->nentries = 0;
}


/* code specific to file descriptors */

/** Constructor for struct evmap_io */
static void
evmap_io_init(struct evmap_io *entry)
{
	LIST_INIT(&entry->events);
	entry->nread = 0;
	entry->nwrite = 0;
	entry->nclose = 0;
}


/* return -1 on error, 0 on success if nothing changed in the event backend,
 * and 1 on success if something did. */
int
evmap_io_add_(struct event_base *base, evutil_socket_t fd, struct event *ev)
{
	const struct eventop *evsel = base->evsel;
	struct event_io_map *io = &base->io;
	struct evmap_io *ctx = NULL;
	int nread, nwrite, nclose, retval = 0;
	short res = 0, old = 0;
	struct event *old_ev;

	EVUTIL_ASSERT(fd == ev->ev_fd);

	if (fd < 0)
		return 0;

#ifndef EVMAP_USE_HT
	if (fd >= io->nentries) {
		if (evmap_make_space(io, fd, sizeof(struct evmap_io *)) == -1)
			return (-1);
	}
#endif
	GET_IO_SLOT_AND_CTOR(ctx, io, fd, evmap_io, evmap_io_init,
						 evsel->fdinfo_len);

	nread = ctx->nread;
	nwrite = ctx->nwrite;
	nclose = ctx->nclose;

	if (nread)
		old |= EV_READ;
	if (nwrite)
		old |= EV_WRITE;
	if (nclose)
		old |= EV_CLOSED;

	if (ev->ev_events & EV_READ) {
		if (++nread == 1)
			res |= EV_READ;
	}
	if (ev->ev_events & EV_WRITE) {
		if (++nwrite == 1)
			res |= EV_WRITE;
	}
	if (ev->ev_events & EV_CLOSED) {
		if (++nclose == 1)
			res |= EV_CLOSED;
	}
	if (EVUTIL_UNLIKELY(nread > 0xffff || nwrite > 0xffff || nclose > 0xffff)) {
		event_warnx("Too many events reading or writing on fd %d",
		    (int)fd);
		return -1;
	}
	if (EVENT_DEBUG_MODE_IS_ON() &&
	    (old_ev = LIST_FIRST(&ctx->events)) &&
	    (old_ev->ev_events&EV_ET) != (ev->ev_events&EV_ET)) {
		event_warnx("Tried to mix edge-triggered and non-edge-triggered"
		    " events on fd %d", (int)fd);
		return -1;
	}

	if (res) {
		void *extra = ((char*)ctx) + sizeof(struct evmap_io);
		/* XXX(niels): we cannot mix edge-triggered and
		 * level-triggered, we should probably assert on
		 * this. */
		if (evsel->add(base, ev->ev_fd,
			old, (ev->ev_events & EV_ET) | res, extra) == -1)
			return (-1);
		retval = 1;
	}

	ctx->nread = (ev_uint16_t) nread;
	ctx->nwrite = (ev_uint16_t) nwrite;
	ctx->nclose = (ev_uint16_t) nclose;
	LIST_INSERT_HEAD(&ctx->events, ev, ev_io_next);

	return (retval);
}

/* return -1 on error, 0 on success if nothing changed in the event backend,
 * and 1 on success if something did. */
int
evmap_io_del_(struct event_base *base, evutil_socket_t fd, struct event *ev)
{
	const struct eventop *evsel = base->evsel;
	struct event_io_map *io = &base->io;
	struct evmap_io *ctx;
	int nread, nwrite, nclose, retval = 0;
	short res = 0, old = 0;

	if (fd < 0)
		return 0;

	EVUTIL_ASSERT(fd == ev->ev_fd);

#ifndef EVMAP_USE_HT
	if (fd >= io->nentries)
		return (-1);
#endif

	GET_IO_SLOT(ctx, io, fd, evmap_io);

	nread = ctx->nread;
	nwrite = ctx->nwrite;
	nclose = ctx->nclose;

	if (nread)
		old |= EV_READ;
	if (nwrite)
		old |= EV_WRITE;
	if (nclose)
		old |= EV_CLOSED;

	if (ev->ev_events & EV_READ) {
		if (--nread == 0)
			res |= EV_READ;
		EVUTIL_ASSERT(nread >= 0);
	}
	if (ev->ev_events & EV_WRITE) {
		if (--nwrite == 0)
			res |= EV_WRITE;
		EVUTIL_ASSERT(nwrite >= 0);
	}
	if (ev->ev_events & EV_CLOSED) {
		if (--nclose == 0)
			res |= EV_CLOSED;
		EVUTIL_ASSERT(nclose >= 0);
	}

	if (res) {
		void *extra = ((char*)ctx) + sizeof(struct evmap_io);
		if (evsel->del(base, ev->ev_fd,
			old, (ev->ev_events & EV_ET) | res, extra) == -1) {
			retval = -1;
		} else {
			retval = 1;
		}
	}

	ctx->nread = nread;
	ctx->nwrite = nwrite;
	ctx->nclose = nclose;
	LIST_REMOVE(ev, ev_io_next);

	return (retval);
}

void
evmap_io_active_(struct event_base *base, evutil_socket_t fd, short events)
{
	struct event_io_map *io = &base->io;
	struct evmap_io *ctx;
	struct event *ev;

#ifndef EVMAP_USE_HT
	if (fd < 0 || fd >= io->nentries)
		return;
#endif
	GET_IO_SLOT(ctx, io, fd, evmap_io);

	if (NULL == ctx)
		return;
	LIST_FOREACH(ev, &ctx->events, ev_io_next) {
		if (ev->ev_events & events)
			event_active_nolock_(ev, ev->ev_events & events, 1);
	}
}

/* code specific to signals */

static void
evmap_signal_init(struct evmap_signal *entry)
{
	LIST_INIT(&entry->events);
}


int
evmap_signal_add_(struct event_base *base, int sig, struct event *ev)
{
	const struct eventop *evsel = base->evsigsel;
	struct event_signal_map *map = &base->sigmap;
	struct evmap_signal *ctx = NULL;

	if (sig < 0 || sig >= NSIG)
		return (-1);

	if (sig >= map->nentries) {
		if (evmap_make_space(
			map, sig, sizeof(struct evmap_signal *)) == -1)
			return (-1);
	}
	GET_SIGNAL_SLOT_AND_CTOR(ctx, map, sig, evmap_signal, evmap_signal_init,
	    base->evsigsel->fdinfo_len);

	if (LIST_EMPTY(&ctx->events)) {
		if (evsel->add(base, ev->ev_fd, 0, EV_SIGNAL, NULL)
		    == -1)
			return (-1);
	}

	LIST_INSERT_HEAD(&ctx->events, ev, ev_signal_next);

	return (1);
}

int
evmap_signal_del_(struct event_base *base, int sig, struct event *ev)
{
	const struct eventop *evsel = base->evsigsel;
	struct event_signal_map *map = &base->sigmap;
	struct evmap_signal *ctx;

	if (sig < 0 || sig >= map->nentries)
		return (-1);

	GET_SIGNAL_SLOT(ctx, map, sig, evmap_signal);

	LIST_REMOVE(ev, ev_signal_next);

	if (LIST_FIRST(&ctx->events) == NULL) {
		if (evsel->del(base, ev->ev_fd, 0, EV_SIGNAL, NULL) == -1)
			return (-1);
	}

	return (1);
}

void
evmap_signal_active_(struct event_base *base, evutil_socket_t sig, int ncalls)
{
	struct event_signal_map *map = &base->sigmap;
	struct evmap_signal *ctx;
	struct event *ev;

	if (sig < 0 || sig >= map->nentries)
		return;
	GET_SIGNAL_SLOT(ctx, map, sig, evmap_signal);

	if (!ctx)
		return;
	LIST_FOREACH(ev, &ctx->events, ev_signal_next)
		event_active_nolock_(ev, EV_SIGNAL, ncalls);
}

void *
evmap_io_get_fdinfo_(struct event_io_map *map, evutil_socket_t fd)
{
	struct evmap_io *ctx;
	GET_IO_SLOT(ctx, map, fd, evmap_io);
	if (ctx)
		return ((char*)ctx) + sizeof(struct evmap_io);
	else
		return NULL;
}

/* Callback type for evmap_io_foreach_fd */
typedef int (*evmap_io_foreach_fd_cb)(
	struct event_base *, evutil_socket_t, struct evmap_io *, void *);

/* Multipurpose helper function: Iterate over every file descriptor event_base
 * for which we could have EV_READ or EV_WRITE events.  For each such fd, call
 * fn(base, signum, evmap_io, arg), where fn is the user-provided
 * function, base is the event_base, signum is the signal number, evmap_io
 * is an evmap_io structure containing a list of events pending on the
 * file descriptor, and arg is the user-supplied argument.
 *
 * If fn returns 0, continue on to the next signal. Otherwise, return the same
 * value that fn returned.
 *
 * Note that there is no guarantee that the file descriptors will be processed
 * in any particular order.
 */
static int
evmap_io_foreach_fd(struct event_base *base,
    evmap_io_foreach_fd_cb fn,
    void *arg)
{
	evutil_socket_t fd;
	struct event_io_map *iomap = &base->io;
	int r = 0;
#ifdef EVMAP_USE_HT
	struct event_map_entry **mapent;
	HT_FOREACH(mapent, event_io_map, iomap) {
		struct evmap_io *ctx = &(*mapent)->ent.evmap_io;
		fd = (*mapent)->fd;
#else
	for (fd = 0; fd < iomap->nentries; ++fd) {
		struct evmap_io *ctx = iomap->entries[fd];
		if (!ctx)
			continue;
#endif
		if ((r = fn(base, fd, ctx, arg)))
			break;
	}
	return r;
}

/* Callback type for evmap_signal_foreach_signal */
typedef int (*evmap_signal_foreach_signal_cb)(
	struct event_base *, int, struct evmap_signal *, void *);

/* Multipurpose helper function: Iterate over every signal number in the
 * event_base for which we could have signal events.  For each such signal,
 * call fn(base, signum, evmap_signal, arg), where fn is the user-provided
 * function, base is the event_base, signum is the signal number, evmap_signal
 * is an evmap_signal structure containing a list of events pending on the
 * signal, and arg is the user-supplied argument.
 *
 * If fn returns 0, continue on to the next signal. Otherwise, return the same
 * value that fn returned.
 */
static int
evmap_signal_foreach_signal(struct event_base *base,
    evmap_signal_foreach_signal_cb fn,
    void *arg)
{
	struct event_signal_map *sigmap = &base->sigmap;
	int r = 0;
	int signum;

	for (signum = 0; signum < sigmap->nentries; ++signum) {
		struct evmap_signal *ctx = sigmap->entries[signum];
		if (!ctx)
			continue;
		if ((r = fn(base, signum, ctx, arg)))
			break;
	}
	return r;
}

/* Helper for evmap_reinit_: tell the backend to add every fd for which we have
 * pending events, with the appropriate combination of EV_READ, EV_WRITE, and
 * EV_ET. */
static int
evmap_io_reinit_iter_fn(struct event_base *base, evutil_socket_t fd,
    struct evmap_io *ctx, void *arg)
{
	const struct eventop *evsel = base->evsel;
	void *extra;
	int *result = arg;
	short events = 0;
	struct event *ev;
	EVUTIL_ASSERT(ctx);

	extra = ((char*)ctx) + sizeof(struct evmap_io);
	if (ctx->nread)
		events |= EV_READ;
	if (ctx->nwrite)
		events |= EV_WRITE;
	if (ctx->nclose)
		events |= EV_CLOSED;
	if (evsel->fdinfo_len)
		memset(extra, 0, evsel->fdinfo_len);
	if (events &&
	    (ev = LIST_FIRST(&ctx->events)) &&
	    (ev->ev_events & EV_ET))
		events |= EV_ET;
	if (evsel->add(base, fd, 0, events, extra) == -1)
		*result = -1;

	return 0;
}

/* Helper for evmap_reinit_: tell the backend to add every signal for which we
 * have pending events.  */
static int
evmap_signal_reinit_iter_fn(struct event_base *base,
    int signum, struct evmap_signal *ctx, void *arg)
{
	const struct eventop *evsel = base->evsigsel;
	int *result = arg;

	if (!LIST_EMPTY(&ctx->events)) {
		if (evsel->add(base, signum, 0, EV_SIGNAL, NULL) == -1)
			*result = -1;
	}
	return 0;
}

int
evmap_reinit_(struct event_base *base)
{
	int result = 0;

	evmap_io_foreach_fd(base, evmap_io_reinit_iter_fn, &result);
	if (result < 0)
		return -1;
	evmap_signal_foreach_signal(base, evmap_signal_reinit_iter_fn, &result);
	if (result < 0)
		return -1;
	return 0;
}

/* Helper for evmap_delete_all_: delete every event in an event_dlist. */
static int
delete_all_in_dlist(struct event_dlist *dlist)
{
	struct event *ev;
	while ((ev = LIST_FIRST(dlist)))
		event_del(ev);
	return 0;
}

/* Helper for evmap_delete_all_: delete every event pending on an fd. */
static int
evmap_io_delete_all_iter_fn(struct event_base *base, evutil_socket_t fd,
    struct evmap_io *io_info, void *arg)
{
	return delete_all_in_dlist(&io_info->events);
}

/* Helper for evmap_delete_all_: delete every event pending on a signal. */
static int
evmap_signal_delete_all_iter_fn(struct event_base *base, int signum,
    struct evmap_signal *sig_info, void *arg)
{
	return delete_all_in_dlist(&sig_info->events);
}

void
evmap_delete_all_(struct event_base *base)
{
	evmap_signal_foreach_signal(base, evmap_signal_delete_all_iter_fn, NULL);
	evmap_io_foreach_fd(base, evmap_io_delete_all_iter_fn, NULL);
}

/** Per-fd structure for use with changelists.  It keeps track, for each fd or
 * signal using the changelist, of where its entry in the changelist is.
 */
struct event_changelist_fdinfo {
	int idxplus1; /* this is the index +1, so that memset(0) will make it
		       * a no-such-element */
};

void
event_changelist_init_(struct event_changelist *changelist)
{
	changelist->changes = NULL;
	changelist->changes_size = 0;
	changelist->n_changes = 0;
}

/** Helper: return the changelist_fdinfo corresponding to a given change. */
static inline struct event_changelist_fdinfo *
event_change_get_fdinfo(struct event_base *base,
    const struct event_change *change)
{
	char *ptr;
	if (change->read_change & EV_CHANGE_SIGNAL) {
		struct evmap_signal *ctx;
		GET_SIGNAL_SLOT(ctx, &base->sigmap, change->fd, evmap_signal);
		ptr = ((char*)ctx) + sizeof(struct evmap_signal);
	} else {
		struct evmap_io *ctx;
		GET_IO_SLOT(ctx, &base->io, change->fd, evmap_io);
		ptr = ((char*)ctx) + sizeof(struct evmap_io);
	}
	return (void*)ptr;
}

/** Callback helper for event_changelist_assert_ok */
static int
event_changelist_assert_ok_foreach_iter_fn(
	struct event_base *base,
	evutil_socket_t fd, struct evmap_io *io, void *arg)
{
	struct event_changelist *changelist = &base->changelist;
	struct event_changelist_fdinfo *f;
	f = (void*)
	    ( ((char*)io) + sizeof(struct evmap_io) );
	if (f->idxplus1) {
		struct event_change *c = &changelist->changes[f->idxplus1 - 1];
		EVUTIL_ASSERT(c->fd == fd);
	}
	return 0;
}

/** Make sure that the changelist is consistent with the evmap structures. */
static void
event_changelist_assert_ok(struct event_base *base)
{
	int i;
	struct event_changelist *changelist = &base->changelist;

	EVUTIL_ASSERT(changelist->changes_size >= changelist->n_changes);
	for (i = 0; i < changelist->n_changes; ++i) {
		struct event_change *c = &changelist->changes[i];
		struct event_changelist_fdinfo *f;
		EVUTIL_ASSERT(c->fd >= 0);
		f = event_change_get_fdinfo(base, c);
		EVUTIL_ASSERT(f);
		EVUTIL_ASSERT(f->idxplus1 == i + 1);
	}

	evmap_io_foreach_fd(base,
	    event_changelist_assert_ok_foreach_iter_fn,
	    NULL);
}

#ifdef DEBUG_CHANGELIST
#define event_changelist_check(base)  event_changelist_assert_ok((base))
#else
#define event_changelist_check(base)  ((void)0)
#endif

void
event_changelist_remove_all_(struct event_changelist *changelist,
    struct event_base *base)
{
	int i;

	event_changelist_check(base);

	for (i = 0; i < changelist->n_changes; ++i) {
		struct event_change *ch = &changelist->changes[i];
		struct event_changelist_fdinfo *fdinfo =
		    event_change_get_fdinfo(base, ch);
		EVUTIL_ASSERT(fdinfo->idxplus1 == i + 1);
		fdinfo->idxplus1 = 0;
	}

	changelist->n_changes = 0;

	event_changelist_check(base);
}

void
event_changelist_freemem_(struct event_changelist *changelist)
{
	if (changelist->changes)
		mm_free(changelist->changes);
	event_changelist_init_(changelist); /* zero it all out. */
}

/** Increase the size of 'changelist' to hold more changes. */
static int
event_changelist_grow(struct event_changelist *changelist)
{
	int new_size;
	struct event_change *new_changes;
	if (changelist->changes_size < 64)
		new_size = 64;
	else
		new_size = changelist->changes_size * 2;

	new_changes = mm_realloc(changelist->changes,
	    new_size * sizeof(struct event_change));

	if (EVUTIL_UNLIKELY(new_changes == NULL))
		return (-1);

	changelist->changes = new_changes;
	changelist->changes_size = new_size;

	return (0);
}

/** Return a pointer to the changelist entry for the file descriptor or signal
 * 'fd', whose fdinfo is 'fdinfo'.  If none exists, construct it, setting its
 * old_events field to old_events.
 */
static struct event_change *
event_changelist_get_or_construct(struct event_changelist *changelist,
    evutil_socket_t fd,
    short old_events,
    struct event_changelist_fdinfo *fdinfo)
{
	struct event_change *change;

	if (fdinfo->idxplus1 == 0) {
		int idx;
		EVUTIL_ASSERT(changelist->n_changes <= changelist->changes_size);

		if (changelist->n_changes == changelist->changes_size) {
			if (event_changelist_grow(changelist) < 0)
				return NULL;
		}

		idx = changelist->n_changes++;
		change = &changelist->changes[idx];
		fdinfo->idxplus1 = idx + 1;

		memset(change, 0, sizeof(struct event_change));
		change->fd = fd;
		change->old_events = old_events;
	} else {
		change = &changelist->changes[fdinfo->idxplus1 - 1];
		EVUTIL_ASSERT(change->fd == fd);
	}
	return change;
}

int
event_changelist_add_(struct event_base *base, evutil_socket_t fd, short old, short events,
    void *p)
{
	struct event_changelist *changelist = &base->changelist;
	struct event_changelist_fdinfo *fdinfo = p;
	struct event_change *change;
	ev_uint8_t evchange = EV_CHANGE_ADD | (events & (EV_ET|EV_PERSIST|EV_SIGNAL));

	event_changelist_check(base);

	change = event_changelist_get_or_construct(changelist, fd, old, fdinfo);
	if (!change)
		return -1;

	/* An add replaces any previous delete, but doesn't result in a no-op,
	 * since the delete might fail (because the fd had been closed since
	 * the last add, for instance. */

	if (events & (EV_READ|EV_SIGNAL))
		change->read_change = evchange;
	if (events & EV_WRITE)
		change->write_change = evchange;
	if (events & EV_CLOSED)
		change->close_change = evchange;

	event_changelist_check(base);
	return (0);
}

int
event_changelist_del_(struct event_base *base, evutil_socket_t fd, short old, short events,
    void *p)
{
	struct event_changelist *changelist = &base->changelist;
	struct event_changelist_fdinfo *fdinfo = p;
	struct event_change *change;
	ev_uint8_t del = EV_CHANGE_DEL | (events & EV_ET);

	event_changelist_check(base);
	change = event_changelist_get_or_construct(changelist, fd, old, fdinfo);
	event_changelist_check(base);
	if (!change)
		return -1;

	/* A delete on an event set that doesn't contain the event to be
	   deleted produces a no-op.  This effectively emoves any previous
	   uncommitted add, rather than replacing it: on those platforms where
	   "add, delete, dispatch" is not the same as "no-op, dispatch", we
	   want the no-op behavior.

	   If we have a no-op item, we could remove it it from the list
	   entirely, but really there's not much point: skipping the no-op
	   change when we do the dispatch later is far cheaper than rejuggling
	   the array now.

	   As this stands, it also lets through deletions of events that are
	   not currently set.
	 */

	if (events & (EV_READ|EV_SIGNAL)) {
		if (!(change->old_events & (EV_READ | EV_SIGNAL)))
			change->read_change = 0;
		else
			change->read_change = del;
	}
	if (events & EV_WRITE) {
		if (!(change->old_events & EV_WRITE))
			change->write_change = 0;
		else
			change->write_change = del;
	}
	if (events & EV_CLOSED) {
		if (!(change->old_events & EV_CLOSED))
			change->close_change = 0;
		else
			change->close_change = del;
	}

	event_changelist_check(base);
	return (0);
}

/* Helper for evmap_check_integrity_: verify that all of the events pending on
 * given fd are set up correctly, and that the nread and nwrite counts on that
 * fd are correct. */
static int
evmap_io_check_integrity_fn(struct event_base *base, evutil_socket_t fd,
    struct evmap_io *io_info, void *arg)
{
	struct event *ev;
	int n_read = 0, n_write = 0, n_close = 0;

	/* First, make sure the list itself isn't corrupt. Otherwise,
	 * running LIST_FOREACH could be an exciting adventure. */
	EVUTIL_ASSERT_LIST_OK(&io_info->events, event, ev_io_next);

	LIST_FOREACH(ev, &io_info->events, ev_io_next) {
		EVUTIL_ASSERT(ev->ev_flags & EVLIST_INSERTED);
		EVUTIL_ASSERT(ev->ev_fd == fd);
		EVUTIL_ASSERT(!(ev->ev_events & EV_SIGNAL));
		EVUTIL_ASSERT((ev->ev_events & (EV_READ|EV_WRITE|EV_CLOSED)));
		if (ev->ev_events & EV_READ)
			++n_read;
		if (ev->ev_events & EV_WRITE)
			++n_write;
		if (ev->ev_events & EV_CLOSED)
			++n_close;
	}

	EVUTIL_ASSERT(n_read == io_info->nread);
	EVUTIL_ASSERT(n_write == io_info->nwrite);
	EVUTIL_ASSERT(n_close == io_info->nclose);

	return 0;
}

/* Helper for evmap_check_integrity_: verify that all of the events pending
 * on given signal are set up correctly. */
static int
evmap_signal_check_integrity_fn(struct event_base *base,
    int signum, struct evmap_signal *sig_info, void *arg)
{
	struct event *ev;
	/* First, make sure the list itself isn't corrupt. */
	EVUTIL_ASSERT_LIST_OK(&sig_info->events, event, ev_signal_next);

	LIST_FOREACH(ev, &sig_info->events, ev_io_next) {
		EVUTIL_ASSERT(ev->ev_flags & EVLIST_INSERTED);
		EVUTIL_ASSERT(ev->ev_fd == signum);
		EVUTIL_ASSERT((ev->ev_events & EV_SIGNAL));
		EVUTIL_ASSERT(!(ev->ev_events & (EV_READ|EV_WRITE|EV_CLOSED)));
	}
	return 0;
}

void
evmap_check_integrity_(struct event_base *base)
{
	evmap_io_foreach_fd(base, evmap_io_check_integrity_fn, NULL);
	evmap_signal_foreach_signal(base, evmap_signal_check_integrity_fn, NULL);

	if (base->evsel->add == event_changelist_add_)
		event_changelist_assert_ok(base);
}

/* Helper type for evmap_foreach_event_: Bundles a function to call on every
 * event, and the user-provided void* to use as its third argument. */
struct evmap_foreach_event_helper {
	event_base_foreach_event_cb fn;
	void *arg;
};

/* Helper for evmap_foreach_event_: calls a provided function on every event
 * pending on a given fd.  */
static int
evmap_io_foreach_event_fn(struct event_base *base, evutil_socket_t fd,
    struct evmap_io *io_info, void *arg)
{
	struct evmap_foreach_event_helper *h = arg;
	struct event *ev;
	int r;
	LIST_FOREACH(ev, &io_info->events, ev_io_next) {
		if ((r = h->fn(base, ev, h->arg)))
			return r;
	}
	return 0;
}

/* Helper for evmap_foreach_event_: calls a provided function on every event
 * pending on a given signal.  */
static int
evmap_signal_foreach_event_fn(struct event_base *base, int signum,
    struct evmap_signal *sig_info, void *arg)
{
	struct event *ev;
	struct evmap_foreach_event_helper *h = arg;
	int r;
	LIST_FOREACH(ev, &sig_info->events, ev_signal_next) {
		if ((r = h->fn(base, ev, h->arg)))
			return r;
	}
	return 0;
}

int
evmap_foreach_event_(struct event_base *base,
    event_base_foreach_event_cb fn, void *arg)
{
	struct evmap_foreach_event_helper h;
	int r;
	h.fn = fn;
	h.arg = arg;
	if ((r = evmap_io_foreach_fd(base, evmap_io_foreach_event_fn, &h)))
		return r;
	return evmap_signal_foreach_signal(base, evmap_signal_foreach_event_fn, &h);
}

