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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // 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.
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.
4
5 #if !defined(DART_IO_DISABLED)
6
7 #include "platform/globals.h"
8 #if defined(HOST_OS_WINDOWS)
9
10 #include "bin/builtin.h"
11 #include "bin/eventhandler.h"
12 #include "bin/file.h"
13 #include "bin/lockers.h"
14 #include "bin/log.h"
15 #include "bin/socket.h"
16 #include "bin/socket_base_win.h"
17 #include "bin/thread.h"
18 #include "bin/utils.h"
19 #include "bin/utils_win.h"
20
21 namespace dart {
22 namespace bin {
23
24 SynchronousSocket::SynchronousSocket(intptr_t fd)
25 : ReferenceCounted(), fd_(fd), port_(ILLEGAL_PORT) {
26 ASSERT(fd_ != kClosedFd);
27 Handle* handle = reinterpret_cast<Handle*>(fd_);
28 ASSERT(handle != NULL);
29 }
30
31
32 void SynchronousSocket::SetClosedFd() {
33 ASSERT(fd_ != kClosedFd);
34 Handle* handle = reinterpret_cast<Handle*>(fd_);
35 ASSERT(handle != NULL);
36 handle->Release();
37 fd_ = kClosedFd;
38 }
39
40
41 static intptr_t Create(const RawAddr& addr) {
42 SOCKET s = socket(addr.ss.ss_family, SOCK_STREAM, 0);
43 if (s == INVALID_SOCKET) {
44 return -1;
45 }
46
47 linger l;
48 l.l_onoff = 1;
49 l.l_linger = 10;
50 int status = setsockopt(s, SOL_SOCKET, SO_LINGER, reinterpret_cast<char*>(&l),
51 sizeof(l));
52 if (status != NO_ERROR) {
53 FATAL("Failed setting SO_LINGER on socket");
54 }
55
56 ClientSocket* client_socket = new ClientSocket(s, true);
57 return reinterpret_cast<intptr_t>(client_socket);
58 }
59
60
61 static intptr_t Connect(intptr_t fd,
62 const RawAddr& addr,
63 const RawAddr& bind_addr) {
64 ASSERT(reinterpret_cast<Handle*>(fd)->is_client_socket());
65 ClientSocket* handle = reinterpret_cast<ClientSocket*>(fd);
66 SOCKET s = handle->socket();
67
68 int status =
69 bind(s, &bind_addr.addr, SocketAddress::GetAddrLength(bind_addr));
70 if (status != NO_ERROR) {
71 int rc = WSAGetLastError();
72 handle->mark_closed(); // Destructor asserts that socket is marked closed.
73 handle->Release();
74 closesocket(s);
75 SetLastError(rc);
76 return -1;
77 }
78
79 LPFN_CONNECTEX connectEx = NULL;
80 GUID guid_connect_ex = WSAID_CONNECTEX;
81 DWORD bytes;
82 status = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid_connect_ex,
83 sizeof(guid_connect_ex), &connectEx, sizeof(connectEx),
84 &bytes, NULL, NULL);
85 DWORD rc;
86 if (status != SOCKET_ERROR) {
87 handle->EnsureInitialized(EventHandler::delegate());
88
89 OverlappedBuffer* overlapped = OverlappedBuffer::AllocateConnectBuffer();
90
91 status = connectEx(s, &addr.addr, SocketAddress::GetAddrLength(addr), NULL,
92 0, NULL, overlapped->GetCleanOverlapped());
93
94
95 if (status == TRUE) {
96 handle->ConnectComplete(overlapped);
97 return fd;
98 } else if (WSAGetLastError() == ERROR_IO_PENDING) {
99 return fd;
100 }
101 rc = WSAGetLastError();
102 // Cleanup in case of error.
103 OverlappedBuffer::DisposeBuffer(overlapped);
104 handle->Release();
105 } else {
106 rc = WSAGetLastError();
107 }
108 handle->Close();
109 handle->Release();
110 SetLastError(rc);
111 return -1;
112 }
113
114
115 intptr_t SynchronousSocket::CreateConnect(const RawAddr& addr) {
116 intptr_t fd = Create(addr);
117 if (fd < 0) {
118 return fd;
119 }
120
121 RawAddr bind_addr;
122 memset(&bind_addr, 0, sizeof(bind_addr));
123 bind_addr.ss.ss_family = addr.ss.ss_family;
124 if (addr.ss.ss_family == AF_INET) {
125 bind_addr.in.sin_addr.s_addr = INADDR_ANY;
126 } else {
127 bind_addr.in6.sin6_addr = in6addr_any;
128 }
129
130 return Connect(fd, addr, bind_addr);
131 }
132
133
134 intptr_t SynchronousSocket::CreateBindConnect(const RawAddr& addr,
135 const RawAddr& source_addr) {
136 intptr_t fd = Create(addr);
137 if (fd < 0) {
138 return fd;
139 }
140
141 return Connect(fd, addr, source_addr);
142 }
143
144 } // namespace bin
145 } // namespace dart
146
147 #endif // defined(HOST_OS_WINDOWS)
148
149 #endif // !defined(DART_IO_DISABLED)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698