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 |