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

Unified Diff: runtime/bin/directory_impl.dart

Issue 9310082: Run all directory async operations on a separate thread using native ports (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Adderssed review comments from ager@ (and rebased) Created 8 years, 10 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 | « runtime/bin/directory.cc ('k') | runtime/bin/directory_posix.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/directory_impl.dart
diff --git a/runtime/bin/directory_impl.dart b/runtime/bin/directory_impl.dart
index f455d7477f7beb72cedfd0842b459fe2d9396659..d5a9953b38fb08b9cf9bb3633e1c41d30cfcdd5a 100644
--- a/runtime/bin/directory_impl.dart
+++ b/runtime/bin/directory_impl.dart
@@ -10,167 +10,30 @@ class _OSStatus {
}
-class _DirectoryListingIsolate extends Isolate {
-
- _DirectoryListingIsolate() : super.heavy();
-
- void main() {
- port.receive((message, replyTo) {
- bool started = _list(message['dir'],
- message['recursive'],
- message['dirPort'],
- message['filePort'],
- message['donePort'],
- message['errorPort']);
- replyTo.send(started);
- port.close();
- });
- }
-
- bool _list(String dir,
- bool recursive,
- SendPort dirPort,
- SendPort filePort,
- SendPort donePort,
- SendPort errorPort) native "Directory_List";
-}
-
-
-class _DirectoryOperation {
- abstract void execute(ReceivePort port);
-
- void set replyPort(SendPort port) {
- _replyPort = port;
- }
-
- SendPort _replyPort;
-}
-
-
-class _DirExitOperation extends _DirectoryOperation {
- void execute(ReceivePort port) {
- port.close();
- }
-}
-
-
-class _DirExistsOperation extends _DirectoryOperation {
- _DirExistsOperation(String this._path);
-
- void execute(ReceivePort port) {
- _replyPort.send(_Directory._exists(_path), port.toSendPort());
- }
-
- String _path;
-}
-
-
-class _DirCreateOperation extends _DirectoryOperation {
- _DirCreateOperation(String this._path);
-
- void execute(ReceivePort port) {
- _replyPort.send(_Directory._create(_path), port.toSendPort());
- }
-
- String _path;
-}
-
-
-class _DirCreateTempOperation extends _DirectoryOperation {
- _DirCreateTempOperation(String this._path);
-
- void execute(ReceivePort port) {
- var status = new _OSStatus();
- var result = _Directory._createTemp(_path, status);
- if (result == null) {
- _replyPort.send(status, port.toSendPort());
- } else {
- _replyPort.send(result, port.toSendPort());
- }
- }
-
- String _path;
-}
-
-
-class _DirDeleteOperation extends _DirectoryOperation {
- _DirDeleteOperation(String this._path, bool this._recursive);
-
- void execute(ReceivePort port) {
- _replyPort.send(_Directory._delete(_path, _recursive), port.toSendPort());
- }
-
- String _path;
- bool _recursive;
-}
-
-
-class _DirectoryOperationIsolate extends Isolate {
- _DirectoryOperationIsolate() : super.heavy();
-
- void handleOperation(_DirectoryOperation message, SendPort ignored) {
- message.execute(port);
- port.receive(handleOperation);
- }
-
- void main() {
- port.receive(handleOperation);
- }
-}
-
-
-class _DirectoryOperationScheduler {
- _DirectoryOperationScheduler() : _queue = new Queue();
-
- void schedule(SendPort port) {
- assert(_isolate != null);
- if (_queue.isEmpty()) {
- port.send(new _DirExitOperation());
- _isolate = null;
- } else {
- port.send(_queue.removeFirst());
- }
- }
-
- void scheduleWrap(void callback(result, ignored)) {
- return (result, replyTo) {
- callback(result, replyTo);
- schedule(replyTo);
- };
- }
-
- void enqueue(_DirectoryOperation operation, void callback(result, ignored)) {
- ReceivePort replyPort = new ReceivePort.singleShot();
- replyPort.receive(scheduleWrap(callback));
- operation.replyPort = replyPort.toSendPort();
- _queue.addLast(operation);
- if (_isolate == null) {
- _isolate = new _DirectoryOperationIsolate();
- _isolate.spawn().then((port) {
- schedule(port);
- });
- }
- }
-
- Queue<_DirectoryOperation> _queue;
- _DirectoryOperationIsolate _isolate;
-}
-
-
class _Directory implements Directory {
+ static final kCreateRequest = 0;
+ static final kDeleteRequest = 1;
+ static final kExistsRequest = 2;
+ static final kCreateTempRequest = 3;
+ static final kListRequest = 4;
- _Directory(String this._path)
- : _scheduler = new _DirectoryOperationScheduler();
+ _Directory(String this._path);
static String _createTemp(String template,
_OSStatus status) native "Directory_CreateTemp";
static int _exists(String path) native "Directory_Exists";
static bool _create(String path) native "Directory_Create";
static bool _delete(String path, bool recursive) native "Directory_Delete";
+ static SendPort _newServicePort() native "Directory_NewServicePort";
void exists() {
- var operation = new _DirExistsOperation(_path);
- _scheduler.enqueue(operation, (result, ignored) {
+ if (_directoryService == null) {
+ _directoryService = _newServicePort();
+ }
+ List request = new List(2);
+ request[0] = kExistsRequest;
+ request[1] = _path;
+ _directoryService.call(request).receive((result, replyTo) {
var handler =
(_existsHandler != null) ? _existsHandler : (result) => null;
if (result < 0) {
@@ -192,11 +55,15 @@ class _Directory implements Directory {
}
void create() {
- var operation = new _DirCreateOperation(_path);
- _scheduler.enqueue(operation, (result, ignored) {
- var handler = (_createHandler != null) ? _createHandler : () => null;
+ if (_directoryService == null) {
+ _directoryService = _newServicePort();
+ }
+ List request = new List(2);
+ request[0] = kCreateRequest;
+ request[1] = _path;
+ _directoryService.call(request).receive((result, replyTo) {
if (result) {
- handler();
+ if (_createHandler != null) _createHandler();
} else if (_errorHandler != null) {
_errorHandler("Directory creation failed: $_path");
}
@@ -210,16 +77,19 @@ class _Directory implements Directory {
}
void createTemp() {
- var operation = new _DirCreateTempOperation(_path);
- _scheduler.enqueue(operation, (result, ignored) {
- var handler =
- (_createTempHandler != null) ? _createTempHandler : () => null;
- if (result is !_OSStatus) {
+ if (_directoryService == null) {
+ _directoryService = _newServicePort();
+ }
+ List request = new List(2);
+ request[0] = kCreateTempRequest;
+ request[1] = _path;
+ _directoryService.call(request).receive((result, replyTo) {
+ if (result is !List) {
_path = result;
- handler();
- } else if (_errorHandler !== null) {
+ if (_createTempHandler != null) _createTempHandler();
+ } else if (_errorHandler != null) {
_errorHandler("Could not create temporary directory [$_path]: " +
- "${result._errorMessage}");
+ "${result[1]}");
}
});
}
@@ -238,11 +108,16 @@ class _Directory implements Directory {
}
void delete([bool recursive = false]) {
- var operation = new _DirDeleteOperation(_path, recursive);
- _scheduler.enqueue(operation, (result, ignored) {
- var handler = (_deleteHandler != null) ? _deleteHandler : () => null;
+ if (_directoryService == null) {
+ _directoryService = _newServicePort();
+ }
+ List request = new List(3);
+ request[0] = kDeleteRequest;
+ request[1] = _path;
+ request[2] = recursive;
+ _directoryService.call(request).receive((result, replyTo) {
if (result) {
- handler();
+ if (_deleteHandler != null) _deleteHandler();
} else if (_errorHandler != null) {
if (recursive) {
_errorHandler("Recursive directory deletion failed: $_path");
@@ -260,66 +135,40 @@ class _Directory implements Directory {
}
void list([bool recursive = false]) {
- new _DirectoryListingIsolate().spawn().then((port) {
- // Build a map of parameters to the directory listing isolate.
- Map listingParameters = new Map();
- listingParameters['dir'] = _path;
- listingParameters['recursive'] = recursive;
-
- // Setup ports to receive messages from listing.
- // TODO(ager): Do not explicitly transform to send ports when
- // implicit conversions are implemented.
- ReceivePort dirPort;
- ReceivePort filePort;
- ReceivePort donePort;
- ReceivePort errorPort;
- if (_dirHandler !== null) {
- dirPort = new ReceivePort();
- dirPort.receive((String dir, ignored) {
- _dirHandler(dir);
- });
- listingParameters['dirPort'] = dirPort.toSendPort();
- }
- if (_fileHandler !== null) {
- filePort = new ReceivePort();
- filePort.receive((String file, ignored) {
- _fileHandler(file);
- });
- listingParameters['filePort'] = filePort.toSendPort();
+ final int kListDirectory = 0;
+ final int kListFile = 1;
+ final int kListError = 2;
+ final int kListDone = 3;
+
+ List request = new List(3);
+ request[0] = kListRequest;
+ request[1] = _path;
+ request[2] = recursive;
+ ReceivePort responsePort = new ReceivePort();
+ // Use a separate directory service port for each listing as
+ // listing operations on the same directory can run in parallel.
+ _newServicePort().send(request, responsePort.toSendPort());
+ responsePort.receive((message, replyTo) {
+ if (message is !List || message[0] is !int) {
+ responsePort.close();
+ if (_errorHandler != null) _errorHandler("Internal error");
+ return;
}
- if (_doneHandler !== null) {
- donePort = new ReceivePort.singleShot();
- donePort.receive((bool completed, ignored) {
- _doneHandler(completed);
- });
- listingParameters['donePort'] = donePort.toSendPort();
+ switch (message[0]) {
+ case kListDirectory:
+ if (_dirHandler != null) _dirHandler(message[1]);
+ break;
+ case kListFile:
+ if (_fileHandler != null) _fileHandler(message[1]);
+ break;
+ case kListError:
+ if (_errorHandler != null) _errorHandler(message[1]);
+ break;
+ case kListDone:
+ responsePort.close();
+ if (_doneHandler != null) _doneHandler(message[1]);
+ break;
}
- if (_errorHandler !== null) {
- errorPort = new ReceivePort.singleShot();
- errorPort.receive((String error, ignored) {
- _errorHandler(error);
- });
- listingParameters['errorPort'] = errorPort.toSendPort();
- }
-
- // Close ports when listing is done.
- ReceivePort closePortsPort = new ReceivePort();
- closePortsPort.receive((message, replyTo) {
- if (!message) {
- errorPort.toSendPort().send(
- "Failed to list directory: $_path recursive: $recursive");
- donePort.toSendPort().send(false);
- } else {
- _closePort(errorPort);
- _closePort(donePort);
- }
- _closePort(dirPort);
- _closePort(filePort);
- _closePort(closePortsPort);
- });
-
- // Send the listing parameters to the isolate.
- port.send(listingParameters, closePortsPort.toSendPort());
});
}
@@ -373,5 +222,5 @@ class _Directory implements Directory {
var _errorHandler;
String _path;
- _DirectoryOperationScheduler _scheduler;
+ SendPort _directoryService;
}
« no previous file with comments | « runtime/bin/directory.cc ('k') | runtime/bin/directory_posix.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698