From 816289ae8fd8239db04a2cd734a5ae2ff569ed8a Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Mon, 16 May 2011 17:08:37 -0700 Subject: [PATCH] unix: implement timers currently loop_handles is broken. --- test/test-timer.c | 11 ++++++++++- uv-unix.c | 42 ++++++++++++++++++++++++++++++++++++++---- uv-unix.h | 5 ++++- uv.h | 3 ++- 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/test/test-timer.c b/test/test-timer.c index f4bd65a9..15c80def 100644 --- a/test/test-timer.c +++ b/test/test-timer.c @@ -32,6 +32,8 @@ static int64_t start_time; static void once_close_cb(uv_handle_t* handle, int status) { + printf("ONCE_CLOSE_CB\n"); + ASSERT(handle != NULL); ASSERT(status == 0); @@ -42,6 +44,8 @@ static void once_close_cb(uv_handle_t* handle, int status) { static void once_cb(uv_handle_t* handle, int status) { + printf("ONCE_CB %d\n", once_cb_called); + ASSERT(handle != NULL); ASSERT(status == 0); @@ -55,6 +59,8 @@ static void once_cb(uv_handle_t* handle, int status) { static void repeat_close_cb(uv_handle_t* handle, int status) { + printf("REPEAT_CLOSE_CB\n"); + ASSERT(handle != NULL); ASSERT(status == 0); @@ -63,6 +69,8 @@ static void repeat_close_cb(uv_handle_t* handle, int status) { static void repeat_cb(uv_handle_t* handle, int status) { + printf("REPEAT_CB\n"); + ASSERT(handle != NULL); ASSERT(status == 0); @@ -111,7 +119,7 @@ TEST_IMPL(timer) { ASSERT(r == 0); } - /* The 11th timer is a repeating timer that runs 5 times */ + /* The 11th timer is a repeating timer that runs 4 times */ r = uv_timer_init(&repeat, repeat_close_cb, NULL); ASSERT(r == 0); r = uv_timer_start(&repeat, repeat_cb, 100, 100); @@ -130,6 +138,7 @@ TEST_IMPL(timer) { ASSERT(once_cb_called == 10); ASSERT(once_close_cb_called == 10); + printf("repeat_cb_called %d\n", repeat_cb_called); ASSERT(repeat_cb_called == 5); ASSERT(repeat_close_cb_called == 1); diff --git a/uv-unix.c b/uv-unix.c index f7ed1ec3..3680db2d 100644 --- a/uv-unix.c +++ b/uv-unix.c @@ -149,6 +149,10 @@ int uv_close(uv_handle_t* handle) { ev_async_stop(EV_DEFAULT_ &handle->async_watcher); break; + case UV_TIMER: + ev_timer_stop(EV_DEFAULT_ &handle->timer_watcher); + break; + default: assert(0); return -1; @@ -187,6 +191,9 @@ static void uv__handle_init(uv_handle_t* handle, uv_handle_type type, ev_init(&handle->next_watcher, uv__next); handle->next_watcher.data = handle; + + /* Ref the loop until this handle is closed. See uv__finish_close. */ + ev_ref(EV_DEFAULT_UC); } @@ -425,6 +432,14 @@ void uv__finish_close(uv_handle_t* handle) { case UV_ASYNC: assert(!ev_is_active(&handle->async_watcher)); break; + + case UV_TIMER: + assert(!ev_is_active(&handle->timer_watcher)); + break; + + default: + assert(0); + break; } ev_idle_stop(EV_DEFAULT_ &handle->next_watcher); @@ -432,6 +447,8 @@ void uv__finish_close(uv_handle_t* handle) { if (handle->close_cb) { handle->close_cb(handle, 0); } + + ev_unref(EV_DEFAULT_UC); } @@ -1062,22 +1079,39 @@ int uv_async_send(uv_handle_t* handle) { } +static void uv__timer_cb(EV_P_ ev_timer* w, int revents) { + uv_handle_t* handle = (uv_handle_t*)(w->data); + + if (handle->timer_cb) handle->timer_cb(handle, 0); +} + + int uv_timer_init(uv_handle_t* handle, uv_close_cb close_cb, void* data) { - assert(0 && "implement me"); + uv__handle_init(handle, UV_TIMER, close_cb, data); + + ev_init(&handle->timer_watcher, uv__timer_cb); + handle->timer_watcher.data = handle; + + return 0; } int uv_timer_start(uv_handle_t* handle, uv_loop_cb cb, int64_t timeout, int64_t repeat) { - assert(0 && "implement me"); + handle->timer_cb = cb; + ev_timer_set(&handle->timer_watcher, timeout / 1000.0, repeat / 1000.0); + ev_timer_start(EV_DEFAULT_UC_ &handle->timer_watcher); + return 0; } int uv_timer_stop(uv_handle_t* handle) { - assert(0 && "implement me"); + ev_timer_stop(EV_DEFAULT_UC_ &handle->timer_watcher); + return 0; } int uv_timer_again(uv_handle_t* handle) { - assert(0 && "implement me"); + ev_timer_again(EV_DEFAULT_UC_ &handle->timer_watcher); + return 0; } diff --git a/uv-unix.h b/uv-unix.h index eb5a5cfa..6301ac3f 100644 --- a/uv-unix.h +++ b/uv-unix.h @@ -72,7 +72,10 @@ typedef struct { uv_loop_cb idle_cb; \ /* UV_ASYNC */ \ ev_async async_watcher; \ - uv_loop_cb async_cb; + uv_loop_cb async_cb; \ +/* UV_TIMER */ \ + ev_timer timer_watcher; \ + uv_loop_cb timer_cb; #endif /* UV_UNIX_H */ diff --git a/uv.h b/uv.h index d1643b77..1d7f1443 100644 --- a/uv.h +++ b/uv.h @@ -111,7 +111,8 @@ typedef enum { UV_PREPARE, UV_CHECK, UV_IDLE, - UV_ASYNC + UV_ASYNC, + UV_TIMER } uv_handle_type; typedef enum {