Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: runtime/bin/eventhandler_win.cc

Issue 1275353005: VM thread shutdown. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698