This source file includes following definitions.
- hashsocket
- eqsocket
- evmap_io_initmap
- evmap_io_clear
- evmap_io_initmap
- evmap_io_clear
- evmap_make_space
- evmap_signal_initmap
- evmap_signal_clear
- evmap_io_init
- evmap_io_add
- evmap_io_del
- evmap_io_active
- evmap_signal_init
- evmap_signal_add
- evmap_signal_del
- evmap_signal_active
- evmap_io_get_fdinfo
- event_changelist_init
- event_change_get_fdinfo
- event_changelist_check
- event_changelist_remove_all
- event_changelist_freemem
- event_changelist_grow
- event_changelist_get_or_construct
- event_changelist_add
- event_changelist_del
- evmap_check_integrity
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 #include "event2/event-config.h"
  27 
  28 #ifdef WIN32
  29 #include <winsock2.h>
  30 #define WIN32_LEAN_AND_MEAN
  31 #include <windows.h>
  32 #undef WIN32_LEAN_AND_MEAN
  33 #endif
  34 #include <sys/types.h>
  35 #if !defined(WIN32) && defined(_EVENT_HAVE_SYS_TIME_H)
  36 #include <sys/time.h>
  37 #endif
  38 #include <sys/queue.h>
  39 #include <stdio.h>
  40 #include <stdlib.h>
  41 #ifndef WIN32
  42 #include <unistd.h>
  43 #endif
  44 #include <errno.h>
  45 #include <signal.h>
  46 #include <string.h>
  47 #include <time.h>
  48 
  49 #include "event-internal.h"
  50 #include "evmap-internal.h"
  51 #include "mm-internal.h"
  52 #include "changelist-internal.h"
  53 
  54 
  55 
  56 
  57 struct evmap_io {
  58         struct event_list events;
  59         ev_uint16_t nread;
  60         ev_uint16_t nwrite;
  61 };
  62 
  63 
  64 
  65 struct evmap_signal {
  66         struct event_list events;
  67 };
  68 
  69 
  70 
  71 
  72 
  73 
  74 
  75 
  76 #ifdef EVMAP_USE_HT
  77 struct event_map_entry {
  78         HT_ENTRY(event_map_entry) map_node;
  79         evutil_socket_t fd;
  80         union { 
  81 
  82                 struct evmap_io evmap_io;
  83         } ent;
  84 };
  85 
  86 
  87 
  88 static inline unsigned
  89 hashsocket(struct event_map_entry *e)
  90 {
  91         
  92 
  93 
  94         unsigned h = (unsigned) e->fd;
  95         h += (h >> 2) | (h << 30);
  96         return h;
  97 }
  98 
  99 
 100 
 101 static inline int
 102 eqsocket(struct event_map_entry *e1, struct event_map_entry *e2)
 103 {
 104         return e1->fd == e2->fd;
 105 }
 106 
 107 HT_PROTOTYPE(event_io_map, event_map_entry, map_node, hashsocket, eqsocket)
 108 HT_GENERATE(event_io_map, event_map_entry, map_node, hashsocket, eqsocket,
 109                         0.5, mm_malloc, mm_realloc, mm_free)
 110 
 111 #define GET_IO_SLOT(x, map, slot, type)                                 \
 112         do {                                                            \
 113                 struct event_map_entry _key, *_ent;                     \
 114                 _key.fd = slot;                                         \
 115                 _ent = HT_FIND(event_io_map, map, &_key);               \
 116                 (x) = _ent ? &_ent->ent.type : NULL;                    \
 117         } while (0);
 118 
 119 #define GET_IO_SLOT_AND_CTOR(x, map, slot, type, ctor, fdinfo_len)      \
 120         do {                                                            \
 121                 struct event_map_entry _key, *_ent;                     \
 122                 _key.fd = slot;                                         \
 123                 _HT_FIND_OR_INSERT(event_io_map, map_node, hashsocket, map, \
 124                     event_map_entry, &_key, ptr,                        \
 125                     {                                                   \
 126                             _ent = *ptr;                                \
 127                     },                                                  \
 128                     {                                                   \
 129                             _ent = mm_calloc(1,sizeof(struct event_map_entry)+fdinfo_len); \
 130                             if (EVUTIL_UNLIKELY(_ent == NULL))          \
 131                                     return (-1);                        \
 132                             _ent->fd = slot;                            \
 133                             (ctor)(&_ent->ent.type);                    \
 134                             _HT_FOI_INSERT(map_node, map, &_key, _ent, ptr) \
 135                                 });                                     \
 136                 (x) = &_ent->ent.type;                                  \
 137         } while (0)
 138 
 139 void evmap_io_initmap(struct event_io_map *ctx)
 140 {
 141         HT_INIT(event_io_map, ctx);
 142 }
 143 
 144 void evmap_io_clear(struct event_io_map *ctx)
 145 {
 146         struct event_map_entry **ent, **next, *this;
 147         for (ent = HT_START(event_io_map, ctx); ent; ent = next) {
 148                 this = *ent;
 149                 next = HT_NEXT_RMV(event_io_map, ctx, ent);
 150                 mm_free(this);
 151         }
 152         HT_CLEAR(event_io_map, ctx); 
 153 }
 154 #endif
 155 
 156 
 157 
 158 
 159 #define GET_SIGNAL_SLOT(x, map, slot, type)                     \
 160         (x) = (struct type *)((map)->entries[slot])
 161 
 162 
 163 
 164 
 165 
 166 #define GET_SIGNAL_SLOT_AND_CTOR(x, map, slot, type, ctor, fdinfo_len)  \
 167         do {                                                            \
 168                 if ((map)->entries[slot] == NULL) {                     \
 169                         (map)->entries[slot] =                          \
 170                             mm_calloc(1,sizeof(struct type)+fdinfo_len); \
 171                         if (EVUTIL_UNLIKELY((map)->entries[slot] == NULL)) \
 172                                 return (-1);                            \
 173                         (ctor)((struct type *)(map)->entries[slot]);    \
 174                 }                                                       \
 175                 (x) = (struct type *)((map)->entries[slot]);            \
 176         } while (0)
 177 
 178 
 179 
 180 #ifndef EVMAP_USE_HT
 181 #define GET_IO_SLOT(x,map,slot,type) GET_SIGNAL_SLOT(x,map,slot,type)
 182 #define GET_IO_SLOT_AND_CTOR(x,map,slot,type,ctor,fdinfo_len)   \
 183         GET_SIGNAL_SLOT_AND_CTOR(x,map,slot,type,ctor,fdinfo_len)
 184 #define FDINFO_OFFSET sizeof(struct evmap_io)
 185 void
 186 evmap_io_initmap(struct event_io_map* ctx)
 187 {
 188         evmap_signal_initmap(ctx);
 189 }
 190 void
 191 evmap_io_clear(struct event_io_map* ctx)
 192 {
 193         evmap_signal_clear(ctx);
 194 }
 195 #endif
 196 
 197 
 198 
 199 
 200 
 201 static int
 202 evmap_make_space(struct event_signal_map *map, int slot, int msize)
 203 {
 204         if (map->nentries <= slot) {
 205                 int nentries = map->nentries ? map->nentries : 32;
 206                 void **tmp;
 207 
 208                 while (nentries <= slot)
 209                         nentries <<= 1;
 210 
 211                 tmp = (void **)mm_realloc(map->entries, nentries * msize);
 212                 if (tmp == NULL)
 213                         return (-1);
 214 
 215                 memset(&tmp[map->nentries], 0,
 216                     (nentries - map->nentries) * msize);
 217 
 218                 map->nentries = nentries;
 219                 map->entries = tmp;
 220         }
 221 
 222         return (0);
 223 }
 224 
 225 void
 226 evmap_signal_initmap(struct event_signal_map *ctx)
 227 {
 228         ctx->nentries = 0;
 229         ctx->entries = NULL;
 230 }
 231 
 232 void
 233 evmap_signal_clear(struct event_signal_map *ctx)
 234 {
 235         if (ctx->entries != NULL) {
 236                 int i;
 237                 for (i = 0; i < ctx->nentries; ++i) {
 238                         if (ctx->entries[i] != NULL)
 239                                 mm_free(ctx->entries[i]);
 240                 }
 241                 mm_free(ctx->entries);
 242                 ctx->entries = NULL;
 243         }
 244         ctx->nentries = 0;
 245 }
 246 
 247 
 248 
 249 
 250 
 251 static void
 252 evmap_io_init(struct evmap_io *entry)
 253 {
 254         TAILQ_INIT(&entry->events);
 255         entry->nread = 0;
 256         entry->nwrite = 0;
 257 }
 258 
 259 
 260 
 261 
 262 int
 263 evmap_io_add(struct event_base *base, evutil_socket_t fd, struct event *ev)
 264 {
 265         const struct eventop *evsel = base->evsel;
 266         struct event_io_map *io = &base->io;
 267         struct evmap_io *ctx = NULL;
 268         int nread, nwrite, retval = 0;
 269         short res = 0, old = 0;
 270         struct event *old_ev;
 271 
 272         EVUTIL_ASSERT(fd == ev->ev_fd);
 273 
 274         if (fd < 0)
 275                 return 0;
 276 
 277 #ifndef EVMAP_USE_HT
 278         if (fd >= io->nentries) {
 279                 if (evmap_make_space(io, fd, sizeof(struct evmap_io *)) == -1)
 280                         return (-1);
 281         }
 282 #endif
 283         GET_IO_SLOT_AND_CTOR(ctx, io, fd, evmap_io, evmap_io_init,
 284                                                  evsel->fdinfo_len);
 285 
 286         nread = ctx->nread;
 287         nwrite = ctx->nwrite;
 288 
 289         if (nread)
 290                 old |= EV_READ;
 291         if (nwrite)
 292                 old |= EV_WRITE;
 293 
 294         if (ev->ev_events & EV_READ) {
 295                 if (++nread == 1)
 296                         res |= EV_READ;
 297         }
 298         if (ev->ev_events & EV_WRITE) {
 299                 if (++nwrite == 1)
 300                         res |= EV_WRITE;
 301         }
 302         if (EVUTIL_UNLIKELY(nread > 0xffff || nwrite > 0xffff)) {
 303                 event_warnx("Too many events reading or writing on fd %d",
 304                     (int)fd);
 305                 return -1;
 306         }
 307         if (EVENT_DEBUG_MODE_IS_ON() &&
 308             (old_ev = TAILQ_FIRST(&ctx->events)) &&
 309             (old_ev->ev_events&EV_ET) != (ev->ev_events&EV_ET)) {
 310                 event_warnx("Tried to mix edge-triggered and non-edge-triggered"
 311                     " events on fd %d", (int)fd);
 312                 return -1;
 313         }
 314 
 315         if (res) {
 316                 void *extra = ((char*)ctx) + sizeof(struct evmap_io);
 317                 
 318 
 319 
 320                 if (evsel->add(base, ev->ev_fd,
 321                         old, (ev->ev_events & EV_ET) | res, extra) == -1)
 322                         return (-1);
 323                 retval = 1;
 324         }
 325 
 326         ctx->nread = (ev_uint16_t) nread;
 327         ctx->nwrite = (ev_uint16_t) nwrite;
 328         TAILQ_INSERT_TAIL(&ctx->events, ev, ev_io_next);
 329 
 330         return (retval);
 331 }
 332 
 333 
 334 
 335 int
 336 evmap_io_del(struct event_base *base, evutil_socket_t fd, struct event *ev)
 337 {
 338         const struct eventop *evsel = base->evsel;
 339         struct event_io_map *io = &base->io;
 340         struct evmap_io *ctx;
 341         int nread, nwrite, retval = 0;
 342         short res = 0, old = 0;
 343 
 344         if (fd < 0)
 345                 return 0;
 346 
 347         EVUTIL_ASSERT(fd == ev->ev_fd);
 348 
 349 #ifndef EVMAP_USE_HT
 350         if (fd >= io->nentries)
 351                 return (-1);
 352 #endif
 353 
 354         GET_IO_SLOT(ctx, io, fd, evmap_io);
 355 
 356         nread = ctx->nread;
 357         nwrite = ctx->nwrite;
 358 
 359         if (nread)
 360                 old |= EV_READ;
 361         if (nwrite)
 362                 old |= EV_WRITE;
 363 
 364         if (ev->ev_events & EV_READ) {
 365                 if (--nread == 0)
 366                         res |= EV_READ;
 367                 EVUTIL_ASSERT(nread >= 0);
 368         }
 369         if (ev->ev_events & EV_WRITE) {
 370                 if (--nwrite == 0)
 371                         res |= EV_WRITE;
 372                 EVUTIL_ASSERT(nwrite >= 0);
 373         }
 374 
 375         if (res) {
 376                 void *extra = ((char*)ctx) + sizeof(struct evmap_io);
 377                 if (evsel->del(base, ev->ev_fd, old, res, extra) == -1)
 378                         return (-1);
 379                 retval = 1;
 380         }
 381 
 382         ctx->nread = nread;
 383         ctx->nwrite = nwrite;
 384         TAILQ_REMOVE(&ctx->events, ev, ev_io_next);
 385 
 386         return (retval);
 387 }
 388 
 389 void
 390 evmap_io_active(struct event_base *base, evutil_socket_t fd, short events)
 391 {
 392         struct event_io_map *io = &base->io;
 393         struct evmap_io *ctx;
 394         struct event *ev;
 395 
 396 #ifndef EVMAP_USE_HT
 397         EVUTIL_ASSERT(fd < io->nentries);
 398 #endif
 399         GET_IO_SLOT(ctx, io, fd, evmap_io);
 400 
 401         EVUTIL_ASSERT(ctx);
 402         TAILQ_FOREACH(ev, &ctx->events, ev_io_next) {
 403                 if (ev->ev_events & events)
 404                         event_active_nolock(ev, ev->ev_events & events, 1);
 405         }
 406 }
 407 
 408 
 409 
 410 static void
 411 evmap_signal_init(struct evmap_signal *entry)
 412 {
 413         TAILQ_INIT(&entry->events);
 414 }
 415 
 416 
 417 int
 418 evmap_signal_add(struct event_base *base, int sig, struct event *ev)
 419 {
 420         const struct eventop *evsel = base->evsigsel;
 421         struct event_signal_map *map = &base->sigmap;
 422         struct evmap_signal *ctx = NULL;
 423 
 424         if (sig >= map->nentries) {
 425                 if (evmap_make_space(
 426                         map, sig, sizeof(struct evmap_signal *)) == -1)
 427                         return (-1);
 428         }
 429         GET_SIGNAL_SLOT_AND_CTOR(ctx, map, sig, evmap_signal, evmap_signal_init,
 430             base->evsigsel->fdinfo_len);
 431 
 432         if (TAILQ_EMPTY(&ctx->events)) {
 433                 if (evsel->add(base, ev->ev_fd, 0, EV_SIGNAL, NULL)
 434                     == -1)
 435                         return (-1);
 436         }
 437 
 438         TAILQ_INSERT_TAIL(&ctx->events, ev, ev_signal_next);
 439 
 440         return (1);
 441 }
 442 
 443 int
 444 evmap_signal_del(struct event_base *base, int sig, struct event *ev)
 445 {
 446         const struct eventop *evsel = base->evsigsel;
 447         struct event_signal_map *map = &base->sigmap;
 448         struct evmap_signal *ctx;
 449 
 450         if (sig >= map->nentries)
 451                 return (-1);
 452 
 453         GET_SIGNAL_SLOT(ctx, map, sig, evmap_signal);
 454 
 455         if (TAILQ_FIRST(&ctx->events) == TAILQ_LAST(&ctx->events, event_list)) {
 456                 if (evsel->del(base, ev->ev_fd, 0, EV_SIGNAL, NULL) == -1)
 457                         return (-1);
 458         }
 459 
 460         TAILQ_REMOVE(&ctx->events, ev, ev_signal_next);
 461 
 462         return (1);
 463 }
 464 
 465 void
 466 evmap_signal_active(struct event_base *base, evutil_socket_t sig, int ncalls)
 467 {
 468         struct event_signal_map *map = &base->sigmap;
 469         struct evmap_signal *ctx;
 470         struct event *ev;
 471 
 472         EVUTIL_ASSERT(sig < map->nentries);
 473         GET_SIGNAL_SLOT(ctx, map, sig, evmap_signal);
 474 
 475         TAILQ_FOREACH(ev, &ctx->events, ev_signal_next)
 476                 event_active_nolock(ev, EV_SIGNAL, ncalls);
 477 }
 478 
 479 void *
 480 evmap_io_get_fdinfo(struct event_io_map *map, evutil_socket_t fd)
 481 {
 482         struct evmap_io *ctx;
 483         GET_IO_SLOT(ctx, map, fd, evmap_io);
 484         if (ctx)
 485                 return ((char*)ctx) + sizeof(struct evmap_io);
 486         else
 487                 return NULL;
 488 }
 489 
 490 
 491 
 492 
 493 struct event_changelist_fdinfo {
 494         int idxplus1; 
 495 
 496 };
 497 
 498 void
 499 event_changelist_init(struct event_changelist *changelist)
 500 {
 501         changelist->changes = NULL;
 502         changelist->changes_size = 0;
 503         changelist->n_changes = 0;
 504 }
 505 
 506 
 507 static inline struct event_changelist_fdinfo *
 508 event_change_get_fdinfo(struct event_base *base,
 509     const struct event_change *change)
 510 {
 511         char *ptr;
 512         if (change->read_change & EV_CHANGE_SIGNAL) {
 513                 struct evmap_signal *ctx;
 514                 GET_SIGNAL_SLOT(ctx, &base->sigmap, change->fd, evmap_signal);
 515                 ptr = ((char*)ctx) + sizeof(struct evmap_signal);
 516         } else {
 517                 struct evmap_io *ctx;
 518                 GET_IO_SLOT(ctx, &base->io, change->fd, evmap_io);
 519                 ptr = ((char*)ctx) + sizeof(struct evmap_io);
 520         }
 521         return (void*)ptr;
 522 }
 523 
 524 #ifdef DEBUG_CHANGELIST
 525 
 526 static void
 527 event_changelist_check(struct event_base *base)
 528 {
 529         int i;
 530         struct event_changelist *changelist = &base->changelist;
 531 
 532         EVUTIL_ASSERT(changelist->changes_size >= changelist->n_changes);
 533         for (i = 0; i < changelist->n_changes; ++i) {
 534                 struct event_change *c = &changelist->changes[i];
 535                 struct event_changelist_fdinfo *f;
 536                 EVUTIL_ASSERT(c->fd >= 0);
 537                 f = event_change_get_fdinfo(base, c);
 538                 EVUTIL_ASSERT(f);
 539                 EVUTIL_ASSERT(f->idxplus1 == i + 1);
 540         }
 541 
 542         for (i = 0; i < base->io.nentries; ++i) {
 543                 struct evmap_io *io = base->io.entries[i];
 544                 struct event_changelist_fdinfo *f;
 545                 if (!io)
 546                         continue;
 547                 f = (void*)
 548                     ( ((char*)io) + sizeof(struct evmap_io) );
 549                 if (f->idxplus1) {
 550                         struct event_change *c = &changelist->changes[f->idxplus1 - 1];
 551                         EVUTIL_ASSERT(c->fd == i);
 552                 }
 553         }
 554 }
 555 #else
 556 #define event_changelist_check(base)  ((void)0)
 557 #endif
 558 
 559 void
 560 event_changelist_remove_all(struct event_changelist *changelist,
 561     struct event_base *base)
 562 {
 563         int i;
 564 
 565         event_changelist_check(base);
 566 
 567         for (i = 0; i < changelist->n_changes; ++i) {
 568                 struct event_change *ch = &changelist->changes[i];
 569                 struct event_changelist_fdinfo *fdinfo =
 570                     event_change_get_fdinfo(base, ch);
 571                 EVUTIL_ASSERT(fdinfo->idxplus1 == i + 1);
 572                 fdinfo->idxplus1 = 0;
 573         }
 574 
 575         changelist->n_changes = 0;
 576 
 577         event_changelist_check(base);
 578 }
 579 
 580 void
 581 event_changelist_freemem(struct event_changelist *changelist)
 582 {
 583         if (changelist->changes)
 584                 mm_free(changelist->changes);
 585         event_changelist_init(changelist); 
 586 }
 587 
 588 
 589 static int
 590 event_changelist_grow(struct event_changelist *changelist)
 591 {
 592         int new_size;
 593         struct event_change *new_changes;
 594         if (changelist->changes_size < 64)
 595                 new_size = 64;
 596         else
 597                 new_size = changelist->changes_size * 2;
 598 
 599         new_changes = mm_realloc(changelist->changes,
 600             new_size * sizeof(struct event_change));
 601 
 602         if (EVUTIL_UNLIKELY(new_changes == NULL))
 603                 return (-1);
 604 
 605         changelist->changes = new_changes;
 606         changelist->changes_size = new_size;
 607 
 608         return (0);
 609 }
 610 
 611 
 612 
 613 
 614 
 615 static struct event_change *
 616 event_changelist_get_or_construct(struct event_changelist *changelist,
 617     evutil_socket_t fd,
 618     short old_events,
 619     struct event_changelist_fdinfo *fdinfo)
 620 {
 621         struct event_change *change;
 622 
 623         if (fdinfo->idxplus1 == 0) {
 624                 int idx;
 625                 EVUTIL_ASSERT(changelist->n_changes <= changelist->changes_size);
 626 
 627                 if (changelist->n_changes == changelist->changes_size) {
 628                         if (event_changelist_grow(changelist) < 0)
 629                                 return NULL;
 630                 }
 631 
 632                 idx = changelist->n_changes++;
 633                 change = &changelist->changes[idx];
 634                 fdinfo->idxplus1 = idx + 1;
 635 
 636                 memset(change, 0, sizeof(struct event_change));
 637                 change->fd = fd;
 638                 change->old_events = old_events;
 639         } else {
 640                 change = &changelist->changes[fdinfo->idxplus1 - 1];
 641                 EVUTIL_ASSERT(change->fd == fd);
 642         }
 643         return change;
 644 }
 645 
 646 int
 647 event_changelist_add(struct event_base *base, evutil_socket_t fd, short old, short events,
 648     void *p)
 649 {
 650         struct event_changelist *changelist = &base->changelist;
 651         struct event_changelist_fdinfo *fdinfo = p;
 652         struct event_change *change;
 653 
 654         event_changelist_check(base);
 655 
 656         change = event_changelist_get_or_construct(changelist, fd, old, fdinfo);
 657         if (!change)
 658                 return -1;
 659 
 660         
 661 
 662 
 663 
 664         if (events & (EV_READ|EV_SIGNAL)) {
 665                 change->read_change = EV_CHANGE_ADD |
 666                     (events & (EV_ET|EV_PERSIST|EV_SIGNAL));
 667         }
 668         if (events & EV_WRITE) {
 669                 change->write_change = EV_CHANGE_ADD |
 670                     (events & (EV_ET|EV_PERSIST|EV_SIGNAL));
 671         }
 672 
 673         event_changelist_check(base);
 674         return (0);
 675 }
 676 
 677 int
 678 event_changelist_del(struct event_base *base, evutil_socket_t fd, short old, short events,
 679     void *p)
 680 {
 681         struct event_changelist *changelist = &base->changelist;
 682         struct event_changelist_fdinfo *fdinfo = p;
 683         struct event_change *change;
 684 
 685         event_changelist_check(base);
 686         change = event_changelist_get_or_construct(changelist, fd, old, fdinfo);
 687         event_changelist_check(base);
 688         if (!change)
 689                 return -1;
 690 
 691         
 692 
 693 
 694 
 695 
 696 
 697 
 698 
 699 
 700 
 701 
 702 
 703 
 704 
 705 
 706 
 707 
 708 
 709         if (events & (EV_READ|EV_SIGNAL)) {
 710                 if (!(change->old_events & (EV_READ | EV_SIGNAL)) &&
 711                     (change->read_change & EV_CHANGE_ADD))
 712                         change->read_change = 0;
 713                 else
 714                         change->read_change = EV_CHANGE_DEL;
 715         }
 716         if (events & EV_WRITE) {
 717                 if (!(change->old_events & EV_WRITE) &&
 718                     (change->write_change & EV_CHANGE_ADD))
 719                         change->write_change = 0;
 720                 else
 721                         change->write_change = EV_CHANGE_DEL;
 722         }
 723 
 724         event_changelist_check(base);
 725         return (0);
 726 }
 727 
 728 void
 729 evmap_check_integrity(struct event_base *base)
 730 {
 731 #define EVLIST_X_SIGFOUND 0x1000
 732 #define EVLIST_X_IOFOUND 0x2000
 733 
 734         evutil_socket_t i;
 735         struct event *ev;
 736         struct event_io_map *io = &base->io;
 737         struct event_signal_map *sigmap = &base->sigmap;
 738 #ifdef EVMAP_USE_HT
 739         struct event_map_entry **mapent;
 740 #endif
 741         int nsignals, ntimers, nio;
 742         nsignals = ntimers = nio = 0;
 743 
 744         TAILQ_FOREACH(ev, &base->eventqueue, ev_next) {
 745                 EVUTIL_ASSERT(ev->ev_flags & EVLIST_INSERTED);
 746                 EVUTIL_ASSERT(ev->ev_flags & EVLIST_INIT);
 747                 ev->ev_flags &= ~(EVLIST_X_SIGFOUND|EVLIST_X_IOFOUND);
 748         }
 749 
 750 #ifdef EVMAP_USE_HT
 751         HT_FOREACH(mapent, event_io_map, io) {
 752                 struct evmap_io *ctx = &(*mapent)->ent.evmap_io;
 753                 i = (*mapent)->fd;
 754 #else
 755         for (i = 0; i < io->nentries; ++i) {
 756                 struct evmap_io *ctx = io->entries[i];
 757 
 758                 if (!ctx)
 759                         continue;
 760 #endif
 761 
 762                 TAILQ_FOREACH(ev, &ctx->events, ev_io_next) {
 763                         EVUTIL_ASSERT(!(ev->ev_flags & EVLIST_X_IOFOUND));
 764                         EVUTIL_ASSERT(ev->ev_fd == i);
 765                         ev->ev_flags |= EVLIST_X_IOFOUND;
 766                         nio++;
 767                 }
 768         }
 769 
 770         for (i = 0; i < sigmap->nentries; ++i) {
 771                 struct evmap_signal *ctx = sigmap->entries[i];
 772                 if (!ctx)
 773                         continue;
 774 
 775                 TAILQ_FOREACH(ev, &ctx->events, ev_signal_next) {
 776                         EVUTIL_ASSERT(!(ev->ev_flags & EVLIST_X_SIGFOUND));
 777                         EVUTIL_ASSERT(ev->ev_fd == i);
 778                         ev->ev_flags |= EVLIST_X_SIGFOUND;
 779                         nsignals++;
 780                 }
 781         }
 782 
 783         TAILQ_FOREACH(ev, &base->eventqueue, ev_next) {
 784                 if (ev->ev_events & (EV_READ|EV_WRITE)) {
 785                         EVUTIL_ASSERT(ev->ev_flags & EVLIST_X_IOFOUND);
 786                         --nio;
 787                 }
 788                 if (ev->ev_events & EV_SIGNAL) {
 789                         EVUTIL_ASSERT(ev->ev_flags & EVLIST_X_SIGFOUND);
 790                         --nsignals;
 791                 }
 792         }
 793 
 794         EVUTIL_ASSERT(nio == 0);
 795         EVUTIL_ASSERT(nsignals == 0);
 796         
 797 
 798 
 799 }