| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | |
| 2 // for details. All rights reserved. Use of this source code is governed by a | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 /// A multiplexing [RawReceivePort]. | |
| 6 /// | |
| 7 /// Allows creating a number of [RawReceivePort] implementations that all send | |
| 8 /// messages through the same real `RawReceivePort`. | |
| 9 /// | |
| 10 /// This allows reducing the number of receive ports created, but adds an | |
| 11 /// overhead to each message. | |
| 12 /// If a library creates many short-lived receive ports, multiplexing might be | |
| 13 /// faster. | |
| 14 /// | |
| 15 /// To use multiplexing receive ports, create and store a | |
| 16 /// [RawReceivePortMultiplexer], and create receive ports by calling | |
| 17 /// `multiplexer.createRawReceivePort(handler)` where you would otherwise | |
| 18 /// write `new RawReceivePort(handler)`. | |
| 19 /// | |
| 20 /// Remember to [close] the multiplexer when it is no longer needed. | |
| 21 /// ` | |
| 22 /// (TODO: Check if it really is faster - creating a receive port requires a | |
| 23 /// global mutex, so it may be a bottleneck, but it's not clear how slow it is). | |
| 24 library pkg.isolate.multiplexreceiveport; | |
| 25 | |
| 26 import "dart:isolate"; | |
| 27 import "dart:collection"; | |
| 28 import "lists.dart"; | |
| 29 | |
| 30 class _MultiplexRawReceivePort implements RawReceivePort { | |
| 31 final RawReceivePortMultiplexer _multiplexer; | |
| 32 final int _id; | |
| 33 Function _handler; | |
| 34 | |
| 35 _MultiplexRawReceivePort(this._multiplexer, this._id, this._handler); | |
| 36 | |
| 37 void set handler(void handler(response)) { | |
| 38 this._handler = handler; | |
| 39 } | |
| 40 | |
| 41 void close() { | |
| 42 _multiplexer._closePort(_id); | |
| 43 } | |
| 44 | |
| 45 SendPort get sendPort => _multiplexer._createSendPort(_id); | |
| 46 | |
| 47 void _invokeHandler(message) { | |
| 48 _handler(message); | |
| 49 } | |
| 50 } | |
| 51 | |
| 52 class _MultiplexSendPort implements SendPort { | |
| 53 final SendPort _sendPort; | |
| 54 final int _id; | |
| 55 _MultiplexSendPort(this._id, this._sendPort); | |
| 56 | |
| 57 void send(message) { | |
| 58 _sendPort.send(list2(_id, message)); | |
| 59 } | |
| 60 } | |
| 61 | |
| 62 /// A shared [RawReceivePort] that distributes messages to | |
| 63 /// [RawReceivePort] instances that it manages. | |
| 64 class RawReceivePortMultiplexer { | |
| 65 final RawReceivePort _port = new RawReceivePort(); | |
| 66 final Map<int, _MultiplexRawReceivePort> _map = new HashMap(); | |
| 67 int _nextId = 0; | |
| 68 | |
| 69 RawReceivePortMultiplexer() { | |
| 70 _port.handler = _multiplexResponse; | |
| 71 } | |
| 72 | |
| 73 RawReceivePort createRawReceivePort([void handler(value)]) { | |
| 74 int id = _nextId++; | |
| 75 var result = new _MultiplexRawReceivePort(this, id, handler); | |
| 76 _map[id] = result; | |
| 77 return result; | |
| 78 } | |
| 79 | |
| 80 void close() { | |
| 81 _port.close(); | |
| 82 } | |
| 83 | |
| 84 void _multiplexResponse(list) { | |
| 85 int id = list[0]; | |
| 86 var message = list[1]; | |
| 87 _MultiplexRawReceivePort receivePort = _map[id]; | |
| 88 // If the receive port is closed, messages are dropped, just as for | |
| 89 // the normal ReceivePort. | |
| 90 if (receivePort == null) return; // Port closed. | |
| 91 receivePort._invokeHandler(message); | |
| 92 } | |
| 93 | |
| 94 SendPort _createSendPort(int id) { | |
| 95 return new _MultiplexSendPort(id, _port.sendPort); | |
| 96 } | |
| 97 | |
| 98 void _closePort(int id) { | |
| 99 _map.remove(id); | |
| 100 } | |
| 101 } | |
| OLD | NEW |