| Index: runtime/bin/io_service_patch.dart
|
| diff --git a/runtime/bin/io_service_patch.dart b/runtime/bin/io_service_patch.dart
|
| index 5d6b7bc1f3c909e9a820e89fd047013d740968fe..a9f0514439a1716480dbc7b322bcde9f82c7df58 100644
|
| --- a/runtime/bin/io_service_patch.dart
|
| +++ b/runtime/bin/io_service_patch.dart
|
| @@ -3,23 +3,39 @@
|
| // BSD-style license that can be found in the LICENSE file.
|
|
|
| class _IOServicePorts {
|
| - List<SendPort> _freeServicePorts = <SendPort>[];
|
| - HashMap<int, SendPort> _usedBy = new HashMap<int, SendPort>();
|
| + // We limit the number of IO Service ports per isolate so that we don't
|
| + // spawn too many threads all at once, which can crash the VM on Windows.
|
| + static const int maxPorts = 32;
|
| + List<SendPort> _ports = <SendPort>[];
|
| + List<SendPort> _freePorts = <SendPort>[];
|
| + HashMap<int, SendPort> _usedPorts = new HashMap<int, SendPort>();
|
|
|
| _IOServicePorts();
|
|
|
| - SendPort _getFreePort(int forRequestId) {
|
| - if (_freeServicePorts.isEmpty) {
|
| - _freeServicePorts.add(_newServicePort());
|
| + SendPort _getPort(int forRequestId) {
|
| + if (_freePorts.isEmpty && _usedPorts.length < maxPorts) {
|
| + final SendPort port = _newServicePort();
|
| + _ports.add(port);
|
| + _freePorts.add(port);
|
| }
|
| - SendPort freePort = _freeServicePorts.removeLast();
|
| - assert(!_usedBy.containsKey(forRequestId));
|
| - _usedBy[forRequestId] = freePort;
|
| - return freePort;
|
| + if (!_freePorts.isEmpty) {
|
| + final SendPort port = _freePorts.removeLast();
|
| + assert(!_usedPorts.containsKey(forRequestId));
|
| + _usedPorts[forRequestId] = port;
|
| + return port;
|
| + }
|
| + // We have already allocated the max number of ports. Re-use an
|
| + // existing one.
|
| + final SendPort port = _ports[forRequestId % maxPorts];
|
| + _usedPorts[forRequestId] = port;
|
| + return port;
|
| }
|
|
|
| void _returnPort(int forRequestId) {
|
| - _freeServicePorts.add(_usedBy.remove(forRequestId));
|
| + final SendPort port = _usedPorts.remove(forRequestId);
|
| + if (!_usedPorts.values.contains(port)) {
|
| + _freePorts.add(port);
|
| + }
|
| }
|
|
|
| static SendPort _newServicePort() native "IOService_NewServicePort";
|
| @@ -39,9 +55,9 @@ class _IOService {
|
| do {
|
| id = _getNextId();
|
| } while (_messageMap.containsKey(id));
|
| - SendPort servicePort = _servicePorts._getFreePort(id);
|
| + final SendPort servicePort = _servicePorts._getPort(id);
|
| _ensureInitialize();
|
| - var completer = new Completer();
|
| + final Completer completer = new Completer();
|
| _messageMap[id] = completer;
|
| try {
|
| servicePort.send([id, _replyToPort, request, data]);
|
|
|