Skip to content

Commit

Permalink
master: Issue 390: Clarify documentation of qb_loop_timer_expire_time…
Browse files Browse the repository at this point in the history
…_get and provide new function to return previously documented behavior
  • Loading branch information
cmurphycode committed Apr 23, 2020
1 parent 93f9975 commit b76ab9d
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 2 deletions.
15 changes: 13 additions & 2 deletions include/qb/qbloop.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,16 +187,27 @@ int32_t qb_loop_timer_del(qb_loop_t *l, qb_loop_timer_handle th);
int32_t qb_loop_timer_is_running(qb_loop_t *l, qb_loop_timer_handle th);

/**
* Get the time remaining before it expires.
* Get the expiration time of the timer, as set when the timer was created
*
* @note if the timer has already expired it will return 0
*
* @param l pointer to the loop instance
* @param th timer handle.
* @return nano seconds left
* @return nano seconds at which the timer will expire
*/
uint64_t qb_loop_timer_expire_time_get(struct qb_loop *l, qb_loop_timer_handle th);

/**
* Get the time remaining before the timer expires
*
* @note if the timer has already expired it will return 0
*
* @param l pointer to the loop instance
* @param th timer handle.
* @return nano seconds remaining until the timer expires
*/
uint64_t qb_loop_timer_expire_time_remaining(struct qb_loop *l, qb_loop_timer_handle th);

/**
* Set a callback to receive events on file descriptors
* getting low.
Expand Down
50 changes: 50 additions & 0 deletions lib/loop_timerlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,56 @@ qb_loop_timer_expire_time_get(struct qb_loop * lp, qb_loop_timer_handle th)
return timerlist_expire_time(&s->timerlist, t->timerlist_handle);
}

uint64_t
qb_loop_timer_expire_time_remaining(struct qb_loop * lp, qb_loop_timer_handle th)
{

uint64_t current_ns;
/* NOTE: while it does not appear that absolute timers are used anywhere,
* we may as well respect this pattern in case that changes.
* Unfortunately, that means we do need to repeat timer fetch code from qb_loop_timer_expire_time_get
* rather than just a simple call to qb_loop_timer_expire_time_get and qb_util_nano_current_get.
*/

struct qb_timer_source *s;
struct qb_loop_timer *t;
int32_t res;
struct qb_loop *l = lp;

if (l == NULL) {
l = qb_loop_default_get();
}
s = (struct qb_timer_source *)l->timer_source;

res = _timer_from_handle_(s, th, &t);
if (res != 0) {
return 0;
}

struct timerlist_timer *timer = (struct timerlist_timer *)t->timerlist_handle;


if (timer->is_absolute_timer) {
current_ns = qb_util_nano_from_epoch_get();
}
else {
current_ns = qb_util_nano_current_get();
}
uint64_t timer_ns = timerlist_expire_time(&s->timerlist, t->timerlist_handle);
/* since time estimation is racy by nature, I'll try to check the state late,
* and try to understand that no matter what, the timer might have expired in the mean time
*/
if (t->state != QB_POLL_ENTRY_ACTIVE) {
return 0;
}
if (timer_ns < current_ns) {
return 0; // respect the "expired" contract
}
return timer_ns - current_ns;


}

int32_t
qb_loop_timer_is_running(qb_loop_t *l, qb_loop_timer_handle th)
{
Expand Down

0 comments on commit b76ab9d

Please sign in to comment.