Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 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 | 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 library dart.pkg.isolate.isolaterunner; | 5 library dart.pkg.isolate.isolaterunner; |
| 6 | 6 |
| 7 import "dart:isolate"; | 7 import "dart:isolate"; |
| 8 import "dart:async"; | 8 import "dart:async"; |
| 9 import "runner.dart"; | 9 import "runner.dart"; |
| 10 import "ports.dart"; | 10 import "ports.dart"; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 52 * Create a new [Isolate], as by [Isolate.spawn] and wrap that. | 52 * Create a new [Isolate], as by [Isolate.spawn] and wrap that. |
| 53 * | 53 * |
| 54 * The returned [IsolateRunner] forwards operations to the new isolate, | 54 * The returned [IsolateRunner] forwards operations to the new isolate, |
| 55 * and keeps a port open in the new isolate that receives commands | 55 * and keeps a port open in the new isolate that receives commands |
| 56 * from the `IsolateRunner`. Remember to [close] the `IsolateRunner` when | 56 * from the `IsolateRunner`. Remember to [close] the `IsolateRunner` when |
| 57 * it's no longer needed. | 57 * it's no longer needed. |
| 58 */ | 58 */ |
| 59 static Future<IsolateRunner> spawn() { | 59 static Future<IsolateRunner> spawn() { |
| 60 Completer portCompleter = new Completer.sync(); | 60 Completer portCompleter = new Completer.sync(); |
| 61 SendPort initPort = singleCompletePort(portCompleter); | 61 SendPort initPort = singleCompletePort(portCompleter); |
| 62 return Isolate.spawn(IsolateRunnerRemote._create, initPort) | 62 return Isolate.spawn(IsolateRunnerRemote._create, initPort).then( |
| 63 .then((Isolate isolate) { | 63 (Isolate isolate) { |
|
Lasse Reichstein Nielsen
2015/02/26 10:59:14
Also has body less indented than its delimiter lin
| |
| 64 // TODO: Add when VM supports it. | 64 // TODO: Add when VM supports it. |
| 65 // isolate.setErrorsFatal(false); | 65 // isolate.setErrorsFatal(false); |
| 66 return portCompleter.future.then((SendPort commandPort) { | 66 return portCompleter.future.then((SendPort commandPort) { |
| 67 var result = new IsolateRunner(isolate, commandPort); | 67 var result = new IsolateRunner(isolate, commandPort); |
| 68 // Guarantees that setErrorsFatal has completed. | 68 // Guarantees that setErrorsFatal has completed. |
| 69 return result.ping().then((_) => result); | 69 return result.ping().then((_) => result); |
| 70 }); | 70 }); |
| 71 }); | 71 }); |
| 72 } | 72 } |
| 73 | 73 |
| 74 /** | 74 /** |
| 75 * Closes the `IsolateRunner` communication down. | 75 * Closes the `IsolateRunner` communication down. |
| 76 * | 76 * |
| 77 * If the isolate isn't running something else to keep it alive, | 77 * If the isolate isn't running something else to keep it alive, |
| 78 * this will also make the isolate shut down. | 78 * this will also make the isolate shut down. |
| 79 * | 79 * |
| 80 * Can be used to create an isolate, use [run] to start a service, and | 80 * Can be used to create an isolate, use [run] to start a service, and |
| 81 * then drop the connection and let the service control the isolate's | 81 * then drop the connection and let the service control the isolate's |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 131 * or doesn't answer within [timeout] for any other reason, | 131 * or doesn't answer within [timeout] for any other reason, |
| 132 * the returned future completes with `false`. | 132 * the returned future completes with `false`. |
| 133 * | 133 * |
| 134 * Guaranteed to only complete after all previous sent isolate commands | 134 * Guaranteed to only complete after all previous sent isolate commands |
| 135 * (like pause and resume) have been handled. | 135 * (like pause and resume) have been handled. |
| 136 * Paused isolates do respond to ping requests. | 136 * Paused isolates do respond to ping requests. |
| 137 */ | 137 */ |
| 138 Future<bool> ping({Duration timeout: const Duration(seconds: 1)}) { | 138 Future<bool> ping({Duration timeout: const Duration(seconds: 1)}) { |
| 139 Completer completer = new Completer<bool>(); | 139 Completer completer = new Completer<bool>(); |
| 140 SendPort port = singleCompletePort(completer, | 140 SendPort port = singleCompletePort(completer, |
| 141 callback: _kTrue, | 141 callback: _kTrue, timeout: timeout, onTimeout: _kFalse); |
|
Lasse Reichstein Nielsen
2015/02/26 10:59:13
I prefer the original.
| |
| 142 timeout: timeout, | |
| 143 onTimeout: _kFalse); | |
| 144 isolate.ping(port); | 142 isolate.ping(port); |
| 145 return completer.future; | 143 return completer.future; |
| 146 } | 144 } |
| 147 | 145 |
| 148 static bool _kTrue(_) => true; | 146 static bool _kTrue(_) => true; |
| 149 static bool _kFalse() => false; | 147 static bool _kFalse() => false; |
| 150 | 148 |
| 151 /** | 149 /** |
| 152 * Pauses the isolate. | 150 * Pauses the isolate. |
| 153 * | 151 * |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 197 * | 195 * |
| 198 * Example: | 196 * Example: |
| 199 * | 197 * |
| 200 * IsolateRunner iso = await IsolateRunner.spawn(); | 198 * IsolateRunner iso = await IsolateRunner.spawn(); |
| 201 * try { | 199 * try { |
| 202 * return await iso.run(heavyComputation, argument); | 200 * return await iso.run(heavyComputation, argument); |
| 203 * } finally { | 201 * } finally { |
| 204 * await iso.close(); | 202 * await iso.close(); |
| 205 * } | 203 * } |
| 206 */ | 204 */ |
| 207 Future run(function(argument), argument, | 205 Future run(function(argument), argument, {Duration timeout, onTimeout()}) { |
| 208 {Duration timeout, onTimeout()}) { | |
| 209 return singleResultFuture((SendPort port) { | 206 return singleResultFuture((SendPort port) { |
| 210 _commandPort.send( | 207 _commandPort |
| 211 list4(_RUN, FunctionRef.from(function), argument, port)); | 208 .send(list4(_RUN, FunctionRef.from(function), argument, port)); |
| 212 }, timeout: timeout, onTimeout: onTimeout); | 209 }, timeout: timeout, onTimeout: onTimeout); |
| 213 } | 210 } |
| 214 | 211 |
| 215 /** | 212 /** |
| 216 * A broadcast stream of uncaught errors from the isolate. | 213 * A broadcast stream of uncaught errors from the isolate. |
| 217 * | 214 * |
| 218 * When listening on the stream, errors from the isolate will be reported | 215 * When listening on the stream, errors from the isolate will be reported |
| 219 * as errors in the stream. Be ready to handle the errors. | 216 * as errors in the stream. Be ready to handle the errors. |
| 220 * | 217 * |
| 221 * The stream closes when the isolate shuts down. | 218 * The stream closes when the isolate shuts down. |
| 222 */ | 219 */ |
| 223 Stream get errors { | 220 Stream get errors { |
| 224 StreamController controller; | 221 StreamController controller; |
| 225 RawReceivePort port; | 222 RawReceivePort port; |
| 226 void handleError(message) { | 223 void handleError(message) { |
| 227 if (message == null) { | 224 if (message == null) { |
| 228 // Isolate shutdown. | 225 // Isolate shutdown. |
| 229 port.close(); | 226 port.close(); |
| 230 controller.close(); | 227 controller.close(); |
| 231 } else { | 228 } else { |
| 232 // Uncaught error. | 229 // Uncaught error. |
| 233 String errorDescription = message[0]; | 230 String errorDescription = message[0]; |
| 234 String stackDescription = message[1]; | 231 String stackDescription = message[1]; |
| 235 var error = new RemoteError(errorDescription, stackDescription); | 232 var error = new RemoteError(errorDescription, stackDescription); |
| 236 controller.addError(error, error.stackTrace); | 233 controller.addError(error, error.stackTrace); |
| 237 } | 234 } |
| 238 } | 235 } |
| 239 controller = new StreamController.broadcast( | 236 controller = new StreamController.broadcast(sync: true, onListen: () { |
| 240 sync: true, | 237 port = new RawReceivePort(handleError); |
| 241 onListen: () { | 238 // TODO: When supported, uncomment this. |
| 242 port = new RawReceivePort(handleError); | 239 // isolate.addErrorListener(port.sendPort); |
| 243 // TODO: When supported, uncomment this. | 240 // isolate.addOnExitListener(port.sendPort); |
| 244 // isolate.addErrorListener(port.sendPort); | 241 // And remove the send below, which acts as an immediate close. |
| 245 // isolate.addOnExitListener(port.sendPort); | 242 port.sendPort.send(null); |
| 246 // And remove the send below, which acts as an immediate close. | 243 }, onCancel: () { |
| 247 port.sendPort.send(null); | 244 port.close(); |
| 248 }, | 245 // this.removeErrorListener(port.sendPort); |
| 249 onCancel: () { | 246 // this.removeOnExitListener(port.sendPort); |
| 250 port.close(); | 247 port = null; |
| 251 // this.removeErrorListener(port.sendPort); | 248 }); |
|
Lasse Reichstein Nielsen
2015/02/26 10:59:13
Less consistently indented. I'd prefer the onListe
| |
| 252 // this.removeOnExitListener(port.sendPort); | |
| 253 port = null; | |
| 254 }); | |
| 255 return controller.stream; | 249 return controller.stream; |
| 256 } | 250 } |
| 257 | 251 |
| 258 /** | 252 /** |
| 259 * Waits for the [isolate] to terminate. | 253 * Waits for the [isolate] to terminate. |
| 260 * | 254 * |
| 261 * Completes the returned future when the isolate terminates. | 255 * Completes the returned future when the isolate terminates. |
| 262 * | 256 * |
| 263 * If the isolate has already stopped responding to commands, | 257 * If the isolate has already stopped responding to commands, |
| 264 * the returned future will never terminate. | 258 * the returned future will never terminate. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 305 switch (command[0]) { | 299 switch (command[0]) { |
| 306 case _SHUTDOWN: | 300 case _SHUTDOWN: |
| 307 SendPort responsePort = command[1]; | 301 SendPort responsePort = command[1]; |
| 308 _commandPort.close(); | 302 _commandPort.close(); |
| 309 responsePort.send(null); | 303 responsePort.send(null); |
| 310 return; | 304 return; |
| 311 case _RUN: | 305 case _RUN: |
| 312 Function function = command[1].function; | 306 Function function = command[1].function; |
| 313 var argument = command[2]; | 307 var argument = command[2]; |
| 314 SendPort responsePort = command[3]; | 308 SendPort responsePort = command[3]; |
| 315 sendFutureResult(new Future.sync(() => function(argument)), | 309 sendFutureResult( |
| 316 responsePort); | 310 new Future.sync(() => function(argument)), responsePort); |
|
Lasse Reichstein Nielsen
2015/02/26 10:59:14
It's not as visible that responsePort is a second
| |
| 317 return; | 311 return; |
| 318 } | 312 } |
| 319 } | 313 } |
| 320 } | 314 } |
| OLD | NEW |