| Index: runtime/bin/eventhandler_win.cc
|
| diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc
|
| index db698a3c8831e637cb17e15fbeef1c242548d152..05511285b0f7a714462756912c340d50bfd1eda8 100644
|
| --- a/runtime/bin/eventhandler_win.cc
|
| +++ b/runtime/bin/eventhandler_win.cc
|
| @@ -121,12 +121,16 @@ Handle::Handle(intptr_t handle)
|
| pending_read_(NULL),
|
| pending_write_(NULL),
|
| last_error_(NOERROR),
|
| - flags_(0) {
|
| + flags_(0),
|
| + read_thread_id_(Thread::kInvalidThreadId),
|
| + read_thread_exists_(false),
|
| + read_thread_monitor_(new Monitor()) {
|
| InitializeCriticalSection(&cs_);
|
| }
|
|
|
|
|
| Handle::~Handle() {
|
| + delete read_thread_monitor_;
|
| DeleteCriticalSection(&cs_);
|
| }
|
|
|
| @@ -197,6 +201,20 @@ void Handle::ReadComplete(OverlappedBuffer* buffer) {
|
| OverlappedBuffer::DisposeBuffer(buffer);
|
| }
|
| pending_read_ = NULL;
|
| +
|
| + // Join the Reader thread if there is one.
|
| + ThreadId to_join;
|
| + {
|
| + MonitorLocker ml(read_thread_monitor_);
|
| + while (read_thread_exists_) {
|
| + ml.Wait();
|
| + }
|
| + to_join = read_thread_id_;
|
| + read_thread_id = Thread::kInvalidThreadId;
|
| + }
|
| + if (to_join != Thread::kInvalidThreadId) {
|
| + Thread::Join(to_join);
|
| + }
|
| }
|
|
|
|
|
| @@ -223,6 +241,12 @@ static void ReadFileThread(uword args) {
|
| void Handle::ReadSyncCompleteAsync() {
|
| ASSERT(pending_read_ != NULL);
|
| ASSERT(pending_read_->GetBufferSize() >= kStdOverlappedBufferSize);
|
| + {
|
| + MonitorLocker ml(read_thread_monitor_);
|
| + read_thread_id_ = Thread::GetCurrentThreadId();
|
| + read_thread_exists_ = true;
|
| + ml.Notify();
|
| + }
|
|
|
| DWORD buffer_size = pending_read_->GetBufferSize();
|
| if (GetFileType(handle_) == FILE_TYPE_CHAR) {
|
| @@ -245,6 +269,11 @@ void Handle::ReadSyncCompleteAsync() {
|
| if (!ok) {
|
| FATAL("PostQueuedCompletionStatus failed");
|
| }
|
| + {
|
| + MonitorLocker ml(read_thread_monitor_);
|
| + read_thread_exists_ = false;
|
| + ml.Notify();
|
| + }
|
| }
|
|
|
|
|
| @@ -277,6 +306,13 @@ bool Handle::IssueRead() {
|
| if (result != 0) {
|
| FATAL1("Failed to start read file thread %d", result);
|
| }
|
| + {
|
| + MonitorLocker ml(read_thread_monitor_);
|
| + while (!read_thread_exists_) {
|
| + ml.Wait();
|
| + }
|
| + ASSERT(read_thread_id_ != Thread::kInvalidThreadId);
|
| + }
|
| return true;
|
| }
|
| }
|
| @@ -677,6 +713,7 @@ static void WriteFileThread(uword args) {
|
| void StdHandle::RunWriteLoop() {
|
| write_monitor_->Enter();
|
| write_thread_running_ = true;
|
| + thread_id_ = Thread::GetCurrentThreadId();
|
| // Notify we have started.
|
| write_monitor_->Notify();
|
|
|
| @@ -762,6 +799,7 @@ void StdHandle::DoClose() {
|
| while (write_thread_exists_) {
|
| locker.Wait(Monitor::kNoTimeout);
|
| }
|
| + Thread::Join(thread_id_);
|
| }
|
| Handle::DoClose();
|
| }
|
| @@ -1278,6 +1316,8 @@ void EventHandlerImplementation::HandleIOCompletion(DWORD bytes,
|
|
|
|
|
| EventHandlerImplementation::EventHandlerImplementation() {
|
| + startup_monitor_ = new Monitor();
|
| + handler_thread_id_ = Thread::kInvalidThreadId;
|
| completion_port_ =
|
| CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 1);
|
| if (completion_port_ == NULL) {
|
| @@ -1288,6 +1328,8 @@ EventHandlerImplementation::EventHandlerImplementation() {
|
|
|
|
|
| EventHandlerImplementation::~EventHandlerImplementation() {
|
| + Thread::Join(handler_thread_id_);
|
| + delete startup_monitor_;
|
| CloseHandle(completion_port_);
|
| }
|
|
|
| @@ -1322,6 +1364,12 @@ void EventHandlerImplementation::EventHandlerEntry(uword args) {
|
| EventHandlerImplementation* handler_impl = &handler->delegate_;
|
| ASSERT(handler_impl != NULL);
|
|
|
| + {
|
| + MonitorLocker ml(handler_impl->startup_monitor_);
|
| + handler_impl->handler_thread_id_ = Thread::GetCurrentThreadId();
|
| + ml.Notify();
|
| + }
|
| +
|
| while (!handler_impl->shutdown_) {
|
| DWORD bytes;
|
| ULONG_PTR key;
|
| @@ -1382,6 +1430,13 @@ void EventHandlerImplementation::Start(EventHandler* handler) {
|
| FATAL1("Failed to start event handler thread %d", result);
|
| }
|
|
|
| + {
|
| + MonitorLocker ml(startup_monitor_);
|
| + while (handler_thread_id_ == Thread::kInvalidThreadId) {
|
| + ml.Wait();
|
| + }
|
| + }
|
| +
|
| // Initialize Winsock32
|
| if (!Socket::Initialize()) {
|
| FATAL("Failed to initialized Windows sockets");
|
|
|