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" |
11 #include "bin/eventhandler_win.h" | 11 #include "bin/eventhandler_win.h" |
12 | 12 |
13 #include <fcntl.h> // NOLINT | 13 #include <fcntl.h> // NOLINT |
14 #include <io.h> // NOLINT | 14 #include <io.h> // NOLINT |
15 #include <mswsock.h> // NOLINT | 15 #include <mswsock.h> // NOLINT |
16 #include <winsock2.h> // NOLINT | 16 #include <winsock2.h> // NOLINT |
17 #include <ws2tcpip.h> // NOLINT | 17 #include <ws2tcpip.h> // NOLINT |
18 | 18 |
19 #include "bin/builtin.h" | 19 #include "bin/builtin.h" |
20 #include "bin/dartutils.h" | 20 #include "bin/dartutils.h" |
21 #include "bin/lockers.h" | 21 #include "bin/lockers.h" |
22 #include "bin/log.h" | 22 #include "bin/log.h" |
23 #include "bin/socket.h" | 23 #include "bin/socket.h" |
24 #include "bin/thread.h" | 24 #include "bin/thread.h" |
25 #include "bin/utils.h" | 25 #include "bin/utils.h" |
26 | 26 |
27 #include "platform/utils.h" | 27 #include "platform/utils.h" |
28 | 28 |
29 namespace dart { | 29 namespace dart { |
30 namespace bin { | 30 namespace bin { |
31 | 31 |
32 static const int kBufferSize = 64 * 1024; | 32 static const int kBufferSize = 64 * 1024; |
33 static const int kStdOverlappedBufferSize = 16 * 1024; | 33 static const int kStdOverlappedBufferSize = 16 * 1024; |
34 static const int kMaxUDPPackageLength = 64 * 1024; | 34 static const int kMaxUDPPackageLength = 64 * 1024; |
35 | 35 |
36 OverlappedBuffer* OverlappedBuffer::AllocateBuffer(int buffer_size, | 36 OverlappedBuffer* OverlappedBuffer::AllocateBuffer(int buffer_size, |
37 Operation operation) { | 37 Operation operation) { |
38 OverlappedBuffer* buffer = | 38 OverlappedBuffer* buffer = |
39 new(buffer_size) OverlappedBuffer(buffer_size, operation); | 39 new (buffer_size) OverlappedBuffer(buffer_size, operation); |
40 return buffer; | 40 return buffer; |
41 } | 41 } |
42 | 42 |
43 | 43 |
44 OverlappedBuffer* OverlappedBuffer::AllocateAcceptBuffer(int buffer_size) { | 44 OverlappedBuffer* OverlappedBuffer::AllocateAcceptBuffer(int buffer_size) { |
45 OverlappedBuffer* buffer = AllocateBuffer(buffer_size, kAccept); | 45 OverlappedBuffer* buffer = AllocateBuffer(buffer_size, kAccept); |
46 return buffer; | 46 return buffer; |
47 } | 47 } |
48 | 48 |
49 | 49 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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_handle_(NULL), |
130 read_thread_starting_(false), | 130 read_thread_starting_(false), |
131 read_thread_finished_(false), | 131 read_thread_finished_(false), |
132 monitor_(new Monitor()) { | 132 monitor_(new Monitor()) {} |
133 } | |
134 | 133 |
135 | 134 |
136 Handle::~Handle() { | 135 Handle::~Handle() { |
137 delete monitor_; | 136 delete monitor_; |
138 } | 137 } |
139 | 138 |
140 | 139 |
141 bool Handle::CreateCompletionPort(HANDLE completion_port) { | 140 bool Handle::CreateCompletionPort(HANDLE completion_port) { |
142 completion_port_ = CreateIoCompletionPort(handle(), | 141 completion_port_ = CreateIoCompletionPort( |
143 completion_port, | 142 handle(), completion_port, reinterpret_cast<ULONG_PTR>(this), 0); |
144 reinterpret_cast<ULONG_PTR>(this), | |
145 0); | |
146 return (completion_port_ != NULL); | 143 return (completion_port_ != NULL); |
147 } | 144 } |
148 | 145 |
149 | 146 |
150 void Handle::Close() { | 147 void Handle::Close() { |
151 MonitorLocker ml(monitor_); | 148 MonitorLocker ml(monitor_); |
152 if (!IsClosing()) { | 149 if (!IsClosing()) { |
153 // Close the socket and set the closing state. This close method can be | 150 // Close the socket and set the closing state. This close method can be |
154 // called again if this socket has pending IO operations in flight. | 151 // called again if this socket has pending IO operations in flight. |
155 MarkClosing(); | 152 MarkClosing(); |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 NotifyReadThreadStarted(); | 270 NotifyReadThreadStarted(); |
274 ASSERT(pending_read_ != NULL); | 271 ASSERT(pending_read_ != NULL); |
275 ASSERT(pending_read_->GetBufferSize() >= kStdOverlappedBufferSize); | 272 ASSERT(pending_read_->GetBufferSize() >= kStdOverlappedBufferSize); |
276 | 273 |
277 DWORD buffer_size = pending_read_->GetBufferSize(); | 274 DWORD buffer_size = pending_read_->GetBufferSize(); |
278 if (GetFileType(handle_) == FILE_TYPE_CHAR) { | 275 if (GetFileType(handle_) == FILE_TYPE_CHAR) { |
279 buffer_size = kStdOverlappedBufferSize; | 276 buffer_size = kStdOverlappedBufferSize; |
280 } | 277 } |
281 char* buffer_start = pending_read_->GetBufferStart(); | 278 char* buffer_start = pending_read_->GetBufferStart(); |
282 DWORD bytes_read = 0; | 279 DWORD bytes_read = 0; |
283 BOOL ok = ReadFile(handle_, | 280 BOOL ok = ReadFile(handle_, buffer_start, buffer_size, &bytes_read, NULL); |
284 buffer_start, | |
285 buffer_size, | |
286 &bytes_read, | |
287 NULL); | |
288 if (!ok) { | 281 if (!ok) { |
289 bytes_read = 0; | 282 bytes_read = 0; |
290 } | 283 } |
291 OVERLAPPED* overlapped = pending_read_->GetCleanOverlapped(); | 284 OVERLAPPED* overlapped = pending_read_->GetCleanOverlapped(); |
292 ok = PostQueuedCompletionStatus(event_handler_->completion_port(), | 285 ok = |
293 bytes_read, | 286 PostQueuedCompletionStatus(event_handler_->completion_port(), bytes_read, |
294 reinterpret_cast<ULONG_PTR>(this), | 287 reinterpret_cast<ULONG_PTR>(this), overlapped); |
295 overlapped); | |
296 if (!ok) { | 288 if (!ok) { |
297 FATAL("PostQueuedCompletionStatus failed"); | 289 FATAL("PostQueuedCompletionStatus failed"); |
298 } | 290 } |
299 NotifyReadThreadFinished(); | 291 NotifyReadThreadFinished(); |
300 } | 292 } |
301 | 293 |
302 | 294 |
303 bool Handle::IssueRead() { | 295 bool Handle::IssueRead() { |
304 ASSERT(type_ != kListenSocket); | 296 ASSERT(type_ != kListenSocket); |
305 ASSERT(pending_read_ == NULL); | 297 ASSERT(pending_read_ == NULL); |
306 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize); | 298 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize); |
307 if (SupportsOverlappedIO()) { | 299 if (SupportsOverlappedIO()) { |
308 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 300 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
309 | 301 |
310 BOOL ok = ReadFile(handle_, | 302 BOOL ok = |
311 buffer->GetBufferStart(), | 303 ReadFile(handle_, buffer->GetBufferStart(), buffer->GetBufferSize(), |
312 buffer->GetBufferSize(), | 304 NULL, buffer->GetCleanOverlapped()); |
313 NULL, | |
314 buffer->GetCleanOverlapped()); | |
315 if (ok || (GetLastError() == ERROR_IO_PENDING)) { | 305 if (ok || (GetLastError() == ERROR_IO_PENDING)) { |
316 // Completing asynchronously. | 306 // Completing asynchronously. |
317 pending_read_ = buffer; | 307 pending_read_ = buffer; |
318 return true; | 308 return true; |
319 } | 309 } |
320 OverlappedBuffer::DisposeBuffer(buffer); | 310 OverlappedBuffer::DisposeBuffer(buffer); |
321 HandleIssueError(); | 311 HandleIssueError(); |
322 return false; | 312 return false; |
323 } else { | 313 } else { |
324 // Completing asynchronously through thread. | 314 // Completing asynchronously through thread. |
325 pending_read_ = buffer; | 315 pending_read_ = buffer; |
326 read_thread_starting_ = true; | 316 read_thread_starting_ = true; |
327 int result = Thread::Start(ReadFileThread, | 317 int result = Thread::Start(ReadFileThread, reinterpret_cast<uword>(this)); |
328 reinterpret_cast<uword>(this)); | |
329 if (result != 0) { | 318 if (result != 0) { |
330 FATAL1("Failed to start read file thread %d", result); | 319 FATAL1("Failed to start read file thread %d", result); |
331 } | 320 } |
332 return true; | 321 return true; |
333 } | 322 } |
334 } | 323 } |
335 | 324 |
336 | 325 |
337 bool Handle::IssueRecvFrom() { | 326 bool Handle::IssueRecvFrom() { |
338 return false; | 327 return false; |
339 } | 328 } |
340 | 329 |
341 | 330 |
342 bool Handle::IssueWrite() { | 331 bool Handle::IssueWrite() { |
343 MonitorLocker ml(monitor_); | 332 MonitorLocker ml(monitor_); |
344 ASSERT(type_ != kListenSocket); | 333 ASSERT(type_ != kListenSocket); |
345 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 334 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
346 ASSERT(pending_write_ != NULL); | 335 ASSERT(pending_write_ != NULL); |
347 ASSERT(pending_write_->operation() == OverlappedBuffer::kWrite); | 336 ASSERT(pending_write_->operation() == OverlappedBuffer::kWrite); |
348 | 337 |
349 OverlappedBuffer* buffer = pending_write_; | 338 OverlappedBuffer* buffer = pending_write_; |
350 BOOL ok = WriteFile(handle_, | 339 BOOL ok = |
351 buffer->GetBufferStart(), | 340 WriteFile(handle_, buffer->GetBufferStart(), buffer->GetBufferSize(), |
352 buffer->GetBufferSize(), | 341 NULL, buffer->GetCleanOverlapped()); |
353 NULL, | |
354 buffer->GetCleanOverlapped()); | |
355 if (ok || (GetLastError() == ERROR_IO_PENDING)) { | 342 if (ok || (GetLastError() == ERROR_IO_PENDING)) { |
356 // Completing asynchronously. | 343 // Completing asynchronously. |
357 pending_write_ = buffer; | 344 pending_write_ = buffer; |
358 return true; | 345 return true; |
359 } | 346 } |
360 OverlappedBuffer::DisposeBuffer(buffer); | 347 OverlappedBuffer::DisposeBuffer(buffer); |
361 HandleIssueError(); | 348 HandleIssueError(); |
362 return false; | 349 return false; |
363 } | 350 } |
364 | 351 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 | 413 |
427 | 414 |
428 bool DirectoryWatchHandle::IssueRead() { | 415 bool DirectoryWatchHandle::IssueRead() { |
429 // It may have been started before, as we start the directory-handler when | 416 // It may have been started before, as we start the directory-handler when |
430 // we create it. | 417 // we create it. |
431 if ((pending_read_ != NULL) || (data_ready_ != NULL)) { | 418 if ((pending_read_ != NULL) || (data_ready_ != NULL)) { |
432 return true; | 419 return true; |
433 } | 420 } |
434 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize); | 421 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize); |
435 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 422 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
436 BOOL ok = ReadDirectoryChangesW(handle_, | 423 BOOL ok = ReadDirectoryChangesW(handle_, buffer->GetBufferStart(), |
437 buffer->GetBufferStart(), | 424 buffer->GetBufferSize(), recursive_, events_, |
438 buffer->GetBufferSize(), | 425 NULL, buffer->GetCleanOverlapped(), NULL); |
439 recursive_, | |
440 events_, | |
441 NULL, | |
442 buffer->GetCleanOverlapped(), | |
443 NULL); | |
444 if (ok || (GetLastError() == ERROR_IO_PENDING)) { | 426 if (ok || (GetLastError() == ERROR_IO_PENDING)) { |
445 // Completing asynchronously. | 427 // Completing asynchronously. |
446 pending_read_ = buffer; | 428 pending_read_ = buffer; |
447 return true; | 429 return true; |
448 } | 430 } |
449 OverlappedBuffer::DisposeBuffer(buffer); | 431 OverlappedBuffer::DisposeBuffer(buffer); |
450 return false; | 432 return false; |
451 } | 433 } |
452 | 434 |
453 | 435 |
(...skipping 18 matching lines...) Expand all Loading... |
472 HandleError(this); | 454 HandleError(this); |
473 } | 455 } |
474 WSASetLastError(error); | 456 WSASetLastError(error); |
475 } | 457 } |
476 | 458 |
477 | 459 |
478 bool ListenSocket::LoadAcceptEx() { | 460 bool ListenSocket::LoadAcceptEx() { |
479 // Load the AcceptEx function into memory using WSAIoctl. | 461 // Load the AcceptEx function into memory using WSAIoctl. |
480 GUID guid_accept_ex = WSAID_ACCEPTEX; | 462 GUID guid_accept_ex = WSAID_ACCEPTEX; |
481 DWORD bytes; | 463 DWORD bytes; |
482 int status = WSAIoctl(socket(), | 464 int status = WSAIoctl(socket(), SIO_GET_EXTENSION_FUNCTION_POINTER, |
483 SIO_GET_EXTENSION_FUNCTION_POINTER, | 465 &guid_accept_ex, sizeof(guid_accept_ex), &AcceptEx_, |
484 &guid_accept_ex, | 466 sizeof(AcceptEx_), &bytes, NULL, NULL); |
485 sizeof(guid_accept_ex), | |
486 &AcceptEx_, | |
487 sizeof(AcceptEx_), | |
488 &bytes, | |
489 NULL, | |
490 NULL); | |
491 return (status != SOCKET_ERROR); | 467 return (status != SOCKET_ERROR); |
492 } | 468 } |
493 | 469 |
494 | 470 |
495 bool ListenSocket::IssueAccept() { | 471 bool ListenSocket::IssueAccept() { |
496 MonitorLocker ml(monitor_); | 472 MonitorLocker ml(monitor_); |
497 | 473 |
498 // For AcceptEx there needs to be buffer storage for address | 474 // For AcceptEx there needs to be buffer storage for address |
499 // information for two addresses (local and remote address). The | 475 // information for two addresses (local and remote address). The |
500 // AcceptEx documentation says: "This value must be at least 16 | 476 // AcceptEx documentation says: "This value must be at least 16 |
501 // bytes more than the maximum address length for the transport | 477 // bytes more than the maximum address length for the transport |
502 // protocol in use." | 478 // protocol in use." |
503 static const int kAcceptExAddressAdditionalBytes = 16; | 479 static const int kAcceptExAddressAdditionalBytes = 16; |
504 static const int kAcceptExAddressStorageSize = | 480 static const int kAcceptExAddressStorageSize = |
505 sizeof(SOCKADDR_STORAGE) + kAcceptExAddressAdditionalBytes; | 481 sizeof(SOCKADDR_STORAGE) + kAcceptExAddressAdditionalBytes; |
506 OverlappedBuffer* buffer = | 482 OverlappedBuffer* buffer = |
507 OverlappedBuffer::AllocateAcceptBuffer(2 * kAcceptExAddressStorageSize); | 483 OverlappedBuffer::AllocateAcceptBuffer(2 * kAcceptExAddressStorageSize); |
508 DWORD received; | 484 DWORD received; |
509 BOOL ok; | 485 BOOL ok; |
510 ok = AcceptEx_(socket(), | 486 ok = AcceptEx_(socket(), buffer->client(), buffer->GetBufferStart(), |
511 buffer->client(), | |
512 buffer->GetBufferStart(), | |
513 0, // For now don't receive data with accept. | 487 0, // For now don't receive data with accept. |
514 kAcceptExAddressStorageSize, | 488 kAcceptExAddressStorageSize, kAcceptExAddressStorageSize, |
515 kAcceptExAddressStorageSize, | 489 &received, buffer->GetCleanOverlapped()); |
516 &received, | |
517 buffer->GetCleanOverlapped()); | |
518 if (!ok) { | 490 if (!ok) { |
519 if (WSAGetLastError() != WSA_IO_PENDING) { | 491 if (WSAGetLastError() != WSA_IO_PENDING) { |
520 int error = WSAGetLastError(); | 492 int error = WSAGetLastError(); |
521 closesocket(buffer->client()); | 493 closesocket(buffer->client()); |
522 OverlappedBuffer::DisposeBuffer(buffer); | 494 OverlappedBuffer::DisposeBuffer(buffer); |
523 WSASetLastError(error); | 495 WSASetLastError(error); |
524 return false; | 496 return false; |
525 } | 497 } |
526 } | 498 } |
527 | 499 |
528 pending_accept_count_++; | 500 pending_accept_count_++; |
529 | 501 |
530 return true; | 502 return true; |
531 } | 503 } |
532 | 504 |
533 | 505 |
534 void ListenSocket::AcceptComplete(OverlappedBuffer* buffer, | 506 void ListenSocket::AcceptComplete(OverlappedBuffer* buffer, |
535 HANDLE completion_port) { | 507 HANDLE completion_port) { |
536 MonitorLocker ml(monitor_); | 508 MonitorLocker ml(monitor_); |
537 if (!IsClosing()) { | 509 if (!IsClosing()) { |
538 // Update the accepted socket to support the full range of API calls. | 510 // Update the accepted socket to support the full range of API calls. |
539 SOCKET s = socket(); | 511 SOCKET s = socket(); |
540 int rc = setsockopt(buffer->client(), | 512 int rc = setsockopt(buffer->client(), SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, |
541 SOL_SOCKET, | |
542 SO_UPDATE_ACCEPT_CONTEXT, | |
543 reinterpret_cast<char*>(&s), sizeof(s)); | 513 reinterpret_cast<char*>(&s), sizeof(s)); |
544 if (rc == NO_ERROR) { | 514 if (rc == NO_ERROR) { |
545 // Insert the accepted socket into the list. | 515 // Insert the accepted socket into the list. |
546 ClientSocket* client_socket = new ClientSocket(buffer->client()); | 516 ClientSocket* client_socket = new ClientSocket(buffer->client()); |
547 client_socket->mark_connected(); | 517 client_socket->mark_connected(); |
548 client_socket->CreateCompletionPort(completion_port); | 518 client_socket->CreateCompletionPort(completion_port); |
549 if (accepted_head_ == NULL) { | 519 if (accepted_head_ == NULL) { |
550 accepted_head_ = client_socket; | 520 accepted_head_ = client_socket; |
551 accepted_tail_ = client_socket; | 521 accepted_tail_ = client_socket; |
552 } else { | 522 } else { |
(...skipping 22 matching lines...) Expand all Loading... |
575 delete handle; | 545 delete handle; |
576 } | 546 } |
577 } | 547 } |
578 | 548 |
579 | 549 |
580 void ListenSocket::DoClose() { | 550 void ListenSocket::DoClose() { |
581 closesocket(socket()); | 551 closesocket(socket()); |
582 handle_ = INVALID_HANDLE_VALUE; | 552 handle_ = INVALID_HANDLE_VALUE; |
583 while (CanAccept()) { | 553 while (CanAccept()) { |
584 // Get rid of connections already accepted. | 554 // Get rid of connections already accepted. |
585 ClientSocket *client = Accept(); | 555 ClientSocket* client = Accept(); |
586 if (client != NULL) { | 556 if (client != NULL) { |
587 client->Close(); | 557 client->Close(); |
588 DeleteIfClosed(client); | 558 DeleteIfClosed(client); |
589 } else { | 559 } else { |
590 break; | 560 break; |
591 } | 561 } |
592 } | 562 } |
593 } | 563 } |
594 | 564 |
595 | 565 |
596 bool ListenSocket::CanAccept() { | 566 bool ListenSocket::CanAccept() { |
597 MonitorLocker ml(monitor_); | 567 MonitorLocker ml(monitor_); |
598 return accepted_head_ != NULL; | 568 return accepted_head_ != NULL; |
599 } | 569 } |
600 | 570 |
601 | 571 |
602 ClientSocket* ListenSocket::Accept() { | 572 ClientSocket* ListenSocket::Accept() { |
603 MonitorLocker ml(monitor_); | 573 MonitorLocker ml(monitor_); |
604 | 574 |
605 ClientSocket *result = NULL; | 575 ClientSocket* result = NULL; |
606 | 576 |
607 if (accepted_head_ != NULL) { | 577 if (accepted_head_ != NULL) { |
608 result = accepted_head_; | 578 result = accepted_head_; |
609 accepted_head_ = accepted_head_->next(); | 579 accepted_head_ = accepted_head_->next(); |
610 if (accepted_head_ == NULL) { | 580 if (accepted_head_ == NULL) { |
611 accepted_tail_ = NULL; | 581 accepted_tail_ = NULL; |
612 } | 582 } |
613 result->set_next(NULL); | 583 result->set_next(NULL); |
614 accepted_count_--; | 584 accepted_count_--; |
615 } | 585 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 ASSERT(!data_ready_->IsEmpty()); | 623 ASSERT(!data_ready_->IsEmpty()); |
654 return data_ready_->GetRemainingLength(); | 624 return data_ready_->GetRemainingLength(); |
655 } | 625 } |
656 | 626 |
657 | 627 |
658 intptr_t Handle::Read(void* buffer, intptr_t num_bytes) { | 628 intptr_t Handle::Read(void* buffer, intptr_t num_bytes) { |
659 MonitorLocker ml(monitor_); | 629 MonitorLocker ml(monitor_); |
660 if (data_ready_ == NULL) { | 630 if (data_ready_ == NULL) { |
661 return 0; | 631 return 0; |
662 } | 632 } |
663 num_bytes = data_ready_->Read( | 633 num_bytes = |
664 buffer, Utils::Minimum<intptr_t>(num_bytes, INT_MAX)); | 634 data_ready_->Read(buffer, Utils::Minimum<intptr_t>(num_bytes, INT_MAX)); |
665 if (data_ready_->IsEmpty()) { | 635 if (data_ready_->IsEmpty()) { |
666 OverlappedBuffer::DisposeBuffer(data_ready_); | 636 OverlappedBuffer::DisposeBuffer(data_ready_); |
667 data_ready_ = NULL; | 637 data_ready_ = NULL; |
668 if (!IsClosing() && !IsClosedRead()) { | 638 if (!IsClosing() && !IsClosedRead()) { |
669 IssueRead(); | 639 IssueRead(); |
670 } | 640 } |
671 } | 641 } |
672 return num_bytes; | 642 return num_bytes; |
673 } | 643 } |
674 | 644 |
675 | 645 |
676 intptr_t Handle::RecvFrom( | 646 intptr_t Handle::RecvFrom(void* buffer, |
677 void* buffer, intptr_t num_bytes, struct sockaddr* sa, socklen_t sa_len) { | 647 intptr_t num_bytes, |
| 648 struct sockaddr* sa, |
| 649 socklen_t sa_len) { |
678 MonitorLocker ml(monitor_); | 650 MonitorLocker ml(monitor_); |
679 if (data_ready_ == NULL) { | 651 if (data_ready_ == NULL) { |
680 return 0; | 652 return 0; |
681 } | 653 } |
682 num_bytes = data_ready_->Read( | 654 num_bytes = |
683 buffer, Utils::Minimum<intptr_t>(num_bytes, INT_MAX)); | 655 data_ready_->Read(buffer, Utils::Minimum<intptr_t>(num_bytes, INT_MAX)); |
684 if (data_ready_->from()->sa_family == AF_INET) { | 656 if (data_ready_->from()->sa_family == AF_INET) { |
685 ASSERT(sa_len >= sizeof(struct sockaddr_in)); | 657 ASSERT(sa_len >= sizeof(struct sockaddr_in)); |
686 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in)); | 658 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in)); |
687 } else { | 659 } else { |
688 ASSERT(data_ready_->from()->sa_family == AF_INET6); | 660 ASSERT(data_ready_->from()->sa_family == AF_INET6); |
689 ASSERT(sa_len >= sizeof(struct sockaddr_in6)); | 661 ASSERT(sa_len >= sizeof(struct sockaddr_in6)); |
690 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in6)); | 662 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in6)); |
691 } | 663 } |
692 // Always dispose of the buffer, as UDP messages must be read in their | 664 // Always dispose of the buffer, as UDP messages must be read in their |
693 // entirety to match how recvfrom works in a socket. | 665 // entirety to match how recvfrom works in a socket. |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
770 | 742 |
771 write_thread_exists_ = false; | 743 write_thread_exists_ = false; |
772 ml.Notify(); | 744 ml.Notify(); |
773 } | 745 } |
774 | 746 |
775 | 747 |
776 void StdHandle::WriteSyncCompleteAsync() { | 748 void StdHandle::WriteSyncCompleteAsync() { |
777 ASSERT(pending_write_ != NULL); | 749 ASSERT(pending_write_ != NULL); |
778 | 750 |
779 DWORD bytes_written = -1; | 751 DWORD bytes_written = -1; |
780 BOOL ok = WriteFile(handle_, | 752 BOOL ok = WriteFile(handle_, pending_write_->GetBufferStart(), |
781 pending_write_->GetBufferStart(), | 753 pending_write_->GetBufferSize(), &bytes_written, NULL); |
782 pending_write_->GetBufferSize(), | |
783 &bytes_written, | |
784 NULL); | |
785 if (!ok) { | 754 if (!ok) { |
786 bytes_written = 0; | 755 bytes_written = 0; |
787 } | 756 } |
788 thread_wrote_ += bytes_written; | 757 thread_wrote_ += bytes_written; |
789 OVERLAPPED* overlapped = pending_write_->GetCleanOverlapped(); | 758 OVERLAPPED* overlapped = pending_write_->GetCleanOverlapped(); |
790 ok = PostQueuedCompletionStatus(event_handler_->completion_port(), | 759 ok = PostQueuedCompletionStatus( |
791 bytes_written, | 760 event_handler_->completion_port(), bytes_written, |
792 reinterpret_cast<ULONG_PTR>(this), | 761 reinterpret_cast<ULONG_PTR>(this), overlapped); |
793 overlapped); | |
794 if (!ok) { | 762 if (!ok) { |
795 FATAL("PostQueuedCompletionStatus failed"); | 763 FATAL("PostQueuedCompletionStatus failed"); |
796 } | 764 } |
797 } | 765 } |
798 | 766 |
799 intptr_t StdHandle::Write(const void* buffer, intptr_t num_bytes) { | 767 intptr_t StdHandle::Write(const void* buffer, intptr_t num_bytes) { |
800 MonitorLocker ml(monitor_); | 768 MonitorLocker ml(monitor_); |
801 if (pending_write_ != NULL) { | 769 if (pending_write_ != NULL) { |
802 return 0; | 770 return 0; |
803 } | 771 } |
804 if (num_bytes > kBufferSize) { | 772 if (num_bytes > kBufferSize) { |
805 num_bytes = kBufferSize; | 773 num_bytes = kBufferSize; |
806 } | 774 } |
807 // In the case of stdout and stderr, OverlappedIO is not supported. | 775 // In the case of stdout and stderr, OverlappedIO is not supported. |
808 // Here we'll instead use a thread, to make it async. | 776 // Here we'll instead use a thread, to make it async. |
809 // This code is actually never exposed to the user, as stdout and stderr is | 777 // This code is actually never exposed to the user, as stdout and stderr is |
810 // not available as a RawSocket, but only wrapped in a Socket. | 778 // not available as a RawSocket, but only wrapped in a Socket. |
811 // Note that we return '0', unless a thread have already completed a write. | 779 // Note that we return '0', unless a thread have already completed a write. |
812 if (thread_wrote_ > 0) { | 780 if (thread_wrote_ > 0) { |
813 if (num_bytes > thread_wrote_) { | 781 if (num_bytes > thread_wrote_) { |
814 num_bytes = thread_wrote_; | 782 num_bytes = thread_wrote_; |
815 } | 783 } |
816 thread_wrote_ -= num_bytes; | 784 thread_wrote_ -= num_bytes; |
817 return num_bytes; | 785 return num_bytes; |
818 } | 786 } |
819 if (!write_thread_exists_) { | 787 if (!write_thread_exists_) { |
820 write_thread_exists_ = true; | 788 write_thread_exists_ = true; |
821 int result = Thread::Start( | 789 int result = Thread::Start(WriteFileThread, reinterpret_cast<uword>(this)); |
822 WriteFileThread, reinterpret_cast<uword>(this)); | |
823 if (result != 0) { | 790 if (result != 0) { |
824 FATAL1("Failed to start write file thread %d", result); | 791 FATAL1("Failed to start write file thread %d", result); |
825 } | 792 } |
826 while (!write_thread_running_) { | 793 while (!write_thread_running_) { |
827 // Wait until we the thread is running. | 794 // Wait until we the thread is running. |
828 ml.Wait(Monitor::kNoTimeout); | 795 ml.Wait(Monitor::kNoTimeout); |
829 } | 796 } |
830 } | 797 } |
831 // Only queue up to INT_MAX bytes. | 798 // Only queue up to INT_MAX bytes. |
832 int truncated_bytes = Utils::Minimum<intptr_t>(num_bytes, INT_MAX); | 799 int truncated_bytes = Utils::Minimum<intptr_t>(num_bytes, INT_MAX); |
(...skipping 19 matching lines...) Expand all Loading... |
852 ASSERT(res == WAIT_OBJECT_0); | 819 ASSERT(res == WAIT_OBJECT_0); |
853 } | 820 } |
854 Handle::DoClose(); | 821 Handle::DoClose(); |
855 } | 822 } |
856 | 823 |
857 | 824 |
858 bool ClientSocket::LoadDisconnectEx() { | 825 bool ClientSocket::LoadDisconnectEx() { |
859 // Load the DisconnectEx function into memory using WSAIoctl. | 826 // Load the DisconnectEx function into memory using WSAIoctl. |
860 GUID guid_disconnect_ex = WSAID_DISCONNECTEX; | 827 GUID guid_disconnect_ex = WSAID_DISCONNECTEX; |
861 DWORD bytes; | 828 DWORD bytes; |
862 int status = WSAIoctl(socket(), | 829 int status = |
863 SIO_GET_EXTENSION_FUNCTION_POINTER, | 830 WSAIoctl(socket(), SIO_GET_EXTENSION_FUNCTION_POINTER, |
864 &guid_disconnect_ex, | 831 &guid_disconnect_ex, sizeof(guid_disconnect_ex), &DisconnectEx_, |
865 sizeof(guid_disconnect_ex), | 832 sizeof(DisconnectEx_), &bytes, NULL, NULL); |
866 &DisconnectEx_, | |
867 sizeof(DisconnectEx_), | |
868 &bytes, | |
869 NULL, | |
870 NULL); | |
871 return (status != SOCKET_ERROR); | 833 return (status != SOCKET_ERROR); |
872 } | 834 } |
873 | 835 |
874 | 836 |
875 void ClientSocket::Shutdown(int how) { | 837 void ClientSocket::Shutdown(int how) { |
876 int rc = shutdown(socket(), how); | 838 int rc = shutdown(socket(), how); |
877 if (how == SD_RECEIVE) { | 839 if (how == SD_RECEIVE) { |
878 MarkClosedRead(); | 840 MarkClosedRead(); |
879 } | 841 } |
880 if (how == SD_SEND) { | 842 if (how == SD_SEND) { |
(...skipping 18 matching lines...) Expand all Loading... |
899 MonitorLocker ml(monitor_); | 861 MonitorLocker ml(monitor_); |
900 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 862 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
901 ASSERT(pending_read_ == NULL); | 863 ASSERT(pending_read_ == NULL); |
902 | 864 |
903 // TODO(sgjesse): Use a MTU value here. Only the loopback adapter can | 865 // TODO(sgjesse): Use a MTU value here. Only the loopback adapter can |
904 // handle 64k datagrams. | 866 // handle 64k datagrams. |
905 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(65536); | 867 OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(65536); |
906 | 868 |
907 DWORD flags; | 869 DWORD flags; |
908 flags = 0; | 870 flags = 0; |
909 int rc = WSARecv(socket(), | 871 int rc = WSARecv(socket(), buffer->GetWASBUF(), 1, NULL, &flags, |
910 buffer->GetWASBUF(), | 872 buffer->GetCleanOverlapped(), NULL); |
911 1, | |
912 NULL, | |
913 &flags, | |
914 buffer->GetCleanOverlapped(), | |
915 NULL); | |
916 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { | 873 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { |
917 pending_read_ = buffer; | 874 pending_read_ = buffer; |
918 return true; | 875 return true; |
919 } | 876 } |
920 OverlappedBuffer::DisposeBuffer(buffer); | 877 OverlappedBuffer::DisposeBuffer(buffer); |
921 pending_read_ = NULL; | 878 pending_read_ = NULL; |
922 HandleIssueError(); | 879 HandleIssueError(); |
923 return false; | 880 return false; |
924 } | 881 } |
925 | 882 |
926 | 883 |
927 bool ClientSocket::IssueWrite() { | 884 bool ClientSocket::IssueWrite() { |
928 MonitorLocker ml(monitor_); | 885 MonitorLocker ml(monitor_); |
929 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 886 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
930 ASSERT(pending_write_ != NULL); | 887 ASSERT(pending_write_ != NULL); |
931 ASSERT(pending_write_->operation() == OverlappedBuffer::kWrite); | 888 ASSERT(pending_write_->operation() == OverlappedBuffer::kWrite); |
932 | 889 |
933 int rc = WSASend(socket(), | 890 int rc = WSASend(socket(), pending_write_->GetWASBUF(), 1, NULL, 0, |
934 pending_write_->GetWASBUF(), | 891 pending_write_->GetCleanOverlapped(), NULL); |
935 1, | |
936 NULL, | |
937 0, | |
938 pending_write_->GetCleanOverlapped(), | |
939 NULL); | |
940 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { | 892 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { |
941 return true; | 893 return true; |
942 } | 894 } |
943 OverlappedBuffer::DisposeBuffer(pending_write_); | 895 OverlappedBuffer::DisposeBuffer(pending_write_); |
944 pending_write_ = NULL; | 896 pending_write_ = NULL; |
945 HandleIssueError(); | 897 HandleIssueError(); |
946 return false; | 898 return false; |
947 } | 899 } |
948 | 900 |
949 | 901 |
950 void ClientSocket::IssueDisconnect() { | 902 void ClientSocket::IssueDisconnect() { |
951 OverlappedBuffer* buffer = OverlappedBuffer::AllocateDisconnectBuffer(); | 903 OverlappedBuffer* buffer = OverlappedBuffer::AllocateDisconnectBuffer(); |
952 BOOL ok = DisconnectEx_( | 904 BOOL ok = |
953 socket(), buffer->GetCleanOverlapped(), TF_REUSE_SOCKET, 0); | 905 DisconnectEx_(socket(), buffer->GetCleanOverlapped(), TF_REUSE_SOCKET, 0); |
954 // DisconnectEx works like other OverlappedIO APIs, where we can get either an | 906 // DisconnectEx works like other OverlappedIO APIs, where we can get either an |
955 // immediate success or delayed operation by WSA_IO_PENDING being set. | 907 // immediate success or delayed operation by WSA_IO_PENDING being set. |
956 if (ok || (WSAGetLastError() != WSA_IO_PENDING)) { | 908 if (ok || (WSAGetLastError() != WSA_IO_PENDING)) { |
957 DisconnectComplete(buffer); | 909 DisconnectComplete(buffer); |
958 } | 910 } |
959 NotifyAllDartPorts(1 << kDestroyedEvent); | 911 NotifyAllDartPorts(1 << kDestroyedEvent); |
960 RemoveAllPorts(); | 912 RemoveAllPorts(); |
961 } | 913 } |
962 | 914 |
963 | 915 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1002 return connected_ && closed_; | 954 return connected_ && closed_; |
1003 } | 955 } |
1004 | 956 |
1005 | 957 |
1006 bool DatagramSocket::IssueSendTo(struct sockaddr* sa, socklen_t sa_len) { | 958 bool DatagramSocket::IssueSendTo(struct sockaddr* sa, socklen_t sa_len) { |
1007 MonitorLocker ml(monitor_); | 959 MonitorLocker ml(monitor_); |
1008 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 960 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
1009 ASSERT(pending_write_ != NULL); | 961 ASSERT(pending_write_ != NULL); |
1010 ASSERT(pending_write_->operation() == OverlappedBuffer::kSendTo); | 962 ASSERT(pending_write_->operation() == OverlappedBuffer::kSendTo); |
1011 | 963 |
1012 int rc = WSASendTo(socket(), | 964 int rc = WSASendTo(socket(), pending_write_->GetWASBUF(), 1, NULL, 0, sa, |
1013 pending_write_->GetWASBUF(), | 965 sa_len, pending_write_->GetCleanOverlapped(), NULL); |
1014 1, | |
1015 NULL, | |
1016 0, | |
1017 sa, | |
1018 sa_len, | |
1019 pending_write_->GetCleanOverlapped(), | |
1020 NULL); | |
1021 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { | 966 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { |
1022 return true; | 967 return true; |
1023 } | 968 } |
1024 OverlappedBuffer::DisposeBuffer(pending_write_); | 969 OverlappedBuffer::DisposeBuffer(pending_write_); |
1025 pending_write_ = NULL; | 970 pending_write_ = NULL; |
1026 HandleIssueError(); | 971 HandleIssueError(); |
1027 return false; | 972 return false; |
1028 } | 973 } |
1029 | 974 |
1030 | 975 |
1031 bool DatagramSocket::IssueRecvFrom() { | 976 bool DatagramSocket::IssueRecvFrom() { |
1032 MonitorLocker ml(monitor_); | 977 MonitorLocker ml(monitor_); |
1033 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 978 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
1034 ASSERT(pending_read_ == NULL); | 979 ASSERT(pending_read_ == NULL); |
1035 | 980 |
1036 OverlappedBuffer* buffer = | 981 OverlappedBuffer* buffer = |
1037 OverlappedBuffer::AllocateRecvFromBuffer(kMaxUDPPackageLength); | 982 OverlappedBuffer::AllocateRecvFromBuffer(kMaxUDPPackageLength); |
1038 | 983 |
1039 DWORD flags; | 984 DWORD flags; |
1040 flags = 0; | 985 flags = 0; |
1041 int rc = WSARecvFrom(socket(), | 986 int rc = WSARecvFrom(socket(), buffer->GetWASBUF(), 1, NULL, &flags, |
1042 buffer->GetWASBUF(), | 987 buffer->from(), buffer->from_len_addr(), |
1043 1, | 988 buffer->GetCleanOverlapped(), NULL); |
1044 NULL, | |
1045 &flags, | |
1046 buffer->from(), | |
1047 buffer->from_len_addr(), | |
1048 buffer->GetCleanOverlapped(), | |
1049 NULL); | |
1050 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { | 989 if ((rc == NO_ERROR) || (WSAGetLastError() == WSA_IO_PENDING)) { |
1051 pending_read_ = buffer; | 990 pending_read_ = buffer; |
1052 return true; | 991 return true; |
1053 } | 992 } |
1054 OverlappedBuffer::DisposeBuffer(buffer); | 993 OverlappedBuffer::DisposeBuffer(buffer); |
1055 pending_read_ = NULL; | 994 pending_read_ = NULL; |
1056 HandleIssueError(); | 995 HandleIssueError(); |
1057 return false; | 996 return false; |
1058 } | 997 } |
1059 | 998 |
(...skipping 29 matching lines...) Expand all Loading... |
1089 // Change of timeout request. Just set the new timeout and port as the | 1028 // Change of timeout request. Just set the new timeout and port as the |
1090 // completion thread will use the new timeout value for its next wait. | 1029 // completion thread will use the new timeout value for its next wait. |
1091 timeout_queue_.UpdateTimeout(msg->dart_port, msg->data); | 1030 timeout_queue_.UpdateTimeout(msg->dart_port, msg->data); |
1092 } else if (msg->id == kShutdownId) { | 1031 } else if (msg->id == kShutdownId) { |
1093 shutdown_ = true; | 1032 shutdown_ = true; |
1094 } else { | 1033 } else { |
1095 Handle* handle = reinterpret_cast<Handle*>(msg->id); | 1034 Handle* handle = reinterpret_cast<Handle*>(msg->id); |
1096 ASSERT(handle != NULL); | 1035 ASSERT(handle != NULL); |
1097 | 1036 |
1098 if (handle->is_listen_socket()) { | 1037 if (handle->is_listen_socket()) { |
1099 ListenSocket* listen_socket = | 1038 ListenSocket* listen_socket = reinterpret_cast<ListenSocket*>(handle); |
1100 reinterpret_cast<ListenSocket*>(handle); | |
1101 listen_socket->EnsureInitialized(this); | 1039 listen_socket->EnsureInitialized(this); |
1102 | 1040 |
1103 MonitorLocker ml(listen_socket->monitor_); | 1041 MonitorLocker ml(listen_socket->monitor_); |
1104 | 1042 |
1105 if (IS_COMMAND(msg->data, kReturnTokenCommand)) { | 1043 if (IS_COMMAND(msg->data, kReturnTokenCommand)) { |
1106 listen_socket->ReturnTokens(msg->dart_port, TOKEN_COUNT(msg->data)); | 1044 listen_socket->ReturnTokens(msg->dart_port, TOKEN_COUNT(msg->data)); |
1107 } else if (IS_COMMAND(msg->data, kSetEventMaskCommand)) { | 1045 } else if (IS_COMMAND(msg->data, kSetEventMaskCommand)) { |
1108 // `events` can only have kInEvent/kOutEvent flags set. | 1046 // `events` can only have kInEvent/kOutEvent flags set. |
1109 intptr_t events = msg->data & EVENT_MASK; | 1047 intptr_t events = msg->data & EVENT_MASK; |
1110 ASSERT(0 == (events & ~(1 << kInEvent | 1 << kOutEvent))); | 1048 ASSERT(0 == (events & ~(1 << kInEvent | 1 << kOutEvent))); |
1111 listen_socket->SetPortAndMask(msg->dart_port, events); | 1049 listen_socket->SetPortAndMask(msg->dart_port, events); |
1112 TryDispatchingPendingAccepts(listen_socket); | 1050 TryDispatchingPendingAccepts(listen_socket); |
1113 } else if (IS_COMMAND(msg->data, kCloseCommand)) { | 1051 } else if (IS_COMMAND(msg->data, kCloseCommand)) { |
1114 listen_socket->RemovePort(msg->dart_port); | 1052 listen_socket->RemovePort(msg->dart_port); |
1115 | 1053 |
1116 // We only close the socket file descriptor from the operating | 1054 // We only close the socket file descriptor from the operating |
1117 // system if there are no other dart socket objects which | 1055 // system if there are no other dart socket objects which |
1118 // are listening on the same (address, port) combination. | 1056 // are listening on the same (address, port) combination. |
1119 ListeningSocketRegistry *registry = | 1057 ListeningSocketRegistry* registry = ListeningSocketRegistry::Instance(); |
1120 ListeningSocketRegistry::Instance(); | |
1121 MutexLocker locker(registry->mutex()); | 1058 MutexLocker locker(registry->mutex()); |
1122 if (registry->CloseSafe(reinterpret_cast<intptr_t>(listen_socket))) { | 1059 if (registry->CloseSafe(reinterpret_cast<intptr_t>(listen_socket))) { |
1123 ASSERT(listen_socket->Mask() == 0); | 1060 ASSERT(listen_socket->Mask() == 0); |
1124 listen_socket->Close(); | 1061 listen_socket->Close(); |
1125 } | 1062 } |
1126 | 1063 |
1127 DartUtils::PostInt32(msg->dart_port, 1 << kDestroyedEvent); | 1064 DartUtils::PostInt32(msg->dart_port, 1 << kDestroyedEvent); |
1128 } else { | 1065 } else { |
1129 UNREACHABLE(); | 1066 UNREACHABLE(); |
1130 } | 1067 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1206 { | 1143 { |
1207 MonitorLocker ml(listen_socket->monitor_); | 1144 MonitorLocker ml(listen_socket->monitor_); |
1208 TryDispatchingPendingAccepts(listen_socket); | 1145 TryDispatchingPendingAccepts(listen_socket); |
1209 } | 1146 } |
1210 | 1147 |
1211 DeleteIfClosed(listen_socket); | 1148 DeleteIfClosed(listen_socket); |
1212 } | 1149 } |
1213 | 1150 |
1214 | 1151 |
1215 void EventHandlerImplementation::TryDispatchingPendingAccepts( | 1152 void EventHandlerImplementation::TryDispatchingPendingAccepts( |
1216 ListenSocket *listen_socket) { | 1153 ListenSocket* listen_socket) { |
1217 if (!listen_socket->IsClosing() && listen_socket->CanAccept()) { | 1154 if (!listen_socket->IsClosing() && listen_socket->CanAccept()) { |
1218 intptr_t event_mask = 1 << kInEvent; | 1155 intptr_t event_mask = 1 << kInEvent; |
1219 for (int i = 0; | 1156 for (int i = 0; (i < listen_socket->accepted_count()) && |
1220 (i < listen_socket->accepted_count()) && | 1157 (listen_socket->Mask() == event_mask); |
1221 (listen_socket->Mask() == event_mask); | |
1222 i++) { | 1158 i++) { |
1223 Dart_Port port = listen_socket->NextNotifyDartPort(event_mask); | 1159 Dart_Port port = listen_socket->NextNotifyDartPort(event_mask); |
1224 DartUtils::PostInt32(port, event_mask); | 1160 DartUtils::PostInt32(port, event_mask); |
1225 } | 1161 } |
1226 } | 1162 } |
1227 } | 1163 } |
1228 | 1164 |
1229 | 1165 |
1230 void EventHandlerImplementation::HandleRead(Handle* handle, | 1166 void EventHandlerImplementation::HandleRead(Handle* handle, |
1231 int bytes, | 1167 int bytes, |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1291 } | 1227 } |
1292 } | 1228 } |
1293 } else { | 1229 } else { |
1294 HandleError(handle); | 1230 HandleError(handle); |
1295 } | 1231 } |
1296 | 1232 |
1297 DeleteIfClosed(handle); | 1233 DeleteIfClosed(handle); |
1298 } | 1234 } |
1299 | 1235 |
1300 | 1236 |
1301 void EventHandlerImplementation::HandleDisconnect( | 1237 void EventHandlerImplementation::HandleDisconnect(ClientSocket* client_socket, |
1302 ClientSocket* client_socket, | 1238 int bytes, |
1303 int bytes, | 1239 OverlappedBuffer* buffer) { |
1304 OverlappedBuffer* buffer) { | |
1305 client_socket->DisconnectComplete(buffer); | 1240 client_socket->DisconnectComplete(buffer); |
1306 DeleteIfClosed(client_socket); | 1241 DeleteIfClosed(client_socket); |
1307 } | 1242 } |
1308 | 1243 |
1309 | 1244 |
1310 void EventHandlerImplementation::HandleConnect( | 1245 void EventHandlerImplementation::HandleConnect(ClientSocket* client_socket, |
1311 ClientSocket* client_socket, | 1246 int bytes, |
1312 int bytes, | 1247 OverlappedBuffer* buffer) { |
1313 OverlappedBuffer* buffer) { | |
1314 if (bytes < 0) { | 1248 if (bytes < 0) { |
1315 HandleError(client_socket); | 1249 HandleError(client_socket); |
1316 OverlappedBuffer::DisposeBuffer(buffer); | 1250 OverlappedBuffer::DisposeBuffer(buffer); |
1317 } else { | 1251 } else { |
1318 client_socket->ConnectComplete(buffer); | 1252 client_socket->ConnectComplete(buffer); |
1319 } | 1253 } |
1320 client_socket->mark_connected(); | 1254 client_socket->mark_connected(); |
1321 DeleteIfClosed(client_socket); | 1255 DeleteIfClosed(client_socket); |
1322 } | 1256 } |
1323 | 1257 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1393 ASSERT(res == WAIT_OBJECT_0); | 1327 ASSERT(res == WAIT_OBJECT_0); |
1394 delete startup_monitor_; | 1328 delete startup_monitor_; |
1395 CloseHandle(completion_port_); | 1329 CloseHandle(completion_port_); |
1396 } | 1330 } |
1397 | 1331 |
1398 | 1332 |
1399 int64_t EventHandlerImplementation::GetTimeout() { | 1333 int64_t EventHandlerImplementation::GetTimeout() { |
1400 if (!timeout_queue_.HasTimeout()) { | 1334 if (!timeout_queue_.HasTimeout()) { |
1401 return kInfinityTimeout; | 1335 return kInfinityTimeout; |
1402 } | 1336 } |
1403 int64_t millis = timeout_queue_.CurrentTimeout() - | 1337 int64_t millis = |
1404 TimerUtils::GetCurrentMonotonicMillis(); | 1338 timeout_queue_.CurrentTimeout() - TimerUtils::GetCurrentMonotonicMillis(); |
1405 return (millis < 0) ? 0 : millis; | 1339 return (millis < 0) ? 0 : millis; |
1406 } | 1340 } |
1407 | 1341 |
1408 | 1342 |
1409 void EventHandlerImplementation::SendData(intptr_t id, | 1343 void EventHandlerImplementation::SendData(intptr_t id, |
1410 Dart_Port dart_port, | 1344 Dart_Port dart_port, |
1411 int64_t data) { | 1345 int64_t data) { |
1412 InterruptMessage* msg = new InterruptMessage; | 1346 InterruptMessage* msg = new InterruptMessage; |
1413 msg->id = id; | 1347 msg->id = id; |
1414 msg->dart_port = dart_port; | 1348 msg->dart_port = dart_port; |
1415 msg->data = data; | 1349 msg->data = data; |
1416 BOOL ok = PostQueuedCompletionStatus( | 1350 BOOL ok = PostQueuedCompletionStatus(completion_port_, 0, NULL, |
1417 completion_port_, 0, NULL, reinterpret_cast<OVERLAPPED*>(msg)); | 1351 reinterpret_cast<OVERLAPPED*>(msg)); |
1418 if (!ok) { | 1352 if (!ok) { |
1419 FATAL("PostQueuedCompletionStatus failed"); | 1353 FATAL("PostQueuedCompletionStatus failed"); |
1420 } | 1354 } |
1421 } | 1355 } |
1422 | 1356 |
1423 | 1357 |
1424 void EventHandlerImplementation::EventHandlerEntry(uword args) { | 1358 void EventHandlerImplementation::EventHandlerEntry(uword args) { |
1425 EventHandler* handler = reinterpret_cast<EventHandler*>(args); | 1359 EventHandler* handler = reinterpret_cast<EventHandler*>(args); |
1426 EventHandlerImplementation* handler_impl = &handler->delegate_; | 1360 EventHandlerImplementation* handler_impl = &handler->delegate_; |
1427 ASSERT(handler_impl != NULL); | 1361 ASSERT(handler_impl != NULL); |
1428 | 1362 |
1429 { | 1363 { |
1430 MonitorLocker ml(handler_impl->startup_monitor_); | 1364 MonitorLocker ml(handler_impl->startup_monitor_); |
1431 handler_impl->handler_thread_id_ = Thread::GetCurrentThreadId(); | 1365 handler_impl->handler_thread_id_ = Thread::GetCurrentThreadId(); |
1432 handler_impl->handler_thread_handle_ = | 1366 handler_impl->handler_thread_handle_ = |
1433 OpenThread(SYNCHRONIZE, false, handler_impl->handler_thread_id_); | 1367 OpenThread(SYNCHRONIZE, false, handler_impl->handler_thread_id_); |
1434 ml.Notify(); | 1368 ml.Notify(); |
1435 } | 1369 } |
1436 | 1370 |
1437 while (!handler_impl->shutdown_) { | 1371 while (!handler_impl->shutdown_) { |
1438 DWORD bytes; | 1372 DWORD bytes; |
1439 ULONG_PTR key; | 1373 ULONG_PTR key; |
1440 OVERLAPPED* overlapped; | 1374 OVERLAPPED* overlapped; |
1441 int64_t millis = handler_impl->GetTimeout(); | 1375 int64_t millis = handler_impl->GetTimeout(); |
1442 ASSERT(millis == kInfinityTimeout || millis >= 0); | 1376 ASSERT(millis == kInfinityTimeout || millis >= 0); |
1443 if (millis > kMaxInt32) { | 1377 if (millis > kMaxInt32) { |
1444 millis = kMaxInt32; | 1378 millis = kMaxInt32; |
1445 } | 1379 } |
1446 ASSERT(sizeof(int32_t) == sizeof(DWORD)); | 1380 ASSERT(sizeof(int32_t) == sizeof(DWORD)); |
1447 BOOL ok = GetQueuedCompletionStatus(handler_impl->completion_port(), | 1381 BOOL ok = |
1448 &bytes, | 1382 GetQueuedCompletionStatus(handler_impl->completion_port(), &bytes, &key, |
1449 &key, | 1383 &overlapped, static_cast<DWORD>(millis)); |
1450 &overlapped, | |
1451 static_cast<DWORD>(millis)); | |
1452 | 1384 |
1453 if (!ok && (overlapped == NULL)) { | 1385 if (!ok && (overlapped == NULL)) { |
1454 if (GetLastError() == ERROR_ABANDONED_WAIT_0) { | 1386 if (GetLastError() == ERROR_ABANDONED_WAIT_0) { |
1455 // The completion port should never be closed. | 1387 // The completion port should never be closed. |
1456 Log::Print("Completion port closed\n"); | 1388 Log::Print("Completion port closed\n"); |
1457 UNREACHABLE(); | 1389 UNREACHABLE(); |
1458 } else { | 1390 } else { |
1459 // Timeout is signalled by false result and NULL in overlapped. | 1391 // Timeout is signalled by false result and NULL in overlapped. |
1460 handler_impl->HandleTimeout(); | 1392 handler_impl->HandleTimeout(); |
1461 } | 1393 } |
(...skipping 26 matching lines...) Expand all Loading... |
1488 delete msg; | 1420 delete msg; |
1489 } else { | 1421 } else { |
1490 handler_impl->HandleIOCompletion(bytes, key, overlapped); | 1422 handler_impl->HandleIOCompletion(bytes, key, overlapped); |
1491 } | 1423 } |
1492 } | 1424 } |
1493 handler->NotifyShutdownDone(); | 1425 handler->NotifyShutdownDone(); |
1494 } | 1426 } |
1495 | 1427 |
1496 | 1428 |
1497 void EventHandlerImplementation::Start(EventHandler* handler) { | 1429 void EventHandlerImplementation::Start(EventHandler* handler) { |
1498 int result = Thread::Start(EventHandlerEntry, | 1430 int result = |
1499 reinterpret_cast<uword>(handler)); | 1431 Thread::Start(EventHandlerEntry, reinterpret_cast<uword>(handler)); |
1500 if (result != 0) { | 1432 if (result != 0) { |
1501 FATAL1("Failed to start event handler thread %d", result); | 1433 FATAL1("Failed to start event handler thread %d", result); |
1502 } | 1434 } |
1503 | 1435 |
1504 { | 1436 { |
1505 MonitorLocker ml(startup_monitor_); | 1437 MonitorLocker ml(startup_monitor_); |
1506 while (handler_thread_id_ == Thread::kInvalidThreadId) { | 1438 while (handler_thread_id_ == Thread::kInvalidThreadId) { |
1507 ml.Wait(); | 1439 ml.Wait(); |
1508 } | 1440 } |
1509 } | 1441 } |
1510 | 1442 |
1511 // Initialize Winsock32 | 1443 // Initialize Winsock32 |
1512 if (!Socket::Initialize()) { | 1444 if (!Socket::Initialize()) { |
1513 FATAL("Failed to initialized Windows sockets"); | 1445 FATAL("Failed to initialized Windows sockets"); |
1514 } | 1446 } |
1515 } | 1447 } |
1516 | 1448 |
1517 | 1449 |
1518 void EventHandlerImplementation::Shutdown() { | 1450 void EventHandlerImplementation::Shutdown() { |
1519 SendData(kShutdownId, 0, 0); | 1451 SendData(kShutdownId, 0, 0); |
1520 } | 1452 } |
1521 | 1453 |
1522 } // namespace bin | 1454 } // namespace bin |
1523 } // namespace dart | 1455 } // namespace dart |
1524 | 1456 |
1525 #endif // defined(TARGET_OS_WINDOWS) | 1457 #endif // defined(TARGET_OS_WINDOWS) |
1526 | 1458 |
1527 #endif // !defined(DART_IO_DISABLED) | 1459 #endif // !defined(DART_IO_DISABLED) |
OLD | NEW |