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 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 198 final List<InternetAddress> addresses = []; | 198 final List<InternetAddress> addresses = []; |
| 199 | 199 |
| 200 _NetworkInterface(this.name, this.index); | 200 _NetworkInterface(this.name, this.index); |
| 201 | 201 |
| 202 String toString() { | 202 String toString() { |
| 203 return "NetworkInterface('$name', $addresses)"; | 203 return "NetworkInterface('$name', $addresses)"; |
| 204 } | 204 } |
| 205 } | 205 } |
| 206 | 206 |
| 207 | 207 |
| 208 // Statics information for the observatory. | |
| 209 class _SocketsObservatory { | |
| 210 static int socketCount = 0; | |
| 211 static Set sockets = new Set(); | |
| 212 | |
| 213 static add(_NativeSocket socket) { | |
| 214 sockets.add(socket); | |
| 215 socketCount++; | |
| 216 } | |
| 217 | |
| 218 static remove(_NativeSicket socket) { | |
| 219 sockets.remove(socket); | |
| 220 socketCount--; | |
| 221 } | |
| 222 | |
| 223 static String toJSON() { | |
| 224 var sb = new StringBuffer(); | |
| 225 sb.write('{"type":"io","sockets":['); | |
| 226 sockets.forEach((s) { | |
|
Cutch
2014/02/13 22:42:09
You probably should use the dart:convert library i
Søren Gjesse
2014/02/14 12:10:13
Absolutely - this was just a first hack.
| |
| 227 var type = s.typeFlags == _NativeSocket.TYPE_LISTENING_SOCKET ? "LISTENING " : "NORMAL"; | |
| 228 var localAddress; | |
| 229 var localPort; | |
| 230 var remoteAddress; | |
| 231 var remotePort; | |
| 232 try { | |
| 233 localAddress = s.address.address; | |
| 234 } catch (e) { | |
| 235 localAddress = "UNKNOWN"; | |
| 236 } | |
| 237 try { | |
| 238 localPort = s.port; | |
| 239 } catch (e) { | |
| 240 localPort = "UNKNOWN"; | |
| 241 } | |
| 242 try { | |
| 243 remoteAddress = s.remoteAddress.address; | |
| 244 } catch (e) { | |
| 245 remoteAddress = "UNKNOWN"; | |
| 246 } | |
| 247 try { | |
| 248 remotePort = s.remotePort; | |
| 249 } catch (e) { | |
| 250 remotePort = "UNKNOWN"; | |
| 251 } | |
| 252 sb.write('{"type","$type"},'); | |
| 253 sb.write('{"localHost","$localAddress"},'); | |
| 254 sb.write('{"localPort","$localPort"},'); | |
| 255 sb.write('{"remoteAddress","$remoteAddress"},'); | |
| 256 sb.write('{"remotePort","$remotePort"},'); | |
| 257 sb.write('{"bytesRead","${s.bytesRead}"},'); | |
| 258 sb.write('{"bytesWritten","${s.bytesWritten}"},'); | |
|
Cutch
2014/02/13 22:42:09
What about rates over the last second, 5 seconds,
Søren Gjesse
2014/02/14 12:10:13
Added rate calculation using a timer. We might hav
| |
| 259 }); | |
| 260 sb.write(']}'); | |
| 261 return sb.toString(); | |
| 262 } | |
| 263 } | |
| 264 | |
| 265 | |
| 208 // The _NativeSocket class encapsulates an OS socket. | 266 // The _NativeSocket class encapsulates an OS socket. |
| 209 class _NativeSocket extends NativeFieldWrapperClass1 { | 267 class _NativeSocket extends NativeFieldWrapperClass1 { |
| 210 // Bit flags used when communicating between the eventhandler and | 268 // Bit flags used when communicating between the eventhandler and |
| 211 // dart code. The EVENT flags are used to indicate events of | 269 // dart code. The EVENT flags are used to indicate events of |
| 212 // interest when sending a message from dart code to the | 270 // interest when sending a message from dart code to the |
| 213 // eventhandler. When receiving a message from the eventhandler the | 271 // eventhandler. When receiving a message from the eventhandler the |
| 214 // EVENT flags indicate the events that actually happened. The | 272 // EVENT flags indicate the events that actually happened. The |
| 215 // COMMAND flags are used to send commands from dart to the | 273 // COMMAND flags are used to send commands from dart to the |
| 216 // eventhandler. COMMAND flags are never received from the | 274 // eventhandler. COMMAND flags are never received from the |
| 217 // eventhandler. Additional flags are used to communicate other | 275 // eventhandler. Additional flags are used to communicate other |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 265 | 323 |
| 266 // The type flags for this socket. | 324 // The type flags for this socket. |
| 267 final int typeFlags; | 325 final int typeFlags; |
| 268 | 326 |
| 269 // Holds the port of the socket, 0 if not known. | 327 // Holds the port of the socket, 0 if not known. |
| 270 int localPort = 0; | 328 int localPort = 0; |
| 271 | 329 |
| 272 // Holds the address used to connect or bind the socket. | 330 // Holds the address used to connect or bind the socket. |
| 273 InternetAddress address; | 331 InternetAddress address; |
| 274 | 332 |
| 333 // Statistics. | |
| 334 int bytesRead = 0; | |
| 335 int bytesWritten = 0; | |
| 336 | |
| 275 static Future<List<InternetAddress>> lookup( | 337 static Future<List<InternetAddress>> lookup( |
| 276 String host, {InternetAddressType type: InternetAddressType.ANY}) { | 338 String host, {InternetAddressType type: InternetAddressType.ANY}) { |
| 277 return _IOService.dispatch(_SOCKET_LOOKUP, [host, type._value]) | 339 return _IOService.dispatch(_SOCKET_LOOKUP, [host, type._value]) |
| 278 .then((response) { | 340 .then((response) { |
| 279 if (isErrorResponse(response)) { | 341 if (isErrorResponse(response)) { |
| 280 throw createError(response, "Failed host lookup: '$host'"); | 342 throw createError(response, "Failed host lookup: '$host'"); |
| 281 } else { | 343 } else { |
| 282 return response.skip(1).map((result) { | 344 return response.skip(1).map((result) { |
| 283 var type = new InternetAddressType._from(result[0]); | 345 var type = new InternetAddressType._from(result[0]); |
| 284 return new _InternetAddress(result[1], host, result[2]); | 346 return new _InternetAddress(result[1], host, result[2]); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 419 throw new SocketException("Failed to create datagram socket", | 481 throw new SocketException("Failed to create datagram socket", |
| 420 osError: result, | 482 osError: result, |
| 421 address: address, | 483 address: address, |
| 422 port: port); | 484 port: port); |
| 423 } | 485 } |
| 424 if (port != 0) socket.localPort = port; | 486 if (port != 0) socket.localPort = port; |
| 425 return socket; | 487 return socket; |
| 426 }); | 488 }); |
| 427 } | 489 } |
| 428 | 490 |
| 429 _NativeSocket.datagram(this.address) | 491 _NativeSocket.datagram(this.address) : typeFlags = TYPE_NORMAL_SOCKET { |
| 430 : typeFlags = TYPE_NORMAL_SOCKET { | |
| 431 eventHandlers = new List(EVENT_COUNT + 1); | 492 eventHandlers = new List(EVENT_COUNT + 1); |
| 493 _SocketsObservatory.add(this); | |
| 432 } | 494 } |
| 433 | 495 |
| 434 _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET { | 496 _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET { |
| 435 eventHandlers = new List(EVENT_COUNT + 1); | 497 eventHandlers = new List(EVENT_COUNT + 1); |
| 498 _SocketsObservatory.add(this); | |
| 436 } | 499 } |
| 437 | 500 |
| 438 _NativeSocket.listen() : typeFlags = TYPE_LISTENING_SOCKET { | 501 _NativeSocket.listen() : typeFlags = TYPE_LISTENING_SOCKET { |
| 439 eventHandlers = new List(EVENT_COUNT + 1); | 502 eventHandlers = new List(EVENT_COUNT + 1); |
| 503 _SocketsObservatory.add(this); | |
| 440 } | 504 } |
| 441 | 505 |
| 442 _NativeSocket.pipe() : typeFlags = TYPE_PIPE { | 506 _NativeSocket.pipe() : typeFlags = TYPE_PIPE { |
| 443 eventHandlers = new List(EVENT_COUNT + 1); | 507 eventHandlers = new List(EVENT_COUNT + 1); |
| 508 _SocketsObservatory.add(this); | |
| 444 } | 509 } |
| 445 | 510 |
| 446 _NativeSocket.watch(int id) : typeFlags = TYPE_NORMAL_SOCKET { | 511 _NativeSocket.watch(int id) : typeFlags = TYPE_NORMAL_SOCKET { |
| 447 eventHandlers = new List(EVENT_COUNT + 1); | 512 eventHandlers = new List(EVENT_COUNT + 1); |
| 448 isClosedWrite = true; | 513 isClosedWrite = true; |
| 449 nativeSetSocketId(id); | 514 nativeSetSocketId(id); |
| 515 _SocketsObservatory.add(this); | |
| 450 } | 516 } |
| 451 | 517 |
| 452 int available() { | 518 int available() { |
| 453 if (isClosing || isClosed) return 0; | 519 if (isClosing || isClosed) return 0; |
| 454 var result = nativeAvailable(); | 520 var result = nativeAvailable(); |
| 455 if (result is OSError) { | 521 if (result is OSError) { |
| 456 reportError(result, "Available failed"); | 522 reportError(result, "Available failed"); |
| 457 return 0; | 523 return 0; |
| 458 } else { | 524 } else { |
| 459 return result; | 525 return result; |
| 460 } | 526 } |
| 461 } | 527 } |
| 462 | 528 |
| 463 List<int> read(int len) { | 529 List<int> read(int len) { |
| 464 if (len != null && len <= 0) { | 530 if (len != null && len <= 0) { |
| 465 throw new ArgumentError("Illegal length $len"); | 531 throw new ArgumentError("Illegal length $len"); |
| 466 } | 532 } |
| 467 if (isClosing || isClosed) return null; | 533 if (isClosing || isClosed) return null; |
| 468 var result = nativeRead(len == null ? -1 : len); | 534 var result = nativeRead(len == null ? -1 : len); |
| 469 if (result is OSError) { | 535 if (result is OSError) { |
| 470 reportError(result, "Read failed"); | 536 reportError(result, "Read failed"); |
| 471 return null; | 537 return null; |
| 472 } | 538 } |
| 539 bytesRead += result.length; | |
| 473 return result; | 540 return result; |
| 474 } | 541 } |
| 475 | 542 |
| 476 Datagram receive() { | 543 Datagram receive() { |
| 477 if (isClosing || isClosed) return null; | 544 if (isClosing || isClosed) return null; |
| 478 var result = nativeRecvFrom(); | 545 var result = nativeRecvFrom(); |
| 479 if (result is OSError) { | 546 if (result is OSError) { |
| 480 reportError(result, "Receive failed"); | 547 reportError(result, "Receive failed"); |
| 481 return null; | 548 return null; |
| 482 } | 549 } |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 503 if (isClosing || isClosed) return 0; | 570 if (isClosing || isClosed) return 0; |
| 504 if (bytes == 0) return 0; | 571 if (bytes == 0) return 0; |
| 505 _BufferAndStart bufferAndStart = | 572 _BufferAndStart bufferAndStart = |
| 506 _ensureFastAndSerializableByteData(buffer, offset, offset + bytes); | 573 _ensureFastAndSerializableByteData(buffer, offset, offset + bytes); |
| 507 var result = | 574 var result = |
| 508 nativeWrite(bufferAndStart.buffer, bufferAndStart.start, bytes); | 575 nativeWrite(bufferAndStart.buffer, bufferAndStart.start, bytes); |
| 509 if (result is OSError) { | 576 if (result is OSError) { |
| 510 scheduleMicrotask(() => reportError(result, "Write failed")); | 577 scheduleMicrotask(() => reportError(result, "Write failed")); |
| 511 result = 0; | 578 result = 0; |
| 512 } | 579 } |
| 580 bytesWritten += result; | |
| 513 return result; | 581 return result; |
| 514 } | 582 } |
| 515 | 583 |
| 516 int send(List<int> buffer, int offset, int bytes, | 584 int send(List<int> buffer, int offset, int bytes, |
| 517 InternetAddress address, int port) { | 585 InternetAddress address, int port) { |
| 518 if (isClosing || isClosed) return 0; | 586 if (isClosing || isClosed) return 0; |
| 519 _BufferAndStart bufferAndStart = | 587 _BufferAndStart bufferAndStart = |
| 520 _ensureFastAndSerializableByteData( | 588 _ensureFastAndSerializableByteData( |
| 521 buffer, offset, bytes); | 589 buffer, offset, bytes); |
| 522 var result = nativeSendTo( | 590 var result = nativeSendTo( |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 567 isClosedRead = true; | 635 isClosedRead = true; |
| 568 } | 636 } |
| 569 | 637 |
| 570 var handler = eventHandlers[i]; | 638 var handler = eventHandlers[i]; |
| 571 if (i == DESTROYED_EVENT) { | 639 if (i == DESTROYED_EVENT) { |
| 572 assert(!isClosed); | 640 assert(!isClosed); |
| 573 isClosed = true; | 641 isClosed = true; |
| 574 closeCompleter.complete(); | 642 closeCompleter.complete(); |
| 575 disconnectFromEventHandler(); | 643 disconnectFromEventHandler(); |
| 576 if (handler != null) handler(); | 644 if (handler != null) handler(); |
| 645 _SocketsObservatory.remove(this); | |
| 577 continue; | 646 continue; |
| 578 } | 647 } |
| 579 assert(handler != null); | 648 assert(handler != null); |
| 580 if (i == WRITE_EVENT) { | 649 if (i == WRITE_EVENT) { |
| 581 // If the event was disabled before we had a chance to fire the event, | 650 // If the event was disabled before we had a chance to fire the event, |
| 582 // discard it. If we register again, we'll get a new one. | 651 // discard it. If we register again, we'll get a new one. |
| 583 if ((eventMask & (1 << i)) == 0) continue; | 652 if ((eventMask & (1 << i)) == 0) continue; |
| 584 // Unregister the out handler before executing it. There is | 653 // Unregister the out handler before executing it. There is |
| 585 // no need to notify the eventhandler as handlers are | 654 // no need to notify the eventhandler as handlers are |
| 586 // disabled while the event is handled. | 655 // disabled while the event is handled. |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 862 _RawServerSocket(this._socket) { | 931 _RawServerSocket(this._socket) { |
| 863 var zone = Zone.current; | 932 var zone = Zone.current; |
| 864 _controller = new StreamController(sync: true, | 933 _controller = new StreamController(sync: true, |
| 865 onListen: _onSubscriptionStateChange, | 934 onListen: _onSubscriptionStateChange, |
| 866 onCancel: _onSubscriptionStateChange, | 935 onCancel: _onSubscriptionStateChange, |
| 867 onPause: _onPauseStateChange, | 936 onPause: _onPauseStateChange, |
| 868 onResume: _onPauseStateChange); | 937 onResume: _onPauseStateChange); |
| 869 _socket.setHandlers( | 938 _socket.setHandlers( |
| 870 read: zone.bindCallback(() { | 939 read: zone.bindCallback(() { |
| 871 var socket = _socket.accept(); | 940 var socket = _socket.accept(); |
| 872 if (socket != null) _controller.add(new _RawSocket(socket)); | 941 if (socket != null) { |
| 942 _controller.add(new _RawSocket(socket)); | |
| 943 } | |
| 873 }), | 944 }), |
| 874 error: zone.bindUnaryCallback((e) { | 945 error: zone.bindUnaryCallback((e) { |
| 875 _controller.addError(e); | 946 _controller.addError(e); |
| 876 _controller.close(); | 947 _controller.close(); |
| 877 }), | 948 }), |
| 878 destroyed: _controller.close | 949 destroyed: _controller.close |
| 879 ); | 950 ); |
| 880 } | 951 } |
| 881 | 952 |
| 882 StreamSubscription<RawSocket> listen(void onData(RawSocket event), | 953 StreamSubscription<RawSocket> listen(void onData(RawSocket event), |
| (...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1551 | 1622 |
| 1552 Datagram _makeDatagram(List<int> data, | 1623 Datagram _makeDatagram(List<int> data, |
| 1553 String address, | 1624 String address, |
| 1554 List<int> in_addr, | 1625 List<int> in_addr, |
| 1555 int port) { | 1626 int port) { |
| 1556 return new Datagram( | 1627 return new Datagram( |
| 1557 data, | 1628 data, |
| 1558 new _InternetAddress(address, null, in_addr), | 1629 new _InternetAddress(address, null, in_addr), |
| 1559 port); | 1630 port); |
| 1560 } | 1631 } |
| 1632 | |
| 1633 String _test() => _SocketsObservatory.toJSON(); | |
| OLD | NEW |