| 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 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 | 246 |
| 247 // Protocol flags. | 247 // Protocol flags. |
| 248 static const int PROTOCOL_IPV4 = 1 << 0; | 248 static const int PROTOCOL_IPV4 = 1 << 0; |
| 249 static const int PROTOCOL_IPV6 = 1 << 1; | 249 static const int PROTOCOL_IPV6 = 1 << 1; |
| 250 | 250 |
| 251 // Socket close state | 251 // Socket close state |
| 252 bool isClosed = false; | 252 bool isClosed = false; |
| 253 bool isClosing = false; | 253 bool isClosing = false; |
| 254 bool isClosedRead = false; | 254 bool isClosedRead = false; |
| 255 bool isClosedWrite = false; | 255 bool isClosedWrite = false; |
| 256 Completer closeCompleter = new Completer(); | 256 Completer closeCompleter = new Completer.sync(); |
| 257 | 257 |
| 258 // Handlers and receive port for socket events from the event handler. | 258 // Handlers and receive port for socket events from the event handler. |
| 259 int eventMask = 0; | 259 int eventMask = 0; |
| 260 List eventHandlers; | 260 List eventHandlers; |
| 261 RawReceivePort eventPort; | 261 RawReceivePort eventPort; |
| 262 | 262 |
| 263 // Indicates if native interrupts can be activated. | 263 // Indicates if native interrupts can be activated. |
| 264 bool canActivateEvents = true; | 264 bool canActivateEvents = true; |
| 265 | 265 |
| 266 // The type flags for this socket. | 266 // The type flags for this socket. |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 564 typeFlags != TYPE_LISTENING_SOCKET && | 564 typeFlags != TYPE_LISTENING_SOCKET && |
| 565 !isClosing && | 565 !isClosing && |
| 566 !isClosed) { | 566 !isClosed) { |
| 567 isClosedRead = true; | 567 isClosedRead = true; |
| 568 } | 568 } |
| 569 | 569 |
| 570 var handler = eventHandlers[i]; | 570 var handler = eventHandlers[i]; |
| 571 if (i == DESTROYED_EVENT) { | 571 if (i == DESTROYED_EVENT) { |
| 572 assert(!isClosed); | 572 assert(!isClosed); |
| 573 isClosed = true; | 573 isClosed = true; |
| 574 closeCompleter.complete(this); | 574 closeCompleter.complete(); |
| 575 disconnectFromEventHandler(); | 575 disconnectFromEventHandler(); |
| 576 if (handler != null) handler(); | 576 if (handler != null) handler(); |
| 577 continue; | 577 continue; |
| 578 } | 578 } |
| 579 assert(handler != null); | 579 assert(handler != null); |
| 580 if (i == WRITE_EVENT) { | 580 if (i == WRITE_EVENT) { |
| 581 // If the event was disabled before we had a chance to fire the event, | 581 // 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. | 582 // discard it. If we register again, we'll get a new one. |
| 583 if ((eventMask & (1 << i)) == 0) continue; | 583 if ((eventMask & (1 << i)) == 0) continue; |
| 584 // Unregister the out handler before executing it. There is | 584 // Unregister the out handler before executing it. There is |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 eventHandlers[DESTROYED_EVENT] = destroyed; | 618 eventHandlers[DESTROYED_EVENT] = destroyed; |
| 619 } | 619 } |
| 620 | 620 |
| 621 void setListening({read: true, write: true}) { | 621 void setListening({read: true, write: true}) { |
| 622 eventMask = (1 << CLOSED_EVENT) | (1 << ERROR_EVENT); | 622 eventMask = (1 << CLOSED_EVENT) | (1 << ERROR_EVENT); |
| 623 if (read) eventMask |= (1 << READ_EVENT); | 623 if (read) eventMask |= (1 << READ_EVENT); |
| 624 if (write) eventMask |= (1 << WRITE_EVENT); | 624 if (write) eventMask |= (1 << WRITE_EVENT); |
| 625 activateHandlers(); | 625 activateHandlers(); |
| 626 } | 626 } |
| 627 | 627 |
| 628 Future<_NativeSocket> get closeFuture => closeCompleter.future; | |
| 629 | 628 |
| 630 void activateHandlers() { | 629 void activateHandlers() { |
| 631 if (canActivateEvents && !isClosing && !isClosed) { | 630 if (canActivateEvents && !isClosing && !isClosed) { |
| 632 if ((eventMask & ((1 << READ_EVENT) | (1 << WRITE_EVENT))) == 0) { | 631 if ((eventMask & ((1 << READ_EVENT) | (1 << WRITE_EVENT))) == 0) { |
| 633 // If we don't listen for either read or write, disconnect as we won't | 632 // If we don't listen for either read or write, disconnect as we won't |
| 634 // get close and error events anyway. | 633 // get close and error events anyway. |
| 635 if (eventPort != null) disconnectFromEventHandler(); | 634 if (eventPort != null) disconnectFromEventHandler(); |
| 636 } else { | 635 } else { |
| 637 int data = eventMask; | 636 int data = eventMask; |
| 638 if (isClosedRead) data &= ~(1 << READ_EVENT); | 637 if (isClosedRead) data &= ~(1 << READ_EVENT); |
| 639 if (isClosedWrite) data &= ~(1 << WRITE_EVENT); | 638 if (isClosedWrite) data &= ~(1 << WRITE_EVENT); |
| 640 data |= typeFlags; | 639 data |= typeFlags; |
| 641 sendToEventHandler(data); | 640 sendToEventHandler(data); |
| 642 } | 641 } |
| 643 } | 642 } |
| 644 } | 643 } |
| 645 | 644 |
| 646 Future<_NativeSocket> close() { | 645 Future close() { |
| 647 if (!isClosing && !isClosed) { | 646 if (!isClosing && !isClosed) { |
| 648 sendToEventHandler(1 << CLOSE_COMMAND); | 647 sendToEventHandler(1 << CLOSE_COMMAND); |
| 649 isClosing = true; | 648 isClosing = true; |
| 650 } | 649 } |
| 651 return closeFuture; | 650 return closeCompleter.future; |
| 652 } | 651 } |
| 653 | 652 |
| 654 void shutdown(SocketDirection direction) { | 653 void shutdown(SocketDirection direction) { |
| 655 if (!isClosing && !isClosed) { | 654 if (!isClosing && !isClosed) { |
| 656 switch (direction) { | 655 switch (direction) { |
| 657 case SocketDirection.RECEIVE: | 656 case SocketDirection.RECEIVE: |
| 658 shutdownRead(); | 657 shutdownRead(); |
| 659 break; | 658 break; |
| 660 case SocketDirection.SEND: | 659 case SocketDirection.SEND: |
| 661 shutdownWrite(); | 660 shutdownWrite(); |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 860 .then((socket) => new _RawServerSocket(socket)); | 859 .then((socket) => new _RawServerSocket(socket)); |
| 861 } | 860 } |
| 862 | 861 |
| 863 _RawServerSocket(this._socket) { | 862 _RawServerSocket(this._socket) { |
| 864 var zone = Zone.current; | 863 var zone = Zone.current; |
| 865 _controller = new StreamController(sync: true, | 864 _controller = new StreamController(sync: true, |
| 866 onListen: _onSubscriptionStateChange, | 865 onListen: _onSubscriptionStateChange, |
| 867 onCancel: _onSubscriptionStateChange, | 866 onCancel: _onSubscriptionStateChange, |
| 868 onPause: _onPauseStateChange, | 867 onPause: _onPauseStateChange, |
| 869 onResume: _onPauseStateChange); | 868 onResume: _onPauseStateChange); |
| 870 _socket.closeFuture.then((_) => _controller.close()); | |
| 871 _socket.setHandlers( | 869 _socket.setHandlers( |
| 872 read: zone.bindCallback(() { | 870 read: zone.bindCallback(() { |
| 873 var socket = _socket.accept(); | 871 var socket = _socket.accept(); |
| 874 if (socket != null) _controller.add(new _RawSocket(socket)); | 872 if (socket != null) _controller.add(new _RawSocket(socket)); |
| 875 }), | 873 }), |
| 876 error: zone.bindUnaryCallback((e) { | 874 error: zone.bindUnaryCallback((e) { |
| 877 _controller.addError(e); | 875 _controller.addError(e); |
| 878 _controller.close(); | 876 _controller.close(); |
| 879 }) | 877 }), |
| 878 destroyed: _controller.close |
| 880 ); | 879 ); |
| 881 } | 880 } |
| 882 | 881 |
| 883 StreamSubscription<RawSocket> listen(void onData(RawSocket event), | 882 StreamSubscription<RawSocket> listen(void onData(RawSocket event), |
| 884 {Function onError, | 883 {Function onError, |
| 885 void onDone(), | 884 void onDone(), |
| 886 bool cancelOnError}) { | 885 bool cancelOnError}) { |
| 887 return _controller.stream.listen( | 886 return _controller.stream.listen( |
| 888 onData, | 887 onData, |
| 889 onError: onError, | 888 onError: onError, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 902 } | 901 } |
| 903 | 902 |
| 904 void _resume() { | 903 void _resume() { |
| 905 _socket.setListening(read: true, write: false); | 904 _socket.setListening(read: true, write: false); |
| 906 } | 905 } |
| 907 | 906 |
| 908 void _onSubscriptionStateChange() { | 907 void _onSubscriptionStateChange() { |
| 909 if (_controller.hasListener) { | 908 if (_controller.hasListener) { |
| 910 _resume(); | 909 _resume(); |
| 911 } else { | 910 } else { |
| 912 close(); | 911 _socket.close(); |
| 913 } | 912 } |
| 914 } | 913 } |
| 915 | 914 |
| 916 void _onPauseStateChange() { | 915 void _onPauseStateChange() { |
| 917 if (_controller.isPaused) { | 916 if (_controller.isPaused) { |
| 918 _pause(); | 917 _pause(); |
| 919 } else { | 918 } else { |
| 920 _resume(); | 919 _resume(); |
| 921 } | 920 } |
| 922 } | 921 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 938 .then((socket) => new _RawSocket(socket)); | 937 .then((socket) => new _RawSocket(socket)); |
| 939 } | 938 } |
| 940 | 939 |
| 941 _RawSocket(this._socket) { | 940 _RawSocket(this._socket) { |
| 942 var zone = Zone.current; | 941 var zone = Zone.current; |
| 943 _controller = new StreamController(sync: true, | 942 _controller = new StreamController(sync: true, |
| 944 onListen: _onSubscriptionStateChange, | 943 onListen: _onSubscriptionStateChange, |
| 945 onCancel: _onSubscriptionStateChange, | 944 onCancel: _onSubscriptionStateChange, |
| 946 onPause: _onPauseStateChange, | 945 onPause: _onPauseStateChange, |
| 947 onResume: _onPauseStateChange); | 946 onResume: _onPauseStateChange); |
| 948 _socket.closeFuture.then((_) => _controller.close()); | |
| 949 _socket.setHandlers( | 947 _socket.setHandlers( |
| 950 read: () => _controller.add(RawSocketEvent.READ), | 948 read: () => _controller.add(RawSocketEvent.READ), |
| 951 write: () { | 949 write: () { |
| 952 // The write event handler is automatically disabled by the | 950 // The write event handler is automatically disabled by the |
| 953 // event handler when it fires. | 951 // event handler when it fires. |
| 954 _writeEventsEnabled = false; | 952 _writeEventsEnabled = false; |
| 955 _controller.add(RawSocketEvent.WRITE); | 953 _controller.add(RawSocketEvent.WRITE); |
| 956 }, | 954 }, |
| 957 closed: () => _controller.add(RawSocketEvent.READ_CLOSED), | 955 closed: () => _controller.add(RawSocketEvent.READ_CLOSED), |
| 958 destroyed: () => _controller.add(RawSocketEvent.CLOSED), | 956 destroyed: () { |
| 957 _controller.add(RawSocketEvent.CLOSED); |
| 958 _controller.close(); |
| 959 }, |
| 959 error: zone.bindUnaryCallback((e) { | 960 error: zone.bindUnaryCallback((e) { |
| 960 _controller.addError(e); | 961 _controller.addError(e); |
| 961 close(); | 962 _socket.close(); |
| 962 }) | 963 }) |
| 963 ); | 964 ); |
| 964 } | 965 } |
| 965 | 966 |
| 966 factory _RawSocket._writePipe(int fd) { | 967 factory _RawSocket._writePipe(int fd) { |
| 967 var native = new _NativeSocket.pipe(); | 968 var native = new _NativeSocket.pipe(); |
| 968 native.isClosedRead = true; | 969 native.isClosedRead = true; |
| 969 if (fd != null) _getStdioHandle(native, fd); | 970 if (fd != null) _getStdioHandle(native, fd); |
| 970 return new _RawSocket(native); | 971 return new _RawSocket(native); |
| 971 } | 972 } |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1057 _pause(); | 1058 _pause(); |
| 1058 } else { | 1059 } else { |
| 1059 _resume(); | 1060 _resume(); |
| 1060 } | 1061 } |
| 1061 } | 1062 } |
| 1062 | 1063 |
| 1063 void _onSubscriptionStateChange() { | 1064 void _onSubscriptionStateChange() { |
| 1064 if (_controller.hasListener) { | 1065 if (_controller.hasListener) { |
| 1065 _resume(); | 1066 _resume(); |
| 1066 } else { | 1067 } else { |
| 1067 close(); | 1068 _socket.close(); |
| 1068 } | 1069 } |
| 1069 } | 1070 } |
| 1070 } | 1071 } |
| 1071 | 1072 |
| 1072 | 1073 |
| 1073 patch class ServerSocket { | 1074 patch class ServerSocket { |
| 1074 /* patch */ static Future<ServerSocket> bind(address, | 1075 /* patch */ static Future<ServerSocket> bind(address, |
| 1075 int port, | 1076 int port, |
| 1076 {int backlog: 0, | 1077 {int backlog: 0, |
| 1077 bool v6Only: false}) { | 1078 bool v6Only: false}) { |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1420 bool _readEventsEnabled = true; | 1421 bool _readEventsEnabled = true; |
| 1421 bool _writeEventsEnabled = true; | 1422 bool _writeEventsEnabled = true; |
| 1422 | 1423 |
| 1423 _RawDatagramSocket(this._socket) { | 1424 _RawDatagramSocket(this._socket) { |
| 1424 var zone = Zone.current; | 1425 var zone = Zone.current; |
| 1425 _controller = new StreamController(sync: true, | 1426 _controller = new StreamController(sync: true, |
| 1426 onListen: _onSubscriptionStateChange, | 1427 onListen: _onSubscriptionStateChange, |
| 1427 onCancel: _onSubscriptionStateChange, | 1428 onCancel: _onSubscriptionStateChange, |
| 1428 onPause: _onPauseStateChange, | 1429 onPause: _onPauseStateChange, |
| 1429 onResume: _onPauseStateChange); | 1430 onResume: _onPauseStateChange); |
| 1430 _socket.closeFuture.then((_) => _controller.close()); | |
| 1431 _socket.setHandlers( | 1431 _socket.setHandlers( |
| 1432 read: () => _controller.add(RawSocketEvent.READ), | 1432 read: () => _controller.add(RawSocketEvent.READ), |
| 1433 write: () { | 1433 write: () { |
| 1434 // The write event handler is automatically disabled by the | 1434 // The write event handler is automatically disabled by the |
| 1435 // event handler when it fires. | 1435 // event handler when it fires. |
| 1436 _writeEventsEnabled = false; | 1436 _writeEventsEnabled = false; |
| 1437 _controller.add(RawSocketEvent.WRITE); | 1437 _controller.add(RawSocketEvent.WRITE); |
| 1438 }, | 1438 }, |
| 1439 closed: () => _controller.add(RawSocketEvent.READ_CLOSED), | 1439 closed: () => _controller.add(RawSocketEvent.READ_CLOSED), |
| 1440 destroyed: () => _controller.add(RawSocketEvent.CLOSED), | 1440 destroyed: () { |
| 1441 _controller.add(RawSocketEvent.CLOSED); |
| 1442 _controller.close(); |
| 1443 }, |
| 1441 error: zone.bindUnaryCallback((e) { | 1444 error: zone.bindUnaryCallback((e) { |
| 1442 _controller.addError(e); | 1445 _controller.addError(e); |
| 1443 close(); | 1446 _socket.close(); |
| 1444 }) | 1447 }) |
| 1445 ); | 1448 ); |
| 1446 } | 1449 } |
| 1447 | 1450 |
| 1448 static Future<RawDatagramSocket> bind( | 1451 static Future<RawDatagramSocket> bind( |
| 1449 host, int port, bool reuseAddress) { | 1452 host, int port, bool reuseAddress) { |
| 1450 if (port < 0 || port > 0xffff) | 1453 if (port < 0 || port > 0xffff) |
| 1451 throw new ArgumentError("Invalid port $port"); | 1454 throw new ArgumentError("Invalid port $port"); |
| 1452 return _NativeSocket.bindDatagram(host, port, reuseAddress) | 1455 return _NativeSocket.bindDatagram(host, port, reuseAddress) |
| 1453 .then((socket) => new _RawDatagramSocket(socket)); | 1456 .then((socket) => new _RawDatagramSocket(socket)); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1534 _pause(); | 1537 _pause(); |
| 1535 } else { | 1538 } else { |
| 1536 _resume(); | 1539 _resume(); |
| 1537 } | 1540 } |
| 1538 } | 1541 } |
| 1539 | 1542 |
| 1540 void _onSubscriptionStateChange() { | 1543 void _onSubscriptionStateChange() { |
| 1541 if (_controller.hasListener) { | 1544 if (_controller.hasListener) { |
| 1542 _resume(); | 1545 _resume(); |
| 1543 } else { | 1546 } else { |
| 1544 close(); | 1547 _socket.close(); |
| 1545 } | 1548 } |
| 1546 } | 1549 } |
| 1547 } | 1550 } |
| 1548 | 1551 |
| 1549 Datagram _makeDatagram(List<int> data, | 1552 Datagram _makeDatagram(List<int> data, |
| 1550 String address, | 1553 String address, |
| 1551 List<int> in_addr, | 1554 List<int> in_addr, |
| 1552 int port) { | 1555 int port) { |
| 1553 return new Datagram( | 1556 return new Datagram( |
| 1554 data, | 1557 data, |
| 1555 new _InternetAddress(address, null, in_addr), | 1558 new _InternetAddress(address, null, in_addr), |
| 1556 port); | 1559 port); |
| 1557 } | 1560 } |
| OLD | NEW |