evport: Remove a linear search over recent events when reactivating them

This commit is contained in:
Nick Mathewson 2011-05-27 14:15:32 -04:00
parent 4687ce4f80
commit 0f77efef8b

View File

@ -86,7 +86,12 @@
*/ */
struct fd_info { struct fd_info {
short fdi_what; /* combinations of EV_READ and EV_WRITE */ /* combinations of EV_READ and EV_WRITE */
short fdi_what;
/* Index of this fd within ed_pending, plus 1. Zero if this fd is
* not in ed_pending. (The +1 is a hack so that memset(0) will set
* it to a nil index. */
int pending_idx_plus_1;
}; };
#define FDI_HAS_READ(fdi) ((fdi)->fdi_what & EV_READ) #define FDI_HAS_READ(fdi) ((fdi)->fdi_what & EV_READ)
@ -250,6 +255,7 @@ evport_dispatch(struct event_base *base, struct timeval *tv)
if (fdi != NULL && FDI_HAS_EVENTS(fdi)) { if (fdi != NULL && FDI_HAS_EVENTS(fdi)) {
reassociate(epdp, fdi, fd); reassociate(epdp, fdi, fd);
epdp->ed_pending[i] = -1; epdp->ed_pending[i] = -1;
fdi->pending_idx_plus_1 = 0;
} }
} }
@ -277,10 +283,12 @@ evport_dispatch(struct event_base *base, struct timeval *tv)
for (i = 0; i < nevents; ++i) { for (i = 0; i < nevents; ++i) {
port_event_t *pevt = &pevtlist[i]; port_event_t *pevt = &pevtlist[i];
int fd = (int) pevt->portev_object; int fd = (int) pevt->portev_object;
struct fd_info *fdi = evmap_io_get_fdinfo(&base->io, fd);
check_evportop(epdp); check_evportop(epdp);
check_event(pevt); check_event(pevt);
epdp->ed_pending[i] = fd; epdp->ed_pending[i] = fd;
fdi->pending_idx_plus_1 = i + 1;
/* /*
* Figure out what kind of event it was * Figure out what kind of event it was
@ -338,18 +346,10 @@ evport_del(struct event_base *base, int fd, short old, short events, void *p)
{ {
struct evport_data *evpd = base->evbase; struct evport_data *evpd = base->evbase;
struct fd_info *fdi = p; struct fd_info *fdi = p;
int i; int associated = ! fdi->pending_idx_plus_1;
int associated = 1;
check_evportop(evpd); check_evportop(evpd);
for (i = 0; i < EVENTS_PER_GETN; ++i) {
if (evpd->ed_pending[i] == fd) {
associated = 0;
break;
}
}
fdi->fdi_what &= ~(events &(EV_READ|EV_WRITE)); fdi->fdi_what &= ~(events &(EV_READ|EV_WRITE));
if (associated) { if (associated) {
@ -370,7 +370,10 @@ evport_del(struct event_base *base, int fd, short old, short events, void *p)
} }
} else { } else {
if ((fdi->fdi_what & (EV_READ|EV_WRITE)) == 0) { if ((fdi->fdi_what & (EV_READ|EV_WRITE)) == 0) {
const int i = fdi->pending_idx_plus_1 - 1;
EVUTIL_ASSERT(evpd->ed_pending[i] == fd);
evpd->ed_pending[i] = -1; evpd->ed_pending[i] = -1;
fdi->pending_idx_plus_1 = 0;
} }
} }
return 0; return 0;