|
|
|
|
@ -158,7 +158,14 @@ static void __timerthread_queue_free(void *p) {
|
|
|
|
|
static int ttqe_compare(const void *a, const void *b) {
|
|
|
|
|
const struct timerthread_queue_entry *t1 = a;
|
|
|
|
|
const struct timerthread_queue_entry *t2 = b;
|
|
|
|
|
return timeval_cmp_ptr(&t1->when, &t2->when);
|
|
|
|
|
int ret = timeval_cmp_zero(&t1->when, &t2->when);
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
if (t1->idx < t2->idx)
|
|
|
|
|
return -1;
|
|
|
|
|
if (t1->idx == t2->idx)
|
|
|
|
|
return 0;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void *timerthread_queue_new(const char *type, size_t size,
|
|
|
|
|
@ -183,6 +190,18 @@ void *timerthread_queue_new(const char *type, size_t size,
|
|
|
|
|
return ttq;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int __ttqe_find_last_idx(const void *a, const void *b) {
|
|
|
|
|
const struct timerthread_queue_entry *ttqe_a = a;
|
|
|
|
|
void **data = (void **) b;
|
|
|
|
|
const struct timerthread_queue_entry *ttqe_b = data[0];
|
|
|
|
|
int ret = timeval_cmp(&ttqe_b->when, &ttqe_a->when);
|
|
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
|
|
|
|
// same timestamp. track highest seen idx
|
|
|
|
|
if (GPOINTER_TO_UINT(data[1]) < ttqe_a->idx)
|
|
|
|
|
data[1] = GUINT_TO_POINTER(ttqe_a->idx);
|
|
|
|
|
return 1; // and continue to higher idx
|
|
|
|
|
}
|
|
|
|
|
void timerthread_queue_push(struct timerthread_queue *ttq, struct timerthread_queue_entry *ttqe) {
|
|
|
|
|
// can we send immediately?
|
|
|
|
|
if (ttq->run_now_func && timerthread_queue_run_one(ttq, ttqe, ttq->run_now_func) == 0)
|
|
|
|
|
@ -203,7 +222,22 @@ void timerthread_queue_push(struct timerthread_queue *ttq, struct timerthread_qu
|
|
|
|
|
// ntohs(rh->seq_num),
|
|
|
|
|
// ntohl(rh->timestamp));
|
|
|
|
|
|
|
|
|
|
ttqe->idx = 0;
|
|
|
|
|
|
|
|
|
|
mutex_lock(&ttq->lock);
|
|
|
|
|
|
|
|
|
|
// check for most common case: no timestamp collision exists
|
|
|
|
|
if (!g_tree_lookup(ttq->entries, ttqe))
|
|
|
|
|
;
|
|
|
|
|
else {
|
|
|
|
|
// something else exists with the same timestamp. find the highest idx
|
|
|
|
|
void *data[2];
|
|
|
|
|
data[0] = ttqe;
|
|
|
|
|
data[1] = 0;
|
|
|
|
|
g_tree_search(ttq->entries, __ttqe_find_last_idx, data);
|
|
|
|
|
ttqe->idx = GPOINTER_TO_UINT(data[1] + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// this hands over ownership of cp, so we must copy the timeval out
|
|
|
|
|
struct timeval tv_send = ttqe->when;
|
|
|
|
|
g_tree_insert(ttq->entries, ttqe, ttqe);
|
|
|
|
|
|