OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 class _IOServicePorts { | 5 class _IOServicePorts { |
6 List<SendPort> _freeServicePorts = <SendPort>[]; | 6 // We limit the number of IO Service ports per isolate so that we don't |
7 HashMap<int, SendPort> _usedBy = new HashMap<int, SendPort>(); | 7 // spawn too many threads all at once, which can crash the VM on Windows. |
| 8 static const int maxPorts = 32; |
| 9 List<SendPort> _ports = <SendPort>[]; |
| 10 List<SendPort> _freePorts = <SendPort>[]; |
| 11 HashMap<int, SendPort> _usedPorts = new HashMap<int, SendPort>(); |
8 | 12 |
9 _IOServicePorts(); | 13 _IOServicePorts(); |
10 | 14 |
11 SendPort _getFreePort(int forRequestId) { | 15 SendPort _getPort(int forRequestId) { |
12 if (_freeServicePorts.isEmpty) { | 16 if (_freePorts.isEmpty && _usedPorts.length < maxPorts) { |
13 _freeServicePorts.add(_newServicePort()); | 17 final SendPort port = _newServicePort(); |
| 18 _ports.add(port); |
| 19 _freePorts.add(port); |
14 } | 20 } |
15 SendPort freePort = _freeServicePorts.removeLast(); | 21 if (!_freePorts.isEmpty) { |
16 assert(!_usedBy.containsKey(forRequestId)); | 22 final SendPort port = _freePorts.removeLast(); |
17 _usedBy[forRequestId] = freePort; | 23 assert(!_usedPorts.containsKey(forRequestId)); |
18 return freePort; | 24 _usedPorts[forRequestId] = port; |
| 25 return port; |
| 26 } |
| 27 // We have already allocated the max number of ports. Re-use an |
| 28 // existing one. |
| 29 final SendPort port = _ports[forRequestId % maxPorts]; |
| 30 _usedPorts[forRequestId] = port; |
| 31 return port; |
19 } | 32 } |
20 | 33 |
21 void _returnPort(int forRequestId) { | 34 void _returnPort(int forRequestId) { |
22 _freeServicePorts.add(_usedBy.remove(forRequestId)); | 35 final SendPort port = _usedPorts.remove(forRequestId); |
| 36 if (!_usedPorts.values.contains(port)) { |
| 37 _freePorts.add(port); |
| 38 } |
23 } | 39 } |
24 | 40 |
25 static SendPort _newServicePort() native "IOService_NewServicePort"; | 41 static SendPort _newServicePort() native "IOService_NewServicePort"; |
26 } | 42 } |
27 | 43 |
28 @patch | 44 @patch |
29 class _IOService { | 45 class _IOService { |
30 static _IOServicePorts _servicePorts = new _IOServicePorts(); | 46 static _IOServicePorts _servicePorts = new _IOServicePorts(); |
31 static RawReceivePort _receivePort; | 47 static RawReceivePort _receivePort; |
32 static SendPort _replyToPort; | 48 static SendPort _replyToPort; |
33 static HashMap<int, Completer> _messageMap = new HashMap<int, Completer>(); | 49 static HashMap<int, Completer> _messageMap = new HashMap<int, Completer>(); |
34 static int _id = 0; | 50 static int _id = 0; |
35 | 51 |
36 @patch | 52 @patch |
37 static Future _dispatch(int request, List data) { | 53 static Future _dispatch(int request, List data) { |
38 int id; | 54 int id; |
39 do { | 55 do { |
40 id = _getNextId(); | 56 id = _getNextId(); |
41 } while (_messageMap.containsKey(id)); | 57 } while (_messageMap.containsKey(id)); |
42 SendPort servicePort = _servicePorts._getFreePort(id); | 58 final SendPort servicePort = _servicePorts._getPort(id); |
43 _ensureInitialize(); | 59 _ensureInitialize(); |
44 var completer = new Completer(); | 60 final Completer completer = new Completer(); |
45 _messageMap[id] = completer; | 61 _messageMap[id] = completer; |
46 try { | 62 try { |
47 servicePort.send([id, _replyToPort, request, data]); | 63 servicePort.send([id, _replyToPort, request, data]); |
48 } catch (error) { | 64 } catch (error) { |
49 _messageMap.remove(id).complete(error); | 65 _messageMap.remove(id).complete(error); |
50 if (_messageMap.length == 0) { | 66 if (_messageMap.length == 0) { |
51 _finalize(); | 67 _finalize(); |
52 } | 68 } |
53 } | 69 } |
54 return completer.future; | 70 return completer.future; |
(...skipping 18 matching lines...) Expand all Loading... |
73 _id = 0; | 89 _id = 0; |
74 _receivePort.close(); | 90 _receivePort.close(); |
75 _receivePort = null; | 91 _receivePort = null; |
76 } | 92 } |
77 | 93 |
78 static int _getNextId() { | 94 static int _getNextId() { |
79 if (_id == 0x7FFFFFFF) _id = 0; | 95 if (_id == 0x7FFFFFFF) _id = 0; |
80 return _id++; | 96 return _id++; |
81 } | 97 } |
82 } | 98 } |
OLD | NEW |