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 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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.sync(); | 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 final List eventHandlers = new List(EVENT_COUNT + 1); |
| 260 List eventHandlers; | |
| 261 RawReceivePort eventPort; | 260 RawReceivePort eventPort; |
| 262 | 261 |
| 263 // Indicates if native interrupts can be activated. | |
| 264 bool canActivateEvents = true; | |
| 265 | |
| 266 // The type flags for this socket. | 262 // The type flags for this socket. |
| 267 final int typeFlags; | 263 final int typeFlags; |
| 268 | 264 |
| 269 // Holds the port of the socket, 0 if not known. | 265 // Holds the port of the socket, 0 if not known. |
| 270 int localPort = 0; | 266 int localPort = 0; |
| 271 | 267 |
| 272 // Holds the address used to connect or bind the socket. | 268 // Holds the address used to connect or bind the socket. |
| 273 InternetAddress address; | 269 InternetAddress address; |
| 274 | 270 |
| 271 int available = 0; | |
| 272 | |
| 273 bool sendReadEvents = false; | |
| 274 bool readEventIssued = false; | |
| 275 | |
| 276 bool sendWriteEvents = false; | |
| 277 bool writeEventIssued = false; | |
| 278 bool writeAvailable = false; | |
| 279 | |
| 275 static Future<List<InternetAddress>> lookup( | 280 static Future<List<InternetAddress>> lookup( |
| 276 String host, {InternetAddressType type: InternetAddressType.ANY}) { | 281 String host, {InternetAddressType type: InternetAddressType.ANY}) { |
| 277 return _IOService.dispatch(_SOCKET_LOOKUP, [host, type._value]) | 282 return _IOService.dispatch(_SOCKET_LOOKUP, [host, type._value]) |
| 278 .then((response) { | 283 .then((response) { |
| 279 if (isErrorResponse(response)) { | 284 if (isErrorResponse(response)) { |
| 280 throw createError(response, "Failed host lookup: '$host'"); | 285 throw createError(response, "Failed host lookup: '$host'"); |
| 281 } else { | 286 } else { |
| 282 return response.skip(1).map((result) { | 287 return response.skip(1).map((result) { |
| 283 var type = new InternetAddressType._from(result[0]); | 288 var type = new InternetAddressType._from(result[0]); |
| 284 return new _InternetAddress(result[1], host, result[2]); | 289 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", | 424 throw new SocketException("Failed to create datagram socket", |
| 420 osError: result, | 425 osError: result, |
| 421 address: address, | 426 address: address, |
| 422 port: port); | 427 port: port); |
| 423 } | 428 } |
| 424 if (port != 0) socket.localPort = port; | 429 if (port != 0) socket.localPort = port; |
| 425 return socket; | 430 return socket; |
| 426 }); | 431 }); |
| 427 } | 432 } |
| 428 | 433 |
| 429 _NativeSocket.datagram(this.address) | 434 _NativeSocket.datagram(this.address) : typeFlags = TYPE_NORMAL_SOCKET; |
| 430 : typeFlags = TYPE_NORMAL_SOCKET { | |
| 431 eventHandlers = new List(EVENT_COUNT + 1); | |
| 432 } | |
| 433 | 435 |
| 434 _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET { | 436 _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET; |
| 435 eventHandlers = new List(EVENT_COUNT + 1); | |
| 436 } | |
| 437 | 437 |
| 438 _NativeSocket.listen() : typeFlags = TYPE_LISTENING_SOCKET { | 438 _NativeSocket.listen() : typeFlags = TYPE_LISTENING_SOCKET; |
| 439 eventHandlers = new List(EVENT_COUNT + 1); | |
| 440 } | |
| 441 | 439 |
| 442 _NativeSocket.pipe() : typeFlags = TYPE_PIPE { | 440 _NativeSocket.pipe() : typeFlags = TYPE_PIPE; |
| 443 eventHandlers = new List(EVENT_COUNT + 1); | |
| 444 } | |
| 445 | 441 |
| 446 _NativeSocket.watch(int id) : typeFlags = TYPE_NORMAL_SOCKET { | 442 _NativeSocket.watch(int id) : typeFlags = TYPE_NORMAL_SOCKET { |
| 447 eventHandlers = new List(EVENT_COUNT + 1); | |
| 448 isClosedWrite = true; | 443 isClosedWrite = true; |
| 449 nativeSetSocketId(id); | 444 nativeSetSocketId(id); |
| 450 } | 445 } |
| 451 | 446 |
| 452 int available() { | |
| 453 if (isClosing || isClosed) return 0; | |
| 454 var result = nativeAvailable(); | |
| 455 if (result is OSError) { | |
| 456 reportError(result, "Available failed"); | |
| 457 return 0; | |
| 458 } else { | |
| 459 return result; | |
| 460 } | |
| 461 } | |
| 462 | |
| 463 List<int> read(int len) { | 447 List<int> read(int len) { |
| 464 if (len != null && len <= 0) { | 448 if (len != null && len <= 0) { |
| 465 throw new ArgumentError("Illegal length $len"); | 449 throw new ArgumentError("Illegal length $len"); |
| 466 } | 450 } |
| 467 if (isClosing || isClosed) return null; | 451 if (isClosing || isClosed) return null; |
| 468 var result = nativeRead(len == null ? -1 : len); | 452 var result = nativeRead(min(available, len == null ? available : len)); |
| 469 if (result is OSError) { | 453 if (result is OSError) { |
| 470 reportError(result, "Read failed"); | 454 reportError(result, "Read failed"); |
| 471 return null; | 455 return null; |
| 472 } | 456 } |
| 457 if (result != null) available -= result.length; | |
| 473 return result; | 458 return result; |
| 474 } | 459 } |
| 475 | 460 |
| 476 Datagram receive() { | 461 Datagram receive() { |
| 477 if (isClosing || isClosed) return null; | 462 if (isClosing || isClosed) return null; |
| 478 var result = nativeRecvFrom(); | 463 var result = nativeRecvFrom(); |
| 479 if (result is OSError) { | 464 if (result is OSError) { |
| 480 reportError(result, "Receive failed"); | 465 reportError(result, "Receive failed"); |
| 481 return null; | 466 return null; |
| 482 } | 467 } |
| 468 if (result != null) { | |
| 469 if (Platform.isMacOS) { | |
| 470 // Mac includes the header size, so we need to query the actual | |
| 471 // available. | |
| 472 available = nativeAvailable(); | |
| 473 } else { | |
| 474 available -= result.data.length; | |
| 475 } | |
| 476 } | |
| 483 return result; | 477 return result; |
| 484 } | 478 } |
| 485 | 479 |
| 486 int write(List<int> buffer, int offset, int bytes) { | 480 int write(List<int> buffer, int offset, int bytes) { |
| 487 if (buffer is! List) throw new ArgumentError(); | 481 if (buffer is! List) throw new ArgumentError(); |
| 488 if (offset == null) offset = 0; | 482 if (offset == null) offset = 0; |
| 489 if (bytes == null) { | 483 if (bytes == null) { |
| 490 if (offset > buffer.length) { | 484 if (offset > buffer.length) { |
| 491 throw new RangeError.value(offset); | 485 throw new RangeError.value(offset); |
| 492 } | 486 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 503 if (isClosing || isClosed) return 0; | 497 if (isClosing || isClosed) return 0; |
| 504 if (bytes == 0) return 0; | 498 if (bytes == 0) return 0; |
| 505 _BufferAndStart bufferAndStart = | 499 _BufferAndStart bufferAndStart = |
| 506 _ensureFastAndSerializableByteData(buffer, offset, offset + bytes); | 500 _ensureFastAndSerializableByteData(buffer, offset, offset + bytes); |
| 507 var result = | 501 var result = |
| 508 nativeWrite(bufferAndStart.buffer, bufferAndStart.start, bytes); | 502 nativeWrite(bufferAndStart.buffer, bufferAndStart.start, bytes); |
| 509 if (result is OSError) { | 503 if (result is OSError) { |
| 510 scheduleMicrotask(() => reportError(result, "Write failed")); | 504 scheduleMicrotask(() => reportError(result, "Write failed")); |
| 511 result = 0; | 505 result = 0; |
| 512 } | 506 } |
| 507 if (result >= 0 && result < bytes) { | |
| 508 writeAvailable = false; | |
| 509 } | |
| 510 if (result < 0) result = -result; | |
|
Søren Gjesse
2014/02/18 14:28:00
If the negative result is needed please explain it
Anders Johnsen
2014/02/19 09:43:03
Done.
| |
| 513 return result; | 511 return result; |
| 514 } | 512 } |
| 515 | 513 |
| 516 int send(List<int> buffer, int offset, int bytes, | 514 int send(List<int> buffer, int offset, int bytes, |
| 517 InternetAddress address, int port) { | 515 InternetAddress address, int port) { |
| 518 if (isClosing || isClosed) return 0; | 516 if (isClosing || isClosed) return 0; |
| 519 _BufferAndStart bufferAndStart = | 517 _BufferAndStart bufferAndStart = |
| 520 _ensureFastAndSerializableByteData( | 518 _ensureFastAndSerializableByteData( |
| 521 buffer, offset, bytes); | 519 buffer, offset, bytes); |
| 522 var result = nativeSendTo( | 520 var result = nativeSendTo( |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 547 int get remotePort { | 545 int get remotePort { |
| 548 return nativeGetRemotePeer()[1]; | 546 return nativeGetRemotePeer()[1]; |
| 549 } | 547 } |
| 550 | 548 |
| 551 InternetAddress get remoteAddress { | 549 InternetAddress get remoteAddress { |
| 552 var result = nativeGetRemotePeer()[0]; | 550 var result = nativeGetRemotePeer()[0]; |
| 553 var type = new InternetAddressType._from(result[0]); | 551 var type = new InternetAddressType._from(result[0]); |
| 554 return new _InternetAddress(result[1], null, result[2]); | 552 return new _InternetAddress(result[1], null, result[2]); |
| 555 } | 553 } |
| 556 | 554 |
| 555 void issueReadEvent() { | |
| 556 if (readEventIssued) return; | |
| 557 readEventIssued = true; | |
| 558 void issue() { | |
| 559 readEventIssued = false; | |
| 560 if (isClosing) return; | |
| 561 if (!sendReadEvents) return; | |
| 562 if (available == 0) { | |
| 563 if (isClosedRead) { | |
| 564 if (isClosedWrite) close(); | |
| 565 var handler = eventHandlers[CLOSED_EVENT]; | |
| 566 if (handler == null) return; | |
| 567 handler(); | |
| 568 } | |
| 569 return; | |
| 570 } | |
| 571 var handler = eventHandlers[READ_EVENT]; | |
| 572 if (handler == null) return; | |
| 573 readEventIssued = true; | |
| 574 handler(); | |
| 575 scheduleMicrotask(issue); | |
| 576 } | |
| 577 scheduleMicrotask(issue); | |
| 578 } | |
| 579 | |
| 580 void issueWriteEvent({bool delayed: true}) { | |
| 581 if (writeEventIssued) return; | |
| 582 if (!writeAvailable) return; | |
| 583 void issue() { | |
| 584 writeEventIssued = false; | |
| 585 if (!writeAvailable) return; | |
| 586 if (isClosing) return; | |
| 587 if (!sendWriteEvents) return; | |
| 588 sendWriteEvents = false; | |
| 589 var handler = eventHandlers[WRITE_EVENT]; | |
| 590 if (handler == null) return; | |
| 591 handler(); | |
| 592 } | |
| 593 if (delayed) { | |
| 594 writeEventIssued = true; | |
| 595 scheduleMicrotask(issue); | |
| 596 } else { | |
| 597 issue(); | |
| 598 } | |
| 599 } | |
| 600 | |
| 557 // Multiplexes socket events to the socket handlers. | 601 // Multiplexes socket events to the socket handlers. |
| 558 void multiplex(int events) { | 602 void multiplex(int events) { |
| 559 canActivateEvents = false; | |
| 560 for (int i = FIRST_EVENT; i <= LAST_EVENT; i++) { | 603 for (int i = FIRST_EVENT; i <= LAST_EVENT; i++) { |
| 561 if (((events & (1 << i)) != 0)) { | 604 if (((events & (1 << i)) != 0)) { |
| 562 if ((i == CLOSED_EVENT || i == READ_EVENT) && isClosedRead) continue; | 605 if ((i == CLOSED_EVENT || i == READ_EVENT) && isClosedRead) continue; |
| 606 if (isClosing && i != DESTROYED_EVENT) continue; | |
| 563 if (i == CLOSED_EVENT && | 607 if (i == CLOSED_EVENT && |
| 564 typeFlags != TYPE_LISTENING_SOCKET && | 608 typeFlags != TYPE_LISTENING_SOCKET && |
| 565 !isClosing && | 609 !isClosing && |
| 566 !isClosed) { | 610 !isClosed) { |
| 567 isClosedRead = true; | 611 isClosedRead = true; |
| 612 issueReadEvent(); | |
| 613 continue; | |
| 614 } | |
| 615 | |
| 616 if (i == WRITE_EVENT) { | |
| 617 writeAvailable = true; | |
| 618 issueWriteEvent(delayed: false); | |
| 619 continue; | |
| 620 } | |
| 621 | |
| 622 if (i == READ_EVENT && | |
| 623 typeFlags != TYPE_LISTENING_SOCKET) { | |
| 624 var avail = nativeAvailable(); | |
| 625 if (avail is int) { | |
| 626 available = avail; | |
| 627 } else { | |
| 628 // Available failed. Mark socket as having data, to ensure read | |
| 629 // events, and thus reporting of this error. | |
| 630 available = 1; | |
| 631 } | |
| 632 issueReadEvent(); | |
|
Søren Gjesse
2014/02/18 14:28:00
Why is there no "delayed: false" for this as well?
Anders Johnsen
2014/02/19 09:43:03
It's always delayed. If it wasn't I was having tro
| |
| 633 continue; | |
| 568 } | 634 } |
| 569 | 635 |
| 570 var handler = eventHandlers[i]; | 636 var handler = eventHandlers[i]; |
| 571 if (i == DESTROYED_EVENT) { | 637 if (i == DESTROYED_EVENT) { |
| 572 assert(!isClosed); | 638 assert(!isClosed); |
| 573 isClosed = true; | 639 isClosed = true; |
| 574 closeCompleter.complete(); | 640 closeCompleter.complete(); |
| 575 disconnectFromEventHandler(); | 641 disconnectFromEventHandler(); |
| 576 if (handler != null) handler(); | 642 if (handler != null) handler(); |
| 577 continue; | 643 continue; |
| 578 } | 644 } |
| 579 assert(handler != null); | |
| 580 if (i == WRITE_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. | |
| 583 if ((eventMask & (1 << i)) == 0) continue; | |
| 584 // Unregister the out handler before executing it. There is | |
| 585 // no need to notify the eventhandler as handlers are | |
| 586 // disabled while the event is handled. | |
| 587 eventMask &= ~(1 << i); | |
| 588 } | |
| 589 | 645 |
| 590 // Don't call the in handler if there is no data available | |
| 591 // after all. | |
| 592 if (i == READ_EVENT && | |
| 593 typeFlags != TYPE_LISTENING_SOCKET && | |
| 594 available() == 0) { | |
| 595 continue; | |
| 596 } | |
| 597 if (i == ERROR_EVENT) { | 646 if (i == ERROR_EVENT) { |
| 598 if (!isClosing) { | 647 if (!isClosing) { |
| 599 reportError(nativeGetError(), ""); | 648 reportError(nativeGetError(), ""); |
| 600 } | 649 } |
| 601 } else if (!isClosed) { | 650 } else if (!isClosed) { |
| 602 // If the connection is closed right after it's accepted, there's a | 651 // If the connection is closed right after it's accepted, there's a |
| 603 // chance the close-handler is not set. | 652 // chance the close-handler is not set. |
| 604 if (handler != null) handler(); | 653 if (handler != null) handler(); |
| 605 } | 654 } |
| 606 } | 655 } |
| 607 } | 656 } |
| 608 if (isClosedRead && isClosedWrite) close(); | |
| 609 canActivateEvents = true; | |
| 610 activateHandlers(); | |
| 611 } | 657 } |
| 612 | 658 |
| 613 void setHandlers({read, write, error, closed, destroyed}) { | 659 void setHandlers({read, write, error, closed, destroyed}) { |
| 614 eventHandlers[READ_EVENT] = read; | 660 eventHandlers[READ_EVENT] = read; |
| 615 eventHandlers[WRITE_EVENT] = write; | 661 eventHandlers[WRITE_EVENT] = write; |
| 616 eventHandlers[ERROR_EVENT] = error; | 662 eventHandlers[ERROR_EVENT] = error; |
| 617 eventHandlers[CLOSED_EVENT] = closed; | 663 eventHandlers[CLOSED_EVENT] = closed; |
| 618 eventHandlers[DESTROYED_EVENT] = destroyed; | 664 eventHandlers[DESTROYED_EVENT] = destroyed; |
| 619 } | 665 } |
| 620 | 666 |
| 621 void setListening({read: true, write: true}) { | 667 void setListening({read: true, write: true}) { |
| 622 eventMask = (1 << CLOSED_EVENT) | (1 << ERROR_EVENT); | 668 sendReadEvents = read; |
| 623 if (read) eventMask |= (1 << READ_EVENT); | 669 sendWriteEvents = write; |
| 624 if (write) eventMask |= (1 << WRITE_EVENT); | 670 if (read) issueReadEvent(); |
| 625 activateHandlers(); | 671 if (write) issueWriteEvent(); |
| 626 } | 672 if (eventPort == null) { |
| 627 | 673 int flags = typeFlags; |
| 628 | 674 if (!isClosedRead) flags |= 1 << READ_EVENT; |
| 629 void activateHandlers() { | 675 if (!isClosedWrite) flags |= 1 << WRITE_EVENT; |
| 630 if (canActivateEvents && !isClosing && !isClosed) { | 676 sendToEventHandler(flags); |
| 631 if ((eventMask & ((1 << READ_EVENT) | (1 << WRITE_EVENT))) == 0) { | |
| 632 // If we don't listen for either read or write, disconnect as we won't | |
| 633 // get close and error events anyway. | |
| 634 if (eventPort != null) disconnectFromEventHandler(); | |
| 635 } else { | |
| 636 int data = eventMask; | |
| 637 if (isClosedRead) data &= ~(1 << READ_EVENT); | |
| 638 if (isClosedWrite) data &= ~(1 << WRITE_EVENT); | |
| 639 data |= typeFlags; | |
| 640 sendToEventHandler(data); | |
| 641 } | |
| 642 } | 677 } |
| 643 } | 678 } |
| 644 | 679 |
| 645 Future close() { | 680 Future close() { |
| 646 if (!isClosing && !isClosed) { | 681 if (!isClosing && !isClosed) { |
| 647 sendToEventHandler(1 << CLOSE_COMMAND); | 682 sendToEventHandler(1 << CLOSE_COMMAND); |
| 648 isClosing = true; | 683 isClosing = true; |
| 649 } | 684 } |
| 650 return closeCompleter.future; | 685 return closeCompleter.future; |
| 651 } | 686 } |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 666 throw new ArgumentError(direction); | 701 throw new ArgumentError(direction); |
| 667 } | 702 } |
| 668 } | 703 } |
| 669 } | 704 } |
| 670 | 705 |
| 671 void shutdownWrite() { | 706 void shutdownWrite() { |
| 672 if (!isClosing && !isClosed) { | 707 if (!isClosing && !isClosed) { |
| 673 if (isClosedRead) { | 708 if (isClosedRead) { |
| 674 close(); | 709 close(); |
| 675 } else { | 710 } else { |
| 676 bool connected = eventPort != null; | |
| 677 sendToEventHandler(1 << SHUTDOWN_WRITE_COMMAND); | 711 sendToEventHandler(1 << SHUTDOWN_WRITE_COMMAND); |
| 678 if (!connected) disconnectFromEventHandler(); | |
| 679 } | 712 } |
| 680 isClosedWrite = true; | 713 isClosedWrite = true; |
| 681 } | 714 } |
| 682 } | 715 } |
| 683 | 716 |
| 684 void shutdownRead() { | 717 void shutdownRead() { |
| 685 if (!isClosing && !isClosed) { | 718 if (!isClosing && !isClosed) { |
| 686 if (isClosedWrite) { | 719 if (isClosedWrite) { |
| 687 close(); | 720 close(); |
| 688 } else { | 721 } else { |
| 689 bool connected = eventPort != null; | |
| 690 sendToEventHandler(1 << SHUTDOWN_READ_COMMAND); | 722 sendToEventHandler(1 << SHUTDOWN_READ_COMMAND); |
| 691 if (!connected) disconnectFromEventHandler(); | |
| 692 } | 723 } |
| 693 isClosedRead = true; | 724 isClosedRead = true; |
| 694 } | 725 } |
| 695 } | 726 } |
| 696 | 727 |
| 697 void sendToEventHandler(int data) { | 728 void sendToEventHandler(int data) { |
| 729 assert(!isClosed); | |
| 698 connectToEventHandler(); | 730 connectToEventHandler(); |
| 699 assert(!isClosed); | |
| 700 _EventHandler._sendData(this, eventPort, data); | 731 _EventHandler._sendData(this, eventPort, data); |
| 701 } | 732 } |
| 702 | 733 |
| 703 void connectToEventHandler() { | 734 void connectToEventHandler() { |
| 704 if (eventPort == null) { | 735 if (eventPort == null) { |
| 705 eventPort = new RawReceivePort(multiplex); | 736 eventPort = new RawReceivePort(multiplex); |
| 706 } | 737 } |
| 707 } | 738 } |
| 708 | 739 |
| 709 void disconnectFromEventHandler() { | 740 void disconnectFromEventHandler() { |
| 710 if (eventPort != null) { | 741 assert(eventPort != null); |
| 711 eventPort.close(); | 742 eventPort.close(); |
| 712 eventPort = null; | 743 eventPort = null; |
| 713 } | |
| 714 } | 744 } |
| 715 | 745 |
| 716 // Check whether this is an error response from a native port call. | 746 // Check whether this is an error response from a native port call. |
| 717 static bool isErrorResponse(response) { | 747 static bool isErrorResponse(response) { |
| 718 return response is List && response[0] != _SUCCESS_RESPONSE; | 748 return response is List && response[0] != _SUCCESS_RESPONSE; |
| 719 } | 749 } |
| 720 | 750 |
| 721 // Create the appropriate error/exception from different returned | 751 // Create the appropriate error/exception from different returned |
| 722 // error objects. | 752 // error objects. |
| 723 static createError(error, | 753 static createError(error, |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 861 | 891 |
| 862 _RawServerSocket(this._socket) { | 892 _RawServerSocket(this._socket) { |
| 863 var zone = Zone.current; | 893 var zone = Zone.current; |
| 864 _controller = new StreamController(sync: true, | 894 _controller = new StreamController(sync: true, |
| 865 onListen: _onSubscriptionStateChange, | 895 onListen: _onSubscriptionStateChange, |
| 866 onCancel: _onSubscriptionStateChange, | 896 onCancel: _onSubscriptionStateChange, |
| 867 onPause: _onPauseStateChange, | 897 onPause: _onPauseStateChange, |
| 868 onResume: _onPauseStateChange); | 898 onResume: _onPauseStateChange); |
| 869 _socket.setHandlers( | 899 _socket.setHandlers( |
| 870 read: zone.bindCallback(() { | 900 read: zone.bindCallback(() { |
| 871 var socket = _socket.accept(); | 901 do { |
| 872 if (socket != null) _controller.add(new _RawSocket(socket)); | 902 var socket = _socket.accept(); |
| 903 if (socket == null) return; | |
| 904 _controller.add(new _RawSocket(socket)); | |
| 905 } while (!_controller.isPaused); | |
| 873 }), | 906 }), |
| 874 error: zone.bindUnaryCallback((e) { | 907 error: zone.bindUnaryCallback((e) { |
| 875 _controller.addError(e); | 908 _controller.addError(e); |
| 876 _controller.close(); | 909 _controller.close(); |
| 877 }), | 910 }), |
| 878 destroyed: _controller.close | 911 destroyed: _controller.close |
| 879 ); | 912 ); |
| 880 } | 913 } |
| 881 | 914 |
| 882 StreamSubscription<RawSocket> listen(void onData(RawSocket event), | 915 StreamSubscription<RawSocket> listen(void onData(RawSocket event), |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 985 {Function onError, | 1018 {Function onError, |
| 986 void onDone(), | 1019 void onDone(), |
| 987 bool cancelOnError}) { | 1020 bool cancelOnError}) { |
| 988 return _controller.stream.listen( | 1021 return _controller.stream.listen( |
| 989 onData, | 1022 onData, |
| 990 onError: onError, | 1023 onError: onError, |
| 991 onDone: onDone, | 1024 onDone: onDone, |
| 992 cancelOnError: cancelOnError); | 1025 cancelOnError: cancelOnError); |
| 993 } | 1026 } |
| 994 | 1027 |
| 995 int available() => _socket.available(); | 1028 int available() => _socket.available; |
| 996 | 1029 |
| 997 List<int> read([int len]) { | 1030 List<int> read([int len]) { |
| 998 if (_isMacOSTerminalInput) { | 1031 if (_isMacOSTerminalInput) { |
| 999 var available = this.available(); | 1032 var available = this.available(); |
| 1000 if (available == 0) return null; | 1033 if (available == 0) return null; |
| 1001 var data = _socket.read(len); | 1034 var data = _socket.read(len); |
| 1002 if (data == null || data.length < available) { | 1035 if (data == null || data.length < available) { |
| 1003 // Reading less than available from a Mac OS terminal indicate Ctrl-D. | 1036 // Reading less than available from a Mac OS terminal indicate Ctrl-D. |
| 1004 // This is interpreted as read closed. | 1037 // This is interpreted as read closed. |
| 1005 scheduleMicrotask(() => _controller.add(RawSocketEvent.READ_CLOSED)); | 1038 scheduleMicrotask(() => _controller.add(RawSocketEvent.READ_CLOSED)); |
| (...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1550 | 1583 |
| 1551 Datagram _makeDatagram(List<int> data, | 1584 Datagram _makeDatagram(List<int> data, |
| 1552 String address, | 1585 String address, |
| 1553 List<int> in_addr, | 1586 List<int> in_addr, |
| 1554 int port) { | 1587 int port) { |
| 1555 return new Datagram( | 1588 return new Datagram( |
| 1556 data, | 1589 data, |
| 1557 new _InternetAddress(address, null, in_addr), | 1590 new _InternetAddress(address, null, in_addr), |
| 1558 port); | 1591 port); |
| 1559 } | 1592 } |
| OLD | NEW |