| 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 // DisconnectEx works like other OverlappedIO APIs, where we can get either an |
| 824 // immediate success or delayed operation by WSA_IO_PENDING being set. |
| 825 if (ok || WSAGetLastError() != WSA_IO_PENDING) { |
| 819 DisconnectComplete(buffer); | 826 DisconnectComplete(buffer); |
| 820 } | 827 } |
| 828 Dart_Port p = port(); |
| 821 if (p != ILLEGAL_PORT) DartUtils::PostInt32(p, 1 << kDestroyedEvent); | 829 if (p != ILLEGAL_PORT) DartUtils::PostInt32(p, 1 << kDestroyedEvent); |
| 830 port_ = ILLEGAL_PORT; |
| 822 } | 831 } |
| 823 | 832 |
| 824 | 833 |
| 825 void ClientSocket::DisconnectComplete(OverlappedBuffer* buffer) { | 834 void ClientSocket::DisconnectComplete(OverlappedBuffer* buffer) { |
| 826 OverlappedBuffer::DisposeBuffer(buffer); | 835 OverlappedBuffer::DisposeBuffer(buffer); |
| 827 closesocket(socket()); | 836 closesocket(socket()); |
| 828 if (data_ready_ != NULL) { | 837 if (data_ready_ != NULL) { |
| 829 OverlappedBuffer::DisposeBuffer(data_ready_); | 838 OverlappedBuffer::DisposeBuffer(data_ready_); |
| 830 } | 839 } |
| 831 // When disconnect is complete get rid of the object. | 840 closed_ = true; |
| 832 delete this; | |
| 833 } | 841 } |
| 834 | 842 |
| 835 | 843 |
| 844 void ClientSocket::ConnectComplete(OverlappedBuffer* buffer) { |
| 845 OverlappedBuffer::DisposeBuffer(buffer); |
| 846 // Update socket to support full socket API, after ConnectEx completed. |
| 847 setsockopt(socket(), SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0); |
| 848 connected_ = true; |
| 849 Dart_Port p = port(); |
| 850 if (p != ILLEGAL_PORT) { |
| 851 // If the port is set, we already listen for this socket in Dart. |
| 852 // Handle the cases here. |
| 853 if (!IsClosedRead()) { |
| 854 IssueRead(); |
| 855 } |
| 856 if (!IsClosedWrite()) { |
| 857 DartUtils::PostInt32(p, 1 << kOutEvent); |
| 858 } |
| 859 } |
| 860 } |
| 861 |
| 862 |
| 836 void ClientSocket::EnsureInitialized( | 863 void ClientSocket::EnsureInitialized( |
| 837 EventHandlerImplementation* event_handler) { | 864 EventHandlerImplementation* event_handler) { |
| 838 ScopedLock lock(this); | 865 ScopedLock lock(this); |
| 839 if (completion_port_ == INVALID_HANDLE_VALUE) { | 866 if (completion_port_ == INVALID_HANDLE_VALUE) { |
| 840 ASSERT(event_handler_ == NULL); | 867 ASSERT(event_handler_ == NULL); |
| 841 event_handler_ = event_handler; | 868 event_handler_ = event_handler; |
| 842 CreateCompletionPort(event_handler_->completion_port()); | 869 CreateCompletionPort(event_handler_->completion_port()); |
| 843 } | 870 } |
| 844 } | 871 } |
| 845 | 872 |
| 846 | 873 |
| 847 bool ClientSocket::IsClosed() { | 874 bool ClientSocket::IsClosed() { |
| 848 return false; | 875 return closed_; |
| 849 } | 876 } |
| 850 | 877 |
| 851 | 878 |
| 852 bool DatagramSocket::IssueSendTo(struct sockaddr* sa, socklen_t sa_len) { | 879 bool DatagramSocket::IssueSendTo(struct sockaddr* sa, socklen_t sa_len) { |
| 853 ScopedLock lock(this); | 880 ScopedLock lock(this); |
| 854 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); | 881 ASSERT(completion_port_ != INVALID_HANDLE_VALUE); |
| 855 ASSERT(pending_write_ != NULL); | 882 ASSERT(pending_write_ != NULL); |
| 856 ASSERT(pending_write_->operation() == OverlappedBuffer::kSendTo); | 883 ASSERT(pending_write_->operation() == OverlappedBuffer::kSendTo); |
| 857 | 884 |
| 858 int rc = WSASendTo(socket(), | 885 int rc = WSASendTo(socket(), |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 925 closesocket(socket()); | 952 closesocket(socket()); |
| 926 MarkClosedRead(); | 953 MarkClosedRead(); |
| 927 MarkClosedWrite(); | 954 MarkClosedWrite(); |
| 928 } | 955 } |
| 929 | 956 |
| 930 | 957 |
| 931 static void DeleteIfClosed(Handle* handle) { | 958 static void DeleteIfClosed(Handle* handle) { |
| 932 if (handle->IsClosed()) { | 959 if (handle->IsClosed()) { |
| 933 Dart_Port port = handle->port(); | 960 Dart_Port port = handle->port(); |
| 934 delete handle; | 961 delete handle; |
| 935 DartUtils::PostInt32(port, 1 << kDestroyedEvent); | 962 if (port != ILLEGAL_PORT) { |
| 963 DartUtils::PostInt32(port, 1 << kDestroyedEvent); |
| 964 } |
| 936 } | 965 } |
| 937 } | 966 } |
| 938 | 967 |
| 939 | 968 |
| 940 void EventHandlerImplementation::HandleInterrupt(InterruptMessage* msg) { | 969 void EventHandlerImplementation::HandleInterrupt(InterruptMessage* msg) { |
| 941 if (msg->id == kTimeoutId) { | 970 if (msg->id == kTimeoutId) { |
| 942 // Change of timeout request. Just set the new timeout and port as the | 971 // 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. | 972 // completion thread will use the new timeout value for its next wait. |
| 944 timeout_queue_.UpdateTimeout(msg->dart_port, msg->data); | 973 timeout_queue_.UpdateTimeout(msg->dart_port, msg->data); |
| 945 } else if (msg->id == kShutdownId) { | 974 } else if (msg->id == kShutdownId) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 967 } | 996 } |
| 968 // Always keep 5 outstanding accepts going, to enhance performance. | 997 // Always keep 5 outstanding accepts going, to enhance performance. |
| 969 while (listen_socket->pending_accept_count() < 5) { | 998 while (listen_socket->pending_accept_count() < 5) { |
| 970 bool accept_success = listen_socket->IssueAccept(); | 999 bool accept_success = listen_socket->IssueAccept(); |
| 971 if (!accept_success) { | 1000 if (!accept_success) { |
| 972 HandleError(listen_socket); | 1001 HandleError(listen_socket); |
| 973 break; | 1002 break; |
| 974 } | 1003 } |
| 975 } | 1004 } |
| 976 } | 1005 } |
| 977 | |
| 978 if ((msg->data & (1 << kCloseCommand)) != 0) { | |
| 979 listen_socket->Close(); | |
| 980 } | |
| 981 } else { | 1006 } else { |
| 982 handle->EnsureInitialized(this); | 1007 handle->EnsureInitialized(this); |
| 983 | 1008 |
| 984 Handle::ScopedLock lock(handle); | 1009 Handle::ScopedLock lock(handle); |
| 985 | 1010 |
| 986 // Only set mask if we turned on kInEvent or kOutEvent. | 1011 // Only set mask if we turned on kInEvent or kOutEvent. |
| 987 if ((msg->data & ((1 << kInEvent) | (1 << kOutEvent))) != 0) { | 1012 if ((msg->data & ((1 << kInEvent) | (1 << kOutEvent))) != 0) { |
| 988 handle->SetPortAndMask(msg->dart_port, msg->data); | 1013 handle->SetPortAndMask(msg->dart_port, msg->data); |
| 989 } | 1014 } |
| 990 | 1015 |
| 991 // Issue a read. | 1016 // Issue a read. |
| 992 if ((msg->data & (1 << kInEvent)) != 0) { | 1017 if ((msg->data & (1 << kInEvent)) != 0) { |
| 993 handle->SetPortAndMask(msg->dart_port, msg->data); | |
| 994 if (handle->is_datagram_socket()) { | 1018 if (handle->is_datagram_socket()) { |
| 995 handle->IssueRecvFrom(); | 1019 handle->IssueRecvFrom(); |
| 1020 } else if (handle->is_client_socket()) { |
| 1021 if (reinterpret_cast<ClientSocket*>(handle)->is_connected()) { |
| 1022 handle->IssueRead(); |
| 1023 } |
| 996 } else { | 1024 } else { |
| 997 handle->IssueRead(); | 1025 handle->IssueRead(); |
| 998 } | 1026 } |
| 999 } | 1027 } |
| 1000 | 1028 |
| 1001 // If out events (can write events) have been requested, and there | 1029 // If out events (can write events) have been requested, and there |
| 1002 // are no pending writes, meaning any writes are already complete, | 1030 // are no pending writes, meaning any writes are already complete, |
| 1003 // post an out event immediately. | 1031 // post an out event immediately. |
| 1004 if ((msg->data & (1 << kOutEvent)) != 0) { | 1032 if ((msg->data & (1 << kOutEvent)) != 0) { |
| 1005 handle->SetPortAndMask(msg->dart_port, msg->data); | |
| 1006 if (!handle->HasPendingWrite()) { | 1033 if (!handle->HasPendingWrite()) { |
| 1007 int event_mask = (1 << kOutEvent); | 1034 if (handle->is_client_socket()) { |
| 1008 DartUtils::PostInt32(handle->port(), event_mask); | 1035 if (reinterpret_cast<ClientSocket*>(handle)->is_connected()) { |
| 1036 DartUtils::PostInt32(handle->port(), 1 << kOutEvent); |
| 1037 } |
| 1038 } else { |
| 1039 DartUtils::PostInt32(handle->port(), 1 << kOutEvent); |
| 1040 } |
| 1009 } | 1041 } |
| 1010 } | 1042 } |
| 1011 | 1043 |
| 1012 if (handle->is_client_socket()) { | 1044 if (handle->is_client_socket()) { |
| 1013 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(handle); | 1045 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(handle); |
| 1014 if ((msg->data & (1 << kShutdownReadCommand)) != 0) { | 1046 if ((msg->data & (1 << kShutdownReadCommand)) != 0) { |
| 1015 client_socket->Shutdown(SD_RECEIVE); | 1047 client_socket->Shutdown(SD_RECEIVE); |
| 1016 } | 1048 } |
| 1017 | 1049 |
| 1018 if ((msg->data & (1 << kShutdownWriteCommand)) != 0) { | 1050 if ((msg->data & (1 << kShutdownWriteCommand)) != 0) { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1107 | 1139 |
| 1108 | 1140 |
| 1109 void EventHandlerImplementation::HandleWrite(Handle* handle, | 1141 void EventHandlerImplementation::HandleWrite(Handle* handle, |
| 1110 int bytes, | 1142 int bytes, |
| 1111 OverlappedBuffer* buffer) { | 1143 OverlappedBuffer* buffer) { |
| 1112 handle->WriteComplete(buffer); | 1144 handle->WriteComplete(buffer); |
| 1113 | 1145 |
| 1114 if (bytes >= 0) { | 1146 if (bytes >= 0) { |
| 1115 if (!handle->IsError() && !handle->IsClosing()) { | 1147 if (!handle->IsError() && !handle->IsClosing()) { |
| 1116 int event_mask = 1 << kOutEvent; | 1148 int event_mask = 1 << kOutEvent; |
| 1149 ASSERT(!handle->is_client_socket() || |
| 1150 reinterpret_cast<ClientSocket*>(handle)->is_connected()); |
| 1117 if ((handle->mask() & event_mask) != 0) { | 1151 if ((handle->mask() & event_mask) != 0) { |
| 1118 DartUtils::PostInt32(handle->port(), event_mask); | 1152 DartUtils::PostInt32(handle->port(), event_mask); |
| 1119 } | 1153 } |
| 1120 } | 1154 } |
| 1121 } else { | 1155 } else { |
| 1122 HandleError(handle); | 1156 HandleError(handle); |
| 1123 } | 1157 } |
| 1124 | 1158 |
| 1125 DeleteIfClosed(handle); | 1159 DeleteIfClosed(handle); |
| 1126 } | 1160 } |
| 1127 | 1161 |
| 1128 | 1162 |
| 1129 void EventHandlerImplementation::HandleDisconnect( | 1163 void EventHandlerImplementation::HandleDisconnect( |
| 1130 ClientSocket* client_socket, | 1164 ClientSocket* client_socket, |
| 1131 int bytes, | 1165 int bytes, |
| 1132 OverlappedBuffer* buffer) { | 1166 OverlappedBuffer* buffer) { |
| 1133 client_socket->DisconnectComplete(buffer); | 1167 client_socket->DisconnectComplete(buffer); |
| 1168 DeleteIfClosed(client_socket); |
| 1134 } | 1169 } |
| 1135 | 1170 |
| 1171 |
| 1172 void EventHandlerImplementation::HandleConnect( |
| 1173 ClientSocket* client_socket, |
| 1174 int bytes, |
| 1175 OverlappedBuffer* buffer) { |
| 1176 if (bytes < 0) { |
| 1177 HandleError(client_socket); |
| 1178 OverlappedBuffer::DisposeBuffer(buffer); |
| 1179 } else { |
| 1180 client_socket->ConnectComplete(buffer); |
| 1181 } |
| 1182 } |
| 1183 |
| 1184 |
| 1136 void EventHandlerImplementation::HandleTimeout() { | 1185 void EventHandlerImplementation::HandleTimeout() { |
| 1137 if (!timeout_queue_.HasTimeout()) return; | 1186 if (!timeout_queue_.HasTimeout()) return; |
| 1138 DartUtils::PostNull(timeout_queue_.CurrentPort()); | 1187 DartUtils::PostNull(timeout_queue_.CurrentPort()); |
| 1139 timeout_queue_.RemoveCurrent(); | 1188 timeout_queue_.RemoveCurrent(); |
| 1140 } | 1189 } |
| 1141 | 1190 |
| 1142 | 1191 |
| 1143 void EventHandlerImplementation::HandleIOCompletion(DWORD bytes, | 1192 void EventHandlerImplementation::HandleIOCompletion(DWORD bytes, |
| 1144 ULONG_PTR key, | 1193 ULONG_PTR key, |
| 1145 OVERLAPPED* overlapped) { | 1194 OVERLAPPED* overlapped) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1164 case OverlappedBuffer::kSendTo: { | 1213 case OverlappedBuffer::kSendTo: { |
| 1165 Handle* handle = reinterpret_cast<Handle*>(key); | 1214 Handle* handle = reinterpret_cast<Handle*>(key); |
| 1166 HandleWrite(handle, bytes, buffer); | 1215 HandleWrite(handle, bytes, buffer); |
| 1167 break; | 1216 break; |
| 1168 } | 1217 } |
| 1169 case OverlappedBuffer::kDisconnect: { | 1218 case OverlappedBuffer::kDisconnect: { |
| 1170 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(key); | 1219 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(key); |
| 1171 HandleDisconnect(client_socket, bytes, buffer); | 1220 HandleDisconnect(client_socket, bytes, buffer); |
| 1172 break; | 1221 break; |
| 1173 } | 1222 } |
| 1223 case OverlappedBuffer::kConnect: { |
| 1224 ClientSocket* client_socket = reinterpret_cast<ClientSocket*>(key); |
| 1225 HandleConnect(client_socket, bytes, buffer); |
| 1226 break; |
| 1227 } |
| 1174 default: | 1228 default: |
| 1175 UNREACHABLE(); | 1229 UNREACHABLE(); |
| 1176 } | 1230 } |
| 1177 } | 1231 } |
| 1178 | 1232 |
| 1179 | 1233 |
| 1180 EventHandlerImplementation::EventHandlerImplementation() { | 1234 EventHandlerImplementation::EventHandlerImplementation() { |
| 1181 intptr_t result; | 1235 intptr_t result; |
| 1182 completion_port_ = | 1236 completion_port_ = |
| 1183 CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 1); | 1237 CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 1); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1289 | 1343 |
| 1290 | 1344 |
| 1291 void EventHandlerImplementation::Shutdown() { | 1345 void EventHandlerImplementation::Shutdown() { |
| 1292 SendData(kShutdownId, 0, 0); | 1346 SendData(kShutdownId, 0, 0); |
| 1293 } | 1347 } |
| 1294 | 1348 |
| 1295 } // namespace bin | 1349 } // namespace bin |
| 1296 } // namespace dart | 1350 } // namespace dart |
| 1297 | 1351 |
| 1298 #endif // defined(TARGET_OS_WINDOWS) | 1352 #endif // defined(TARGET_OS_WINDOWS) |
| OLD | NEW |