| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "bin/eventhandler.h" | 5 #include "bin/eventhandler.h" |
| 6 | 6 |
| 7 #include <process.h> | 7 #include <process.h> |
| 8 #include <winsock2.h> | 8 #include <winsock2.h> |
| 9 #include <ws2tcpip.h> | 9 #include <ws2tcpip.h> |
| 10 #include <mswsock.h> | 10 #include <mswsock.h> |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 BOOL ok = ReadFile(handle_, | 251 BOOL ok = ReadFile(handle_, |
| 252 buffer->GetBufferStart(), | 252 buffer->GetBufferStart(), |
| 253 buffer->GetBufferSize(), | 253 buffer->GetBufferSize(), |
| 254 NULL, | 254 NULL, |
| 255 buffer->GetCleanOverlapped()); | 255 buffer->GetCleanOverlapped()); |
| 256 if (ok || GetLastError() == ERROR_IO_PENDING) { | 256 if (ok || GetLastError() == ERROR_IO_PENDING) { |
| 257 // Completing asynchronously. | 257 // Completing asynchronously. |
| 258 pending_read_ = buffer; | 258 pending_read_ = buffer; |
| 259 return true; | 259 return true; |
| 260 } | 260 } |
| 261 IOBuffer::DisposeBuffer(buffer); |
| 261 | 262 |
| 262 if (GetLastError() != ERROR_BROKEN_PIPE) { | 263 if (GetLastError() == ERROR_BROKEN_PIPE) { |
| 263 Log::PrintErr("ReadFile failed: %d\n", GetLastError()); | 264 event_handler_->HandleClosed(this); |
| 265 } else { |
| 266 event_handler_->HandleError(this); |
| 264 } | 267 } |
| 265 event_handler_->HandleClosed(this); | |
| 266 IOBuffer::DisposeBuffer(buffer); | |
| 267 return false; | 268 return false; |
| 268 } else { | 269 } else { |
| 269 // Completing asynchronously through thread. | 270 // Completing asynchronously through thread. |
| 270 pending_read_ = buffer; | 271 pending_read_ = buffer; |
| 271 uint32_t tid; | 272 uint32_t tid; |
| 272 uintptr_t thread_handle = | 273 uintptr_t thread_handle = |
| 273 _beginthreadex(NULL, 32 * 1024, ReadFileThread, this, 0, &tid); | 274 _beginthreadex(NULL, 32 * 1024, ReadFileThread, this, 0, &tid); |
| 274 if (thread_handle == -1) { | 275 if (thread_handle == -1) { |
| 275 FATAL("Failed to start read file thread"); | 276 FATAL("Failed to start read file thread"); |
| 276 } | 277 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 290 BOOL ok = WriteFile(handle_, | 291 BOOL ok = WriteFile(handle_, |
| 291 buffer->GetBufferStart(), | 292 buffer->GetBufferStart(), |
| 292 buffer->GetBufferSize(), | 293 buffer->GetBufferSize(), |
| 293 NULL, | 294 NULL, |
| 294 buffer->GetCleanOverlapped()); | 295 buffer->GetCleanOverlapped()); |
| 295 if (ok || GetLastError() == ERROR_IO_PENDING) { | 296 if (ok || GetLastError() == ERROR_IO_PENDING) { |
| 296 // Completing asynchronously. | 297 // Completing asynchronously. |
| 297 pending_write_ = buffer; | 298 pending_write_ = buffer; |
| 298 return true; | 299 return true; |
| 299 } | 300 } |
| 301 IOBuffer::DisposeBuffer(buffer); |
| 300 | 302 |
| 301 if (GetLastError() != ERROR_BROKEN_PIPE) { | 303 if (GetLastError() == ERROR_BROKEN_PIPE) { |
| 302 Log::PrintErr("WriteFile failed: %d\n", GetLastError()); | 304 event_handler_->HandleClosed(this); |
| 305 } else { |
| 306 event_handler_->HandleError(this); |
| 303 } | 307 } |
| 304 event_handler_->HandleClosed(this); | |
| 305 IOBuffer::DisposeBuffer(buffer); | |
| 306 return false; | 308 return false; |
| 307 } | 309 } |
| 308 | 310 |
| 309 | 311 |
| 310 void FileHandle::EnsureInitialized(EventHandlerImplementation* event_handler) { | 312 void FileHandle::EnsureInitialized(EventHandlerImplementation* event_handler) { |
| 311 ScopedLock lock(this); | 313 ScopedLock lock(this); |
| 312 event_handler_ = event_handler; | 314 event_handler_ = event_handler; |
| 313 if (SupportsOverlappedIO() && completion_port_ == INVALID_HANDLE_VALUE) { | 315 if (SupportsOverlappedIO() && completion_port_ == INVALID_HANDLE_VALUE) { |
| 314 CreateCompletionPort(event_handler_->completion_port()); | 316 CreateCompletionPort(event_handler_->completion_port()); |
| 315 } | 317 } |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 551 buffer->GetWASBUF(), | 553 buffer->GetWASBUF(), |
| 552 1, | 554 1, |
| 553 NULL, | 555 NULL, |
| 554 &flags, | 556 &flags, |
| 555 buffer->GetCleanOverlapped(), | 557 buffer->GetCleanOverlapped(), |
| 556 NULL); | 558 NULL); |
| 557 if (rc == NO_ERROR || WSAGetLastError() == WSA_IO_PENDING) { | 559 if (rc == NO_ERROR || WSAGetLastError() == WSA_IO_PENDING) { |
| 558 pending_read_ = buffer; | 560 pending_read_ = buffer; |
| 559 return true; | 561 return true; |
| 560 } | 562 } |
| 563 IOBuffer::DisposeBuffer(buffer); |
| 564 pending_read_ = NULL; |
| 561 | 565 |
| 562 if (WSAGetLastError() != WSAECONNRESET) { | 566 if (WSAGetLastError() == WSAECONNRESET) { |
| 563 Log::PrintErr("WSARecv failed: %d\n", WSAGetLastError()); | 567 event_handler_->HandleClosed(this); |
| 568 } else { |
| 569 event_handler_->HandleError(this); |
| 564 } | 570 } |
| 565 event_handler_->HandleClosed(this); | |
| 566 IOBuffer::DisposeBuffer(buffer); | |
| 567 return false; | 571 return false; |
| 568 } | 572 } |
| 569 | 573 |
| 570 | 574 |
| 571 bool ClientSocket::IssueWrite() { | 575 bool ClientSocket::IssueWrite() { |
| 572 ScopedLock lock(this); | 576 ScopedLock lock(this); |
| 573 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 577 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
| 574 ASSERT(pending_write_ != NULL); | 578 ASSERT(pending_write_ != NULL); |
| 575 ASSERT(pending_write_->operation() == IOBuffer::kWrite); | 579 ASSERT(pending_write_->operation() == IOBuffer::kWrite); |
| 576 | 580 |
| 577 int rc = WSASend(socket(), | 581 int rc = WSASend(socket(), |
| 578 pending_write_->GetWASBUF(), | 582 pending_write_->GetWASBUF(), |
| 579 1, | 583 1, |
| 580 NULL, | 584 NULL, |
| 581 0, | 585 0, |
| 582 pending_write_->GetCleanOverlapped(), | 586 pending_write_->GetCleanOverlapped(), |
| 583 NULL); | 587 NULL); |
| 584 if (rc == NO_ERROR || WSAGetLastError() == WSA_IO_PENDING) { | 588 if (rc == NO_ERROR || WSAGetLastError() == WSA_IO_PENDING) { |
| 585 return true; | 589 return true; |
| 586 } | 590 } |
| 587 | |
| 588 Log::PrintErr("WSASend failed: %d\n", WSAGetLastError()); | |
| 589 IOBuffer::DisposeBuffer(pending_write_); | 591 IOBuffer::DisposeBuffer(pending_write_); |
| 590 pending_write_ = NULL; | 592 pending_write_ = NULL; |
| 593 |
| 594 if (WSAGetLastError() == WSAECONNRESET) { |
| 595 event_handler_->HandleClosed(this); |
| 596 } else { |
| 597 event_handler_->HandleError(this); |
| 598 } |
| 591 return false; | 599 return false; |
| 592 } | 600 } |
| 593 | 601 |
| 594 | 602 |
| 595 void ClientSocket::EnsureInitialized( | 603 void ClientSocket::EnsureInitialized( |
| 596 EventHandlerImplementation* event_handler) { | 604 EventHandlerImplementation* event_handler) { |
| 597 ScopedLock lock(this); | 605 ScopedLock lock(this); |
| 598 if (completion_port_ == INVALID_HANDLE_VALUE) { | 606 if (completion_port_ == INVALID_HANDLE_VALUE) { |
| 599 ASSERT(event_handler_ == NULL); | 607 ASSERT(event_handler_ == NULL); |
| 600 event_handler_ = event_handler; | 608 event_handler_ = event_handler; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 if (listen_socket->IsClosed()) { | 658 if (listen_socket->IsClosed()) { |
| 651 delete_handle = true; | 659 delete_handle = true; |
| 652 } | 660 } |
| 653 } | 661 } |
| 654 } else { | 662 } else { |
| 655 handle->SetPortAndMask(msg->dart_port, msg->data); | 663 handle->SetPortAndMask(msg->dart_port, msg->data); |
| 656 handle->EnsureInitialized(this); | 664 handle->EnsureInitialized(this); |
| 657 | 665 |
| 658 Handle::ScopedLock lock(handle); | 666 Handle::ScopedLock lock(handle); |
| 659 | 667 |
| 660 // If the data available callback has been requested and data are | 668 if (!handle->IsError()) { |
| 661 // available post it immediately. Otherwise make sure that a pending | 669 // If in events (data available events) have been requested, and data |
| 662 // read is issued unless the socket is already closed for read. | 670 // is available, post an in event immediately. Otherwise make sure |
| 663 if ((msg->data & (1 << kInEvent)) != 0) { | 671 // that a pending read is issued, unless the socket is already closed |
| 664 if (handle->Available() > 0) { | 672 // for read. |
| 665 int event_mask = (1 << kInEvent); | 673 if ((msg->data & (1 << kInEvent)) != 0) { |
| 666 DartUtils::PostInt32(handle->port(), event_mask); | 674 if (handle->Available() > 0) { |
| 667 } else if (!handle->HasPendingRead() && | 675 int event_mask = (1 << kInEvent); |
| 668 !handle->IsClosedRead()) { | 676 handle->set_mask(handle->mask() & ~event_mask); |
| 669 handle->IssueRead(); | 677 DartUtils::PostInt32(handle->port(), event_mask); |
| 678 } else if (!handle->HasPendingRead() && |
| 679 !handle->IsClosedRead()) { |
| 680 handle->IssueRead(); |
| 681 } |
| 682 } |
| 683 |
| 684 // If out events (can write events) have been requested, and there |
| 685 // are no pending writes, post an out event immediately. |
| 686 if ((msg->data & (1 << kOutEvent)) != 0) { |
| 687 if (!handle->HasPendingWrite()) { |
| 688 int event_mask = (1 << kOutEvent); |
| 689 handle->set_mask(handle->mask() & ~event_mask); |
| 690 DartUtils::PostInt32(handle->port(), event_mask); |
| 691 } |
| 692 } |
| 693 |
| 694 if (handle->is_client_socket()) { |
| 695 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(handle); |
| 696 if ((msg->data & (1 << kShutdownReadCommand)) != 0) { |
| 697 client_socket->Shutdown(SD_RECEIVE); |
| 698 } |
| 699 |
| 700 if ((msg->data & (1 << kShutdownWriteCommand)) != 0) { |
| 701 client_socket->Shutdown(SD_SEND); |
| 702 } |
| 670 } | 703 } |
| 671 } | 704 } |
| 672 | 705 |
| 673 // If can send callback had been requested and there is no pending | |
| 674 // send post it immediately. | |
| 675 if ((msg->data & (1 << kOutEvent)) != 0) { | |
| 676 if (!handle->HasPendingWrite()) { | |
| 677 int event_mask = (1 << kOutEvent); | |
| 678 DartUtils::PostInt32(handle->port(), event_mask); | |
| 679 } | |
| 680 } | |
| 681 | |
| 682 if (handle->is_client_socket()) { | |
| 683 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(handle); | |
| 684 if ((msg->data & (1 << kShutdownReadCommand)) != 0) { | |
| 685 client_socket->Shutdown(SD_RECEIVE); | |
| 686 } | |
| 687 | |
| 688 if ((msg->data & (1 << kShutdownWriteCommand)) != 0) { | |
| 689 client_socket->Shutdown(SD_SEND); | |
| 690 } | |
| 691 } | |
| 692 | |
| 693 if ((msg->data & (1 << kCloseCommand)) != 0) { | 706 if ((msg->data & (1 << kCloseCommand)) != 0) { |
| 694 handle->close(); | 707 handle->close(); |
| 695 if (handle->IsClosed()) { | 708 if (handle->IsClosed()) { |
| 696 delete_handle = true; | 709 delete_handle = true; |
| 697 } | 710 } |
| 698 } | 711 } |
| 699 } | 712 } |
| 700 if (delete_handle) { | 713 if (delete_handle) { |
| 701 delete handle; | 714 delete handle; |
| 702 } | 715 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 724 void EventHandlerImplementation::HandleClosed(Handle* handle) { | 737 void EventHandlerImplementation::HandleClosed(Handle* handle) { |
| 725 if (!handle->IsClosing()) { | 738 if (!handle->IsClosing()) { |
| 726 int event_mask = 1 << kCloseEvent; | 739 int event_mask = 1 << kCloseEvent; |
| 727 DartUtils::PostInt32(handle->port(), event_mask); | 740 DartUtils::PostInt32(handle->port(), event_mask); |
| 728 } | 741 } |
| 729 } | 742 } |
| 730 | 743 |
| 731 | 744 |
| 732 void EventHandlerImplementation::HandleError(Handle* handle) { | 745 void EventHandlerImplementation::HandleError(Handle* handle) { |
| 733 handle->set_last_error(WSAGetLastError()); | 746 handle->set_last_error(WSAGetLastError()); |
| 747 handle->MarkError(); |
| 734 if (!handle->IsClosing()) { | 748 if (!handle->IsClosing()) { |
| 735 int event_mask = 1 << kErrorEvent; | 749 int event_mask = 1 << kErrorEvent; |
| 736 DartUtils::PostInt32(handle->port(), event_mask); | 750 DartUtils::PostInt32(handle->port(), event_mask); |
| 737 } | 751 } |
| 738 } | 752 } |
| 739 | 753 |
| 740 | 754 |
| 741 void EventHandlerImplementation::HandleRead(Handle* handle, | 755 void EventHandlerImplementation::HandleRead(Handle* handle, |
| 742 int bytes, | 756 int bytes, |
| 743 IOBuffer* buffer) { | 757 IOBuffer* buffer) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 764 } | 778 } |
| 765 } | 779 } |
| 766 | 780 |
| 767 | 781 |
| 768 void EventHandlerImplementation::HandleWrite(Handle* handle, | 782 void EventHandlerImplementation::HandleWrite(Handle* handle, |
| 769 int bytes, | 783 int bytes, |
| 770 IOBuffer* buffer) { | 784 IOBuffer* buffer) { |
| 771 handle->WriteComplete(buffer); | 785 handle->WriteComplete(buffer); |
| 772 | 786 |
| 773 if (bytes > 0) { | 787 if (bytes > 0) { |
| 774 if (!handle->IsClosing()) { | 788 if (!handle->IsError() && !handle->IsClosing()) { |
| 775 int event_mask = 1 << kOutEvent; | 789 int event_mask = 1 << kOutEvent; |
| 776 if ((handle->mask() & event_mask) != 0) { | 790 if ((handle->mask() & event_mask) != 0) { |
| 777 DartUtils::PostInt32(handle->port(), event_mask); | 791 DartUtils::PostInt32(handle->port(), event_mask); |
| 778 } | 792 } |
| 779 } | 793 } |
| 780 } else if (bytes == 0) { | 794 } else if (bytes == 0) { |
| 781 HandleClosed(handle); | 795 HandleClosed(handle); |
| 782 } else { | 796 } else { |
| 783 HandleError(handle); | 797 HandleError(handle); |
| 784 } | 798 } |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 922 // Initialize Winsock32 | 936 // Initialize Winsock32 |
| 923 if (!Socket::Initialize()) { | 937 if (!Socket::Initialize()) { |
| 924 FATAL("Failed to initialized Windows sockets"); | 938 FATAL("Failed to initialized Windows sockets"); |
| 925 } | 939 } |
| 926 } | 940 } |
| 927 | 941 |
| 928 | 942 |
| 929 void EventHandlerImplementation::Shutdown() { | 943 void EventHandlerImplementation::Shutdown() { |
| 930 SendData(kShutdownId, 0, 0); | 944 SendData(kShutdownId, 0, 0); |
| 931 } | 945 } |
| OLD | NEW |