| Index: lib/src/multiplexport.dart
|
| diff --git a/lib/src/multiplexport.dart b/lib/src/multiplexport.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d0c2f67d3f72b0e3ff591311ca4736e2e3404b3c
|
| --- /dev/null
|
| +++ b/lib/src/multiplexport.dart
|
| @@ -0,0 +1,103 @@
|
| +// 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 pkg.isolate.multiplexreceiveport;
|
| +
|
| +import "dart:isolate";
|
| +import "dart:collection";
|
| +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(void handler(response)) {
|
| + 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);
|
| + }
|
| +}
|
|
|