win,pipe: race condition canceling readfile thread

Fixes a race condition where if uv_read_stop was called shortly
after uv_read_start or a successful read and before the
uv_pipe_zero_readfile_thread_proc thread started,
that thread would call the blocking ReadFile call after the
HANDLE_READING flag had already been cleared.

Also ignores EINTR to be more consistent with unix
(although we generally don't expect to see this condition on windows).

PR-URL: https://github.com/libuv/libuv/pull/1322
Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
Reviewed-By: Bartosz Sosnowski <bartosz@janeasystems.com>
This commit is contained in:
Jameson Nash 2015-07-16 01:54:28 -04:00 committed by Santiago Gimeno
parent d5fc593b5f
commit c42a4ca372
No known key found for this signature in database
GPG Key ID: F28C3C8DA33C03BE

View File

@ -968,6 +968,7 @@ static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) {
uv_mutex_unlock(m);
}
restart_readfile:
if (handle->flags & UV_HANDLE_READING) {
result = ReadFile(handle->handle,
&uv_zero_,
0,
@ -990,6 +991,9 @@ restart_readfile:
}
}
}
} else {
result = 1; /* successfully aborted read before it even started */
}
if (hThread) {
assert(hThread == handle->pipe.conn.readfile_thread);
/* mutex does not control clearing readfile_thread */
@ -1515,7 +1519,10 @@ static void uv_pipe_read_error(uv_loop_t* loop, uv_pipe_t* handle, int error,
static void uv_pipe_read_error_or_eof(uv_loop_t* loop, uv_pipe_t* handle,
int error, uv_buf_t buf) {
if (error == ERROR_BROKEN_PIPE) {
if (error == ERROR_OPERATION_ABORTED) {
/* do nothing (equivalent to EINTR) */
}
else if (error == ERROR_BROKEN_PIPE) {
uv_pipe_read_eof(loop, handle, buf);
} else {
uv_pipe_read_error(loop, handle, error, buf);