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

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 illegal to pass a function closure.
Lasse Reichstein Nielsen 2013/10/14 14:26:48 illegal -> not allowed
floitsch 2013/10/14 17:22:41 Done.
63 *
64 * The entryPoint function is invoked with the initial [message].
Lasse Reichstein Nielsen 2013/10/14 14:26:48 `entryPoint`
floitsch 2013/10/14 17:22:41 changed to "entry-point".
65 * Usually the initial [message] contains a [SendPort] so
66 * that the spawner and spawnee can communicate with each other.
Lasse Reichstein Nielsen 2013/10/14 14:26:48 Document return value.
floitsch 2013/10/14 17:22:41 Done, although more needs to be done.
67 */
68 static Future<Isolate> spawn(void entryPoint(message), var message,
69 { startPaused, or, other, Arguments, we, will, find, useful }) {
70 }
71
72 /**
73 * Creates and spawns an isolate that runs the code from the specified URI.
74 *
75 * The entry point of the spawned isolate is automatically set to
Lasse Reichstein Nielsen 2013/10/14 14:26:48 "... that runs the code from the library with the
floitsch 2013/10/14 17:22:41 Done.
76 * `main`. Otherwise similar to [spawn].
77 */
78 static Future<Isolate> spawnUri(Uri uri, var arguments, { named, args }) {
79
80 }
81
82 /**
83 * Creates a new isolate instance controlling an existing isolate.
84 *
85 * The new instance controls the isolate that is controlled by the
86 * argument [controlPort].
87 *
88 * The given [permissions] map specifies what the returned instance can
89 * do with the existing isolate.
90 */
91 Isolate.fromControlPort(SendPort controlPort,
92 Map<Permission, Capability> permissions)
93 : _permissions = permissions,
94 controlPort = controlPort;
95
96 /**
97 * Listening to this stream will install an error handler on the isolate.
98 *
99 * The installation of the error handler is an asynchronous operation.
100 * If one wants to be sure to see all errors, one should start the isolate in
101 * a paused state, start listening to the errors, and then only resume the
102 * other isolate.
103 */
104 Stream uncaughtErrors;
105
106 /**
107 * Pauses the isolate.
108 */
109 Future pause() {}
110
111 /**
112 * Resumes the isolate.
113 */
114 Future resume() {}
115
116 Future kill() {
117 // Proposed implementation:
118 return controlPort.send([_someInternalObjectIdentifyingKillAction,
119 _permissions[Permission.SHUTDOWN]]);
120 }
121
122 /**
123 * Since this is an asynchronous operation the state might change before
124 * we get a chance to act on it (if someone else has the capability to
125 * resume the isolate).
126 */
127 Future<bool> queryIsPaused() {}
Lasse Reichstein Nielsen 2013/10/14 14:26:48 drop "query". We just have "isPaused" elsewhere, a
floitsch 2013/10/14 17:22:41 Let's discuss this. If we call it "isPaused" it ne
128
129 /// This port uniquely identifies the spawned isolate.
130 final SendPort controlPort;
131
132 final Map<Permission, Capability> _permissions;
133
134 /**
135 * Clones this Isolate but with limited permissions.
136 *
137 * When handing out isolates, one should always
138 */
139 Map<Permission, Capability> extractPermissions(
140 Iterable<Permission> permissions) {
141 }
142 }
61 143
62 /** 144 /**
63 * Creates and spawns an isolate that runs the code from the specified URI. 145 * 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 * 146 *
75 * [SendPort]s are created from [ReceivePort]s. Any message sent through 147 * [SendPort]s are created from [ReceivePort]s. Any message sent through
76 * a [SendPort] is delivered to its respective [ReceivePort]. There might be 148 * a [SendPort] is delivered to its respective [ReceivePort]. There might be
77 * many [SendPort]s for the same [ReceivePort]. 149 * many [SendPort]s for the same [ReceivePort].
78 * 150 *
79 * [SendPort]s can be transmitted to other isolates. 151 * [SendPort]s can be transmitted to other isolates.
80 */ 152 */
81 abstract class SendPort { 153 abstract class SendPort {
82 154
83 /** 155 /**
84 * Sends an asynchronous [message] to this send port. The message is copied to 156 * 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 157 * the receiving isolate.
86 * the receiver to facilitate exchanging sequences of messages.
87 * 158 *
88 * The content of [message] can be: primitive values (null, num, bool, double, 159 * 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 160 * String), instances of [SendPort], and lists and maps whose elements are any
90 * of these. List and maps are also allowed to be cyclic. 161 * of these. List and maps are also allowed to be cyclic.
91 * 162 *
92 * In the special circumstances when two isolates share the same code and are 163 * 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 164 * 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 165 * 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 166 * process). This is currently only supported by the dartvm. For now, the
96 * dart2js compiler only supports the restricted messages described above. 167 * 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 */ 168 */
102 void send(var message, [SendPort replyTo]); 169 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 170
113 /** 171 /**
114 * Tests whether [other] is a [SendPort] pointing to the same 172 * Tests whether [other] is a [SendPort] pointing to the same
115 * [ReceivePort] as this one. 173 * [ReceivePort] as this one.
116 */ 174 */
117 bool operator==(var other); 175 bool operator==(var other);
118 176
119 /** 177 /**
120 * Returns an immutable hash code for this send port that is 178 * Returns an immutable hash code for this send port that is
121 * consistent with the == operator. 179 * consistent with the == operator.
122 */ 180 */
123 int get hashCode; 181 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 } 182 }
194 183
184 /**
185 * Together with [SendPort], the only means of communication between isolates.
186 *
187 * [ReceivePort]s have a `sendport` getter which returns a [SendPort].
188 * Any message that is sent through this [SendPort]
189 * is delivered to the [ReceivePort] it has been created from. There, the
190 * message is dispatched to its listener.
191 *
192 * A [ReceivePort] is a non-broadcast stream. This means that it buffers
193 * incoming messages until a listener is registered. Only one listener can
194 * receive messages. See [Stream.asBroadcastStream] for transforming the port
195 * to a broadcast stream.
196 *
197 * A [ReceivePort] may have many [SendPort]s.
198 */
199 abstract class ReceivePort implements Stream {
200
201 /**
202 * Opens a long-lived port for receiving messages.
203 *
204 * A [ReceivePort] is a non-broadcast stream. This means that it buffers
205 * incoming messages until a listener is registered. Only one listener can
206 * receive messages. See [Stream.asBroadcastStream] for transforming the port
207 * to a broadcast stream.
208 *
209 * A receive port is closed by canceling its subscription.
210 */
211 external factory ReceivePort();
212
213 /**
214 * Inherited from [Stream].
215 *
216 * Note that all named arguments are ignored since a ReceivePort will never
217 * receive an error, or done message.
218 */
219 StreamSubscription listen(void callback(var message),
220 { Function onError,
221 void onDone(),
222 bool cancelOnError });
223
224 /**
225 * Returns a send port that sends to this receive port.
226 */
227 SendPort get sendPort;
228 }
229
195 // The VM doesn't support accessing external globals in the same library. We 230 // The VM doesn't support accessing external globals in the same library. We
196 // therefore create this wrapper class. 231 // therefore create this wrapper class.
197 // TODO(6997): Don't go through static class for external variables. 232 // TODO(6997): Don't go through static class for external variables.
198 abstract class _Isolate { 233 abstract class _Isolate {
199 external static ReceivePort get port; 234 external static ReceivePort get port;
200 external static SendPort spawnFunction(void topLevelFunction(), 235 external static SendPort spawnFunction(void topLevelFunction(),
201 [bool unhandledExceptionCallback(IsolateUnhandledException e)]); 236 [bool unhandledExceptionCallback(IsolateUnhandledException e)]);
202 external static SendPort spawnUri(String uri); 237 external static SendPort spawnUri(String uri);
203 } 238 }
204 239
205 /** 240 /**
206 * Wraps unhandled exceptions thrown during isolate execution. It is 241 * Wraps unhandled exceptions thrown during isolate execution. It is
207 * used to show both the error message and the stack trace for unhandled 242 * used to show both the error message and the stack trace for unhandled
208 * exceptions. 243 * exceptions.
209 */ 244 */
245 // TODO(floitsch): probably going to remove and replace with something else.
210 class IsolateUnhandledException implements Exception { 246 class IsolateUnhandledException implements Exception {
211 /** Message being handled when exception occurred. */ 247 /** Message being handled when exception occurred. */
212 final message; 248 final message;
213 249
214 /** Wrapped exception. */ 250 /** Wrapped exception. */
215 final source; 251 final source;
216 252
217 /** Trace for the wrapped exception. */ 253 /** Trace for the wrapped exception. */
218 final Object stackTrace; 254 final Object stackTrace;
219 255
220 const IsolateUnhandledException(this.message, this.source, this.stackTrace); 256 const IsolateUnhandledException(this.message, this.source, this.stackTrace);
221 257
222 String toString() { 258 String toString() {
223 return 'IsolateUnhandledException: exception while handling message: ' 259 return 'IsolateUnhandledException: exception while handling message: '
224 '${message} \n ' 260 '${message} \n '
225 '${source.toString().replaceAll("\n", "\n ")}\n' 261 '${source.toString().replaceAll("\n", "\n ")}\n'
226 'original stack trace:\n ' 262 'original stack trace:\n '
227 '${stackTrace.toString().replaceAll("\n","\n ")}'; 263 '${stackTrace.toString().replaceAll("\n","\n ")}';
228 } 264 }
229 } 265 }
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