aboutsummaryrefslogtreecommitdiff
path: root/src/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/timer.c')
-rw-r--r--src/timer.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/src/timer.c b/src/timer.c
index bc680e71..b57d6427 100644
--- a/src/timer.c
+++ b/src/timer.c
@@ -40,8 +40,8 @@ static int timer_less_than(const struct heap_node* ha,
const uv_timer_t* a;
const uv_timer_t* b;
- a = container_of(ha, uv_timer_t, heap_node);
- b = container_of(hb, uv_timer_t, heap_node);
+ a = container_of(ha, uv_timer_t, node.heap);
+ b = container_of(hb, uv_timer_t, node.heap);
if (a->timeout < b->timeout)
return 1;
@@ -60,6 +60,7 @@ int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
handle->timer_cb = NULL;
handle->timeout = 0;
handle->repeat = 0;
+ uv__queue_init(&handle->node.queue);
return 0;
}
@@ -73,8 +74,7 @@ int uv_timer_start(uv_timer_t* handle,
if (uv__is_closing(handle) || cb == NULL)
return UV_EINVAL;
- if (uv__is_active(handle))
- uv_timer_stop(handle);
+ uv_timer_stop(handle);
clamped_timeout = handle->loop->time + timeout;
if (clamped_timeout < timeout)
@@ -87,23 +87,27 @@ int uv_timer_start(uv_timer_t* handle,
handle->start_id = handle->loop->timer_counter++;
heap_insert(timer_heap(handle->loop),
- (struct heap_node*) &handle->heap_node,
+ (struct heap_node*) &handle->node.heap,
timer_less_than);
uv__handle_start(handle);
return 0;
}
-
-int uv_timer_stop(uv_timer_t* handle) {
- if (!uv__is_active(handle))
- return 0;
-
+static void timer_stop(uv_timer_t* handle) {
heap_remove(timer_heap(handle->loop),
- (struct heap_node*) &handle->heap_node,
+ (struct heap_node*) &handle->node.heap,
timer_less_than);
uv__handle_stop(handle);
+ uv__queue_init(&handle->node.queue);
+}
+
+int uv_timer_stop(uv_timer_t* handle) {
+ if (uv__is_active(handle))
+ timer_stop(handle);
+ else
+ uv__queue_remove(&handle->node.queue);
return 0;
}
@@ -148,7 +152,7 @@ int uv__next_timeout(const uv_loop_t* loop) {
if (heap_node == NULL)
return -1; /* block indefinitely */
- handle = container_of(heap_node, uv_timer_t, heap_node);
+ handle = container_of(heap_node, uv_timer_t, node.heap);
if (handle->timeout <= loop->time)
return 0;
@@ -163,17 +167,30 @@ int uv__next_timeout(const uv_loop_t* loop) {
void uv__run_timers(uv_loop_t* loop) {
struct heap_node* heap_node;
uv_timer_t* handle;
+ struct uv__queue* queue_node;
+ struct uv__queue ready_queue;
+
+ uv__queue_init(&ready_queue);
for (;;) {
heap_node = heap_min(timer_heap(loop));
if (heap_node == NULL)
break;
- handle = container_of(heap_node, uv_timer_t, heap_node);
+ handle = container_of(heap_node, uv_timer_t, node.heap);
if (handle->timeout > loop->time)
break;
- uv_timer_stop(handle);
+ timer_stop(handle);
+ uv__queue_insert_tail(&ready_queue, &handle->node.queue);
+ }
+
+ while (!uv__queue_empty(&ready_queue)) {
+ queue_node = uv__queue_head(&ready_queue);
+ uv__queue_remove(queue_node);
+ uv__queue_init(queue_node);
+ handle = container_of(queue_node, uv_timer_t, node.queue);
+
uv_timer_again(handle);
handle->timer_cb(handle);
}