@@ -34,7 +34,6 @@ export notification;
34
34
export sched_mode;
35
35
export sched_opts;
36
36
export task_opts;
37
- export builder;
38
37
export task_builder;
39
38
40
39
export default_task_opts;
@@ -184,14 +183,6 @@ type task_opts = {
184
183
// when you try to reuse the builder to spawn a new task. We'll just
185
184
// sidestep that whole issue by making builders uncopyable and making
186
185
// the run function move them in.
187
- enum builder {
188
- builder_( {
189
- mut opts : task_opts ,
190
- mut gen_body : fn @( +fn ~( ) ) -> fn ~( ) ,
191
- can_not_copy : option < comm:: port < ( ) > >
192
- } )
193
- }
194
-
195
186
class dummy { let x: ( ) ; new ( ) { self . x = ( ) ; } drop { } }
196
187
197
188
// FIXME (#2585): Replace the 'consumed' bit with move mode on self
@@ -262,8 +253,26 @@ impl task_builder for task_builder {
262
253
} )
263
254
}
264
255
265
- /// Configure a future result notification for this task.
256
+ /**
257
+ * Get a future representing the exit status of the task.
258
+ *
259
+ * Taking the value of the future will block until the child task
260
+ * terminates. The future-receiving callback specified will be called
261
+ * *before* the task is spawned; as such, do not invoke .get() within the
262
+ * closure; rather, store it in an outer variable/list for later use.
263
+ *
264
+ * Note that the future returning by this function is only useful for
265
+ * obtaining the value of the next task to be spawning with the
266
+ * builder. If additional tasks are spawned with the same builder
267
+ * then a new result future must be obtained prior to spawning each
268
+ * task.
269
+ */
266
270
fn future_result ( blk : fn ( -future:: future < task_result > ) ) -> task_builder {
271
+ // FIXME (#1087, #1857): Once linked failure and notification are
272
+ // handled in the library, I can imagine implementing this by just
273
+ // registering an arbitrary number of task::on_exit handlers and
274
+ // sending out messages.
275
+
267
276
// Construct the future and give it to the caller.
268
277
let po = comm:: port :: < notification > ( ) ;
269
278
let ch = comm:: chan ( po) ;
@@ -290,6 +299,19 @@ impl task_builder for task_builder {
290
299
with * self . consume ( )
291
300
} )
292
301
}
302
+
303
+ /**
304
+ * Add a wrapper to the body of the spawned task.
305
+ *
306
+ * Before the task is spawned it is passed through a 'body generator'
307
+ * function that may perform local setup operations as well as wrap
308
+ * the task body in remote setup operations. With this the behavior
309
+ * of tasks can be extended in simple ways.
310
+ *
311
+ * This function augments the current body generator with a new body
312
+ * generator by applying the task body which results from the
313
+ * existing body generator to the new body generator.
314
+ */
293
315
fn add_wrapper ( wrapper : fn @( +fn ~( ) ) -> fn ~( ) ) -> task_builder {
294
316
let prev_gen_body = self . gen_body ;
295
317
task_builder ( {
@@ -299,7 +321,18 @@ impl task_builder for task_builder {
299
321
} )
300
322
}
301
323
302
- /// Run the task.
324
+ /**
325
+ * Creates and exucutes a new child task
326
+ *
327
+ * Sets up a new task with its own call stack and schedules it to run
328
+ * the provided unique closure. The task has the properties and behavior
329
+ * specified by the task_builder.
330
+ *
331
+ * # Failure
332
+ *
333
+ * When spawning into a new scheduler, the number of threads requested
334
+ * must be greater than zero.
335
+ */
303
336
fn spawn ( +f : fn ~( ) ) {
304
337
let x = self . consume ( ) ;
305
338
spawn_raw ( x. opts , x. gen_body ( f) ) ;
@@ -313,7 +346,18 @@ impl task_builder for task_builder {
313
346
f ( option:: unwrap ( my_arg) )
314
347
}
315
348
}
316
- /// Runs a task with a listening port, returning the associated channel.
349
+
350
+ /**
351
+ * Runs a new task while providing a channel from the parent to the child
352
+ *
353
+ * Sets up a communication channel from the current task to the new
354
+ * child task, passes the port to child's body, and returns a channel
355
+ * linked to the port to the parent.
356
+ *
357
+ * This encapsulates some boilerplate handshaking logic that would
358
+ * otherwise be required to establish communication from the parent
359
+ * to the child.
360
+ */
317
361
fn spawn_listener < A : send > ( +f : fn ~( comm:: port < A > ) ) -> comm:: chan < A > {
318
362
let setup_po = comm:: port ( ) ;
319
363
let setup_ch = comm:: chan ( setup_po) ;
@@ -346,182 +390,6 @@ fn default_task_opts() -> task_opts {
346
390
}
347
391
}
348
392
349
- fn builder ( ) -> builder {
350
- //! Construct a builder
351
-
352
- let body_identity = fn@( +body : fn ~( ) ) -> fn ~( ) { body } ;
353
-
354
- builder_ ( {
355
- mut opts: default_task_opts ( ) ,
356
- mut gen_body: body_identity,
357
- can_not_copy: none
358
- } )
359
- }
360
-
361
- fn get_opts ( builder : builder ) -> task_opts {
362
- //! Get the task_opts associated with a builder
363
-
364
- builder. opts
365
- }
366
-
367
- fn set_opts ( builder : builder , opts : task_opts ) {
368
- /*!
369
- * Set the task_opts associated with a builder
370
- *
371
- * To update a single option use a pattern like the following:
372
- *
373
- * set_opts(builder, {
374
- * linked: false
375
- * with get_opts(builder)
376
- * });
377
- */
378
-
379
- builder. opts = opts;
380
- }
381
-
382
- fn set_sched_mode ( builder : builder , mode : sched_mode ) {
383
- set_opts ( builder, {
384
- sched: some ( {
385
- mode: mode,
386
- foreign_stack_size: none
387
- } )
388
- with get_opts ( builder)
389
- } ) ;
390
- }
391
-
392
- fn add_wrapper ( builder : builder , gen_body : fn @( +fn ~( ) ) -> fn ~( ) ) {
393
- /*!
394
- * Add a wrapper to the body of the spawned task.
395
- *
396
- * Before the task is spawned it is passed through a 'body generator'
397
- * function that may perform local setup operations as well as wrap
398
- * the task body in remote setup operations. With this the behavior
399
- * of tasks can be extended in simple ways.
400
- *
401
- * This function augments the current body generator with a new body
402
- * generator by applying the task body which results from the
403
- * existing body generator to the new body generator.
404
- */
405
-
406
- let prev_gen_body = builder. gen_body ;
407
- builder. gen_body = fn@( +body : fn ~( ) ) -> fn ~( ) {
408
- gen_body ( prev_gen_body ( body) )
409
- } ;
410
- }
411
-
412
- fn run ( -builder : builder , +f : fn ~( ) ) {
413
- /*!
414
- * Creates and exucutes a new child task
415
- *
416
- * Sets up a new task with its own call stack and schedules it to run
417
- * the provided unique closure. The task has the properties and behavior
418
- * specified by `builder`.
419
- *
420
- * # Failure
421
- *
422
- * When spawning into a new scheduler, the number of threads requested
423
- * must be greater than zero.
424
- */
425
-
426
- let body = builder. gen_body ( f) ;
427
- spawn_raw ( builder. opts , body) ;
428
- }
429
-
430
-
431
- /* Builder convenience functions */
432
-
433
- fn future_result ( builder : builder ) -> future:: future < task_result > {
434
- /*!
435
- * Get a future representing the exit status of the task.
436
- *
437
- * Taking the value of the future will block until the child task
438
- * terminates.
439
- *
440
- * Note that the future returning by this function is only useful for
441
- * obtaining the value of the next task to be spawning with the
442
- * builder. If additional tasks are spawned with the same builder
443
- * then a new result future must be obtained prior to spawning each
444
- * task.
445
- */
446
-
447
- // FIXME (#1087, #1857): Once linked failure and notification are
448
- // handled in the library, I can imagine implementing this by just
449
- // registering an arbitrary number of task::on_exit handlers and
450
- // sending out messages.
451
-
452
- let po = comm:: port ( ) ;
453
- let ch = comm:: chan ( po) ;
454
-
455
- set_opts ( builder, {
456
- notify_chan : some( ch)
457
- with get_opts( builder)
458
- } ) ;
459
-
460
- do future:: from_fn {
461
- alt comm:: recv ( po) {
462
- exit ( _, result) { result }
463
- }
464
- }
465
- }
466
-
467
- fn unsupervise ( builder : builder ) {
468
- //! Configures the new task to not propagate failure to its parent
469
-
470
- set_opts ( builder, {
471
- linked: false
472
- with get_opts ( builder)
473
- } ) ;
474
- }
475
-
476
- fn run_with < A : send > ( -builder : builder ,
477
- +arg : A ,
478
- +f : fn ~( +A ) ) {
479
-
480
- /*!
481
- * Runs a task, while transfering ownership of one argument to the
482
- * child.
483
- *
484
- * This is useful for transfering ownership of noncopyables to
485
- * another task.
486
- *
487
- */
488
-
489
- let arg = ~mut some ( arg) ;
490
- do run( builder) {
491
- let mut my_arg = none;
492
- my_arg <-> * arg;
493
- f ( option:: unwrap ( my_arg) )
494
- }
495
- }
496
-
497
- fn run_listener < A : send > ( -builder : builder ,
498
- +f : fn ~( comm:: port < A > ) ) -> comm:: chan < A > {
499
- /*!
500
- * Runs a new task while providing a channel from the parent to the child
501
- *
502
- * Sets up a communication channel from the current task to the new
503
- * child task, passes the port to child's body, and returns a channel
504
- * linked to the port to the parent.
505
- *
506
- * This encapsulates some boilerplate handshaking logic that would
507
- * otherwise be required to establish communication from the parent
508
- * to the child.
509
- */
510
-
511
- let setup_po = comm:: port ( ) ;
512
- let setup_ch = comm:: chan ( setup_po) ;
513
-
514
- do run( builder) {
515
- let po = comm:: port ( ) ;
516
- let mut ch = comm:: chan ( po) ;
517
- comm:: send ( setup_ch, ch) ;
518
- f ( po) ;
519
- }
520
-
521
- comm:: recv ( setup_po)
522
- }
523
-
524
-
525
393
/* Spawn convenience functions */
526
394
527
395
fn spawn ( +f : fn ~( ) ) {
@@ -531,7 +399,7 @@ fn spawn(+f: fn~()) {
531
399
* Sets up a new task with its own call stack and schedules it to run
532
400
* the provided unique closure.
533
401
*
534
- * This function is equivalent to `run(new_builder(), f)`.
402
+ * This function is equivalent to `task().spawn( f)`.
535
403
*/
536
404
537
405
task ( ) . spawn ( f)
@@ -563,7 +431,7 @@ fn spawn_with<A:send>(+arg: A, +f: fn~(+A)) {
563
431
* This is useful for transfering ownership of noncopyables to
564
432
* another task.
565
433
*
566
- * This function is equivalent to `run_with(builder(), arg, f)`.
434
+ * This function is equivalent to `task().spawn_with( arg, f)`.
567
435
*/
568
436
569
437
task ( ) . spawn_with ( arg, f)
@@ -592,7 +460,7 @@ fn spawn_listener<A:send>(+f: fn~(comm::port<A>)) -> comm::chan<A> {
592
460
* };
593
461
* // Likewise, the parent has both a 'po' and 'ch'
594
462
*
595
- * This function is equivalent to `run_listener(builder(), f)`.
463
+ * This function is equivalent to `task().spawn_listener( f)`.
596
464
*/
597
465
598
466
task ( ) . spawn_listener ( f)
0 commit comments