| // Copyright (c) 2015, 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. |
| |
| /// A multiplexing [RawReceivePort]. |
| /// |
| /// Allows creating a number of [RawReceivePort] implementations that all send |
| /// messages through the same real `RawReceivePort`. |
| /// |
| /// This allows reducing the number of receive ports created, but adds an |
| /// overhead to each message. |
| /// If a library creates many short-lived receive ports, multiplexing might be |
| /// faster. |
| /// |
| /// To use multiplexing receive ports, create and store a |
| /// [RawReceivePortMultiplexer], and create receive ports by calling |
| /// `multiplexer.createRawReceivePort(handler)` where you would otherwise |
| /// write `new RawReceivePort(handler)`. |
| /// |
| /// Remember to [close] the multiplexer when it is no longer needed. |
| /// |
| /// (TODO: Check if it really is faster - creating a receive port requires a |
| /// global mutex, so it may be a bottleneck, but it's not clear how slow it is). |
| library isolate.raw_receive_port_multiplexer; |
| |
| import "dart:collection"; |
| import "dart:isolate"; |
| |
| import "util.dart"; |
| |
| class _MultiplexRawReceivePort implements RawReceivePort { |
| final RawReceivePortMultiplexer _multiplexer; |
| final int _id; |
| Function _handler; |
| |
| _MultiplexRawReceivePort(this._multiplexer, this._id, this._handler); |
| |
| void set handler(Function handler) { |
| this._handler = handler; |
| } |
| |
| void close() { |
| _multiplexer._closePort(_id); |
| } |
| |
| SendPort get sendPort => _multiplexer._createSendPort(_id); |
| |
| void _invokeHandler(message) { |
| _handler(message); |
| } |
| } |
| |
| class _MultiplexSendPort implements SendPort { |
| final SendPort _sendPort; |
| final int _id; |
| _MultiplexSendPort(this._id, this._sendPort); |
| |
| void send(message) { |
| _sendPort.send(list2(_id, message)); |
| } |
| } |
| |
| /// A shared [RawReceivePort] that distributes messages to |
| /// [RawReceivePort] instances that it manages. |
| class RawReceivePortMultiplexer { |
| final RawReceivePort _port = new RawReceivePort(); |
| final Map<int, _MultiplexRawReceivePort> _map = new HashMap(); |
| int _nextId = 0; |
| |
| RawReceivePortMultiplexer() { |
| _port.handler = _multiplexResponse; |
| } |
| |
| RawReceivePort createRawReceivePort([void handler(value)]) { |
| int id = _nextId++; |
| var result = new _MultiplexRawReceivePort(this, id, handler); |
| _map[id] = result; |
| return result; |
| } |
| |
| void close() { |
| _port.close(); |
| } |
| |
| void _multiplexResponse(list) { |
| int id = list[0]; |
| var message = list[1]; |
| _MultiplexRawReceivePort receivePort = _map[id]; |
| // If the receive port is closed, messages are dropped, just as for |
| // the normal ReceivePort. |
| if (receivePort == null) return; // Port closed. |
| receivePort._invokeHandler(message); |
| } |
| |
| SendPort _createSendPort(int id) { |
| return new _MultiplexSendPort(id, _port.sendPort); |
| } |
| |
| void _closePort(int id) { |
| _map.remove(id); |
| } |
| } |