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:
parent
d5fc593b5f
commit
c42a4ca372
@ -968,27 +968,31 @@ static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) {
|
||||
uv_mutex_unlock(m);
|
||||
}
|
||||
restart_readfile:
|
||||
result = ReadFile(handle->handle,
|
||||
&uv_zero_,
|
||||
0,
|
||||
&bytes,
|
||||
NULL);
|
||||
if (!result) {
|
||||
err = GetLastError();
|
||||
if (err == ERROR_OPERATION_ABORTED &&
|
||||
handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
|
||||
if (handle->flags & UV_HANDLE_READING) {
|
||||
/* just a brief break to do something else */
|
||||
handle->pipe.conn.readfile_thread = NULL;
|
||||
/* resume after it is finished */
|
||||
uv_mutex_lock(m);
|
||||
handle->pipe.conn.readfile_thread = hThread;
|
||||
uv_mutex_unlock(m);
|
||||
goto restart_readfile;
|
||||
} else {
|
||||
result = 1; /* successfully stopped reading */
|
||||
if (handle->flags & UV_HANDLE_READING) {
|
||||
result = ReadFile(handle->handle,
|
||||
&uv_zero_,
|
||||
0,
|
||||
&bytes,
|
||||
NULL);
|
||||
if (!result) {
|
||||
err = GetLastError();
|
||||
if (err == ERROR_OPERATION_ABORTED &&
|
||||
handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
|
||||
if (handle->flags & UV_HANDLE_READING) {
|
||||
/* just a brief break to do something else */
|
||||
handle->pipe.conn.readfile_thread = NULL;
|
||||
/* resume after it is finished */
|
||||
uv_mutex_lock(m);
|
||||
handle->pipe.conn.readfile_thread = hThread;
|
||||
uv_mutex_unlock(m);
|
||||
goto restart_readfile;
|
||||
} else {
|
||||
result = 1; /* successfully stopped reading */
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result = 1; /* successfully aborted read before it even started */
|
||||
}
|
||||
if (hThread) {
|
||||
assert(hThread == handle->pipe.conn.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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user