Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(747)

Unified Diff: runtime/bin/eventhandler_win.cc

Issue 8437090: Change the handling of closing sockets (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed review comments by ager@ Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/bin/eventhandler_win.h ('k') | runtime/bin/input_stream.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/eventhandler_win.cc
diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc
index f7f1f17d32cd914cc75cf64e06920644baceeaf8..1b1202894f72e150e591b13cc7e296075b3f58da 100644
--- a/runtime/bin/eventhandler_win.cc
+++ b/runtime/bin/eventhandler_win.cc
@@ -342,19 +342,30 @@ bool ListenSocket::IssueAccept() {
void ListenSocket::AcceptComplete(IOBuffer* buffer, HANDLE completion_port) {
ScopedLock lock(this);
if (!closing_) {
- ClientSocket* client_socket = new ClientSocket(buffer->client(), 0);
- client_socket->CreateCompletionPort(completion_port);
- if (accepted_head_ == NULL) {
- accepted_head_ = client_socket;
- accepted_tail_ = client_socket;
+ // Update the accepted socket to support the full range of API calls.
+ SOCKET s = socket();
+ int rc = setsockopt(buffer->client(),
+ SOL_SOCKET,
+ SO_UPDATE_ACCEPT_CONTEXT,
+ reinterpret_cast<char*>(&s), sizeof(s));
+ if (rc == NO_ERROR) {
+ // Insert the accepted socket into the list.
+ ClientSocket* client_socket = new ClientSocket(buffer->client(), 0);
+ client_socket->CreateCompletionPort(completion_port);
+ if (accepted_head_ == NULL) {
+ accepted_head_ = client_socket;
+ accepted_tail_ = client_socket;
+ } else {
+ ASSERT(accepted_tail_ != NULL);
+ accepted_tail_->set_next(client_socket);
+ accepted_tail_ = client_socket;
+ }
} else {
- ASSERT(accepted_tail_ != NULL);
- accepted_tail_->set_next(client_socket);
- accepted_tail_ = client_socket;
+ fprintf(stderr, "setsockopt failed: %d\n", WSAGetLastError());
+ closesocket(buffer->client());
}
- } else {
- closesocket(buffer->client());
}
+
pending_accept_count_--;
IOBuffer::DisposeBuffer(buffer);
}
@@ -366,6 +377,7 @@ ClientSocket* ListenSocket::Accept() {
ClientSocket* result = accepted_head_;
accepted_head_ = accepted_head_->next();
if (accepted_head_ == NULL) accepted_tail_ = NULL;
+ result->set_next(NULL);
return result;
}
@@ -433,6 +445,19 @@ int Handle::Write(const void* buffer, int num_bytes) {
return num_bytes;
}
+void ClientSocket::Shutdown(int how) {
+ int rc = shutdown(socket(), how);
+ if (rc == SOCKET_ERROR) {
+ fprintf(stderr, "shutdown failed: %d %d\n", socket(), WSAGetLastError());
+ }
+ if (how == SD_RECEIVE) MarkClosedRead();
+ if (how == SD_SEND) MarkClosedWrite();
+ if (how == SD_BOTH) {
+ MarkClosedRead();
+ MarkClosedWrite();
+ }
+}
+
bool ClientSocket::IssueRead() {
ScopedLock lock(this);
@@ -554,14 +579,15 @@ void EventHandlerImplementation::HandleInterrupt(InterruptMessage* msg) {
Handle::ScopedLock lock(client_socket);
- // If data available callback has been requested and data are
+ // If the data available callback has been requested and data are
// available post it immediately. Otherwise make sure that a pending
- // read is issued.
+ // read is issued unless the socket is already closed for read.
if ((msg->data & (1 << kInEvent)) != 0) {
if (client_socket->Available() > 0) {
int event_mask = (1 << kInEvent);
Dart_PostIntArray(client_socket->port(), 1, &event_mask);
- } else if (!client_socket->HasPendingRead()) {
+ } else if (!client_socket->HasPendingRead() &&
+ !client_socket->IsClosedRead()) {
client_socket->IssueRead();
}
}
@@ -575,6 +601,14 @@ void EventHandlerImplementation::HandleInterrupt(InterruptMessage* msg) {
}
}
+ 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) {
client_socket->close();
if (client_socket->IsClosed()) {
@@ -621,7 +655,6 @@ void EventHandlerImplementation::HandleRead(ClientSocket* client_socket,
IOBuffer* buffer) {
buffer->set_data_length(bytes);
client_socket->ReadComplete(buffer);
-
if (bytes > 0) {
if (!client_socket->is_closing()) {
int event_mask = 1 << kInEvent;
@@ -631,6 +664,7 @@ void EventHandlerImplementation::HandleRead(ClientSocket* client_socket,
}
} else {
ASSERT(bytes == 0);
+ client_socket->MarkClosedRead();
HandleClosed(client_socket);
}
« no previous file with comments | « runtime/bin/eventhandler_win.h ('k') | runtime/bin/input_stream.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698