summaryrefslogtreecommitdiffstats
path: root/lldb/source/Host/windows/PipeWindows.cpp
diff options
context:
space:
mode:
authorPavel Labath <labath@google.com>2015-07-21 09:23:34 +0000
committerPavel Labath <labath@google.com>2015-07-21 09:23:34 +0000
commit9f0701f8cafd50bbe9b36795c4331f3d82ce109a (patch)
tree017bcb9a0539c0118a026502c3da864e3de4407d /lldb/source/Host/windows/PipeWindows.cpp
parentd818e38ff979c21577abada60057c83946852aeb (diff)
downloadbcm5719-llvm-9f0701f8cafd50bbe9b36795c4331f3d82ce109a.tar.gz
bcm5719-llvm-9f0701f8cafd50bbe9b36795c4331f3d82ce109a.zip
Add Pipe::WriteWithTimeout method
Summary: This commit adds a WriteWithTimeout method to time Pipe class, analogous to the existing ReadWithTimeout(). It also changes the meaning of passing zero as a timeout value. Previously, zero was used as an infinite timeout value. Now, the meaning of zero timeout to return the data avaiable without sleeping (basically, a non-blocking operation). This makes the behaviour of Pipe consistent with the Communication/Connection classes. For blocking operatios with infinite timeout, I introduce a special constant for this purpose. Reviewers: ovyalov, zturner Subscribers: lldb-commits Differential Revision: http://reviews.llvm.org/D11358 llvm-svn: 242764
Diffstat (limited to 'lldb/source/Host/windows/PipeWindows.cpp')
-rw-r--r--lldb/source/Host/windows/PipeWindows.cpp33
1 files changed, 30 insertions, 3 deletions
diff --git a/lldb/source/Host/windows/PipeWindows.cpp b/lldb/source/Host/windows/PipeWindows.cpp
index d4afd6e7494..e2029971742 100644
--- a/lldb/source/Host/windows/PipeWindows.cpp
+++ b/lldb/source/Host/windows/PipeWindows.cpp
@@ -289,7 +289,7 @@ PipeWindows::ReadWithTimeout(void *buf, size_t size, const std::chrono::microsec
if (!result && GetLastError() != ERROR_IO_PENDING)
return Error(::GetLastError(), eErrorTypeWin32);
- DWORD timeout = (duration == std::chrono::microseconds::zero()) ? INFINITE : duration.count() * 1000;
+ DWORD timeout = (duration == kInfiniteTimeout) ? INFINITE : duration.count() * 1000;
DWORD wait_result = ::WaitForSingleObject(m_read_overlapped.hEvent, timeout);
if (wait_result != WAIT_OBJECT_0)
{
@@ -319,7 +319,10 @@ PipeWindows::ReadWithTimeout(void *buf, size_t size, const std::chrono::microsec
}
Error
-PipeWindows::Write(const void *buf, size_t num_bytes, size_t &bytes_written)
+PipeWindows::WriteWithTimeout(const void *buf,
+ size_t num_bytes,
+ const std::chrono::microseconds &duration,
+ size_t &bytes_written)
{
if (!CanWrite())
return Error(ERROR_INVALID_HANDLE, eErrorTypeWin32);
@@ -329,8 +332,32 @@ PipeWindows::Write(const void *buf, size_t num_bytes, size_t &bytes_written)
if (!write_result && GetLastError() != ERROR_IO_PENDING)
return Error(::GetLastError(), eErrorTypeWin32);
- BOOL result = GetOverlappedResult(m_write, &m_write_overlapped, &sys_bytes_written, TRUE);
+ DWORD timeout = (duration == kInfiniteTimeout) ? INFINITE : duration.count() * 1000;
+ DWORD wait_result = ::WaitForSingleObject(m_write_overlapped.hEvent, timeout);
+ if (wait_result != WAIT_OBJECT_0)
+ {
+ // The operation probably failed. However, if it timed out, we need to cancel the I/O.
+ // Between the time we returned from WaitForSingleObject and the time we call CancelIoEx,
+ // the operation may complete. If that hapens, CancelIoEx will fail and return ERROR_NOT_FOUND.
+ // If that happens, the original operation should be considered to have been successful.
+ bool failed = true;
+ DWORD failure_error = ::GetLastError();
+ if (wait_result == WAIT_TIMEOUT)
+ {
+ BOOL cancel_result = CancelIoEx(m_read, &m_write_overlapped);
+ if (!cancel_result && GetLastError() == ERROR_NOT_FOUND)
+ failed = false;
+ }
+ if (failed)
+ return Error(failure_error, eErrorTypeWin32);
+ }
+
+ // Now we call GetOverlappedResult setting bWait to false, since we've already waited
+ // as long as we're willing to.
+ BOOL result = GetOverlappedResult(m_write, &m_write_overlapped, &sys_bytes_written, FALSE);
if (!result)
return Error(::GetLastError(), eErrorTypeWin32);
+
+ bytes_written = sys_bytes_written;
return Error();
}
OpenPOWER on IntegriCloud