Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

upgrade libuv to e1bee05ecdbffbe9de37830530ad2ae2f1fb41c8

  • Loading branch information...
Igor Zinkovsky
Igor Zinkovsky committed Nov 2, 2011
1 parent 850609e commit 143aeb9ea716b1af0baeb700903961612b457143
@@ -983,6 +983,10 @@ UV_EXTERN int uv_spawn(uv_loop_t*, uv_process_t*,
UV_EXTERN int uv_process_kill(uv_process_t*, int signum);


/* Kills the process with the specified signal. */
UV_EXTERN uv_err_t uv_kill(int pid, int signum);


/*
* uv_work_t is a subclass of uv_req_t
*/
@@ -26,8 +26,6 @@
#include <errno.h>


static const uv_err_t uv_ok_ = { UV_OK, 0 };

uv_err_t uv_dlopen(const char* filename, uv_lib_t* library) {
void* handle = dlopen(filename, RTLD_LAZY);
if (handle == NULL) {
@@ -61,6 +61,7 @@ static int uv__translate_lib_error(int code) {
case UV_ENOSYS: return ENOSYS;
case UV_ENOENT: return ENOENT;
case UV_EACCESS: return EACCES;
case UV_EAFNOSUPPORT: return EAFNOSUPPORT;
case UV_EBADF: return EBADF;
case UV_EPIPE: return EPIPE;
case UV_EAGAIN: return EAGAIN;
@@ -90,6 +91,7 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
case ENOSYS: return UV_ENOSYS;
case ENOENT: return UV_ENOENT;
case EACCES: return UV_EACCESS;
case EAFNOSUPPORT: return UV_EAFNOSUPPORT;
case EBADF: return UV_EBADF;
case EPIPE: return UV_EPIPE;
case EAGAIN: return UV_EAGAIN;
@@ -300,3 +300,14 @@ int uv_process_kill(uv_process_t* process, int signum) {
return 0;
}
}


uv_err_t uv_kill(int pid, int signum) {
int r = kill(pid, signum);

if (r) {
return uv__new_sys_error(errno);
} else {
return uv_ok_;
}
}
@@ -62,6 +62,7 @@ void uv__stream_init(uv_loop_t* loop,
stream->accepted_fd = -1;
stream->fd = -1;
stream->delayed_error = 0;
stream->blocking = 0;
ngx_queue_init(&stream->write_queue);
ngx_queue_init(&stream->write_completed_queue);
stream->write_queue_size = 0;
@@ -340,9 +341,9 @@ static void uv__write(uv_stream_t* stream) {
int iovcnt;
ssize_t n;

assert(stream->fd >= 0);
start:

/* TODO: should probably while(1) here until EAGAIN */
assert(stream->fd >= 0);

/* Get the request at the head of the queue. */
req = uv_write_queue_head(stream);
@@ -353,14 +354,16 @@ static void uv__write(uv_stream_t* stream) {

assert(req->handle == stream);

/* Cast to iovec. We had to have our own uv_buf_t instead of iovec
/*
* Cast to iovec. We had to have our own uv_buf_t instead of iovec
* because Windows's WSABUF is not an iovec.
*/
assert(sizeof(uv_buf_t) == sizeof(struct iovec));
iov = (struct iovec*) &(req->bufs[req->write_index]);
iovcnt = req->bufcnt - req->write_index;

/* Now do the actual writev. Note that we've been updating the pointers
/*
* Now do the actual writev. Note that we've been updating the pointers
* inside the iov each time we write. So there is no need to offset it.
*/

@@ -409,6 +412,9 @@ static void uv__write(uv_stream_t* stream) {
stream->write_queue_size -= uv__write_req_size(req);
uv__write_req_finish(req);
return;
} else if (stream->blocking) {
/* If this is a blocking stream, try again. */
goto start;
}
} else {
/* Successful write */
@@ -426,8 +432,17 @@ static void uv__write(uv_stream_t* stream) {
stream->write_queue_size -= n;
n = 0;

/* There is more to write. Break and ensure the watcher is pending. */
break;
/* There is more to write. */
if (stream->blocking) {
/*
* If we're blocking then we should not be enabling the write
* watcher - instead we need to try again.
*/
goto start;
} else {
/* Break loop and ensure the watcher is pending. */
break;
}

} else {
/* Finished writing the buf at index req->write_index. */
@@ -453,6 +468,9 @@ static void uv__write(uv_stream_t* stream) {
/* Either we've counted n down to zero or we've got EAGAIN. */
assert(n == 0 || n == -1);

/* Only non-blocking streams should use the write_watcher. */
assert(!stream->blocking);

/* We're not done. */
ev_io_start(stream->loop->ev, &stream->write_watcher);
}
@@ -862,6 +880,13 @@ int uv_write2(uv_write_t* req, uv_stream_t* stream, uv_buf_t bufs[], int bufcnt,
if (empty_queue) {
uv__write(stream);
} else {
/*
* blocking streams should never have anything in the queue.
* if this assert fires then somehow the blocking stream isn't being
* sufficently flushed in uv__write.
*/
assert(!stream->blocking);

ev_io_start(stream->loop->ev, &stream->write_watcher);
}

@@ -41,7 +41,6 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
uv__stream_open((uv_stream_t*)tty, fd, UV_READABLE);
} else {
/* Note: writable tty we set to blocking mode. */
uv__nonblock(fd, 0);
uv__stream_open((uv_stream_t*)tty, fd, UV_WRITABLE);
tty->blocking = 1;
}
@@ -48,6 +48,9 @@ uv_buf_t uv_buf_init(char* base, size_t len) {
}


const uv_err_t uv_ok_ = { UV_OK, 0 };


const char* uv_err_name(uv_err_t err) {
switch (err.code) {
case UV_UNKNOWN: return "UNKNOWN";
@@ -48,6 +48,8 @@ void uv_add_ares_handle(uv_loop_t* loop, uv_ares_task_t* handle);

int uv_ares_handles_empty(uv_loop_t* loop);

extern const uv_err_t uv_ok_;

uv_err_code uv_translate_sys_error(int sys_errno);
void uv__set_error(uv_loop_t* loop, uv_err_code code, int sys_error);
void uv__set_sys_error(uv_loop_t* loop, int sys_error);
@@ -40,6 +40,10 @@ static uv_once_t uv_default_loop_init_guard_ = UV_ONCE_INIT;


static void uv_init(void) {
/* Tell Windows that we will handle critical errors. */
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
SEM_NOOPENFILEERRORBOX);

/* Initialize winsock */
uv_winsock_init();

@@ -30,9 +30,6 @@
#include "internal.h"


const uv_err_t uv_ok_ = { UV_OK, ERROR_SUCCESS };


/*
* Display an error message and abort the event loop.
*/
@@ -286,11 +286,6 @@ void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle);
int uv_parent_pid();


/*
* Error handling
*/
extern const uv_err_t uv_ok_;

void uv_fatal_error(const int errorno, const char* syscall);

uv_err_code uv_translate_sys_error(int sys_errno);
@@ -26,8 +26,11 @@
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <signal.h>
#include <windows.h>

#define SIGKILL 9

typedef struct env_var {
const char* narrow;
const wchar_t* wide;
@@ -1052,35 +1055,65 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
}


int uv_process_kill(uv_process_t* process, int signum) {
static uv_err_t uv__kill(HANDLE process_handle, int signum) {
DWORD status;
uv_err_t err;

if (signum == SIGTERM || signum == SIGKILL) {
/* Kill the process. On Windows, killed processes normally return 1. */
if (TerminateProcess(process_handle, 1)) {
err = uv_ok_;
} else {
err = uv__new_sys_error(GetLastError());
}
} else if (signum == 0) {
/* Health check: is the process still alive? */
if (GetExitCodeProcess(process_handle, &status) &&
status == STILL_ACTIVE) {
err = uv_ok_;
} else {
err = uv__new_sys_error(GetLastError());
}
} else {
err.code = UV_ENOSYS;
}

return err;
}


int uv_process_kill(uv_process_t* process, int signum) {
uv_err_t err;

if (process->process_handle == INVALID_HANDLE_VALUE) {
uv__set_artificial_error(process->loop, UV_EINVAL);
return -1;
}

if (signum) {
/* Kill the process. On Windows, killed processes normally return 1. */
if (TerminateProcess(process->process_handle, 1)) {
process->exit_signal = signum;
return 0;
}
else {
uv__set_sys_error(process->loop, GetLastError());
return -1;
}
err = uv__kill(process->process_handle, signum);

if (err.code != UV_OK) {
uv__set_error(process->loop, err.code, err.sys_errno_);
return -1;
}
else {
/* Health check: is the process still alive? */
if (GetExitCodeProcess(process->process_handle, &status) && status == STILL_ACTIVE) {
return 0;
}
else {
uv__set_artificial_error(process->loop, UV_EINVAL);
return -1;
}

process->exit_signal = signum;

return 0;
}


uv_err_t uv_kill(int pid, int signum) {
uv_err_t err;
HANDLE process_handle = OpenProcess(PROCESS_TERMINATE |
PROCESS_QUERY_INFORMATION, FALSE, pid);

if (process_handle == INVALID_HANDLE_VALUE) {
return uv__new_sys_error(GetLastError());
}

assert(0 && "unreachable");
err = uv__kill(process_handle, signum);
CloseHandle(process_handle);

return err;
}
@@ -89,6 +89,7 @@ TEST_DECLARE (spawn_stdout)
TEST_DECLARE (spawn_stdin)
TEST_DECLARE (spawn_and_kill)
TEST_DECLARE (spawn_and_ping)
TEST_DECLARE (kill)
TEST_DECLARE (fs_file_noent)
TEST_DECLARE (fs_file_async)
TEST_DECLARE (fs_file_sync)
@@ -227,6 +228,7 @@ TASK_LIST_START
TEST_ENTRY (spawn_stdin)
TEST_ENTRY (spawn_and_kill)
TEST_ENTRY (spawn_and_ping)
TEST_ENTRY (kill)
#ifdef _WIN32
TEST_ENTRY (spawn_detect_pipe_name_collisions_on_windows)
TEST_ENTRY (argument_escaping)
@@ -33,6 +33,7 @@ static uv_process_options_t options;
static char exepath[1024];
static size_t exepath_size = 1024;
static char* args[3];
static int no_term_signal;

#define OUTPUT_SIZE 1024
static char output[OUTPUT_SIZE];
@@ -55,15 +56,23 @@ static void exit_cb(uv_process_t* process, int exit_status, int term_signal) {


static void kill_cb(uv_process_t* process, int exit_status, int term_signal) {
uv_err_t err;

printf("exit_cb\n");
exit_cb_called++;
#ifdef _WIN32
ASSERT(exit_status == 1);
#else
ASSERT(exit_status == 0);
#endif
ASSERT(term_signal == 15);
ASSERT(no_term_signal || term_signal == 15);
uv_close((uv_handle_t*)process, close_cb);

/* Sending signum == 0 should check if the
* child process is still alive, not kill it.
*/
err = uv_kill(process->pid, 0);
ASSERT(err.code != UV_OK);
}


@@ -261,6 +270,39 @@ TEST_IMPL(spawn_and_ping) {
}


TEST_IMPL(kill) {
int r;
uv_err_t err;

#ifdef _WIN32
no_term_signal = 1;
#endif

init_process_options("spawn_helper4", kill_cb);

r = uv_spawn(uv_default_loop(), &process, options);
ASSERT(r == 0);

/* Sending signum == 0 should check if the
* child process is still alive, not kill it.
*/
err = uv_kill(process.pid, 0);
ASSERT(err.code == UV_OK);

/* Kill the process. */
err = uv_kill(process.pid, /* SIGTERM */ 15);
ASSERT(err.code == UV_OK);

r = uv_run(uv_default_loop());
ASSERT(r == 0);

ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 1);

return 0;
}


#ifdef _WIN32
TEST_IMPL(spawn_detect_pipe_name_collisions_on_windows) {
int r;

0 comments on commit 143aeb9

Please sign in to comment.
You can’t perform that action at this time.