| 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 | 9 |
| 10 #include <winsock2.h> // NOLINT | 10 #include <winsock2.h> // NOLINT |
| (...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 599 LoadAcceptEx(); | 599 LoadAcceptEx(); |
| 600 } | 600 } |
| 601 } | 601 } |
| 602 | 602 |
| 603 | 603 |
| 604 bool ListenSocket::IsClosed() { | 604 bool ListenSocket::IsClosed() { |
| 605 return IsClosing() && !HasPendingAccept(); | 605 return IsClosing() && !HasPendingAccept(); |
| 606 } | 606 } |
| 607 | 607 |
| 608 | 608 |
| 609 int Handle::Available() { | 609 intptr_t Handle::Available() { |
| 610 ScopedLock lock(this); | 610 ScopedLock lock(this); |
| 611 if (data_ready_ == NULL) return 0; | 611 if (data_ready_ == NULL) return 0; |
| 612 ASSERT(!data_ready_->IsEmpty()); | 612 ASSERT(!data_ready_->IsEmpty()); |
| 613 return data_ready_->GetRemainingLength(); | 613 return data_ready_->GetRemainingLength(); |
| 614 } | 614 } |
| 615 | 615 |
| 616 | 616 |
| 617 int Handle::Read(void* buffer, int num_bytes) { | 617 intptr_t Handle::Read(void* buffer, intptr_t num_bytes) { |
| 618 ScopedLock lock(this); | 618 ScopedLock lock(this); |
| 619 if (data_ready_ == NULL) return 0; | 619 if (data_ready_ == NULL) return 0; |
| 620 num_bytes = data_ready_->Read(buffer, num_bytes); | 620 num_bytes = data_ready_->Read( |
| 621 buffer, Utils::Minimum<intptr_t>(num_bytes, INT_MAX)); |
| 621 if (data_ready_->IsEmpty()) { | 622 if (data_ready_->IsEmpty()) { |
| 622 OverlappedBuffer::DisposeBuffer(data_ready_); | 623 OverlappedBuffer::DisposeBuffer(data_ready_); |
| 623 data_ready_ = NULL; | 624 data_ready_ = NULL; |
| 624 if (!IsClosing() && !IsClosedRead()) IssueRead(); | 625 if (!IsClosing() && !IsClosedRead()) IssueRead(); |
| 625 } | 626 } |
| 626 return num_bytes; | 627 return num_bytes; |
| 627 } | 628 } |
| 628 | 629 |
| 629 | 630 |
| 630 int Handle::RecvFrom( | 631 intptr_t Handle::RecvFrom( |
| 631 void* buffer, int num_bytes, struct sockaddr* sa, socklen_t sa_len) { | 632 void* buffer, intptr_t num_bytes, struct sockaddr* sa, socklen_t sa_len) { |
| 632 ScopedLock lock(this); | 633 ScopedLock lock(this); |
| 633 if (data_ready_ == NULL) return 0; | 634 if (data_ready_ == NULL) return 0; |
| 634 num_bytes = data_ready_->Read(buffer, num_bytes); | 635 num_bytes = data_ready_->Read( |
| 636 buffer, Utils::Minimum<intptr_t>(num_bytes, INT_MAX)); |
| 635 if (data_ready_->from()->sa_family == AF_INET) { | 637 if (data_ready_->from()->sa_family == AF_INET) { |
| 636 ASSERT(sa_len >= sizeof(struct sockaddr_in)); | 638 ASSERT(sa_len >= sizeof(struct sockaddr_in)); |
| 637 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in)); | 639 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in)); |
| 638 } else { | 640 } else { |
| 639 ASSERT(data_ready_->from()->sa_family == AF_INET6); | 641 ASSERT(data_ready_->from()->sa_family == AF_INET6); |
| 640 ASSERT(sa_len >= sizeof(struct sockaddr_in6)); | 642 ASSERT(sa_len >= sizeof(struct sockaddr_in6)); |
| 641 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in6)); | 643 memmove(sa, data_ready_->from(), sizeof(struct sockaddr_in6)); |
| 642 } | 644 } |
| 643 // Always dispose of the buffer, as UDP messages must be read in their | 645 // Always dispose of the buffer, as UDP messages must be read in their |
| 644 // entirety to match how recvfrom works in a socket. | 646 // entirety to match how recvfrom works in a socket. |
| 645 OverlappedBuffer::DisposeBuffer(data_ready_); | 647 OverlappedBuffer::DisposeBuffer(data_ready_); |
| 646 data_ready_ = NULL; | 648 data_ready_ = NULL; |
| 647 if (!IsClosing() && !IsClosedRead()) IssueRecvFrom(); | 649 if (!IsClosing() && !IsClosedRead()) IssueRecvFrom(); |
| 648 return num_bytes; | 650 return num_bytes; |
| 649 } | 651 } |
| 650 | 652 |
| 651 | 653 |
| 652 int Handle::Write(const void* buffer, int num_bytes) { | 654 intptr_t Handle::Write(const void* buffer, intptr_t num_bytes) { |
| 653 ScopedLock lock(this); | 655 ScopedLock lock(this); |
| 654 if (pending_write_ != NULL) return 0; | 656 if (pending_write_ != NULL) return 0; |
| 655 if (num_bytes > kBufferSize) num_bytes = kBufferSize; | 657 if (num_bytes > kBufferSize) num_bytes = kBufferSize; |
| 656 ASSERT(SupportsOverlappedIO()); | 658 ASSERT(SupportsOverlappedIO()); |
| 657 if (completion_port_ == INVALID_HANDLE_VALUE) return 0; | 659 if (completion_port_ == INVALID_HANDLE_VALUE) return 0; |
| 658 pending_write_ = OverlappedBuffer::AllocateWriteBuffer(num_bytes); | 660 int truncated_bytes = Utils::Minimum<intptr_t>(num_bytes, INT_MAX); |
| 659 pending_write_->Write(buffer, num_bytes); | 661 pending_write_ = OverlappedBuffer::AllocateWriteBuffer(truncated_bytes); |
| 662 pending_write_->Write(buffer, truncated_bytes); |
| 660 if (!IssueWrite()) return -1; | 663 if (!IssueWrite()) return -1; |
| 661 return num_bytes; | 664 return truncated_bytes; |
| 662 } | 665 } |
| 663 | 666 |
| 664 | 667 |
| 665 int Handle::SendTo( | 668 intptr_t Handle::SendTo(const void* buffer, |
| 666 const void* buffer, int num_bytes, struct sockaddr* sa, socklen_t sa_len) { | 669 intptr_t num_bytes, |
| 670 struct sockaddr* sa, |
| 671 socklen_t sa_len) { |
| 667 ScopedLock lock(this); | 672 ScopedLock lock(this); |
| 668 if (pending_write_ != NULL) return 0; | 673 if (pending_write_ != NULL) return 0; |
| 669 if (num_bytes > kBufferSize) num_bytes = kBufferSize; | 674 if (num_bytes > kBufferSize) num_bytes = kBufferSize; |
| 670 ASSERT(SupportsOverlappedIO()); | 675 ASSERT(SupportsOverlappedIO()); |
| 671 if (completion_port_ == INVALID_HANDLE_VALUE) return 0; | 676 if (completion_port_ == INVALID_HANDLE_VALUE) return 0; |
| 672 pending_write_ = OverlappedBuffer::AllocateSendToBuffer(num_bytes); | 677 pending_write_ = OverlappedBuffer::AllocateSendToBuffer(num_bytes); |
| 673 pending_write_->Write(buffer, num_bytes); | 678 pending_write_->Write(buffer, num_bytes); |
| 674 if (!IssueSendTo(sa, sa_len)) return -1; | 679 if (!IssueSendTo(sa, sa_len)) return -1; |
| 675 return num_bytes; | 680 return num_bytes; |
| 676 } | 681 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 718 OVERLAPPED* overlapped = pending_write_->GetCleanOverlapped(); | 723 OVERLAPPED* overlapped = pending_write_->GetCleanOverlapped(); |
| 719 ok = PostQueuedCompletionStatus(event_handler_->completion_port(), | 724 ok = PostQueuedCompletionStatus(event_handler_->completion_port(), |
| 720 bytes_written, | 725 bytes_written, |
| 721 reinterpret_cast<ULONG_PTR>(this), | 726 reinterpret_cast<ULONG_PTR>(this), |
| 722 overlapped); | 727 overlapped); |
| 723 if (!ok) { | 728 if (!ok) { |
| 724 FATAL("PostQueuedCompletionStatus failed"); | 729 FATAL("PostQueuedCompletionStatus failed"); |
| 725 } | 730 } |
| 726 } | 731 } |
| 727 | 732 |
| 728 int StdHandle::Write(const void* buffer, int num_bytes) { | 733 intptr_t StdHandle::Write(const void* buffer, intptr_t num_bytes) { |
| 729 ScopedLock lock(this); | 734 ScopedLock lock(this); |
| 730 if (pending_write_ != NULL) return 0; | 735 if (pending_write_ != NULL) return 0; |
| 731 if (num_bytes > kBufferSize) num_bytes = kBufferSize; | 736 if (num_bytes > kBufferSize) num_bytes = kBufferSize; |
| 732 // In the case of stdout and stderr, OverlappedIO is not supported. | 737 // In the case of stdout and stderr, OverlappedIO is not supported. |
| 733 // Here we'll instead use a thread, to make it async. | 738 // Here we'll instead use a thread, to make it async. |
| 734 // This code is actually never exposed to the user, as stdout and stderr is | 739 // This code is actually never exposed to the user, as stdout and stderr is |
| 735 // not available as a RawSocket, but only wrapped in a Socket. | 740 // not available as a RawSocket, but only wrapped in a Socket. |
| 736 // Note that we return '0', unless a thread have already completed a write. | 741 // Note that we return '0', unless a thread have already completed a write. |
| 737 MonitorLocker locker(write_monitor_); | 742 MonitorLocker locker(write_monitor_); |
| 738 if (thread_wrote_ > 0) { | 743 if (thread_wrote_ > 0) { |
| 739 if (num_bytes > thread_wrote_) num_bytes = thread_wrote_; | 744 if (num_bytes > thread_wrote_) num_bytes = thread_wrote_; |
| 740 thread_wrote_ -= num_bytes; | 745 thread_wrote_ -= num_bytes; |
| 741 return num_bytes; | 746 return num_bytes; |
| 742 } | 747 } |
| 743 if (!write_thread_exists_) { | 748 if (!write_thread_exists_) { |
| 744 write_thread_exists_ = true; | 749 write_thread_exists_ = true; |
| 745 int result = dart::Thread::Start(WriteFileThread, | 750 int result = dart::Thread::Start(WriteFileThread, |
| 746 reinterpret_cast<uword>(this)); | 751 reinterpret_cast<uword>(this)); |
| 747 if (result != 0) { | 752 if (result != 0) { |
| 748 FATAL1("Failed to start write file thread %d", result); | 753 FATAL1("Failed to start write file thread %d", result); |
| 749 } | 754 } |
| 750 while (!write_thread_running_) { | 755 while (!write_thread_running_) { |
| 751 // Wait until we the thread is running. | 756 // Wait until we the thread is running. |
| 752 locker.Wait(Monitor::kNoTimeout); | 757 locker.Wait(Monitor::kNoTimeout); |
| 753 } | 758 } |
| 754 } | 759 } |
| 760 // Only queue up to INT_MAX bytes. |
| 761 int truncated_bytes = Utils::Minimum<intptr_t>(num_bytes, INT_MAX); |
| 755 // Create buffer and notify thread about the new handle. | 762 // Create buffer and notify thread about the new handle. |
| 756 pending_write_ = OverlappedBuffer::AllocateWriteBuffer(num_bytes); | 763 pending_write_ = OverlappedBuffer::AllocateWriteBuffer(truncated_bytes); |
| 757 pending_write_->Write(buffer, num_bytes); | 764 pending_write_->Write(buffer, truncated_bytes); |
| 758 locker.Notify(); | 765 locker.Notify(); |
| 759 return 0; | 766 return 0; |
| 760 } | 767 } |
| 761 | 768 |
| 762 | 769 |
| 763 void StdHandle::DoClose() { | 770 void StdHandle::DoClose() { |
| 764 MonitorLocker locker(write_monitor_); | 771 MonitorLocker locker(write_monitor_); |
| 765 if (write_thread_exists_) { | 772 if (write_thread_exists_) { |
| 766 write_thread_running_ = false; | 773 write_thread_running_ = false; |
| 767 locker.Notify(); | 774 locker.Notify(); |
| (...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1365 | 1372 |
| 1366 | 1373 |
| 1367 void EventHandlerImplementation::Shutdown() { | 1374 void EventHandlerImplementation::Shutdown() { |
| 1368 SendData(kShutdownId, 0, 0); | 1375 SendData(kShutdownId, 0, 0); |
| 1369 } | 1376 } |
| 1370 | 1377 |
| 1371 } // namespace bin | 1378 } // namespace bin |
| 1372 } // namespace dart | 1379 } // namespace dart |
| 1373 | 1380 |
| 1374 #endif // defined(TARGET_OS_WINDOWS) | 1381 #endif // defined(TARGET_OS_WINDOWS) |
| OLD | NEW |