* All callbacks in libuv are made asynchronously. That is they are never
* made by the function that takes them as a parameter.
*/
-void uv_init();
uv_loop_t* uv_loop_new();
-
void uv_loop_delete(uv_loop_t*);
+
/*
* Returns the default loop.
*/
#endif
-void uv_init() {
- default_loop_ptr = &default_loop_struct;
-#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
- default_loop_struct.ev = ev_default_loop(EVBACKEND_KQUEUE);
-#else
- default_loop_struct.ev = ev_default_loop(EVFLAG_AUTO);
-#endif
- ev_set_userdata(default_loop_struct.ev, default_loop_ptr);
-}
-
-
void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
uv_udp_t* udp;
uv_async_t* async;
uv_loop_t* uv_default_loop() {
+ if (!default_loop_ptr) {
+ default_loop_ptr = &default_loop_struct;
+#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
+ default_loop_struct.ev = ev_default_loop(EVBACKEND_KQUEUE);
+#else
+ default_loop_struct.ev = ev_default_loop(EVFLAG_AUTO);
+#endif
+ ev_set_userdata(default_loop_struct.ev, default_loop_ptr);
+ }
assert(default_loop_ptr->ev == EV_DEFAULT_UC);
return default_loop_ptr;
}
int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
- struct sockaddr_un sun;
+ struct sockaddr_un saddr;
const char* pipe_fname;
int saved_errno;
int sockfd;
goto out;
}
- memset(&sun, 0, sizeof sun);
- uv__strlcpy(sun.sun_path, pipe_fname, sizeof(sun.sun_path));
- sun.sun_family = AF_UNIX;
+ memset(&saddr, 0, sizeof saddr);
+ uv__strlcpy(saddr.sun_path, pipe_fname, sizeof(saddr.sun_path));
+ saddr.sun_family = AF_UNIX;
- if (bind(sockfd, (struct sockaddr*)&sun, sizeof sun) == -1) {
+ if (bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr) == -1) {
/* On EADDRINUSE:
*
* We hold the file lock so there is no other process listening
*/
if (errno != EADDRINUSE
|| unlink(pipe_fname) == -1
- || bind(sockfd, (struct sockaddr*)&sun, sizeof sun) == -1) {
+ || bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr) == -1) {
/* Convert ENOENT to EACCES for compatibility with Windows. */
uv_err_new(handle->loop, (errno == ENOENT) ? EACCES : errno);
goto out;
uv_pipe_t* handle,
const char* name,
uv_connect_cb cb) {
- struct sockaddr_un sun;
+ struct sockaddr_un saddr;
int saved_errno;
int sockfd;
int status;
goto out;
}
- memset(&sun, 0, sizeof sun);
- uv__strlcpy(sun.sun_path, name, sizeof(sun.sun_path));
- sun.sun_family = AF_UNIX;
+ memset(&saddr, 0, sizeof saddr);
+ uv__strlcpy(saddr.sun_path, name, sizeof(saddr.sun_path));
+ saddr.sun_family = AF_UNIX;
/* We don't check for EINPROGRESS. Think about it: the socket
* is either there or not.
*/
do {
- r = connect(sockfd, (struct sockaddr*)&sun, sizeof sun);
+ r = connect(sockfd, (struct sockaddr*)&saddr, sizeof saddr);
}
while (r == -1 && errno == EINTR);
/* TODO merge with uv__server_io()? */
void uv__pipe_accept(EV_P_ ev_io* watcher, int revents) {
- struct sockaddr_un sun;
+ struct sockaddr_un saddr;
uv_pipe_t* pipe;
int saved_errno;
int sockfd;
assert(pipe->type == UV_NAMED_PIPE);
assert(pipe->pipe_fname != NULL);
- sockfd = uv__accept(pipe->fd, (struct sockaddr *)&sun, sizeof sun);
+ sockfd = uv__accept(pipe->fd, (struct sockaddr *)&saddr, sizeof saddr);
if (sockfd == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
assert(0 && "EAGAIN on uv__accept(pipefd)");
/* The only event loop we support right now */
static uv_loop_t uv_default_loop_;
-static int uv_default_loop_initialized_ = 0;
+
+/* uv_once intialization guards */
+static uv_once_t uv_init_guard_ = UV_ONCE_INIT;
+static uv_once_t uv_default_loop_init_guard_ = UV_ONCE_INIT;
+
+
+static void uv_init(void) {
+ /* Initialize winsock */
+ uv_winsock_init();
+
+ /* Fetch winapi function pointers */
+ uv_winapi_init();
+
+ /* Initialize FS */
+ uv_fs_init();
+}
static void uv_loop_init(uv_loop_t* loop) {
}
-uv_loop_t* uv_default_loop() {
- if (!uv_default_loop_initialized_) {
- uv_loop_init(&uv_default_loop_);
- uv_default_loop_initialized_ = 1;
- }
+static void uv_default_loop_init(void) {
+ /* Intialize libuv itself first */
+ uv_once(&uv_init_guard_, uv_init);
- return &uv_default_loop_;
+ /* Initialize the main loop */
+ uv_loop_init(&uv_default_loop_);
}
-void uv_init() {
- /* Initialize winsock */
- uv_winsock_init();
-
- /* Fetch winapi function pointers */
- uv_winapi_init();
-
- /* Initialize FS */
- uv_fs_init();
+uv_loop_t* uv_default_loop() {
+ uv_once(&uv_default_loop_init_guard_, uv_default_loop_init);
+ return &uv_default_loop_;
}
int uv_ntstatus_to_winsock_error(NTSTATUS status);
+/* Threads and synchronization */
+typedef struct uv_once_s {
+ unsigned char ran;
+ /* The actual event handle must be aligned to sizeof(HANDLE), so in */
+ /* practice it might overlap padding a little. */
+ HANDLE event;
+ HANDLE padding;
+} uv_once_t;
+
+#define UV_ONCE_INIT \
+ { 0, NULL, NULL }
+
+void uv_once(uv_once_t* guard, void (*callback)(void));
+
+
#endif /* UV_WIN_INTERNAL_H_ */
/* The resolution of the high-resolution clock. */
static int64_t uv_ticks_per_msec_ = 0;
static uint64_t uv_hrtime_frequency_ = 0;
-static char uv_hrtime_initialized_ = 0;
+static uv_once_t uv_hrtime_init_guard_ = UV_ONCE_INIT;
void uv_update_time(uv_loop_t* loop) {
return loop->time;
}
-/* TODO: thread safety */
-uint64_t uv_hrtime(void) {
- LARGE_INTEGER counter;
-
- /* When called for the first time, obtain the high-resolution clock */
- /* frequency. */
- if (!uv_hrtime_initialized_) {
- uv_hrtime_initialized_ = 1;
- if (!QueryPerformanceFrequency(&counter)) {
- uv_hrtime_frequency_ = 0;
- /* uv_set_sys_error(loop, GetLastError()); */
- return 0;
- }
+static void uv_hrtime_init(void) {
+ LARGE_INTEGER frequency;
- uv_hrtime_frequency_ = counter.QuadPart;
+ if (!QueryPerformanceFrequency(&frequency)) {
+ uv_hrtime_frequency_ = 0;
+ return;
}
+ uv_hrtime_frequency_ = frequency.QuadPart;
+}
+
+
+uint64_t uv_hrtime(void) {
+ LARGE_INTEGER counter;
+
+ uv_once(&uv_hrtime_init_guard_, uv_hrtime_init);
+
/* If the performance frequency is zero, there's no support. */
if (!uv_hrtime_frequency_) {
/* uv_set_sys_error(loop, ERROR_NOT_SUPPORTED); */
return 1;
}
- uv_init();
loop = uv_default_loop();
ares_callbacks = 0;
BENCHMARK_IMPL(getaddrinfo) {
int i;
- uv_init(loop);
loop = uv_default_loop();
uv_update_time(loop);
BENCHMARK_IMPL(ping_pongs) {
- uv_init();
loop = uv_default_loop();
start_time = uv_now(loop);
uint64_t start_time; /* in ns */
uint64_t end_time;
- uv_init();
loop = uv_default_loop();
uv_update_time(loop);
int r;
type = TCP;
- uv_init();
loop = uv_default_loop();
listen_addr = uv_ip4_addr("0.0.0.0", TEST_PORT);
int r;
type = PIPE;
- uv_init();
loop = uv_default_loop();
/* Server */
TARGET_CONNECTIONS = n;
type = TCP;
- uv_init();
loop = uv_default_loop();
connect_addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
TARGET_CONNECTIONS = n;
type = PIPE;
- uv_init();
loop = uv_default_loop();
/* Start making connections */
int r;
static int64_t start_time, end_time;
- uv_init();
loop = uv_default_loop();
r = uv_exepath(exepath, &exepath_size);
ASSERT(n_senders <= MAX_SENDERS);
ASSERT(n_receivers <= MAX_RECEIVERS);
- uv_init();
loop = uv_default_loop();
n_senders_ = n_senders;
HELPER_IMPL(dns_server) {
- uv_init();
loop = uv_default_loop();
if (dns_start(TEST_PORT_2))
HELPER_IMPL(tcp4_echo_server) {
- uv_init();
loop = uv_default_loop();
if (tcp4_echo_start(TEST_PORT))
HELPER_IMPL(tcp6_echo_server) {
- uv_init();
loop = uv_default_loop();
if (tcp6_echo_start(TEST_PORT))
HELPER_IMPL(pipe_echo_server) {
- uv_init();
loop = uv_default_loop();
if (pipe_echo_start(TEST_PIPENAME))
TEST_IMPL(async) {
int r;
- uv_init();
-
r = uv_prepare_init(uv_default_loop(), &prepare_handle);
ASSERT(r == 0);
r = uv_prepare_start(&prepare_handle, prepare_cb);
TEST_IMPL(callback_stack) {
struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
- uv_init();
-
if (uv_tcp_init(uv_default_loop(), &client)) {
FATAL("uv_tcp_init failed");
}
* expect an error.
*/
TEST_IMPL(connection_fail) {
- uv_init();
-
connection_fail(on_connect_with_close);
ASSERT(timer_close_cb_calls == 0);
* attempt.
*/
TEST_IMPL(connection_fail_doesnt_auto_close) {
- uv_init();
-
-
uv_timer_init(uv_default_loop(), &timer);
connection_fail(on_connect_without_close);
TEST_IMPL(delayed_accept) {
- uv_init();
-
start_server();
client_connect();
uv_fs_t req;
int r;
- uv_init();
loop = uv_default_loop();
r = uv_fs_open(loop, &req, "does_not_exist", O_RDONLY, 0, NULL);
unlink("test_file");
unlink("test_file2");
- uv_init();
loop = uv_default_loop();
r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT,
unlink("test_file");
unlink("test_file2");
- uv_init();
loop = uv_default_loop();
r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT,
unlink("test_dir/file2");
rmdir("test_dir");
- uv_init();
loop = uv_default_loop();
r = uv_fs_mkdir(loop, &mkdir_req, "test_dir", 0755, mkdir_cb);
struct stat s1, s2;
/* Setup. */
- uv_init();
unlink("test_file");
unlink("test_file2");
/* Setup. */
unlink("test_file");
- uv_init();
-
loop = uv_default_loop();
r = uv_fs_open(loop, &req, "test_file", O_RDWR | O_CREAT,
/* Setup. */
unlink("test_file");
- uv_init();
-
loop = uv_default_loop();
r = uv_fs_open(loop, &req, "test_file", O_RDWR | O_CREAT,
/* Setup. */
unlink("test_file");
- uv_init();
-
loop = uv_default_loop();
r = uv_fs_open(loop, &req, "test_file", O_RDWR | O_CREAT,
unlink("test_file_link");
unlink("test_file_link2");
- uv_init();
-
loop = uv_default_loop();
r = uv_fs_open(loop, &req, "test_file", O_RDWR | O_CREAT,
unlink("test_file_symlink_symlink");
unlink("test_file_symlink2_symlink");
- uv_init();
-
loop = uv_default_loop();
r = uv_fs_open(loop, &req, "test_file", O_RDWR | O_CREAT,
uv_fs_t req;
int r;
- uv_init();
loop = uv_default_loop();
atime = mtime = 400497753; /* 1982-09-10 11:22:33 */
uv_fs_t req;
int r;
- uv_init();
loop = uv_default_loop();
atime = mtime = 400497753; /* 1982-09-10 11:22:33 */
TEST_IMPL(getaddrinfo_basic) {
int r;
- uv_init();
-
-
r = uv_getaddrinfo(uv_default_loop(),
&getaddrinfo_handle,
&getaddrinfo_basic_cb,
int i, r;
int* data;
- uv_init();
-
for (i = 0; i < CONCURRENT_COUNT; i++) {
callback_counts[i] = 0;
return 1;
}
- uv_init();
-
printf("Start basic gethostbyname test\n");
prep_tcploopback();
TEST_IMPL(getsockname_tcp) {
- uv_init();
loop = uv_default_loop();
if (tcp_listener())
TEST_IMPL(getsockname_udp) {
- uv_init();
loop = uv_default_loop();
if (udp_listener())
TEST_IMPL(idle_starvation) {
int r;
- uv_init();
-
-
r = uv_idle_init(uv_default_loop(), &idle_handle);
ASSERT(r == 0);
r = uv_idle_start(&idle_handle, idle_cb);
int i;
int r;
- uv_init();
-
-
r = uv_prepare_init(uv_default_loop(), &prepare_1_handle);
ASSERT(r == 0);
r = uv_prepare_start(&prepare_1_handle, prepare_1_cb);
TEST_IMPL(tcp_ping_pong) {
- uv_init();
-
tcp_pinger_new();
uv_run(uv_default_loop());
TEST_IMPL(tcp_ping_pong_v6) {
- uv_init();
-
tcp_pinger_v6_new();
uv_run(uv_default_loop());
TEST_IMPL(pipe_ping_pong) {
- uv_init();
-
pipe_pinger_new();
uv_run(uv_default_loop());
uv_pipe_t server1, server2;
int r;
- uv_init();
-
-
r = uv_pipe_init(uv_default_loop(), &server1);
ASSERT(r == 0);
r = uv_pipe_bind(&server1, TEST_PIPENAME);
uv_pipe_t server;
int r;
- uv_init();
-
-
r = uv_pipe_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_pipe_bind(&server, BAD_PIPENAME);
uv_pipe_t server;
int r;
- uv_init();
-
-
r = uv_pipe_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_pipe_bind(&server, TEST_PIPENAME);
uv_pipe_t server;
int r;
- uv_init();
-
-
r = uv_pipe_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_listen((uv_stream_t*)&server, SOMAXCONN, NULL);
TEST_IMPL(ref) {
- uv_init();
uv_run(uv_default_loop());
return 0;
}
TEST_IMPL(idle_ref) {
uv_idle_t h;
- uv_init();
uv_idle_init(uv_default_loop(), &h);
uv_idle_start(&h, NULL);
uv_unref(uv_default_loop());
TEST_IMPL(async_ref) {
uv_async_t h;
- uv_init();
uv_async_init(uv_default_loop(), &h, NULL);
uv_unref(uv_default_loop());
uv_run(uv_default_loop());
TEST_IMPL(prepare_ref) {
uv_prepare_t h;
- uv_init();
uv_prepare_init(uv_default_loop(), &h);
uv_prepare_start(&h, NULL);
uv_unref(uv_default_loop());
TEST_IMPL(check_ref) {
uv_check_t h;
- uv_init();
uv_check_init(uv_default_loop(), &h);
uv_check_start(&h, NULL);
uv_unref(uv_default_loop());
TEST_IMPL(unref_in_prepare_cb) {
uv_prepare_t h;
- uv_init();
-
uv_prepare_init(uv_default_loop(), &h);
uv_prepare_start(&h, prepare_cb);
uv_run(uv_default_loop());
struct sockaddr_in server_addr;
int r;
- uv_init();
-
qbuf.base = "Q";
qbuf.len = 1;
TEST_IMPL(spawn_exit_code) {
int r;
- uv_init();
-
init_process_options("spawn_helper1", exit_cb);
r = uv_spawn(uv_default_loop(), &process, options);
int r;
uv_pipe_t out;
- uv_init();
-
init_process_options("spawn_helper2", exit_cb);
uv_pipe_init(uv_default_loop(), &out);
uv_buf_t buf;
char buffer[] = "hello-from-spawn_stdin";
- uv_init();
-
init_process_options("spawn_helper3", exit_cb);
uv_pipe_init(uv_default_loop(), &out);
TEST_IMPL(spawn_and_kill) {
int r;
- uv_init();
-
init_process_options("spawn_helper4", kill_cb);
r = uv_spawn(uv_default_loop(), &process, options);
char name[64];
HANDLE pipe_handle;
- uv_init();
-
init_process_options("spawn_helper2", exit_cb);
uv_pipe_init(uv_default_loop(), &out);
uv_tcp_t server1, server2;
int r;
- uv_init();
-
-
r = uv_tcp_init(uv_default_loop(), &server1);
ASSERT(r == 0);
r = uv_tcp_bind(&server1, addr);
uv_tcp_t server;
int r;
- uv_init();
-
-
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_tcp_bind(&server, addr);
uv_tcp_t server;
int r;
- uv_init();
-
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_tcp_bind(&server, addr);
garbage_addr = (struct sockaddr_in*) &garbage;
- uv_init();
-
-
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_tcp_bind(&server, *garbage_addr);
uv_tcp_t server;
int r;
- uv_init();
-
-
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_tcp_bind(&server, addr1);
uv_tcp_t server;
int r;
- uv_init();
-
-
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_tcp_bind(&server, addr);
int r;
uv_tcp_t server;
- uv_init();
-
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_listen((uv_stream_t*)&server, 128, NULL);
uv_tcp_t server1, server2;
int r;
- uv_init();
-
-
r = uv_tcp_init(uv_default_loop(), &server1);
ASSERT(r == 0);
r = uv_tcp_bind6(&server1, addr);
uv_tcp_t server;
int r;
- uv_init();
-
-
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_tcp_bind6(&server, addr);
garbage_addr = (struct sockaddr_in6*) &garbage;
- uv_init();
-
-
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_tcp_bind6(&server, *garbage_addr);
uv_tcp_t server;
int r;
- uv_init();
-
-
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_tcp_bind6(&server, addr1);
uv_tcp_t server;
int r;
- uv_init();
-
-
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_tcp_bind6(&server, addr);
ASSERT(send_buffer != NULL);
- uv_init();
-
-
r = uv_tcp_init(uv_default_loop(), client);
ASSERT(r == 0);
TEST_IMPL(threadpool_queue_work_simple) {
int r;
- uv_init();
-
work_req.data = &data;
r = uv_queue_work(uv_default_loop(), &work_req, work_cb, after_work_cb);
ASSERT(r == 0);
TEST_IMPL(timer_again) {
int r;
- uv_init();
-
-
start_time = uv_now(uv_default_loop());
ASSERT(0 < start_time);
uv_timer_t repeat, never;
int i, r;
- uv_init();
-
start_time = uv_now(uv_default_loop());
ASSERT(0 < start_time);
memset(dgram, 42, sizeof dgram); /* silence valgrind */
- uv_init();
-
r = uv_udp_init(uv_default_loop(), &handle_);
ASSERT(r == 0);
uv_buf_t buf;
int r;
- uv_init();
-
addr6 = uv_ip6_addr("::0", TEST_PORT);
r = uv_udp_init(uv_default_loop(), &server);
addr = uv_ip4_addr("0.0.0.0", TEST_PORT);
- uv_init();
-
r = uv_udp_init(uv_default_loop(), &server);
ASSERT(r == 0);
'src/win/stream.c',
'src/win/tcp.c',
'src/win/threadpool.c',
+ 'src/win/threads.c',
'src/win/timer.c',
'src/win/udp.c',
'src/win/util.c',
'libraries': [ '-lrt' ],
},
}],
- # TODO add OS=='sun'
+ [ 'OS=="solaris"', {
+ 'include_dirs': [ 'src/ares/config_sunos' ],
+ 'sources': [ 'src/unix/sunos.c' ],
+ 'defines': [
+ '__EXTENSIONS__',
+ '_XOPEN_SOURCE=500',
+ 'EV_CONFIG_H="config_sunos.h"',
+ 'EIO_CONFIG_H="config_sunos.h"',
+ ],
+ 'direct_dependent_settings': {
+ 'libraries': [ '-lrt' ],
+ },
+ }],
]
},
pthread_win32_process_attach_np();
#endif
- uv_init();
-
// This needs to run *before* V8::Initialize()
argv = Init(argc, argv);