loop_timerlist.c | loop_timerlist.c | |||
---|---|---|---|---|
skipping to change at line 49 | skipping to change at line 49 | |||
uint32_t install_pos; | uint32_t install_pos; | |||
}; | }; | |||
struct qb_timer_source { | struct qb_timer_source { | |||
struct qb_loop_source s; | struct qb_loop_source s; | |||
struct timerlist timerlist; | struct timerlist timerlist; | |||
qb_array_t *timers; | qb_array_t *timers; | |||
size_t timer_entry_count; | size_t timer_entry_count; | |||
}; | }; | |||
static void timer_dispatch(struct qb_loop_item * item, | static void | |||
enum qb_loop_priority p) | timer_dispatch(struct qb_loop_item *item, enum qb_loop_priority p) | |||
{ | { | |||
struct qb_loop_timer *timer = (struct qb_loop_timer *)item; | struct qb_loop_timer *timer = (struct qb_loop_timer *)item; | |||
assert(timer->state == QB_POLL_ENTRY_JOBLIST); | assert(timer->state == QB_POLL_ENTRY_JOBLIST); | |||
timer->check = 0; | timer->check = 0; | |||
timer->dispatch_fn(timer->item.user_data); | timer->dispatch_fn(timer->item.user_data); | |||
timer->state = QB_POLL_ENTRY_EMPTY; | timer->state = QB_POLL_ENTRY_EMPTY; | |||
} | } | |||
static int32_t expired_timers; | static int32_t expired_timers; | |||
static void make_job_from_tmo(void *data) | static void | |||
make_job_from_tmo(void *data) | ||||
{ | { | |||
struct qb_loop_timer *t = (struct qb_loop_timer *)data; | struct qb_loop_timer *t = (struct qb_loop_timer *)data; | |||
struct qb_loop *l = t->item.source->l; | struct qb_loop *l = t->item.source->l; | |||
assert(t->state == QB_POLL_ENTRY_ACTIVE); | assert(t->state == QB_POLL_ENTRY_ACTIVE); | |||
qb_loop_level_item_add(&l->level[t->p], &t->item); | qb_loop_level_item_add(&l->level[t->p], &t->item); | |||
t->state = QB_POLL_ENTRY_JOBLIST; | t->state = QB_POLL_ENTRY_JOBLIST; | |||
expired_timers++; | expired_timers++; | |||
} | } | |||
static int32_t expire_the_timers(struct qb_loop_source* s, int32_t ms_timeo | static int32_t | |||
ut) | expire_the_timers(struct qb_loop_source *s, int32_t ms_timeout) | |||
{ | { | |||
struct qb_timer_source *ts = (struct qb_timer_source *)s; | struct qb_timer_source *ts = (struct qb_timer_source *)s; | |||
expired_timers = 0; | expired_timers = 0; | |||
timerlist_expire(&ts->timerlist); | timerlist_expire(&ts->timerlist); | |||
return expired_timers; | return expired_timers; | |||
} | } | |||
int32_t qb_loop_timer_msec_duration_to_expire(struct qb_loop_source *timer_ | int32_t | |||
source) | qb_loop_timer_msec_duration_to_expire(struct qb_loop_source * timer_source) | |||
{ | { | |||
struct qb_timer_source * my_src = (struct qb_timer_source *)timer_so urce; | struct qb_timer_source *my_src = (struct qb_timer_source *)timer_sou rce; | |||
uint64_t left = timerlist_msec_duration_to_expire(&my_src->timerlist ); | uint64_t left = timerlist_msec_duration_to_expire(&my_src->timerlist ); | |||
if (left != -1 && left > 0xFFFFFFFF) { | if (left != -1 && left > 0xFFFFFFFF) { | |||
left = 0xFFFFFFFE; | left = 0xFFFFFFFE; | |||
} | } | |||
return left; | return left; | |||
} | } | |||
struct qb_loop_source* | struct qb_loop_source * | |||
qb_loop_timer_create(struct qb_loop *l) | qb_loop_timer_create(struct qb_loop *l) | |||
{ | { | |||
struct qb_timer_source * my_src = malloc(sizeof(struct qb_timer_sour | struct qb_timer_source *my_src = malloc(sizeof(struct qb_timer_sourc | |||
ce)); | e)); | |||
if (my_src == NULL) { | ||||
return NULL; | ||||
} | ||||
my_src->s.l = l; | my_src->s.l = l; | |||
my_src->s.dispatch_and_take_back = timer_dispatch; | my_src->s.dispatch_and_take_back = timer_dispatch; | |||
my_src->s.poll = expire_the_timers; | my_src->s.poll = expire_the_timers; | |||
timerlist_init(&my_src->timerlist); | timerlist_init(&my_src->timerlist); | |||
my_src->timers = qb_array_create(64, sizeof(struct qb_loop_timer)); | my_src->timers = qb_array_create(64, sizeof(struct qb_loop_timer)); | |||
my_src->timer_entry_count = 0; | my_src->timer_entry_count = 0; | |||
return (struct qb_loop_source*)my_src; | return (struct qb_loop_source *)my_src; | |||
} | } | |||
void qb_loop_timer_destroy(struct qb_loop *l) | void | |||
qb_loop_timer_destroy(struct qb_loop *l) | ||||
{ | { | |||
struct qb_timer_source * my_src = (struct qb_timer_source *)l->timer | struct qb_timer_source *my_src = | |||
_source; | (struct qb_timer_source *)l->timer_source; | |||
qb_array_free(my_src->timers); | qb_array_free(my_src->timers); | |||
free(l->timer_source); | free(l->timer_source); | |||
} | } | |||
static int32_t _timer_from_handle_(struct qb_timer_source *s, | static int32_t | |||
qb_loop_timer_handle handle_in, | _timer_from_handle_(struct qb_timer_source *s, | |||
struct qb_loop_timer **timer_pt) | qb_loop_timer_handle handle_in, | |||
struct qb_loop_timer **timer_pt) | ||||
{ | { | |||
int32_t rc; | int32_t rc; | |||
uint32_t check; | uint32_t check; | |||
uint32_t install_pos; | uint32_t install_pos; | |||
struct qb_loop_timer * timer; | struct qb_loop_timer *timer; | |||
if (handle_in == 0) { | if (handle_in == 0) { | |||
return -EINVAL; | return -EINVAL; | |||
} | } | |||
check = ((uint32_t) (((uint64_t) handle_in) >> 32)); | check = ((uint32_t) (((uint64_t) handle_in) >> 32)); | |||
install_pos = handle_in & 0xffffffff; | install_pos = handle_in & 0xffffffff; | |||
rc = qb_array_index(s->timers, install_pos, (void**)&timer); | rc = qb_array_index(s->timers, install_pos, (void **)&timer); | |||
if (rc != 0) { | if (rc != 0) { | |||
return rc; | return rc; | |||
} | } | |||
if (timer->check != check) { | if (timer->check != check) { | |||
return -EINVAL; | return -EINVAL; | |||
} | } | |||
*timer_pt = timer; | *timer_pt = timer; | |||
return 0; | return 0; | |||
} | } | |||
static int32_t _get_empty_array_position_(struct qb_timer_source * s) | static int32_t | |||
_get_empty_array_position_(struct qb_timer_source *s) | ||||
{ | { | |||
int32_t install_pos; | int32_t install_pos; | |||
int32_t res = 0; | int32_t res = 0; | |||
struct qb_loop_timer *timer; | struct qb_loop_timer *timer; | |||
for (install_pos = 0; | for (install_pos = 0; install_pos < s->timer_entry_count; install_po | |||
install_pos < s->timer_entry_count; install_pos++) { | s++) { | |||
assert(qb_array_index(s->timers, install_pos, (void**)&timer | assert(qb_array_index(s->timers, install_pos, (void **)&time | |||
) == 0); | r) | |||
== 0); | ||||
if (timer->state == QB_POLL_ENTRY_EMPTY) { | if (timer->state == QB_POLL_ENTRY_EMPTY) { | |||
return install_pos; | return install_pos; | |||
} | } | |||
} | } | |||
res = qb_array_grow(s->timers, s->timer_entry_count + 1); | res = qb_array_grow(s->timers, s->timer_entry_count + 1); | |||
if (res != 0) { | if (res != 0) { | |||
return res; | return res; | |||
} | } | |||
s->timer_entry_count++; | s->timer_entry_count++; | |||
install_pos = s->timer_entry_count - 1; | install_pos = s->timer_entry_count - 1; | |||
return install_pos; | return install_pos; | |||
} | } | |||
int32_t qb_loop_timer_add(struct qb_loop *l, | int32_t | |||
enum qb_loop_priority p, | qb_loop_timer_add(struct qb_loop * l, | |||
uint64_t nsec_duration, | enum qb_loop_priority p, | |||
void *data, | uint64_t nsec_duration, | |||
qb_loop_timer_dispatch_fn timer_fn, | void *data, | |||
qb_loop_timer_handle * timer_handle_out) | qb_loop_timer_dispatch_fn timer_fn, | |||
qb_loop_timer_handle * timer_handle_out) | ||||
{ | { | |||
struct qb_loop_timer *t; | struct qb_loop_timer *t; | |||
struct qb_timer_source * my_src; | struct qb_timer_source *my_src; | |||
int32_t i; | int32_t i; | |||
if (l == NULL || timer_fn == NULL) { | if (l == NULL || timer_fn == NULL) { | |||
return -EINVAL; | return -EINVAL; | |||
} | } | |||
my_src = (struct qb_timer_source *)l->timer_source; | my_src = (struct qb_timer_source *)l->timer_source; | |||
if (timer_handle_out == 0) { | if (timer_handle_out == 0) { | |||
return -ENOENT; | return -ENOENT; | |||
} | } | |||
i = _get_empty_array_position_(my_src); | i = _get_empty_array_position_(my_src); | |||
assert(qb_array_index(my_src->timers, i, (void**)&t) >= 0); | assert(qb_array_index(my_src->timers, i, (void **)&t) >= 0); | |||
t->state = QB_POLL_ENTRY_ACTIVE; | t->state = QB_POLL_ENTRY_ACTIVE; | |||
t->install_pos = i; | t->install_pos = i; | |||
t->item.user_data = data; | t->item.user_data = data; | |||
t->item.source = (struct qb_loop_source*)my_src; | t->item.source = (struct qb_loop_source *)my_src; | |||
t->dispatch_fn = timer_fn; | t->dispatch_fn = timer_fn; | |||
t->p = p; | t->p = p; | |||
qb_list_init(&t->item.list); | qb_list_init(&t->item.list); | |||
for (i = 0; i < 200; i++) { | for (i = 0; i < 200; i++) { | |||
t->check = random(); | t->check = random(); | |||
if (t->check != 0 && t->check != 0xffffffff) { | if (t->check != 0 && t->check != 0xffffffff) { | |||
break; | break; | |||
} | } | |||
} | } | |||
*timer_handle_out = (((uint64_t) (t->check)) << 32) | t->install_pos ; | *timer_handle_out = (((uint64_t) (t->check)) << 32) | t->install_pos ; | |||
return timerlist_add_duration(&my_src->timerlist, | return timerlist_add_duration(&my_src->timerlist, | |||
make_job_from_tmo, t, | make_job_from_tmo, t, | |||
nsec_duration, | nsec_duration, &t->timerlist_handle); | |||
&t->timerlist_handle); | ||||
} | } | |||
int32_t qb_loop_timer_del(struct qb_loop *l, qb_loop_timer_handle th) | int32_t | |||
qb_loop_timer_del(struct qb_loop * l, qb_loop_timer_handle th) | ||||
{ | { | |||
struct qb_timer_source * s = (struct qb_timer_source *)l->timer_sour ce; | struct qb_timer_source *s = (struct qb_timer_source *)l->timer_sourc e; | |||
struct qb_loop_timer *t; | struct qb_loop_timer *t; | |||
int32_t res; | int32_t res; | |||
res = _timer_from_handle_(s, th, &t); | res = _timer_from_handle_(s, th, &t); | |||
if (res != 0) { | if (res != 0) { | |||
return res; | return res; | |||
} | } | |||
if (t->state == QB_POLL_ENTRY_DELETED) { | if (t->state == QB_POLL_ENTRY_DELETED) { | |||
qb_util_log(LOG_WARNING, "timer already deleted"); | qb_util_log(LOG_WARNING, "timer already deleted"); | |||
skipping to change at line 235 | skipping to change at line 246 | |||
} | } | |||
if (t->state == QB_POLL_ENTRY_JOBLIST) { | if (t->state == QB_POLL_ENTRY_JOBLIST) { | |||
qb_loop_level_item_del(&l->level[t->p], &t->item); | qb_loop_level_item_del(&l->level[t->p], &t->item); | |||
} | } | |||
timerlist_del(&s->timerlist, t->timerlist_handle); | timerlist_del(&s->timerlist, t->timerlist_handle); | |||
t->state = QB_POLL_ENTRY_EMPTY; | t->state = QB_POLL_ENTRY_EMPTY; | |||
return 0; | return 0; | |||
} | } | |||
uint64_t qb_loop_timer_expire_time_get(struct qb_loop *l, qb_loop_timer_han | uint64_t | |||
dle th) | qb_loop_timer_expire_time_get(struct qb_loop * l, qb_loop_timer_handle th) | |||
{ | { | |||
struct qb_timer_source *s = (struct qb_timer_source *)l->timer_sourc e; | struct qb_timer_source *s = (struct qb_timer_source *)l->timer_sourc e; | |||
struct qb_loop_timer *t; | struct qb_loop_timer *t; | |||
int32_t res; | int32_t res; | |||
res = _timer_from_handle_(s, th, &t); | res = _timer_from_handle_(s, th, &t); | |||
if (res != 0) { | if (res != 0) { | |||
return res; | return 0; | |||
} | } | |||
if (t->state != QB_POLL_ENTRY_ACTIVE) { | if (t->state != QB_POLL_ENTRY_ACTIVE) { | |||
return -EBADF; | return 0; | |||
} | } | |||
return timerlist_expire_time (&s->timerlist, t->timerlist_handle); | return timerlist_expire_time(&s->timerlist, t->timerlist_handle); | |||
} | } | |||
End of changes. 26 change blocks. | ||||
43 lines changed or deleted | 52 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |