Chromium Code Reviews| 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 patch class RawServerSocket { | 5 patch class RawServerSocket { |
| 6 /* patch */ static Future<RawServerSocket> bind(address, | 6 /* patch */ static Future<RawServerSocket> bind(address, |
| 7 int port, | 7 int port, |
| 8 {int backlog: 0, | 8 {int backlog: 0, |
| 9 bool v6Only: false}) { | 9 bool v6Only: false}) { |
| 10 return _RawServerSocket.bind(address, port, backlog, v6Only); | 10 return _RawServerSocket.bind(address, port, backlog, v6Only); |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 204 String toString() { | 204 String toString() { |
| 205 return "NetworkInterface('$name', $addresses)"; | 205 return "NetworkInterface('$name', $addresses)"; |
| 206 } | 206 } |
| 207 } | 207 } |
| 208 | 208 |
| 209 | 209 |
| 210 // The NativeFieldWrapperClass1 can not be used with a mixin, due to missing | 210 // The NativeFieldWrapperClass1 can not be used with a mixin, due to missing |
| 211 // implicit constructor. | 211 // implicit constructor. |
| 212 class _NativeSocketNativeWrapper extends NativeFieldWrapperClass1 {} | 212 class _NativeSocketNativeWrapper extends NativeFieldWrapperClass1 {} |
| 213 | 213 |
| 214 class _ConnectingSocket { | |
| 215 final _NativeSocket socket; | |
| 216 final Timer timer; | |
| 217 | |
| 218 _ConnectingSocket(this.socket, this.timer); | |
| 219 | |
| 220 void abort() { | |
| 221 timer.cancel(); | |
| 222 socket.close(); | |
| 223 socket.setHandlers(); | |
| 224 socket.setListening(read: false, write: false); | |
| 225 } | |
| 226 } | |
| 227 | |
| 214 | 228 |
| 215 // The _NativeSocket class encapsulates an OS socket. | 229 // The _NativeSocket class encapsulates an OS socket. |
| 216 class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { | 230 class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject { |
| 217 // Bit flags used when communicating between the eventhandler and | 231 // Bit flags used when communicating between the eventhandler and |
| 218 // dart code. The EVENT flags are used to indicate events of | 232 // dart code. The EVENT flags are used to indicate events of |
| 219 // interest when sending a message from dart code to the | 233 // interest when sending a message from dart code to the |
| 220 // eventhandler. When receiving a message from the eventhandler the | 234 // eventhandler. When receiving a message from the eventhandler the |
| 221 // EVENT flags indicate the events that actually happened. The | 235 // EVENT flags indicate the events that actually happened. The |
| 222 // COMMAND flags are used to send commands from dart to the | 236 // COMMAND flags are used to send commands from dart to the |
| 223 // eventhandler. COMMAND flags are never received from the | 237 // eventhandler. COMMAND flags are never received from the |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 266 static const LIST_INTERFACES = 1; | 280 static const LIST_INTERFACES = 1; |
| 267 static const REVERSE_LOOKUP = 2; | 281 static const REVERSE_LOOKUP = 2; |
| 268 | 282 |
| 269 // Protocol flags. | 283 // Protocol flags. |
| 270 static const int PROTOCOL_IPV4 = 1 << 0; | 284 static const int PROTOCOL_IPV4 = 1 << 0; |
| 271 static const int PROTOCOL_IPV6 = 1 << 1; | 285 static const int PROTOCOL_IPV6 = 1 << 1; |
| 272 | 286 |
| 273 static const int NORMAL_TOKEN_BATCH_SIZE = 8; | 287 static const int NORMAL_TOKEN_BATCH_SIZE = 8; |
| 274 static const int LISTENING_TOKEN_BATCH_SIZE = 2; | 288 static const int LISTENING_TOKEN_BATCH_SIZE = 2; |
| 275 | 289 |
| 290 static const Duration _RETRY_DURATION = const Duration(milliseconds: 250); | |
| 291 static const Duration _RETRY_DURATION_LOOPBACK = | |
| 292 const Duration(milliseconds: 25); | |
| 293 | |
| 276 // Use default Map so we keep order. | 294 // Use default Map so we keep order. |
| 277 static Map<int, _NativeSocket> _sockets = new Map<int, _NativeSocket>(); | 295 static Map<int, _NativeSocket> _sockets = new Map<int, _NativeSocket>(); |
| 278 | 296 |
| 279 // Socket close state | 297 // Socket close state |
| 280 bool isClosed = false; | 298 bool isClosed = false; |
| 281 bool isClosing = false; | 299 bool isClosing = false; |
| 282 bool isClosedRead = false; | 300 bool isClosedRead = false; |
| 283 bool isClosedWrite = false; | 301 bool isClosedWrite = false; |
| 284 Completer closeCompleter = new Completer.sync(); | 302 Completer closeCompleter = new Completer.sync(); |
| 285 | 303 |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 375 } | 393 } |
| 376 }); | 394 }); |
| 377 } | 395 } |
| 378 | 396 |
| 379 static Future<_NativeSocket> connect(host, int port) { | 397 static Future<_NativeSocket> connect(host, int port) { |
| 380 return new Future.value(host) | 398 return new Future.value(host) |
| 381 .then((host) { | 399 .then((host) { |
| 382 if (host is _InternetAddress) return [host]; | 400 if (host is _InternetAddress) return [host]; |
| 383 return lookup(host) | 401 return lookup(host) |
| 384 .then((list) { | 402 .then((list) { |
| 385 if (list.length == 0) { | 403 if (list.length == 0) { |
|
Bill Hesse
2014/07/29 10:57:06
Maybe list should be "addresses" here. Use isNotE
Anders Johnsen
2014/07/29 11:23:27
Done.
| |
| 386 throw createError(response, "Failed host lookup: '$host'"); | 404 throw createError(response, "Failed host lookup: '$host'"); |
| 387 } | 405 } |
| 388 return list; | 406 return list; |
| 389 }); | 407 }); |
| 390 }) | 408 }) |
| 391 .then((addresses) { | 409 .then((addresses) { |
| 392 assert(addresses is List); | 410 assert(addresses is List); |
| 411 assert(addresses.isNotEmpty); | |
|
Bill Hesse
2014/07/29 10:57:06
This assert is covered by the check in the above f
Anders Johnsen
2014/07/29 11:23:27
Done.
| |
| 393 var completer = new Completer(); | 412 var completer = new Completer(); |
| 394 var it = addresses.iterator; | 413 var it = addresses.iterator; |
| 395 void run(error) { | 414 var error = null; |
| 415 var connecting = new HashSet(); | |
| 416 void connectNext() { | |
| 396 if (!it.moveNext()) { | 417 if (!it.moveNext()) { |
| 397 assert(error != null); | 418 if (connecting.isEmpty) { |
| 398 completer.completeError(error); | 419 assert(error != null); |
| 420 completer.completeError(error); | |
| 421 } | |
| 399 return; | 422 return; |
| 400 } | 423 } |
| 401 var address = it.current; | 424 var address = it.current; |
| 402 var socket = new _NativeSocket.normal(); | 425 var socket = new _NativeSocket.normal(); |
| 403 socket.address = address; | 426 socket.address = address; |
| 404 var result = socket.nativeCreateConnect(address._in_addr, port); | 427 var result = socket.nativeCreateConnect(address._in_addr, port); |
| 405 if (result is OSError) { | 428 if (result is OSError) { |
| 406 // Keep first error, if present. | 429 // Keep first error, if present. |
| 407 run(error != null ? error : | 430 if (error == null) { |
| 408 createError(result, "Connection failed", address, port)); | 431 error = createError(result, "Connection failed", address, port); |
| 432 } | |
| 433 connectNext(); | |
| 409 } else { | 434 } else { |
| 410 socket.port; // Query the local port, for error messages. | 435 socket.port; // Query the local port, for error messages. |
| 436 // Set up timer for when we should retry the next address (if any) . | |
| 437 var duration = address.isLoopback ? | |
| 438 _RETRY_DURATION_LOOPBACK : | |
| 439 _RETRY_DURATION; | |
| 440 var timer = new Timer(duration, connectNext); | |
| 441 var connectingSocket = new _ConnectingSocket(socket, timer); | |
| 442 connecting.add(connectingSocket); | |
|
Bill Hesse
2014/07/29 10:57:06
If you used a Map, rather than a Set, then this wo
Anders Johnsen
2014/07/29 11:23:27
Acknowledged.
| |
| 411 // Setup handlers for receiving the first write event which | 443 // Setup handlers for receiving the first write event which |
| 412 // indicate that the socket is fully connected. | 444 // indicate that the socket is fully connected. |
| 413 socket.setHandlers( | 445 socket.setHandlers( |
| 414 write: () { | 446 write: () { |
| 447 timer.cancel(); | |
| 415 socket.setListening(read: false, write: false); | 448 socket.setListening(read: false, write: false); |
| 416 completer.complete(socket); | 449 completer.complete(socket); |
| 450 connecting.remove(connectingSocket); | |
| 451 for (var s in connecting) { | |
| 452 s.abort(); | |
| 453 } | |
| 417 }, | 454 }, |
| 418 error: (e) { | 455 error: (e) { |
| 419 socket.close(); | 456 connectingSocket.abort(); |
| 420 // Keep first error, if present. | 457 // Keep first error, if present. |
| 421 run(error != null ? error : e); | 458 if (error == null) error = e; |
| 422 } | 459 connecting.remove(connectingSocket); |
| 423 ); | 460 if (connecting.isEmpty) connectNext(); |
| 461 }); | |
| 424 socket.setListening(read: false, write: true); | 462 socket.setListening(read: false, write: true); |
| 425 } | 463 } |
| 426 } | 464 } |
| 427 run(null); | 465 connectNext(); |
| 428 return completer.future; | 466 return completer.future; |
| 429 }); | 467 }); |
| 430 } | 468 } |
| 431 | 469 |
| 432 static Future<_NativeSocket> bind(host, | 470 static Future<_NativeSocket> bind(host, |
| 433 int port, | 471 int port, |
| 434 int backlog, | 472 int backlog, |
| 435 bool v6Only) { | 473 bool v6Only) { |
| 436 return new Future.value(host) | 474 return new Future.value(host) |
| 437 .then((host) { | 475 .then((host) { |
| (...skipping 1464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1902 String address, | 1940 String address, |
| 1903 List<int> in_addr, | 1941 List<int> in_addr, |
| 1904 int port) { | 1942 int port) { |
| 1905 return new Datagram( | 1943 return new Datagram( |
| 1906 data, | 1944 data, |
| 1907 new _InternetAddress(address, null, in_addr), | 1945 new _InternetAddress(address, null, in_addr), |
| 1908 port); | 1946 port); |
| 1909 } | 1947 } |
| 1910 | 1948 |
| 1911 String _socketsStats() => _SocketsObservatory.toJSON(); | 1949 String _socketsStats() => _SocketsObservatory.toJSON(); |
| OLD | NEW |