From e53cecb8c02ac03a67f284e248765b84f840c7f2 Mon Sep 17 00:00:00 2001 From: mattn Date: Tue, 13 Dec 2011 09:58:53 +0900 Subject: [PATCH] add uv_run_once() --- include/uv.h | 5 +++++ src/unix/core.c | 6 ++++++ src/win/core.c | 20 +++++++++++++++++--- test/test-run-once.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 test/test-run-once.c diff --git a/include/uv.h b/include/uv.h index 387afcf0..37bdf9cf 100644 --- a/include/uv.h +++ b/include/uv.h @@ -212,6 +212,11 @@ UV_EXTERN uv_loop_t* uv_default_loop(void); */ UV_EXTERN int uv_run (uv_loop_t*); +/* + * This function polls for new events without blocking. + */ +UV_EXTERN int uv_run_once (uv_loop_t*); + /* * Manually modify the event loop's reference count. Useful if the user wants * to have a handle or timeout that doesn't keep the loop alive. diff --git a/src/unix/core.c b/src/unix/core.c index cf323adc..933c9bd7 100644 --- a/src/unix/core.c +++ b/src/unix/core.c @@ -202,6 +202,12 @@ int uv_run(uv_loop_t* loop) { } +int uv_run_once(uv_loop_t* loop) { + ev_run(loop->ev, EVRUN_NOWAIT); + return 0; +} + + void uv__handle_init(uv_loop_t* loop, uv_handle_t* handle, uv_handle_type type) { loop->counters.handle_init++; diff --git a/src/win/core.c b/src/win/core.c index 72fee1c8..5f61f0ab 100644 --- a/src/win/core.c +++ b/src/win/core.c @@ -192,9 +192,8 @@ static void uv_poll_ex(uv_loop_t* loop, int block) { } } - -#define UV_LOOP(loop, poll) \ - while ((loop)->refs > 0) { \ +#define UV_LOOP_ONCE(loop, poll) \ + do { \ uv_update_time((loop)); \ uv_process_timers((loop)); \ \ @@ -219,9 +218,24 @@ static void uv_poll_ex(uv_loop_t* loop, int block) { (loop)->refs > 0); \ \ uv_check_invoke((loop)); \ + } while (0); + +#define UV_LOOP(loop, poll) \ + while ((loop)->refs > 0) { \ + UV_LOOP_ONCE(loop, poll) \ } +int uv_run_once(uv_loop_t* loop) { + if (pGetQueuedCompletionStatusEx) { + UV_LOOP_ONCE(loop, uv_poll_ex); + } else { + UV_LOOP_ONCE(loop, uv_poll); + } + return 0; +} + + int uv_run(uv_loop_t* loop) { if (pGetQueuedCompletionStatusEx) { UV_LOOP(loop, uv_poll_ex); diff --git a/test/test-run-once.c b/test/test-run-once.c new file mode 100644 index 00000000..c03ab88e --- /dev/null +++ b/test/test-run-once.c @@ -0,0 +1,44 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +static idle_counter = 0; + +static void idle_cb(uv_idle_t* handle, int status) { + ASSERT(handle != NULL); + ASSERT(status == 0); + idle_counter ++; +} + + +TEST_IMPL(run_once) { + int n; + uv_idle_t h; + uv_idle_init(uv_default_loop(), &h); + uv_idle_start(&h, idle_cb); + for (n = 0; n < 500; n++) { + uv_run_once(uv_default_loop()); + } + ASSERT(n == 500); + return 0; +}