mirror of
https://salsa.debian.org/ha-team/libqb
synced 2026-08-09 22:49:43 +00:00
LOOP: add qb_loop_destroy()
Signed-off-by: Angus Salkeld <asalkeld@redhat.com>
This commit is contained in:
parent
e211caab96
commit
970a4bc6d5
@ -58,6 +58,11 @@ typedef void (*qb_loop_poll_low_fds_event_fn) (int32_t not_enough, int32_t fds_a
|
||||
*/
|
||||
qb_loop_t * qb_loop_create(void);
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void qb_loop_destroy(struct qb_loop * l);
|
||||
|
||||
/**
|
||||
* Stop the main loop.
|
||||
* @param l pointer to the loop instance
|
||||
|
||||
27
lib/loop.c
27
lib/loop.c
@ -25,10 +25,6 @@
|
||||
#include <qb/qbloop.h>
|
||||
#include "loop_int.h"
|
||||
|
||||
static struct qb_loop_source * timer_source;
|
||||
static struct qb_loop_source * job_source;
|
||||
static struct qb_loop_source * fd_source;
|
||||
|
||||
static int32_t qb_loop_run_level(struct qb_loop_level *level)
|
||||
{
|
||||
struct qb_loop_item *job;
|
||||
@ -70,15 +66,22 @@ struct qb_loop * qb_loop_create(void)
|
||||
}
|
||||
|
||||
l->stop_requested = QB_FALSE;
|
||||
qb_list_init(&l->source_head);
|
||||
// install sources
|
||||
timer_source = qb_loop_timer_init(l);
|
||||
job_source = qb_loop_jobs_init(l);
|
||||
fd_source = qb_loop_poll_init(l);
|
||||
l->timer_source = qb_loop_timer_create(l);
|
||||
l->job_source = qb_loop_jobs_create(l);
|
||||
l->fd_source = qb_loop_poll_create(l);
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
void qb_loop_destroy(struct qb_loop * l)
|
||||
{
|
||||
qb_loop_timer_destroy(l);
|
||||
qb_loop_jobs_destroy(l);
|
||||
qb_loop_poll_destroy(l);
|
||||
free(l);
|
||||
}
|
||||
|
||||
void qb_loop_stop(struct qb_loop *l)
|
||||
{
|
||||
l->stop_requested = QB_TRUE;
|
||||
@ -98,16 +101,16 @@ void qb_loop_run(struct qb_loop *l)
|
||||
p_stop--;
|
||||
}
|
||||
|
||||
todo += job_source->poll(job_source, 0);
|
||||
todo += timer_source->poll(timer_source, 0);
|
||||
todo += l->job_source->poll(l->job_source, 0);
|
||||
todo += l->timer_source->poll(l->timer_source, 0);
|
||||
|
||||
if (todo > 0) {
|
||||
ms_timeout = 0;
|
||||
} else {
|
||||
todo = 0;
|
||||
ms_timeout = qb_loop_timer_msec_duration_to_expire(timer_source);
|
||||
ms_timeout = qb_loop_timer_msec_duration_to_expire(l->timer_source);
|
||||
}
|
||||
todo += fd_source->poll(fd_source, ms_timeout);
|
||||
todo += l->fd_source->poll(l->fd_source, ms_timeout);
|
||||
|
||||
for (p = QB_LOOP_HIGH; p >= p_stop; p--) {
|
||||
todo -= qb_loop_run_level(&l->level[p]);
|
||||
|
||||
@ -46,23 +46,31 @@ struct qb_loop_source {
|
||||
void (*dispatch_and_take_back)(struct qb_loop_item *i,
|
||||
enum qb_loop_priority p);
|
||||
int32_t (*poll)(struct qb_loop_source* s, int32_t ms_timeout);
|
||||
struct qb_list_head list;
|
||||
};
|
||||
|
||||
struct qb_loop {
|
||||
struct qb_loop_level level[3];
|
||||
int32_t stop_requested;
|
||||
struct qb_list_head source_head;
|
||||
struct qb_loop_source * timer_source;
|
||||
struct qb_loop_source * job_source;
|
||||
struct qb_loop_source * fd_source;
|
||||
};
|
||||
|
||||
struct qb_loop_source *
|
||||
qb_loop_jobs_init(struct qb_loop *l);
|
||||
qb_loop_jobs_create(struct qb_loop *l);
|
||||
|
||||
struct qb_loop_source*
|
||||
qb_loop_timer_init(struct qb_loop *l);
|
||||
qb_loop_timer_create(struct qb_loop *l);
|
||||
|
||||
struct qb_loop_source*
|
||||
qb_loop_poll_init(struct qb_loop *l);
|
||||
qb_loop_poll_create(struct qb_loop *l);
|
||||
|
||||
void qb_loop_jobs_destroy(struct qb_loop *l);
|
||||
|
||||
void qb_loop_timer_destroy(struct qb_loop *l);
|
||||
|
||||
void qb_loop_poll_destroy(struct qb_loop *l);
|
||||
|
||||
|
||||
int32_t qb_loop_timer_msec_duration_to_expire(struct qb_loop_source *timer_source);
|
||||
|
||||
|
||||
@ -30,9 +30,6 @@ struct qb_loop_job {
|
||||
qb_loop_job_dispatch_fn dispatch_fn;
|
||||
};
|
||||
|
||||
static struct qb_loop_source * my_src;
|
||||
|
||||
|
||||
static void job_dispatch(struct qb_loop_item * item,
|
||||
enum qb_loop_priority p)
|
||||
{
|
||||
@ -61,16 +58,19 @@ static int32_t get_more_jobs(struct qb_loop_source* s, int32_t ms_timeout)
|
||||
}
|
||||
|
||||
struct qb_loop_source *
|
||||
qb_loop_jobs_init(struct qb_loop *l)
|
||||
qb_loop_jobs_create(struct qb_loop *l)
|
||||
{
|
||||
my_src = malloc(sizeof(struct qb_loop_source));
|
||||
my_src->l = l;
|
||||
my_src->dispatch_and_take_back = job_dispatch;
|
||||
my_src->poll = get_more_jobs;
|
||||
struct qb_loop_source *s = malloc(sizeof(struct qb_loop_source));
|
||||
s->l = l;
|
||||
s->dispatch_and_take_back = job_dispatch;
|
||||
s->poll = get_more_jobs;
|
||||
|
||||
qb_list_init(&my_src->list);
|
||||
qb_list_add_tail(&my_src->list, &l->source_head);
|
||||
return my_src;
|
||||
return s;
|
||||
}
|
||||
|
||||
void qb_loop_jobs_destroy(struct qb_loop *l)
|
||||
{
|
||||
free(l->job_source);
|
||||
}
|
||||
|
||||
int32_t qb_loop_job_add(struct qb_loop *l,
|
||||
@ -90,7 +90,7 @@ int32_t qb_loop_job_add(struct qb_loop *l,
|
||||
|
||||
job->dispatch_fn = dispatch_fn;
|
||||
job->item.user_data = data;
|
||||
job->item.source = my_src;
|
||||
job->item.source = l->job_source;
|
||||
|
||||
qb_list_init(&job->item.list);
|
||||
qb_list_add_tail(&job->item.list, &l->level[p].wait_head);
|
||||
|
||||
108
lib/loop_poll.c
108
lib/loop_poll.c
@ -62,8 +62,6 @@ struct qb_poll_source {
|
||||
#endif /* HAVE_EPOLL */
|
||||
};
|
||||
|
||||
static struct qb_poll_source * my_src;
|
||||
|
||||
|
||||
#ifdef HAVE_EPOLL
|
||||
static int32_t poll_to_epoll_event(int32_t event)
|
||||
@ -128,7 +126,7 @@ static void poll_fds_usage_check(struct qb_poll_source *s)
|
||||
}
|
||||
|
||||
for (i = 0; i < s->poll_entry_count; i++) {
|
||||
assert(qb_array_index(my_src->poll_entries, i, (void**)&pe) == 0);
|
||||
assert(qb_array_index(s->poll_entries, i, (void**)&pe) == 0);
|
||||
if (pe->ufd.fd != -1) {
|
||||
socks_used++;
|
||||
}
|
||||
@ -179,7 +177,7 @@ static int32_t poll_and_add_to_jobs(struct qb_loop_source* src, int32_t ms_timeo
|
||||
}
|
||||
|
||||
for (i = 0; i < res; i++) {
|
||||
assert(qb_array_index(my_src->poll_entries, events[i].data.u32, (void**)&pe) == 0);
|
||||
assert(qb_array_index(s->poll_entries, events[i].data.u32, (void**)&pe) == 0);
|
||||
if (pe->ufd.fd == -1) {
|
||||
// empty
|
||||
continue;
|
||||
@ -208,7 +206,7 @@ static int32_t poll_and_add_to_jobs(struct qb_loop_source* src, int32_t ms_timeo
|
||||
poll_fds_usage_check(s);
|
||||
|
||||
for (i = 0; i < s->poll_entry_count; i++) {
|
||||
assert(qb_array_index(my_src->poll_entries, i, (void**)&pe) == 0);
|
||||
assert(qb_array_index(l->fd_source->poll_entries, i, (void**)&pe) == 0);
|
||||
memcpy(&s->ufds[i], &pe->ufd, sizeof(struct pollfd));
|
||||
}
|
||||
|
||||
@ -225,7 +223,7 @@ static int32_t poll_and_add_to_jobs(struct qb_loop_source* src, int32_t ms_timeo
|
||||
// empty
|
||||
continue;
|
||||
}
|
||||
assert(qb_array_index(my_src->poll_entries, i, (void**)&pe) == 0);
|
||||
assert(qb_array_index(l->fd_source->poll_entries, i, (void**)&pe) == 0);
|
||||
if (s->ufds[i].revents == pe->ufd.revents) {
|
||||
// entry already in the job queue.
|
||||
continue;
|
||||
@ -241,35 +239,44 @@ static int32_t poll_and_add_to_jobs(struct qb_loop_source* src, int32_t ms_timeo
|
||||
#endif /* HAVE_EPOLL */
|
||||
|
||||
struct qb_loop_source*
|
||||
qb_loop_poll_init(struct qb_loop *l)
|
||||
qb_loop_poll_create(struct qb_loop *l)
|
||||
{
|
||||
my_src = malloc(sizeof(struct qb_poll_source));
|
||||
my_src->s.l = l;
|
||||
my_src->s.dispatch_and_take_back = poll_dispatch_and_take_back;
|
||||
my_src->s.poll = poll_and_add_to_jobs;
|
||||
struct qb_poll_source *s = malloc(sizeof(struct qb_poll_source));
|
||||
s->s.l = l;
|
||||
s->s.dispatch_and_take_back = poll_dispatch_and_take_back;
|
||||
s->s.poll = poll_and_add_to_jobs;
|
||||
|
||||
my_src->poll_entries = qb_array_create(128, sizeof(struct qb_poll_entry));
|
||||
my_src->poll_entry_count = 0;
|
||||
my_src->low_fds_event_fn = NULL;
|
||||
my_src->not_enough_fds = 0;
|
||||
s->poll_entries = qb_array_create(128, sizeof(struct qb_poll_entry));
|
||||
s->poll_entry_count = 0;
|
||||
s->low_fds_event_fn = NULL;
|
||||
s->not_enough_fds = 0;
|
||||
|
||||
#ifdef HAVE_EPOLL
|
||||
my_src->epollfd = epoll_create1(EPOLL_CLOEXEC);
|
||||
my_src->events = 0;
|
||||
s->epollfd = epoll_create1(EPOLL_CLOEXEC);
|
||||
s->events = 0;
|
||||
#else
|
||||
my_src->ufds = 0;
|
||||
s->ufds = 0;
|
||||
#endif /* HAVE_EPOLL */
|
||||
|
||||
qb_list_init(&my_src->s.list);
|
||||
qb_list_add_tail(&my_src->s.list, &l->source_head);
|
||||
return (struct qb_loop_source*)my_src;
|
||||
return (struct qb_loop_source*)s;
|
||||
}
|
||||
|
||||
void qb_loop_poll_destroy(struct qb_loop *l)
|
||||
{
|
||||
struct qb_poll_source * s = (struct qb_poll_source *)l->fd_source;
|
||||
qb_array_free(s->poll_entries);
|
||||
#ifdef HAVE_EPOLL
|
||||
close(s->epollfd);
|
||||
#endif /* HAVE_EPOLL */
|
||||
free(s);
|
||||
}
|
||||
|
||||
int32_t qb_loop_poll_low_fds_event_set(
|
||||
qb_loop_t *l,
|
||||
qb_loop_poll_low_fds_event_fn fn)
|
||||
{
|
||||
my_src->low_fds_event_fn = fn;
|
||||
struct qb_poll_source * s = (struct qb_poll_source *)l->fd_source;
|
||||
s->low_fds_event_fn = fn;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -292,10 +299,11 @@ int32_t qb_loop_poll_add(struct qb_loop *l,
|
||||
#else
|
||||
struct pollfd *ufds;
|
||||
#endif /* HAVE_EPOLL */
|
||||
struct qb_poll_source * s = (struct qb_poll_source *)l->fd_source;
|
||||
|
||||
for (found = 0, install_pos = 0;
|
||||
install_pos < my_src->poll_entry_count; install_pos++) {
|
||||
assert(qb_array_index(my_src->poll_entries, install_pos, (void**)&pe) == 0);
|
||||
install_pos < s->poll_entry_count; install_pos++) {
|
||||
assert(qb_array_index(s->poll_entries, install_pos, (void**)&pe) == 0);
|
||||
if (pe->ufd.fd == -1) {
|
||||
found = 1;
|
||||
break;
|
||||
@ -306,50 +314,50 @@ int32_t qb_loop_poll_add(struct qb_loop *l,
|
||||
/*
|
||||
* Grow pollfd list
|
||||
*/
|
||||
res = qb_array_grow(my_src->poll_entries,
|
||||
my_src->poll_entry_count + 1);
|
||||
res = qb_array_grow(s->poll_entries,
|
||||
s->poll_entry_count + 1);
|
||||
if (res != 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef HAVE_EPOLL
|
||||
new_size = (my_src->poll_entry_count+ 1) * sizeof(struct epoll_event);
|
||||
ev = realloc(my_src->events, new_size);
|
||||
new_size = (s->poll_entry_count+ 1) * sizeof(struct epoll_event);
|
||||
ev = realloc(s->events, new_size);
|
||||
if (ev == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
my_src->events = ev;
|
||||
s->events = ev;
|
||||
#else
|
||||
new_size = (my_src->poll_entry_count+ 1) * sizeof(struct pollfd);
|
||||
ufds = realloc(my_src->ufds, new_size);
|
||||
new_size = (s->poll_entry_count+ 1) * sizeof(struct pollfd);
|
||||
ufds = realloc(s->ufds, new_size);
|
||||
if (ufds == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
my_src->ufds = ufds;
|
||||
s->ufds = ufds;
|
||||
#endif /* HAVE_EPOLL */
|
||||
|
||||
my_src->poll_entry_count += 1;
|
||||
install_pos = my_src->poll_entry_count - 1;
|
||||
s->poll_entry_count += 1;
|
||||
install_pos = s->poll_entry_count - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Install new dispatch handler
|
||||
*/
|
||||
assert(qb_array_index(my_src->poll_entries, install_pos, (void**)&pe) == 0);
|
||||
assert(qb_array_index(s->poll_entries, install_pos, (void**)&pe) == 0);
|
||||
pe->install_pos = install_pos;
|
||||
pe->ufd.fd = fd;
|
||||
pe->ufd.events = events;
|
||||
pe->ufd.revents = 0;
|
||||
pe->dispatch_fn = dispatch_fn;
|
||||
pe->item.user_data = data;
|
||||
pe->item.source = (struct qb_loop_source*)my_src;
|
||||
pe->item.source = (struct qb_loop_source*)l->fd_source;
|
||||
pe->p = p;
|
||||
#ifdef HAVE_EPOLL
|
||||
ev = &my_src->events[install_pos];
|
||||
ev = &s->events[install_pos];
|
||||
ev->events = poll_to_epoll_event(events);
|
||||
ev->data.u64 = 0; /* valgrind */
|
||||
ev->data.u32 = install_pos;
|
||||
if (epoll_ctl(my_src->epollfd, EPOLL_CTL_ADD, fd, ev) == -1) {
|
||||
if (epoll_ctl(s->epollfd, EPOLL_CTL_ADD, fd, ev) == -1) {
|
||||
res = -errno;
|
||||
qb_util_log(LOG_ERR, "epoll_ctl(add) : %s", strerror(-res));
|
||||
}
|
||||
@ -368,12 +376,13 @@ int32_t qb_loop_poll_mod(struct qb_loop *l,
|
||||
int32_t i;
|
||||
int32_t res = 0;
|
||||
struct qb_poll_entry *pe;
|
||||
struct qb_poll_source * s = (struct qb_poll_source *)l->fd_source;
|
||||
|
||||
/*
|
||||
* Find file descriptor to modify events and dispatch function
|
||||
*/
|
||||
for (i = 0; i < my_src->poll_entry_count; i++) {
|
||||
assert(qb_array_index(my_src->poll_entries, i, (void**)&pe) == 0);
|
||||
for (i = 0; i < s->poll_entry_count; i++) {
|
||||
assert(qb_array_index(s->poll_entries, i, (void**)&pe) == 0);
|
||||
if (pe->ufd.fd != fd) {
|
||||
continue;
|
||||
}
|
||||
@ -382,9 +391,9 @@ int32_t qb_loop_poll_mod(struct qb_loop *l,
|
||||
pe->p = p;
|
||||
if (pe->ufd.events != events) {
|
||||
#ifdef HAVE_EPOLL
|
||||
my_src->events[i].events = poll_to_epoll_event(events);
|
||||
my_src->events[i].data.u32 = i;
|
||||
if (epoll_ctl(my_src->epollfd, EPOLL_CTL_MOD, fd, &my_src->events[i]) == -1) {
|
||||
s->events[i].events = poll_to_epoll_event(events);
|
||||
s->events[i].data.u32 = i;
|
||||
if (epoll_ctl(s->epollfd, EPOLL_CTL_MOD, fd, &s->events[i]) == -1) {
|
||||
res = -errno;
|
||||
qb_util_log(LOG_ERR, "epoll_ctl(mod) : %s", strerror(-res));
|
||||
}
|
||||
@ -402,12 +411,13 @@ int32_t qb_loop_poll_del(struct qb_loop *l, int32_t fd)
|
||||
int32_t i;
|
||||
int32_t res = 0;
|
||||
struct qb_poll_entry *pe;
|
||||
struct qb_poll_source * s = (struct qb_poll_source *)l->fd_source;
|
||||
|
||||
/*
|
||||
* Find file descriptor to modify events and dispatch function
|
||||
*/
|
||||
for (i = 0; i < my_src->poll_entry_count; i++) {
|
||||
assert(qb_array_index(my_src->poll_entries, i, (void**)&pe) == 0);
|
||||
for (i = 0; i < s->poll_entry_count; i++) {
|
||||
assert(qb_array_index(s->poll_entries, i, (void**)&pe) == 0);
|
||||
if (pe->ufd.fd != fd) {
|
||||
continue;
|
||||
}
|
||||
@ -415,15 +425,15 @@ int32_t qb_loop_poll_del(struct qb_loop *l, int32_t fd)
|
||||
pe->ufd.events = 0;
|
||||
pe->ufd.revents = 0;
|
||||
#ifdef HAVE_EPOLL
|
||||
if (epoll_ctl(my_src->epollfd, EPOLL_CTL_DEL, fd, NULL) == -1) {
|
||||
if (epoll_ctl(s->epollfd, EPOLL_CTL_DEL, fd, NULL) == -1) {
|
||||
res = -errno;
|
||||
qb_util_log(LOG_ERR, "epoll_ctl(del) : %s",
|
||||
strerror(-res));
|
||||
}
|
||||
#else
|
||||
my_src->ufds[i].fd = -1;
|
||||
my_src->ufds[i].events = 0;
|
||||
my_src->ufds[i].revents = 0;
|
||||
s->ufds[i].fd = -1;
|
||||
s->ufds[i].events = 0;
|
||||
s->ufds[i].revents = 0;
|
||||
#endif /* HAVE_EPOLL */
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -38,8 +38,6 @@ struct qb_timer_source {
|
||||
struct timerlist timerlist;
|
||||
};
|
||||
|
||||
static struct qb_timer_source * my_src;
|
||||
|
||||
static void timer_dispatch(struct qb_loop_item * item,
|
||||
enum qb_loop_priority p)
|
||||
{
|
||||
@ -69,6 +67,7 @@ static int32_t expire_the_timers(struct qb_loop_source* s, int32_t ms_timeout)
|
||||
|
||||
int32_t qb_loop_timer_msec_duration_to_expire(struct qb_loop_source *timer_source)
|
||||
{
|
||||
struct qb_timer_source * my_src = (struct qb_timer_source *)timer_source;
|
||||
uint64_t left = timerlist_msec_duration_to_expire(&my_src->timerlist);
|
||||
if (left != -1 && left > 0xFFFFFFFF) {
|
||||
left = 0xFFFFFFFE;
|
||||
@ -77,21 +76,24 @@ int32_t qb_loop_timer_msec_duration_to_expire(struct qb_loop_source *timer_sourc
|
||||
}
|
||||
|
||||
struct qb_loop_source*
|
||||
qb_loop_timer_init(struct qb_loop *l)
|
||||
qb_loop_timer_create(struct qb_loop *l)
|
||||
{
|
||||
my_src = malloc(sizeof(struct qb_timer_source));
|
||||
struct qb_timer_source * my_src = malloc(sizeof(struct qb_timer_source));
|
||||
my_src->s.l = l;
|
||||
my_src->s.dispatch_and_take_back = timer_dispatch;
|
||||
my_src->s.poll = expire_the_timers;
|
||||
|
||||
qb_list_init(&my_src->s.list);
|
||||
qb_list_add_tail(&my_src->s.list, &l->source_head);
|
||||
|
||||
timerlist_init(&my_src->timerlist);
|
||||
|
||||
return (struct qb_loop_source*)my_src;
|
||||
}
|
||||
|
||||
|
||||
void qb_loop_timer_destroy(struct qb_loop *l)
|
||||
{
|
||||
free(l->timer_source);
|
||||
}
|
||||
|
||||
int32_t qb_loop_timer_add(struct qb_loop *l,
|
||||
enum qb_loop_priority p,
|
||||
int32_t msec_duration,
|
||||
@ -100,7 +102,12 @@ int32_t qb_loop_timer_add(struct qb_loop *l,
|
||||
qb_loop_timer_handle * timer_handle_out)
|
||||
{
|
||||
struct qb_loop_timer *t;
|
||||
struct qb_timer_source * my_src;
|
||||
|
||||
if (l == NULL || timer_fn == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
my_src = (struct qb_timer_source *)l->timer_source;
|
||||
if (timer_handle_out == NULL) {
|
||||
return -ENOENT;
|
||||
}
|
||||
@ -119,6 +126,7 @@ int32_t qb_loop_timer_add(struct qb_loop *l,
|
||||
|
||||
int32_t qb_loop_timer_del(struct qb_loop *l, qb_loop_timer_handle th)
|
||||
{
|
||||
struct qb_timer_source * my_src = (struct qb_timer_source *)l->timer_source;
|
||||
if (th == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -129,6 +137,7 @@ int32_t qb_loop_timer_del(struct qb_loop *l, qb_loop_timer_handle th)
|
||||
|
||||
uint64_t qb_loop_timer_expire_time_get(struct qb_loop *l, qb_loop_timer_handle th)
|
||||
{
|
||||
struct qb_timer_source * my_src = (struct qb_timer_source *)l->timer_source;
|
||||
if (th == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ START_TEST(test_loop_job_input)
|
||||
ck_assert_int_eq(res, -EINVAL);
|
||||
res = qb_loop_job_add(l, QB_LOOP_LOW, NULL, NULL);
|
||||
ck_assert_int_eq(res, -EINVAL);
|
||||
|
||||
qb_loop_destroy(l);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
@ -116,6 +116,7 @@ START_TEST(test_loop_job_1)
|
||||
|
||||
qb_loop_run(l);
|
||||
ck_assert_int_eq(job_1_run_count, 1);
|
||||
qb_loop_destroy(l);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
@ -132,6 +133,7 @@ START_TEST(test_loop_job_4)
|
||||
ck_assert_int_eq(job_1_run_count, 1);
|
||||
ck_assert_int_eq(job_2_run_count, 1);
|
||||
ck_assert_int_eq(job_3_run_count, 1);
|
||||
qb_loop_destroy(l);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
@ -147,11 +149,11 @@ START_TEST(test_loop_job_nuts)
|
||||
|
||||
qb_loop_run(l);
|
||||
fail_if(job_1_run_count < 500);
|
||||
qb_loop_destroy(l);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
static Suite *rb_suite(void)
|
||||
static Suite *loop_job_suite(void)
|
||||
{
|
||||
TCase *tc;
|
||||
Suite *s = suite_create("qb_loop_job");
|
||||
@ -175,6 +177,110 @@ static Suite *rb_suite(void)
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------------
|
||||
* Timers
|
||||
*/
|
||||
|
||||
START_TEST(test_loop_timer_input)
|
||||
{
|
||||
int32_t res;
|
||||
qb_loop_timer_handle th;
|
||||
qb_loop_t *l = qb_loop_create();
|
||||
fail_if(l == NULL);
|
||||
|
||||
res = qb_loop_timer_add(NULL, QB_LOOP_LOW, 5, NULL, job_2, &th);
|
||||
ck_assert_int_eq(res, -EINVAL);
|
||||
res = qb_loop_timer_add(l, QB_LOOP_LOW, 5, l, NULL, &th);
|
||||
ck_assert_int_eq(res, -EINVAL);
|
||||
res = qb_loop_timer_add(l, QB_LOOP_LOW, 5, l, job_1, NULL);
|
||||
ck_assert_int_eq(res, -ENOENT);
|
||||
qb_loop_destroy(l);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
struct qb_stop_watch {
|
||||
uint64_t start;
|
||||
uint64_t end;
|
||||
qb_loop_t *l;
|
||||
int32_t ms_timer;
|
||||
uint64_t total;
|
||||
int32_t count;
|
||||
};
|
||||
|
||||
static void stop_watch_tmo(void*data)
|
||||
{
|
||||
qb_loop_timer_handle th;
|
||||
struct qb_stop_watch *sw = (struct qb_stop_watch *)data;
|
||||
|
||||
sw->end = qb_util_nano_current_get();
|
||||
sw->total += (sw->end - sw->start) / QB_TIME_NS_IN_MSEC;
|
||||
sw->start = sw->end;
|
||||
sw->count++;
|
||||
if (sw->count < 50) {
|
||||
qb_loop_timer_add(sw->l, QB_LOOP_HIGH, sw->ms_timer, data, stop_watch_tmo, &th);
|
||||
} else {
|
||||
printf("average timeout for %d ms timer is %ld\n", sw->ms_timer,
|
||||
sw->total/sw->count);
|
||||
if (sw->ms_timer == 100) {
|
||||
qb_loop_stop(sw->l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void start_timer(qb_loop_t *l, struct qb_stop_watch *sw, int32_t timeout)
|
||||
{
|
||||
qb_loop_timer_handle th;
|
||||
int32_t res;
|
||||
|
||||
sw->l = l;
|
||||
sw->count = 0;
|
||||
sw->total = 0;
|
||||
sw->ms_timer = timeout;
|
||||
sw->start = qb_util_nano_current_get();
|
||||
res = qb_loop_timer_add(sw->l, QB_LOOP_LOW, sw->ms_timer, sw, stop_watch_tmo, &th);
|
||||
ck_assert_int_eq(res, 0);
|
||||
}
|
||||
|
||||
|
||||
START_TEST(test_loop_timer_basic)
|
||||
{
|
||||
int32_t i;
|
||||
int32_t max = RAND_MAX / 125;
|
||||
int32_t tmo;
|
||||
struct qb_stop_watch sw[11];
|
||||
qb_loop_t *l = qb_loop_create();
|
||||
|
||||
fail_if(l == NULL);
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
tmo = QB_MAX(1, random() / max);
|
||||
start_timer(l, &sw[i], tmo);
|
||||
}
|
||||
start_timer(l, &sw[i], 100);
|
||||
|
||||
qb_loop_run(l);
|
||||
qb_loop_destroy(l);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static Suite *loop_timer_suite(void)
|
||||
{
|
||||
TCase *tc;
|
||||
Suite *s = suite_create("qb_loop_timers");
|
||||
|
||||
tc = tcase_create("limits");
|
||||
tcase_add_test(tc, test_loop_timer_input);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("basic");
|
||||
tcase_add_test(tc, test_loop_timer_basic);
|
||||
tcase_set_timeout(tc, 30);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static void libqb_log_fn(const char *file_name,
|
||||
int32_t file_line, int32_t severity, const char *msg)
|
||||
{
|
||||
@ -184,9 +290,8 @@ static void libqb_log_fn(const char *file_name,
|
||||
int32_t main(void)
|
||||
{
|
||||
int32_t number_failed;
|
||||
|
||||
Suite *s = rb_suite();
|
||||
SRunner *sr = srunner_create(s);
|
||||
SRunner *sr = srunner_create(loop_job_suite());
|
||||
srunner_add_suite (sr, loop_timer_suite());
|
||||
|
||||
qb_util_set_log_function(libqb_log_fn);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user