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

Unified Diff: runtime/bin/sync_socket_win.cc

Issue 2803543006: Added synchronous socket implementation to dart:io. (Closed)
Patch Set: Small fix for MacOS Created 3 years, 8 months 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
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)

Powered by Google App Engine
This is Rietveld 408576698