Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1227)

Side by Side Diff: sdk/lib/isolate/isolate.dart

Issue 20703003: Proposal for new Isolate library. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | sdk/lib/isolate/isolate_stream.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 /** 5 /**
6 * Concurrent programming using _isolates_: 6 * Concurrent programming using _isolates_:
7 * independent workers that are similar to threads 7 * independent workers that are similar to threads
8 * but don't share memory, 8 * but don't share memory,
9 * communicating only via messages. 9 * communicating only via messages.
10 * 10 *
11 * See also: 11 * See also:
12 * [dart:isolate - Concurrency with Isolates](https://www.dartlang.org/docs/dart -up-and-running/contents/ch03.html#ch03-dartisolate---concurrency-with-isolates) 12 * [dart:isolate - Concurrency with Isolates](https://www.dartlang.org/docs/dart -up-and-running/contents/ch03.html#ch03-dartisolate---concurrency-with-isolates)
13 * in the library tour. 13 * in the library tour.
14 */ 14 */
15 library dart.isolate; 15 library dart.isolate;
16 16
17 import "dart:async"; 17 import "dart:async";
18 18
19 part "isolate_stream.dart"; 19 /**
20 20 * Thrown when an isolate cannot be created.
21 */
21 class IsolateSpawnException implements Exception { 22 class IsolateSpawnException implements Exception {
22 const IsolateSpawnException(String this._s); 23 const IsolateSpawnException();
23 String toString() => "IsolateSpawnException: '$_s'";
24 final String _s;
25 } 24 }
26 25
27 /** 26 /**
28 * The initial ReceivePort available by default for this isolate. 27 * A capability is unique among all isolates and can be shared with
28 * other isolates.
29 * 29 *
30 * This ReceivePort is created automatically 30 * Capabilities are opaque objects. They do not expose what they can be used
31 * and is commonly used to establish 31 * for.
32 * the first communication between isolates.
33 * (See [spawnFunction] and [spawnUri].)
34 */ 32 */
35 ReceivePort get port => _Isolate.port; 33 class Capability {
34 }
36 35
37 /** 36 /**
38 * Creates and spawns an isolate 37 * An enum that enumerates permissions that are required to control isolates.
39 * that shares the same code as the current isolate,
40 * but that starts from the specified function.
41 * 38 *
42 * The [topLevelFunction] argument must be 39 * Some control messages require capabilities to be accepted by the isolate.
43 * a static top-level function or a static method that takes no 40 * The [Permission] enum gives these capabilities names.
44 * arguments. It is illegal to pass a function closure.
45 *
46 * When any isolate starts (even the main script of the application), a default
47 * [ReceivePort] is created for it. This port is available from the top-level
48 * getter [port] defined in this library.
49 *
50 * This function returns a [SendPort] derived from
51 * the child isolate's default port.
52 *
53 * The optional [unhandledExceptionCallback] argument is invoked whenever an
54 * exception inside the isolate is unhandled. It can be seen as a big
55 * `try/catch` around everything that is executed inside the isolate. The
56 * callback should return `true` if it was able to handle the exception.
57 */ 41 */
58 SendPort spawnFunction(void topLevelFunction(), 42 class Permission {
59 [bool unhandledExceptionCallback(IsolateUnhandledException e)]) 43 final Symbol _permission;
60 => _Isolate.spawnFunction(topLevelFunction, unhandledExceptionCallback); 44 const Permission(this._permission);
45
46 // Mirror-modify basically allows everything, since we can just modify the
47 // program to our liking.
48 static const FULL_CONTROL = const Permission(#full_control);
49 static const MIRROR_INSPECT = const Permission(#mirror_inspect);
50 static const SHUTDOWN = const Permission(#shutdown);
51 // Allows to control resources (maybe even giving more than usual?).
52 static const RESOURCE = const Permission(#resource);
53 }
54
55 class Isolate {
56 /**
57 * Creates and spawns an isolate that shares the same code as the current
58 * isolate.
59 *
60 * The argument [entryPoint] specifies the entry point of the spawned
61 * isolate. It must be a static top-level function or a static method that
62 * takes no arguments. It is not allowed to pass a function closure.
63 *
64 * The entry-point function is invoked with the initial [message].
65 * Usually the initial [message] contains a [SendPort] so
66 * that the spawner and spawnee can communicate with each other.
67 *
68 * Returns a future that will complete with an [Isolate] instance. The
69 * isolate instance can be used to control the spawned isolate.
70 */
71 static Future<Isolate> spawn(void entryPoint(message), var message,
72 { startPaused, or, other, Arguments, we, will, find, useful }) {
73 }
74
75 /**
76 * Creates and spawns an isolate that runs the code from the library with
77 * the specified URI.
78 *
79 * The isolate starts executing the top-level `main` function of the library
80 * with the given URI. Otherwise similar to [spawn].
81 */
82 static Future<Isolate> spawnUri(Uri uri, var arguments, { named, args }) {
83
84 }
85
86 /**
87 * Creates a new isolate instance controlling an existing isolate.
88 *
89 * The new instance controls the isolate that is controlled by the
90 * argument [controlPort].
91 *
92 * The given [permissions] map specifies what the returned instance can
93 * do with the existing isolate.
94 */
95 Isolate.fromControlPort(SendPort controlPort,
96 Map<Permission, Capability> permissions)
97 : _permissions = permissions,
98 controlPort = controlPort;
99
100 /**
101 * Listening to this stream will install an error handler on the isolate.
102 *
103 * The installation of the error handler is an asynchronous operation.
104 * If one wants to be sure to see all errors, one should start the isolate in
105 * a paused state, start listening to the errors, and then only resume the
106 * other isolate.
107 */
108 Stream uncaughtErrors;
109
110 /**
111 * Pauses the isolate.
112 */
113 Future pause() {}
114
115 /**
116 * Resumes the isolate.
117 */
118 Future resume() {}
119
120 Future kill() {
121 // Proposed implementation:
122 return controlPort.send([_someInternalObjectIdentifyingKillAction,
123 _permissions[Permission.SHUTDOWN]]);
124 }
125
126 /**
127 * Since this is an asynchronous operation the state might change before
128 * we get a chance to act on it (if someone else has the capability to
129 * resume the isolate).
130 */
131 Future<bool> queryIsPaused() {}
132
133 /// This port uniquely identifies the spawned isolate.
134 final SendPort controlPort;
135
136 final Map<Permission, Capability> _permissions;
137
138 /**
139 * Clones this Isolate but with limited permissions.
140 *
141 * When handing out isolates, one should always
142 */
143 Map<Permission, Capability> extractPermissions(
144 Iterable<Permission> permissions) {
145 }
146 }
61 147
62 /** 148 /**
63 * Creates and spawns an isolate that runs the code from the specified URI. 149 * Sends messages to its [ReceivePort]s.
64 *
65 * As with [spawnFunction],
66 * the child isolate has a default [ReceivePort],
67 * and this function returns a [SendPort] derived from it.
68 */
69 SendPort spawnUri(String uri) => _Isolate.spawnUri(uri);
70
71 /**
72 * Together with [ReceivePort],
73 * the only means of communication between isolates.
74 * 150 *
75 * [SendPort]s are created from [ReceivePort]s. Any message sent through 151 * [SendPort]s are created from [ReceivePort]s. Any message sent through
76 * a [SendPort] is delivered to its respective [ReceivePort]. There might be 152 * a [SendPort] is delivered to its respective [ReceivePort]. There might be
77 * many [SendPort]s for the same [ReceivePort]. 153 * many [SendPort]s for the same [ReceivePort].
78 * 154 *
79 * [SendPort]s can be transmitted to other isolates. 155 * [SendPort]s can be transmitted to other isolates.
80 */ 156 */
81 abstract class SendPort { 157 abstract class SendPort {
82 158
83 /** 159 /**
84 * Sends an asynchronous [message] to this send port. The message is copied to 160 * Sends an asynchronous [message] to this send port. The message is copied to
85 * the receiving isolate. If specified, the [replyTo] port will be provided to 161 * the receiving isolate.
86 * the receiver to facilitate exchanging sequences of messages.
87 * 162 *
88 * The content of [message] can be: primitive values (null, num, bool, double, 163 * The content of [message] can be: primitive values (null, num, bool, double,
89 * String), instances of [SendPort], and lists and maps whose elements are any 164 * String), instances of [SendPort], and lists and maps whose elements are any
90 * of these. List and maps are also allowed to be cyclic. 165 * of these. List and maps are also allowed to be cyclic.
91 * 166 *
92 * In the special circumstances when two isolates share the same code and are 167 * In the special circumstances when two isolates share the same code and are
93 * running in the same process (e.g. isolates created via [spawnFunction]), it 168 * running in the same process (e.g. isolates created via [spawnFunction]), it
94 * is also possible to send object instances (which would be copied in the 169 * is also possible to send object instances (which would be copied in the
95 * process). This is currently only supported by the dartvm. For now, the 170 * process). This is currently only supported by the dartvm. For now, the
96 * dart2js compiler only supports the restricted messages described above. 171 * dart2js compiler only supports the restricted messages described above.
97 *
98 * Deprecation note: it is no longer valid to transmit a [ReceivePort] in a
99 * message. Previously they were translated to the corresponding send port
100 * before being transmitted.
101 */ 172 */
102 void send(var message, [SendPort replyTo]); 173 void send(var message);
103
104 /**
105 * Sends a message to this send port and returns a [Future] of the reply.
106 * Basically, this internally creates a new receive port, sends a
107 * message to this send port with replyTo set to such receive port, and, when
108 * a reply is received, it closes the receive port and completes the returned
109 * future.
110 */
111 Future call(var message);
112 174
113 /** 175 /**
114 * Tests whether [other] is a [SendPort] pointing to the same 176 * Tests whether [other] is a [SendPort] pointing to the same
115 * [ReceivePort] as this one. 177 * [ReceivePort] as this one.
116 */ 178 */
117 bool operator==(var other); 179 bool operator==(var other);
118 180
119 /** 181 /**
120 * Returns an immutable hash code for this send port that is 182 * Returns an immutable hash code for this send port that is
121 * consistent with the == operator. 183 * consistent with the == operator.
122 */ 184 */
123 int get hashCode; 185 int get hashCode;
124
125 }
126
127 /**
128 * Together with [SendPort], the only means of
129 * communication between isolates.
130 *
131 * [ReceivePort]s have a [:toSendPort:] method
132 * which returns a [SendPort]. Any message that is sent through this [SendPort]
133 * is delivered to the [ReceivePort] it has been created from. There, they are
134 * dispatched to the callback that has been registered on the receive port.
135 *
136 * A [ReceivePort] may have many [SendPort]s.
137 */
138 abstract class ReceivePort {
139
140 /**
141 * Opens a long-lived port for receiving messages. The returned port
142 * must be explicitly closed through [ReceivePort.close].
143 */
144 external factory ReceivePort();
145
146 /**
147 * Sets up a callback function for receiving pending or future
148 * messages on this receive port.
149 */
150 void receive(void callback(var message, SendPort replyTo));
151
152 /**
153 * Closes this receive port immediately. Pending messages will not
154 * be processed and it is impossible to re-open the port. Single-shot
155 * reply ports, such as those created through [SendPort.call], are
156 * automatically closed when the reply has been received. Multiple
157 * invocations of [close] are allowed but ignored.
158 */
159 void close();
160
161 /**
162 * Creates a new send port that sends to this receive port. It is legal to
163 * create several [SendPort]s from the same [ReceivePort].
164 */
165 SendPort toSendPort();
166
167 }
168
169 /**
170 * [SendPortSync]s are created from [ReceivePortSync]s. Any message sent through
171 * a [SendPortSync] is delivered to its respective [ReceivePortSync]. There
172 * might be many [SendPortSync]s for the same [ReceivePortSync].
173 *
174 * [SendPortSync]s can be transmitted to other isolates.
175 */
176 abstract class SendPortSync {
177 /**
178 * Sends a synchronous message to this send port and returns the result.
179 */
180 callSync(var message);
181
182 /**
183 * Tests whether [other] is a [SendPortSync] pointing to the same
184 * [ReceivePortSync] as this one.
185 */
186 bool operator==(var other);
187
188 /**
189 * Returns an immutable hash code for this send port that is
190 * consistent with the == operator.
191 */
192 int get hashCode;
193 } 186 }
194 187
188 /**
189 * Together with [SendPort], the only means of communication between isolates.
190 *
191 * [ReceivePort]s have a `sendport` getter which returns a [SendPort].
192 * Any message that is sent through this [SendPort]
193 * is delivered to the [ReceivePort] it has been created from. There, the
194 * message is dispatched to its listener.
195 *
196 * A [ReceivePort] is a non-broadcast stream. This means that it buffers
197 * incoming messages until a listener is registered. Only one listener can
198 * receive messages. See [Stream.asBroadcastStream] for transforming the port
199 * to a broadcast stream.
200 *
201 * A [ReceivePort] may have many [SendPort]s.
202 */
203 abstract class ReceivePort implements Stream {
204
205 /**
206 * Opens a long-lived port for receiving messages.
207 *
208 * A [ReceivePort] is a non-broadcast stream. This means that it buffers
209 * incoming messages until a listener is registered. Only one listener can
210 * receive messages. See [Stream.asBroadcastStream] for transforming the port
211 * to a broadcast stream.
212 *
213 * A receive port is closed by canceling its subscription.
214 */
215 external factory ReceivePort();
216
217 /**
218 * Inherited from [Stream].
219 *
220 * Note that all named arguments are ignored since a ReceivePort will never
221 * receive an error, or done message.
222 */
223 StreamSubscription listen(void callback(var message),
224 { Function onError,
225 void onDone(),
226 bool cancelOnError });
227
228 /**
229 * Returns a send port that sends to this receive port.
230 */
231 SendPort get sendPort;
232 }
233
195 // The VM doesn't support accessing external globals in the same library. We 234 // The VM doesn't support accessing external globals in the same library. We
196 // therefore create this wrapper class. 235 // therefore create this wrapper class.
197 // TODO(6997): Don't go through static class for external variables. 236 // TODO(6997): Don't go through static class for external variables.
198 abstract class _Isolate { 237 abstract class _Isolate {
199 external static ReceivePort get port; 238 external static ReceivePort get port;
200 external static SendPort spawnFunction(void topLevelFunction(), 239 external static SendPort spawnFunction(void topLevelFunction(),
201 [bool unhandledExceptionCallback(IsolateUnhandledException e)]); 240 [bool unhandledExceptionCallback(IsolateUnhandledException e)]);
202 external static SendPort spawnUri(String uri); 241 external static SendPort spawnUri(String uri);
203 } 242 }
204 243
205 /** 244 /**
206 * Wraps unhandled exceptions thrown during isolate execution. It is 245 * Wraps unhandled exceptions thrown during isolate execution. It is
207 * used to show both the error message and the stack trace for unhandled 246 * used to show both the error message and the stack trace for unhandled
208 * exceptions. 247 * exceptions.
209 */ 248 */
249 // TODO(floitsch): probably going to remove and replace with something else.
210 class IsolateUnhandledException implements Exception { 250 class IsolateUnhandledException implements Exception {
211 /** Message being handled when exception occurred. */ 251 /** Message being handled when exception occurred. */
212 final message; 252 final message;
213 253
214 /** Wrapped exception. */ 254 /** Wrapped exception. */
215 final source; 255 final source;
216 256
217 /** Trace for the wrapped exception. */ 257 /** Trace for the wrapped exception. */
218 final Object stackTrace; 258 final Object stackTrace;
219 259
220 const IsolateUnhandledException(this.message, this.source, this.stackTrace); 260 const IsolateUnhandledException(this.message, this.source, this.stackTrace);
221 261
222 String toString() { 262 String toString() {
223 return 'IsolateUnhandledException: exception while handling message: ' 263 return 'IsolateUnhandledException: exception while handling message: '
224 '${message} \n ' 264 '${message} \n '
225 '${source.toString().replaceAll("\n", "\n ")}\n' 265 '${source.toString().replaceAll("\n", "\n ")}\n'
226 'original stack trace:\n ' 266 'original stack trace:\n '
227 '${stackTrace.toString().replaceAll("\n","\n ")}'; 267 '${stackTrace.toString().replaceAll("\n","\n ")}';
228 } 268 }
229 } 269 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/isolate/isolate_stream.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698