io/m_event_timer.c
/* NOTE: event handle must be locked when this function is called */
event handle must be locked when this function is called
event handle must be locked when this function is called
void M_event_timer_process(M_event_t *event)
{
	M_event_timer_t   *timer;
	M_event_timer_t   *last_timer = NULL;
	M_timeval_t        curr;
	size_t             cnt = 0;
	M_time_elapsed_start(&curr);
	while ((timer = M_queue_first(event->u.loop.timers)) != NULL && timer != last_timer && timer->started && M_time_timeval_diff(&timer->next_run, &curr) >= 0) {
		last_timer = timer;
		M_event_timer_dequeue(timer);
		if (M_event_timer_tvset(&timer->end_tv)) {
			M_timeval_t tv;
			M_time_gettimeofday(&tv);
			if (M_time_timeval_diff(&tv, &timer->end_tv) <= 0) {
				timer->started = M_FALSE;
			}
		}
		if (timer->started) {
			timer->cnt++;
			timer->executing = M_TRUE;
			M_event_unlock(event);
			timer->callback(event, M_EVENT_TYPE_OTHER, NULL, timer->cb_data);
			M_event_lock(event);
			timer->executing = M_FALSE;
			if (timer->callback_next != NULL) {
				timer->callback      = timer->callback_next;
				timer->cb_data       = timer->cb_data_next;
				timer->callback_next = NULL;
				timer->cb_data_next  = NULL;
			}
			cnt++;
		}
		if (timer->fire_cnt != 0 && timer->cnt >= timer->fire_cnt) {
			timer->started = M_FALSE;
		}
		if (!timer->started && timer->autodestroy) {
			M_free(timer);
			continue;
		}
		if (timer->delay_destroy) {
			M_free(timer);
			continue;
		}
		M_time_elapsed_start(&timer->last_run);
		if (timer->started)
			M_event_timer_schedule(timer);
		M_event_timer_enqueue(timer);
		M_time_elapsed_start(&curr);
	}
	event->u.loop.timer_cnt += cnt;
}
void M_event_timer_process ( M_event_t * event ) { M_event_timer_t * timer ; M_event_timer_t * last_timer = NULL ; M_timeval_t curr ; size_t cnt = 0 ; M_time_elapsed_start ( & curr ) ; while ( ( timer = M_queue_first ( event -> u . loop . timers ) ) != NULL && timer != last_timer && timer -> started && M_time_timeval_diff ( & timer -> next_run , & curr ) >= 0 ) { last_timer = timer ; M_event_timer_dequeue ( timer ) ; if ( M_event_timer_tvset ( & timer -> end_tv ) ) { M_timeval_t tv ; M_time_gettimeofday ( & tv ) ; if ( M_time_timeval_diff ( & tv , & timer -> end_tv ) <= 0 ) { timer -> started = M_FALSE ; } } if ( timer -> started ) { timer -> cnt ++ ; timer -> executing = M_TRUE ; M_event_unlock ( event ) ; timer -> callback ( event , M_EVENT_TYPE_OTHER , NULL , timer -> cb_data ) ; M_event_lock ( event ) ; timer -> executing = M_FALSE ; if ( timer -> callback_next != NULL ) { timer -> callback = timer -> callback_next ; timer -> cb_data = timer -> cb_data_next ; timer -> callback_next = NULL ; timer -> cb_data_next = NULL ; } cnt ++ ; } if ( timer -> fire_cnt != 0 && timer -> cnt >= timer -> fire_cnt ) { timer -> started = M_FALSE ; } if ( ! timer -> started && timer -> autodestroy ) { M_free ( timer ) ; continue ; } if ( timer -> delay_destroy ) { M_free ( timer ) ; continue ; } M_time_elapsed_start ( & timer -> last_run ) ; if ( timer -> started ) M_event_timer_schedule ( timer ) ; M_event_timer_enqueue ( timer ) ; M_time_elapsed_start ( & curr ) ; } event -> u . loop . timer_cnt += cnt ; }
NOTE: event handle must be locked when this function is called
NOTE : event handle must be locked when this function is called
/* Iterate across timers until either we run out or hit one that isn't yet triggered */ //M_printf("%s(): processing timer %p\n", __FUNCTION__, timer); fflush(stdout); /* We always dequeue the timer from the list as we may add it back in if it is to be rescheduled */ /* See if timer expired, if so mark it as such */ /* Trigger callback */ /* Unlock event lock since the callback may take some time */ /* Relock to possibly re-queue or loop */ /* If we have callback changes pending go ahead and
			 * change them. The only time they'll be pending is
			 * if they were set while executing was true. Basically,
			 * when the callback and data was being used. */ /* Determine if timer should be stopped */ //M_printf("%s(): stopping timer %p-- max fire count\n", __FUNCTION__, timer); fflush(stdout); /* If autodestroy and timer went to stopped mode, kill it */ /* If self-deleted during the callback, cleanup now */ /* Record the last run, that way it can't re-insert itself in front of other
		 * tasks ready to run immediately, thus starving them */ /* Reschedule */ /* re-enqueue */ /* Pull current time as we do not know how long this iteration took */ //M_printf("%s(): delivered %zu events\n", __FUNCTION__, cnt);