| Index: packages/isolate/lib/src/raw_receive_port_multiplexer.dart
|
| diff --git a/packages/isolate/lib/src/raw_receive_port_multiplexer.dart b/packages/isolate/lib/src/raw_receive_port_multiplexer.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..0e45f4ba5b59ebb5699c020cc01265e099879629
|
| --- /dev/null
|
| +++ b/packages/isolate/lib/src/raw_receive_port_multiplexer.dart
|
| @@ -0,0 +1,102 @@
|
| +// 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 'lists.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);
|
| + }
|
| +}
|
|
|