Beispiel #1
0
/* 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; 
}
Beispiel #2
0
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;
}