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

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

Issue 27215002: Very simple version of Isolates. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 7 years, 1 month 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 | « sdk/lib/io/timer_impl.dart ('k') | sdk/lib/isolate/isolate_sources.gypi » ('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 import "dart:collection" show HashMap;
18 19
19 part "isolate_stream.dart"; 20 /**
20 21 * Thrown when an isolate cannot be created.
22 */
21 class IsolateSpawnException implements Exception { 23 class IsolateSpawnException implements Exception {
24 // TODO(floitsch): clean up spawn exception.
22 const IsolateSpawnException(String this._s); 25 const IsolateSpawnException(String this._s);
23 String toString() => "IsolateSpawnException: '$_s'"; 26 String toString() => "IsolateSpawnException: '$_s'";
24 final String _s; 27 final String _s;
25 } 28 }
26 29
27 /** 30 class Isolate {
28 * The initial ReceivePort available by default for this isolate. 31
29 * 32 final SendPort _controlPort;
30 * This ReceivePort is created automatically 33
31 * and is commonly used to establish 34 Isolate._fromControlPort(SendPort controlPort)
32 * the first communication between isolates. 35 : this._controlPort = controlPort;
33 * (See [spawnFunction] and [spawnUri].) 36
34 */ 37 /**
35 ReceivePort get port => _Isolate.port; 38 * Creates and spawns an isolate that shares the same code as the current
39 * isolate.
40 *
41 * The argument [entryPoint] specifies the entry point of the spawned
42 * isolate. It must be a static top-level function or a static method that
43 * takes no arguments. It is not allowed to pass a function closure.
44 *
45 * The entry-point function is invoked with the initial [message].
46 * Usually the initial [message] contains a [SendPort] so
47 * that the spawner and spawnee can communicate with each other.
48 *
49 * Returns a future that will complete with an [Isolate] instance. The
50 * isolate instance can be used to control the spawned isolate.
51 */
52 external static Future<Isolate> spawn(void entryPoint(message), var message);
53
54 /**
55 * Creates and spawns an isolate that runs the code from the library with
56 * the specified URI.
57 *
58 * The isolate starts executing the top-level `main` function of the library
59 * with the given URI.
60 *
61 * The target `main` may have one of the four following signatures:
62 *
63 * * `main()`
64 * * `main(args)`
65 * * `main(args, message)`
66 *
67 * When present, the argument `message` is set to the initial [message].
68 * When present, the argument `args` is set to the provided [args] list.
69 *
70 * Returns a future that will complete with an [Isolate] instance. The
71 * isolate instance can be used to control the spawned isolate.
72 */
73 external static Future<Isolate> spawnUri(
74 Uri uri, List<String> args, var message);
75 }
36 76
37 /** 77 /**
38 * Creates and spawns an isolate 78 * Sends messages to its [ReceivePort]s.
39 * that shares the same code as the current isolate,
40 * but that starts from the specified function.
41 *
42 * The [topLevelFunction] argument must be
43 * a static top-level function or a static method that takes no
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 */
58 SendPort spawnFunction(void topLevelFunction(),
59 [bool unhandledExceptionCallback(IsolateUnhandledException e)])
60 => _Isolate.spawnFunction(topLevelFunction, unhandledExceptionCallback);
61
62 /**
63 * Creates and spawns an isolate that runs the code from the specified URI.
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 * 79 *
75 * [SendPort]s are created from [ReceivePort]s. Any message sent through 80 * [SendPort]s are created from [ReceivePort]s. Any message sent through
76 * a [SendPort] is delivered to its respective [ReceivePort]. There might be 81 * a [SendPort] is delivered to its respective [ReceivePort]. There might be
77 * many [SendPort]s for the same [ReceivePort]. 82 * many [SendPort]s for the same [ReceivePort].
78 * 83 *
79 * [SendPort]s can be transmitted to other isolates. 84 * [SendPort]s can be transmitted to other isolates.
80 */ 85 */
81 abstract class SendPort { 86 abstract class SendPort {
82 87
83 /** 88 /**
84 * Sends an asynchronous [message] to this send port. The message is copied to 89 * 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 90 * the receiving isolate.
86 * the receiver to facilitate exchanging sequences of messages.
87 * 91 *
88 * The content of [message] can be: primitive values (null, num, bool, double, 92 * 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 93 * String), instances of [SendPort], and lists and maps whose elements are any
90 * of these. List and maps are also allowed to be cyclic. 94 * of these. List and maps are also allowed to be cyclic.
91 * 95 *
92 * In the special circumstances when two isolates share the same code and are 96 * 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 97 * 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 98 * 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 99 * process). This is currently only supported by the dartvm. For now, the
96 * dart2js compiler only supports the restricted messages described above. 100 * dart2js compiler only supports the restricted messages described above.
97 * 101 *
98 * Deprecation note: it is no longer valid to transmit a [ReceivePort] in a 102 * The second argument [replyTo] is deprecated and its value is ignored.
99 * message. Previously they were translated to the corresponding send port
100 * before being transmitted.
101 */ 103 */
102 void send(var message, [SendPort replyTo]); 104 void send(var message, [SendPort replyTo]);
103 105
104 /** 106 /**
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
113 /**
114 * Tests whether [other] is a [SendPort] pointing to the same 107 * Tests whether [other] is a [SendPort] pointing to the same
115 * [ReceivePort] as this one. 108 * [ReceivePort] as this one.
116 */ 109 */
117 bool operator==(var other); 110 bool operator==(var other);
118 111
119 /** 112 /**
120 * Returns an immutable hash code for this send port that is 113 * Returns an immutable hash code for this send port that is
121 * consistent with the == operator. 114 * consistent with the == operator.
122 */ 115 */
123 int get hashCode; 116 int get hashCode;
124
125 } 117 }
126 118
127 /** 119 /**
128 * Together with [SendPort], the only means of 120 * Together with [SendPort], the only means of communication between isolates.
129 * communication between isolates.
130 * 121 *
131 * [ReceivePort]s have a [:toSendPort:] method 122 * [ReceivePort]s have a `sendport` getter which returns a [SendPort].
132 * which returns a [SendPort]. Any message that is sent through this [SendPort] 123 * Any message that is sent through this [SendPort]
133 * is delivered to the [ReceivePort] it has been created from. There, they are 124 * is delivered to the [ReceivePort] it has been created from. There, the
134 * dispatched to the callback that has been registered on the receive port. 125 * message is dispatched to its listener.
126 *
127 * A [ReceivePort] is a non-broadcast stream. This means that it buffers
128 * incoming messages until a listener is registered. Only one listener can
129 * receive messages. See [Stream.asBroadcastStream] for transforming the port
130 * to a broadcast stream.
135 * 131 *
136 * A [ReceivePort] may have many [SendPort]s. 132 * A [ReceivePort] may have many [SendPort]s.
137 */ 133 */
138 abstract class ReceivePort { 134 abstract class ReceivePort implements Stream {
139 135
140 /** 136 /**
141 * Opens a long-lived port for receiving messages. The returned port 137 * Opens a long-lived port for receiving messages.
142 * must be explicitly closed through [ReceivePort.close]. 138 *
139 * A [ReceivePort] is a non-broadcast stream. This means that it buffers
140 * incoming messages until a listener is registered. Only one listener can
141 * receive messages. See [Stream.asBroadcastStream] for transforming the port
142 * to a broadcast stream.
143 *
144 * A receive port is closed by canceling its subscription.
143 */ 145 */
144 external factory ReceivePort(); 146 external factory ReceivePort();
145 147
146 /** 148 /**
147 * Sets up a callback function for receiving pending or future 149 * Creates a [ReceivePort] from a [RawReceivePort].
148 * messages on this receive port. 150 *
151 * The handler of the given [rawPort] is overwritten during the construction
152 * of the result.
149 */ 153 */
150 void receive(void callback(var message, SendPort replyTo)); 154 external factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort);
151 155
152 /** 156 /**
153 * Closes this receive port immediately. Pending messages will not 157 * Inherited from [Stream].
154 * be processed and it is impossible to re-open the port. Single-shot 158 *
155 * reply ports, such as those created through [SendPort.call], are 159 * Note that all named arguments are ignored since a ReceivePort will never
156 * automatically closed when the reply has been received. Multiple 160 * receive an error, or done message.
157 * invocations of [close] are allowed but ignored. 161 */
162 StreamSubscription listen(void onData(var message),
163 { Function onError,
164 void onDone(),
165 bool cancelOnError });
166
167 /**
168 * Closes `this`.
169 *
170 * If the stream has not been canceled yet, adds a close-event to the event
171 * queue and discards any further incoming messages.
172 *
173 * If the stream has already been canceled this method has no effect.
158 */ 174 */
159 void close(); 175 void close();
160 176
161 /** 177 /**
162 * Creates a new send port that sends to this receive port. It is legal to 178 * Returns a send port that sends to this receive port.
163 * create several [SendPort]s from the same [ReceivePort].
164 */ 179 */
165 SendPort toSendPort(); 180 SendPort get sendPort;
181 }
166 182
183 abstract class RawReceivePort {
184 /**
185 * Opens a long-lived port for receiving messages.
186 *
187 * A [RawReceivePort] is low level and does not work with [Zone]s. It
188 * can not be paused. The data-handler must be set before the first
189 * event is received.
190 */
191 external factory RawReceivePort([void handler(event)]);
192
193 /**
194 * Sets the handler that is invoked for every incoming message.
195 *
196 * The handler is invoked in the root-zone ([Zone.ROOT]).
197 */
198 void set handler(Function newHandler);
199
200 /**
201 * Closes the port.
202 *
203 * After a call to this method any incoming message is silently dropped.
204 */
205 void close();
167 } 206 }
168 207
169 /** 208 /**
170 * [SendPortSync]s are created from [ReceivePortSync]s. Any message sent through 209 * [SendPortSync]s are created from [ReceivePortSync]s. Any message sent through
171 * a [SendPortSync] is delivered to its respective [ReceivePortSync]. There 210 * a [SendPortSync] is delivered to its respective [ReceivePortSync]. There
172 * might be many [SendPortSync]s for the same [ReceivePortSync]. 211 * might be many [SendPortSync]s for the same [ReceivePortSync].
173 * 212 *
174 * [SendPortSync]s can be transmitted to other isolates. 213 * [SendPortSync]s can be transmitted to other isolates.
214 *
215 * *DEPRECATED*.
175 */ 216 */
217 @deprecated
176 abstract class SendPortSync { 218 abstract class SendPortSync {
177 /** 219 /**
178 * Sends a synchronous message to this send port and returns the result. 220 * Sends a synchronous message to this send port and returns the result.
179 */ 221 */
180 callSync(var message); 222 callSync(var message);
181 223
182 /** 224 /**
183 * Tests whether [other] is a [SendPortSync] pointing to the same 225 * Tests whether [other] is a [SendPortSync] pointing to the same
184 * [ReceivePortSync] as this one. 226 * [ReceivePortSync] as this one.
185 */ 227 */
186 bool operator==(var other); 228 bool operator==(var other);
187 229
188 /** 230 /**
189 * Returns an immutable hash code for this send port that is 231 * Returns an immutable hash code for this send port that is
190 * consistent with the == operator. 232 * consistent with the == operator.
191 */ 233 */
192 int get hashCode; 234 int get hashCode;
193 } 235 }
194 236
195 // The VM doesn't support accessing external globals in the same library. We
196 // therefore create this wrapper class.
197 // TODO(6997): Don't go through static class for external variables.
198 abstract class _Isolate {
199 external static ReceivePort get port;
200 external static SendPort spawnFunction(void topLevelFunction(),
201 [bool unhandledExceptionCallback(IsolateUnhandledException e)]);
202 external static SendPort spawnUri(String uri);
203 }
204
205 /** 237 /**
206 * Wraps unhandled exceptions thrown during isolate execution. It is 238 * Wraps unhandled exceptions thrown during isolate execution. It is
207 * used to show both the error message and the stack trace for unhandled 239 * used to show both the error message and the stack trace for unhandled
208 * exceptions. 240 * exceptions.
209 */ 241 */
210 class IsolateUnhandledException implements Exception { 242 // TODO(floitsch): probably going to remove and replace with something else.
243 class _IsolateUnhandledException implements Exception {
211 /** Message being handled when exception occurred. */ 244 /** Message being handled when exception occurred. */
212 final message; 245 final message;
213 246
214 /** Wrapped exception. */ 247 /** Wrapped exception. */
215 final source; 248 final source;
216 249
217 /** Trace for the wrapped exception. */ 250 /** Trace for the wrapped exception. */
218 final Object stackTrace; 251 final Object stackTrace;
219 252
220 const IsolateUnhandledException(this.message, this.source, this.stackTrace); 253 const _IsolateUnhandledException(this.message, this.source, this.stackTrace);
221 254
222 String toString() { 255 String toString() {
223 return 'IsolateUnhandledException: exception while handling message: ' 256 return 'IsolateUnhandledException: exception while handling message: '
224 '${message} \n ' 257 '${message} \n '
225 '${source.toString().replaceAll("\n", "\n ")}\n' 258 '${source.toString().replaceAll("\n", "\n ")}\n'
226 'original stack trace:\n ' 259 'original stack trace:\n '
227 '${stackTrace.toString().replaceAll("\n","\n ")}'; 260 '${stackTrace.toString().replaceAll("\n","\n ")}';
228 } 261 }
229 } 262 }
OLDNEW
« no previous file with comments | « sdk/lib/io/timer_impl.dart ('k') | sdk/lib/isolate/isolate_sources.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698