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

Unified Diff: runtime/bin/socket_impl.dart

Issue 11337019: Use patching for dart:io. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments Created 8 years, 2 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 side-by-side diff with in-line comments
Download patch
Index: runtime/bin/socket_impl.dart
diff --git a/runtime/bin/socket_impl.dart b/runtime/bin/socket_impl.dart
deleted file mode 100644
index 8594afaef0b5eda58f2d2ec2d32a902dc4cf9b7e..0000000000000000000000000000000000000000
--- a/runtime/bin/socket_impl.dart
+++ /dev/null
@@ -1,582 +0,0 @@
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-
-class _SocketBase extends NativeFieldWrapperClass1 {
- // Bit flags used when communicating between the eventhandler and
- // dart code. The EVENT flags are used to indicate events of
- // interest when sending a message from dart code to the
- // eventhandler. When receiving a message from the eventhandler the
- // EVENT flags indicate the events that actually happened. The
- // COMMAND flags are used to send commands from dart to the
- // eventhandler. COMMAND flags are never received from the
- // eventhandler. Additional flags are used to communicate other
- // information.
- static const int _IN_EVENT = 0;
- static const int _OUT_EVENT = 1;
- static const int _ERROR_EVENT = 2;
- static const int _CLOSE_EVENT = 3;
-
- static const int _CLOSE_COMMAND = 8;
- static const int _SHUTDOWN_READ_COMMAND = 9;
- static const int _SHUTDOWN_WRITE_COMMAND = 10;
-
- // Flag send to the eventhandler providing additional information on
- // the type of the file descriptor.
- static const int _LISTENING_SOCKET = 16;
- static const int _PIPE = 17;
-
- static const int _FIRST_EVENT = _IN_EVENT;
- static const int _LAST_EVENT = _CLOSE_EVENT;
-
- static const int _FIRST_COMMAND = _CLOSE_COMMAND;
- static const int _LAST_COMMAND = _SHUTDOWN_WRITE_COMMAND;
-
- _SocketBase () {
- _handlerMap = new List(_LAST_EVENT + 1);
- _handlerMask = 0;
- _canActivateHandlers = true;
- _closed = true;
- _EventHandler._start();
- _hashCode = _nextHashCode;
- _nextHashCode = (_nextHashCode + 1) & 0xFFFFFFF;
- }
-
- // Multiplexes socket events to the socket handlers.
- void _multiplex(int event_mask) {
- _canActivateHandlers = false;
- for (int i = _FIRST_EVENT; i <= _LAST_EVENT; i++) {
- if (((event_mask & (1 << i)) != 0)) {
- if ((i == _CLOSE_EVENT) && this is _Socket && !_closed) {
- _closedRead = true;
- if (_closedWrite) _close();
- }
-
- var eventHandler = _handlerMap[i];
- if (eventHandler != null || i == _ERROR_EVENT) {
- // Unregister the out handler before executing it.
- if (i == _OUT_EVENT) _setHandler(i, null);
-
- // Don't call the in handler if there is no data available
- // after all.
- if ((i == _IN_EVENT) && (this is _Socket) && (available() == 0)) {
- continue;
- }
- if (i == _ERROR_EVENT) {
- _reportError(_getError(), "");
- close();
- } else {
- eventHandler();
- }
- }
- }
- }
- _canActivateHandlers = true;
- _activateHandlers();
- }
-
- void _setHandler(int event, Function callback) {
- if (callback == null) {
- _handlerMask &= ~(1 << event);
- } else {
- _handlerMask |= (1 << event);
- }
- _handlerMap[event] = callback;
- // If the socket is only for writing then close the receive port
- // when not waiting for any events.
- if (this is _Socket &&
- _closedRead &&
- _handlerMask == 0 &&
- _handler != null) {
- _handler.close();
- _handler = null;
- } else {
- _activateHandlers();
- }
- }
-
- OSError _getError() native "Socket_GetError";
- int _getPort() native "Socket_GetPort";
-
- void set onError(void callback(e)) {
- _setHandler(_ERROR_EVENT, callback);
- }
-
- void _activateHandlers() {
- if (_canActivateHandlers && !_closed) {
- if (_handlerMask == 0) {
- if (_handler != null) {
- _handler.close();
- _handler = null;
- }
- return;
- }
- int data = _handlerMask;
- if (_isListenSocket()) {
- data |= (1 << _LISTENING_SOCKET);
- } else {
- if (_closedRead) { data &= ~(1 << _IN_EVENT); }
- if (_closedWrite) { data &= ~(1 << _OUT_EVENT); }
- if (_isPipe()) data |= (1 << _PIPE);
- }
- _sendToEventHandler(data);
- }
- }
-
- int get port {
- if (_port === null) {
- _port = _getPort();
- }
- return _port;
- }
-
- void close([bool halfClose = false]) {
- if (!_closed) {
- if (halfClose) {
- _closeWrite();
- } else {
- _close();
- }
- } else if (_handler != null) {
- // This is to support closing sockets created but never assigned
- // any actual socket.
- _handler.close();
- _handler = null;
- }
- }
-
- void _closeWrite() {
- if (!_closed) {
- if (_closedRead) {
- _close();
- } else {
- _sendToEventHandler(1 << _SHUTDOWN_WRITE_COMMAND);
- }
- _closedWrite = true;
- }
- }
-
- void _closeRead() {
- if (!_closed) {
- if (_closedWrite) {
- _close();
- } else {
- _sendToEventHandler(1 << _SHUTDOWN_READ_COMMAND);
- }
- _closedRead = true;
- }
- }
-
- void _close() {
- if (!_closed) {
- _sendToEventHandler(1 << _CLOSE_COMMAND);
- _handler.close();
- _handler = null;
- _closed = true;
- }
- }
-
- void _sendToEventHandler(int data) {
- if (_handler === null) {
- _handler = new ReceivePort();
- _handler.receive((var message, ignored) { _multiplex(message); });
- }
- assert(!_closed);
- _EventHandler._sendData(this, _handler, data);
- }
-
- bool _reportError(error, String message) {
- void doReportError(Exception e) {
- // Invoke the socket error callback if any.
- bool reported = false;
- if (_handlerMap[_ERROR_EVENT] != null) {
- _handlerMap[_ERROR_EVENT](e);
- reported = true;
- }
- // Propagate the error to any additional listeners.
- reported = reported || _propagateError(e);
- if (!reported) throw e;
- }
-
- // For all errors we close the socket, call the error handler and
- // disable further calls of the error handler.
- close();
- if (error is OSError) {
- doReportError(new SocketIOException(message, error));
- } else if (error is List) {
- assert(_isErrorResponse(error));
- switch (error[0]) {
- case _ILLEGAL_ARGUMENT_RESPONSE:
- doReportError(new ArgumentError());
- break;
- case _OSERROR_RESPONSE:
- doReportError(new SocketIOException(
- message, new OSError(error[2], error[1])));
- break;
- default:
- doReportError(new Exception("Unknown error"));
- break;
- }
- } else {
- doReportError(new SocketIOException(message));
- }
- }
-
- int get hashCode => _hashCode;
-
- bool _propagateError(Exception e) => false;
-
- abstract bool _isListenSocket();
- abstract bool _isPipe();
-
- // Is this socket closed.
- bool _closed;
-
- // Dedicated ReceivePort for socket events.
- ReceivePort _handler;
-
- // Poll event to handler map.
- List _handlerMap;
-
- // Indicates for which poll events the socket registered handlers.
- int _handlerMask;
-
- // Indicates if native interrupts can be activated.
- bool _canActivateHandlers;
-
- // Holds the port of the socket, null if not known.
- int _port;
-
- // Hash code for the socket. Currently this is just a counter.
- int _hashCode;
- static int _nextHashCode = 0;
- bool _closedRead = false;
- bool _closedWrite = false;
-}
-
-
-class _ServerSocket extends _SocketBase implements ServerSocket {
- // Constructor for server socket. First a socket object is allocated
- // in which the native socket is stored. After that _createBind
- // is called which creates a file descriptor and binds the given address
- // and port to the socket. Null is returned if file descriptor creation or
- // bind failed.
- factory _ServerSocket(String bindAddress, int port, int backlog) {
- _ServerSocket socket = new _ServerSocket._internal();
- var result = socket._createBindListen(bindAddress, port, backlog);
- if (result is OSError) {
- socket.close();
- throw new SocketIOException("Failed to create server socket", result);
- }
- socket._closed = false;
- assert(result);
- if (port != 0) {
- socket._port = port;
- }
- return socket;
- }
-
- _ServerSocket._internal();
-
- _accept(Socket socket) native "ServerSocket_Accept";
-
- _createBindListen(String bindAddress, int port, int backlog)
- native "ServerSocket_CreateBindListen";
-
- void set onConnection(void callback(Socket connection)) {
- _clientConnectionHandler = callback;
- _setHandler(_SocketBase._IN_EVENT,
- _clientConnectionHandler != null ? _connectionHandler : null);
- }
-
- void _connectionHandler() {
- if (!_closed) {
- _Socket socket = new _Socket._internal();
- var result = _accept(socket);
- if (result is OSError) {
- _reportError(result, "Accept failed");
- } else if (result) {
- socket._closed = false;
- _clientConnectionHandler(socket);
- } else {
- // Temporary failure accepting the connection. Ignoring
- // temporary failures lets us retry when we wake up with data
- // on the listening socket again.
- }
- }
- }
-
- bool _isListenSocket() => true;
- bool _isPipe() => false;
-
- var _clientConnectionHandler;
-}
-
-
-class _Socket extends _SocketBase implements Socket {
- static const HOST_NAME_LOOKUP = 0;
-
- // Constructs a new socket. During the construction an asynchronous
- // host name lookup is initiated. The returned socket is not yet
- // connected but ready for registration of callbacks.
- factory _Socket(String host, int port) {
- Socket socket = new _Socket._internal();
- _ensureSocketService();
- List request = new List(2);
- request[0] = HOST_NAME_LOOKUP;
- request[1] = host;
- _socketService.call(request).then((response) {
- if (socket._isErrorResponse(response)) {
- socket._reportError(response, "Failed host name lookup");
- } else{
- var result = socket._createConnect(response, port);
- if (result is OSError) {
- socket.close();
- socket._reportError(result, "Connection failed");
- } else {
- socket._closed = false;
- socket._activateHandlers();
- }
- }
- });
- return socket;
- }
-
- _Socket._internal();
- _Socket._internalReadOnly() : _pipe = true { super._closedWrite = true; }
- _Socket._internalWriteOnly() : _pipe = true { super._closedRead = true; }
-
- int available() {
- if (!_closed) {
- var result = _available();
- if (result is OSError) {
- _reportError(result, "Available failed");
- return 0;
- } else {
- return result;
- }
- }
- throw new
- SocketIOException("Error: available failed - invalid socket handle");
- }
-
- _available() native "Socket_Available";
-
- int readList(List<int> buffer, int offset, int bytes) {
- if (!_closed) {
- if (bytes == 0) {
- return 0;
- }
- if (offset < 0) {
- throw new IndexOutOfRangeException(offset);
- }
- if (bytes < 0) {
- throw new IndexOutOfRangeException(bytes);
- }
- if ((offset + bytes) > buffer.length) {
- throw new IndexOutOfRangeException(offset + bytes);
- }
- var result = _readList(buffer, offset, bytes);
- if (result is OSError) {
- _reportError(result, "Read failed");
- return -1;
- }
- return result;
- }
- throw new
- SocketIOException("Error: readList failed - invalid socket handle");
- }
-
- _readList(List<int> buffer, int offset, int bytes) native "Socket_ReadList";
-
- int writeList(List<int> buffer, int offset, int bytes) {
- if (buffer is! List || offset is! int || bytes is! int) {
- throw new ArgumentError(
- "Invalid arguments to writeList on Socket");
- }
- if (!_closed) {
- if (bytes == 0) {
- return 0;
- }
- if (offset < 0) {
- throw new IndexOutOfRangeException(offset);
- }
- if (bytes < 0) {
- throw new IndexOutOfRangeException(bytes);
- }
- if ((offset + bytes) > buffer.length) {
- throw new IndexOutOfRangeException(offset + bytes);
- }
- _BufferAndOffset bufferAndOffset =
- _ensureFastAndSerializableBuffer(buffer, offset, bytes);
- var result =
- _writeList(bufferAndOffset.buffer, bufferAndOffset.offset, bytes);
- if (result is OSError) {
- _reportError(result, "Write failed");
- // If writing fails we return 0 as the number of bytes and
- // report the error on the error handler.
- result = 0;
- }
- return result;
- }
- throw new SocketIOException("writeList failed - invalid socket handle");
- }
-
- _writeList(List<int> buffer, int offset, int bytes)
- native "Socket_WriteList";
-
- bool _isErrorResponse(response) {
- return response is List && response[0] != _SUCCESS_RESPONSE;
- }
-
- bool _createConnect(String host, int port) native "Socket_CreateConnect";
-
- void set onWrite(void callback()) {
- if (_outputStream != null) throw new StreamException(
- "Cannot set write handler when output stream is used");
- _clientWriteHandler = callback;
- _updateOutHandler();
- }
-
- void set onConnect(void callback()) {
- if (_seenFirstOutEvent || _outputStream != null) {
- throw new StreamException(
- "Cannot set connect handler when already connected");
- }
- if (_outputStream != null) {
- throw new StreamException(
- "Cannot set connect handler when output stream is used");
- }
- _clientConnectHandler = callback;
- _updateOutHandler();
- }
-
- void set onData(void callback()) {
- if (_inputStream != null) throw new StreamException(
- "Cannot set data handler when input stream is used");
- _onData = callback;
- }
-
- void set onClosed(void callback()) {
- if (_inputStream != null) throw new StreamException(
- "Cannot set close handler when input stream is used");
- _onClosed = callback;
- }
-
- bool _isListenSocket() => false;
-
- bool _isPipe() => _pipe;
-
- InputStream get inputStream {
- if (_inputStream == null) {
- if (_handlerMap[_SocketBase._IN_EVENT] !== null ||
- _handlerMap[_SocketBase._CLOSE_EVENT] !== null) {
- throw new StreamException(
- "Cannot get input stream when socket handlers are used");
- }
- _inputStream = new _SocketInputStream(this);
- }
- return _inputStream;
- }
-
- OutputStream get outputStream {
- if (_outputStream == null) {
- if (_handlerMap[_SocketBase._OUT_EVENT] !== null) {
- throw new StreamException(
- "Cannot get input stream when socket handlers are used");
- }
- _outputStream = new _SocketOutputStream(this);
- }
- return _outputStream;
- }
-
- void set _onWrite(void callback()) {
- _setHandler(_SocketBase._OUT_EVENT, callback);
- }
-
- void set _onData(void callback()) {
- _setHandler(_SocketBase._IN_EVENT, callback);
- }
-
- void set _onClosed(void callback()) {
- _setHandler(_SocketBase._CLOSE_EVENT, callback);
- }
-
- bool _propagateError(Exception e) {
- bool reported = false;
- if (_inputStream != null) {
- reported = reported || _inputStream._onSocketError(e);
- }
- if (_outputStream != null) {
- reported = reported || _outputStream._onSocketError(e);
- }
- return reported;
- }
-
- void _updateOutHandler() {
- void firstWriteHandler() {
- assert(!_seenFirstOutEvent);
- _seenFirstOutEvent = true;
-
- // From now on the write handler is only the client write
- // handler (connect handler cannot be called again). Change this
- // before calling any handlers as handlers can change the
- // handlers.
- if (_clientWriteHandler === null) _onWrite = _clientWriteHandler;
-
- // First out event is socket connected event.
- if (_clientConnectHandler !== null) _clientConnectHandler();
- _clientConnectHandler = null;
-
- // Always (even for the first out event) call the write handler.
- if (_clientWriteHandler !== null) _clientWriteHandler();
- }
-
- if (_clientConnectHandler === null && _clientWriteHandler === null) {
- _onWrite = null;
- } else {
- if (_seenFirstOutEvent) {
- _onWrite = _clientWriteHandler;
- } else {
- _onWrite = firstWriteHandler;
- }
- }
- }
-
- int get remotePort {
- if (_remotePort === null) {
- remoteHost;
- }
- return _remotePort;
- }
-
- String get remoteHost {
- if (_remoteHost === null) {
- List peer = _getRemotePeer();
- _remoteHost = peer[0];
- _remotePort = peer[1];
- }
- return _remoteHost;
- }
-
- List _getRemotePeer() native "Socket_GetRemotePeer";
-
- static SendPort _newServicePort() native "Socket_NewServicePort";
-
- static void _ensureSocketService() {
- if (_socketService == null) {
- _socketService = _Socket._newServicePort();
- }
- }
-
- bool _seenFirstOutEvent = false;
- bool _pipe = false;
- Function _clientConnectHandler;
- Function _clientWriteHandler;
- _SocketInputStream _inputStream;
- _SocketOutputStream _outputStream;
- String _remoteHost;
- int _remotePort;
- static SendPort _socketService;
-}

Powered by Google App Engine
This is Rietveld 408576698