| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 import "dart:collection" show HashMap; | 5 import "dart:collection" show HashMap; |
| 6 import "dart:_internal" hide Symbol; | 6 import "dart:_internal" hide Symbol; |
| 7 | 7 |
| 8 @patch | 8 @patch class ReceivePort { |
| 9 class ReceivePort { | 9 @patch factory ReceivePort() = _ReceivePortImpl; |
| 10 @patch | |
| 11 factory ReceivePort() = _ReceivePortImpl; | |
| 12 | 10 |
| 13 @patch | 11 @patch factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) = |
| 14 factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) = | |
| 15 _ReceivePortImpl.fromRawReceivePort; | 12 _ReceivePortImpl.fromRawReceivePort; |
| 16 } | 13 } |
| 17 | 14 |
| 18 @patch | 15 @patch class Capability { |
| 19 class Capability { | 16 @patch factory Capability() = _CapabilityImpl; |
| 20 @patch | |
| 21 factory Capability() = _CapabilityImpl; | |
| 22 } | 17 } |
| 23 | 18 |
| 24 class _CapabilityImpl implements Capability { | 19 class _CapabilityImpl implements Capability { |
| 25 factory _CapabilityImpl() native "CapabilityImpl_factory"; | 20 factory _CapabilityImpl() native "CapabilityImpl_factory"; |
| 26 | 21 |
| 27 bool operator ==(var other) { | 22 bool operator==(var other) { |
| 28 return (other is _CapabilityImpl) && _equals(other); | 23 return (other is _CapabilityImpl) && _equals(other); |
| 29 } | 24 } |
| 30 | 25 |
| 31 int get hashCode { | 26 int get hashCode { |
| 32 return _get_hashcode(); | 27 return _get_hashcode(); |
| 33 } | 28 } |
| 34 | 29 |
| 35 _equals(other) native "CapabilityImpl_equals"; | 30 _equals(other) native "CapabilityImpl_equals"; |
| 36 _get_hashcode() native "CapabilityImpl_get_hashcode"; | 31 _get_hashcode() native "CapabilityImpl_get_hashcode"; |
| 37 } | 32 } |
| 38 | 33 |
| 39 @patch | 34 @patch class RawReceivePort { |
| 40 class RawReceivePort { | |
| 41 /** | 35 /** |
| 42 * Opens a long-lived port for receiving messages. | 36 * Opens a long-lived port for receiving messages. |
| 43 * | 37 * |
| 44 * A [RawReceivePort] is low level and does not work with [Zone]s. It | 38 * A [RawReceivePort] is low level and does not work with [Zone]s. It |
| 45 * can not be paused. The data-handler must be set before the first | 39 * can not be paused. The data-handler must be set before the first |
| 46 * event is received. | 40 * event is received. |
| 47 */ | 41 */ |
| 48 @patch | 42 @patch factory RawReceivePort([void handler(event)]) { |
| 49 factory RawReceivePort([void handler(event)]) { | |
| 50 _RawReceivePortImpl result = new _RawReceivePortImpl(); | 43 _RawReceivePortImpl result = new _RawReceivePortImpl(); |
| 51 result.handler = handler; | 44 result.handler = handler; |
| 52 return result; | 45 return result; |
| 53 } | 46 } |
| 54 } | 47 } |
| 55 | 48 |
| 56 class _ReceivePortImpl extends Stream implements ReceivePort { | 49 class _ReceivePortImpl extends Stream implements ReceivePort { |
| 57 _ReceivePortImpl() : this.fromRawReceivePort(new RawReceivePort()); | 50 _ReceivePortImpl() : this.fromRawReceivePort(new RawReceivePort()); |
| 58 | 51 |
| 59 _ReceivePortImpl.fromRawReceivePort(this._rawPort) { | 52 _ReceivePortImpl.fromRawReceivePort(this._rawPort) { |
| 60 _controller = new StreamController(onCancel: close, sync: true); | 53 _controller = new StreamController(onCancel: close, sync: true); |
| 61 _rawPort.handler = _controller.add; | 54 _rawPort.handler = _controller.add; |
| 62 } | 55 } |
| 63 | 56 |
| 64 SendPort get sendPort { | 57 SendPort get sendPort { |
| 65 return _rawPort.sendPort; | 58 return _rawPort.sendPort; |
| 66 } | 59 } |
| 67 | 60 |
| 68 StreamSubscription listen(void onData(var message), | 61 StreamSubscription listen(void onData(var message), |
| 69 {Function onError, void onDone(), bool cancelOnError}) { | 62 { Function onError, |
| 63 void onDone(), |
| 64 bool cancelOnError }) { |
| 70 return _controller.stream.listen(onData, | 65 return _controller.stream.listen(onData, |
| 71 onError: onError, onDone: onDone, cancelOnError: cancelOnError); | 66 onError: onError, |
| 67 onDone: onDone, |
| 68 cancelOnError: cancelOnError); |
| 72 } | 69 } |
| 73 | 70 |
| 74 close() { | 71 close() { |
| 75 _rawPort.close(); | 72 _rawPort.close(); |
| 76 _controller.close(); | 73 _controller.close(); |
| 77 } | 74 } |
| 78 | 75 |
| 79 final RawReceivePort _rawPort; | 76 final RawReceivePort _rawPort; |
| 80 StreamController _controller; | 77 StreamController _controller; |
| 81 } | 78 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 | 114 |
| 118 close() { | 115 close() { |
| 119 // Close the port and remove it from the handler map. | 116 // Close the port and remove it from the handler map. |
| 120 _handlerMap.remove(this._closeInternal()); | 117 _handlerMap.remove(this._closeInternal()); |
| 121 } | 118 } |
| 122 | 119 |
| 123 SendPort get sendPort { | 120 SendPort get sendPort { |
| 124 return _get_sendport(); | 121 return _get_sendport(); |
| 125 } | 122 } |
| 126 | 123 |
| 127 bool operator ==(var other) { | 124 bool operator==(var other) { |
| 128 return (other is _RawReceivePortImpl) && | 125 return (other is _RawReceivePortImpl) && |
| 129 (this._get_id() == other._get_id()); | 126 (this._get_id() == other._get_id()); |
| 130 } | 127 } |
| 131 | 128 |
| 132 int get hashCode { | 129 int get hashCode { |
| 133 return sendPort.hashCode; | 130 return sendPort.hashCode; |
| 134 } | 131 } |
| 135 | 132 |
| 136 /**** Internal implementation details ****/ | 133 /**** Internal implementation details ****/ |
| 137 _get_id() native "RawReceivePortImpl_get_id"; | 134 _get_id() native "RawReceivePortImpl_get_id"; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 163 // id to handler mapping. | 160 // id to handler mapping. |
| 164 static _initHandlerMap() { | 161 static _initHandlerMap() { |
| 165 // TODO(18511): Workaround bad CheckSmi hoisting. | 162 // TODO(18511): Workaround bad CheckSmi hoisting. |
| 166 var tempMap = new HashMap(); | 163 var tempMap = new HashMap(); |
| 167 // Collect feedback that not all keys are Smis. | 164 // Collect feedback that not all keys are Smis. |
| 168 tempMap["."] = 1; | 165 tempMap["."] = 1; |
| 169 tempMap["."] = 2; | 166 tempMap["."] = 2; |
| 170 | 167 |
| 171 return new HashMap(); | 168 return new HashMap(); |
| 172 } | 169 } |
| 173 | |
| 174 static final Map _handlerMap = _initHandlerMap(); | 170 static final Map _handlerMap = _initHandlerMap(); |
| 175 } | 171 } |
| 176 | 172 |
| 173 |
| 177 class _SendPortImpl implements SendPort { | 174 class _SendPortImpl implements SendPort { |
| 178 /*--- public interface ---*/ | 175 /*--- public interface ---*/ |
| 179 void send(var message) { | 176 void send(var message) { |
| 180 _sendInternal(message); | 177 _sendInternal(message); |
| 181 } | 178 } |
| 182 | 179 |
| 183 bool operator ==(var other) { | 180 bool operator==(var other) { |
| 184 return (other is _SendPortImpl) && (this._get_id() == other._get_id()); | 181 return (other is _SendPortImpl) && (this._get_id() == other._get_id()); |
| 185 } | 182 } |
| 186 | 183 |
| 187 int get hashCode { | 184 int get hashCode { |
| 188 return _get_hashcode(); | 185 return _get_hashcode(); |
| 189 } | 186 } |
| 190 | 187 |
| 191 /*--- private implementation ---*/ | 188 /*--- private implementation ---*/ |
| 192 _get_id() native "SendPortImpl_get_id"; | 189 _get_id() native "SendPortImpl_get_id"; |
| 193 _get_hashcode() native "SendPortImpl_get_hashcode"; | 190 _get_hashcode() native "SendPortImpl_get_hashcode"; |
| 194 | 191 |
| 195 // Forward the implementation of sending messages to the VM. | 192 // Forward the implementation of sending messages to the VM. |
| 196 void _sendInternal(var message) native "SendPortImpl_sendInternal_"; | 193 void _sendInternal(var message) native "SendPortImpl_sendInternal_"; |
| 197 } | 194 } |
| 198 | 195 |
| 199 typedef _NullaryFunction(); | 196 typedef _NullaryFunction(); |
| 200 typedef _UnaryFunction(args); | 197 typedef _UnaryFunction(args); |
| 201 typedef _BinaryFunction(args, message); | 198 typedef _BinaryFunction(args, message); |
| 202 | 199 |
| 203 /** | 200 /** |
| 204 * Takes the real entry point as argument and invokes it with the | 201 * Takes the real entry point as argument and invokes it with the |
| 205 * initial message. Defers execution of the entry point until the | 202 * initial message. Defers execution of the entry point until the |
| 206 * isolate is in the message loop. | 203 * isolate is in the message loop. |
| 207 */ | 204 */ |
| 208 void _startMainIsolate(Function entryPoint, List<String> args) { | 205 void _startMainIsolate(Function entryPoint, |
| 209 _startIsolate( | 206 List<String> args) { |
| 210 null, // no parent port | 207 _startIsolate(null, // no parent port |
| 211 entryPoint, | 208 entryPoint, |
| 212 args, | 209 args, |
| 213 null, // no message | 210 null, // no message |
| 214 true, // isSpawnUri | 211 true, // isSpawnUri |
| 215 null, // no control port | 212 null, // no control port |
| 216 null); // no capabilities | 213 null); // no capabilities |
| 217 } | 214 } |
| 218 | 215 |
| 219 /** | 216 /** |
| 220 * Takes the real entry point as argument and invokes it with the initial | 217 * Takes the real entry point as argument and invokes it with the initial |
| 221 * message. | 218 * message. |
| 222 */ | 219 */ |
| 223 void _startIsolate( | 220 void _startIsolate(SendPort parentPort, |
| 224 SendPort parentPort, | 221 Function entryPoint, |
| 225 Function entryPoint, | 222 List<String> args, |
| 226 List<String> args, | 223 var message, |
| 227 var message, | 224 bool isSpawnUri, |
| 228 bool isSpawnUri, | 225 RawReceivePort controlPort, |
| 229 RawReceivePort controlPort, | 226 List capabilities) { |
| 230 List capabilities) { | |
| 231 // The control port (aka the main isolate port) does not handle any messages. | 227 // The control port (aka the main isolate port) does not handle any messages. |
| 232 if (controlPort != null) { | 228 if (controlPort != null) { |
| 233 controlPort.handler = (_) {}; // Nobody home on the control port. | 229 controlPort.handler = (_) {}; // Nobody home on the control port. |
| 234 } | 230 } |
| 235 | 231 |
| 236 if (parentPort != null) { | 232 if (parentPort != null) { |
| 237 // Build a message to our parent isolate providing access to the | 233 // Build a message to our parent isolate providing access to the |
| 238 // current isolate's control port and capabilities. | 234 // current isolate's control port and capabilities. |
| 239 // | 235 // |
| 240 // TODO(floitsch): Send an error message if we can't find the entry point. | 236 // TODO(floitsch): Send an error message if we can't find the entry point. |
| 241 var readyMessage = new List(2); | 237 var readyMessage = new List(2); |
| 242 readyMessage[0] = controlPort.sendPort; | 238 readyMessage[0] = controlPort.sendPort; |
| 243 readyMessage[1] = capabilities; | 239 readyMessage[1] = capabilities; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 265 entryPoint(); | 261 entryPoint(); |
| 266 } | 262 } |
| 267 } else { | 263 } else { |
| 268 entryPoint(message); | 264 entryPoint(message); |
| 269 } | 265 } |
| 270 }; | 266 }; |
| 271 // Make sure the message handler is triggered. | 267 // Make sure the message handler is triggered. |
| 272 port.sendPort.send(null); | 268 port.sendPort.send(null); |
| 273 } | 269 } |
| 274 | 270 |
| 275 @patch | 271 @patch class Isolate { |
| 276 class Isolate { | |
| 277 static final _currentIsolate = _getCurrentIsolate(); | 272 static final _currentIsolate = _getCurrentIsolate(); |
| 278 static final _rootUri = _getCurrentRootUri(); | 273 static final _rootUri = _getCurrentRootUri(); |
| 279 | 274 |
| 280 @patch | 275 @patch static Isolate get current => _currentIsolate; |
| 281 static Isolate get current => _currentIsolate; | |
| 282 | 276 |
| 283 @patch | 277 @patch static Future<Uri> get packageRoot { |
| 284 static Future<Uri> get packageRoot { | |
| 285 var hook = VMLibraryHooks.packageRootUriFuture; | 278 var hook = VMLibraryHooks.packageRootUriFuture; |
| 286 if (hook == null) { | 279 if (hook == null) { |
| 287 throw new UnsupportedError("Isolate.packageRoot"); | 280 throw new UnsupportedError("Isolate.packageRoot"); |
| 288 } | 281 } |
| 289 return hook(); | 282 return hook(); |
| 290 } | 283 } |
| 291 | 284 |
| 292 @patch | 285 @patch static Future<Uri> get packageConfig { |
| 293 static Future<Uri> get packageConfig { | |
| 294 var hook = VMLibraryHooks.packageConfigUriFuture; | 286 var hook = VMLibraryHooks.packageConfigUriFuture; |
| 295 if (hook == null) { | 287 if (hook == null) { |
| 296 throw new UnsupportedError("Isolate.packageConfig"); | 288 throw new UnsupportedError("Isolate.packageConfig"); |
| 297 } | 289 } |
| 298 return hook(); | 290 return hook(); |
| 299 } | 291 } |
| 300 | 292 |
| 301 @patch | 293 @patch static Future<Uri> resolvePackageUri(Uri packageUri) { |
| 302 static Future<Uri> resolvePackageUri(Uri packageUri) { | |
| 303 var hook = VMLibraryHooks.resolvePackageUriFuture; | 294 var hook = VMLibraryHooks.resolvePackageUriFuture; |
| 304 if (hook == null) { | 295 if (hook == null) { |
| 305 throw new UnsupportedError("Isolate.resolvePackageUri"); | 296 throw new UnsupportedError("Isolate.resolvePackageUri"); |
| 306 } | 297 } |
| 307 return hook(packageUri); | 298 return hook(packageUri); |
| 308 } | 299 } |
| 309 | 300 |
| 310 static bool _packageSupported() => | 301 static bool _packageSupported() => |
| 311 (VMLibraryHooks.packageRootUriFuture != null) && | 302 (VMLibraryHooks.packageRootUriFuture != null) && |
| 312 (VMLibraryHooks.packageConfigUriFuture != null) && | 303 (VMLibraryHooks.packageConfigUriFuture != null) && |
| 313 (VMLibraryHooks.resolvePackageUriFuture != null); | 304 (VMLibraryHooks.resolvePackageUriFuture != null); |
| 314 | 305 |
| 315 @patch | 306 @patch static Future<Isolate> spawn( |
| 316 static Future<Isolate> spawn(void entryPoint(message), var message, | 307 void entryPoint(message), var message, |
| 317 {bool paused: false, | 308 {bool paused: false, bool errorsAreFatal, |
| 318 bool errorsAreFatal, | 309 SendPort onExit, SendPort onError}) async { |
| 319 SendPort onExit, | |
| 320 SendPort onError}) async { | |
| 321 // `paused` isn't handled yet. | 310 // `paused` isn't handled yet. |
| 322 RawReceivePort readyPort; | 311 RawReceivePort readyPort; |
| 323 try { | 312 try { |
| 324 // Check for the type of `entryPoint` on the spawning isolate to make | 313 // Check for the type of `entryPoint` on the spawning isolate to make |
| 325 // error-handling easier. | 314 // error-handling easier. |
| 326 if (entryPoint is! _UnaryFunction) { | 315 if (entryPoint is! _UnaryFunction) { |
| 327 throw new ArgumentError(entryPoint); | 316 throw new ArgumentError(entryPoint); |
| 328 } | 317 } |
| 329 // The VM will invoke [_startIsolate] with entryPoint as argument. | 318 // The VM will invoke [_startIsolate] with entryPoint as argument. |
| 330 readyPort = new RawReceivePort(); | 319 readyPort = new RawReceivePort(); |
| 331 | 320 |
| 332 // We do not inherit the package root or package config settings | 321 // We do not inherit the package root or package config settings |
| 333 // from the parent isolate, instead we use the values that were | 322 // from the parent isolate, instead we use the values that were |
| 334 // set on the command line. | 323 // set on the command line. |
| 335 var packageRoot = VMLibraryHooks.packageRootString; | 324 var packageRoot = VMLibraryHooks.packageRootString; |
| 336 var packageConfig = VMLibraryHooks.packageConfigString; | 325 var packageConfig = VMLibraryHooks.packageConfigString; |
| 337 var script = VMLibraryHooks.platformScript; | 326 var script = VMLibraryHooks.platformScript; |
| 338 if (script == null) { | 327 if (script == null) { |
| 339 // We do not have enough information to support spawning the new | 328 // We do not have enough information to support spawning the new |
| 340 // isolate. | 329 // isolate. |
| 341 throw new UnsupportedError("Isolate.spawn"); | 330 throw new UnsupportedError("Isolate.spawn"); |
| 342 } | 331 } |
| 343 if (script.scheme == "package") { | 332 if (script.scheme == "package") { |
| 344 script = await Isolate.resolvePackageUri(script); | 333 script = await Isolate.resolvePackageUri(script); |
| 345 } | 334 } |
| 346 | 335 |
| 347 _spawnFunction(readyPort.sendPort, script.toString(), entryPoint, message, | 336 _spawnFunction(readyPort.sendPort, script.toString(), entryPoint, message, |
| 348 paused, errorsAreFatal, onExit, onError, packageRoot, packageConfig); | 337 paused, errorsAreFatal, onExit, onError, |
| 338 packageRoot, packageConfig); |
| 349 return await _spawnCommon(readyPort); | 339 return await _spawnCommon(readyPort); |
| 350 } catch (e, st) { | 340 } catch (e, st) { |
| 351 if (readyPort != null) { | 341 if (readyPort != null) { |
| 352 readyPort.close(); | 342 readyPort.close(); |
| 353 } | 343 } |
| 354 return await new Future<Isolate>.error(e, st); | 344 return await new Future<Isolate>.error(e, st); |
| 355 } | 345 } |
| 356 } | 346 } |
| 357 | 347 |
| 358 @patch | 348 @patch static Future<Isolate> spawnUri( |
| 359 static Future<Isolate> spawnUri(Uri uri, List<String> args, var message, | 349 Uri uri, List<String> args, var message, |
| 360 {bool paused: false, | 350 {bool paused: false, |
| 361 SendPort onExit, | 351 SendPort onExit, |
| 362 SendPort onError, | 352 SendPort onError, |
| 363 bool errorsAreFatal, | 353 bool errorsAreFatal, |
| 364 bool checked, | 354 bool checked, |
| 365 Map<String, String> environment, | 355 Map<String, String> environment, |
| 366 Uri packageRoot, | 356 Uri packageRoot, |
| 367 Uri packageConfig, | 357 Uri packageConfig, |
| 368 bool automaticPackageResolution: false}) async { | 358 bool automaticPackageResolution: false}) async { |
| 369 RawReceivePort readyPort; | 359 RawReceivePort readyPort; |
| 370 if (environment != null) { | 360 if (environment != null) { |
| 371 throw new UnimplementedError("environment"); | 361 throw new UnimplementedError("environment"); |
| 372 } | 362 } |
| 373 | 363 |
| 374 // Verify that no mutually exclusive arguments have been passed. | 364 // Verify that no mutually exclusive arguments have been passed. |
| 375 if (automaticPackageResolution) { | 365 if (automaticPackageResolution) { |
| 376 if (packageRoot != null) { | 366 if (packageRoot != null) { |
| 377 throw new ArgumentError("Cannot simultaneously request " | 367 throw new ArgumentError("Cannot simultaneously request " |
| 378 "automaticPackageResolution and specify a" | 368 "automaticPackageResolution and specify a" |
| 379 "packageRoot."); | 369 "packageRoot."); |
| 380 } | 370 } |
| 381 if (packageConfig != null) { | 371 if (packageConfig != null) { |
| 382 throw new ArgumentError("Cannot simultaneously request " | 372 throw new ArgumentError("Cannot simultaneously request " |
| 383 "automaticPackageResolution and specify a" | 373 "automaticPackageResolution and specify a" |
| 384 "packageConfig."); | 374 "packageConfig."); |
| 385 } | 375 } |
| 386 } else { | 376 } else { |
| 387 if ((packageRoot != null) && (packageConfig != null)) { | 377 if ((packageRoot != null) && (packageConfig != null)) { |
| 388 throw new ArgumentError("Cannot simultaneously specify a " | 378 throw new ArgumentError("Cannot simultaneously specify a " |
| 389 "packageRoot and a packageConfig."); | 379 "packageRoot and a packageConfig."); |
| 390 } | 380 } |
| 391 } | 381 } |
| 392 try { | 382 try { |
| 393 // Resolve the uri against the current isolate's root Uri first. | 383 // Resolve the uri against the current isolate's root Uri first. |
| 394 var spawnedUri = _rootUri.resolveUri(uri); | 384 var spawnedUri = _rootUri.resolveUri(uri); |
| 395 | 385 |
| 396 // Inherit this isolate's package resolution setup if not overridden. | 386 // Inherit this isolate's package resolution setup if not overridden. |
| 397 if (!automaticPackageResolution && | 387 if (!automaticPackageResolution && |
| 398 (packageRoot == null) && | 388 (packageRoot == null) && |
| 399 (packageConfig == null)) { | 389 (packageConfig == null)) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 416 if (packageConfig.scheme == "package") { | 406 if (packageConfig.scheme == "package") { |
| 417 packageConfig = await Isolate.resolvePackageUri(packageConfig); | 407 packageConfig = await Isolate.resolvePackageUri(packageConfig); |
| 418 } | 408 } |
| 419 } | 409 } |
| 420 | 410 |
| 421 // The VM will invoke [_startIsolate] and not `main`. | 411 // The VM will invoke [_startIsolate] and not `main`. |
| 422 readyPort = new RawReceivePort(); | 412 readyPort = new RawReceivePort(); |
| 423 var packageRootString = packageRoot?.toString(); | 413 var packageRootString = packageRoot?.toString(); |
| 424 var packageConfigString = packageConfig?.toString(); | 414 var packageConfigString = packageConfig?.toString(); |
| 425 | 415 |
| 426 _spawnUri( | 416 _spawnUri(readyPort.sendPort, spawnedUri.toString(), |
| 427 readyPort.sendPort, | 417 args, message, |
| 428 spawnedUri.toString(), | 418 paused, onExit, onError, |
| 429 args, | 419 errorsAreFatal, checked, |
| 430 message, | 420 null, /* environment */ |
| 431 paused, | 421 packageRootString, packageConfigString); |
| 432 onExit, | |
| 433 onError, | |
| 434 errorsAreFatal, | |
| 435 checked, | |
| 436 null, | |
| 437 /* environment */ | |
| 438 packageRootString, | |
| 439 packageConfigString); | |
| 440 return await _spawnCommon(readyPort); | 422 return await _spawnCommon(readyPort); |
| 441 } catch (e, st) { | 423 } catch (e, st) { |
| 442 if (readyPort != null) { | 424 if (readyPort != null) { |
| 443 readyPort.close(); | 425 readyPort.close(); |
| 444 } | 426 } |
| 445 rethrow; | 427 rethrow; |
| 446 } | 428 } |
| 447 } | 429 } |
| 448 | 430 |
| 449 static Future<Isolate> _spawnCommon(RawReceivePort readyPort) { | 431 static Future<Isolate> _spawnCommon(RawReceivePort readyPort) { |
| 450 Completer completer = new Completer<Isolate>.sync(); | 432 Completer completer = new Completer<Isolate>.sync(); |
| 451 readyPort.handler = (readyMessage) { | 433 readyPort.handler = (readyMessage) { |
| 452 readyPort.close(); | 434 readyPort.close(); |
| 453 if (readyMessage is List && readyMessage.length == 2) { | 435 if (readyMessage is List && readyMessage.length == 2) { |
| 454 SendPort controlPort = readyMessage[0]; | 436 SendPort controlPort = readyMessage[0]; |
| 455 List capabilities = readyMessage[1]; | 437 List capabilities = readyMessage[1]; |
| 456 completer.complete(new Isolate(controlPort, | 438 completer.complete(new Isolate(controlPort, |
| 457 pauseCapability: capabilities[0], | 439 pauseCapability: capabilities[0], |
| 458 terminateCapability: capabilities[1])); | 440 terminateCapability: capabilities[1])); |
| 459 } else if (readyMessage is String) { | 441 } else if (readyMessage is String) { |
| 460 // We encountered an error while starting the new isolate. | 442 // We encountered an error while starting the new isolate. |
| 461 completer.completeError(new IsolateSpawnException( | 443 completer.completeError(new IsolateSpawnException( |
| 462 'Unable to spawn isolate: ${readyMessage}')); | 444 'Unable to spawn isolate: ${readyMessage}')); |
| 463 } else { | 445 } else { |
| 464 // This shouldn't happen. | 446 // This shouldn't happen. |
| 465 completer.completeError(new IsolateSpawnException( | 447 completer.completeError(new IsolateSpawnException( |
| 466 "Internal error: unexpected format for ready message: " | 448 "Internal error: unexpected format for ready message: " |
| 467 "'${readyMessage}'")); | 449 "'${readyMessage}'")); |
| 468 } | 450 } |
| 469 }; | 451 }; |
| 470 return completer.future; | 452 return completer.future; |
| 471 } | 453 } |
| 472 | 454 |
| 473 // TODO(iposva): Cleanup to have only one definition. | 455 // TODO(iposva): Cleanup to have only one definition. |
| 474 // These values need to be kept in sync with the class IsolateMessageHandler | 456 // These values need to be kept in sync with the class IsolateMessageHandler |
| 475 // in vm/isolate.cc. | 457 // in vm/isolate.cc. |
| 476 static const _PAUSE = 1; | 458 static const _PAUSE = 1; |
| 477 static const _RESUME = 2; | 459 static const _RESUME = 2; |
| 478 static const _PING = 3; | 460 static const _PING = 3; |
| 479 static const _KILL = 4; | 461 static const _KILL = 4; |
| 480 static const _ADD_EXIT = 5; | 462 static const _ADD_EXIT = 5; |
| 481 static const _DEL_EXIT = 6; | 463 static const _DEL_EXIT = 6; |
| 482 static const _ADD_ERROR = 7; | 464 static const _ADD_ERROR = 7; |
| 483 static const _DEL_ERROR = 8; | 465 static const _DEL_ERROR = 8; |
| 484 static const _ERROR_FATAL = 9; | 466 static const _ERROR_FATAL = 9; |
| 485 | 467 |
| 486 static void _spawnFunction( | |
| 487 SendPort readyPort, | |
| 488 String uri, | |
| 489 Function topLevelFunction, | |
| 490 var message, | |
| 491 bool paused, | |
| 492 bool errorsAreFatal, | |
| 493 SendPort onExit, | |
| 494 SendPort onError, | |
| 495 String packageRoot, | |
| 496 String packageConfig) native "Isolate_spawnFunction"; | |
| 497 | 468 |
| 498 static void _spawnUri( | 469 static void _spawnFunction(SendPort readyPort, String uri, |
| 499 SendPort readyPort, | 470 Function topLevelFunction, |
| 500 String uri, | 471 var message, bool paused, bool errorsAreFatal, |
| 501 List<String> args, | 472 SendPort onExit, SendPort onError, |
| 502 var message, | 473 String packageRoot, String packageConfig) |
| 503 bool paused, | 474 native "Isolate_spawnFunction"; |
| 504 SendPort onExit, | 475 |
| 505 SendPort onError, | 476 static void _spawnUri(SendPort readyPort, String uri, |
| 506 bool errorsAreFatal, | 477 List<String> args, var message, |
| 507 bool checked, | 478 bool paused, SendPort onExit, SendPort onError, |
| 508 List environment, | 479 bool errorsAreFatal, bool checked, |
| 509 String packageRoot, | 480 List environment, |
| 510 String packageConfig) native "Isolate_spawnUri"; | 481 String packageRoot, String packageConfig) |
| 482 native "Isolate_spawnUri"; |
| 511 | 483 |
| 512 static void _sendOOB(port, msg) native "Isolate_sendOOB"; | 484 static void _sendOOB(port, msg) native "Isolate_sendOOB"; |
| 513 | 485 |
| 514 @patch | 486 @patch void _pause(Capability resumeCapability) { |
| 515 void _pause(Capability resumeCapability) { | |
| 516 var msg = new List(4) | 487 var msg = new List(4) |
| 517 ..[0] = 0 // Make room for OOB message type. | 488 ..[0] = 0 // Make room for OOB message type. |
| 518 ..[1] = _PAUSE | 489 ..[1] = _PAUSE |
| 519 ..[2] = pauseCapability | 490 ..[2] = pauseCapability |
| 520 ..[3] = resumeCapability; | 491 ..[3] = resumeCapability; |
| 521 _sendOOB(controlPort, msg); | 492 _sendOOB(controlPort, msg); |
| 522 } | 493 } |
| 523 | 494 |
| 524 @patch | 495 @patch void resume(Capability resumeCapability) { |
| 525 void resume(Capability resumeCapability) { | |
| 526 var msg = new List(4) | 496 var msg = new List(4) |
| 527 ..[0] = 0 // Make room for OOB message type. | 497 ..[0] = 0 // Make room for OOB message type. |
| 528 ..[1] = _RESUME | 498 ..[1] = _RESUME |
| 529 ..[2] = pauseCapability | 499 ..[2] = pauseCapability |
| 530 ..[3] = resumeCapability; | 500 ..[3] = resumeCapability; |
| 531 _sendOOB(controlPort, msg); | 501 _sendOOB(controlPort, msg); |
| 532 } | 502 } |
| 533 | 503 |
| 534 @patch | 504 @patch void addOnExitListener(SendPort responsePort, |
| 535 void addOnExitListener(SendPort responsePort, {Object response}) { | 505 {Object response}) { |
| 536 var msg = new List(4) | 506 var msg = new List(4) |
| 537 ..[0] = 0 // Make room for OOB message type. | 507 ..[0] = 0 // Make room for OOB message type. |
| 538 ..[1] = _ADD_EXIT | 508 ..[1] = _ADD_EXIT |
| 539 ..[2] = responsePort | 509 ..[2] = responsePort |
| 540 ..[3] = response; | 510 ..[3] = response; |
| 541 _sendOOB(controlPort, msg); | 511 _sendOOB(controlPort, msg); |
| 542 } | 512 } |
| 543 | 513 |
| 544 @patch | 514 @patch void removeOnExitListener(SendPort responsePort) { |
| 545 void removeOnExitListener(SendPort responsePort) { | |
| 546 var msg = new List(3) | 515 var msg = new List(3) |
| 547 ..[0] = 0 // Make room for OOB message type. | 516 ..[0] = 0 // Make room for OOB message type. |
| 548 ..[1] = _DEL_EXIT | 517 ..[1] = _DEL_EXIT |
| 549 ..[2] = responsePort; | 518 ..[2] = responsePort; |
| 550 _sendOOB(controlPort, msg); | 519 _sendOOB(controlPort, msg); |
| 551 } | 520 } |
| 552 | 521 |
| 553 @patch | 522 @patch void setErrorsFatal(bool errorsAreFatal) { |
| 554 void setErrorsFatal(bool errorsAreFatal) { | |
| 555 var msg = new List(4) | 523 var msg = new List(4) |
| 556 ..[0] = 0 // Make room for OOB message type. | 524 ..[0] = 0 // Make room for OOB message type. |
| 557 ..[1] = _ERROR_FATAL | 525 ..[1] = _ERROR_FATAL |
| 558 ..[2] = terminateCapability | 526 ..[2] = terminateCapability |
| 559 ..[3] = errorsAreFatal; | 527 ..[3] = errorsAreFatal; |
| 560 _sendOOB(controlPort, msg); | 528 _sendOOB(controlPort, msg); |
| 561 } | 529 } |
| 562 | 530 |
| 563 @patch | 531 @patch void kill({int priority: BEFORE_NEXT_EVENT}) { |
| 564 void kill({int priority: BEFORE_NEXT_EVENT}) { | |
| 565 var msg = new List(4) | 532 var msg = new List(4) |
| 566 ..[0] = 0 // Make room for OOB message type. | 533 ..[0] = 0 // Make room for OOB message type. |
| 567 ..[1] = _KILL | 534 ..[1] = _KILL |
| 568 ..[2] = terminateCapability | 535 ..[2] = terminateCapability |
| 569 ..[3] = priority; | 536 ..[3] = priority; |
| 570 _sendOOB(controlPort, msg); | 537 _sendOOB(controlPort, msg); |
| 571 } | 538 } |
| 572 | 539 |
| 573 @patch | 540 @patch void ping(SendPort responsePort, {Object response, |
| 574 void ping(SendPort responsePort, {Object response, int priority: IMMEDIATE}) { | 541 int priority: IMMEDIATE}) { |
| 575 var msg = new List(5) | 542 var msg = new List(5) |
| 576 ..[0] = 0 // Make room for OOM message type. | 543 ..[0] = 0 // Make room for OOM message type. |
| 577 ..[1] = _PING | 544 ..[1] = _PING |
| 578 ..[2] = responsePort | 545 ..[2] = responsePort |
| 579 ..[3] = priority | 546 ..[3] = priority |
| 580 ..[4] = response; | 547 ..[4] = response; |
| 581 _sendOOB(controlPort, msg); | 548 _sendOOB(controlPort, msg); |
| 582 } | 549 } |
| 583 | 550 |
| 584 @patch | 551 @patch void addErrorListener(SendPort port) { |
| 585 void addErrorListener(SendPort port) { | |
| 586 var msg = new List(3) | 552 var msg = new List(3) |
| 587 ..[0] = 0 // Make room for OOB message type. | 553 ..[0] = 0 // Make room for OOB message type. |
| 588 ..[1] = _ADD_ERROR | 554 ..[1] = _ADD_ERROR |
| 589 ..[2] = port; | 555 ..[2] = port; |
| 590 _sendOOB(controlPort, msg); | 556 _sendOOB(controlPort, msg); |
| 591 } | 557 } |
| 592 | 558 |
| 593 @patch | 559 @patch void removeErrorListener(SendPort port) { |
| 594 void removeErrorListener(SendPort port) { | |
| 595 var msg = new List(3) | 560 var msg = new List(3) |
| 596 ..[0] = 0 // Make room for OOB message type. | 561 ..[0] = 0 // Make room for OOB message type. |
| 597 ..[1] = _DEL_ERROR | 562 ..[1] = _DEL_ERROR |
| 598 ..[2] = port; | 563 ..[2] = port; |
| 599 _sendOOB(controlPort, msg); | 564 _sendOOB(controlPort, msg); |
| 600 } | 565 } |
| 601 | 566 |
| 602 static Isolate _getCurrentIsolate() { | 567 static Isolate _getCurrentIsolate() { |
| 603 List portAndCapabilities = _getPortAndCapabilitiesOfCurrentIsolate(); | 568 List portAndCapabilities = _getPortAndCapabilitiesOfCurrentIsolate(); |
| 604 return new Isolate(portAndCapabilities[0], | 569 return new Isolate(portAndCapabilities[0], |
| 605 pauseCapability: portAndCapabilities[1], | 570 pauseCapability: portAndCapabilities[1], |
| 606 terminateCapability: portAndCapabilities[2]); | 571 terminateCapability: portAndCapabilities[2]); |
| 607 } | 572 } |
| 608 | 573 |
| 609 static List _getPortAndCapabilitiesOfCurrentIsolate() | 574 static List _getPortAndCapabilitiesOfCurrentIsolate() |
| 610 native "Isolate_getPortAndCapabilitiesOfCurrentIsolate"; | 575 native "Isolate_getPortAndCapabilitiesOfCurrentIsolate"; |
| 611 | 576 |
| 612 static Uri _getCurrentRootUri() { | 577 static Uri _getCurrentRootUri() { |
| 613 try { | 578 try { |
| 614 return Uri.parse(_getCurrentRootUriStr()); | 579 return Uri.parse(_getCurrentRootUriStr()); |
| 615 } catch (e, s) { | 580 } catch (e, s) { |
| 616 return null; | 581 return null; |
| 617 } | 582 } |
| 618 } | 583 } |
| 619 | 584 |
| 620 static String _getCurrentRootUriStr() native "Isolate_getCurrentRootUriStr"; | 585 static String _getCurrentRootUriStr() |
| 586 native "Isolate_getCurrentRootUriStr"; |
| 621 } | 587 } |
| OLD | NEW |