OLD | NEW |
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 * |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 * If an isolate is paused more than once using the same capability, | 136 * If an isolate is paused more than once using the same capability, |
137 * only one resume with that capability is needed to end the pause. | 137 * only one resume with that capability is needed to end the pause. |
138 * | 138 * |
139 * If an isolate is paused using more than one capability, | 139 * If an isolate is paused using more than one capability, |
140 * they must all be individully ended before the isolate resumes. | 140 * they must all be individully ended before the isolate resumes. |
141 * | 141 * |
142 * Returns the capability that must be used to resume end the pause. | 142 * Returns the capability that must be used to resume end the pause. |
143 */ | 143 */ |
144 Capability pause([Capability resumeCapability]) { | 144 Capability pause([Capability resumeCapability]) { |
145 if (resumeCapability == null) resumeCapability = new Capability(); | 145 if (resumeCapability == null) resumeCapability = new Capability(); |
146 var message = new List(3) | 146 _pause(resumeCapability); |
147 ..[0] = "pause" | |
148 ..[1] = pauseCapability | |
149 ..[2] = resumeCapability; | |
150 controlPort.send(message); | |
151 return resumeCapability; | 147 return resumeCapability; |
152 } | 148 } |
153 | 149 |
| 150 /** Internal implementation of [pause]. */ |
| 151 external void _pause(Capability resumeCapability); |
| 152 |
154 /** | 153 /** |
155 * Resumes a paused isolate. | 154 * Resumes a paused isolate. |
156 * | 155 * |
157 * WARNING: This method is experimental and not handled on every platform yet. | 156 * WARNING: This method is experimental and not handled on every platform yet. |
158 * | 157 * |
159 * Sends a message to an isolate requesting that it ends a pause | 158 * Sends a message to an isolate requesting that it ends a pause |
160 * that was requested using the [resumeCapability]. | 159 * that was requested using the [resumeCapability]. |
161 * | 160 * |
162 * When all active pause requests have been cancelled, the isolate | 161 * When all active pause requests have been cancelled, the isolate |
163 * will continue handling normal messages. | 162 * will continue handling normal messages. |
164 * | 163 * |
165 * The capability must be one returned by a call to [pause] on this | 164 * The capability must be one returned by a call to [pause] on this |
166 * isolate, otherwise the resume call does nothing. | 165 * isolate, otherwise the resume call does nothing. |
167 */ | 166 */ |
168 void resume(Capability resumeCapability) { | 167 external void resume(Capability resumeCapability); |
169 var message = new List(2) | |
170 ..[0] = "resume" | |
171 ..[1] = resumeCapability; | |
172 controlPort.send(message); | |
173 } | |
174 | 168 |
175 /** | 169 /** |
176 * Asks the isolate to send a message on [responsePort] when it terminates. | 170 * Asks the isolate to send a message on [responsePort] when it terminates. |
177 * | 171 * |
178 * WARNING: This method is experimental and not handled on every platform yet. | 172 * WARNING: This method is experimental and not handled on every platform yet. |
179 * | 173 * |
180 * The isolate will send a `null` message on [responsePort] as the last | 174 * The isolate will send a `null` message on [responsePort] as the last |
181 * thing before it terminates. It will run no further code after the message | 175 * thing before it terminates. It will run no further code after the message |
182 * has been sent. | 176 * has been sent. |
183 * | 177 * |
184 * If the isolate is already dead, no message will be sent. | 178 * If the isolate is already dead, no message will be sent. |
185 * TODO(lrn): Can we do better? Can the system recognize this message and | 179 */ |
| 180 /* TODO(lrn): Can we do better? Can the system recognize this message and |
186 * send a reply if the receiving isolate is dead? | 181 * send a reply if the receiving isolate is dead? |
187 */ | 182 */ |
188 void addOnExitListener(SendPort responsePort) { | 183 external void addOnExitListener(SendPort responsePort); |
189 // TODO(lrn): Can we have an internal method that checks if the receiving | |
190 // isolate of a SendPort is still alive? | |
191 var message = new List(2) | |
192 ..[0] = "add-ondone" | |
193 ..[1] = responsePort; | |
194 controlPort.send(message); | |
195 } | |
196 | 184 |
197 /** | 185 /** |
198 * Stop listening on exit messages from the isolate. | 186 * Stop listening on exit messages from the isolate. |
199 * | 187 * |
200 * WARNING: This method is experimental and not handled on every platform yet. | 188 * WARNING: This method is experimental and not handled on every platform yet. |
201 * | 189 * |
202 * If a call has previously been made to [addOnExitListener] with the same | 190 * If a call has previously been made to [addOnExitListener] with the same |
203 * send-port, this will unregister the port, and it will no longer receive | 191 * send-port, this will unregister the port, and it will no longer receive |
204 * a message when the isolate terminates. | 192 * a message when the isolate terminates. |
205 * A response may still be sent until this operation is fully processed by | 193 * A response may still be sent until this operation is fully processed by |
206 * the isolate. | 194 * the isolate. |
207 */ | 195 */ |
208 void removeOnExitListener(SendPort responsePort) { | 196 external void removeOnExitListener(SendPort responsePort); |
209 var message = new List(2) | |
210 ..[0] = "remove-ondone" | |
211 ..[1] = responsePort; | |
212 controlPort.send(message); | |
213 } | |
214 | 197 |
215 /** | 198 /** |
216 * Set whether uncaught errors will terminate the isolate. | 199 * Set whether uncaught errors will terminate the isolate. |
217 * | 200 * |
218 * WARNING: This method is experimental and not handled on every platform yet. | 201 * WARNING: This method is experimental and not handled on every platform yet. |
219 * | 202 * |
220 * If errors are fatal, any uncaught error will terminate the isolate | 203 * If errors are fatal, any uncaught error will terminate the isolate |
221 * event loop and shut down the isolate. | 204 * event loop and shut down the isolate. |
222 * | 205 * |
223 * This call requires the [terminateCapability] for the isolate. | 206 * This call requires the [terminateCapability] for the isolate. |
224 * If the capability is not correct, no change is made. | 207 * If the capability is not correct, no change is made. |
225 */ | 208 */ |
226 void setErrorsFatal(bool errorsAreFatal) { | 209 external void setErrorsFatal(bool errorsAreFatal); |
227 var message = new List(3) | |
228 ..[0] = "set-errors-fatal" | |
229 ..[1] = terminateCapability | |
230 ..[2] = errorsAreFatal; | |
231 controlPort.send(message); | |
232 } | |
233 | 210 |
234 /** | 211 /** |
235 * Requests the isolate to shut down. | 212 * Requests the isolate to shut down. |
236 * | 213 * |
237 * WARNING: This method is experimental and not handled on every platform yet. | 214 * WARNING: This method is experimental and not handled on every platform yet. |
238 * | 215 * |
239 * The isolate is requested to terminate itself. | 216 * The isolate is requested to terminate itself. |
240 * The [priority] argument specifies when this must happen. | 217 * The [priority] argument specifies when this must happen. |
241 * | 218 * |
242 * The [priority] must be one of [IMMEDIATE], [BEFORE_NEXT_EVENT] or | 219 * The [priority] must be one of [IMMEDIATE], [BEFORE_NEXT_EVENT] or |
(...skipping 12 matching lines...) Expand all Loading... |
255 * If more than one such event are scheduled, they are executed in | 232 * If more than one such event are scheduled, they are executed in |
256 * the order their control messages were received. | 233 * the order their control messages were received. |
257 * * `AS_EVENT`: The shutdown does not happen until all prevously sent | 234 * * `AS_EVENT`: The shutdown does not happen until all prevously sent |
258 * non-control messages from the current isolate to the receiving isolate | 235 * non-control messages from the current isolate to the receiving isolate |
259 * have been processed. | 236 * have been processed. |
260 * The kill operation effectively puts the shutdown into the normal event | 237 * The kill operation effectively puts the shutdown into the normal event |
261 * queue after previously sent messages, and it is affected by any control | 238 * queue after previously sent messages, and it is affected by any control |
262 * messages that affect normal events, including `pause`. | 239 * messages that affect normal events, including `pause`. |
263 * This can be used to wait for a another event to be processed. | 240 * This can be used to wait for a another event to be processed. |
264 */ | 241 */ |
265 void kill([int priority = BEFORE_NEXT_EVENT]) { | 242 external void kill([int priority = BEFORE_NEXT_EVENT]); |
266 controlPort.send(["kill", terminateCapability, priority]); | |
267 } | |
268 | 243 |
269 /** | 244 /** |
270 * Request that the isolate send a response on the [responsePort]. | 245 * Request that the isolate send a response on the [responsePort]. |
271 * | 246 * |
272 * WARNING: This method is experimental and not handled on every platform yet. | 247 * WARNING: This method is experimental and not handled on every platform yet. |
273 * | 248 * |
274 * If the isolate is alive, it will eventually send a `null` response on | 249 * If the isolate is alive, it will eventually send a `null` response on |
275 * the response port. | 250 * the response port. |
276 * | 251 * |
277 * The [pingType] must be one of [IMMEDIATE], [BEFORE_NEXT_EVENT] or | 252 * The [pingType] must be one of [IMMEDIATE], [BEFORE_NEXT_EVENT] or |
278 * [AS_EVENT]. | 253 * [AS_EVENT]. |
279 * The response is sent at different times depending on the ping type: | 254 * The response is sent at different times depending on the ping type: |
280 * | 255 * |
281 * * `IMMEDIATE`: The the isolate responds as soon as it receives the | 256 * * `IMMEDIATE`: The the isolate responds as soon as it receives the |
282 * control message. | 257 * control message. |
283 * * `BEFORE_NEXT_EVENT`: The response is scheduled for the next time | 258 * * `BEFORE_NEXT_EVENT`: The response is scheduled for the next time |
284 * control returns to the event loop of the receiving isolate. | 259 * control returns to the event loop of the receiving isolate. |
285 * If more than one such event are scheduled, they are executed in | 260 * If more than one such event are scheduled, they are executed in |
286 * the order their control messages were received. | 261 * the order their control messages were received. |
287 * * `AS_EVENT`: The response is not sent until all prevously sent | 262 * * `AS_EVENT`: The response is not sent until all prevously sent |
288 * non-control messages from the current isolate to the receiving isolate | 263 * non-control messages from the current isolate to the receiving isolate |
289 * have been processed. | 264 * have been processed. |
290 * The ping effectively puts the response into the normal event queue | 265 * The ping effectively puts the response into the normal event queue |
291 * after previously sent messages, and it is affected by any control | 266 * after previously sent messages, and it is affected by any control |
292 * messages that affect normal events, including `pause`. | 267 * messages that affect normal events, including `pause`. |
293 * This can be used to wait for a another event to be processed. | 268 * This can be used to wait for a another event to be processed. |
294 */ | 269 */ |
295 void ping(SendPort responsePort, [int pingType = IMMEDIATE]) { | 270 external void ping(SendPort responsePort, [int pingType = IMMEDIATE]); |
296 var message = new List(3) | |
297 ..[0] = "ping" | |
298 ..[1] = responsePort | |
299 ..[2] = pingType; | |
300 controlPort.send(message); | |
301 } | |
302 | 271 |
303 /** | 272 /** |
304 * Requests that uncaught errors of the isolate are sent back to [port]. | 273 * Requests that uncaught errors of the isolate are sent back to [port]. |
305 * | 274 * |
| 275 * WARNING: This method is experimental and not handled on every platform yet. |
| 276 * |
306 * The errors are sent back as two elements lists. | 277 * The errors are sent back as two elements lists. |
307 * The first element is a `String` representation of the error, usually | 278 * The first element is a `String` representation of the error, usually |
308 * created by calling `toString` on the error. | 279 * created by calling `toString` on the error. |
309 * The second element is a `String` representation of an accompanying | 280 * The second element is a `String` representation of an accompanying |
310 * stack trace, or `null` if no stack trace was provided. | 281 * stack trace, or `null` if no stack trace was provided. |
311 * | 282 * |
312 * Listening using the same port more than once does nothing. It will only | 283 * Listening using the same port more than once does nothing. It will only |
313 * get each error once. | 284 * get each error once. |
314 */ | 285 */ |
315 void addErrorListener(SendPort port) { | 286 external void addErrorListener(SendPort port); |
316 var message = new List(2) | |
317 ..[0] = "getErrors" | |
318 ..[1] = port; | |
319 controlPort.send(message); | |
320 } | |
321 | 287 |
322 /** | 288 /** |
323 * Stop listening for uncaught errors through [port]. | 289 * Stop listening for uncaught errors through [port]. |
324 * | 290 * |
| 291 * WARNING: This method is experimental and not handled on every platform yet. |
| 292 * |
325 * The `port` should be a port that is listening for errors through | 293 * The `port` should be a port that is listening for errors through |
326 * [addErrorListener]. This call requests that the isolate stops sending | 294 * [addErrorListener]. This call requests that the isolate stops sending |
327 * errors on the port. | 295 * errors on the port. |
328 * | 296 * |
329 * If the same port has been passed via `addErrorListener` more than once, | 297 * If the same port has been passed via `addErrorListener` more than once, |
330 * only one call to `removeErrorListener` is needed to stop it from receiving | 298 * only one call to `removeErrorListener` is needed to stop it from receiving |
331 * errors. | 299 * errors. |
332 * | 300 * |
333 * Closing the receive port at the end of the send port will not stop the | 301 * Closing the receive port at the end of the send port will not stop the |
334 * isolate from sending errors, they are just going to be lost. | 302 * isolate from sending errors, they are just going to be lost. |
335 */ | 303 */ |
336 void removeErrorListener(SendPort port) { | 304 external void removeErrorListener(SendPort port); |
337 var message = new List(2) | |
338 ..[0] = "stopErrors" | |
339 ..[1] = port; | |
340 controlPort.send(message); | |
341 } | |
342 | 305 |
343 /** | 306 /** |
344 * Returns a broadcast stream of uncaught errors from the isolate. | 307 * Returns a broadcast stream of uncaught errors from the isolate. |
345 * | 308 * |
346 * Each error is provided as an error event on the stream. | 309 * Each error is provided as an error event on the stream. |
347 * | 310 * |
348 * The actual error object and stackTraces will not necessarily | 311 * The actual error object and stackTraces will not necessarily |
349 * be the same object types as in the actual isolate, but they will | 312 * be the same object types as in the actual isolate, but they will |
350 * always have the same [Object.toString] result. | 313 * always have the same [Object.toString] result. |
351 * | 314 * |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 : _description = description, | 516 : _description = description, |
554 stackTrace = new _RemoteStackTrace(stackDescription); | 517 stackTrace = new _RemoteStackTrace(stackDescription); |
555 String toString() => _description; | 518 String toString() => _description; |
556 } | 519 } |
557 | 520 |
558 class _RemoteStackTrace implements StackTrace { | 521 class _RemoteStackTrace implements StackTrace { |
559 String _trace; | 522 String _trace; |
560 _RemoteStackTrace(this._trace); | 523 _RemoteStackTrace(this._trace); |
561 String toString() => _trace; | 524 String toString() => _trace; |
562 } | 525 } |
OLD | NEW |