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

Side by Side Diff: runtime/bin/sync_socket_patch.dart

Issue 2803543006: Added synchronous socket implementation to dart:io. (Closed)
Patch Set: Addressed first round of comments 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) 2017, the Dart project authors. Please see the AUTHORS file
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 @patch
6 class RawSynchronousSocket {
7 @patch
8 static RawSynchronousSocket connectSync(host, int port) {
9 return _RawSynchronousSocket.connectSync(host, port);
10 }
11 }
12
13 class _RawSynchronousSocket implements RawSynchronousSocket {
14 final _NativeSynchronousSocket _socket;
15
16 _RawSynchronousSocket(this._socket) {}
zra 2017/04/10 21:39:43 {} not needed.
bkonyi 2017/04/11 01:30:51 Done.
17
18 static RawSynchronousSocket connectSync(host, int port) {
19 _throwOnBadPort(port);
20 return new _RawSynchronousSocket(
21 _NativeSynchronousSocket.connectSync(host, port));
22 }
23
24 InternetAddress get address => _socket.address;
25 int get port => _socket.port;
26 InternetAddress get remoteAddress => _socket.remoteAddress;
27 int get remotePort => _socket.remotePort;
28
29 int available() => _socket.available;
30
31 void closeSync() => _socket.closeSync();
32
33 int readIntoSync(List<int> buffer, [int start = 0, int end]) =>
34 _socket.readIntoSync(buffer, start, end);
35
36 List<int> readSync(int bytes) => _socket.readSync(bytes);
37
38 void shutdown(SocketDirection direction) => _socket.shutdown(direction);
39
40 void writeFromSync(List<int> buffer, [int start = 0, int end]) =>
41 _socket.writeFromSync(buffer, start, end);
42 }
43
44 // The NativeFieldWrapperClass1 can not be used with a mixin, due to missing
45 // implicit constructor.
46 class _NativeSynchronousSocketNativeWrapper extends NativeFieldWrapperClass1 {}
47
48 // The _NativeSynchronousSocket class encapsulates a synchronous OS socket.
49 class _NativeSynchronousSocket extends _NativeSynchronousSocketNativeWrapper {
50 // Socket close state.
51 bool isClosed = false;
52 bool isClosedRead = false;
53 bool isClosedWrite = false;
54
55 // Holds the address used to connect the socket.
56 InternetAddress localAddress;
57
58 // Holds the port of the socket, 0 if not known.
59 int localPort = 0;
60
61 _ReadWriteResourceInfo resourceInfo;
62
63 static _NativeSynchronousSocket connectSync(host, int port) {
64 List<_InternetAddress> addresses = null;
65 var error = null;
66 if (host is _InternetAddress) {
67 addresses = [host];
68 } else {
69 try {
70 addresses = lookup(host);
71 } catch (e) {
72 error = e;
73 }
74 if (error != null || addresses == null || addresses.isEmpty) {
75 throw createError(error, "Failed host lookup: '$host'");
76 }
77 }
78 assert(addresses is List);
79 var it = addresses.iterator;
80 _NativeSynchronousSocket connectNext() {
81 if (!it.moveNext()) {
82 // Could not connect. Throw the first connection error we encountered.
83 assert(error != null);
84 throw error;
85 }
86 var address = it.current;
87 var socket = new _NativeSynchronousSocket();
88 socket.localAddress = address;
89 var result = socket.nativeCreateConnectSync(address._in_addr, port);
90 if (result is OSError) {
91 // Keep first error, if present.
92 if (error == null) {
93 error = createError(result, "Connection failed", address, port);
94 }
95 return connectNext();
96 } else {
97 // Query the local port, for error messages.
98 try {
99 socket.port;
100 } catch (e) {
101 if (error == null) {
102 error = createError(e, "Connection failed", address, port);
103 }
104 return connectNext();
105 }
106 setupResourceInfo(socket);
107 }
108 return socket;
109 }
110
111 return connectNext();
112 }
113
114 InternetAddress get address => localAddress;
115 int get available => nativeAvailable();
116
117 int get port {
118 if (localPort != 0) {
119 return localPort;
120 }
121 if (isClosed) {
122 throw const SocketException.closed();
123 }
124 var result = nativeGetPort();
125 if (result is OSError) {
126 throw result;
127 }
128 return localPort = result;
129 }
130
131 InternetAddress get remoteAddress {
132 if (isClosed) {
133 throw const SocketException.closed();
134 }
135 var result = nativeGetRemotePeer();
136 if (result is OSError) {
137 throw result;
138 }
139 var addr = result[0];
140 var type = new InternetAddressType._from(addr[0]);
zra 2017/04/10 21:39:43 type is unused.
bkonyi 2017/04/11 01:30:51 Done.
141 return new _InternetAddress(addr[1], null, addr[2]);
142 }
143
144 int get remotePort {
145 if (isClosed) {
146 throw const SocketException.closed();
147 }
148 var result = nativeGetRemotePeer();
149 if (result is OSError) {
150 throw result;
151 }
152 return result[1];
153 }
154
155 void closeSync() {
156 if (!isClosed) {
157 nativeCloseSync();
158 _SocketResourceInfo.SocketClosed(resourceInfo);
159 isClosed = true;
160 }
161 }
162
163 // Create the appropriate error/exception from different returned
164 // error objects.
165 static createError(error, String message,
166 [InternetAddress address, int port]) {
167 if (error is OSError) {
168 return new SocketException(message,
169 osError: error, address: address, port: port);
170 } else {
171 return new SocketException(message, address: address, port: port);
172 }
173 }
174
175 static List<InternetAddress> lookup(String host,
176 {InternetAddressType type: InternetAddressType.ANY}) {
177 var response = nativeLookupRequest(host, type._value);
178 if (response is OSError) {
179 throw response;
180 }
181 return response.map((result) {
zra 2017/04/10 21:39:43 A for-loop that adds elements to a preallocated li
bkonyi 2017/04/11 01:30:51 Done.
182 var type = new InternetAddressType._from(result[0]);
zra 2017/04/10 21:39:43 type is unused.
bkonyi 2017/04/11 01:30:51 Done.
183 return new _InternetAddress(result[1], host, result[2]);
184 }).toList();
185 }
186
187 int readIntoSync(List<int> buffer, int start, int end) {
188 _checkAvailable();
189 if (isClosedRead) {
190 throw new SocketException("Socket is closed for reading");
191 }
192
193 if ((buffer is! List) ||
194 ((start != null) && (start is! int)) ||
195 ((end != null) && (end is! int))) {
196 throw new ArgumentError("Invalid arguments to readIntoSync");
197 }
198 if (start == null) {
199 throw new ArgumentError("start cannot be equal to null");
zra 2017/04/10 21:39:43 strike "equal to"
bkonyi 2017/04/11 01:30:51 Done.
200 }
201 end = RangeError.checkValidRange(start, end, buffer.length);
202 if (end == start) {
203 return 0;
204 }
205 var result = nativeReadInto(buffer, start, (end - start));
206 if (result is OSError) {
207 throw new SocketException("readIntoSync failed", osError: result);
208 }
209 resourceInfo.addRead(result);
210 return result;
211 }
212
213 List<int> readSync(int len) {
214 _checkAvailable();
215 if (isClosedRead) {
216 throw new SocketException("Socket is closed for reading");
217 }
218
219 if (len != null && len < 0) {
zra 2017/04/10 21:39:43 Please put () around clauses.
bkonyi 2017/04/11 01:30:51 Done.
220 throw new ArgumentError("Illegal length $len");
221 }
222 if (len == 0) {
223 return null;
224 }
225 var result = nativeRead(len);
226 if (result is OSError) {
227 throw result;
228 return null;
zra 2017/04/10 21:39:43 this statement is unreachable.
bkonyi 2017/04/11 01:30:51 Done.
229 }
230 assert(resourceInfo != null);
231 if (result != null) {
232 if (resourceInfo != null) {
233 resourceInfo.totalRead += result.length;
234 }
235 }
236 if (resourceInfo != null) {
237 resourceInfo.didRead();
238 }
239 return result;
240 }
241
242 static void setupResourceInfo(_NativeSynchronousSocket socket) {
243 socket.resourceInfo = new _SocketResourceInfo(socket);
244 }
245
246 void shutdown(SocketDirection direction) {
247 if (isClosed) {
248 return;
249 }
250 switch (direction) {
251 case SocketDirection.RECEIVE:
252 shutdownRead();
253 break;
254 case SocketDirection.SEND:
255 shutdownWrite();
256 break;
257 case SocketDirection.BOTH:
258 closeSync();
259 break;
260 default:
261 throw new ArgumentError(direction);
262 }
263 }
264
265 void shutdownRead() {
266 if (isClosed || isClosedRead) {
267 return;
268 }
269 if (isClosedWrite) {
270 closeSync();
271 } else {
272 nativeShutdownRead();
273 }
274 isClosedRead = true;
275 }
276
277 void shutdownWrite() {
278 if (isClosed || isClosedWrite) {
279 return;
280 }
281 if (isClosedRead) {
282 closeSync();
283 } else {
284 nativeShutdownWrite();
285 }
286 isClosedWrite = true;
287 }
288
289 void writeFromSync(List<int> buffer, int start, int end) {
290 _checkAvailable();
291 if (isClosedWrite) {
292 throw new SocketException("Socket is closed for writing");
293 }
294 if ((buffer is! List) ||
295 ((start != null) && (start is! int)) ||
296 ((end != null) && (end is! int))) {
297 throw new ArgumentError("Invalid arguments to writeFromSync");
298 }
299 if (start == null) {
300 throw new ArgumentError("start cannot be equal to null");
301 }
302
303 end = RangeError.checkValidRange(start, end, buffer.length);
304 if (end == start) {
305 return;
306 }
307
308 _BufferAndStart bufferAndStart =
309 _ensureFastAndSerializableByteData(buffer, start, end);
310 var result = nativeWrite(bufferAndStart.buffer, bufferAndStart.start,
311 end - (start - bufferAndStart.start));
312 if (result is OSError) {
313 throw new SocketException("writeFromSync failed", osError: result);
314 }
315 assert(resourceInfo != null);
316 if (resourceInfo != null) {
317 resourceInfo.addWrite(result);
318 }
319 }
320
321 void _checkAvailable() {
322 if (isClosed) {
323 throw const SocketException.closed();
324 }
325 }
326
327 // Native method declarations.
328 static nativeLookupRequest(host, int type)
329 native "SynchronousSocket_LookupRequest";
330 nativeCreateConnectSync(host, int port)
331 native "SynchronousSocket_CreateConnectSync";
332 nativeAvailable() native "SynchronousSocket_Available";
333 nativeCloseSync() native "SynchronousSocket_CloseSync";
334 int nativeGetPort() native "SynchronousSocket_GetPort";
335 List nativeGetRemotePeer() native "SynchronousSocket_GetRemotePeer";
336 nativeRead(int len) native "SynchronousSocket_Read";
337 nativeReadInto(List<int> buffer, int offset, int bytes)
338 native "SynchronousSocket_ReadList";
339 nativeShutdownRead() native "SynchronousSocket_ShutdownRead";
340 nativeShutdownWrite() native "SynchronousSocket_ShutdownWrite";
341 nativeWrite(List<int> buffer, int offset, int bytes)
342 native "SynchronousSocket_WriteList";
343 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698