Chromium Code Reviews| 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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 66 OverlappedBuffer* OverlappedBuffer::AllocateSendToBuffer(int buffer_size) { | 66 OverlappedBuffer* OverlappedBuffer::AllocateSendToBuffer(int buffer_size) { |
| 67 return AllocateBuffer(buffer_size, kSendTo); | 67 return AllocateBuffer(buffer_size, kSendTo); |
| 68 } | 68 } |
| 69 | 69 |
| 70 | 70 |
| 71 OverlappedBuffer* OverlappedBuffer::AllocateDisconnectBuffer() { | 71 OverlappedBuffer* OverlappedBuffer::AllocateDisconnectBuffer() { |
| 72 return AllocateBuffer(0, kDisconnect); | 72 return AllocateBuffer(0, kDisconnect); |
| 73 } | 73 } |
| 74 | 74 |
| 75 | 75 |
| 76 OverlappedBuffer* OverlappedBuffer::AllocateConnectBuffer() { | |
| 77 return AllocateBuffer(0, kConnect); | |
| 78 } | |
| 79 | |
| 80 | |
| 76 void OverlappedBuffer::DisposeBuffer(OverlappedBuffer* buffer) { | 81 void OverlappedBuffer::DisposeBuffer(OverlappedBuffer* buffer) { |
| 77 delete buffer; | 82 delete buffer; |
| 78 } | 83 } |
| 79 | 84 |
| 80 | 85 |
| 81 OverlappedBuffer* OverlappedBuffer::GetFromOverlapped(OVERLAPPED* overlapped) { | 86 OverlappedBuffer* OverlappedBuffer::GetFromOverlapped(OVERLAPPED* overlapped) { |
| 82 OverlappedBuffer* buffer = | 87 OverlappedBuffer* buffer = |
| 83 CONTAINING_RECORD(overlapped, OverlappedBuffer, overlapped_); | 88 CONTAINING_RECORD(overlapped, OverlappedBuffer, overlapped_); |
| 84 return buffer; | 89 return buffer; |
| 85 } | 90 } |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 467 if (!IsClosing()) { | 472 if (!IsClosing()) { |
| 468 // Update the accepted socket to support the full range of API calls. | 473 // Update the accepted socket to support the full range of API calls. |
| 469 SOCKET s = socket(); | 474 SOCKET s = socket(); |
| 470 int rc = setsockopt(buffer->client(), | 475 int rc = setsockopt(buffer->client(), |
| 471 SOL_SOCKET, | 476 SOL_SOCKET, |
| 472 SO_UPDATE_ACCEPT_CONTEXT, | 477 SO_UPDATE_ACCEPT_CONTEXT, |
| 473 reinterpret_cast<char*>(&s), sizeof(s)); | 478 reinterpret_cast<char*>(&s), sizeof(s)); |
| 474 if (rc == NO_ERROR) { | 479 if (rc == NO_ERROR) { |
| 475 // Insert the accepted socket into the list. | 480 // Insert the accepted socket into the list. |
| 476 ClientSocket* client_socket = new ClientSocket(buffer->client(), 0); | 481 ClientSocket* client_socket = new ClientSocket(buffer->client(), 0); |
| 482 client_socket->mark_connected(); | |
| 477 client_socket->CreateCompletionPort(completion_port); | 483 client_socket->CreateCompletionPort(completion_port); |
| 478 if (accepted_head_ == NULL) { | 484 if (accepted_head_ == NULL) { |
| 479 accepted_head_ = client_socket; | 485 accepted_head_ = client_socket; |
| 480 accepted_tail_ = client_socket; | 486 accepted_tail_ = client_socket; |
| 481 } else { | 487 } else { |
| 482 ASSERT(accepted_tail_ != NULL); | 488 ASSERT(accepted_tail_ != NULL); |
| 483 accepted_tail_->set_next(client_socket); | 489 accepted_tail_->set_next(client_socket); |
| 484 accepted_tail_ = client_socket; | 490 accepted_tail_ = client_socket; |
| 485 } | 491 } |
| 486 } else { | 492 } else { |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 804 return true; | 810 return true; |
| 805 } | 811 } |
| 806 OverlappedBuffer::DisposeBuffer(pending_write_); | 812 OverlappedBuffer::DisposeBuffer(pending_write_); |
| 807 pending_write_ = NULL; | 813 pending_write_ = NULL; |
| 808 HandleIssueError(); | 814 HandleIssueError(); |
| 809 return false; | 815 return false; |
| 810 } | 816 } |
| 811 | 817 |
| 812 | 818 |
| 813 void ClientSocket::IssueDisconnect() { | 819 void ClientSocket::IssueDisconnect() { |
| 814 Dart_Port p = port(); | |
| 815 OverlappedBuffer* buffer = OverlappedBuffer::AllocateDisconnectBuffer(); | 820 OverlappedBuffer* buffer = OverlappedBuffer::AllocateDisconnectBuffer(); |
| 816 BOOL ok = DisconnectEx_( | 821 BOOL ok = DisconnectEx_( |
| 817 socket(), buffer->GetCleanOverlapped(), TF_REUSE_SOCKET, 0); | 822 socket(), buffer->GetCleanOverlapped(), TF_REUSE_SOCKET, 0); |
| 818 if (!ok && WSAGetLastError() != WSA_IO_PENDING) { | 823 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
| |
| 819 DisconnectComplete(buffer); | 824 DisconnectComplete(buffer); |
| 820 } | 825 } |
| 826 Dart_Port p = port(); | |
| 821 if (p != ILLEGAL_PORT) DartUtils::PostInt32(p, 1 << kDestroyedEvent); | 827 if (p != ILLEGAL_PORT) DartUtils::PostInt32(p, 1 << kDestroyedEvent); |
| 828 port_ = ILLEGAL_PORT; | |
| 822 } | 829 } |
| 823 | 830 |
| 824 | 831 |
| 825 void ClientSocket::DisconnectComplete(OverlappedBuffer* buffer) { | 832 void ClientSocket::DisconnectComplete(OverlappedBuffer* buffer) { |
| 826 OverlappedBuffer::DisposeBuffer(buffer); | 833 OverlappedBuffer::DisposeBuffer(buffer); |
| 827 closesocket(socket()); | 834 closesocket(socket()); |
| 828 if (data_ready_ != NULL) { | 835 if (data_ready_ != NULL) { |
| 829 OverlappedBuffer::DisposeBuffer(data_ready_); | 836 OverlappedBuffer::DisposeBuffer(data_ready_); |
| 830 } | 837 } |
| 831 // When disconnect is complete get rid of the object. | 838 closed_ = true; |
| 832 delete this; | |
| 833 } | 839 } |
| 834 | 840 |
| 835 | 841 |
| 842 void ClientSocket::ConnectComplete(OverlappedBuffer* buffer) { | |
| 843 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.
| |
| 844 setsockopt(socket(), SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0); | |
| 845 connected_ = true; | |
| 846 Dart_Port p = port(); | |
| 847 if (p != ILLEGAL_PORT) { | |
| 848 // If the port is set, we already listen for this socket in Dart. | |
| 849 // Handle the cases here. | |
| 850 if (!IsClosedRead()) { | |
| 851 IssueRead(); | |
| 852 } | |
| 853 if (!IsClosedWrite()) { | |
| 854 DartUtils::PostInt32(p, 1 << kOutEvent); | |
| 855 } | |
| 856 } | |
| 857 } | |
| 858 | |
| 859 | |
| 836 void ClientSocket::EnsureInitialized( | 860 void ClientSocket::EnsureInitialized( |
| 837 EventHandlerImplementation* event_handler) { | 861 EventHandlerImplementation* event_handler) { |
| 838 ScopedLock lock(this); | 862 ScopedLock lock(this); |
| 839 if (completion_port_ == INVALID_HANDLE_VALUE) { | 863 if (completion_port_ == INVALID_HANDLE_VALUE) { |
| 840 ASSERT(event_handler_ == NULL); | 864 ASSERT(event_handler_ == NULL); |
| 841 event_handler_ = event_handler; | 865 event_handler_ = event_handler; |
| 842 CreateCompletionPort(event_handler_->completion_port()); | 866 CreateCompletionPort(event_handler_->completion_port()); |
| 843 } | 867 } |
| 844 } | 868 } |
| 845 | 869 |
| 846 | 870 |
| 847 bool ClientSocket::IsClosed() { | 871 bool ClientSocket::IsClosed() { |
| 848 return false; | 872 return closed_; |
| 849 } | 873 } |
| 850 | 874 |
| 851 | 875 |
| 852 bool DatagramSocket::IssueSendTo(struct sockaddr* sa, socklen_t sa_len) { | 876 bool DatagramSocket::IssueSendTo(struct sockaddr* sa, socklen_t sa_len) { |
| 853 ScopedLock lock(this); | 877 ScopedLock lock(this); |
| 854 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 878 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
| 855 ASSERT(pending_write_ != NULL); | 879 ASSERT(pending_write_ != NULL); |
| 856 ASSERT(pending_write_->operation() == OverlappedBuffer::kSendTo); | 880 ASSERT(pending_write_->operation() == OverlappedBuffer::kSendTo); |
| 857 | 881 |
| 858 int rc = WSASendTo(socket(), | 882 int rc = WSASendTo(socket(), |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 925 closesocket(socket()); | 949 closesocket(socket()); |
| 926 MarkClosedRead(); | 950 MarkClosedRead(); |
| 927 MarkClosedWrite(); | 951 MarkClosedWrite(); |
| 928 } | 952 } |
| 929 | 953 |
| 930 | 954 |
| 931 static void DeleteIfClosed(Handle* handle) { | 955 static void DeleteIfClosed(Handle* handle) { |
| 932 if (handle->IsClosed()) { | 956 if (handle->IsClosed()) { |
| 933 Dart_Port port = handle->port(); | 957 Dart_Port port = handle->port(); |
| 934 delete handle; | 958 delete handle; |
| 935 DartUtils::PostInt32(port, 1 << kDestroyedEvent); | 959 if (port != ILLEGAL_PORT) { |
| 960 DartUtils::PostInt32(port, 1 << kDestroyedEvent); | |
| 961 } | |
| 936 } | 962 } |
| 937 } | 963 } |
| 938 | 964 |
| 939 | 965 |
| 940 void EventHandlerImplementation::HandleInterrupt(InterruptMessage* msg) { | 966 void EventHandlerImplementation::HandleInterrupt(InterruptMessage* msg) { |
| 941 if (msg->id == kTimeoutId) { | 967 if (msg->id == kTimeoutId) { |
| 942 // Change of timeout request. Just set the new timeout and port as the | 968 // Change of timeout request. Just set the new timeout and port as the |
| 943 // completion thread will use the new timeout value for its next wait. | 969 // completion thread will use the new timeout value for its next wait. |
| 944 timeout_queue_.UpdateTimeout(msg->dart_port, msg->data); | 970 timeout_queue_.UpdateTimeout(msg->dart_port, msg->data); |
| 945 } else if (msg->id == kShutdownId) { | 971 } else if (msg->id == kShutdownId) { |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 967 } | 993 } |
| 968 // Always keep 5 outstanding accepts going, to enhance performance. | 994 // Always keep 5 outstanding accepts going, to enhance performance. |
| 969 while (listen_socket->pending_accept_count() < 5) { | 995 while (listen_socket->pending_accept_count() < 5) { |
| 970 bool accept_success = listen_socket->IssueAccept(); | 996 bool accept_success = listen_socket->IssueAccept(); |
| 971 if (!accept_success) { | 997 if (!accept_success) { |
| 972 HandleError(listen_socket); | 998 HandleError(listen_socket); |
| 973 break; | 999 break; |
| 974 } | 1000 } |
| 975 } | 1001 } |
| 976 } | 1002 } |
| 977 | |
| 978 if ((msg->data & (1 << kCloseCommand)) != 0) { | |
| 979 listen_socket->Close(); | |
| 980 } | |
| 981 } else { | 1003 } else { |
| 982 handle->EnsureInitialized(this); | 1004 handle->EnsureInitialized(this); |
| 983 | 1005 |
| 984 Handle::ScopedLock lock(handle); | 1006 Handle::ScopedLock lock(handle); |
| 985 | 1007 |
| 986 // Only set mask if we turned on kInEvent or kOutEvent. | 1008 // Only set mask if we turned on kInEvent or kOutEvent. |
| 987 if ((msg->data & ((1 << kInEvent) | (1 << kOutEvent))) != 0) { | 1009 if ((msg->data & ((1 << kInEvent) | (1 << kOutEvent))) != 0) { |
| 988 handle->SetPortAndMask(msg->dart_port, msg->data); | 1010 handle->SetPortAndMask(msg->dart_port, msg->data); |
| 989 } | 1011 } |
| 990 | 1012 |
| 991 // Issue a read. | 1013 // Issue a read. |
| 992 if ((msg->data & (1 << kInEvent)) != 0) { | 1014 if ((msg->data & (1 << kInEvent)) != 0) { |
| 993 handle->SetPortAndMask(msg->dart_port, msg->data); | |
| 994 if (handle->is_datagram_socket()) { | 1015 if (handle->is_datagram_socket()) { |
| 995 handle->IssueRecvFrom(); | 1016 handle->IssueRecvFrom(); |
| 1017 } else if (handle->is_client_socket()) { | |
| 1018 if (reinterpret_cast<ClientSocket*>(handle)->is_connected()) { | |
| 1019 handle->IssueRead(); | |
| 1020 } | |
| 996 } else { | 1021 } else { |
| 997 handle->IssueRead(); | 1022 handle->IssueRead(); |
| 998 } | 1023 } |
| 999 } | 1024 } |
| 1000 | 1025 |
| 1001 // If out events (can write events) have been requested, and there | 1026 // If out events (can write events) have been requested, and there |
| 1002 // are no pending writes, meaning any writes are already complete, | 1027 // are no pending writes, meaning any writes are already complete, |
| 1003 // post an out event immediately. | 1028 // post an out event immediately. |
| 1004 if ((msg->data & (1 << kOutEvent)) != 0) { | 1029 if ((msg->data & (1 << kOutEvent)) != 0) { |
| 1005 handle->SetPortAndMask(msg->dart_port, msg->data); | |
| 1006 if (!handle->HasPendingWrite()) { | 1030 if (!handle->HasPendingWrite()) { |
| 1007 int event_mask = (1 << kOutEvent); | 1031 if (handle->is_client_socket()) { |
| 1008 DartUtils::PostInt32(handle->port(), event_mask); | 1032 if (reinterpret_cast<ClientSocket*>(handle)->is_connected()) { |
| 1033 DartUtils::PostInt32(handle->port(), 1 << kOutEvent); | |
| 1034 } | |
| 1035 } else { | |
| 1036 DartUtils::PostInt32(handle->port(), 1 << kOutEvent); | |
| 1037 } | |
| 1009 } | 1038 } |
| 1010 } | 1039 } |
| 1011 | 1040 |
| 1012 if (handle->is_client_socket()) { | 1041 if (handle->is_client_socket()) { |
| 1013 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(handle); | 1042 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(handle); |
| 1014 if ((msg->data & (1 << kShutdownReadCommand)) != 0) { | 1043 if ((msg->data & (1 << kShutdownReadCommand)) != 0) { |
| 1015 client_socket->Shutdown(SD_RECEIVE); | 1044 client_socket->Shutdown(SD_RECEIVE); |
| 1016 } | 1045 } |
| 1017 | 1046 |
| 1018 if ((msg->data & (1 << kShutdownWriteCommand)) != 0) { | 1047 if ((msg->data & (1 << kShutdownWriteCommand)) != 0) { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1107 | 1136 |
| 1108 | 1137 |
| 1109 void EventHandlerImplementation::HandleWrite(Handle* handle, | 1138 void EventHandlerImplementation::HandleWrite(Handle* handle, |
| 1110 int bytes, | 1139 int bytes, |
| 1111 OverlappedBuffer* buffer) { | 1140 OverlappedBuffer* buffer) { |
| 1112 handle->WriteComplete(buffer); | 1141 handle->WriteComplete(buffer); |
| 1113 | 1142 |
| 1114 if (bytes >= 0) { | 1143 if (bytes >= 0) { |
| 1115 if (!handle->IsError() && !handle->IsClosing()) { | 1144 if (!handle->IsError() && !handle->IsClosing()) { |
| 1116 int event_mask = 1 << kOutEvent; | 1145 int event_mask = 1 << kOutEvent; |
| 1146 ASSERT(!handle->is_client_socket() || | |
| 1147 reinterpret_cast<ClientSocket*>(handle)->is_connected()); | |
| 1117 if ((handle->mask() & event_mask) != 0) { | 1148 if ((handle->mask() & event_mask) != 0) { |
| 1118 DartUtils::PostInt32(handle->port(), event_mask); | 1149 DartUtils::PostInt32(handle->port(), event_mask); |
| 1119 } | 1150 } |
| 1120 } | 1151 } |
| 1121 } else { | 1152 } else { |
| 1122 HandleError(handle); | 1153 HandleError(handle); |
| 1123 } | 1154 } |
| 1124 | 1155 |
| 1125 DeleteIfClosed(handle); | 1156 DeleteIfClosed(handle); |
| 1126 } | 1157 } |
| 1127 | 1158 |
| 1128 | 1159 |
| 1129 void EventHandlerImplementation::HandleDisconnect( | 1160 void EventHandlerImplementation::HandleDisconnect( |
| 1130 ClientSocket* client_socket, | 1161 ClientSocket* client_socket, |
| 1131 int bytes, | 1162 int bytes, |
| 1132 OverlappedBuffer* buffer) { | 1163 OverlappedBuffer* buffer) { |
| 1133 client_socket->DisconnectComplete(buffer); | 1164 client_socket->DisconnectComplete(buffer); |
| 1165 DeleteIfClosed(client_socket); | |
| 1134 } | 1166 } |
| 1135 | 1167 |
| 1168 | |
| 1169 void EventHandlerImplementation::HandleConnect( | |
| 1170 ClientSocket* client_socket, | |
| 1171 int bytes, | |
| 1172 OverlappedBuffer* buffer) { | |
| 1173 if (bytes < 0) { | |
| 1174 HandleError(client_socket); | |
| 1175 OverlappedBuffer::DisposeBuffer(buffer); | |
| 1176 } else { | |
| 1177 client_socket->ConnectComplete(buffer); | |
| 1178 } | |
| 1179 } | |
| 1180 | |
| 1181 | |
| 1136 void EventHandlerImplementation::HandleTimeout() { | 1182 void EventHandlerImplementation::HandleTimeout() { |
| 1137 if (!timeout_queue_.HasTimeout()) return; | 1183 if (!timeout_queue_.HasTimeout()) return; |
| 1138 DartUtils::PostNull(timeout_queue_.CurrentPort()); | 1184 DartUtils::PostNull(timeout_queue_.CurrentPort()); |
| 1139 timeout_queue_.RemoveCurrent(); | 1185 timeout_queue_.RemoveCurrent(); |
| 1140 } | 1186 } |
| 1141 | 1187 |
| 1142 | 1188 |
| 1143 void EventHandlerImplementation::HandleIOCompletion(DWORD bytes, | 1189 void EventHandlerImplementation::HandleIOCompletion(DWORD bytes, |
| 1144 ULONG_PTR key, | 1190 ULONG_PTR key, |
| 1145 OVERLAPPED* overlapped) { | 1191 OVERLAPPED* overlapped) { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 1164 case OverlappedBuffer::kSendTo: { | 1210 case OverlappedBuffer::kSendTo: { |
| 1165 Handle* handle = reinterpret_cast<Handle*>(key); | 1211 Handle* handle = reinterpret_cast<Handle*>(key); |
| 1166 HandleWrite(handle, bytes, buffer); | 1212 HandleWrite(handle, bytes, buffer); |
| 1167 break; | 1213 break; |
| 1168 } | 1214 } |
| 1169 case OverlappedBuffer::kDisconnect: { | 1215 case OverlappedBuffer::kDisconnect: { |
| 1170 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(key); | 1216 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(key); |
| 1171 HandleDisconnect(client_socket, bytes, buffer); | 1217 HandleDisconnect(client_socket, bytes, buffer); |
| 1172 break; | 1218 break; |
| 1173 } | 1219 } |
| 1220 case OverlappedBuffer::kConnect: { | |
| 1221 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(key); | |
| 1222 HandleConnect(client_socket, bytes, buffer); | |
| 1223 break; | |
| 1224 } | |
| 1174 default: | 1225 default: |
| 1175 UNREACHABLE(); | 1226 UNREACHABLE(); |
| 1176 } | 1227 } |
| 1177 } | 1228 } |
| 1178 | 1229 |
| 1179 | 1230 |
| 1180 EventHandlerImplementation::EventHandlerImplementation() { | 1231 EventHandlerImplementation::EventHandlerImplementation() { |
| 1181 intptr_t result; | 1232 intptr_t result; |
| 1182 completion_port_ = | 1233 completion_port_ = |
| 1183 CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 1); | 1234 CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 1); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1289 | 1340 |
| 1290 | 1341 |
| 1291 void EventHandlerImplementation::Shutdown() { | 1342 void EventHandlerImplementation::Shutdown() { |
| 1292 SendData(kShutdownId, 0, 0); | 1343 SendData(kShutdownId, 0, 0); |
| 1293 } | 1344 } |
| 1294 | 1345 |
| 1295 } // namespace bin | 1346 } // namespace bin |
| 1296 } // namespace dart | 1347 } // namespace dart |
| 1297 | 1348 |
| 1298 #endif // defined(TARGET_OS_WINDOWS) | 1349 #endif // defined(TARGET_OS_WINDOWS) |
| OLD | NEW |