Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(467)

Unified Diff: runtime/bin/io_service_patch.dart

Issue 2903593004: [dart:io] Remove collisions from IO Service port dispatch (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/io_service_patch.dart
diff --git a/runtime/bin/io_service_patch.dart b/runtime/bin/io_service_patch.dart
index 20cc5aa7a10ee33ca60885d8d91c61345ea24a15..5d6b7bc1f3c909e9a820e89fd047013d740968fe 100644
--- a/runtime/bin/io_service_patch.dart
+++ b/runtime/bin/io_service_patch.dart
@@ -2,14 +2,35 @@
// 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.
+class _IOServicePorts {
+ List<SendPort> _freeServicePorts = <SendPort>[];
+ HashMap<int, SendPort> _usedBy = new HashMap<int, SendPort>();
+
+ _IOServicePorts();
+
+ SendPort _getFreePort(int forRequestId) {
+ if (_freeServicePorts.isEmpty) {
+ _freeServicePorts.add(_newServicePort());
+ }
+ SendPort freePort = _freeServicePorts.removeLast();
+ assert(!_usedBy.containsKey(forRequestId));
+ _usedBy[forRequestId] = freePort;
+ return freePort;
+ }
+
+ void _returnPort(int forRequestId) {
+ _freeServicePorts.add(_usedBy.remove(forRequestId));
+ }
+
+ static SendPort _newServicePort() native "IOService_NewServicePort";
+}
+
@patch
class _IOService {
- // Lazy initialize service ports, 32 per isolate.
- static const int _SERVICE_PORT_COUNT = 32;
- static List<SendPort> _servicePort = new List(_SERVICE_PORT_COUNT);
+ static _IOServicePorts _servicePorts = new _IOServicePorts();
static RawReceivePort _receivePort;
static SendPort _replyToPort;
- static Map<int, Completer> _messageMap = {};
+ static HashMap<int, Completer> _messageMap = new HashMap<int, Completer>();
static int _id = 0;
@patch
@@ -18,12 +39,12 @@ class _IOService {
do {
id = _getNextId();
} while (_messageMap.containsKey(id));
- int index = id % _SERVICE_PORT_COUNT;
- _initialize(index);
+ SendPort servicePort = _servicePorts._getFreePort(id);
+ _ensureInitialize();
var completer = new Completer();
_messageMap[id] = completer;
try {
- _servicePort[index].send([id, _replyToPort, request, data]);
+ servicePort.send([id, _replyToPort, request, data]);
} catch (error) {
_messageMap.remove(id).complete(error);
if (_messageMap.length == 0) {
@@ -33,16 +54,14 @@ class _IOService {
return completer.future;
}
- static void _initialize(int index) {
- if (_servicePort[index] == null) {
- _servicePort[index] = _newServicePort();
- }
+ static void _ensureInitialize() {
if (_receivePort == null) {
_receivePort = new RawReceivePort();
_replyToPort = _receivePort.sendPort;
_receivePort.handler = (data) {
assert(data is List && data.length == 2);
_messageMap.remove(data[0]).complete(data[1]);
+ _servicePorts._returnPort(data[0]);
if (_messageMap.length == 0) {
_finalize();
}
@@ -60,6 +79,4 @@ class _IOService {
if (_id == 0x7FFFFFFF) _id = 0;
return _id++;
}
-
- static SendPort _newServicePort() native "IOService_NewServicePort";
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698