OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #if !defined(DART_IO_DISABLED) | 5 #if !defined(DART_IO_DISABLED) |
6 | 6 |
7 #include "platform/globals.h" | 7 #include "platform/globals.h" |
8 #if defined(TARGET_OS_WINDOWS) | 8 #if defined(TARGET_OS_WINDOWS) |
9 | 9 |
10 #include "bin/eventhandler.h" | 10 #include "bin/eventhandler.h" |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 : DescriptorInfoBase(handle), | 119 : DescriptorInfoBase(handle), |
120 handle_(reinterpret_cast<HANDLE>(handle)), | 120 handle_(reinterpret_cast<HANDLE>(handle)), |
121 completion_port_(INVALID_HANDLE_VALUE), | 121 completion_port_(INVALID_HANDLE_VALUE), |
122 event_handler_(NULL), | 122 event_handler_(NULL), |
123 data_ready_(NULL), | 123 data_ready_(NULL), |
124 pending_read_(NULL), | 124 pending_read_(NULL), |
125 pending_write_(NULL), | 125 pending_write_(NULL), |
126 last_error_(NOERROR), | 126 last_error_(NOERROR), |
127 flags_(0), | 127 flags_(0), |
128 read_thread_id_(Thread::kInvalidThreadId), | 128 read_thread_id_(Thread::kInvalidThreadId), |
| 129 read_thread_handle_(NULL), |
129 read_thread_starting_(false), | 130 read_thread_starting_(false), |
130 read_thread_finished_(false), | 131 read_thread_finished_(false), |
131 monitor_(new Monitor()) { | 132 monitor_(new Monitor()) { |
132 } | 133 } |
133 | 134 |
134 | 135 |
135 Handle::~Handle() { | 136 Handle::~Handle() { |
136 delete monitor_; | 137 delete monitor_; |
137 } | 138 } |
138 | 139 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 | 182 |
182 void Handle::WaitForReadThreadStarted() { | 183 void Handle::WaitForReadThreadStarted() { |
183 MonitorLocker ml(monitor_); | 184 MonitorLocker ml(monitor_); |
184 while (read_thread_starting_) { | 185 while (read_thread_starting_) { |
185 ml.Wait(); | 186 ml.Wait(); |
186 } | 187 } |
187 } | 188 } |
188 | 189 |
189 | 190 |
190 void Handle::WaitForReadThreadFinished() { | 191 void Handle::WaitForReadThreadFinished() { |
191 MonitorLocker ml(monitor_); | 192 HANDLE to_join = NULL; |
192 if (read_thread_id_ != Thread::kInvalidThreadId) { | 193 { |
193 while (!read_thread_finished_) { | 194 MonitorLocker ml(monitor_); |
194 ml.Wait(); | 195 if (read_thread_id_ != Thread::kInvalidThreadId) { |
| 196 while (!read_thread_finished_) { |
| 197 ml.Wait(); |
| 198 } |
| 199 read_thread_finished_ = false; |
| 200 read_thread_id_ = Thread::kInvalidThreadId; |
| 201 to_join = read_thread_handle_; |
| 202 read_thread_handle_ = NULL; |
195 } | 203 } |
196 read_thread_finished_ = false; | 204 } |
197 read_thread_id_ = Thread::kInvalidThreadId; | 205 if (to_join != NULL) { |
| 206 // Join the read thread. |
| 207 DWORD res = WaitForSingleObject(to_join, INFINITE); |
| 208 CloseHandle(to_join); |
| 209 ASSERT(res == WAIT_OBJECT_0); |
198 } | 210 } |
199 } | 211 } |
200 | 212 |
201 | 213 |
202 void Handle::ReadComplete(OverlappedBuffer* buffer) { | 214 void Handle::ReadComplete(OverlappedBuffer* buffer) { |
203 WaitForReadThreadStarted(); | 215 WaitForReadThreadStarted(); |
204 { | 216 { |
205 MonitorLocker ml(monitor_); | 217 MonitorLocker ml(monitor_); |
206 // Currently only one outstanding read at the time. | 218 // Currently only one outstanding read at the time. |
207 ASSERT(pending_read_ == buffer); | 219 ASSERT(pending_read_ == buffer); |
(...skipping 27 matching lines...) Expand all Loading... |
235 Handle* handle = reinterpret_cast<Handle*>(args); | 247 Handle* handle = reinterpret_cast<Handle*>(args); |
236 handle->ReadSyncCompleteAsync(); | 248 handle->ReadSyncCompleteAsync(); |
237 } | 249 } |
238 | 250 |
239 | 251 |
240 void Handle::NotifyReadThreadStarted() { | 252 void Handle::NotifyReadThreadStarted() { |
241 MonitorLocker ml(monitor_); | 253 MonitorLocker ml(monitor_); |
242 ASSERT(read_thread_starting_); | 254 ASSERT(read_thread_starting_); |
243 ASSERT(read_thread_id_ == Thread::kInvalidThreadId); | 255 ASSERT(read_thread_id_ == Thread::kInvalidThreadId); |
244 read_thread_id_ = Thread::GetCurrentThreadId(); | 256 read_thread_id_ = Thread::GetCurrentThreadId(); |
| 257 read_thread_handle_ = OpenThread(SYNCHRONIZE, false, read_thread_id_); |
245 read_thread_starting_ = false; | 258 read_thread_starting_ = false; |
246 ml.Notify(); | 259 ml.Notify(); |
247 } | 260 } |
248 | 261 |
| 262 |
249 void Handle::NotifyReadThreadFinished() { | 263 void Handle::NotifyReadThreadFinished() { |
250 MonitorLocker ml(monitor_); | 264 MonitorLocker ml(monitor_); |
251 ASSERT(!read_thread_finished_); | 265 ASSERT(!read_thread_finished_); |
252 ASSERT(read_thread_id_ != Thread::kInvalidThreadId); | 266 ASSERT(read_thread_id_ != Thread::kInvalidThreadId); |
253 read_thread_finished_ = true; | 267 read_thread_finished_ = true; |
254 ml.Notify(); | 268 ml.Notify(); |
255 } | 269 } |
256 | 270 |
257 | 271 |
258 void Handle::ReadSyncCompleteAsync() { | 272 void Handle::ReadSyncCompleteAsync() { |
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 static void WriteFileThread(uword args) { | 749 static void WriteFileThread(uword args) { |
736 StdHandle* handle = reinterpret_cast<StdHandle*>(args); | 750 StdHandle* handle = reinterpret_cast<StdHandle*>(args); |
737 handle->RunWriteLoop(); | 751 handle->RunWriteLoop(); |
738 } | 752 } |
739 | 753 |
740 | 754 |
741 void StdHandle::RunWriteLoop() { | 755 void StdHandle::RunWriteLoop() { |
742 MonitorLocker ml(monitor_); | 756 MonitorLocker ml(monitor_); |
743 write_thread_running_ = true; | 757 write_thread_running_ = true; |
744 thread_id_ = Thread::GetCurrentThreadId(); | 758 thread_id_ = Thread::GetCurrentThreadId(); |
| 759 thread_handle_ = OpenThread(SYNCHRONIZE, false, thread_id_); |
745 // Notify we have started. | 760 // Notify we have started. |
746 ml.Notify(); | 761 ml.Notify(); |
747 | 762 |
748 while (write_thread_running_) { | 763 while (write_thread_running_) { |
749 ml.Wait(Monitor::kNoTimeout); | 764 ml.Wait(Monitor::kNoTimeout); |
750 if (pending_write_ != NULL) { | 765 if (pending_write_ != NULL) { |
751 // We woke up and had a pending write. Execute it. | 766 // We woke up and had a pending write. Execute it. |
752 WriteSyncCompleteAsync(); | 767 WriteSyncCompleteAsync(); |
753 } | 768 } |
754 } | 769 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
824 | 839 |
825 | 840 |
826 void StdHandle::DoClose() { | 841 void StdHandle::DoClose() { |
827 MonitorLocker ml(monitor_); | 842 MonitorLocker ml(monitor_); |
828 if (write_thread_exists_) { | 843 if (write_thread_exists_) { |
829 write_thread_running_ = false; | 844 write_thread_running_ = false; |
830 ml.Notify(); | 845 ml.Notify(); |
831 while (write_thread_exists_) { | 846 while (write_thread_exists_) { |
832 ml.Wait(Monitor::kNoTimeout); | 847 ml.Wait(Monitor::kNoTimeout); |
833 } | 848 } |
| 849 // Join the thread. |
| 850 DWORD res = WaitForSingleObject(thread_handle_, INFINITE); |
| 851 CloseHandle(thread_handle_); |
| 852 ASSERT(res == WAIT_OBJECT_0); |
834 } | 853 } |
835 Handle::DoClose(); | 854 Handle::DoClose(); |
836 } | 855 } |
837 | 856 |
838 | 857 |
839 bool ClientSocket::LoadDisconnectEx() { | 858 bool ClientSocket::LoadDisconnectEx() { |
840 // Load the DisconnectEx function into memory using WSAIoctl. | 859 // Load the DisconnectEx function into memory using WSAIoctl. |
841 GUID guid_disconnect_ex = WSAID_DISCONNECTEX; | 860 GUID guid_disconnect_ex = WSAID_DISCONNECTEX; |
842 DWORD bytes; | 861 DWORD bytes; |
843 int status = WSAIoctl(socket(), | 862 int status = WSAIoctl(socket(), |
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1350 } | 1369 } |
1351 default: | 1370 default: |
1352 UNREACHABLE(); | 1371 UNREACHABLE(); |
1353 } | 1372 } |
1354 } | 1373 } |
1355 | 1374 |
1356 | 1375 |
1357 EventHandlerImplementation::EventHandlerImplementation() { | 1376 EventHandlerImplementation::EventHandlerImplementation() { |
1358 startup_monitor_ = new Monitor(); | 1377 startup_monitor_ = new Monitor(); |
1359 handler_thread_id_ = Thread::kInvalidThreadId; | 1378 handler_thread_id_ = Thread::kInvalidThreadId; |
| 1379 handler_thread_handle_ = NULL; |
1360 completion_port_ = | 1380 completion_port_ = |
1361 CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 1); | 1381 CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 1); |
1362 if (completion_port_ == NULL) { | 1382 if (completion_port_ == NULL) { |
1363 FATAL("Completion port creation failed"); | 1383 FATAL("Completion port creation failed"); |
1364 } | 1384 } |
1365 shutdown_ = false; | 1385 shutdown_ = false; |
1366 } | 1386 } |
1367 | 1387 |
1368 | 1388 |
1369 EventHandlerImplementation::~EventHandlerImplementation() { | 1389 EventHandlerImplementation::~EventHandlerImplementation() { |
| 1390 // Join the handler thread. |
| 1391 DWORD res = WaitForSingleObject(handler_thread_handle_, INFINITE); |
| 1392 CloseHandle(handler_thread_handle_); |
| 1393 ASSERT(res == WAIT_OBJECT_0); |
1370 delete startup_monitor_; | 1394 delete startup_monitor_; |
1371 CloseHandle(completion_port_); | 1395 CloseHandle(completion_port_); |
1372 } | 1396 } |
1373 | 1397 |
1374 | 1398 |
1375 int64_t EventHandlerImplementation::GetTimeout() { | 1399 int64_t EventHandlerImplementation::GetTimeout() { |
1376 if (!timeout_queue_.HasTimeout()) { | 1400 if (!timeout_queue_.HasTimeout()) { |
1377 return kInfinityTimeout; | 1401 return kInfinityTimeout; |
1378 } | 1402 } |
1379 int64_t millis = timeout_queue_.CurrentTimeout() - | 1403 int64_t millis = timeout_queue_.CurrentTimeout() - |
(...skipping 18 matching lines...) Expand all Loading... |
1398 | 1422 |
1399 | 1423 |
1400 void EventHandlerImplementation::EventHandlerEntry(uword args) { | 1424 void EventHandlerImplementation::EventHandlerEntry(uword args) { |
1401 EventHandler* handler = reinterpret_cast<EventHandler*>(args); | 1425 EventHandler* handler = reinterpret_cast<EventHandler*>(args); |
1402 EventHandlerImplementation* handler_impl = &handler->delegate_; | 1426 EventHandlerImplementation* handler_impl = &handler->delegate_; |
1403 ASSERT(handler_impl != NULL); | 1427 ASSERT(handler_impl != NULL); |
1404 | 1428 |
1405 { | 1429 { |
1406 MonitorLocker ml(handler_impl->startup_monitor_); | 1430 MonitorLocker ml(handler_impl->startup_monitor_); |
1407 handler_impl->handler_thread_id_ = Thread::GetCurrentThreadId(); | 1431 handler_impl->handler_thread_id_ = Thread::GetCurrentThreadId(); |
| 1432 handler_impl->handler_thread_handle_ = |
| 1433 OpenThread(SYNCHRONIZE, false, handler_impl->handler_thread_id_); |
1408 ml.Notify(); | 1434 ml.Notify(); |
1409 } | 1435 } |
1410 | 1436 |
1411 while (!handler_impl->shutdown_) { | 1437 while (!handler_impl->shutdown_) { |
1412 DWORD bytes; | 1438 DWORD bytes; |
1413 ULONG_PTR key; | 1439 ULONG_PTR key; |
1414 OVERLAPPED* overlapped; | 1440 OVERLAPPED* overlapped; |
1415 int64_t millis = handler_impl->GetTimeout(); | 1441 int64_t millis = handler_impl->GetTimeout(); |
1416 ASSERT(millis == kInfinityTimeout || millis >= 0); | 1442 ASSERT(millis == kInfinityTimeout || millis >= 0); |
1417 if (millis > kMaxInt32) { | 1443 if (millis > kMaxInt32) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1492 void EventHandlerImplementation::Shutdown() { | 1518 void EventHandlerImplementation::Shutdown() { |
1493 SendData(kShutdownId, 0, 0); | 1519 SendData(kShutdownId, 0, 0); |
1494 } | 1520 } |
1495 | 1521 |
1496 } // namespace bin | 1522 } // namespace bin |
1497 } // namespace dart | 1523 } // namespace dart |
1498 | 1524 |
1499 #endif // defined(TARGET_OS_WINDOWS) | 1525 #endif // defined(TARGET_OS_WINDOWS) |
1500 | 1526 |
1501 #endif // !defined(DART_IO_DISABLED) | 1527 #endif // !defined(DART_IO_DISABLED) |
OLD | NEW |