mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 16:41:07 +00:00
Add Isolate.current getter, returning the current isolate as an Isolate object.
R=floitsch@google.com Review URL: https://codereview.chromium.org//771993003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@42499 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
efad8e46a1
commit
cf724d70a9
|
@ -267,6 +267,17 @@ DEFINE_NATIVE_ENTRY(Isolate_spawnUri, 5) {
|
|||
}
|
||||
|
||||
|
||||
DEFINE_NATIVE_ENTRY(Isolate_getPortAndCapabilitiesOfCurrentIsolate, 0) {
|
||||
const Array& result = Array::Handle(Array::New(3));
|
||||
result.SetAt(0, SendPort::Handle(SendPort::New(isolate->main_port())));
|
||||
result.SetAt(1, Capability::Handle(
|
||||
Capability::New(isolate->pause_capability())));
|
||||
result.SetAt(2, Capability::Handle(
|
||||
Capability::New(isolate->terminate_capability())));
|
||||
return result.raw();
|
||||
}
|
||||
|
||||
|
||||
DEFINE_NATIVE_ENTRY(Isolate_sendOOB, 2) {
|
||||
GET_NON_NULL_NATIVE_ARGUMENT(SendPort, port, arguments->NativeArgAt(0));
|
||||
GET_NON_NULL_NATIVE_ARGUMENT(Array, msg, arguments->NativeArgAt(1));
|
||||
|
|
|
@ -256,6 +256,10 @@ void _startIsolate(SendPort parentPort,
|
|||
}
|
||||
|
||||
patch class Isolate {
|
||||
static final _currentIsolate = _getCurrentIsolate();
|
||||
|
||||
/* patch */ static Isolate get current => _currentIsolate;
|
||||
|
||||
/* patch */ static Future<Isolate> spawn(
|
||||
void entryPoint(message), var message, { bool paused: false }) {
|
||||
// `paused` isn't handled yet.
|
||||
|
@ -392,4 +396,14 @@ patch class Isolate {
|
|||
/* patch */ void removeErrorListener(SendPort port) {
|
||||
throw new UnsupportedError("removeErrorListener");
|
||||
}
|
||||
|
||||
static Isolate _getCurrentIsolate() {
|
||||
List portAndCapabilities = _getPortAndCapabilitiesOfCurrentIsolate();
|
||||
return new Isolate(portAndCapabilities[0],
|
||||
pauseCapability: portAndCapabilities[1],
|
||||
terminateCapability: portAndCapabilities[2]);
|
||||
}
|
||||
|
||||
static List _getPortAndCapabilitiesOfCurrentIsolate()
|
||||
native "Isolate_getPortAndCapabilitiesOfCurrentIsolate";
|
||||
}
|
||||
|
|
|
@ -294,6 +294,7 @@ namespace dart {
|
|||
V(Int32x4_select, 3) \
|
||||
V(Isolate_spawnFunction, 3) \
|
||||
V(Isolate_spawnUri, 5) \
|
||||
V(Isolate_getPortAndCapabilitiesOfCurrentIsolate, 0) \
|
||||
V(Isolate_sendOOB, 2) \
|
||||
V(Mirrors_evalInLibraryWithPrivateKey, 2) \
|
||||
V(Mirrors_makeLocalClassMirror, 1) \
|
||||
|
|
|
@ -1035,6 +1035,13 @@ class IsolateNatives {
|
|||
}, 'nonworker start');
|
||||
}
|
||||
|
||||
static Isolate get currentIsolate {
|
||||
_IsolateContext context = JS_CURRENT_ISOLATE_CONTEXT();
|
||||
return new Isolate(context.controlPort.sendPort,
|
||||
pauseCapability: context.pauseCapability,
|
||||
terminateCapability: context.terminateCapability);
|
||||
}
|
||||
|
||||
static void _startIsolate(Function topLevel,
|
||||
List<String> args, message,
|
||||
bool isSpawnUri,
|
||||
|
|
|
@ -14,6 +14,13 @@ import 'dart:_isolate_helper' show CapabilityImpl,
|
|||
|
||||
@patch
|
||||
class Isolate {
|
||||
static final _currentIsolateCache = IsolateNatives.currentIsolate;
|
||||
|
||||
// `current` must be a getter, not just a final field,
|
||||
// to match the external declaration.
|
||||
@patch
|
||||
static Isolate get current => _currentIsolateCache;
|
||||
|
||||
@patch
|
||||
static Future<Isolate> spawn(void entryPoint(message), var message,
|
||||
{ bool paused: false }) {
|
||||
|
|
|
@ -119,6 +119,15 @@ class Isolate {
|
|||
Isolate(this.controlPort, {this.pauseCapability,
|
||||
this.terminateCapability});
|
||||
|
||||
/**
|
||||
* Return the current [Isolate].
|
||||
*
|
||||
* The isolate gives access to the capabilities needed to inspect,
|
||||
* pause or kill the isolate, and allows granting these capabilities
|
||||
* to others.
|
||||
*/
|
||||
external static Isolate get current;
|
||||
|
||||
/**
|
||||
* Creates and spawns an isolate that shares the same code as the current
|
||||
* isolate.
|
||||
|
|
135
tests/isolate/isolate_current_test.dart
Normal file
135
tests/isolate/isolate_current_test.dart
Normal file
|
@ -0,0 +1,135 @@
|
|||
// Copyright (c) 2014, 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.
|
||||
|
||||
library isolate_current_test;
|
||||
import "dart:isolate";
|
||||
import "dart:async";
|
||||
import "package:expect/expect.dart";
|
||||
import "package:async_helper/async_helper.dart";
|
||||
|
||||
void main() {
|
||||
asyncStart();
|
||||
|
||||
Expect.isNotNull(Isolate.current);
|
||||
|
||||
// Sending controlPort and capabilities as list.
|
||||
testSend(i2l, l2i);
|
||||
testSpawnReturnVsCurrent(true);
|
||||
testSpawnReturnVsCurrent2(true);
|
||||
|
||||
// Sending Isolate itself.
|
||||
testSend(id, id);
|
||||
testSpawnReturnVsCurrent(false);
|
||||
testSpawnReturnVsCurrent2(false);
|
||||
|
||||
asyncEnd();
|
||||
}
|
||||
|
||||
/** Test sending the isolate data or isolate through a [SendPort]. */
|
||||
void testSend(i2l, l2i) {
|
||||
asyncStart();
|
||||
RawReceivePort p = new RawReceivePort();
|
||||
Isolate isolate = Isolate.current;
|
||||
p.handler = (list) {
|
||||
var isolate2 = l2i(list);
|
||||
Expect.equals(isolate.controlPort, isolate2.controlPort);
|
||||
Expect.equals(isolate.pauseCapability, isolate2.pauseCapability);
|
||||
Expect.equals(isolate.terminateCapability, isolate2.terminateCapability);
|
||||
p.close();
|
||||
asyncEnd();
|
||||
};
|
||||
p.sendPort.send(i2l(isolate));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the isolate returned by [Isolate.spawn] is the same as
|
||||
* the one returned by [Isolate.current] in the spawned isolate.
|
||||
* Checked in the spawning isolate.
|
||||
*/
|
||||
void testSpawnReturnVsCurrent(bool asList) {
|
||||
asyncStart();
|
||||
Function transform = asList ? l2i : id;
|
||||
Completer response = new Completer();
|
||||
var p = new RawReceivePort();
|
||||
p.handler = (v) {
|
||||
response.complete(transform(v));
|
||||
p.close();
|
||||
};
|
||||
|
||||
Isolate.spawn(replyCurrent, [p.sendPort, asList]).then((Isolate isolate) {
|
||||
return response.future.then((Isolate isolate2) {
|
||||
expectIsolateEquals(isolate, isolate2);
|
||||
asyncEnd();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void replyCurrent(args) {
|
||||
SendPort responsePort = args[0];
|
||||
Function transform = args[1] ? i2l : id;
|
||||
responsePort.send(transform(Isolate.current));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the isolate returned by [Isolate.spawn] is the same as
|
||||
* the one returned by [Isolate.current] in the spawned isolate.
|
||||
* Checked in the spawned isolate.
|
||||
*/
|
||||
void testSpawnReturnVsCurrent2(bool asList) {
|
||||
asyncStart();
|
||||
Function transform = asList ? i2l : id;
|
||||
|
||||
Completer response = new Completer();
|
||||
var p = new RawReceivePort();
|
||||
int state = 0;
|
||||
p.handler = (v) {
|
||||
switch (state) {
|
||||
case 0:
|
||||
response.complete(v);
|
||||
state++;
|
||||
break;
|
||||
case 1:
|
||||
p.close();
|
||||
Expect.isTrue(v);
|
||||
asyncEnd();
|
||||
}
|
||||
};
|
||||
|
||||
Isolate.spawn(expectCurrent, [p.sendPort, asList]).then((Isolate isolate) {
|
||||
return response.future.then((SendPort port) {
|
||||
port.send(transform(isolate));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void expectCurrent(args) {
|
||||
SendPort responsePort = args[0];
|
||||
Function transform = args[1] ? l2i : id;
|
||||
RawReceivePort port = new RawReceivePort();
|
||||
port.handler = (isoData) {
|
||||
Isolate isolate2 = transform(isoData);
|
||||
port.close();
|
||||
Isolate isolate = Isolate.current;
|
||||
expectIsolateEquals(isolate, isolate2);
|
||||
responsePort.send(true);
|
||||
};
|
||||
responsePort.send(port.sendPort);
|
||||
}
|
||||
|
||||
/** Convert isolate to list (of control port and capabilities). */
|
||||
i2l(Isolate isolate) => [isolate.controlPort,
|
||||
isolate.pauseCapability,
|
||||
isolate.terminateCapability];
|
||||
/** Convert list to isolate. */
|
||||
l2i(List list) => new Isolate(list[0], pauseCapability: list[1],
|
||||
terminateCapability: list[2]);
|
||||
|
||||
/** Identity transformation. */
|
||||
id(Isolate isolate) => isolate;
|
||||
|
||||
void expectIsolateEquals(Isolate expect, Isolate actual) {
|
||||
Expect.equals(expect.controlPort, actual.controlPort);
|
||||
Expect.equals(expect.pauseCapability, actual.pauseCapability);
|
||||
Expect.equals(expect.terminateCapability, actual.terminateCapability);
|
||||
}
|
Loading…
Reference in a new issue