diff options
Diffstat (limited to 'cras/src/server/cras_tm.c')
-rw-r--r-- | cras/src/server/cras_tm.c | 149 |
1 files changed, 0 insertions, 149 deletions
diff --git a/cras/src/server/cras_tm.c b/cras/src/server/cras_tm.c deleted file mode 100644 index c215fdc0..00000000 --- a/cras/src/server/cras_tm.c +++ /dev/null @@ -1,149 +0,0 @@ -/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "cras_types.h" -#include "cras_util.h" -#include "utlist.h" - -#include <time.h> - -/* Represents an armed timer. - * Members: - * ts - timespec at which the timer should fire. - * cb - Callback to call when the timer expires. - * cb_data - Data passed to the callback. - */ -struct cras_timer { - struct timespec ts; - void (*cb)(struct cras_timer *t, void *data); - void *cb_data; - struct cras_timer *next, *prev; -}; - -/* Timer Manager, keeps a list of active timers. */ -struct cras_tm { - struct cras_timer *timers; -}; - -/* Local Functions. */ - -/* Adds ms milliseconds to ts. */ -static inline void add_ms_ts(struct timespec *ts, unsigned int ms) -{ - if (ms >= 1000) { - ts->tv_sec += ms / 1000; - ms %= 1000; - } - ts->tv_nsec += ms * 1000000L; - if (ts->tv_nsec >= 1000000000L) { - ts->tv_sec += ts->tv_nsec / 1000000000L; - ts->tv_nsec %= 1000000000L; - } -} - -/* Checks if timespec a is less than b. */ -static inline int timespec_sooner(const struct timespec *a, - const struct timespec *b) -{ - return (a->tv_sec < b->tv_sec || - (a->tv_sec == b->tv_sec && a->tv_nsec <= b->tv_nsec)); -} - -/* Exported Interface. */ - -struct cras_timer *cras_tm_create_timer(struct cras_tm *tm, unsigned int ms, - void (*cb)(struct cras_timer *t, - void *data), - void *cb_data) -{ - struct cras_timer *t; - - t = calloc(1, sizeof(*t)); - if (!t) - return NULL; - - t->cb = cb; - t->cb_data = cb_data; - - clock_gettime(CLOCK_MONOTONIC_RAW, &t->ts); - add_ms_ts(&t->ts, ms); - - DL_APPEND(tm->timers, t); - - return t; -} - -void cras_tm_cancel_timer(struct cras_tm *tm, struct cras_timer *t) -{ - DL_DELETE(tm->timers, t); - free(t); -} - -struct cras_tm *cras_tm_init() -{ - return calloc(1, sizeof(struct cras_tm)); -} - -void cras_tm_deinit(struct cras_tm *tm) -{ - struct cras_timer *t; - - DL_FOREACH (tm->timers, t) { - DL_DELETE(tm->timers, t); - free(t); - } - free(tm); -} - -int cras_tm_get_next_timeout(const struct cras_tm *tm, struct timespec *ts) -{ - struct cras_timer *t; - struct timespec now; - struct timespec *min; - - if (!tm->timers) - return 0; - - min = &tm->timers->ts; - DL_FOREACH (tm->timers, t) - if (timespec_sooner(&t->ts, min)) - min = &t->ts; - - clock_gettime(CLOCK_MONOTONIC_RAW, &now); - - if (timespec_sooner(min, &now)) { - /* Timer already expired. */ - ts->tv_sec = ts->tv_nsec = 0; - return 1; - } - - subtract_timespecs(min, &now, ts); - return 1; -} - -void cras_tm_call_callbacks(struct cras_tm *tm) -{ - struct timespec now; - struct cras_timer *t, *next; - - clock_gettime(CLOCK_MONOTONIC_RAW, &now); - - /* Don't use DL_FOREACH to iterate timers because in each loop the - * next timer pointer is stored for later access but it could be - * cancelled and freed in current timer's callback causing invalid - * memory access. */ - t = tm->timers; - while (t) { - next = t->next; - if (timespec_sooner(&t->ts, &now)) { - t->cb(t, t->cb_data); - /* Update next timer because it could have been modified - * in t->cb(). */ - next = t->next; - cras_tm_cancel_timer(tm, t); - } - t = next; - } -} |