📄 su_timer.c
字号:
* @param t pointer to the timer object * @param wakeup pointer to the wakeup function * @param arg argument given to the wakeup function * * @return 0 if successful, -1 otherwise. */int su_timer_set(su_timer_t *t, su_timer_f wakeup, su_timer_arg_t *arg){ char const *func = "su_timer_set"; if (t == NULL) return -1; assert(t->sut_duration > 0); if (t->sut_duration == 0) { SU_DEBUG_0(("%s(%p): %s\n", func, t, "timer without default duration")); return -1; } return su_timer_set_interval(t, wakeup, arg, t->sut_duration);}/** Set timer at known time. * * Sets the timer to expire at given time. * * @param t pointer to the timer object * @param wakeup pointer to the wakeup function * @param arg argument given to the wakeup function * @param when time structure defining the wakeup time * * @return 0 if successful, -1 otherwise. */int su_timer_set_at(su_timer_t *t, su_timer_f wakeup, su_wakeup_arg_t *arg, su_time_t when){ char const *func = "su_timer_set_at"; su_timer_t **timers; if (t == NULL) { SU_DEBUG_1(("%s(%p): %s\n", func, t, "NULL argument")); return -1; } timers = su_task_timers(t->sut_task); if (timers == NULL) { SU_DEBUG_1(("%s(%p): %s\n", func, t, "invalid timer")); return -1; } su_timer_set0(timers, t, wakeup, arg, when, 0); return 0;}/** Set the timer for regular intervals. * * Run the given timer continuously, call wakeup function repeately in the * default interval. If a wakeup call is missed, try to make it up (in other * words, this kind of timer fails miserably if time is adjusted and it * should really use /proc/uptime instead of gettimeofday()). * * While a continously running timer is active it @b must @b not @b be @b * set using su_timer_set() or su_timer_set_at(). * * The timer must have an non-zero default interval. * * @param t pointer to the timer object * @param wakeup pointer to the wakeup function * @param arg argument given to the wakeup function * * @return 0 if successful, -1 otherwise. */int su_timer_run(su_timer_t *t, su_timer_f wakeup, su_timer_arg_t *arg){ char const *func = "su_timer_run"; su_timer_t **timers; su_time_t now = su_now(); if (t == NULL) { SU_DEBUG_1(("%s(%p): %s\n", func, t, "NULL argument")); return -1; } assert(t->sut_duration > 0); if (t->sut_duration == 0) { SU_DEBUG_1(("%s(%p): %s\n", func, t, "timer without default duration")); return -1; } timers = su_task_timers(t->sut_task); if (timers == NULL) { SU_DEBUG_1(("%s(%p): %s\n", func, t, "invalid timer")); return -1; } t->sut_running = run_at_intervals; t->sut_run = now; t->sut_woken = 0; su_timer_set0(timers, t, wakeup, arg, now, t->sut_duration); return 0;}/**Set the timer for regular intervals. * * Run the given timer continuously, call wakeup function repeately in the * default interval. While a continously running timer is active it @b must * @b not @b be @b set using su_timer_set() or su_timer_set_at(). Unlike * su_timer_run(), set for ever timer does not try to catchup missed * callbacks. * * The timer must have an non-zero default interval. * * @param t pointer to the timer object * @param wakeup pointer to the wakeup function * @param arg argument given to the wakeup function * * @return 0 if successful, -1 otherwise. */int su_timer_set_for_ever(su_timer_t *t, su_timer_f wakeup, su_timer_arg_t *arg){ char const *func = "su_timer_run"; su_timer_t **timers; su_time_t now = su_now(); if (t == NULL) { SU_DEBUG_1(("%s(%p): %s\n", func, t, "NULL argument")); return -1; } assert(t->sut_duration > 0); if (t->sut_duration == 0) { SU_DEBUG_1(("%s(%p): %s\n", func, t, "timer without default duration")); return -1; } timers = su_task_timers(t->sut_task); if (timers == NULL) { SU_DEBUG_1(("%s(%p): %s\n", func, t, "invalid timer")); return -1; } t->sut_running = run_for_ever; t->sut_run = now; t->sut_woken = 0; su_timer_set0(timers, t, wakeup, arg, now, t->sut_duration); return 0;}/**Reset the timer. * * Resets (stops) the given timer. * * @param t pointer to the timer object * * @return 0 if successful, -1 otherwise. */int su_timer_reset(su_timer_t *t){ char const *func = "su_timer_reset"; su_timer_t **timers; if (t == NULL) { SU_DEBUG_1(("%s(%p): %s\n", func, t, "NULL argument")); return -1; } timers = su_task_timers(t->sut_task); su_timer_reset0(timers, t); return 0;}/** @internal Check for expired timers in queue. * * The function su_timer_expire() checks a timer queue and executes and * removes expired timers from the queue. It also calculates the time when * the next timer expires. * * @param timers pointer to the timer queue * @param timeout timeout in milliseconds [IN/OUT] * @param now current timestamp * * @return * The number of expired timers. */int su_timer_expire(su_timer_t ** const timers, su_duration_t *timeout, su_time_t now){ su_timer_t *t; su_timer_f f; int n = 0; if (!*timers) return n; for (;;) { t = timers_first(*timers); if (t == NULL || SU_TIME_CMP(t->sut_when, now) > 0) break; timers_remove(timers, t); f = t->sut_wakeup; t->sut_wakeup = NULL; assert(f); if (t->sut_running == run_at_intervals) { while (t->sut_running == run_at_intervals && t->sut_duration > 0) { if (su_time_diff(t->sut_when, now) > 0) { su_timer_set0(timers, t, f, t->sut_arg, t->sut_run, 0); break; } t->sut_when = t->sut_run = su_time_add(t->sut_run, t->sut_duration); t->sut_woken++; f(su_root_magic(su_task_root(t->sut_task)), t, t->sut_arg), n++; } } else if (t->sut_running == run_for_ever) { t->sut_woken++; t->sut_when = now; f(su_root_magic(su_task_root(t->sut_task)), t, t->sut_arg), n++; if (t->sut_running == run_for_ever) su_timer_set0(timers, t, f, t->sut_arg, now, t->sut_duration); } else { t->sut_when = now; f(su_root_magic(su_task_root(t->sut_task)), t, t->sut_arg); n++; } } if (t) { su_duration_t at = su_duration(t->sut_when, now); if (at < *timeout) *timeout = at; } return n;}su_duration_t su_timer_next_expires(su_timer_t const * t, su_time_t now){ su_duration_t tout; if (!t) return SU_DURATION_MAX; tout = su_duration(t->sut_when, now); return tout > 0 ? tout : 0 ;}/** * Resets and frees all timers belonging to a task. * * The function su_timer_destroy_all() resets and frees all timers belonging * to the specified task in the queue. * * @param timers pointer to the timers * @param task task owning the timers * * @return Number of timers reset. */int su_timer_reset_all(su_timer_t **timers, su_task_r task){ su_timer_t *t, *t_next; int n = 0; if (!timers || !*timers) return 0; for (t = timers_first(*timers); t; t = t_next) { t_next = timers_succ(t); if (su_task_cmp(task, t->sut_task)) continue; n++; timers_remove(timers, t); su_free(NULL, t); } return n;}/** Get the root object owning the timer. * * The function su_timer_root() return pointer to the root object owning the * timer. * * @param t pointer to the timer * * @return Pointer to the root object owning the timer. */su_root_t *su_timer_root(su_timer_t const *t){ return su_task_root(t->sut_task);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -