| 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 #include "platform/globals.h" | 5 #include "platform/globals.h" |
| 6 #if defined(TARGET_OS_WINDOWS) | 6 #if defined(TARGET_OS_WINDOWS) |
| 7 | 7 |
| 8 #include "bin/eventhandler.h" | 8 #include "bin/eventhandler.h" |
| 9 #include "bin/eventhandler_win.h" | 9 #include "bin/eventhandler_win.h" |
| 10 | 10 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 | 114 |
| 115 Handle::Handle(intptr_t handle) | 115 Handle::Handle(intptr_t handle) |
| 116 : DescriptorInfoBase(handle), | 116 : DescriptorInfoBase(handle), |
| 117 handle_(reinterpret_cast<HANDLE>(handle)), | 117 handle_(reinterpret_cast<HANDLE>(handle)), |
| 118 completion_port_(INVALID_HANDLE_VALUE), | 118 completion_port_(INVALID_HANDLE_VALUE), |
| 119 event_handler_(NULL), | 119 event_handler_(NULL), |
| 120 data_ready_(NULL), | 120 data_ready_(NULL), |
| 121 pending_read_(NULL), | 121 pending_read_(NULL), |
| 122 pending_write_(NULL), | 122 pending_write_(NULL), |
| 123 last_error_(NOERROR), | 123 last_error_(NOERROR), |
| 124 flags_(0) { | 124 flags_(0), |
| 125 read_thread_id_(Thread::kInvalidThreadId), |
| 126 read_thread_exists_(false), |
| 127 read_thread_monitor_(new Monitor()) { |
| 125 InitializeCriticalSection(&cs_); | 128 InitializeCriticalSection(&cs_); |
| 126 } | 129 } |
| 127 | 130 |
| 128 | 131 |
| 129 Handle::~Handle() { | 132 Handle::~Handle() { |
| 133 delete read_thread_monitor_; |
| 130 DeleteCriticalSection(&cs_); | 134 DeleteCriticalSection(&cs_); |
| 131 } | 135 } |
| 132 | 136 |
| 133 | 137 |
| 134 void Handle::Lock() { | 138 void Handle::Lock() { |
| 135 EnterCriticalSection(&cs_); | 139 EnterCriticalSection(&cs_); |
| 136 } | 140 } |
| 137 | 141 |
| 138 | 142 |
| 139 void Handle::Unlock() { | 143 void Handle::Unlock() { |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 ScopedLock lock(this); | 194 ScopedLock lock(this); |
| 191 // Currently only one outstanding read at the time. | 195 // Currently only one outstanding read at the time. |
| 192 ASSERT(pending_read_ == buffer); | 196 ASSERT(pending_read_ == buffer); |
| 193 ASSERT(data_ready_ == NULL); | 197 ASSERT(data_ready_ == NULL); |
| 194 if (!IsClosing() && !buffer->IsEmpty()) { | 198 if (!IsClosing() && !buffer->IsEmpty()) { |
| 195 data_ready_ = pending_read_; | 199 data_ready_ = pending_read_; |
| 196 } else { | 200 } else { |
| 197 OverlappedBuffer::DisposeBuffer(buffer); | 201 OverlappedBuffer::DisposeBuffer(buffer); |
| 198 } | 202 } |
| 199 pending_read_ = NULL; | 203 pending_read_ = NULL; |
| 204 |
| 205 // Join the Reader thread if there is one. |
| 206 ThreadId to_join; |
| 207 { |
| 208 MonitorLocker ml(read_thread_monitor_); |
| 209 while (read_thread_exists_) { |
| 210 ml.Wait(); |
| 211 } |
| 212 to_join = read_thread_id_; |
| 213 read_thread_id = Thread::kInvalidThreadId; |
| 214 } |
| 215 if (to_join != Thread::kInvalidThreadId) { |
| 216 Thread::Join(to_join); |
| 217 } |
| 200 } | 218 } |
| 201 | 219 |
| 202 | 220 |
| 203 void Handle::RecvFromComplete(OverlappedBuffer* buffer) { | 221 void Handle::RecvFromComplete(OverlappedBuffer* buffer) { |
| 204 ReadComplete(buffer); | 222 ReadComplete(buffer); |
| 205 } | 223 } |
| 206 | 224 |
| 207 | 225 |
| 208 void Handle::WriteComplete(OverlappedBuffer* buffer) { | 226 void Handle::WriteComplete(OverlappedBuffer* buffer) { |
| 209 ScopedLock lock(this); | 227 ScopedLock lock(this); |
| 210 // Currently only one outstanding write at the time. | 228 // Currently only one outstanding write at the time. |
| 211 ASSERT(pending_write_ == buffer); | 229 ASSERT(pending_write_ == buffer); |
| 212 OverlappedBuffer::DisposeBuffer(buffer); | 230 OverlappedBuffer::DisposeBuffer(buffer); |
| 213 pending_write_ = NULL; | 231 pending_write_ = NULL; |
| 214 } | 232 } |
| 215 | 233 |
| 216 | 234 |
| 217 static void ReadFileThread(uword args) { | 235 static void ReadFileThread(uword args) { |
| 218 Handle* handle = reinterpret_cast<Handle*>(args); | 236 Handle* handle = reinterpret_cast<Handle*>(args); |
| 219 handle->ReadSyncCompleteAsync(); | 237 handle->ReadSyncCompleteAsync(); |
| 220 } | 238 } |
| 221 | 239 |
| 222 | 240 |
| 223 void Handle::ReadSyncCompleteAsync() { | 241 void Handle::ReadSyncCompleteAsync() { |
| 224 ASSERT(pending_read_ != NULL); | 242 ASSERT(pending_read_ != NULL); |
| 225 ASSERT(pending_read_->GetBufferSize() >= kStdOverlappedBufferSize); | 243 ASSERT(pending_read_->GetBufferSize() >= kStdOverlappedBufferSize); |
| 244 { |
| 245 MonitorLocker ml(read_thread_monitor_); |
| 246 read_thread_id_ = Thread::GetCurrentThreadId(); |
| 247 read_thread_exists_ = true; |
| 248 ml.Notify(); |
| 249 } |
| 226 | 250 |
| 227 DWORD buffer_size = pending_read_->GetBufferSize(); | 251 DWORD buffer_size = pending_read_->GetBufferSize(); |
| 228 if (GetFileType(handle_) == FILE_TYPE_CHAR) { | 252 if (GetFileType(handle_) == FILE_TYPE_CHAR) { |
| 229 buffer_size = kStdOverlappedBufferSize; | 253 buffer_size = kStdOverlappedBufferSize; |
| 230 } | 254 } |
| 231 DWORD bytes_read = 0; | 255 DWORD bytes_read = 0; |
| 232 BOOL ok = ReadFile(handle_, | 256 BOOL ok = ReadFile(handle_, |
| 233 pending_read_->GetBufferStart(), | 257 pending_read_->GetBufferStart(), |
| 234 buffer_size, | 258 buffer_size, |
| 235 &bytes_read, | 259 &bytes_read, |
| 236 NULL); | 260 NULL); |
| 237 if (!ok) { | 261 if (!ok) { |
| 238 bytes_read = 0; | 262 bytes_read = 0; |
| 239 } | 263 } |
| 240 OVERLAPPED* overlapped = pending_read_->GetCleanOverlapped(); | 264 OVERLAPPED* overlapped = pending_read_->GetCleanOverlapped(); |
| 241 ok = PostQueuedCompletionStatus(event_handler_->completion_port(), | 265 ok = PostQueuedCompletionStatus(event_handler_->completion_port(), |
| 242 bytes_read, | 266 bytes_read, |
| 243 reinterpret_cast<ULONG_PTR>(this), | 267 reinterpret_cast<ULONG_PTR>(this), |
| 244 overlapped); | 268 overlapped); |
| 245 if (!ok) { | 269 if (!ok) { |
| 246 FATAL("PostQueuedCompletionStatus failed"); | 270 FATAL("PostQueuedCompletionStatus failed"); |
| 247 } | 271 } |
| 272 { |
| 273 MonitorLocker ml(read_thread_monitor_); |
| 274 read_thread_exists_ = false; |
| 275 ml.Notify(); |
| 276 } |
| 248 } | 277 } |
| 249 | 278 |
| 250 | 279 |
| 251 bool Handle::IssueRead() { | 280 bool Handle::IssueRead() { |
| 252 ScopedLock lock(this); | 281 ScopedLock lock(this); |
| 253 ASSERT(type_ != kListenSocket); | 282 ASSERT(type_ != kListenSocket); |
| 254 ASSERT(pending_read_ == NULL); | 283 ASSERT(pending_read_ == NULL); |
| 255 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize); | 284 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize); |
| 256 if (SupportsOverlappedIO()) { | 285 if (SupportsOverlappedIO()) { |
| 257 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 286 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 270 HandleIssueError(); | 299 HandleIssueError(); |
| 271 return false; | 300 return false; |
| 272 } else { | 301 } else { |
| 273 // Completing asynchronously through thread. | 302 // Completing asynchronously through thread. |
| 274 pending_read_ = buffer; | 303 pending_read_ = buffer; |
| 275 int result = Thread::Start(ReadFileThread, | 304 int result = Thread::Start(ReadFileThread, |
| 276 reinterpret_cast<uword>(this)); | 305 reinterpret_cast<uword>(this)); |
| 277 if (result != 0) { | 306 if (result != 0) { |
| 278 FATAL1("Failed to start read file thread %d", result); | 307 FATAL1("Failed to start read file thread %d", result); |
| 279 } | 308 } |
| 309 { |
| 310 MonitorLocker ml(read_thread_monitor_); |
| 311 while (!read_thread_exists_) { |
| 312 ml.Wait(); |
| 313 } |
| 314 ASSERT(read_thread_id_ != Thread::kInvalidThreadId); |
| 315 } |
| 280 return true; | 316 return true; |
| 281 } | 317 } |
| 282 } | 318 } |
| 283 | 319 |
| 284 | 320 |
| 285 bool Handle::IssueRecvFrom() { | 321 bool Handle::IssueRecvFrom() { |
| 286 return false; | 322 return false; |
| 287 } | 323 } |
| 288 | 324 |
| 289 | 325 |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 670 | 706 |
| 671 static void WriteFileThread(uword args) { | 707 static void WriteFileThread(uword args) { |
| 672 StdHandle* handle = reinterpret_cast<StdHandle*>(args); | 708 StdHandle* handle = reinterpret_cast<StdHandle*>(args); |
| 673 handle->RunWriteLoop(); | 709 handle->RunWriteLoop(); |
| 674 } | 710 } |
| 675 | 711 |
| 676 | 712 |
| 677 void StdHandle::RunWriteLoop() { | 713 void StdHandle::RunWriteLoop() { |
| 678 write_monitor_->Enter(); | 714 write_monitor_->Enter(); |
| 679 write_thread_running_ = true; | 715 write_thread_running_ = true; |
| 716 thread_id_ = Thread::GetCurrentThreadId(); |
| 680 // Notify we have started. | 717 // Notify we have started. |
| 681 write_monitor_->Notify(); | 718 write_monitor_->Notify(); |
| 682 | 719 |
| 683 while (write_thread_running_) { | 720 while (write_thread_running_) { |
| 684 write_monitor_->Wait(Monitor::kNoTimeout); | 721 write_monitor_->Wait(Monitor::kNoTimeout); |
| 685 if (pending_write_ != NULL) { | 722 if (pending_write_ != NULL) { |
| 686 // We woke up and had a pending write. Execute it. | 723 // We woke up and had a pending write. Execute it. |
| 687 WriteSyncCompleteAsync(); | 724 WriteSyncCompleteAsync(); |
| 688 } | 725 } |
| 689 } | 726 } |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 755 | 792 |
| 756 | 793 |
| 757 void StdHandle::DoClose() { | 794 void StdHandle::DoClose() { |
| 758 MonitorLocker locker(write_monitor_); | 795 MonitorLocker locker(write_monitor_); |
| 759 if (write_thread_exists_) { | 796 if (write_thread_exists_) { |
| 760 write_thread_running_ = false; | 797 write_thread_running_ = false; |
| 761 locker.Notify(); | 798 locker.Notify(); |
| 762 while (write_thread_exists_) { | 799 while (write_thread_exists_) { |
| 763 locker.Wait(Monitor::kNoTimeout); | 800 locker.Wait(Monitor::kNoTimeout); |
| 764 } | 801 } |
| 802 Thread::Join(thread_id_); |
| 765 } | 803 } |
| 766 Handle::DoClose(); | 804 Handle::DoClose(); |
| 767 } | 805 } |
| 768 | 806 |
| 769 | 807 |
| 770 bool ClientSocket::LoadDisconnectEx() { | 808 bool ClientSocket::LoadDisconnectEx() { |
| 771 // Load the DisconnectEx function into memory using WSAIoctl. | 809 // Load the DisconnectEx function into memory using WSAIoctl. |
| 772 GUID guid_disconnect_ex = WSAID_DISCONNECTEX; | 810 GUID guid_disconnect_ex = WSAID_DISCONNECTEX; |
| 773 DWORD bytes; | 811 DWORD bytes; |
| 774 int status = WSAIoctl(socket(), | 812 int status = WSAIoctl(socket(), |
| (...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1271 HandleConnect(client_socket, bytes, buffer); | 1309 HandleConnect(client_socket, bytes, buffer); |
| 1272 break; | 1310 break; |
| 1273 } | 1311 } |
| 1274 default: | 1312 default: |
| 1275 UNREACHABLE(); | 1313 UNREACHABLE(); |
| 1276 } | 1314 } |
| 1277 } | 1315 } |
| 1278 | 1316 |
| 1279 | 1317 |
| 1280 EventHandlerImplementation::EventHandlerImplementation() { | 1318 EventHandlerImplementation::EventHandlerImplementation() { |
| 1319 startup_monitor_ = new Monitor(); |
| 1320 handler_thread_id_ = Thread::kInvalidThreadId; |
| 1281 completion_port_ = | 1321 completion_port_ = |
| 1282 CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 1); | 1322 CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 1); |
| 1283 if (completion_port_ == NULL) { | 1323 if (completion_port_ == NULL) { |
| 1284 FATAL("Completion port creation failed"); | 1324 FATAL("Completion port creation failed"); |
| 1285 } | 1325 } |
| 1286 shutdown_ = false; | 1326 shutdown_ = false; |
| 1287 } | 1327 } |
| 1288 | 1328 |
| 1289 | 1329 |
| 1290 EventHandlerImplementation::~EventHandlerImplementation() { | 1330 EventHandlerImplementation::~EventHandlerImplementation() { |
| 1331 Thread::Join(handler_thread_id_); |
| 1332 delete startup_monitor_; |
| 1291 CloseHandle(completion_port_); | 1333 CloseHandle(completion_port_); |
| 1292 } | 1334 } |
| 1293 | 1335 |
| 1294 | 1336 |
| 1295 int64_t EventHandlerImplementation::GetTimeout() { | 1337 int64_t EventHandlerImplementation::GetTimeout() { |
| 1296 if (!timeout_queue_.HasTimeout()) { | 1338 if (!timeout_queue_.HasTimeout()) { |
| 1297 return kInfinityTimeout; | 1339 return kInfinityTimeout; |
| 1298 } | 1340 } |
| 1299 int64_t millis = timeout_queue_.CurrentTimeout() - | 1341 int64_t millis = timeout_queue_.CurrentTimeout() - |
| 1300 TimerUtils::GetCurrentTimeMilliseconds(); | 1342 TimerUtils::GetCurrentTimeMilliseconds(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1315 FATAL("PostQueuedCompletionStatus failed"); | 1357 FATAL("PostQueuedCompletionStatus failed"); |
| 1316 } | 1358 } |
| 1317 } | 1359 } |
| 1318 | 1360 |
| 1319 | 1361 |
| 1320 void EventHandlerImplementation::EventHandlerEntry(uword args) { | 1362 void EventHandlerImplementation::EventHandlerEntry(uword args) { |
| 1321 EventHandler* handler = reinterpret_cast<EventHandler*>(args); | 1363 EventHandler* handler = reinterpret_cast<EventHandler*>(args); |
| 1322 EventHandlerImplementation* handler_impl = &handler->delegate_; | 1364 EventHandlerImplementation* handler_impl = &handler->delegate_; |
| 1323 ASSERT(handler_impl != NULL); | 1365 ASSERT(handler_impl != NULL); |
| 1324 | 1366 |
| 1367 { |
| 1368 MonitorLocker ml(handler_impl->startup_monitor_); |
| 1369 handler_impl->handler_thread_id_ = Thread::GetCurrentThreadId(); |
| 1370 ml.Notify(); |
| 1371 } |
| 1372 |
| 1325 while (!handler_impl->shutdown_) { | 1373 while (!handler_impl->shutdown_) { |
| 1326 DWORD bytes; | 1374 DWORD bytes; |
| 1327 ULONG_PTR key; | 1375 ULONG_PTR key; |
| 1328 OVERLAPPED* overlapped; | 1376 OVERLAPPED* overlapped; |
| 1329 int64_t millis = handler_impl->GetTimeout(); | 1377 int64_t millis = handler_impl->GetTimeout(); |
| 1330 ASSERT(millis == kInfinityTimeout || millis >= 0); | 1378 ASSERT(millis == kInfinityTimeout || millis >= 0); |
| 1331 if (millis > kMaxInt32) millis = kMaxInt32; | 1379 if (millis > kMaxInt32) millis = kMaxInt32; |
| 1332 ASSERT(sizeof(int32_t) == sizeof(DWORD)); | 1380 ASSERT(sizeof(int32_t) == sizeof(DWORD)); |
| 1333 BOOL ok = GetQueuedCompletionStatus(handler_impl->completion_port(), | 1381 BOOL ok = GetQueuedCompletionStatus(handler_impl->completion_port(), |
| 1334 &bytes, | 1382 &bytes, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1375 } | 1423 } |
| 1376 | 1424 |
| 1377 | 1425 |
| 1378 void EventHandlerImplementation::Start(EventHandler* handler) { | 1426 void EventHandlerImplementation::Start(EventHandler* handler) { |
| 1379 int result = Thread::Start(EventHandlerEntry, | 1427 int result = Thread::Start(EventHandlerEntry, |
| 1380 reinterpret_cast<uword>(handler)); | 1428 reinterpret_cast<uword>(handler)); |
| 1381 if (result != 0) { | 1429 if (result != 0) { |
| 1382 FATAL1("Failed to start event handler thread %d", result); | 1430 FATAL1("Failed to start event handler thread %d", result); |
| 1383 } | 1431 } |
| 1384 | 1432 |
| 1433 { |
| 1434 MonitorLocker ml(startup_monitor_); |
| 1435 while (handler_thread_id_ == Thread::kInvalidThreadId) { |
| 1436 ml.Wait(); |
| 1437 } |
| 1438 } |
| 1439 |
| 1385 // Initialize Winsock32 | 1440 // Initialize Winsock32 |
| 1386 if (!Socket::Initialize()) { | 1441 if (!Socket::Initialize()) { |
| 1387 FATAL("Failed to initialized Windows sockets"); | 1442 FATAL("Failed to initialized Windows sockets"); |
| 1388 } | 1443 } |
| 1389 } | 1444 } |
| 1390 | 1445 |
| 1391 | 1446 |
| 1392 void EventHandlerImplementation::Shutdown() { | 1447 void EventHandlerImplementation::Shutdown() { |
| 1393 SendData(kShutdownId, 0, 0); | 1448 SendData(kShutdownId, 0, 0); |
| 1394 } | 1449 } |
| 1395 | 1450 |
| 1396 } // namespace bin | 1451 } // namespace bin |
| 1397 } // namespace dart | 1452 } // namespace dart |
| 1398 | 1453 |
| 1399 #endif // defined(TARGET_OS_WINDOWS) | 1454 #endif // defined(TARGET_OS_WINDOWS) |
| OLD | NEW |