mirror of https://github.com/lukechilds/node.git
Ryan Dahl
14 years ago
29 changed files with 1025 additions and 397 deletions
@ -1,105 +0,0 @@ |
|||||
/* 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 int expected = 0; |
|
||||
static int timeouts = 0; |
|
||||
|
|
||||
static int64_t start_time; |
|
||||
|
|
||||
static void timeout_cb(uv_req_t *req, int64_t skew, int status) { |
|
||||
ASSERT(req != NULL); |
|
||||
ASSERT(status == 0); |
|
||||
|
|
||||
free(req); |
|
||||
timeouts++; |
|
||||
|
|
||||
/* Just call this randomly for the code coverage. */ |
|
||||
uv_update_time(); |
|
||||
} |
|
||||
|
|
||||
static void exit_timeout_cb(uv_req_t *req, int64_t skew, int status) { |
|
||||
int64_t now = uv_now(); |
|
||||
ASSERT(req != NULL); |
|
||||
ASSERT(status == 0); |
|
||||
ASSERT(timeouts == expected); |
|
||||
ASSERT(start_time < now); |
|
||||
exit(0); |
|
||||
} |
|
||||
|
|
||||
static void dummy_timeout_cb(uv_req_t *req, int64_t skew, int status) { |
|
||||
/* Should never be called */ |
|
||||
FATAL("dummy_timer_cb should never be called"); |
|
||||
} |
|
||||
|
|
||||
|
|
||||
static uv_buf alloc_cb(uv_handle_t* handle, size_t size) { |
|
||||
uv_buf buf = {0, 0}; |
|
||||
FATAL("alloc should not be called"); |
|
||||
return buf; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
TEST_IMPL(timeout) { |
|
||||
uv_req_t *req; |
|
||||
uv_req_t exit_req; |
|
||||
uv_req_t dummy_req; |
|
||||
int i; |
|
||||
|
|
||||
uv_init(alloc_cb); |
|
||||
|
|
||||
start_time = uv_now(); |
|
||||
ASSERT(0 < start_time); |
|
||||
|
|
||||
/* Let 10 timers time out in 500 ms total. */ |
|
||||
for (i = 0; i < 10; i++) { |
|
||||
req = (uv_req_t*)malloc(sizeof(*req)); |
|
||||
ASSERT(req != NULL); |
|
||||
|
|
||||
uv_req_init(req, NULL, timeout_cb); |
|
||||
|
|
||||
if (uv_timeout(req, i * 50) < 0) { |
|
||||
FATAL("uv_timeout failed"); |
|
||||
} |
|
||||
|
|
||||
expected++; |
|
||||
} |
|
||||
|
|
||||
/* The 11th timer exits the test and runs after 1 s. */ |
|
||||
uv_req_init(&exit_req, NULL, exit_timeout_cb); |
|
||||
if (uv_timeout(&exit_req, 1000) < 0) { |
|
||||
FATAL("uv_timeout failed"); |
|
||||
} |
|
||||
|
|
||||
/* The 12th timer should never run. */ |
|
||||
uv_req_init(&dummy_req, NULL, dummy_timeout_cb); |
|
||||
if (uv_timeout(&dummy_req, 2000)) { |
|
||||
FATAL("uv_timeout failed"); |
|
||||
} |
|
||||
|
|
||||
uv_run(); |
|
||||
|
|
||||
FATAL("should never get here"); |
|
||||
return 2; |
|
||||
} |
|
@ -0,0 +1,153 @@ |
|||||
|
/* 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 int close_cb_called = 0; |
||||
|
static int repeat_1_cb_called = 0; |
||||
|
static int repeat_2_cb_called = 0; |
||||
|
|
||||
|
static int repeat_2_cb_allowed = 0; |
||||
|
|
||||
|
static uv_handle_t dummy, repeat_1, repeat_2; |
||||
|
|
||||
|
static int64_t start_time; |
||||
|
|
||||
|
|
||||
|
static void close_cb(uv_handle_t* handle, int status) { |
||||
|
ASSERT(handle != NULL); |
||||
|
ASSERT(status == 0); |
||||
|
|
||||
|
close_cb_called++; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static void repeat_1_cb(uv_handle_t* handle, int status) { |
||||
|
int r; |
||||
|
|
||||
|
ASSERT(handle == &repeat_1); |
||||
|
ASSERT(status == 0); |
||||
|
|
||||
|
ASSERT(uv_timer_get_repeat(handle) == 50); |
||||
|
|
||||
|
LOGF("repeat_1_cb called after %ld ms\n", (long int)(uv_now() - start_time)); |
||||
|
|
||||
|
repeat_1_cb_called++; |
||||
|
|
||||
|
r = uv_timer_again(&repeat_2); |
||||
|
ASSERT(r == 0); |
||||
|
|
||||
|
if (uv_now() >= start_time + 500) { |
||||
|
uv_close(handle); |
||||
|
/* We're not calling uv_timer_again on repeat_2 any more, so after this */ |
||||
|
/* timer_2_cb is expected. */ |
||||
|
repeat_2_cb_allowed = 1; |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static void repeat_2_cb(uv_handle_t* handle, int status) { |
||||
|
ASSERT(handle == &repeat_2); |
||||
|
ASSERT(status == 0); |
||||
|
ASSERT(repeat_2_cb_allowed); |
||||
|
|
||||
|
LOGF("repeat_2_cb called after %ld ms\n", (long int)(uv_now() - start_time)); |
||||
|
|
||||
|
repeat_2_cb_called++; |
||||
|
|
||||
|
if (uv_timer_get_repeat(handle) == 0) { |
||||
|
/* XXX Libev does considers the timer active here.
|
||||
|
* I'm not saying it must be this way, but we should consider what |
||||
|
* exactly the semantics of uv_is_active() should be. Is a timer that's |
||||
|
* initialized but stopped active? |
||||
|
*/ |
||||
|
ASSERT(uv_is_active(handle)); |
||||
|
uv_close(handle); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
LOGF("uv_timer_get_repeat %ld ms\n", (long int)uv_timer_get_repeat(handle)); |
||||
|
ASSERT(uv_timer_get_repeat(handle) == 100); |
||||
|
|
||||
|
/* This shouldn't take effect immediately. */ |
||||
|
uv_timer_set_repeat(&repeat_2, 0); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static uv_buf_t alloc_cb(uv_handle_t* handle, size_t size) { |
||||
|
uv_buf_t buf = {0, 0}; |
||||
|
FATAL("alloc should not be called"); |
||||
|
return buf; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
TEST_IMPL(timer_again) { |
||||
|
int r; |
||||
|
|
||||
|
uv_init(alloc_cb); |
||||
|
|
||||
|
start_time = uv_now(); |
||||
|
ASSERT(0 < start_time); |
||||
|
|
||||
|
/* Verify that it is not possible to uv_timer_again a never-started timer. */ |
||||
|
r = uv_timer_init(&dummy, NULL, NULL); |
||||
|
ASSERT(r == 0); |
||||
|
r = uv_timer_again(&dummy); |
||||
|
ASSERT(r == -1); |
||||
|
ASSERT(uv_last_error().code == UV_EINVAL); |
||||
|
uv_unref(); |
||||
|
|
||||
|
/* Start timer repeat_1. */ |
||||
|
r = uv_timer_init(&repeat_1, close_cb, NULL); |
||||
|
ASSERT(r == 0); |
||||
|
r = uv_timer_start(&repeat_1, repeat_1_cb, 50, 0); |
||||
|
ASSERT(r == 0); |
||||
|
ASSERT(uv_timer_get_repeat(&repeat_1) == 0); |
||||
|
|
||||
|
/* Actually make repeat_1 repeating. */ |
||||
|
uv_timer_set_repeat(&repeat_1, 50); |
||||
|
ASSERT(uv_timer_get_repeat(&repeat_1) == 50); |
||||
|
|
||||
|
/*
|
||||
|
* Start another repeating timer. It'll be again()ed by the repeat_1 so |
||||
|
* it should not time out until repeat_1 stops. |
||||
|
*/ |
||||
|
r = uv_timer_init(&repeat_2, close_cb, NULL); |
||||
|
ASSERT(r == 0); |
||||
|
r = uv_timer_start(&repeat_2, repeat_2_cb, 100, 100); |
||||
|
ASSERT(r == 0); |
||||
|
ASSERT(uv_timer_get_repeat(&repeat_2) == 100); |
||||
|
|
||||
|
uv_run(); |
||||
|
|
||||
|
ASSERT(repeat_1_cb_called == 10); |
||||
|
ASSERT(repeat_2_cb_called == 2); |
||||
|
ASSERT(close_cb_called == 2); |
||||
|
|
||||
|
LOGF("Test took %ld ms (expected ~700 ms)\n", |
||||
|
(long int)(uv_now() - start_time)); |
||||
|
ASSERT(700 <= uv_now() - start_time); |
||||
|
|
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,148 @@ |
|||||
|
/* 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 int once_cb_called = 0; |
||||
|
static int once_close_cb_called = 0; |
||||
|
static int repeat_cb_called = 0; |
||||
|
static int repeat_close_cb_called = 0; |
||||
|
|
||||
|
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); |
||||
|
|
||||
|
once_close_cb_called++; |
||||
|
|
||||
|
free(handle); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static void once_cb(uv_handle_t* handle, int status) { |
||||
|
printf("ONCE_CB %d\n", once_cb_called); |
||||
|
|
||||
|
ASSERT(handle != NULL); |
||||
|
ASSERT(status == 0); |
||||
|
|
||||
|
once_cb_called++; |
||||
|
|
||||
|
uv_close(handle); |
||||
|
|
||||
|
/* Just call this randomly for the code coverage. */ |
||||
|
uv_update_time(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static void repeat_close_cb(uv_handle_t* handle, int status) { |
||||
|
printf("REPEAT_CLOSE_CB\n"); |
||||
|
|
||||
|
ASSERT(handle != NULL); |
||||
|
ASSERT(status == 0); |
||||
|
|
||||
|
repeat_close_cb_called++; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static void repeat_cb(uv_handle_t* handle, int status) { |
||||
|
printf("REPEAT_CB\n"); |
||||
|
|
||||
|
ASSERT(handle != NULL); |
||||
|
ASSERT(status == 0); |
||||
|
|
||||
|
repeat_cb_called++; |
||||
|
|
||||
|
if (repeat_cb_called == 5) { |
||||
|
uv_close(handle); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static void never_close_cb(uv_handle_t* handle, int status) { |
||||
|
FATAL("never_close_cb should never be called"); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static void never_cb(uv_handle_t* handle, int status) { |
||||
|
FATAL("never_cb should never be called"); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
static uv_buf_t alloc_cb(uv_handle_t* handle, size_t size) { |
||||
|
uv_buf_t buf = {0, 0}; |
||||
|
FATAL("alloc should not be called"); |
||||
|
return buf; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
TEST_IMPL(timer) { |
||||
|
uv_handle_t *once; |
||||
|
uv_handle_t repeat, never; |
||||
|
int i, r; |
||||
|
|
||||
|
uv_init(alloc_cb); |
||||
|
|
||||
|
start_time = uv_now(); |
||||
|
ASSERT(0 < start_time); |
||||
|
|
||||
|
/* Let 10 timers time out in 500 ms total. */ |
||||
|
for (i = 0; i < 10; i++) { |
||||
|
once = (uv_handle_t*)malloc(sizeof(*once)); |
||||
|
ASSERT(once != NULL); |
||||
|
r = uv_timer_init(once, once_close_cb, NULL); |
||||
|
ASSERT(r == 0); |
||||
|
r = uv_timer_start(once, once_cb, i * 50, 0); |
||||
|
ASSERT(r == 0); |
||||
|
} |
||||
|
|
||||
|
/* 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); |
||||
|
ASSERT(r == 0); |
||||
|
|
||||
|
/* The 12th timer should not do anything. */ |
||||
|
r = uv_timer_init(&never, never_close_cb, NULL); |
||||
|
ASSERT(r == 0); |
||||
|
r = uv_timer_start(&never, never_cb, 100, 100); |
||||
|
ASSERT(r == 0); |
||||
|
r = uv_timer_stop(&never); |
||||
|
ASSERT(r == 0); |
||||
|
uv_unref(); |
||||
|
|
||||
|
uv_run(); |
||||
|
|
||||
|
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); |
||||
|
|
||||
|
ASSERT(500 <= uv_now() - start_time); |
||||
|
|
||||
|
return 0; |
||||
|
} |
@ -0,0 +1,69 @@ |
|||||
|
/* 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 <assert.h> |
||||
|
#include <stddef.h> /* NULL */ |
||||
|
|
||||
|
|
||||
|
const char* uv_err_name(uv_err_t err) { |
||||
|
switch (err.code) { |
||||
|
case UV_UNKNOWN: return "UNKNOWN"; |
||||
|
case UV_OK: return "OK"; |
||||
|
case UV_EOF: return "EOF"; |
||||
|
case UV_EACCESS: return "EACCESS"; |
||||
|
case UV_EAGAIN: return "EAGAIN"; |
||||
|
case UV_EADDRINUSE: return "EADDRINUSE"; |
||||
|
case UV_EADDRNOTAVAIL: return "EADDRNOTAVAIL"; |
||||
|
case UV_EAFNOSUPPORT: return "EAFNOSUPPORT"; |
||||
|
case UV_EALREADY: return "EALREADY"; |
||||
|
case UV_EBADF: return "EBADF"; |
||||
|
case UV_EBUSY: return "EBUSY"; |
||||
|
case UV_ECONNABORTED: return "ECONNABORTED"; |
||||
|
case UV_ECONNREFUSED: return "ECONNREFUSED"; |
||||
|
case UV_ECONNRESET: return "ECONNRESET"; |
||||
|
case UV_EDESTADDRREQ: return "EDESTADDRREQ"; |
||||
|
case UV_EFAULT: return "EFAULT"; |
||||
|
case UV_EHOSTUNREACH: return "EHOSTUNREACH"; |
||||
|
case UV_EINTR: return "EINTR"; |
||||
|
case UV_EINVAL: return "EINVAL"; |
||||
|
case UV_EISCONN: return "EISCONN"; |
||||
|
case UV_EMFILE: return "EMFILE"; |
||||
|
case UV_ENETDOWN: return "ENETDOWN"; |
||||
|
case UV_ENETUNREACH: return "ENETUNREACH"; |
||||
|
case UV_ENFILE: return "ENFILE"; |
||||
|
case UV_ENOBUFS: return "ENOBUFS"; |
||||
|
case UV_ENOMEM: return "ENOMEM"; |
||||
|
case UV_ENONET: return "ENONET"; |
||||
|
case UV_ENOPROTOOPT: return "ENOPROTOOPT"; |
||||
|
case UV_ENOTCONN: return "ENOTCONN"; |
||||
|
case UV_ENOTSOCK: return "ENOTSOCK"; |
||||
|
case UV_ENOTSUP: return "ENOTSUP"; |
||||
|
case UV_EPROTO: return "EPROTO"; |
||||
|
case UV_EPROTONOSUPPORT: return "EPROTONOSUPPORT"; |
||||
|
case UV_EPROTOTYPE: return "EPROTOTYPE"; |
||||
|
case UV_ETIMEDOUT: return "ETIMEDOUT"; |
||||
|
default: |
||||
|
assert(0); |
||||
|
return NULL; |
||||
|
} |
||||
|
} |
Loading…
Reference in new issue