| Index: runtime/bin/eventhandler_win.cc
|
| diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc
|
| index 85bb1368e1ea6edd7c64380a12677b60ad6a59ea..27a509ed527c0019090c5f13537463bed8d898e7 100644
|
| --- a/runtime/bin/eventhandler_win.cc
|
| +++ b/runtime/bin/eventhandler_win.cc
|
| @@ -373,6 +373,9 @@ bool DirectoryWatchHandle::IsClosed() {
|
|
|
| bool DirectoryWatchHandle::IssueRead() {
|
| ScopedLock lock(this);
|
| + // It may have been started before, as we start the directory-handler when
|
| + // we create it.
|
| + if (pending_read_ != NULL) return true;
|
| OverlappedBuffer* buffer = OverlappedBuffer::AllocateReadBuffer(kBufferSize);
|
|
|
| ASSERT(completion_port_ != INVALID_HANDLE_VALUE);
|
| @@ -529,6 +532,13 @@ ClientSocket* ListenSocket::Accept() {
|
| accepted_head_ = accepted_head_->next();
|
| if (accepted_head_ == NULL) accepted_tail_ = NULL;
|
| result->set_next(NULL);
|
| + if (!IsClosing()) {
|
| + while (pending_accept_count() < 5) {
|
| + if (!IssueAccept()) {
|
| + event_handler_->HandleError(this);
|
| + }
|
| + }
|
| + }
|
| return result;
|
| }
|
|
|
| @@ -566,6 +576,7 @@ int Handle::Read(void* buffer, int num_bytes) {
|
| if (data_ready_->IsEmpty()) {
|
| OverlappedBuffer::DisposeBuffer(data_ready_);
|
| data_ready_ = NULL;
|
| + if (!IsClosing() && !IsClosedRead()) IssueRead();
|
| }
|
| return num_bytes;
|
| }
|
| @@ -588,6 +599,7 @@ int Handle::RecvFrom(
|
| // entirety to match how recvfrom works in a socket.
|
| OverlappedBuffer::DisposeBuffer(data_ready_);
|
| data_ready_ = NULL;
|
| + if (!IsClosing() && !IsClosedRead()) IssueRecvFrom();
|
| return num_bytes;
|
| }
|
|
|
| @@ -981,62 +993,49 @@ void EventHandlerImplementation::HandleInterrupt(InterruptMessage* msg) {
|
|
|
| Handle::ScopedLock lock(handle);
|
|
|
| - if (handle->IsError()) {
|
| - DartUtils::PostInt32(msg->dart_port, 1 << kErrorEvent);
|
| - } else {
|
| - if ((msg->data & ((1 << kInEvent) | (1 << kOutEvent))) != 0) {
|
| - // Only set mask if we turned on kInEvent or kOutEvent.
|
| - handle->SetPortAndMask(msg->dart_port, msg->data);
|
| -
|
| - // If in events (data available events) have been requested, and data
|
| - // is available, post an in event immediately. Otherwise make sure
|
| - // that a pending read is issued, unless the socket is already closed
|
| - // for read.
|
| - if ((msg->data & (1 << kInEvent)) != 0) {
|
| - if (handle->Available() > 0) {
|
| - int event_mask = (1 << kInEvent);
|
| - handle->set_mask(handle->mask() & ~event_mask);
|
| - DartUtils::PostInt32(handle->port(), event_mask);
|
| - } else if (handle->IsClosedRead()) {
|
| - int event_mask = (1 << kCloseEvent);
|
| - DartUtils::PostInt32(handle->port(), event_mask);
|
| - } else if (!handle->HasPendingRead()) {
|
| - if (handle->is_datagram_socket()) {
|
| - handle->IssueRecvFrom();
|
| - } else {
|
| - handle->IssueRead();
|
| - }
|
| - }
|
| - }
|
| + // Only set mask if we turned on kInEvent or kOutEvent.
|
| + if ((msg->data & ((1 << kInEvent) | (1 << kOutEvent))) != 0) {
|
| + handle->SetPortAndMask(msg->dart_port, msg->data);
|
| + }
|
|
|
| - // If out events (can write events) have been requested, and there
|
| - // are no pending writes, post an out event immediately.
|
| - if ((msg->data & (1 << kOutEvent)) != 0) {
|
| - if (!handle->HasPendingWrite()) {
|
| - int event_mask = (1 << kOutEvent);
|
| - handle->set_mask(handle->mask() & ~event_mask);
|
| - DartUtils::PostInt32(handle->port(), event_mask);
|
| - }
|
| - }
|
| + // Issue a read.
|
| + if ((msg->data & (1 << kInEvent)) != 0) {
|
| + handle->SetPortAndMask(msg->dart_port, msg->data);
|
| + if (handle->is_datagram_socket()) {
|
| + handle->IssueRecvFrom();
|
| + } else {
|
| + handle->IssueRead();
|
| }
|
| + }
|
|
|
| - if (handle->is_client_socket()) {
|
| - ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(handle);
|
| - if ((msg->data & (1 << kShutdownReadCommand)) != 0) {
|
| - client_socket->Shutdown(SD_RECEIVE);
|
| - }
|
| -
|
| - if ((msg->data & (1 << kShutdownWriteCommand)) != 0) {
|
| - client_socket->Shutdown(SD_SEND);
|
| - }
|
| + // If out events (can write events) have been requested, and there
|
| + // are no pending writes, meaning any writes are already complete,
|
| + // post an out event immediately.
|
| + if ((msg->data & (1 << kOutEvent)) != 0) {
|
| + handle->SetPortAndMask(msg->dart_port, msg->data);
|
| + if (!handle->HasPendingWrite()) {
|
| + int event_mask = (1 << kOutEvent);
|
| + DartUtils::PostInt32(handle->port(), event_mask);
|
| }
|
| }
|
|
|
| - if ((msg->data & (1 << kCloseCommand)) != 0) {
|
| - handle->SetPortAndMask(msg->dart_port, msg->data);
|
| - handle->Close();
|
| + if (handle->is_client_socket()) {
|
| + ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(handle);
|
| + if ((msg->data & (1 << kShutdownReadCommand)) != 0) {
|
| + client_socket->Shutdown(SD_RECEIVE);
|
| + }
|
| +
|
| + if ((msg->data & (1 << kShutdownWriteCommand)) != 0) {
|
| + client_socket->Shutdown(SD_SEND);
|
| + }
|
| }
|
| }
|
| +
|
| + if ((msg->data & (1 << kCloseCommand)) != 0) {
|
| + handle->SetPortAndMask(msg->dart_port, msg->data);
|
| + handle->Close();
|
| + }
|
| +
|
| DeleteIfClosed(handle);
|
| }
|
| }
|
|
|