]>
Dogcows Code - chaz/openbox/blob - openbox/timer.c
8 static GTimeVal ret_wait
;
9 static GSList
*timers
; /* nearest timer is at the top */
11 #define NEAREST_TIMEOUT (((Timer*)timers->data)->timeout)
13 static long timecompare(GTimeVal
*a
, GTimeVal
*b
)
17 if ((r
= b
->tv_sec
- a
->tv_sec
)) return r
;
18 return b
->tv_usec
- a
->tv_usec
;
22 static void insert_timer(Timer
*self
)
25 for (it
= timers
; it
!= NULL
; it
= it
->next
) {
27 if (timecompare(&self
->timeout
, &t
->timeout
) <= 0) {
28 timers
= g_slist_insert_before(timers
, it
, self
);
32 if (it
== NULL
) /* didnt fit anywhere in the list */
33 timers
= g_slist_append(timers
, self
);
38 g_get_current_time(&now
);
45 for (it
= timers
; it
!= NULL
; it
= it
->next
) {
52 Timer
*timer_start(long delay
, TimeoutHandler cb
, void *data
)
54 Timer
*self
= g_new(Timer
, 1);
59 self
->last
= self
->timeout
= now
;
60 g_time_val_add(&self
->timeout
, delay
);
67 void timer_stop(Timer
*self
)
72 /* find the time to wait for the nearest timeout */
73 static gboolean
nearest_timeout_wait(GTimeVal
*tm
)
78 tm
->tv_sec
= NEAREST_TIMEOUT
.tv_sec
- now
.tv_sec
;
79 tm
->tv_usec
= NEAREST_TIMEOUT
.tv_usec
- now
.tv_usec
;
81 while (tm
->tv_usec
< 0) {
82 tm
->tv_usec
+= G_USEC_PER_SEC
;
85 tm
->tv_sec
+= tm
->tv_usec
/ G_USEC_PER_SEC
;
86 tm
->tv_usec
%= G_USEC_PER_SEC
;
94 void timer_dispatch(GTimeVal
**wait
)
96 g_get_current_time(&now
);
98 while (timers
!= NULL
) {
99 Timer
*curr
= timers
->data
; /* get the top element */
100 /* since timer_stop doesn't actually free the timer, we have to do our
101 real freeing in here.
104 timers
= g_slist_delete_link(timers
, timers
); /* delete the top */
109 /* the queue is sorted, so if this timer shouldn't fire, none are
111 if (timecompare(&NEAREST_TIMEOUT
, &now
) <= 0)
114 /* we set the last fired time to delay msec after the previous firing,
115 then re-insert. timers maintain their order and may trigger more
116 than once if they've waited more than one delay's worth of time.
118 timers
= g_slist_delete_link(timers
, timers
);
119 g_time_val_add(&curr
->last
, curr
->delay
);
120 curr
->action(curr
->data
);
121 g_time_val_add(&curr
->timeout
, curr
->delay
);
124 /* if at least one timer fires, then don't wait on X events, as there
125 may already be some in the queue from the timer callbacks.
127 ret_wait
.tv_sec
= ret_wait
.tv_usec
= 0;
132 if (nearest_timeout_wait(&ret_wait
))
This page took 0.042548 seconds and 4 git commands to generate.