Allow nested spawns.

Review URL: https://chromereviews.googleplex.com/3511015

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@31 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
floitsch@google.com 2011-10-05 11:38:17 +00:00
parent f4b71c573b
commit dacfcd5fa2
4 changed files with 146 additions and 8 deletions

View file

@ -158,9 +158,9 @@ function isolate$processWorkerMessage(sender, e) {
var msg = e.data;
switch (msg.command) {
case 'start':
isolate$log("starting worker: " + msg.id + " " + msg.runner);
isolate$log("starting worker: " + msg.id + " " + msg.factoryName);
isolate$initializeWorker(msg.id);
var runnerObject = (isolate$globalThis[msg.runner])();
var runnerObject = (isolate$globalThis[msg.factoryName])();
var serializedReplyTo = msg.replyTo;
isolate$IsolateEvent.enqueue(new isolate$Isolate(), function() {
var replyTo = isolate$deserializeMessage(serializedReplyTo);
@ -168,6 +168,9 @@ function isolate$processWorkerMessage(sender, e) {
});
isolate$runEventLoop();
break;
case 'spawn-worker':
isolate$spawnWorker(msg.factoryName, msg.replyPort);
break;
case 'message':
isolate$sendMessage(msg.workerId, msg.isolateId, msg.portId,
msg.msg, msg.replyTo);
@ -364,12 +367,19 @@ var isolate$thisScript = function() {
}();
function isolate$startWorker(runnable, replyPort) {
if (isolate$inWorker) {
isolate$mainWorker.postMessage("Unimplemented nested spawn.");
throw "Unimplemented";
}
var factory = runnable.getIsolateFactory();
var factoryName = factory.name;
var serializedReplyPort = isolate$serializeMessage(replyPort);
if (isolate$inWorker) {
isolate$mainWorker.postMessage({ command: 'spawn-worker',
factoryName: factoryName,
replyPort: serializedReplyPort } );
} else {
isolate$spawnWorker(factoryName, serializedReplyPort);
}
}
function isolate$spawnWorker(factoryName, serializedReplyPort) {
var worker = new Worker(isolate$thisScript);
worker.onmessage = function(e) {
isolate$processWorkerMessage(worker, e);
@ -380,8 +390,8 @@ function isolate$startWorker(runnable, replyPort) {
isolate$workerRegistry.register(workerId, worker);
worker.postMessage({ command: 'start',
id: workerId,
replyTo: isolate$serializeMessage(replyPort),
runner: factoryName });
replyTo: serializedReplyPort,
factoryName: factoryName });
}
function native_SendPortImpl__sendNow(message, replyTo) {

View file

@ -15,6 +15,8 @@ PromiseBasedTest: Fail # Bug 5246195
StaticStateTest: Fail # Bug 5246195
RequestReplyTest: Crash, Fail # Bug 5395487
CrossIsolateMessageTest: Fail # Bug 5246195
NestedSpawnTest: Fail # Bug 5246195
NestedSpawn2Test: Fail # Bug 5246195
[ $arch == ia32 ]

View file

@ -0,0 +1,76 @@
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Dart test program for testing that isolates can spawn other isolates and
// that the nested isolates can communicate with the main once the spawner has
// disappeared.
#library('NestedSpawn2Test');
#import('TestFramework.dart');
class Isolate1 extends Isolate {
Isolate1() : super.heavy();
void main() {
this.port.receive((msg, replyTo) {
Expect.equals("launch nested!", msg);
new Isolate2().spawn().then((SendPort p) {
p.send(replyTo, null);
this.port.close();
});
});
}
}
String msg0 = "0 there?";
String msg1 = "1 Yes.";
String msg2 = "2 great. Think the other one is already dead?";
String msg3 = "3 Give him some time.";
String msg4 = "4 now?";
String msg5 = "5 Now.";
String msg6 = "6 Great. Bye";
class Isolate2 extends Isolate {
Isolate2() : super.heavy();
void main() {
this.port.receive((mainPort, replyTo) {
this.port.close();
// Do a little ping-pong dance to give the intermediate isolate time to
// die.
mainPort.call(msg0).receive((msg, replyTo) {
Expect.equals("1", msg[0]);
replyTo.call(msg2).receive((msg, replyTo) {
Expect.equals("3", msg[0]);
replyTo.call(msg4).receive((msg, replyTo) {
Expect.equals("5", msg[0]);
replyTo.send(msg6, null);
});
});
});
});
}
}
test(TestExpectation expect) {
expect.completes(new Isolate1().spawn()).then((SendPort port) {
port.call("launch nested!").receive(expect.runs2((msg, replyTo) {
Expect.equals("0", msg[0]);
replyTo.call(msg1).receive(expect.runs2((msg, replyTo) {
Expect.equals("2", msg[0]);
replyTo.call(msg3).receive(expect.runs2((msg, replyTo) {
Expect.equals("4", msg[0]);
replyTo.call(msg5).receive(expect.runs2((msg, replyTo) {
Expect.equals("6", msg[0]);
expect.succeeded();
}));
}));
}));
}));
});
}
main() {
runTests([test]);
}

View file

@ -0,0 +1,50 @@
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Dart test program for testing that isolates can spawn other isolates.
#library('NestedSpawnTest');
#import('TestFramework.dart');
class Isolate1 extends Isolate {
Isolate1() : super.heavy();
void main() {
this.port.receive((msg, replyTo) {
Expect.equals("launch nested!", msg);
new Isolate2().spawn().then((SendPort p) {
p.call("alive?").receive((msg, ignored) {
Expect.equals("and kicking", msg);
replyTo.send(499, null);
this.port.close();
});
});
});
}
}
class Isolate2 extends Isolate {
Isolate2() : super.heavy();
void main() {
this.port.receive((msg, replyTo) {
Expect.equals("alive?", msg);
replyTo.send("and kicking", null);
this.port.close();
});
}
}
test(TestExpectation expect) {
expect.completes(new Isolate1().spawn()).then((SendPort port) {
port.call("launch nested!").receive(expect.runs2((msg, ignored) {
Expect.equals(499, msg);
expect.succeeded();
}));
});
}
main() {
runTests([test]);
}