Chromium Code Reviews| Index: runtime/bin/eventhandler_win.cc |
| diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc |
| index 1584c8b71e455fe3854cda70301746f5b43adce1..6ed83bb15b62133ed4a3e5c64bfd81030e9c1df1 100644 |
| --- a/runtime/bin/eventhandler_win.cc |
| +++ b/runtime/bin/eventhandler_win.cc |
| @@ -107,6 +107,7 @@ Handle::Handle(HANDLE handle) |
| pending_read_(NULL), |
| pending_write_(NULL), |
| last_error_(NOERROR), |
| + thread_wrote_(0), |
| flags_(0) { |
| InitializeCriticalSection(&cs_); |
| } |
| @@ -122,6 +123,7 @@ Handle::Handle(HANDLE handle, Dart_Port port) |
| pending_read_(NULL), |
| pending_write_(NULL), |
| last_error_(NOERROR), |
| + thread_wrote_(0), |
| flags_(0) { |
| InitializeCriticalSection(&cs_); |
| } |
| @@ -332,7 +334,7 @@ bool FileHandle::IsClosed() { |
| void FileHandle::DoClose() { |
| - if (GetStdHandle(STD_OUTPUT_HANDLE) == handle_) { |
| + if (handle_ == GetStdHandle(STD_OUTPUT_HANDLE)) { |
| int fd = _open("NUL", _O_WRONLY); |
| ASSERT(fd >= 0); |
| _dup2(fd, _fileno(stdout)); |
| @@ -358,10 +360,6 @@ bool DirectoryWatchHandle::IsClosed() { |
| } |
| -void DirectoryWatchHandle::DoClose() { |
| - Handle::DoClose(); |
| -} |
| - |
| bool DirectoryWatchHandle::IssueRead() { |
| ScopedLock lock(this); |
| OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize); |
| @@ -562,30 +560,66 @@ int Handle::Read(void* buffer, int num_bytes) { |
| } |
| +static unsigned int __stdcall WriteFileThread(void* args) { |
| + Handle* handle = reinterpret_cast<Handle*>(args); |
| + handle->WriteSyncCompleteAsync(); |
| + return 0; |
| +} |
| + |
| + |
| +void Handle::WriteSyncCompleteAsync() { |
| + ASSERT(pending_write_ != NULL); |
| + |
| + DWORD bytes_written = -1; |
| + BOOL ok = WriteFile(handle_, |
| + pending_write_->GetBufferStart(), |
| + pending_write_->GetBufferSize(), |
| + &bytes_written, |
| + NULL); |
| + if (!ok) { |
| + if (GetLastError() != ERROR_BROKEN_PIPE) { |
| + Log::PrintErr("WriteFile failed %d\n", GetLastError()); |
| + } |
| + bytes_written = 0; |
| + } |
| + thread_wrote_ += bytes_written; |
| + OVERLAPPED* overlapped = pending_write_->GetCleanOverlapped(); |
| + ok = PostQueuedCompletionStatus(event_handler_->completion_port(), |
| + bytes_written, |
| + reinterpret_cast<ULONG_PTR>(this), |
| + overlapped); |
| + if (!ok) { |
| + FATAL("PostQueuedCompletionStatus failed"); |
| + } |
| +} |
| + |
| + |
| int Handle::Write(const void* buffer, int num_bytes) { |
|
Søren Gjesse
2013/09/24 11:24:22
This concept is pretty nasty. Please put in a comm
Anders Johnsen
2013/09/24 11:41:56
Done.
|
| ScopedLock lock(this); |
| + if (pending_write_ != NULL) return 0; |
| + if (num_bytes > kBufferSize) num_bytes = kBufferSize; |
| if (SupportsOverlappedIO()) { |
| - if (pending_write_ != NULL) return 0; |
| if (completion_port_ == INVALID_HANDLE_VALUE) return 0; |
| - if (num_bytes > kBufferSize) num_bytes = kBufferSize; |
| pending_write_ = OverlappedBuffer::AllocateWriteBuffer(num_bytes); |
| pending_write_->Write(buffer, num_bytes); |
| if (!IssueWrite()) return -1; |
| return num_bytes; |
| } else { |
| - DWORD bytes_written = -1; |
| - BOOL ok = WriteFile(handle_, |
| - buffer, |
| - num_bytes, |
| - &bytes_written, |
| - NULL); |
| - if (!ok) { |
| - if (GetLastError() != ERROR_BROKEN_PIPE) { |
| - Log::PrintErr("WriteFile failed: %d\n", GetLastError()); |
| - } |
| - event_handler_->HandleClosed(this); |
| + if (thread_wrote_ > 0) { |
| + if (num_bytes > thread_wrote_) num_bytes = thread_wrote_; |
| + thread_wrote_ -= num_bytes; |
| + return num_bytes; |
| + } |
| + pending_write_ = OverlappedBuffer::AllocateWriteBuffer(num_bytes); |
| + pending_write_->Write(buffer, num_bytes); |
| + // Completing asynchronously through thread. |
| + uint32_t tid; |
| + uintptr_t thread_handle = |
| + _beginthreadex(NULL, 32 * 1024, WriteFileThread, this, 0, &tid); |
|
Søren Gjesse
2013/09/24 11:24:22
Please open an issue on not starting a new thread
Anders Johnsen
2013/09/24 11:41:56
Done.
|
| + if (thread_handle == -1) { |
| + FATAL("Failed to start write file thread"); |
| } |
| - return bytes_written; |
| + return 0; |
| } |
| } |