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 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
165 // eventhandler. When receiving a message from the eventhandler the | 165 // eventhandler. When receiving a message from the eventhandler the |
166 // EVENT flags indicate the events that actually happened. The | 166 // EVENT flags indicate the events that actually happened. The |
167 // COMMAND flags are used to send commands from dart to the | 167 // COMMAND flags are used to send commands from dart to the |
168 // eventhandler. COMMAND flags are never received from the | 168 // eventhandler. COMMAND flags are never received from the |
169 // eventhandler. Additional flags are used to communicate other | 169 // eventhandler. Additional flags are used to communicate other |
170 // information. | 170 // information. |
171 static const int READ_EVENT = 0; | 171 static const int READ_EVENT = 0; |
172 static const int WRITE_EVENT = 1; | 172 static const int WRITE_EVENT = 1; |
173 static const int ERROR_EVENT = 2; | 173 static const int ERROR_EVENT = 2; |
174 static const int CLOSED_EVENT = 3; | 174 static const int CLOSED_EVENT = 3; |
| 175 static const int DESTROYED_EVENT = 4; |
175 static const int FIRST_EVENT = READ_EVENT; | 176 static const int FIRST_EVENT = READ_EVENT; |
176 static const int LAST_EVENT = CLOSED_EVENT; | 177 static const int LAST_EVENT = DESTROYED_EVENT; |
177 static const int EVENT_COUNT = LAST_EVENT - FIRST_EVENT + 1; | 178 static const int EVENT_COUNT = LAST_EVENT - FIRST_EVENT + 1; |
178 | 179 |
179 static const int CLOSE_COMMAND = 8; | 180 static const int CLOSE_COMMAND = 8; |
180 static const int SHUTDOWN_READ_COMMAND = 9; | 181 static const int SHUTDOWN_READ_COMMAND = 9; |
181 static const int SHUTDOWN_WRITE_COMMAND = 10; | 182 static const int SHUTDOWN_WRITE_COMMAND = 10; |
182 static const int FIRST_COMMAND = CLOSE_COMMAND; | 183 static const int FIRST_COMMAND = CLOSE_COMMAND; |
183 static const int LAST_COMMAND = SHUTDOWN_WRITE_COMMAND; | 184 static const int LAST_COMMAND = SHUTDOWN_WRITE_COMMAND; |
184 | 185 |
185 // Type flag send to the eventhandler providing additional | 186 // Type flag send to the eventhandler providing additional |
186 // information on the type of the file descriptor. | 187 // information on the type of the file descriptor. |
187 static const int LISTENING_SOCKET = 16; | 188 static const int LISTENING_SOCKET = 16; |
188 static const int PIPE_SOCKET = 17; | 189 static const int PIPE_SOCKET = 17; |
189 static const int TYPE_NORMAL_SOCKET = 0; | 190 static const int TYPE_NORMAL_SOCKET = 0; |
190 static const int TYPE_LISTENING_SOCKET = 1 << LISTENING_SOCKET; | 191 static const int TYPE_LISTENING_SOCKET = 1 << LISTENING_SOCKET; |
191 static const int TYPE_PIPE = 1 << PIPE_SOCKET; | 192 static const int TYPE_PIPE = 1 << PIPE_SOCKET; |
192 | 193 |
193 // Native port messages. | 194 // Native port messages. |
194 static const HOST_NAME_LOOKUP = 0; | 195 static const HOST_NAME_LOOKUP = 0; |
195 static const LIST_INTERFACES = 1; | 196 static const LIST_INTERFACES = 1; |
196 static const REVERSE_LOOKUP = 2; | 197 static const REVERSE_LOOKUP = 2; |
197 | 198 |
198 // Socket close state | 199 // Socket close state |
199 bool isClosed = false; | 200 bool isClosed = false; |
| 201 bool isClosing = false; |
200 bool isClosedRead = false; | 202 bool isClosedRead = false; |
201 bool isClosedWrite = false; | 203 bool isClosedWrite = false; |
202 Completer closeCompleter = new Completer(); | 204 Completer closeCompleter = new Completer(); |
203 | 205 |
204 // Handlers and receive port for socket events from the event handler. | 206 // Handlers and receive port for socket events from the event handler. |
205 int eventMask = 0; | 207 int eventMask = 0; |
206 List eventHandlers; | 208 List eventHandlers; |
207 ReceivePort eventPort; | 209 ReceivePort eventPort; |
208 | 210 |
209 // Indicates if native interrupts can be activated. | 211 // Indicates if native interrupts can be activated. |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 eventHandlers = new List(EVENT_COUNT + 1); | 365 eventHandlers = new List(EVENT_COUNT + 1); |
364 _EventHandler._start(); | 366 _EventHandler._start(); |
365 } | 367 } |
366 | 368 |
367 _NativeSocket.pipe() : typeFlags = TYPE_PIPE { | 369 _NativeSocket.pipe() : typeFlags = TYPE_PIPE { |
368 eventHandlers = new List(EVENT_COUNT + 1); | 370 eventHandlers = new List(EVENT_COUNT + 1); |
369 _EventHandler._start(); | 371 _EventHandler._start(); |
370 } | 372 } |
371 | 373 |
372 int available() { | 374 int available() { |
373 if (isClosed) return 0; | 375 if (isClosing || isClosed) return 0; |
374 var result = nativeAvailable(); | 376 var result = nativeAvailable(); |
375 if (result is OSError) { | 377 if (result is OSError) { |
376 reportError(result, "Available failed"); | 378 reportError(result, "Available failed"); |
377 return 0; | 379 return 0; |
378 } else { | 380 } else { |
379 return result; | 381 return result; |
380 } | 382 } |
381 } | 383 } |
382 | 384 |
383 List<int> read(int len) { | 385 List<int> read(int len) { |
384 if (len != null && len <= 0) { | 386 if (len != null && len <= 0) { |
385 throw new ArgumentError("Illegal length $len"); | 387 throw new ArgumentError("Illegal length $len"); |
386 } | 388 } |
387 if (isClosed) return null; | 389 if (isClosing || isClosed) return null; |
388 var result = nativeRead(len == null ? -1 : len); | 390 var result = nativeRead(len == null ? -1 : len); |
389 if (result is OSError) { | 391 if (result is OSError) { |
390 reportError(result, "Read failed"); | 392 reportError(result, "Read failed"); |
391 return null; | 393 return null; |
392 } | 394 } |
393 return result; | 395 return result; |
394 } | 396 } |
395 | 397 |
396 int write(List<int> buffer, int offset, int bytes) { | 398 int write(List<int> buffer, int offset, int bytes) { |
397 if (buffer is! List) throw new ArgumentError(); | 399 if (buffer is! List) throw new ArgumentError(); |
398 if (offset == null) offset = 0; | 400 if (offset == null) offset = 0; |
399 if (bytes == null) { | 401 if (bytes == null) { |
400 if (offset > buffer.length) { | 402 if (offset > buffer.length) { |
401 throw new RangeError.value(offset); | 403 throw new RangeError.value(offset); |
402 } | 404 } |
403 bytes = buffer.length - offset; | 405 bytes = buffer.length - offset; |
404 } | 406 } |
405 if (offset < 0) throw new RangeError.value(offset); | 407 if (offset < 0) throw new RangeError.value(offset); |
406 if (bytes < 0) throw new RangeError.value(bytes); | 408 if (bytes < 0) throw new RangeError.value(bytes); |
407 if ((offset + bytes) > buffer.length) { | 409 if ((offset + bytes) > buffer.length) { |
408 throw new RangeError.value(offset + bytes); | 410 throw new RangeError.value(offset + bytes); |
409 } | 411 } |
410 if (offset is! int || bytes is! int) { | 412 if (offset is! int || bytes is! int) { |
411 throw new ArgumentError("Invalid arguments to write on Socket"); | 413 throw new ArgumentError("Invalid arguments to write on Socket"); |
412 } | 414 } |
413 if (isClosed) return 0; | 415 if (isClosing || isClosed) return 0; |
414 if (bytes == 0) return 0; | 416 if (bytes == 0) return 0; |
415 _BufferAndStart bufferAndStart = | 417 _BufferAndStart bufferAndStart = |
416 _ensureFastAndSerializableByteData(buffer, offset, offset + bytes); | 418 _ensureFastAndSerializableByteData(buffer, offset, offset + bytes); |
417 var result = | 419 var result = |
418 nativeWrite(bufferAndStart.buffer, bufferAndStart.start, bytes); | 420 nativeWrite(bufferAndStart.buffer, bufferAndStart.start, bytes); |
419 if (result is OSError) { | 421 if (result is OSError) { |
420 reportError(result, "Write failed"); | 422 reportError(result, "Write failed"); |
421 result = 0; | 423 result = 0; |
422 } | 424 } |
423 return result; | 425 return result; |
(...skipping 20 matching lines...) Expand all Loading... |
444 return nativeGetRemotePeer()[0]; | 446 return nativeGetRemotePeer()[0]; |
445 } | 447 } |
446 | 448 |
447 // Multiplexes socket events to the socket handlers. | 449 // Multiplexes socket events to the socket handlers. |
448 void multiplex(int events) { | 450 void multiplex(int events) { |
449 canActivateEvents = false; | 451 canActivateEvents = false; |
450 for (int i = FIRST_EVENT; i <= LAST_EVENT; i++) { | 452 for (int i = FIRST_EVENT; i <= LAST_EVENT; i++) { |
451 if (((events & (1 << i)) != 0)) { | 453 if (((events & (1 << i)) != 0)) { |
452 if (i == CLOSED_EVENT && | 454 if (i == CLOSED_EVENT && |
453 typeFlags != TYPE_LISTENING_SOCKET && | 455 typeFlags != TYPE_LISTENING_SOCKET && |
| 456 !isClosing && |
454 !isClosed) { | 457 !isClosed) { |
455 isClosedRead = true; | 458 isClosedRead = true; |
456 } | 459 } |
457 | 460 |
458 var handler = eventHandlers[i]; | 461 var handler = eventHandlers[i]; |
| 462 if (i == DESTROYED_EVENT) { |
| 463 assert(!isClosed); |
| 464 isClosed = true; |
| 465 closeCompleter.complete(this); |
| 466 disconnectFromEventHandler(); |
| 467 if (handler != null) handler(); |
| 468 continue; |
| 469 } |
459 assert(handler != null); | 470 assert(handler != null); |
460 if (i == WRITE_EVENT) { | 471 if (i == WRITE_EVENT) { |
461 // If the event was disabled before we had a chance to fire the event, | 472 // If the event was disabled before we had a chance to fire the event, |
462 // discard it. If we register again, we'll get a new one. | 473 // discard it. If we register again, we'll get a new one. |
463 if ((eventMask & (1 << i)) == 0) continue; | 474 if ((eventMask & (1 << i)) == 0) continue; |
464 // Unregister the out handler before executing it. There is | 475 // Unregister the out handler before executing it. There is |
465 // no need to notify the eventhandler as handlers are | 476 // no need to notify the eventhandler as handlers are |
466 // disabled while the event is handled. | 477 // disabled while the event is handled. |
467 eventMask &= ~(1 << i); | 478 eventMask &= ~(1 << i); |
468 } | 479 } |
(...skipping 10 matching lines...) Expand all Loading... |
479 } else if (!isClosed) { | 490 } else if (!isClosed) { |
480 handler(); | 491 handler(); |
481 } | 492 } |
482 } | 493 } |
483 } | 494 } |
484 if (isClosedRead && isClosedWrite) close(); | 495 if (isClosedRead && isClosedWrite) close(); |
485 canActivateEvents = true; | 496 canActivateEvents = true; |
486 activateHandlers(); | 497 activateHandlers(); |
487 } | 498 } |
488 | 499 |
489 void setHandlers({read: null, write: null, error: null, closed: null}) { | 500 void setHandlers({read, write, error, closed, destroyed}) { |
490 eventHandlers[READ_EVENT] = read; | 501 eventHandlers[READ_EVENT] = read; |
491 eventHandlers[WRITE_EVENT] = write; | 502 eventHandlers[WRITE_EVENT] = write; |
492 eventHandlers[ERROR_EVENT] = error; | 503 eventHandlers[ERROR_EVENT] = error; |
493 eventHandlers[CLOSED_EVENT] = closed; | 504 eventHandlers[CLOSED_EVENT] = closed; |
| 505 eventHandlers[DESTROYED_EVENT] = destroyed; |
494 } | 506 } |
495 | 507 |
496 void setListening({read: true, write: true}) { | 508 void setListening({read: true, write: true}) { |
497 eventMask = (1 << CLOSED_EVENT) | (1 << ERROR_EVENT); | 509 eventMask = (1 << CLOSED_EVENT) | (1 << ERROR_EVENT); |
498 if (read) eventMask |= (1 << READ_EVENT); | 510 if (read) eventMask |= (1 << READ_EVENT); |
499 if (write) eventMask |= (1 << WRITE_EVENT); | 511 if (write) eventMask |= (1 << WRITE_EVENT); |
500 activateHandlers(); | 512 activateHandlers(); |
501 } | 513 } |
502 | 514 |
503 Future get closeFuture => closeCompleter.future; | 515 Future<_NativeSocket> get closeFuture => closeCompleter.future; |
504 | 516 |
505 void activateHandlers() { | 517 void activateHandlers() { |
506 if (canActivateEvents && !isClosed) { | 518 if (canActivateEvents && !isClosing && !isClosed) { |
507 // If we don't listen for either read or write, disconnect as we won't | |
508 // get close and error events anyway. | |
509 if ((eventMask & ((1 << READ_EVENT) | (1 << WRITE_EVENT))) == 0) { | 519 if ((eventMask & ((1 << READ_EVENT) | (1 << WRITE_EVENT))) == 0) { |
| 520 // If we don't listen for either read or write, disconnect as we won't |
| 521 // get close and error events anyway. |
510 if (eventPort != null) disconnectFromEventHandler(); | 522 if (eventPort != null) disconnectFromEventHandler(); |
511 } else { | 523 } else { |
512 int data = eventMask; | 524 int data = eventMask; |
513 data |= typeFlags; | |
514 if (isClosedRead) data &= ~(1 << READ_EVENT); | 525 if (isClosedRead) data &= ~(1 << READ_EVENT); |
515 if (isClosedWrite) data &= ~(1 << WRITE_EVENT); | 526 if (isClosedWrite) data &= ~(1 << WRITE_EVENT); |
| 527 data |= typeFlags; |
516 sendToEventHandler(data); | 528 sendToEventHandler(data); |
517 } | 529 } |
518 } | 530 } |
519 } | 531 } |
520 | 532 |
521 void close() { | 533 Future<_NativeSocket> close() { |
522 if (!isClosed) { | 534 if (!isClosing && !isClosed) { |
523 sendToEventHandler(1 << CLOSE_COMMAND); | 535 sendToEventHandler(1 << CLOSE_COMMAND); |
524 isClosed = true; | 536 isClosing = true; |
525 closeCompleter.complete(this); | |
526 } | 537 } |
527 // Outside the if support closing sockets created but never | 538 return closeFuture; |
528 // assigned any actual socket. | |
529 disconnectFromEventHandler(); | |
530 } | 539 } |
531 | 540 |
532 void shutdown(SocketDirection direction) { | 541 void shutdown(SocketDirection direction) { |
533 if (!isClosed) { | 542 if (!isClosing && !isClosed) { |
534 switch (direction) { | 543 switch (direction) { |
535 case SocketDirection.RECEIVE: | 544 case SocketDirection.RECEIVE: |
536 shutdownRead(); | 545 shutdownRead(); |
537 break; | 546 break; |
538 case SocketDirection.SEND: | 547 case SocketDirection.SEND: |
539 shutdownWrite(); | 548 shutdownWrite(); |
540 break; | 549 break; |
541 case SocketDirection.BOTH: | 550 case SocketDirection.BOTH: |
542 close(); | 551 close(); |
543 break; | 552 break; |
544 default: | 553 default: |
545 throw new ArgumentError(direction); | 554 throw new ArgumentError(direction); |
546 } | 555 } |
547 } | 556 } |
548 } | 557 } |
549 | 558 |
550 void shutdownWrite() { | 559 void shutdownWrite() { |
551 if (!isClosed) { | 560 if (!isClosing && !isClosed) { |
552 if (isClosedRead) { | 561 if (isClosedRead) { |
553 close(); | 562 close(); |
554 } else { | 563 } else { |
555 sendToEventHandler(1 << SHUTDOWN_WRITE_COMMAND); | 564 sendToEventHandler(1 << SHUTDOWN_WRITE_COMMAND); |
556 } | 565 } |
557 isClosedWrite = true; | 566 isClosedWrite = true; |
558 } | 567 } |
559 } | 568 } |
560 | 569 |
561 void shutdownRead() { | 570 void shutdownRead() { |
562 if (!isClosed) { | 571 if (!isClosing && !isClosed) { |
563 if (isClosedWrite) { | 572 if (isClosedWrite) { |
564 close(); | 573 close(); |
565 } else { | 574 } else { |
566 sendToEventHandler(1 << SHUTDOWN_READ_COMMAND); | 575 sendToEventHandler(1 << SHUTDOWN_READ_COMMAND); |
567 } | 576 } |
568 isClosedRead = true; | 577 isClosedRead = true; |
569 } | 578 } |
570 } | 579 } |
571 | 580 |
572 void sendToEventHandler(int data) { | 581 void sendToEventHandler(int data) { |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 bool cancelOnError}) { | 711 bool cancelOnError}) { |
703 return _controller.stream.listen( | 712 return _controller.stream.listen( |
704 onData, | 713 onData, |
705 onError: onError, | 714 onError: onError, |
706 onDone: onDone, | 715 onDone: onDone, |
707 cancelOnError: cancelOnError); | 716 cancelOnError: cancelOnError); |
708 } | 717 } |
709 | 718 |
710 int get port => _socket.port; | 719 int get port => _socket.port; |
711 | 720 |
712 void close() => _socket.close(); | 721 Future close() => _socket.close().then((_) => this); |
713 | 722 |
714 void _pause() { | 723 void _pause() { |
715 _socket.setListening(read: false, write: false); | 724 _socket.setListening(read: false, write: false); |
716 } | 725 } |
717 | 726 |
718 void _resume() { | 727 void _resume() { |
719 _socket.setListening(read: true, write: false); | 728 _socket.setListening(read: true, write: false); |
720 } | 729 } |
721 | 730 |
722 void _onSubscriptionStateChange() { | 731 void _onSubscriptionStateChange() { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
761 _socket.closeFuture.then((_) => _controller.close()); | 770 _socket.closeFuture.then((_) => _controller.close()); |
762 _socket.setHandlers( | 771 _socket.setHandlers( |
763 read: () => _controller.add(RawSocketEvent.READ), | 772 read: () => _controller.add(RawSocketEvent.READ), |
764 write: () { | 773 write: () { |
765 // The write event handler is automatically disabled by the | 774 // The write event handler is automatically disabled by the |
766 // event handler when it fires. | 775 // event handler when it fires. |
767 _writeEventsEnabled = false; | 776 _writeEventsEnabled = false; |
768 _controller.add(RawSocketEvent.WRITE); | 777 _controller.add(RawSocketEvent.WRITE); |
769 }, | 778 }, |
770 closed: () => _controller.add(RawSocketEvent.READ_CLOSED), | 779 closed: () => _controller.add(RawSocketEvent.READ_CLOSED), |
| 780 destroyed: () => _controller.add(RawSocketEvent.CLOSED), |
771 error: (e) { | 781 error: (e) { |
772 _controller.addError(e); | 782 _controller.addError(e); |
773 close(); | 783 close(); |
774 } | 784 } |
775 ); | 785 ); |
776 } | 786 } |
777 | 787 |
778 factory _RawSocket._writePipe(int fd) { | 788 factory _RawSocket._writePipe(int fd) { |
779 var native = new _NativeSocket.pipe(); | 789 var native = new _NativeSocket.pipe(); |
780 native.isClosedRead = true; | 790 native.isClosedRead = true; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
818 } | 828 } |
819 return data; | 829 return data; |
820 } else { | 830 } else { |
821 return _socket.read(len); | 831 return _socket.read(len); |
822 } | 832 } |
823 } | 833 } |
824 | 834 |
825 int write(List<int> buffer, [int offset, int count]) => | 835 int write(List<int> buffer, [int offset, int count]) => |
826 _socket.write(buffer, offset, count); | 836 _socket.write(buffer, offset, count); |
827 | 837 |
828 void close() => _socket.close(); | 838 Future close() => _socket.close().then((_) => this); |
829 | 839 |
830 void shutdown(SocketDirection direction) => _socket.shutdown(direction); | 840 void shutdown(SocketDirection direction) => _socket.shutdown(direction); |
831 | 841 |
832 int get port => _socket.port; | 842 int get port => _socket.port; |
833 | 843 |
834 int get remotePort => _socket.remotePort; | 844 int get remotePort => _socket.remotePort; |
835 | 845 |
836 InternetAddress get address => _socket.address; | 846 InternetAddress get address => _socket.address; |
837 | 847 |
838 String get remoteHost => _socket.remoteHost; | 848 String get remoteHost => _socket.remoteHost; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
911 bool cancelOnError}) { | 921 bool cancelOnError}) { |
912 return _socket.map((rawSocket) => new _Socket(rawSocket)).listen( | 922 return _socket.map((rawSocket) => new _Socket(rawSocket)).listen( |
913 onData, | 923 onData, |
914 onError: onError, | 924 onError: onError, |
915 onDone: onDone, | 925 onDone: onDone, |
916 cancelOnError: cancelOnError); | 926 cancelOnError: cancelOnError); |
917 } | 927 } |
918 | 928 |
919 int get port => _socket.port; | 929 int get port => _socket.port; |
920 | 930 |
921 void close() => _socket.close(); | 931 Future close() => _socket.close().then((_) => this); |
922 } | 932 } |
923 | 933 |
924 | 934 |
925 patch class Socket { | 935 patch class Socket { |
926 /* patch */ static Future<Socket> connect(host, int port) { | 936 /* patch */ static Future<Socket> connect(host, int port) { |
927 return RawSocket.connect(host, port).then( | 937 return RawSocket.connect(host, port).then( |
928 (socket) => new _Socket(socket)); | 938 (socket) => new _Socket(socket)); |
929 } | 939 } |
930 } | 940 } |
931 | 941 |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1206 if (_detachReady != null) { | 1216 if (_detachReady != null) { |
1207 _detachReady.complete(null); | 1217 _detachReady.complete(null); |
1208 } else { | 1218 } else { |
1209 if (_raw != null) { | 1219 if (_raw != null) { |
1210 _raw.shutdown(SocketDirection.SEND); | 1220 _raw.shutdown(SocketDirection.SEND); |
1211 _disableWriteEvent(); | 1221 _disableWriteEvent(); |
1212 } | 1222 } |
1213 } | 1223 } |
1214 } | 1224 } |
1215 } | 1225 } |
OLD | NEW |