#include "connect.h"
#include "iotable.h"
#include "timer-ng.h"
#define TMR_IS_DESTROYED(timer) ((timer)->state & LCBIO_TIMER_S_DESTROYED)
#define TMR_IS_ARMED(timer) ((timer)->state & LCBIO_TIMER_S_ARMED)
static void
destroy_timer(lcbio_TIMER *timer)
{
if (timer->event) {
timer->io->timer.destroy(timer->io->p, timer->event);
}
lcbio_table_unref(timer->io);
free(timer);
}
static void
timer_callback(lcb_socket_t sock, short which, void *arg)
{
lcbio_TIMER *timer = arg;
lcb_assert(TMR_IS_ARMED(timer));
lcb_assert(!TMR_IS_DESTROYED(timer));
timer->state |= LCBIO_TIMER_S_ENTERED;
lcbio_timer_disarm(timer);
timer->callback(timer->data);
if (TMR_IS_DESTROYED(timer)) {
destroy_timer(timer);
} else {
timer->state &= ~LCBIO_TIMER_S_ENTERED;
}
(void)sock;
(void)which;
}
lcbio_TIMER *
lcbio_timer_new(lcbio_TABLE *io, void *data, lcbio_TIMER_cb callback)
{
lcbio_TIMER *ret = calloc(1, sizeof(*ret));
if (!ret) {
return NULL;
}
ret->callback = callback;
ret->data = data;
ret->io = io;
ret->event = io->timer.create(IOT_ARG(io));
lcbio_table_ref(io);
return ret;
}
void
lcbio_timer_destroy(lcbio_TIMER *timer)
{
lcbio_timer_disarm(timer);
if (timer->state & LCBIO_TIMER_S_ENTERED) {
timer->state |= LCBIO_TIMER_S_DESTROYED;
} else {
destroy_timer(timer);
}
}
void
lcbio_timer_disarm(lcbio_TIMER *timer)
{
if (!TMR_IS_ARMED(timer)) {
return;
}
timer->state &= ~LCBIO_TIMER_S_ARMED;
timer->io->timer.cancel(timer->io->p, timer->event);
}
void
lcbio_timer_rearm(lcbio_TIMER * timer, uint32_t usec)
{
if (TMR_IS_ARMED(timer)) {
lcbio_timer_disarm(timer);
}
timer->usec_ = usec;
timer->io->timer.schedule(timer->io->p,
timer->event, usec, timer, timer_callback);
timer->state |= LCBIO_TIMER_S_ARMED;
}
void
lcbio_async_signal(lcbio_TIMER *timer)
{
lcbio_timer_rearm(timer, 0);
}
void
lcbio_async_cancel(lcbio_TIMER *timer)
{
lcbio_timer_disarm(timer);
}
void
lcbio_timer_dump(lcbio_TIMER *timer, FILE *fp)
{
fprintf(fp, "~~ DUMP TIMER BEGIN ~~\n");
fprintf(fp, "TIMER=%p\n", (void*)timer);
fprintf(fp, "INNER PTR=%p\n", timer->event);
fprintf(fp, "USERDATA=%p\n", timer->data);
fprintf(fp, "ACTIVE: %s\n", (timer->state & LCBIO_TIMER_S_ARMED) ? "YES":"NO");
fprintf(fp, "INTERVAL: %lu\n", (unsigned long)timer->usec_);
fprintf(fp, "~~ DUMP TIMER END ~~\n");
}