+
+
+void add_timeout_intern(int value_msec, int interval_msec, void(*_callback)(), struct timeout *t)
+{
+ t->interval_msec = interval_msec;
+ t->_callback = _callback;
+ struct timespec expire;
+ clock_gettime(CLOCK_MONOTONIC, &expire);
+ expire.tv_sec += value_msec / 1000;
+ expire.tv_nsec += (value_msec % 1000)*1000000;
+ if (expire.tv_nsec >= 1000000000) { // 10^9
+ expire.tv_sec++;
+ expire.tv_nsec -= 1000000000;
+ }
+ t->timeout_expires = expire;
+ timeout_list = g_slist_insert_sorted(timeout_list, t, compare_timeouts);
+}
+
+
+gint compare_timeouts(gconstpointer t1, gconstpointer t2)
+{
+ return compare_timespecs(&((const struct timeout*)t1)->timeout_expires,
+ &((const struct timeout*)t2)->timeout_expires);
+}
+
+
+gint compare_timespecs(const struct timespec* t1, const struct timespec* t2)
+{
+ if (t1->tv_sec < t2->tv_sec)
+ return -1;
+ else if (t1->tv_sec == t2->tv_sec) {
+ if (t1->tv_nsec < t2->tv_nsec)
+ return -1;
+ else if (t1->tv_nsec == t2->tv_nsec)
+ return 0;
+ else
+ return 1;
+ }
+ else
+ return 1;
+}
+
+int timespec_subtract(struct timespec* result, struct timespec* x, struct timespec* y)
+{
+ /* Perform the carry for the later subtraction by updating y. */
+ if (x->tv_nsec < y->tv_nsec) {
+ int nsec = (y->tv_nsec - x->tv_nsec) / 1000000000 + 1;
+ y->tv_nsec -= 1000000000 * nsec;
+ y->tv_sec += nsec;
+ }
+ if (x->tv_nsec - y->tv_nsec > 1000000000) {
+ int nsec = (x->tv_nsec - y->tv_nsec) / 1000000000;
+ y->tv_nsec += 1000000000 * nsec;
+ y->tv_sec -= nsec;
+ }
+
+ /* Compute the time remaining to wait. tv_nsec is certainly positive. */
+ result->tv_sec = x->tv_sec - y->tv_sec;
+ result->tv_nsec = x->tv_nsec - y->tv_nsec;
+
+ /* Return 1 if result is negative. */
+ return x->tv_sec < y->tv_sec;
+}