Index: runtime/bin/socket_impl.dart |
diff --git a/runtime/bin/socket_impl.dart b/runtime/bin/socket_impl.dart |
index 7b948d124a9d4db4d555581438d2c799edb114f1..ef909cac57cbe264b790a355c29c267da0d13352 100644 |
--- a/runtime/bin/socket_impl.dart |
+++ b/runtime/bin/socket_impl.dart |
@@ -22,9 +22,10 @@ class _SocketBase { |
static final int _SHUTDOWN_READ_COMMAND = 9; |
static final int _SHUTDOWN_WRITE_COMMAND = 10; |
- // Flag send to the eventhandler saying that the file descriptor in |
- // question represents a listening socket. |
+ // Flag send to the eventhandler providing additional information on |
+ // the type of the file descriptor. |
static final int _LISTENING_SOCKET = 16; |
+ static final int _PIPE = 17; |
static final int _FIRST_EVENT = _IN_EVENT; |
static final int _LAST_EVENT = _CLOSE_EVENT; |
@@ -33,20 +34,14 @@ class _SocketBase { |
static final int _LAST_COMMAND = _SHUTDOWN_WRITE_COMMAND; |
_SocketBase () { |
- _handler = new ReceivePort(); |
_handlerMap = new List(_LAST_EVENT + 1); |
_handlerMask = 0; |
_canActivateHandlers = true; |
_id = -1; |
- _handler.receive((var message, ignored) { |
- _multiplex(message); |
- }); |
EventHandler._start(); |
} |
- /* |
- * Multiplexes socket events to the right socket handler. |
- */ |
+ // Multiplexes socket events to the socket handlers. |
void _multiplex(List<int> message) { |
assert(message.length == 1); |
_canActivateHandlers = false; |
@@ -83,7 +78,17 @@ class _SocketBase { |
_handlerMask |= (1 << event); |
} |
_handlerMap[event] = callback; |
- _activateHandlers(); |
+ // 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(); |
+ } |
} |
void _getPort() native "Socket_GetPort"; |
@@ -100,16 +105,12 @@ class _SocketBase { |
} else { |
if (_closedRead) { data &= ~(1 << _IN_EVENT); } |
if (_closedWrite) { data &= ~(1 << _OUT_EVENT); } |
- if (_isListenSocket()) data |= (1 << _LISTENING_SOCKET); |
Mads Ager (google)
2011/11/14 14:14:23
Good catch. :)
|
+ if (_isPipe()) data |= (1 << _PIPE); |
} |
- EventHandler._sendData(_id, _handler, data); |
+ _sendToEventHandler(data); |
} |
} |
- void _scheduleEvent(int event) { |
- _handler.toSendPort().send([1 << event], null); |
- } |
- |
int get port() { |
if (_port === null) { |
_port = _getPort(); |
@@ -136,7 +137,7 @@ class _SocketBase { |
if (_closedRead) { |
_close(); |
} else { |
- EventHandler._sendData(_id, _handler, 1 << _SHUTDOWN_WRITE_COMMAND); |
+ _sendToEventHandler(1 << _SHUTDOWN_WRITE_COMMAND); |
} |
_closedWrite = true; |
} |
@@ -145,19 +146,28 @@ class _SocketBase { |
if (_closedWrite) { |
_close(); |
} else { |
- EventHandler._sendData(_id, _handler, 1 << _SHUTDOWN_READ_COMMAND); |
+ _sendToEventHandler(1 << _SHUTDOWN_READ_COMMAND); |
} |
_closedRead = true; |
} |
void _close() { |
- EventHandler._sendData(_id, _handler, 1 << _CLOSE_COMMAND); |
+ _sendToEventHandler(1 << _CLOSE_COMMAND); |
_handler.close(); |
_handler = null; |
_id = -1; |
} |
+ void _sendToEventHandler(int data) { |
+ if (_handler === null) { |
+ _handler = new ReceivePort(); |
+ _handler.receive((var message, ignored) { _multiplex(message); }); |
+ } |
+ EventHandler._sendData(_id, _handler, data); |
+ } |
+ |
abstract bool _isListenSocket(); |
+ abstract bool _isPipe(); |
/* |
* Socket id is set from native. -1 indicates that the socket was closed. |
@@ -235,6 +245,7 @@ class _ServerSocket extends _SocketBase implements ServerSocket { |
} |
bool _isListenSocket() => true; |
+ bool _isPipe() => false; |
} |
@@ -256,8 +267,8 @@ class _Socket extends _SocketBase implements Socket { |
} |
_Socket._internal(); |
- _Socket._internalReadOnly() : _closedWrite = true; |
- _Socket._internalWriteOnly() : _closedRead = true; |
+ _Socket._internalReadOnly() : _closedWrite = true, _pipe = true; |
+ _Socket._internalWriteOnly() : _closedRead = true, _pipe = true; |
int available() { |
if (_id >= 0) { |
@@ -336,6 +347,7 @@ class _Socket extends _SocketBase implements Socket { |
} |
bool _isListenSocket() => false; |
+ bool _isPipe() => _pipe; |
InputStream get inputStream() { |
if (_inputStream === null) { |
@@ -353,6 +365,7 @@ class _Socket extends _SocketBase implements Socket { |
bool _closedRead = false; |
bool _closedWrite = false; |
+ bool _pipe = false; |
SocketInputStream _inputStream; |
SocketOutputStream _outputStream; |
} |