From bd8cf2ada19dd071ee1e70d19331c6903f9fa943 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Thu, 16 Jul 2015 01:54:28 -0400 Subject: [PATCH] win pipe: missing conditional check on uv_pipe_zero_readfile_thread_proc 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 --- src/win/pipe.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/win/pipe.c b/src/win/pipe.c index 6503855127e..8ee458c5198 100644 --- a/src/win/pipe.c +++ b/src/win/pipe.c @@ -1089,26 +1089,30 @@ 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 && m) { - if (handle->flags & UV_HANDLE_READING) { - /* just a brief break to do something else */ - handle->readfile_thread = NULL; - /* resume after it is finished */ - uv_mutex_lock(m); - handle->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 && m) { + if (handle->flags & UV_HANDLE_READING) { + /* just a brief break to do something else */ + handle->readfile_thread = NULL; + /* resume after it is finished */ + uv_mutex_lock(m); + handle->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->readfile_thread);