| 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 | 6 |
| 7 patch class ReceivePort { | 7 patch class ReceivePort { |
| 8 /* patch */ factory ReceivePort() = _ReceivePortImpl; | 8 /* patch */ factory ReceivePort() = _ReceivePortImpl; |
| 9 | 9 |
| 10 /* patch */ factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) = | 10 /* patch */ factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) = |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 typedef _MainFunctionArgs(args); | 190 typedef _MainFunctionArgs(args); |
| 191 typedef _MainFunctionArgsMessage(args, message); | 191 typedef _MainFunctionArgsMessage(args, message); |
| 192 | 192 |
| 193 /** | 193 /** |
| 194 * Takes the real entry point as argument and invokes it with the | 194 * Takes the real entry point as argument and invokes it with the |
| 195 * initial message. Defers execution of the entry point until the | 195 * initial message. Defers execution of the entry point until the |
| 196 * isolate is in the message loop. | 196 * isolate is in the message loop. |
| 197 */ | 197 */ |
| 198 void _startMainIsolate(Function entryPoint, | 198 void _startMainIsolate(Function entryPoint, |
| 199 List<String> args) { | 199 List<String> args) { |
| 200 RawReceivePort port = new RawReceivePort(); | 200 _startIsolate(null, // no parent port |
| 201 port.handler = (_) { | 201 entryPoint, |
| 202 port.close(); | 202 args, |
| 203 _startIsolate(null, // no parent port | 203 null, // no message |
| 204 entryPoint, | 204 true, // isSpawnUri |
| 205 args, | 205 null, // no control port |
| 206 null, // no message | 206 null); // no capabilities |
| 207 true, // isSpawnUri | |
| 208 null, // no control port | |
| 209 null); // no capabilities | |
| 210 }; | |
| 211 port.sendPort.send(null); | |
| 212 } | 207 } |
| 213 | 208 |
| 214 /** | 209 /** |
| 215 * Takes the real entry point as argument and invokes it with the initial | 210 * Takes the real entry point as argument and invokes it with the initial |
| 216 * message. | 211 * message. |
| 217 */ | 212 */ |
| 218 void _startIsolate(SendPort parentPort, | 213 void _startIsolate(SendPort parentPort, |
| 219 Function entryPoint, | 214 Function entryPoint, |
| 220 List<String> args, | 215 List<String> args, |
| 221 var message, | 216 var message, |
| 222 bool isSpawnUri, | 217 bool isSpawnUri, |
| 223 RawReceivePort controlPort, | 218 RawReceivePort controlPort, |
| 224 List capabilities) { | 219 List capabilities) { |
| 220 // The control port (aka the main isolate port) does not handle any messages. |
| 225 if (controlPort != null) { | 221 if (controlPort != null) { |
| 226 controlPort.handler = (_) {}; // Nobody home on the control port. | 222 controlPort.handler = (_) {}; // Nobody home on the control port. |
| 227 } | 223 } |
| 224 |
| 228 if (parentPort != null) { | 225 if (parentPort != null) { |
| 229 // Build a message to our parent isolate providing access to the | 226 // Build a message to our parent isolate providing access to the |
| 230 // current isolate's control port and capabilities. | 227 // current isolate's control port and capabilities. |
| 231 // | 228 // |
| 232 // TODO(floitsch): Send an error message if we can't find the entry point. | 229 // TODO(floitsch): Send an error message if we can't find the entry point. |
| 233 var readyMessage = new List(2); | 230 var readyMessage = new List(2); |
| 234 readyMessage[0] = controlPort.sendPort; | 231 readyMessage[0] = controlPort.sendPort; |
| 235 readyMessage[1] = capabilities; | 232 readyMessage[1] = capabilities; |
| 236 | 233 |
| 237 // Out of an excess of paranoia we clear the capabilities from the | 234 // Out of an excess of paranoia we clear the capabilities from the |
| 238 // stack. Not really necessary. | 235 // stack. Not really necessary. |
| 239 capabilities = null; | 236 capabilities = null; |
| 240 parentPort.send(readyMessage); | 237 parentPort.send(readyMessage); |
| 241 } | 238 } |
| 242 assert(capabilities == null); | 239 assert(capabilities == null); |
| 243 | 240 |
| 244 if (isSpawnUri) { | 241 // Delay all user code handling to the next run of the message loop. This |
| 245 if (entryPoint is _MainFunctionArgsMessage) { | 242 // allows us to intercept certain conditions in the event dispatch, such as |
| 246 entryPoint(args, message); | 243 // starting in paused state. |
| 247 } else if (entryPoint is _MainFunctionArgs) { | 244 RawReceivePort port = new RawReceivePort(); |
| 248 entryPoint(args); | 245 port.handler = (_) { |
| 246 port.close(); |
| 247 |
| 248 if (isSpawnUri) { |
| 249 if (entryPoint is _MainFunctionArgsMessage) { |
| 250 entryPoint(args, message); |
| 251 } else if (entryPoint is _MainFunctionArgs) { |
| 252 entryPoint(args); |
| 253 } else { |
| 254 entryPoint(); |
| 255 } |
| 249 } else { | 256 } else { |
| 250 entryPoint(); | 257 entryPoint(message); |
| 251 } | 258 } |
| 252 } else { | 259 }; |
| 253 entryPoint(message); | 260 // Make sure the message handler is triggered. |
| 254 } | 261 port.sendPort.send(null); |
| 255 _runPendingImmediateCallback(); | |
| 256 } | 262 } |
| 257 | 263 |
| 258 patch class Isolate { | 264 patch class Isolate { |
| 259 static final _currentIsolate = _getCurrentIsolate(); | 265 static final _currentIsolate = _getCurrentIsolate(); |
| 260 | 266 |
| 261 /* patch */ static Isolate get current => _currentIsolate; | 267 /* patch */ static Isolate get current => _currentIsolate; |
| 262 | 268 |
| 263 /* patch */ static Future<Isolate> spawn( | 269 /* patch */ static Future<Isolate> spawn( |
| 264 void entryPoint(message), var message, { bool paused: false }) { | 270 void entryPoint(message), var message, { bool paused: false }) { |
| 265 // `paused` isn't handled yet. | 271 // `paused` isn't handled yet. |
| 266 RawReceivePort readyPort; | 272 RawReceivePort readyPort; |
| 267 try { | 273 try { |
| 268 // The VM will invoke [_startIsolate] with entryPoint as argument. | 274 // The VM will invoke [_startIsolate] with entryPoint as argument. |
| 269 readyPort = new RawReceivePort(); | 275 readyPort = new RawReceivePort(); |
| 270 _spawnFunction(readyPort.sendPort, entryPoint, message); | 276 _spawnFunction(readyPort.sendPort, entryPoint, message, paused); |
| 271 Completer completer = new Completer<Isolate>.sync(); | 277 Completer completer = new Completer<Isolate>.sync(); |
| 272 readyPort.handler = (readyMessage) { | 278 readyPort.handler = (readyMessage) { |
| 273 readyPort.close(); | 279 readyPort.close(); |
| 274 assert(readyMessage is List); | 280 assert(readyMessage is List); |
| 275 assert(readyMessage.length == 2); | 281 assert(readyMessage.length == 2); |
| 276 SendPort controlPort = readyMessage[0]; | 282 SendPort controlPort = readyMessage[0]; |
| 277 List capabilities = readyMessage[1]; | 283 List capabilities = readyMessage[1]; |
| 278 completer.complete(new Isolate(controlPort, | 284 completer.complete(new Isolate(controlPort, |
| 279 pauseCapability: capabilities[0], | 285 pauseCapability: capabilities[0], |
| 280 terminateCapability: capabilities[1])); | 286 terminateCapability: capabilities[1])); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 291 /* patch */ static Future<Isolate> spawnUri( | 297 /* patch */ static Future<Isolate> spawnUri( |
| 292 Uri uri, List<String> args, var message, | 298 Uri uri, List<String> args, var message, |
| 293 { bool paused: false, Uri packageRoot }) { | 299 { bool paused: false, Uri packageRoot }) { |
| 294 // `paused` isn't handled yet. | 300 // `paused` isn't handled yet. |
| 295 RawReceivePort readyPort; | 301 RawReceivePort readyPort; |
| 296 try { | 302 try { |
| 297 // The VM will invoke [_startIsolate] and not `main`. | 303 // The VM will invoke [_startIsolate] and not `main`. |
| 298 readyPort = new RawReceivePort(); | 304 readyPort = new RawReceivePort(); |
| 299 var packageRootString = | 305 var packageRootString = |
| 300 (packageRoot == null) ? null : packageRoot.toString(); | 306 (packageRoot == null) ? null : packageRoot.toString(); |
| 301 _spawnUri( | 307 _spawnUri(readyPort.sendPort, uri.toString(), args, message, |
| 302 readyPort.sendPort, uri.toString(), args, message, packageRootString); | 308 paused, packageRootString); |
| 303 Completer completer = new Completer<Isolate>.sync(); | 309 Completer completer = new Completer<Isolate>.sync(); |
| 304 readyPort.handler = (readyMessage) { | 310 readyPort.handler = (readyMessage) { |
| 305 readyPort.close(); | 311 readyPort.close(); |
| 306 assert(readyMessage is List); | 312 assert(readyMessage is List); |
| 307 assert(readyMessage.length == 2); | 313 assert(readyMessage.length == 2); |
| 308 SendPort controlPort = readyMessage[0]; | 314 SendPort controlPort = readyMessage[0]; |
| 309 List capabilities = readyMessage[1]; | 315 List capabilities = readyMessage[1]; |
| 310 completer.complete(new Isolate(controlPort, | 316 completer.complete(new Isolate(controlPort, |
| 311 pauseCapability: capabilities[0], | 317 pauseCapability: capabilities[0], |
| 312 terminateCapability: capabilities[1])); | 318 terminateCapability: capabilities[1])); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 324 // TODO(iposva): Cleanup to have only one definition. | 330 // TODO(iposva): Cleanup to have only one definition. |
| 325 // These values need to be kept in sync with the class IsolateMessageHandler | 331 // These values need to be kept in sync with the class IsolateMessageHandler |
| 326 // in vm/isolate.cc. | 332 // in vm/isolate.cc. |
| 327 static const _PAUSE = 1; | 333 static const _PAUSE = 1; |
| 328 static const _RESUME = 2; | 334 static const _RESUME = 2; |
| 329 static const _PING = 3; | 335 static const _PING = 3; |
| 330 static const _KILL = 4; | 336 static const _KILL = 4; |
| 331 | 337 |
| 332 | 338 |
| 333 static SendPort _spawnFunction(SendPort readyPort, Function topLevelFunction, | 339 static SendPort _spawnFunction(SendPort readyPort, Function topLevelFunction, |
| 334 var message) | 340 var message, bool paused) |
| 335 native "Isolate_spawnFunction"; | 341 native "Isolate_spawnFunction"; |
| 336 | 342 |
| 337 static SendPort _spawnUri(SendPort readyPort, String uri, | 343 static SendPort _spawnUri(SendPort readyPort, String uri, |
| 338 List<String> args, var message, | 344 List<String> args, var message, |
| 339 String packageRoot) | 345 bool paused, String packageRoot) |
| 340 native "Isolate_spawnUri"; | 346 native "Isolate_spawnUri"; |
| 341 | 347 |
| 342 static void _sendOOB(port, msg) native "Isolate_sendOOB"; | 348 static void _sendOOB(port, msg) native "Isolate_sendOOB"; |
| 343 | 349 |
| 344 /* patch */ void _pause(Capability resumeCapability) { | 350 /* patch */ void _pause(Capability resumeCapability) { |
| 345 var msg = new List(4) | 351 var msg = new List(4) |
| 346 ..[0] = 0 // Make room for OOB message type. | 352 ..[0] = 0 // Make room for OOB message type. |
| 347 ..[1] = _PAUSE | 353 ..[1] = _PAUSE |
| 348 ..[2] = pauseCapability | 354 ..[2] = pauseCapability |
| 349 ..[3] = resumeCapability; | 355 ..[3] = resumeCapability; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 static Isolate _getCurrentIsolate() { | 406 static Isolate _getCurrentIsolate() { |
| 401 List portAndCapabilities = _getPortAndCapabilitiesOfCurrentIsolate(); | 407 List portAndCapabilities = _getPortAndCapabilitiesOfCurrentIsolate(); |
| 402 return new Isolate(portAndCapabilities[0], | 408 return new Isolate(portAndCapabilities[0], |
| 403 pauseCapability: portAndCapabilities[1], | 409 pauseCapability: portAndCapabilities[1], |
| 404 terminateCapability: portAndCapabilities[2]); | 410 terminateCapability: portAndCapabilities[2]); |
| 405 } | 411 } |
| 406 | 412 |
| 407 static List _getPortAndCapabilitiesOfCurrentIsolate() | 413 static List _getPortAndCapabilitiesOfCurrentIsolate() |
| 408 native "Isolate_getPortAndCapabilitiesOfCurrentIsolate"; | 414 native "Isolate_getPortAndCapabilitiesOfCurrentIsolate"; |
| 409 } | 415 } |
| OLD | NEW |