/* Since Linux 2.6.17, poll is able to report about peer half-closed connection usingspecialPOLLRDHUPflagonareadevent.
*/ #if !defined(POLLRDHUP) #define POLLRDHUP 0 #define EARLY_CLOSE_IF_HAVE_RDHUP 0 #else #define EARLY_CLOSE_IF_HAVE_RDHUP EV_FEATURE_EARLY_CLOSE #endif
struct pollidx {
int idxplus1;
};
struct pollop {
int event_count; /* Highest number alloc */
int nfds; /* Highest number used */
int realloc_copy; /* True iff we must realloc
* event_set_copy */ struct pollfd *event_set; struct pollfd *event_set_copy;
};
staticvoid *poll_init(struct event_base *); static int poll_add(struct event_base *, int, short old, short events, void *idx); static int poll_del(struct event_base *, int, short old, short events, void *idx); static int poll_dispatch(struct event_base *, struct timeval *); staticvoid poll_dealloc(struct event_base *);
i = evutil_weakrand_range_(&base->weakrand_seed, nfds);
for (j = 0; j < nfds; j++) {
int what;
if (++i == nfds)
i = 0;
what = event_set[i].revents;
if (!what) continue;
res = 0;
/* If the file gets closed notify */
if (what & (POLLHUP|POLLERR|POLLNVAL))
what |= POLLIN|POLLOUT;
if (what & POLLIN)
res |= EV_READ;
if (what & POLLOUT)
res |= EV_WRITE;
if (what & POLLRDHUP)
res |= EV_CLOSED;
if (res == 0) continue;
evmap_io_active_(base, event_set[i].fd, res);
}
return (0);
}
static int
poll_add(struct event_base *base, int fd, short old, short events, void *idx_)
{ struct pollop *pop = base->evbase; struct pollfd *pfd = NULL; struct pollidx *idx = idx_;
int i;
poll_check_ok(pop);
i = idx->idxplus1 - 1;
if (i < 0) return (-1);
/* Do we still want to read or write? */
pfd = &pop->event_set[i];
if (events & EV_READ)
pfd->events &= ~POLLIN;
if (events & EV_WRITE)
pfd->events &= ~POLLOUT;
if (events & EV_CLOSED)
pfd->events &= ~POLLRDHUP;
poll_check_ok(pop);
if (pfd->events) /* Another event cares about that fd. */ return (0);
/* Okay, so we aren't interested in that fd anymore. */
idx->idxplus1 = 0;
--pop->nfds;
if (i != pop->nfds) { /* *Shiftthelastpollfddownintothenow-unoccupied *position.
*/
memcpy(&pop->event_set[i], &pop->event_set[pop->nfds], sizeof(struct pollfd));
idx = evmap_io_get_fdinfo_(&base->io, pop->event_set[i].fd);
EVUTIL_ASSERT(idx);
EVUTIL_ASSERT(idx->idxplus1 == pop->nfds + 1);
idx->idxplus1 = i + 1;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.