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

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

Issue 159663004: Avoid over-use of futures in socket. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Make socket-completer sync. Created 6 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698