Skip to content

Commit

Permalink
WIP - add libev based posix timers
Browse files Browse the repository at this point in the history
  • Loading branch information
franc0is committed Sep 9, 2015
1 parent 9892ec1 commit ff5eefe
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 62 deletions.
29 changes: 2 additions & 27 deletions examples/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -1030,7 +1030,6 @@ main(int argc, char **argv) {
struct timeval tv;
int result;
coap_tick_t now;
coap_queue_t *nextpdu;
coap_pdu_t *pdu;
static str server;
unsigned short port = COAP_DEFAULT_PORT;
Expand Down Expand Up @@ -1210,32 +1209,8 @@ main(int argc, char **argv) {
FD_ZERO(&readfds);
FD_SET( ctx->sockfd, &readfds );

nextpdu = coap_peek_next( ctx );

// coap_ticks(&now);
// while (nextpdu && nextpdu->t <= now - ctx->sendqueue_basetime) {
// coap_retransmit( ctx, coap_pop_next( ctx ));
// nextpdu = coap_peek_next( ctx );
// }

if (nextpdu && nextpdu->t < min(obs_wait ? obs_wait : max_wait, max_wait) - now) {
/* set timeout if there is a pdu to send */
tv.tv_usec = ((nextpdu->t) % COAP_TICKS_PER_SECOND) * 1000000 / COAP_TICKS_PER_SECOND;
tv.tv_sec = (nextpdu->t) / COAP_TICKS_PER_SECOND;
} else {
/* check if obs_wait fires before max_wait */
if (obs_wait && obs_wait < max_wait) {
tv.tv_usec = ((obs_wait - now) % COAP_TICKS_PER_SECOND) * 1000000 / COAP_TICKS_PER_SECOND;
tv.tv_sec = (obs_wait - now) / COAP_TICKS_PER_SECOND;
} else {
tv.tv_usec = ((max_wait - now) % COAP_TICKS_PER_SECOND) * 1000000 / COAP_TICKS_PER_SECOND;
tv.tv_sec = (max_wait - now) / COAP_TICKS_PER_SECOND;
}
}

//result = select(ctx->sockfd + 1, &readfds, 0, 0, &tv);
result = 0;
pause();
tv.tv_sec = wait_seconds;
result = select(ctx->sockfd + 1, &readfds, 0, 0, &tv);

if ( result < 0 ) { /* error */
perror("select");
Expand Down
20 changes: 3 additions & 17 deletions examples/coap-server.c
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,6 @@ main(int argc, char **argv) {
struct timeval tv, *timeout;
int result;
coap_tick_t now;
coap_queue_t *nextpdu;
char addr_str[NI_MAXHOST] = "::";
char port_str[NI_MAXSERV] = "5683";
int opt;
Expand Down Expand Up @@ -498,24 +497,11 @@ main(int argc, char **argv) {
FD_ZERO(&readfds);
FD_SET( ctx->sockfd, &readfds );

nextpdu = coap_peek_next( ctx );

coap_ticks(&now);
while (nextpdu && nextpdu->t <= now - ctx->sendqueue_basetime) {
coap_retransmit( ctx, coap_pop_next( ctx ) );
nextpdu = coap_peek_next( ctx );
}

if ( nextpdu && nextpdu->t <= COAP_RESOURCE_CHECK_TIME ) {
/* set timeout if there is a pdu to send before our automatic timeout occurs */
tv.tv_usec = ((nextpdu->t) % COAP_TICKS_PER_SECOND) * 1000000 / COAP_TICKS_PER_SECOND;
tv.tv_sec = (nextpdu->t) / COAP_TICKS_PER_SECOND;
timeout = &tv;
} else {
tv.tv_usec = 0;
tv.tv_sec = COAP_RESOURCE_CHECK_TIME;
timeout = &tv;
}
tv.tv_usec = 0;
tv.tv_sec = COAP_RESOURCE_CHECK_TIME;
timeout = &tv;
result = select( FD_SETSIZE, &readfds, 0, 0, timeout );

if ( result < 0 ) { /* error */
Expand Down
4 changes: 3 additions & 1 deletion platform/posix/platform_time.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ static coap_time_t coap_clock_offset = 0;
#define COAP_CLOCK CLOCK_REALTIME
#endif

#undef COAP_CLOCK

void
coap_clock_init(void) {
#ifdef COAP_CLOCK
Expand Down Expand Up @@ -61,7 +63,7 @@ coap_ticks(coap_tick_t *t) {
* Both cases should not be possible here.
*/

tmp = tv.tv_usec * Q(FRAC, (COAP_TICKS_PER_SECOND/1000000.0));
tmp = tv.tv_usec / 1000; // * Q(FRAC, (COAP_TICKS_PER_SECOND/1000000.0));
#endif /* not _POSIX_TIMERS */

/* Finally, convert temporary FP representation to multiple of
Expand Down
73 changes: 60 additions & 13 deletions platform/posix/platform_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <string.h>
#include <sys/time.h> // TODO needs something like HAVE_TIME_H
#include <signal.h> // TODO needs something like HAVE_SIGNAL_H
#include <pthread.h> // TODO needs something like HAVE_PTHREAD_H

#include "libev/ev.h"

Expand All @@ -15,35 +16,81 @@
#define UNUSED
#endif

struct coap_timer_t;

struct coap_timer_t {
ev_timer timer;
CoapTimerCallback cb;
void *data;
};

static pthread_t timer_thread;
static struct ev_loop *timer_loop;
static ev_async thread_wakeup;

static void timeout_cb(EV_P_ ev_timer *w, int revents) {
coap_timer_t *coap_timer = (coap_timer_t *)w;
if (coap_timer->cb) {
coap_timer->cb(coap_timer->data);
}
}

static void *timer_thread_func(void* args) {
ev_run(timer_loop, 0);
return NULL;
}

static void thread_wakeup_cb(EV_P_ ev_async *w, int revents) {
// this only exists to wake up the thread
// so it may pick up new timer watchers
}


// TODO coap_timer_deinit to cleanly kill the loop
void coap_timer_init(void) {
struct ev_loop *loop = EV_DEFAULT;
ev_run (loop, 0);
timer_loop = EV_DEFAULT;

// set up an async event for thread wakeup
ev_async_init(&thread_wakeup, thread_wakeup_cb);
ev_async_start(timer_loop, &thread_wakeup);

pthread_create(&timer_thread, NULL, timer_thread_func, NULL);
}

coap_timer_t *coap_new_timer(CoapTimerCallback cb, void *data) {
return NULL;
coap_timer_t *coap_timer = coap_malloc_type(COAP_TIMER, sizeof(coap_timer_t));

if (coap_timer) {
coap_timer->cb = cb;
coap_timer->data = data;
ev_timer_init(&coap_timer->timer, timeout_cb, 0., 0.);
}

return coap_timer;
}

void coap_free_timer(coap_timer_t *timer) {
return;
void coap_free_timer(coap_timer_t *coap_timer) {
ev_timer_stop(timer_loop, &coap_timer->timer);
coap_free_type(COAP_TIMER, coap_timer);
}

void coap_timer_set(coap_timer_t *timer, coap_tick_t num_ticks) {
return;
void coap_timer_set(coap_timer_t *coap_timer, coap_tick_t num_ticks) {
// stop the timer if it is running
ev_timer_stop(timer_loop, &coap_timer->timer);

// set the new timeout
ev_tstamp time = (ev_tstamp)num_ticks / COAP_TICKS_PER_SECOND;
ev_timer_set(&coap_timer->timer, time, 0.);
ev_timer_start(timer_loop, &coap_timer->timer);

// wake up the thread
ev_async_send(timer_loop, &thread_wakeup);
}

char coap_timer_is_set(coap_timer_t *timer) {
return 0;
char coap_timer_is_set(coap_timer_t *coap_timer) {
return (ev_timer_remaining(timer_loop, &coap_timer->timer) != 0.);
}

void coap_timer_unset(coap_timer_t *timer) {
return;
void coap_timer_unset(coap_timer_t *coap_timer) {
ev_timer_stop(timer_loop, &coap_timer->timer);
ev_timer_set(&coap_timer->timer, 0., 0.);
}

2 changes: 0 additions & 2 deletions src/coap_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ coap_context_t the_coap_context;

#ifndef WITHOUT_OBSERVE
static void notify_timer_cb(void *data) {
debug("NOTIFY!\n");
coap_context_t *c = data;
coap_check_notify(c);
coap_timer_set(c->notify_timer, COAP_RESOURCE_CHECK_TIME * COAP_TICKS_PER_SECOND);
Expand All @@ -60,7 +59,6 @@ static void notify_timer_cb(void *data) {

// TODO this should probably be in its own file ... coap_retransmit.c?
static void retransmit_timer_cb(void *data) {
debug("CALLBACK!\n");
coap_context_t *c = data;
coap_queue_t *nextpdu = coap_peek_next(c);

Expand Down
2 changes: 0 additions & 2 deletions src/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,6 @@ coap_send_confirmed(coap_context_t *context,

/* Reschedule the retransmit timer if the head node is the new node */
if (node == context->sendqueue) {
debug("SCHEDULING RETRANSMIT!\n");
coap_timer_set(context->retransmit_timer, node->t);
}

Expand All @@ -503,7 +502,6 @@ coap_send_confirmed(coap_context_t *context,

coap_tid_t
coap_retransmit(coap_context_t *context, coap_queue_t *node) {
debug("RETRANSMIT\n");

if (!context || !node)
return COAP_INVALID_TID;
Expand Down

0 comments on commit ff5eefe

Please sign in to comment.