| Index: sdk/lib/isolate/isolate.dart
|
| diff --git a/sdk/lib/isolate/isolate.dart b/sdk/lib/isolate/isolate.dart
|
| index 3cfc4fc3b8849e3ed11893c2d83301252d6cfd75..3b01d86743a5863bf977ed30886204ce3d551a5d 100644
|
| --- a/sdk/lib/isolate/isolate.dart
|
| +++ b/sdk/lib/isolate/isolate.dart
|
| @@ -16,61 +16,137 @@ library dart.isolate;
|
|
|
| import "dart:async";
|
|
|
| -part "isolate_stream.dart";
|
| -
|
| +/**
|
| + * Thrown when an isolate cannot be created.
|
| + */
|
| class IsolateSpawnException implements Exception {
|
| - const IsolateSpawnException(String this._s);
|
| - String toString() => "IsolateSpawnException: '$_s'";
|
| - final String _s;
|
| + const IsolateSpawnException();
|
| }
|
|
|
| /**
|
| - * The initial ReceivePort available by default for this isolate.
|
| + * A capability is unique among all isolates and can be shared with
|
| + * other isolates.
|
| *
|
| - * This ReceivePort is created automatically
|
| - * and is commonly used to establish
|
| - * the first communication between isolates.
|
| - * (See [spawnFunction] and [spawnUri].)
|
| + * Capabilities are opaque objects. They do not expose what they can be used
|
| + * for.
|
| */
|
| -ReceivePort get port => _Isolate.port;
|
| +class Capability {
|
| +}
|
|
|
| /**
|
| - * Creates and spawns an isolate
|
| - * that shares the same code as the current isolate,
|
| - * but that starts from the specified function.
|
| - *
|
| - * The [topLevelFunction] argument must be
|
| - * a static top-level function or a static method that takes no
|
| - * arguments. It is illegal to pass a function closure.
|
| - *
|
| - * When any isolate starts (even the main script of the application), a default
|
| - * [ReceivePort] is created for it. This port is available from the top-level
|
| - * getter [port] defined in this library.
|
| + * An enum that enumerates permissions that are required to control isolates.
|
| *
|
| - * This function returns a [SendPort] derived from
|
| - * the child isolate's default port.
|
| - *
|
| - * The optional [unhandledExceptionCallback] argument is invoked whenever an
|
| - * exception inside the isolate is unhandled. It can be seen as a big
|
| - * `try/catch` around everything that is executed inside the isolate. The
|
| - * callback should return `true` if it was able to handle the exception.
|
| + * Some control messages require capabilities to be accepted by the isolate.
|
| + * The [Permission] enum gives these capabilities names.
|
| */
|
| -SendPort spawnFunction(void topLevelFunction(),
|
| - [bool unhandledExceptionCallback(IsolateUnhandledException e)])
|
| - => _Isolate.spawnFunction(topLevelFunction, unhandledExceptionCallback);
|
| +class Permission {
|
| + final Symbol _permission;
|
| + const Permission(this._permission);
|
|
|
| -/**
|
| - * Creates and spawns an isolate that runs the code from the specified URI.
|
| - *
|
| - * As with [spawnFunction],
|
| - * the child isolate has a default [ReceivePort],
|
| - * and this function returns a [SendPort] derived from it.
|
| - */
|
| -SendPort spawnUri(String uri) => _Isolate.spawnUri(uri);
|
| + // Mirror-modify basically allows everything, since we can just modify the
|
| + // program to our liking.
|
| + static const FULL_CONTROL = const Permission(#full_control);
|
| + static const MIRROR_INSPECT = const Permission(#mirror_inspect);
|
| + static const SHUTDOWN = const Permission(#shutdown);
|
| + // Allows to control resources (maybe even giving more than usual?).
|
| + static const RESOURCE = const Permission(#resource);
|
| +}
|
| +
|
| +class Isolate {
|
| + /**
|
| + * Creates and spawns an isolate that shares the same code as the current
|
| + * isolate.
|
| + *
|
| + * The argument [entryPoint] specifies the entry point of the spawned
|
| + * isolate. It must be a static top-level function or a static method that
|
| + * takes no arguments. It is not allowed to pass a function closure.
|
| + *
|
| + * The entry-point function is invoked with the initial [message].
|
| + * Usually the initial [message] contains a [SendPort] so
|
| + * that the spawner and spawnee can communicate with each other.
|
| + *
|
| + * Returns a future that will complete with an [Isolate] instance. The
|
| + * isolate instance can be used to control the spawned isolate.
|
| + */
|
| + static Future<Isolate> spawn(void entryPoint(message), var message,
|
| + { startPaused, or, other, Arguments, we, will, find, useful }) {
|
| + }
|
| +
|
| + /**
|
| + * Creates and spawns an isolate that runs the code from the library with
|
| + * the specified URI.
|
| + *
|
| + * The isolate starts executing the top-level `main` function of the library
|
| + * with the given URI. Otherwise similar to [spawn].
|
| + */
|
| + static Future<Isolate> spawnUri(Uri uri, var arguments, { named, args }) {
|
| +
|
| + }
|
| +
|
| + /**
|
| + * Creates a new isolate instance controlling an existing isolate.
|
| + *
|
| + * The new instance controls the isolate that is controlled by the
|
| + * argument [controlPort].
|
| + *
|
| + * The given [permissions] map specifies what the returned instance can
|
| + * do with the existing isolate.
|
| + */
|
| + Isolate.fromControlPort(SendPort controlPort,
|
| + Map<Permission, Capability> permissions)
|
| + : _permissions = permissions,
|
| + controlPort = controlPort;
|
| +
|
| + /**
|
| + * Listening to this stream will install an error handler on the isolate.
|
| + *
|
| + * The installation of the error handler is an asynchronous operation.
|
| + * If one wants to be sure to see all errors, one should start the isolate in
|
| + * a paused state, start listening to the errors, and then only resume the
|
| + * other isolate.
|
| + */
|
| + Stream uncaughtErrors;
|
| +
|
| + /**
|
| + * Pauses the isolate.
|
| + */
|
| + Future pause() {}
|
| +
|
| + /**
|
| + * Resumes the isolate.
|
| + */
|
| + Future resume() {}
|
| +
|
| + Future kill() {
|
| + // Proposed implementation:
|
| + return controlPort.send([_someInternalObjectIdentifyingKillAction,
|
| + _permissions[Permission.SHUTDOWN]]);
|
| + }
|
| +
|
| + /**
|
| + * Since this is an asynchronous operation the state might change before
|
| + * we get a chance to act on it (if someone else has the capability to
|
| + * resume the isolate).
|
| + */
|
| + Future<bool> queryIsPaused() {}
|
| +
|
| + /// This port uniquely identifies the spawned isolate.
|
| + final SendPort controlPort;
|
| +
|
| + final Map<Permission, Capability> _permissions;
|
| +
|
| + /**
|
| + * Clones this Isolate but with limited permissions.
|
| + *
|
| + * When handing out isolates, one should always
|
| + */
|
| + Map<Permission, Capability> extractPermissions(
|
| + Iterable<Permission> permissions) {
|
| + }
|
| +}
|
|
|
| /**
|
| - * Together with [ReceivePort],
|
| - * the only means of communication between isolates.
|
| + * Sends messages to its [ReceivePort]s.
|
| *
|
| * [SendPort]s are created from [ReceivePort]s. Any message sent through
|
| * a [SendPort] is delivered to its respective [ReceivePort]. There might be
|
| @@ -82,8 +158,7 @@ abstract class SendPort {
|
|
|
| /**
|
| * Sends an asynchronous [message] to this send port. The message is copied to
|
| - * the receiving isolate. If specified, the [replyTo] port will be provided to
|
| - * the receiver to facilitate exchanging sequences of messages.
|
| + * the receiving isolate.
|
| *
|
| * The content of [message] can be: primitive values (null, num, bool, double,
|
| * String), instances of [SendPort], and lists and maps whose elements are any
|
| @@ -94,21 +169,8 @@ abstract class SendPort {
|
| * is also possible to send object instances (which would be copied in the
|
| * process). This is currently only supported by the dartvm. For now, the
|
| * dart2js compiler only supports the restricted messages described above.
|
| - *
|
| - * Deprecation note: it is no longer valid to transmit a [ReceivePort] in a
|
| - * message. Previously they were translated to the corresponding send port
|
| - * before being transmitted.
|
| */
|
| - void send(var message, [SendPort replyTo]);
|
| -
|
| - /**
|
| - * Sends a message to this send port and returns a [Future] of the reply.
|
| - * Basically, this internally creates a new receive port, sends a
|
| - * message to this send port with replyTo set to such receive port, and, when
|
| - * a reply is received, it closes the receive port and completes the returned
|
| - * future.
|
| - */
|
| - Future call(var message);
|
| + void send(var message);
|
|
|
| /**
|
| * Tests whether [other] is a [SendPort] pointing to the same
|
| @@ -121,75 +183,52 @@ abstract class SendPort {
|
| * consistent with the == operator.
|
| */
|
| int get hashCode;
|
| -
|
| }
|
|
|
| /**
|
| - * Together with [SendPort], the only means of
|
| - * communication between isolates.
|
| + * Together with [SendPort], the only means of communication between isolates.
|
| *
|
| - * [ReceivePort]s have a [:toSendPort:] method
|
| - * which returns a [SendPort]. Any message that is sent through this [SendPort]
|
| - * is delivered to the [ReceivePort] it has been created from. There, they are
|
| - * dispatched to the callback that has been registered on the receive port.
|
| + * [ReceivePort]s have a `sendport` getter which returns a [SendPort].
|
| + * Any message that is sent through this [SendPort]
|
| + * is delivered to the [ReceivePort] it has been created from. There, the
|
| + * message is dispatched to its listener.
|
| + *
|
| + * A [ReceivePort] is a non-broadcast stream. This means that it buffers
|
| + * incoming messages until a listener is registered. Only one listener can
|
| + * receive messages. See [Stream.asBroadcastStream] for transforming the port
|
| + * to a broadcast stream.
|
| *
|
| * A [ReceivePort] may have many [SendPort]s.
|
| */
|
| -abstract class ReceivePort {
|
| +abstract class ReceivePort implements Stream {
|
|
|
| /**
|
| - * Opens a long-lived port for receiving messages. The returned port
|
| - * must be explicitly closed through [ReceivePort.close].
|
| + * Opens a long-lived port for receiving messages.
|
| + *
|
| + * A [ReceivePort] is a non-broadcast stream. This means that it buffers
|
| + * incoming messages until a listener is registered. Only one listener can
|
| + * receive messages. See [Stream.asBroadcastStream] for transforming the port
|
| + * to a broadcast stream.
|
| + *
|
| + * A receive port is closed by canceling its subscription.
|
| */
|
| external factory ReceivePort();
|
|
|
| /**
|
| - * Sets up a callback function for receiving pending or future
|
| - * messages on this receive port.
|
| - */
|
| - void receive(void callback(var message, SendPort replyTo));
|
| -
|
| - /**
|
| - * Closes this receive port immediately. Pending messages will not
|
| - * be processed and it is impossible to re-open the port. Single-shot
|
| - * reply ports, such as those created through [SendPort.call], are
|
| - * automatically closed when the reply has been received. Multiple
|
| - * invocations of [close] are allowed but ignored.
|
| - */
|
| - void close();
|
| -
|
| - /**
|
| - * Creates a new send port that sends to this receive port. It is legal to
|
| - * create several [SendPort]s from the same [ReceivePort].
|
| - */
|
| - SendPort toSendPort();
|
| -
|
| -}
|
| -
|
| -/**
|
| - * [SendPortSync]s are created from [ReceivePortSync]s. Any message sent through
|
| - * a [SendPortSync] is delivered to its respective [ReceivePortSync]. There
|
| - * might be many [SendPortSync]s for the same [ReceivePortSync].
|
| - *
|
| - * [SendPortSync]s can be transmitted to other isolates.
|
| - */
|
| -abstract class SendPortSync {
|
| - /**
|
| - * Sends a synchronous message to this send port and returns the result.
|
| - */
|
| - callSync(var message);
|
| -
|
| - /**
|
| - * Tests whether [other] is a [SendPortSync] pointing to the same
|
| - * [ReceivePortSync] as this one.
|
| + * Inherited from [Stream].
|
| + *
|
| + * Note that all named arguments are ignored since a ReceivePort will never
|
| + * receive an error, or done message.
|
| */
|
| - bool operator==(var other);
|
| + StreamSubscription listen(void callback(var message),
|
| + { Function onError,
|
| + void onDone(),
|
| + bool cancelOnError });
|
|
|
| /**
|
| - * Returns an immutable hash code for this send port that is
|
| - * consistent with the == operator.
|
| + * Returns a send port that sends to this receive port.
|
| */
|
| - int get hashCode;
|
| + SendPort get sendPort;
|
| }
|
|
|
| // The VM doesn't support accessing external globals in the same library. We
|
| @@ -207,6 +246,7 @@ abstract class _Isolate {
|
| * used to show both the error message and the stack trace for unhandled
|
| * exceptions.
|
| */
|
| +// TODO(floitsch): probably going to remove and replace with something else.
|
| class IsolateUnhandledException implements Exception {
|
| /** Message being handled when exception occurred. */
|
| final message;
|
|
|