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

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

Issue 14864009: Keep track of when a socket has been destroyed (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Remove delete_handle marker. Created 7 years, 5 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 | « runtime/bin/eventhandler_win.cc ('k') | sdk/lib/_internal/pub/lib/src/safe_http_server.dart » ('j') | 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 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « runtime/bin/eventhandler_win.cc ('k') | sdk/lib/_internal/pub/lib/src/safe_http_server.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698