Index: runtime/bin/sync_socket_win.cc |
diff --git a/runtime/bin/sync_socket_win.cc b/runtime/bin/sync_socket_win.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..20a992165235976837451e593259e45e5b88b29b |
--- /dev/null |
+++ b/runtime/bin/sync_socket_win.cc |
@@ -0,0 +1,149 @@ |
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
zra
2017/04/07 16:29:41
2017
bkonyi
2017/04/10 19:20:06
Done.
|
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+#if !defined(DART_IO_DISABLED) |
+ |
+#include "platform/globals.h" |
+#if defined(HOST_OS_WINDOWS) |
+ |
+#include "bin/builtin.h" |
+#include "bin/eventhandler.h" |
+#include "bin/file.h" |
+#include "bin/lockers.h" |
+#include "bin/log.h" |
+#include "bin/socket.h" |
+#include "bin/socket_base_win.h" |
+#include "bin/thread.h" |
+#include "bin/utils.h" |
+#include "bin/utils_win.h" |
+ |
+namespace dart { |
+namespace bin { |
+ |
+SynchronousSocket::SynchronousSocket(intptr_t fd) |
+ : ReferenceCounted(), fd_(fd), port_(ILLEGAL_PORT) { |
+ ASSERT(fd_ != kClosedFd); |
+ Handle* handle = reinterpret_cast<Handle*>(fd_); |
+ ASSERT(handle != NULL); |
+} |
+ |
+ |
+void SynchronousSocket::SetClosedFd() { |
+ ASSERT(fd_ != kClosedFd); |
+ Handle* handle = reinterpret_cast<Handle*>(fd_); |
+ ASSERT(handle != NULL); |
+ handle->Release(); |
+ fd_ = kClosedFd; |
+} |
+ |
+ |
+static intptr_t Create(const RawAddr& addr) { |
+ SOCKET s = socket(addr.ss.ss_family, SOCK_STREAM, 0); |
+ if (s == INVALID_SOCKET) { |
+ return -1; |
+ } |
+ |
+ linger l; |
+ l.l_onoff = 1; |
+ l.l_linger = 10; |
+ int status = setsockopt(s, SOL_SOCKET, SO_LINGER, reinterpret_cast<char*>(&l), |
+ sizeof(l)); |
+ if (status != NO_ERROR) { |
+ FATAL("Failed setting SO_LINGER on socket"); |
+ } |
+ |
+ ClientSocket* client_socket = new ClientSocket(s, true); |
+ return reinterpret_cast<intptr_t>(client_socket); |
+} |
+ |
+ |
+static intptr_t Connect(intptr_t fd, |
+ const RawAddr& addr, |
+ const RawAddr& bind_addr) { |
+ ASSERT(reinterpret_cast<Handle*>(fd)->is_client_socket()); |
+ ClientSocket* handle = reinterpret_cast<ClientSocket*>(fd); |
+ SOCKET s = handle->socket(); |
+ |
+ int status = |
+ bind(s, &bind_addr.addr, SocketAddress::GetAddrLength(bind_addr)); |
+ if (status != NO_ERROR) { |
+ int rc = WSAGetLastError(); |
+ handle->mark_closed(); // Destructor asserts that socket is marked closed. |
+ handle->Release(); |
+ closesocket(s); |
+ SetLastError(rc); |
+ return -1; |
+ } |
+ |
+ LPFN_CONNECTEX connectEx = NULL; |
+ GUID guid_connect_ex = WSAID_CONNECTEX; |
+ DWORD bytes; |
+ status = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid_connect_ex, |
+ sizeof(guid_connect_ex), &connectEx, sizeof(connectEx), |
+ &bytes, NULL, NULL); |
+ DWORD rc; |
+ if (status != SOCKET_ERROR) { |
+ handle->EnsureInitialized(EventHandler::delegate()); |
+ |
+ OverlappedBuffer* overlapped = OverlappedBuffer::AllocateConnectBuffer(); |
+ |
+ status = connectEx(s, &addr.addr, SocketAddress::GetAddrLength(addr), NULL, |
+ 0, NULL, overlapped->GetCleanOverlapped()); |
+ |
+ |
+ if (status == TRUE) { |
+ handle->ConnectComplete(overlapped); |
+ return fd; |
+ } else if (WSAGetLastError() == ERROR_IO_PENDING) { |
+ return fd; |
+ } |
+ rc = WSAGetLastError(); |
+ // Cleanup in case of error. |
+ OverlappedBuffer::DisposeBuffer(overlapped); |
+ handle->Release(); |
+ } else { |
+ rc = WSAGetLastError(); |
+ } |
+ handle->Close(); |
+ handle->Release(); |
+ SetLastError(rc); |
+ return -1; |
+} |
+ |
+ |
+intptr_t SynchronousSocket::CreateConnect(const RawAddr& addr) { |
+ intptr_t fd = Create(addr); |
+ if (fd < 0) { |
+ return fd; |
+ } |
+ |
+ RawAddr bind_addr; |
+ memset(&bind_addr, 0, sizeof(bind_addr)); |
+ bind_addr.ss.ss_family = addr.ss.ss_family; |
+ if (addr.ss.ss_family == AF_INET) { |
+ bind_addr.in.sin_addr.s_addr = INADDR_ANY; |
+ } else { |
+ bind_addr.in6.sin6_addr = in6addr_any; |
+ } |
+ |
+ return Connect(fd, addr, bind_addr); |
+} |
+ |
+ |
+intptr_t SynchronousSocket::CreateBindConnect(const RawAddr& addr, |
+ const RawAddr& source_addr) { |
+ intptr_t fd = Create(addr); |
+ if (fd < 0) { |
+ return fd; |
+ } |
+ |
+ return Connect(fd, addr, source_addr); |
+} |
+ |
+} // namespace bin |
+} // namespace dart |
+ |
+#endif // defined(HOST_OS_WINDOWS) |
+ |
+#endif // !defined(DART_IO_DISABLED) |