Chromium Code Reviews| Index: runtime/bin/eventhandler_win.cc |
| diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc |
| index d32fb1ec253fcffcce214715f5aaf0b8bd82d5eb..25efab6d089eb0fb58eac8ae698bc74f705d956f 100644 |
| --- a/runtime/bin/eventhandler_win.cc |
| +++ b/runtime/bin/eventhandler_win.cc |
| @@ -73,6 +73,11 @@ OverlappedBuffer* OverlappedBuffer::AllocateDisconnectBuffer() { |
| } |
| +OverlappedBuffer* OverlappedBuffer::AllocateConnectBuffer() { |
| + return AllocateBuffer(0, kConnect); |
| +} |
| + |
| + |
| void OverlappedBuffer::DisposeBuffer(OverlappedBuffer* buffer) { |
| delete buffer; |
| } |
| @@ -474,6 +479,7 @@ void ListenSocket::AcceptComplete(OverlappedBuffer* buffer, |
| if (rc == NO_ERROR) { |
| // Insert the accepted socket into the list. |
| ClientSocket* client_socket = new ClientSocket(buffer->client(), 0); |
| + client_socket->mark_connected(); |
| client_socket->CreateCompletionPort(completion_port); |
| if (accepted_head_ == NULL) { |
| accepted_head_ = client_socket; |
| @@ -811,14 +817,15 @@ bool ClientSocket::IssueWrite() { |
| void ClientSocket::IssueDisconnect() { |
| - Dart_Port p = port(); |
| OverlappedBuffer* buffer = OverlappedBuffer::AllocateDisconnectBuffer(); |
| BOOL ok = DisconnectEx_( |
| socket(), buffer->GetCleanOverlapped(), TF_REUSE_SOCKET, 0); |
| - if (!ok && WSAGetLastError() != WSA_IO_PENDING) { |
| + if (ok || WSAGetLastError() != WSA_IO_PENDING) { |
|
Søren Gjesse
2014/05/01 07:19:26
When is it possible to get a success here? Please
Anders Johnsen
2014/05/01 08:05:11
"On success, the DisconnectEx function returns TRU
|
| DisconnectComplete(buffer); |
| } |
| + Dart_Port p = port(); |
| if (p != ILLEGAL_PORT) DartUtils::PostInt32(p, 1 << kDestroyedEvent); |
| + port_ = ILLEGAL_PORT; |
| } |
| @@ -828,8 +835,25 @@ void ClientSocket::DisconnectComplete(OverlappedBuffer* buffer) { |
| if (data_ready_ != NULL) { |
| OverlappedBuffer::DisposeBuffer(data_ready_); |
| } |
| - // When disconnect is complete get rid of the object. |
| - delete this; |
| + closed_ = true; |
| +} |
| + |
| + |
| +void ClientSocket::ConnectComplete(OverlappedBuffer* buffer) { |
| + OverlappedBuffer::DisposeBuffer(buffer); |
|
Søren Gjesse
2014/05/01 07:19:26
Please add a comment on this call, e.g. " // Updat
Anders Johnsen
2014/05/01 08:05:11
Done.
|
| + setsockopt(socket(), SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0); |
| + connected_ = true; |
| + Dart_Port p = port(); |
| + if (p != ILLEGAL_PORT) { |
| + // If the port is set, we already listen for this socket in Dart. |
| + // Handle the cases here. |
| + if (!IsClosedRead()) { |
| + IssueRead(); |
| + } |
| + if (!IsClosedWrite()) { |
| + DartUtils::PostInt32(p, 1 << kOutEvent); |
| + } |
| + } |
| } |
| @@ -845,7 +869,7 @@ void ClientSocket::EnsureInitialized( |
| bool ClientSocket::IsClosed() { |
| - return false; |
| + return closed_; |
| } |
| @@ -932,7 +956,9 @@ static void DeleteIfClosed(Handle* handle) { |
| if (handle->IsClosed()) { |
| Dart_Port port = handle->port(); |
| delete handle; |
| - DartUtils::PostInt32(port, 1 << kDestroyedEvent); |
| + if (port != ILLEGAL_PORT) { |
| + DartUtils::PostInt32(port, 1 << kDestroyedEvent); |
| + } |
| } |
| } |
| @@ -974,10 +1000,6 @@ void EventHandlerImplementation::HandleInterrupt(InterruptMessage* msg) { |
| } |
| } |
| } |
| - |
| - if ((msg->data & (1 << kCloseCommand)) != 0) { |
| - listen_socket->Close(); |
| - } |
| } else { |
| handle->EnsureInitialized(this); |
| @@ -990,9 +1012,12 @@ void EventHandlerImplementation::HandleInterrupt(InterruptMessage* msg) { |
| // Issue a read. |
| if ((msg->data & (1 << kInEvent)) != 0) { |
| - handle->SetPortAndMask(msg->dart_port, msg->data); |
| if (handle->is_datagram_socket()) { |
| handle->IssueRecvFrom(); |
| + } else if (handle->is_client_socket()) { |
| + if (reinterpret_cast<ClientSocket*>(handle)->is_connected()) { |
| + handle->IssueRead(); |
| + } |
| } else { |
| handle->IssueRead(); |
| } |
| @@ -1002,10 +1027,14 @@ void EventHandlerImplementation::HandleInterrupt(InterruptMessage* msg) { |
| // 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 (handle->is_client_socket()) { |
| + if (reinterpret_cast<ClientSocket*>(handle)->is_connected()) { |
| + DartUtils::PostInt32(handle->port(), 1 << kOutEvent); |
| + } |
| + } else { |
| + DartUtils::PostInt32(handle->port(), 1 << kOutEvent); |
| + } |
| } |
| } |
| @@ -1114,6 +1143,8 @@ void EventHandlerImplementation::HandleWrite(Handle* handle, |
| if (bytes >= 0) { |
| if (!handle->IsError() && !handle->IsClosing()) { |
| int event_mask = 1 << kOutEvent; |
| + ASSERT(!handle->is_client_socket() || |
| + reinterpret_cast<ClientSocket*>(handle)->is_connected()); |
| if ((handle->mask() & event_mask) != 0) { |
| DartUtils::PostInt32(handle->port(), event_mask); |
| } |
| @@ -1131,8 +1162,23 @@ void EventHandlerImplementation::HandleDisconnect( |
| int bytes, |
| OverlappedBuffer* buffer) { |
| client_socket->DisconnectComplete(buffer); |
| + DeleteIfClosed(client_socket); |
| } |
| + |
| +void EventHandlerImplementation::HandleConnect( |
| + ClientSocket* client_socket, |
| + int bytes, |
| + OverlappedBuffer* buffer) { |
| + if (bytes < 0) { |
| + HandleError(client_socket); |
| + OverlappedBuffer::DisposeBuffer(buffer); |
| + } else { |
| + client_socket->ConnectComplete(buffer); |
| + } |
| +} |
| + |
| + |
| void EventHandlerImplementation::HandleTimeout() { |
| if (!timeout_queue_.HasTimeout()) return; |
| DartUtils::PostNull(timeout_queue_.CurrentPort()); |
| @@ -1171,6 +1217,11 @@ void EventHandlerImplementation::HandleIOCompletion(DWORD bytes, |
| HandleDisconnect(client_socket, bytes, buffer); |
| break; |
| } |
| + case OverlappedBuffer::kConnect: { |
| + ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(key); |
| + HandleConnect(client_socket, bytes, buffer); |
| + break; |
| + } |
| default: |
| UNREACHABLE(); |
| } |