libuv 2016-09-27 (8221f9b3)
Code extracted from: https://github.com/libuv/libuv.git at commit 8221f9b305c09205be575d8d34a5c493ba03d392 (v1.x).
This commit is contained in:
parent
3a713eaaf7
commit
66ac1febc4
|
@ -346,22 +346,30 @@ done:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(__OpenBSD__) || (defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_8))
|
#if defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_8)
|
||||||
static int uv__fs_scandir_filter(uv__dirent_t* dent) {
|
#define UV_CONST_DIRENT uv__dirent_t
|
||||||
#else
|
#else
|
||||||
static int uv__fs_scandir_filter(const uv__dirent_t* dent) {
|
#define UV_CONST_DIRENT const uv__dirent_t
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static int uv__fs_scandir_filter(UV_CONST_DIRENT* dent) {
|
||||||
return strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0;
|
return strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int uv__fs_scandir_sort(UV_CONST_DIRENT** a, UV_CONST_DIRENT** b) {
|
||||||
|
return strcmp((*a)->d_name, (*b)->d_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static ssize_t uv__fs_scandir(uv_fs_t* req) {
|
static ssize_t uv__fs_scandir(uv_fs_t* req) {
|
||||||
uv__dirent_t **dents;
|
uv__dirent_t **dents;
|
||||||
int saved_errno;
|
int saved_errno;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
dents = NULL;
|
dents = NULL;
|
||||||
n = scandir(req->path, &dents, uv__fs_scandir_filter, alphasort);
|
n = scandir(req->path, &dents, uv__fs_scandir_filter, uv__fs_scandir_sort);
|
||||||
|
|
||||||
/* NOTE: We will use nbufs as an index field */
|
/* NOTE: We will use nbufs as an index field */
|
||||||
req->nbufs = 0;
|
req->nbufs = 0;
|
||||||
|
@ -790,6 +798,7 @@ static void uv__to_stat(struct stat* src, uv_stat_t* dst) {
|
||||||
dst->st_flags = 0;
|
dst->st_flags = 0;
|
||||||
dst->st_gen = 0;
|
dst->st_gen = 0;
|
||||||
#elif !defined(_AIX) && ( \
|
#elif !defined(_AIX) && ( \
|
||||||
|
defined(_GNU_SOURCE) || \
|
||||||
defined(_BSD_SOURCE) || \
|
defined(_BSD_SOURCE) || \
|
||||||
defined(_SVID_SOURCE) || \
|
defined(_SVID_SOURCE) || \
|
||||||
defined(_XOPEN_SOURCE) || \
|
defined(_XOPEN_SOURCE) || \
|
||||||
|
|
|
@ -230,6 +230,7 @@ INLINE static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req,
|
||||||
req->ptr = NULL;
|
req->ptr = NULL;
|
||||||
req->path = NULL;
|
req->path = NULL;
|
||||||
req->cb = cb;
|
req->cb = cb;
|
||||||
|
memset(&req->fs, 0, sizeof(req->fs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1893,9 +1894,13 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
|
||||||
uv__free(req->ptr);
|
uv__free(req->ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (req->fs.info.bufs != req->fs.info.bufsml)
|
||||||
|
uv__free(req->fs.info.bufs);
|
||||||
|
|
||||||
req->path = NULL;
|
req->path = NULL;
|
||||||
req->file.pathw = NULL;
|
req->file.pathw = NULL;
|
||||||
req->fs.info.new_pathw = NULL;
|
req->fs.info.new_pathw = NULL;
|
||||||
|
req->fs.info.bufs = NULL;
|
||||||
req->ptr = NULL;
|
req->ptr = NULL;
|
||||||
|
|
||||||
req->flags |= UV_FS_CLEANEDUP;
|
req->flags |= UV_FS_CLEANEDUP;
|
||||||
|
|
|
@ -111,7 +111,11 @@ static int uv_tty_virtual_offset = -1;
|
||||||
static int uv_tty_virtual_height = -1;
|
static int uv_tty_virtual_height = -1;
|
||||||
static int uv_tty_virtual_width = -1;
|
static int uv_tty_virtual_width = -1;
|
||||||
|
|
||||||
static CRITICAL_SECTION uv_tty_output_lock;
|
/* We use a semaphore rather than a mutex or critical section because in some
|
||||||
|
cases (uv__cancel_read_console) we need take the lock in the main thread and
|
||||||
|
release it in another thread. Using a semaphore ensures that in such
|
||||||
|
scenario the main thread will still block when trying to acquire the lock. */
|
||||||
|
static uv_sem_t uv_tty_output_lock;
|
||||||
|
|
||||||
static HANDLE uv_tty_output_handle = INVALID_HANDLE_VALUE;
|
static HANDLE uv_tty_output_handle = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
|
@ -134,7 +138,8 @@ static uv_vtermstate_t uv__vterm_state = UV_UNCHECKED;
|
||||||
static void uv__determine_vterm_state(HANDLE handle);
|
static void uv__determine_vterm_state(HANDLE handle);
|
||||||
|
|
||||||
void uv_console_init() {
|
void uv_console_init() {
|
||||||
InitializeCriticalSection(&uv_tty_output_lock);
|
if (uv_sem_init(&uv_tty_output_lock, 1))
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -172,7 +177,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
|
||||||
|
|
||||||
/* Obtain the the tty_output_lock because the virtual window state is */
|
/* Obtain the the tty_output_lock because the virtual window state is */
|
||||||
/* shared between all uv_tty_t handles. */
|
/* shared between all uv_tty_t handles. */
|
||||||
EnterCriticalSection(&uv_tty_output_lock);
|
uv_sem_wait(&uv_tty_output_lock);
|
||||||
|
|
||||||
if (uv__vterm_state == UV_UNCHECKED)
|
if (uv__vterm_state == UV_UNCHECKED)
|
||||||
uv__determine_vterm_state(handle);
|
uv__determine_vterm_state(handle);
|
||||||
|
@ -187,7 +192,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
|
||||||
|
|
||||||
uv_tty_update_virtual_window(&screen_buffer_info);
|
uv_tty_update_virtual_window(&screen_buffer_info);
|
||||||
|
|
||||||
LeaveCriticalSection(&uv_tty_output_lock);
|
uv_sem_post(&uv_tty_output_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -315,10 +320,6 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
|
||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SetConsoleMode(tty->handle, flags)) {
|
|
||||||
return uv_translate_sys_error(GetLastError());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If currently reading, stop, and restart reading. */
|
/* If currently reading, stop, and restart reading. */
|
||||||
if (tty->flags & UV_HANDLE_READING) {
|
if (tty->flags & UV_HANDLE_READING) {
|
||||||
was_reading = 1;
|
was_reading = 1;
|
||||||
|
@ -332,6 +333,14 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
|
||||||
was_reading = 0;
|
was_reading = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uv_sem_wait(&uv_tty_output_lock);
|
||||||
|
if (!SetConsoleMode(tty->handle, flags)) {
|
||||||
|
err = uv_translate_sys_error(GetLastError());
|
||||||
|
uv_sem_post(&uv_tty_output_lock);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
uv_sem_post(&uv_tty_output_lock);
|
||||||
|
|
||||||
/* Update flag. */
|
/* Update flag. */
|
||||||
tty->flags &= ~UV_HANDLE_TTY_RAW;
|
tty->flags &= ~UV_HANDLE_TTY_RAW;
|
||||||
tty->flags |= mode ? UV_HANDLE_TTY_RAW : 0;
|
tty->flags |= mode ? UV_HANDLE_TTY_RAW : 0;
|
||||||
|
@ -361,9 +370,9 @@ int uv_tty_get_winsize(uv_tty_t* tty, int* width, int* height) {
|
||||||
return uv_translate_sys_error(GetLastError());
|
return uv_translate_sys_error(GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
EnterCriticalSection(&uv_tty_output_lock);
|
uv_sem_wait(&uv_tty_output_lock);
|
||||||
uv_tty_update_virtual_window(&info);
|
uv_tty_update_virtual_window(&info);
|
||||||
LeaveCriticalSection(&uv_tty_output_lock);
|
uv_sem_post(&uv_tty_output_lock);
|
||||||
|
|
||||||
*width = uv_tty_virtual_width;
|
*width = uv_tty_virtual_width;
|
||||||
*height = uv_tty_virtual_height;
|
*height = uv_tty_virtual_height;
|
||||||
|
@ -432,6 +441,7 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
|
||||||
DWORD chars, read_chars;
|
DWORD chars, read_chars;
|
||||||
LONG status;
|
LONG status;
|
||||||
COORD pos;
|
COORD pos;
|
||||||
|
BOOL read_console_success;
|
||||||
|
|
||||||
assert(data);
|
assert(data);
|
||||||
|
|
||||||
|
@ -461,11 +471,13 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ReadConsoleW(handle->handle,
|
read_console_success = ReadConsoleW(handle->handle,
|
||||||
(void*) utf16,
|
(void*) utf16,
|
||||||
chars,
|
chars,
|
||||||
&read_chars,
|
&read_chars,
|
||||||
NULL)) {
|
NULL);
|
||||||
|
|
||||||
|
if (read_console_success) {
|
||||||
read_bytes = WideCharToMultiByte(CP_UTF8,
|
read_bytes = WideCharToMultiByte(CP_UTF8,
|
||||||
0,
|
0,
|
||||||
utf16,
|
utf16,
|
||||||
|
@ -480,33 +492,36 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
|
||||||
SET_REQ_ERROR(req, GetLastError());
|
SET_REQ_ERROR(req, GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
InterlockedExchange(&uv__read_console_status, COMPLETED);
|
status = InterlockedExchange(&uv__read_console_status, COMPLETED);
|
||||||
|
|
||||||
/* If we canceled the read by sending a VK_RETURN event, restore the screen
|
if (status == TRAP_REQUESTED) {
|
||||||
state to undo the visual effect of the VK_RETURN*/
|
/* If we canceled the read by sending a VK_RETURN event, restore the
|
||||||
if (InterlockedOr(&uv__restore_screen_state, 0)) {
|
screen state to undo the visual effect of the VK_RETURN */
|
||||||
HANDLE active_screen_buffer = CreateFileA("conout$",
|
if (read_console_success && InterlockedOr(&uv__restore_screen_state, 0)) {
|
||||||
|
HANDLE active_screen_buffer;
|
||||||
|
active_screen_buffer = CreateFileA("conout$",
|
||||||
GENERIC_READ | GENERIC_WRITE,
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
NULL,
|
NULL,
|
||||||
OPEN_EXISTING,
|
OPEN_EXISTING,
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
NULL);
|
NULL);
|
||||||
if (active_screen_buffer != INVALID_HANDLE_VALUE) {
|
if (active_screen_buffer != INVALID_HANDLE_VALUE) {
|
||||||
pos = uv__saved_screen_state.dwCursorPosition;
|
pos = uv__saved_screen_state.dwCursorPosition;
|
||||||
|
|
||||||
/* If the cursor was at the bottom line of the screen buffer, the
|
/* If the cursor was at the bottom line of the screen buffer, the
|
||||||
VK_RETURN would have caused the buffer contents to scroll up by
|
VK_RETURN would have caused the buffer contents to scroll up by one
|
||||||
one line. The right position to reset the cursor to is therefore one
|
line. The right position to reset the cursor to is therefore one line
|
||||||
line higher */
|
higher */
|
||||||
if (pos.Y == uv__saved_screen_state.dwSize.Y - 1)
|
if (pos.Y == uv__saved_screen_state.dwSize.Y - 1)
|
||||||
pos.Y--;
|
pos.Y--;
|
||||||
|
|
||||||
SetConsoleCursorPosition(active_screen_buffer, pos);
|
SetConsoleCursorPosition(active_screen_buffer, pos);
|
||||||
CloseHandle(active_screen_buffer);
|
CloseHandle(active_screen_buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
uv_sem_post(&uv_tty_output_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
POST_COMPLETION_FOR_REQ(loop, req);
|
POST_COMPLETION_FOR_REQ(loop, req);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -694,14 +709,14 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
|
||||||
if (handle->tty.rd.last_input_record.EventType == WINDOW_BUFFER_SIZE_EVENT) {
|
if (handle->tty.rd.last_input_record.EventType == WINDOW_BUFFER_SIZE_EVENT) {
|
||||||
CONSOLE_SCREEN_BUFFER_INFO info;
|
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||||
|
|
||||||
EnterCriticalSection(&uv_tty_output_lock);
|
uv_sem_wait(&uv_tty_output_lock);
|
||||||
|
|
||||||
if (uv_tty_output_handle != INVALID_HANDLE_VALUE &&
|
if (uv_tty_output_handle != INVALID_HANDLE_VALUE &&
|
||||||
GetConsoleScreenBufferInfo(uv_tty_output_handle, &info)) {
|
GetConsoleScreenBufferInfo(uv_tty_output_handle, &info)) {
|
||||||
uv_tty_update_virtual_window(&info);
|
uv_tty_update_virtual_window(&info);
|
||||||
}
|
}
|
||||||
|
|
||||||
LeaveCriticalSection(&uv_tty_output_lock);
|
uv_sem_post(&uv_tty_output_lock);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1035,11 +1050,16 @@ static int uv__cancel_read_console(uv_tty_t* handle) {
|
||||||
|
|
||||||
assert(!(handle->flags & UV_HANDLE_CANCELLATION_PENDING));
|
assert(!(handle->flags & UV_HANDLE_CANCELLATION_PENDING));
|
||||||
|
|
||||||
|
/* Hold the output lock during the cancellation, to ensure that further
|
||||||
|
writes don't interfere with the screen state. It will be the ReadConsole
|
||||||
|
thread's responsibility to release the lock. */
|
||||||
|
uv_sem_wait(&uv_tty_output_lock);
|
||||||
status = InterlockedExchange(&uv__read_console_status, TRAP_REQUESTED);
|
status = InterlockedExchange(&uv__read_console_status, TRAP_REQUESTED);
|
||||||
if (status != IN_PROGRESS) {
|
if (status != IN_PROGRESS) {
|
||||||
/* Either we have managed to set a trap for the other thread before
|
/* Either we have managed to set a trap for the other thread before
|
||||||
ReadConsole is called, or ReadConsole has returned because the user
|
ReadConsole is called, or ReadConsole has returned because the user
|
||||||
has pressed ENTER. In either case, there is nothing else to do. */
|
has pressed ENTER. In either case, there is nothing else to do. */
|
||||||
|
uv_sem_post(&uv_tty_output_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1624,7 +1644,7 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
|
||||||
/* state. */
|
/* state. */
|
||||||
*error = ERROR_SUCCESS;
|
*error = ERROR_SUCCESS;
|
||||||
|
|
||||||
EnterCriticalSection(&uv_tty_output_lock);
|
uv_sem_wait(&uv_tty_output_lock);
|
||||||
|
|
||||||
for (i = 0; i < nbufs; i++) {
|
for (i = 0; i < nbufs; i++) {
|
||||||
uv_buf_t buf = bufs[i];
|
uv_buf_t buf = bufs[i];
|
||||||
|
@ -2061,7 +2081,7 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
|
||||||
handle->tty.wr.previous_eol = previous_eol;
|
handle->tty.wr.previous_eol = previous_eol;
|
||||||
handle->tty.wr.ansi_parser_state = ansi_parser_state;
|
handle->tty.wr.ansi_parser_state = ansi_parser_state;
|
||||||
|
|
||||||
LeaveCriticalSection(&uv_tty_output_lock);
|
uv_sem_post(&uv_tty_output_lock);
|
||||||
|
|
||||||
if (*error == STATUS_SUCCESS) {
|
if (*error == STATUS_SUCCESS) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1078,6 +1078,7 @@ int uv_getrusage(uv_rusage_t *uv_rusage) {
|
||||||
FILETIME createTime, exitTime, kernelTime, userTime;
|
FILETIME createTime, exitTime, kernelTime, userTime;
|
||||||
SYSTEMTIME kernelSystemTime, userSystemTime;
|
SYSTEMTIME kernelSystemTime, userSystemTime;
|
||||||
PROCESS_MEMORY_COUNTERS memCounters;
|
PROCESS_MEMORY_COUNTERS memCounters;
|
||||||
|
IO_COUNTERS ioCounters;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &kernelTime, &userTime);
|
ret = GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &kernelTime, &userTime);
|
||||||
|
@ -1102,6 +1103,11 @@ int uv_getrusage(uv_rusage_t *uv_rusage) {
|
||||||
return uv_translate_sys_error(GetLastError());
|
return uv_translate_sys_error(GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = GetProcessIoCounters(GetCurrentProcess(), &ioCounters);
|
||||||
|
if (ret == 0) {
|
||||||
|
return uv_translate_sys_error(GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
memset(uv_rusage, 0, sizeof(*uv_rusage));
|
memset(uv_rusage, 0, sizeof(*uv_rusage));
|
||||||
|
|
||||||
uv_rusage->ru_utime.tv_sec = userSystemTime.wHour * 3600 +
|
uv_rusage->ru_utime.tv_sec = userSystemTime.wHour * 3600 +
|
||||||
|
@ -1117,6 +1123,9 @@ int uv_getrusage(uv_rusage_t *uv_rusage) {
|
||||||
uv_rusage->ru_majflt = (uint64_t) memCounters.PageFaultCount;
|
uv_rusage->ru_majflt = (uint64_t) memCounters.PageFaultCount;
|
||||||
uv_rusage->ru_maxrss = (uint64_t) memCounters.PeakWorkingSetSize / 1024;
|
uv_rusage->ru_maxrss = (uint64_t) memCounters.PeakWorkingSetSize / 1024;
|
||||||
|
|
||||||
|
uv_rusage->ru_oublock = (uint64_t) ioCounters.WriteOperationCount;
|
||||||
|
uv_rusage->ru_inblock = (uint64_t) ioCounters.ReadOperationCount;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue