/* Process every pending time event, then every pending file event (that may be registered by time event callbacks just processed). Without special flags the function sleeps until some file event fires, or when the next time event occurs (if any). If flag is 0, the function does nothing and returns. if flag has AE_ALL_EVENTS set, all the kind of events are processed. if flag has AE_FILE_EVENTS set, file events are processed. if flag has AE_TIME_EVENTS set, time events are processed. if flag has AE_DONT_WAIT set, the function returns ASAP (As soon as possible) until all the events that's possible to process without to wait are processed. The function returns the number of events processed. */ int ae_process_events(ae_event_loop *el, int flags) { int processed = 0, numevents; /* Nothing to do ? return ASAP */ if (!(flags & AE_TIME_EVENTS) && !(flags & AE_FILE_EVENTS)) { return 0; } /* Note that we want call select() even if there are no file events to process as long as we want to process time events, in order to sleep until the next time event is ready to fire. */ if (el->maxfd != -1 || ((flags & AE_TIME_EVENTS) && !(flags & AE_DONT_WAIT))) { int j; ae_time_event *shortest = NULL; struct timeval tv, *tvp; if (flags & AE_TIME_EVENTS && !(flags & AE_DONT_WAIT)) { shortest = ae_search_nearest_timer(el); } if (shortest) { long now_sec, now_ms; /* Calculate the time missing for the nearest timer to fire. */ ae_get_time(&now_sec, &now_ms); tvp = &tv; tvp->tv_sec = shortest->when_sec - now_sec; if (shortest->when_ms < now_ms) { tvp->tv_usec = ((shortest->when_ms + 1000) - now_ms) * 1000; --tvp->tv_sec; } else { tvp->tv_usec = (shortest->when_ms - now_ms) * 1000; } if (tvp->tv_sec < 0) { tvp->tv_sec = 0; } if (tvp->tv_usec < 0) { tvp->tv_usec = 0; } } else { /* If we have to check for events but need to return ASAP because of AE_DONT_WAIT we need to set the timeout to zero. */ if (flags & AE_DONT_WAIT) { tv.tv_sec = tv.tv_usec = 0; tvp = &tv; } else { /* Otherwise we can block. */ tvp = NULL; /* wait forever */ } } numevents = ae_api_poll(el, tvp); for (j = 0; j < numevents; ++j) { ae_file_event *fe = &el->events[el->fired[j].fd]; int mask = el->fired[j].mask; int fd = el->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 events is still valid. */ if (fe->mask & mask & AE_READABLE) { rfired = 1; fe->r_file_proc(el, fd, fe->client_data, mask); } if (fe->mask & mask & AE_WRITABLE) { if (!rfired || fe->w_file_proc != fe->r_file_proc) { fe->w_file_proc(el, fd, fe->client_data, mask); } } ++processed; } } /* Check time events */ if (flags & AE_TIME_EVENTS) { processed += process_time_events(el); } /* Return the number of processed file/time events */ return processed; }
int ae_process_events(ae_event_loop * ev_loop, int flags) { int processed = 0, numevents = 0; struct timeval * tvp = NULL; if (!(flags & AE_TIME_EVENTS) && !(flags & AE_FILE_EVENTS)) return 0; // There is some fd registered if (ev_loop->maxfd != -1 || ((flags & AE_TIME_EVENTS) && (flags & AE_DONT_WAIT))) { int j; ae_time_event * shortest = NULL; struct timeval tv, *tvp = NULL; if (flags & AE_TIME_EVENTS && !(flags & AE_DONT_WAIT)) shortest = ae_search_nearest_timer(ev_loop); if (shortest) { long now_sec, now_ms; ae_get_time(&now_sec, &now_ms); tvp = &tv; tvp->tv_sec = shortest->when_sec - now_sec; if (shortest->when_ms < now_ms) { tvp->tv_usec = ((shortest->when_ms+1000) - now_ms)*1000; tvp->tv_sec --; } else { tvp->tv_usec = (shortest->when_ms - now_ms)*1000; } if (tvp->tv_sec < 0) tvp->tv_sec = 0; if (tvp->tv_usec < 0) tvp->tv_usec = 0; } else { if (flags & AE_DONT_WAIT) { tv.tv_sec = tv.tv_usec = 0; tvp = &tv; } else { tvp = NULL; } } numevents = ae_api_poll(ev_loop, tvp); for (j = 0; j < numevents; j++) { // Registered event ae_file_event * fe = &ev_loop->events[ev_loop->fired[j].fd]; // Fired event int mask = ev_loop->fired[j].mask; int fd = ev_loop->fired[j].fd; int rfired = 0; if (fe != NULL && (fe->mask & mask & AE_READABLE)) { rfired = 1; fe->r_file_func(ev_loop, fd, fe->client_data, mask); } if (fe != NULL && (fe->mask & mask & AE_WRITABLE)) { if (!rfired || fe->w_file_func != fe->r_file_func) fe->w_file_func(ev_loop, fd, fe->client_data, mask); } processed++; } } if (flags & AE_TIME_EVENTS) processed += process_time_event(ev_loop); return processed; }