Home | History | Annotate | Download | only in libevent
      1 /*
      2  * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  * 3. The name of the author may not be used to endorse or promote products
     13  *    derived from this software without specific prior written permission.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     25  */
     26 #include "event2/event-config.h"
     27 #include "evconfig-private.h"
     28 
     29 #ifdef _WIN32
     30 #include <winsock2.h>
     31 #define WIN32_LEAN_AND_MEAN
     32 #include <windows.h>
     33 #undef WIN32_LEAN_AND_MEAN
     34 #endif
     35 #include <sys/types.h>
     36 #if !defined(_WIN32) && defined(EVENT__HAVE_SYS_TIME_H)
     37 #include <sys/time.h>
     38 #endif
     39 #include <sys/queue.h>
     40 #include <stdio.h>
     41 #include <stdlib.h>
     42 #ifndef _WIN32
     43 #include <unistd.h>
     44 #endif
     45 #include <errno.h>
     46 #include <signal.h>
     47 #include <string.h>
     48 #include <time.h>
     49 
     50 #include "event-internal.h"
     51 #include "evmap-internal.h"
     52 #include "mm-internal.h"
     53 #include "changelist-internal.h"
     54 
     55 /** An entry for an evmap_io list: notes all the events that want to read or
     56 	write on a given fd, and the number of each.
     57   */
     58 struct evmap_io {
     59 	struct event_dlist events;
     60 	ev_uint16_t nread;
     61 	ev_uint16_t nwrite;
     62 	ev_uint16_t nclose;
     63 };
     64 
     65 /* An entry for an evmap_signal list: notes all the events that want to know
     66    when a signal triggers. */
     67 struct evmap_signal {
     68 	struct event_dlist events;
     69 };
     70 
     71 /* On some platforms, fds start at 0 and increment by 1 as they are
     72    allocated, and old numbers get used.  For these platforms, we
     73    implement io maps just like signal maps: as an array of pointers to
     74    struct evmap_io.  But on other platforms (windows), sockets are not
     75    0-indexed, not necessarily consecutive, and not necessarily reused.
     76    There, we use a hashtable to implement evmap_io.
     77 */
     78 #ifdef EVMAP_USE_HT
     79 struct event_map_entry {
     80 	HT_ENTRY(event_map_entry) map_node;
     81 	evutil_socket_t fd;
     82 	union { /* This is a union in case we need to make more things that can
     83 			   be in the hashtable. */
     84 		struct evmap_io evmap_io;
     85 	} ent;
     86 };
     87 
     88 /* Helper used by the event_io_map hashtable code; tries to return a good hash
     89  * of the fd in e->fd. */
     90 static inline unsigned
     91 hashsocket(struct event_map_entry *e)
     92 {
     93 	/* On win32, in practice, the low 2-3 bits of a SOCKET seem not to
     94 	 * matter.  Our hashtable implementation really likes low-order bits,
     95 	 * though, so let's do the rotate-and-add trick. */
     96 	unsigned h = (unsigned) e->fd;
     97 	h += (h >> 2) | (h << 30);
     98 	return h;
     99 }
    100 
    101 /* Helper used by the event_io_map hashtable code; returns true iff e1 and e2
    102  * have the same e->fd. */
    103 static inline int
    104 eqsocket(struct event_map_entry *e1, struct event_map_entry *e2)
    105 {
    106 	return e1->fd == e2->fd;
    107 }
    108 
    109 HT_PROTOTYPE(event_io_map, event_map_entry, map_node, hashsocket, eqsocket)
    110 HT_GENERATE(event_io_map, event_map_entry, map_node, hashsocket, eqsocket,
    111 			0.5, mm_malloc, mm_realloc, mm_free)
    112 
    113 #define GET_IO_SLOT(x, map, slot, type)					\
    114 	do {								\
    115 		struct event_map_entry key_, *ent_;			\
    116 		key_.fd = slot;						\
    117 		ent_ = HT_FIND(event_io_map, map, &key_);		\
    118 		(x) = ent_ ? &ent_->ent.type : NULL;			\
    119 	} while (0);
    120 
    121 #define GET_IO_SLOT_AND_CTOR(x, map, slot, type, ctor, fdinfo_len)	\
    122 	do {								\
    123 		struct event_map_entry key_, *ent_;			\
    124 		key_.fd = slot;						\
    125 		HT_FIND_OR_INSERT_(event_io_map, map_node, hashsocket, map, \
    126 		    event_map_entry, &key_, ptr,			\
    127 		    {							\
    128 			    ent_ = *ptr;				\
    129 		    },							\
    130 		    {							\
    131 			    ent_ = mm_calloc(1,sizeof(struct event_map_entry)+fdinfo_len); \
    132 			    if (EVUTIL_UNLIKELY(ent_ == NULL))		\
    133 				    return (-1);			\
    134 			    ent_->fd = slot;				\
    135 			    (ctor)(&ent_->ent.type);			\
    136 			    HT_FOI_INSERT_(map_node, map, &key_, ent_, ptr) \
    137 				});					\
    138 		(x) = &ent_->ent.type;					\
    139 	} while (0)
    140 
    141 void evmap_io_initmap_(struct event_io_map *ctx)
    142 {
    143 	HT_INIT(event_io_map, ctx);
    144 }
    145 
    146 void evmap_io_clear_(struct event_io_map *ctx)
    147 {
    148 	struct event_map_entry **ent, **next, *this;
    149 	for (ent = HT_START(event_io_map, ctx); ent; ent = next) {
    150 		this = *ent;
    151 		next = HT_NEXT_RMV(event_io_map, ctx, ent);
    152 		mm_free(this);
    153 	}
    154 	HT_CLEAR(event_io_map, ctx); /* remove all storage held by the ctx. */
    155 }
    156 #endif
    157 
    158 /* Set the variable 'x' to the field in event_map 'map' with fields of type
    159    'struct type *' corresponding to the fd or signal 'slot'.  Set 'x' to NULL
    160    if there are no entries for 'slot'.  Does no bounds-checking. */
    161 #define GET_SIGNAL_SLOT(x, map, slot, type)			\
    162 	(x) = (struct type *)((map)->entries[slot])
    163 /* As GET_SLOT, but construct the entry for 'slot' if it is not present,
    164    by allocating enough memory for a 'struct type', and initializing the new
    165    value by calling the function 'ctor' on it.  Makes the function
    166    return -1 on allocation failure.
    167  */
    168 #define GET_SIGNAL_SLOT_AND_CTOR(x, map, slot, type, ctor, fdinfo_len)	\
    169 	do {								\
    170 		if ((map)->entries[slot] == NULL) {			\
    171 			(map)->entries[slot] =				\
    172 			    mm_calloc(1,sizeof(struct type)+fdinfo_len); \
    173 			if (EVUTIL_UNLIKELY((map)->entries[slot] == NULL)) \
    174 				return (-1);				\
    175 			(ctor)((struct type *)(map)->entries[slot]);	\
    176 		}							\
    177 		(x) = (struct type *)((map)->entries[slot]);		\
    178 	} while (0)
    179 
    180 /* If we aren't using hashtables, then define the IO_SLOT macros and functions
    181    as thin aliases over the SIGNAL_SLOT versions. */
    182 #ifndef EVMAP_USE_HT
    183 #define GET_IO_SLOT(x,map,slot,type) GET_SIGNAL_SLOT(x,map,slot,type)
    184 #define GET_IO_SLOT_AND_CTOR(x,map,slot,type,ctor,fdinfo_len)	\
    185 	GET_SIGNAL_SLOT_AND_CTOR(x,map,slot,type,ctor,fdinfo_len)
    186 #define FDINFO_OFFSET sizeof(struct evmap_io)
    187 void
    188 evmap_io_initmap_(struct event_io_map* ctx)
    189 {
    190 	evmap_signal_initmap_(ctx);
    191 }
    192 void
    193 evmap_io_clear_(struct event_io_map* ctx)
    194 {
    195 	evmap_signal_clear_(ctx);
    196 }
    197 #endif
    198 
    199 
    200 /** Expand 'map' with new entries of width 'msize' until it is big enough
    201 	to store a value in 'slot'.
    202  */
    203 static int
    204 evmap_make_space(struct event_signal_map *map, int slot, int msize)
    205 {
    206 	if (map->nentries <= slot) {
    207 		int nentries = map->nentries ? map->nentries : 32;
    208 		void **tmp;
    209 
    210 		while (nentries <= slot)
    211 			nentries <<= 1;
    212 
    213 		tmp = (void **)mm_realloc(map->entries, nentries * msize);
    214 		if (tmp == NULL)
    215 			return (-1);
    216 
    217 		memset(&tmp[map->nentries], 0,
    218 		    (nentries - map->nentries) * msize);
    219 
    220 		map->nentries = nentries;
    221 		map->entries = tmp;
    222 	}
    223 
    224 	return (0);
    225 }
    226 
    227 void
    228 evmap_signal_initmap_(struct event_signal_map *ctx)
    229 {
    230 	ctx->nentries = 0;
    231 	ctx->entries = NULL;
    232 }
    233 
    234 void
    235 evmap_signal_clear_(struct event_signal_map *ctx)
    236 {
    237 	if (ctx->entries != NULL) {
    238 		int i;
    239 		for (i = 0; i < ctx->nentries; ++i) {
    240 			if (ctx->entries[i] != NULL)
    241 				mm_free(ctx->entries[i]);
    242 		}
    243 		mm_free(ctx->entries);
    244 		ctx->entries = NULL;
    245 	}
    246 	ctx->nentries = 0;
    247 }
    248 
    249 
    250 /* code specific to file descriptors */
    251 
    252 /** Constructor for struct evmap_io */
    253 static void
    254 evmap_io_init(struct evmap_io *entry)
    255 {
    256 	LIST_INIT(&entry->events);
    257 	entry->nread = 0;
    258 	entry->nwrite = 0;
    259 	entry->nclose = 0;
    260 }
    261 
    262 
    263 /* return -1 on error, 0 on success if nothing changed in the event backend,
    264  * and 1 on success if something did. */
    265 int
    266 evmap_io_add_(struct event_base *base, evutil_socket_t fd, struct event *ev)
    267 {
    268 	const struct eventop *evsel = base->evsel;
    269 	struct event_io_map *io = &base->io;
    270 	struct evmap_io *ctx = NULL;
    271 	int nread, nwrite, nclose, retval = 0;
    272 	short res = 0, old = 0;
    273 	struct event *old_ev;
    274 
    275 	EVUTIL_ASSERT(fd == ev->ev_fd);
    276 
    277 	if (fd < 0)
    278 		return 0;
    279 
    280 #ifndef EVMAP_USE_HT
    281 	if (fd >= io->nentries) {
    282 		if (evmap_make_space(io, fd, sizeof(struct evmap_io *)) == -1)
    283 			return (-1);
    284 	}
    285 #endif
    286 	GET_IO_SLOT_AND_CTOR(ctx, io, fd, evmap_io, evmap_io_init,
    287 						 evsel->fdinfo_len);
    288 
    289 	nread = ctx->nread;
    290 	nwrite = ctx->nwrite;
    291 	nclose = ctx->nclose;
    292 
    293 	if (nread)
    294 		old |= EV_READ;
    295 	if (nwrite)
    296 		old |= EV_WRITE;
    297 	if (nclose)
    298 		old |= EV_CLOSED;
    299 
    300 	if (ev->ev_events & EV_READ) {
    301 		if (++nread == 1)
    302 			res |= EV_READ;
    303 	}
    304 	if (ev->ev_events & EV_WRITE) {
    305 		if (++nwrite == 1)
    306 			res |= EV_WRITE;
    307 	}
    308 	if (ev->ev_events & EV_CLOSED) {
    309 		if (++nclose == 1)
    310 			res |= EV_CLOSED;
    311 	}
    312 	if (EVUTIL_UNLIKELY(nread > 0xffff || nwrite > 0xffff || nclose > 0xffff)) {
    313 		event_warnx("Too many events reading or writing on fd %d",
    314 		    (int)fd);
    315 		return -1;
    316 	}
    317 	if (EVENT_DEBUG_MODE_IS_ON() &&
    318 	    (old_ev = LIST_FIRST(&ctx->events)) &&
    319 	    (old_ev->ev_events&EV_ET) != (ev->ev_events&EV_ET)) {
    320 		event_warnx("Tried to mix edge-triggered and non-edge-triggered"
    321 		    " events on fd %d", (int)fd);
    322 		return -1;
    323 	}
    324 
    325 	if (res) {
    326 		void *extra = ((char*)ctx) + sizeof(struct evmap_io);
    327 		/* XXX(niels): we cannot mix edge-triggered and
    328 		 * level-triggered, we should probably assert on
    329 		 * this. */
    330 		if (evsel->add(base, ev->ev_fd,
    331 			old, (ev->ev_events & EV_ET) | res, extra) == -1)
    332 			return (-1);
    333 		retval = 1;
    334 	}
    335 
    336 	ctx->nread = (ev_uint16_t) nread;
    337 	ctx->nwrite = (ev_uint16_t) nwrite;
    338 	ctx->nclose = (ev_uint16_t) nclose;
    339 	LIST_INSERT_HEAD(&ctx->events, ev, ev_io_next);
    340 
    341 	return (retval);
    342 }
    343 
    344 /* return -1 on error, 0 on success if nothing changed in the event backend,
    345  * and 1 on success if something did. */
    346 int
    347 evmap_io_del_(struct event_base *base, evutil_socket_t fd, struct event *ev)
    348 {
    349 	const struct eventop *evsel = base->evsel;
    350 	struct event_io_map *io = &base->io;
    351 	struct evmap_io *ctx;
    352 	int nread, nwrite, nclose, retval = 0;
    353 	short res = 0, old = 0;
    354 
    355 	if (fd < 0)
    356 		return 0;
    357 
    358 	EVUTIL_ASSERT(fd == ev->ev_fd);
    359 
    360 #ifndef EVMAP_USE_HT
    361 	if (fd >= io->nentries)
    362 		return (-1);
    363 #endif
    364 
    365 	GET_IO_SLOT(ctx, io, fd, evmap_io);
    366 
    367 	nread = ctx->nread;
    368 	nwrite = ctx->nwrite;
    369 	nclose = ctx->nclose;
    370 
    371 	if (nread)
    372 		old |= EV_READ;
    373 	if (nwrite)
    374 		old |= EV_WRITE;
    375 	if (nclose)
    376 		old |= EV_CLOSED;
    377 
    378 	if (ev->ev_events & EV_READ) {
    379 		if (--nread == 0)
    380 			res |= EV_READ;
    381 		EVUTIL_ASSERT(nread >= 0);
    382 	}
    383 	if (ev->ev_events & EV_WRITE) {
    384 		if (--nwrite == 0)
    385 			res |= EV_WRITE;
    386 		EVUTIL_ASSERT(nwrite >= 0);
    387 	}
    388 	if (ev->ev_events & EV_CLOSED) {
    389 		if (--nclose == 0)
    390 			res |= EV_CLOSED;
    391 		EVUTIL_ASSERT(nclose >= 0);
    392 	}
    393 
    394 	if (res) {
    395 		void *extra = ((char*)ctx) + sizeof(struct evmap_io);
    396 		if (evsel->del(base, ev->ev_fd, old, res, extra) == -1) {
    397 			retval = -1;
    398 		} else {
    399 			retval = 1;
    400 		}
    401 	}
    402 
    403 	ctx->nread = nread;
    404 	ctx->nwrite = nwrite;
    405 	ctx->nclose = nclose;
    406 	LIST_REMOVE(ev, ev_io_next);
    407 
    408 	return (retval);
    409 }
    410 
    411 void
    412 evmap_io_active_(struct event_base *base, evutil_socket_t fd, short events)
    413 {
    414 	struct event_io_map *io = &base->io;
    415 	struct evmap_io *ctx;
    416 	struct event *ev;
    417 
    418 #ifndef EVMAP_USE_HT
    419 	if (fd < 0 || fd >= io->nentries)
    420 		return;
    421 #endif
    422 	GET_IO_SLOT(ctx, io, fd, evmap_io);
    423 
    424 	if (NULL == ctx)
    425 		return;
    426 	LIST_FOREACH(ev, &ctx->events, ev_io_next) {
    427 		if (ev->ev_events & events)
    428 			event_active_nolock_(ev, ev->ev_events & events, 1);
    429 	}
    430 }
    431 
    432 /* code specific to signals */
    433 
    434 static void
    435 evmap_signal_init(struct evmap_signal *entry)
    436 {
    437 	LIST_INIT(&entry->events);
    438 }
    439 
    440 
    441 int
    442 evmap_signal_add_(struct event_base *base, int sig, struct event *ev)
    443 {
    444 	const struct eventop *evsel = base->evsigsel;
    445 	struct event_signal_map *map = &base->sigmap;
    446 	struct evmap_signal *ctx = NULL;
    447 
    448 	if (sig >= map->nentries) {
    449 		if (evmap_make_space(
    450 			map, sig, sizeof(struct evmap_signal *)) == -1)
    451 			return (-1);
    452 	}
    453 	GET_SIGNAL_SLOT_AND_CTOR(ctx, map, sig, evmap_signal, evmap_signal_init,
    454 	    base->evsigsel->fdinfo_len);
    455 
    456 	if (LIST_EMPTY(&ctx->events)) {
    457 		if (evsel->add(base, ev->ev_fd, 0, EV_SIGNAL, NULL)
    458 		    == -1)
    459 			return (-1);
    460 	}
    461 
    462 	LIST_INSERT_HEAD(&ctx->events, ev, ev_signal_next);
    463 
    464 	return (1);
    465 }
    466 
    467 int
    468 evmap_signal_del_(struct event_base *base, int sig, struct event *ev)
    469 {
    470 	const struct eventop *evsel = base->evsigsel;
    471 	struct event_signal_map *map = &base->sigmap;
    472 	struct evmap_signal *ctx;
    473 
    474 	if (sig >= map->nentries)
    475 		return (-1);
    476 
    477 	GET_SIGNAL_SLOT(ctx, map, sig, evmap_signal);
    478 
    479 	LIST_REMOVE(ev, ev_signal_next);
    480 
    481 	if (LIST_FIRST(&ctx->events) == NULL) {
    482 		if (evsel->del(base, ev->ev_fd, 0, EV_SIGNAL, NULL) == -1)
    483 			return (-1);
    484 	}
    485 
    486 	return (1);
    487 }
    488 
    489 void
    490 evmap_signal_active_(struct event_base *base, evutil_socket_t sig, int ncalls)
    491 {
    492 	struct event_signal_map *map = &base->sigmap;
    493 	struct evmap_signal *ctx;
    494 	struct event *ev;
    495 
    496 	if (sig < 0 || sig >= map->nentries)
    497 		return;
    498 	GET_SIGNAL_SLOT(ctx, map, sig, evmap_signal);
    499 
    500 	if (!ctx)
    501 		return;
    502 	LIST_FOREACH(ev, &ctx->events, ev_signal_next)
    503 		event_active_nolock_(ev, EV_SIGNAL, ncalls);
    504 }
    505 
    506 void *
    507 evmap_io_get_fdinfo_(struct event_io_map *map, evutil_socket_t fd)
    508 {
    509 	struct evmap_io *ctx;
    510 	GET_IO_SLOT(ctx, map, fd, evmap_io);
    511 	if (ctx)
    512 		return ((char*)ctx) + sizeof(struct evmap_io);
    513 	else
    514 		return NULL;
    515 }
    516 
    517 /* Callback type for evmap_io_foreach_fd */
    518 typedef int (*evmap_io_foreach_fd_cb)(
    519 	struct event_base *, evutil_socket_t, struct evmap_io *, void *);
    520 
    521 /* Multipurpose helper function: Iterate over every file descriptor event_base
    522  * for which we could have EV_READ or EV_WRITE events.  For each such fd, call
    523  * fn(base, signum, evmap_io, arg), where fn is the user-provided
    524  * function, base is the event_base, signum is the signal number, evmap_io
    525  * is an evmap_io structure containing a list of events pending on the
    526  * file descriptor, and arg is the user-supplied argument.
    527  *
    528  * If fn returns 0, continue on to the next signal. Otherwise, return the same
    529  * value that fn returned.
    530  *
    531  * Note that there is no guarantee that the file descriptors will be processed
    532  * in any particular order.
    533  */
    534 static int
    535 evmap_io_foreach_fd(struct event_base *base,
    536     evmap_io_foreach_fd_cb fn,
    537     void *arg)
    538 {
    539 	evutil_socket_t fd;
    540 	struct event_io_map *iomap = &base->io;
    541 	int r = 0;
    542 #ifdef EVMAP_USE_HT
    543 	struct event_map_entry **mapent;
    544 	HT_FOREACH(mapent, event_io_map, iomap) {
    545 		struct evmap_io *ctx = &(*mapent)->ent.evmap_io;
    546 		fd = (*mapent)->fd;
    547 #else
    548 	for (fd = 0; fd < iomap->nentries; ++fd) {
    549 		struct evmap_io *ctx = iomap->entries[fd];
    550 		if (!ctx)
    551 			continue;
    552 #endif
    553 		if ((r = fn(base, fd, ctx, arg)))
    554 			break;
    555 	}
    556 	return r;
    557 }
    558 
    559 /* Callback type for evmap_signal_foreach_signal */
    560 typedef int (*evmap_signal_foreach_signal_cb)(
    561 	struct event_base *, int, struct evmap_signal *, void *);
    562 
    563 /* Multipurpose helper function: Iterate over every signal number in the
    564  * event_base for which we could have signal events.  For each such signal,
    565  * call fn(base, signum, evmap_signal, arg), where fn is the user-provided
    566  * function, base is the event_base, signum is the signal number, evmap_signal
    567  * is an evmap_signal structure containing a list of events pending on the
    568  * signal, and arg is the user-supplied argument.
    569  *
    570  * If fn returns 0, continue on to the next signal. Otherwise, return the same
    571  * value that fn returned.
    572  */
    573 static int
    574 evmap_signal_foreach_signal(struct event_base *base,
    575     evmap_signal_foreach_signal_cb fn,
    576     void *arg)
    577 {
    578 	struct event_signal_map *sigmap = &base->sigmap;
    579 	int r = 0;
    580 	int signum;
    581 
    582 	for (signum = 0; signum < sigmap->nentries; ++signum) {
    583 		struct evmap_signal *ctx = sigmap->entries[signum];
    584 		if (!ctx)
    585 			continue;
    586 		if ((r = fn(base, signum, ctx, arg)))
    587 			break;
    588 	}
    589 	return r;
    590 }
    591 
    592 /* Helper for evmap_reinit_: tell the backend to add every fd for which we have
    593  * pending events, with the appropriate combination of EV_READ, EV_WRITE, and
    594  * EV_ET. */
    595 static int
    596 evmap_io_reinit_iter_fn(struct event_base *base, evutil_socket_t fd,
    597     struct evmap_io *ctx, void *arg)
    598 {
    599 	const struct eventop *evsel = base->evsel;
    600 	void *extra;
    601 	int *result = arg;
    602 	short events = 0;
    603 	struct event *ev;
    604 	EVUTIL_ASSERT(ctx);
    605 
    606 	extra = ((char*)ctx) + sizeof(struct evmap_io);
    607 	if (ctx->nread)
    608 		events |= EV_READ;
    609 	if (ctx->nwrite)
    610 		events |= EV_WRITE;
    611 	if (ctx->nclose)
    612 		events |= EV_CLOSED;
    613 	if (evsel->fdinfo_len)
    614 		memset(extra, 0, evsel->fdinfo_len);
    615 	if (events &&
    616 	    (ev = LIST_FIRST(&ctx->events)) &&
    617 	    (ev->ev_events & EV_ET))
    618 		events |= EV_ET;
    619 	if (evsel->add(base, fd, 0, events, extra) == -1)
    620 		*result = -1;
    621 
    622 	return 0;
    623 }
    624 
    625 /* Helper for evmap_reinit_: tell the backend to add every signal for which we
    626  * have pending events.  */
    627 static int
    628 evmap_signal_reinit_iter_fn(struct event_base *base,
    629     int signum, struct evmap_signal *ctx, void *arg)
    630 {
    631 	const struct eventop *evsel = base->evsigsel;
    632 	int *result = arg;
    633 
    634 	if (!LIST_EMPTY(&ctx->events)) {
    635 		if (evsel->add(base, signum, 0, EV_SIGNAL, NULL) == -1)
    636 			*result = -1;
    637 	}
    638 	return 0;
    639 }
    640 
    641 int
    642 evmap_reinit_(struct event_base *base)
    643 {
    644 	int result = 0;
    645 
    646 	evmap_io_foreach_fd(base, evmap_io_reinit_iter_fn, &result);
    647 	if (result < 0)
    648 		return -1;
    649 	evmap_signal_foreach_signal(base, evmap_signal_reinit_iter_fn, &result);
    650 	if (result < 0)
    651 		return -1;
    652 	return 0;
    653 }
    654 
    655 /* Helper for evmap_delete_all_: delete every event in an event_dlist. */
    656 static int
    657 delete_all_in_dlist(struct event_dlist *dlist)
    658 {
    659 	struct event *ev;
    660 	while ((ev = LIST_FIRST(dlist)))
    661 		event_del(ev);
    662 	return 0;
    663 }
    664 
    665 /* Helper for evmap_delete_all_: delete every event pending on an fd. */
    666 static int
    667 evmap_io_delete_all_iter_fn(struct event_base *base, evutil_socket_t fd,
    668     struct evmap_io *io_info, void *arg)
    669 {
    670 	return delete_all_in_dlist(&io_info->events);
    671 }
    672 
    673 /* Helper for evmap_delete_all_: delete every event pending on a signal. */
    674 static int
    675 evmap_signal_delete_all_iter_fn(struct event_base *base, int signum,
    676     struct evmap_signal *sig_info, void *arg)
    677 {
    678 	return delete_all_in_dlist(&sig_info->events);
    679 }
    680 
    681 void
    682 evmap_delete_all_(struct event_base *base)
    683 {
    684 	evmap_signal_foreach_signal(base, evmap_signal_delete_all_iter_fn, NULL);
    685 	evmap_io_foreach_fd(base, evmap_io_delete_all_iter_fn, NULL);
    686 }
    687 
    688 /** Per-fd structure for use with changelists.  It keeps track, for each fd or
    689  * signal using the changelist, of where its entry in the changelist is.
    690  */
    691 struct event_changelist_fdinfo {
    692 	int idxplus1; /* this is the index +1, so that memset(0) will make it
    693 		       * a no-such-element */
    694 };
    695 
    696 void
    697 event_changelist_init_(struct event_changelist *changelist)
    698 {
    699 	changelist->changes = NULL;
    700 	changelist->changes_size = 0;
    701 	changelist->n_changes = 0;
    702 }
    703 
    704 /** Helper: return the changelist_fdinfo corresponding to a given change. */
    705 static inline struct event_changelist_fdinfo *
    706 event_change_get_fdinfo(struct event_base *base,
    707     const struct event_change *change)
    708 {
    709 	char *ptr;
    710 	if (change->read_change & EV_CHANGE_SIGNAL) {
    711 		struct evmap_signal *ctx;
    712 		GET_SIGNAL_SLOT(ctx, &base->sigmap, change->fd, evmap_signal);
    713 		ptr = ((char*)ctx) + sizeof(struct evmap_signal);
    714 	} else {
    715 		struct evmap_io *ctx;
    716 		GET_IO_SLOT(ctx, &base->io, change->fd, evmap_io);
    717 		ptr = ((char*)ctx) + sizeof(struct evmap_io);
    718 	}
    719 	return (void*)ptr;
    720 }
    721 
    722 /** Callback helper for event_changelist_assert_ok */
    723 static int
    724 event_changelist_assert_ok_foreach_iter_fn(
    725 	struct event_base *base,
    726 	evutil_socket_t fd, struct evmap_io *io, void *arg)
    727 {
    728 	struct event_changelist *changelist = &base->changelist;
    729 	struct event_changelist_fdinfo *f;
    730 	f = (void*)
    731 	    ( ((char*)io) + sizeof(struct evmap_io) );
    732 	if (f->idxplus1) {
    733 		struct event_change *c = &changelist->changes[f->idxplus1 - 1];
    734 		EVUTIL_ASSERT(c->fd == fd);
    735 	}
    736 	return 0;
    737 }
    738 
    739 /** Make sure that the changelist is consistent with the evmap structures. */
    740 static void
    741 event_changelist_assert_ok(struct event_base *base)
    742 {
    743 	int i;
    744 	struct event_changelist *changelist = &base->changelist;
    745 
    746 	EVUTIL_ASSERT(changelist->changes_size >= changelist->n_changes);
    747 	for (i = 0; i < changelist->n_changes; ++i) {
    748 		struct event_change *c = &changelist->changes[i];
    749 		struct event_changelist_fdinfo *f;
    750 		EVUTIL_ASSERT(c->fd >= 0);
    751 		f = event_change_get_fdinfo(base, c);
    752 		EVUTIL_ASSERT(f);
    753 		EVUTIL_ASSERT(f->idxplus1 == i + 1);
    754 	}
    755 
    756 	evmap_io_foreach_fd(base,
    757 	    event_changelist_assert_ok_foreach_iter_fn,
    758 	    NULL);
    759 }
    760 
    761 #ifdef DEBUG_CHANGELIST
    762 #define event_changelist_check(base)  event_changelist_assert_ok((base))
    763 #else
    764 #define event_changelist_check(base)  ((void)0)
    765 #endif
    766 
    767 void
    768 event_changelist_remove_all_(struct event_changelist *changelist,
    769     struct event_base *base)
    770 {
    771 	int i;
    772 
    773 	event_changelist_check(base);
    774 
    775 	for (i = 0; i < changelist->n_changes; ++i) {
    776 		struct event_change *ch = &changelist->changes[i];
    777 		struct event_changelist_fdinfo *fdinfo =
    778 		    event_change_get_fdinfo(base, ch);
    779 		EVUTIL_ASSERT(fdinfo->idxplus1 == i + 1);
    780 		fdinfo->idxplus1 = 0;
    781 	}
    782 
    783 	changelist->n_changes = 0;
    784 
    785 	event_changelist_check(base);
    786 }
    787 
    788 void
    789 event_changelist_freemem_(struct event_changelist *changelist)
    790 {
    791 	if (changelist->changes)
    792 		mm_free(changelist->changes);
    793 	event_changelist_init_(changelist); /* zero it all out. */
    794 }
    795 
    796 /** Increase the size of 'changelist' to hold more changes. */
    797 static int
    798 event_changelist_grow(struct event_changelist *changelist)
    799 {
    800 	int new_size;
    801 	struct event_change *new_changes;
    802 	if (changelist->changes_size < 64)
    803 		new_size = 64;
    804 	else
    805 		new_size = changelist->changes_size * 2;
    806 
    807 	new_changes = mm_realloc(changelist->changes,
    808 	    new_size * sizeof(struct event_change));
    809 
    810 	if (EVUTIL_UNLIKELY(new_changes == NULL))
    811 		return (-1);
    812 
    813 	changelist->changes = new_changes;
    814 	changelist->changes_size = new_size;
    815 
    816 	return (0);
    817 }
    818 
    819 /** Return a pointer to the changelist entry for the file descriptor or signal
    820  * 'fd', whose fdinfo is 'fdinfo'.  If none exists, construct it, setting its
    821  * old_events field to old_events.
    822  */
    823 static struct event_change *
    824 event_changelist_get_or_construct(struct event_changelist *changelist,
    825     evutil_socket_t fd,
    826     short old_events,
    827     struct event_changelist_fdinfo *fdinfo)
    828 {
    829 	struct event_change *change;
    830 
    831 	if (fdinfo->idxplus1 == 0) {
    832 		int idx;
    833 		EVUTIL_ASSERT(changelist->n_changes <= changelist->changes_size);
    834 
    835 		if (changelist->n_changes == changelist->changes_size) {
    836 			if (event_changelist_grow(changelist) < 0)
    837 				return NULL;
    838 		}
    839 
    840 		idx = changelist->n_changes++;
    841 		change = &changelist->changes[idx];
    842 		fdinfo->idxplus1 = idx + 1;
    843 
    844 		memset(change, 0, sizeof(struct event_change));
    845 		change->fd = fd;
    846 		change->old_events = old_events;
    847 	} else {
    848 		change = &changelist->changes[fdinfo->idxplus1 - 1];
    849 		EVUTIL_ASSERT(change->fd == fd);
    850 	}
    851 	return change;
    852 }
    853 
    854 int
    855 event_changelist_add_(struct event_base *base, evutil_socket_t fd, short old, short events,
    856     void *p)
    857 {
    858 	struct event_changelist *changelist = &base->changelist;
    859 	struct event_changelist_fdinfo *fdinfo = p;
    860 	struct event_change *change;
    861 
    862 	event_changelist_check(base);
    863 
    864 	change = event_changelist_get_or_construct(changelist, fd, old, fdinfo);
    865 	if (!change)
    866 		return -1;
    867 
    868 	/* An add replaces any previous delete, but doesn't result in a no-op,
    869 	 * since the delete might fail (because the fd had been closed since
    870 	 * the last add, for instance. */
    871 
    872 	if (events & (EV_READ|EV_SIGNAL)) {
    873 		change->read_change = EV_CHANGE_ADD |
    874 		    (events & (EV_ET|EV_PERSIST|EV_SIGNAL));
    875 	}
    876 	if (events & EV_WRITE) {
    877 		change->write_change = EV_CHANGE_ADD |
    878 		    (events & (EV_ET|EV_PERSIST|EV_SIGNAL));
    879 	}
    880 	if (events & EV_CLOSED) {
    881 		change->close_change = EV_CHANGE_ADD |
    882 		    (events & (EV_ET|EV_PERSIST|EV_SIGNAL));
    883 	}
    884 
    885 	event_changelist_check(base);
    886 	return (0);
    887 }
    888 
    889 int
    890 event_changelist_del_(struct event_base *base, evutil_socket_t fd, short old, short events,
    891     void *p)
    892 {
    893 	struct event_changelist *changelist = &base->changelist;
    894 	struct event_changelist_fdinfo *fdinfo = p;
    895 	struct event_change *change;
    896 
    897 	event_changelist_check(base);
    898 	change = event_changelist_get_or_construct(changelist, fd, old, fdinfo);
    899 	event_changelist_check(base);
    900 	if (!change)
    901 		return -1;
    902 
    903 	/* A delete on an event set that doesn't contain the event to be
    904 	   deleted produces a no-op.  This effectively emoves any previous
    905 	   uncommitted add, rather than replacing it: on those platforms where
    906 	   "add, delete, dispatch" is not the same as "no-op, dispatch", we
    907 	   want the no-op behavior.
    908 
    909 	   If we have a no-op item, we could remove it it from the list
    910 	   entirely, but really there's not much point: skipping the no-op
    911 	   change when we do the dispatch later is far cheaper than rejuggling
    912 	   the array now.
    913 
    914 	   As this stands, it also lets through deletions of events that are
    915 	   not currently set.
    916 	 */
    917 
    918 	if (events & (EV_READ|EV_SIGNAL)) {
    919 		if (!(change->old_events & (EV_READ | EV_SIGNAL)))
    920 			change->read_change = 0;
    921 		else
    922 			change->read_change = EV_CHANGE_DEL;
    923 	}
    924 	if (events & EV_WRITE) {
    925 		if (!(change->old_events & EV_WRITE))
    926 			change->write_change = 0;
    927 		else
    928 			change->write_change = EV_CHANGE_DEL;
    929 	}
    930 	if (events & EV_CLOSED) {
    931 		if (!(change->old_events & EV_CLOSED))
    932 			change->close_change = 0;
    933 		else
    934 			change->close_change = EV_CHANGE_DEL;
    935 	}
    936 
    937 	event_changelist_check(base);
    938 	return (0);
    939 }
    940 
    941 /* Helper for evmap_check_integrity_: verify that all of the events pending on
    942  * given fd are set up correctly, and that the nread and nwrite counts on that
    943  * fd are correct. */
    944 static int
    945 evmap_io_check_integrity_fn(struct event_base *base, evutil_socket_t fd,
    946     struct evmap_io *io_info, void *arg)
    947 {
    948 	struct event *ev;
    949 	int n_read = 0, n_write = 0, n_close = 0;
    950 
    951 	/* First, make sure the list itself isn't corrupt. Otherwise,
    952 	 * running LIST_FOREACH could be an exciting adventure. */
    953 	EVUTIL_ASSERT_LIST_OK(&io_info->events, event, ev_io_next);
    954 
    955 	LIST_FOREACH(ev, &io_info->events, ev_io_next) {
    956 		EVUTIL_ASSERT(ev->ev_flags & EVLIST_INSERTED);
    957 		EVUTIL_ASSERT(ev->ev_fd == fd);
    958 		EVUTIL_ASSERT(!(ev->ev_events & EV_SIGNAL));
    959 		EVUTIL_ASSERT((ev->ev_events & (EV_READ|EV_WRITE|EV_CLOSED)));
    960 		if (ev->ev_events & EV_READ)
    961 			++n_read;
    962 		if (ev->ev_events & EV_WRITE)
    963 			++n_write;
    964 		if (ev->ev_events & EV_CLOSED)
    965 			++n_close;
    966 	}
    967 
    968 	EVUTIL_ASSERT(n_read == io_info->nread);
    969 	EVUTIL_ASSERT(n_write == io_info->nwrite);
    970 	EVUTIL_ASSERT(n_close == io_info->nclose);
    971 
    972 	return 0;
    973 }
    974 
    975 /* Helper for evmap_check_integrity_: verify that all of the events pending
    976  * on given signal are set up correctly. */
    977 static int
    978 evmap_signal_check_integrity_fn(struct event_base *base,
    979     int signum, struct evmap_signal *sig_info, void *arg)
    980 {
    981 	struct event *ev;
    982 	/* First, make sure the list itself isn't corrupt. */
    983 	EVUTIL_ASSERT_LIST_OK(&sig_info->events, event, ev_signal_next);
    984 
    985 	LIST_FOREACH(ev, &sig_info->events, ev_io_next) {
    986 		EVUTIL_ASSERT(ev->ev_flags & EVLIST_INSERTED);
    987 		EVUTIL_ASSERT(ev->ev_fd == signum);
    988 		EVUTIL_ASSERT((ev->ev_events & EV_SIGNAL));
    989 		EVUTIL_ASSERT(!(ev->ev_events & (EV_READ|EV_WRITE|EV_CLOSED)));
    990 	}
    991 	return 0;
    992 }
    993 
    994 void
    995 evmap_check_integrity_(struct event_base *base)
    996 {
    997 	evmap_io_foreach_fd(base, evmap_io_check_integrity_fn, NULL);
    998 	evmap_signal_foreach_signal(base, evmap_signal_check_integrity_fn, NULL);
    999 
   1000 	if (base->evsel->add == event_changelist_add_)
   1001 		event_changelist_assert_ok(base);
   1002 }
   1003 
   1004 /* Helper type for evmap_foreach_event_: Bundles a function to call on every
   1005  * event, and the user-provided void* to use as its third argument. */
   1006 struct evmap_foreach_event_helper {
   1007 	event_base_foreach_event_cb fn;
   1008 	void *arg;
   1009 };
   1010 
   1011 /* Helper for evmap_foreach_event_: calls a provided function on every event
   1012  * pending on a given fd.  */
   1013 static int
   1014 evmap_io_foreach_event_fn(struct event_base *base, evutil_socket_t fd,
   1015     struct evmap_io *io_info, void *arg)
   1016 {
   1017 	struct evmap_foreach_event_helper *h = arg;
   1018 	struct event *ev;
   1019 	int r;
   1020 	LIST_FOREACH(ev, &io_info->events, ev_io_next) {
   1021 		if ((r = h->fn(base, ev, h->arg)))
   1022 			return r;
   1023 	}
   1024 	return 0;
   1025 }
   1026 
   1027 /* Helper for evmap_foreach_event_: calls a provided function on every event
   1028  * pending on a given signal.  */
   1029 static int
   1030 evmap_signal_foreach_event_fn(struct event_base *base, int signum,
   1031     struct evmap_signal *sig_info, void *arg)
   1032 {
   1033 	struct event *ev;
   1034 	struct evmap_foreach_event_helper *h = arg;
   1035 	int r;
   1036 	LIST_FOREACH(ev, &sig_info->events, ev_signal_next) {
   1037 		if ((r = h->fn(base, ev, h->arg)))
   1038 			return r;
   1039 	}
   1040 	return 0;
   1041 }
   1042 
   1043 int
   1044 evmap_foreach_event_(struct event_base *base,
   1045     event_base_foreach_event_cb fn, void *arg)
   1046 {
   1047 	struct evmap_foreach_event_helper h;
   1048 	int r;
   1049 	h.fn = fn;
   1050 	h.arg = arg;
   1051 	if ((r = evmap_io_foreach_fd(base, evmap_io_foreach_event_fn, &h)))
   1052 		return r;
   1053 	return evmap_signal_foreach_signal(base, evmap_signal_foreach_event_fn, &h);
   1054 }
   1055 
   1056