- retval = select(maxfd+1, &rfds, &wfds, &efds, tvp);
- if (retval > 0) {
- fe = eventLoop->fileEventHead;
- while(fe != NULL) {
- int fd = (int) fe->fd;
-
- if ((fe->mask & AE_READABLE && FD_ISSET(fd, &rfds)) ||
- (fe->mask & AE_WRITABLE && FD_ISSET(fd, &wfds)) ||
- (fe->mask & AE_EXCEPTION && FD_ISSET(fd, &efds)))
- {
- int mask = 0;
-
- if (fe->mask & AE_READABLE && FD_ISSET(fd, &rfds))
- mask |= AE_READABLE;
- if (fe->mask & AE_WRITABLE && FD_ISSET(fd, &wfds))
- mask |= AE_WRITABLE;
- if (fe->mask & AE_EXCEPTION && FD_ISSET(fd, &efds))
- mask |= AE_EXCEPTION;
- fe->fileProc(eventLoop, fe->fd, fe->clientData, mask);
- processed++;
- /* After an event is processed our file event list
- * may no longer be the same, so what we do
- * is to clear the bit for this file descriptor and
- * restart again from the head. */
- fe = eventLoop->fileEventHead;
- FD_CLR(fd, &rfds);
- FD_CLR(fd, &wfds);
- FD_CLR(fd, &efds);
- } else {
- fe = fe->next;
- }
+ numevents = aeApiPoll(eventLoop, tvp);
+ for (j = 0; j < numevents; j++) {
+ aeFileEvent *fe = &eventLoop->events[eventLoop->fired[j].fd];
+ int mask = eventLoop->fired[j].mask;
+ int fd = eventLoop->fired[j].fd;
+ int rfired = 0;
+
+ /* note the fe->mask & mask & ... code: maybe an already processed
+ * event removed an element that fired and we still didn't
+ * processed, so we check if the event is still valid. */
+ if (fe->mask & mask & AE_READABLE) {
+ rfired = 1;
+ fe->rfileProc(eventLoop,fd,fe->clientData,mask);
+ }
+ if (fe->mask & mask & AE_WRITABLE) {
+ if (!rfired || fe->wfileProc != fe->rfileProc)
+ fe->wfileProc(eventLoop,fd,fe->clientData,mask);