@@ -120,6 +120,8 @@ pub struct SchedOpts {
120
120
*
121
121
* * notify_chan - Enable lifecycle notifications on the given channel
122
122
*
123
+ * * name - A name for the task-to-be, for identification in failure messages.
124
+ *
123
125
* * sched - Specify the configuration of a new scheduler to create the task
124
126
* in
125
127
*
@@ -139,6 +141,7 @@ pub struct TaskOpts {
139
141
watched : bool ,
140
142
indestructible : bool ,
141
143
notify_chan : Option < Chan < TaskResult > > ,
144
+ name : Option < ~str > ,
142
145
sched : SchedOpts
143
146
}
144
147
@@ -185,23 +188,23 @@ impl TaskBuilder {
185
188
self . consumed = true ;
186
189
let gen_body = self . gen_body . take ( ) ;
187
190
let notify_chan = self . opts . notify_chan . take ( ) ;
191
+ let name = self . opts . name . take ( ) ;
188
192
TaskBuilder {
189
193
opts : TaskOpts {
190
194
linked : self . opts . linked ,
191
195
supervised : self . opts . supervised ,
192
196
watched : self . opts . watched ,
193
197
indestructible : self . opts . indestructible ,
194
198
notify_chan : notify_chan,
199
+ name : name,
195
200
sched : self . opts . sched
196
201
} ,
197
202
gen_body : gen_body,
198
203
can_not_copy : None ,
199
204
consumed : false
200
205
}
201
206
}
202
- }
203
207
204
- impl TaskBuilder {
205
208
/// Decouple the child task's failure from the parent's. If either fails,
206
209
/// the other will not be killed.
207
210
pub fn unlinked ( & mut self ) {
@@ -281,6 +284,12 @@ impl TaskBuilder {
281
284
self . opts . notify_chan = Some ( notify_pipe_ch) ;
282
285
}
283
286
287
+ /// Name the task-to-be. Currently the name is used for identification
288
+ /// only in failure messages.
289
+ pub fn name ( & mut self , name : ~str ) {
290
+ self . opts . name = Some ( name) ;
291
+ }
292
+
284
293
/// Configure a custom scheduler mode for the task.
285
294
pub fn sched_mode ( & mut self , mode : SchedMode ) {
286
295
self . opts . sched . mode = mode;
@@ -333,13 +342,15 @@ impl TaskBuilder {
333
342
pub fn spawn ( & mut self , f : ~fn ( ) ) {
334
343
let gen_body = self . gen_body . take ( ) ;
335
344
let notify_chan = self . opts . notify_chan . take ( ) ;
345
+ let name = self . opts . name . take ( ) ;
336
346
let x = self . consume ( ) ;
337
347
let opts = TaskOpts {
338
348
linked : x. opts . linked ,
339
349
supervised : x. opts . supervised ,
340
350
watched : x. opts . watched ,
341
351
indestructible : x. opts . indestructible ,
342
352
notify_chan : notify_chan,
353
+ name : name,
343
354
sched : x. opts . sched
344
355
} ;
345
356
let f = match gen_body {
@@ -408,6 +419,7 @@ pub fn default_task_opts() -> TaskOpts {
408
419
watched : true ,
409
420
indestructible : false ,
410
421
notify_chan : None ,
422
+ name : None ,
411
423
sched : SchedOpts {
412
424
mode : DefaultScheduler ,
413
425
}
@@ -507,6 +519,21 @@ pub fn try<T:Send>(f: ~fn() -> T) -> Result<T,()> {
507
519
508
520
/* Lifecycle functions */
509
521
522
+ /// Read the name of the current task.
523
+ pub fn with_task_name < U > ( blk : & fn ( Option < & str > ) -> U ) -> U {
524
+ use rt:: task:: Task ;
525
+
526
+ match context ( ) {
527
+ TaskContext => do Local :: borrow :: < Task , U > |task| {
528
+ match task. name {
529
+ Some ( ref name) => blk ( Some ( name. as_slice ( ) ) ) ,
530
+ None => blk ( None )
531
+ }
532
+ } ,
533
+ _ => fail ! ( "no task name exists in %?" , context( ) ) ,
534
+ }
535
+ }
536
+
510
537
pub fn yield ( ) {
511
538
//! Yield control to the task scheduler
512
539
@@ -628,44 +655,6 @@ pub unsafe fn rekillable<U>(f: &fn() -> U) -> U {
628
655
}
629
656
}
630
657
631
- /**
632
- * A stronger version of unkillable that also inhibits scheduling operations.
633
- * For use with exclusive Arcs, which use pthread mutexes directly.
634
- */
635
- pub unsafe fn atomically < U > ( f : & fn ( ) -> U ) -> U {
636
- use rt:: task:: Task ;
637
-
638
- match context ( ) {
639
- OldTaskContext => {
640
- let t = rt:: rust_get_task ( ) ;
641
- do ( || {
642
- rt:: rust_task_inhibit_kill ( t) ;
643
- rt:: rust_task_inhibit_yield ( t) ;
644
- f ( )
645
- } ) . finally {
646
- rt:: rust_task_allow_yield ( t) ;
647
- rt:: rust_task_allow_kill ( t) ;
648
- }
649
- }
650
- TaskContext => {
651
- let t = Local :: unsafe_borrow :: < Task > ( ) ;
652
- do ( || {
653
- // It's important to inhibit kill after inhibiting yield, because
654
- // inhibit-kill might fail if we were already killed, and the
655
- // inhibit-yield must happen to match the finally's allow-yield.
656
- ( * t) . death . inhibit_yield ( ) ;
657
- ( * t) . death . inhibit_kill ( ( * t) . unwinder . unwinding ) ;
658
- f ( )
659
- } ) . finally {
660
- ( * t) . death . allow_kill ( ( * t) . unwinder . unwinding ) ;
661
- ( * t) . death . allow_yield ( ) ;
662
- }
663
- }
664
- // FIXME(#3095): As in unkillable().
665
- _ => f ( )
666
- }
667
- }
668
-
669
658
#[ test] #[ should_fail] #[ ignore( cfg( windows) ) ]
670
659
fn test_cant_dup_task_builder ( ) {
671
660
let mut builder = task ( ) ;
@@ -805,6 +794,34 @@ fn test_spawn_linked_sup_propagate_sibling() {
805
794
fail ! ( ) ;
806
795
}
807
796
797
+ #[ test]
798
+ fn test_unnamed_task( ) {
799
+ use rt:: test:: run_in_newsched_task;
800
+
801
+ do run_in_newsched_task {
802
+ do spawn {
803
+ do with_task_name |name| {
804
+ assert!( name. is_none( ) ) ;
805
+ }
806
+ }
807
+ }
808
+ }
809
+
810
+ #[ test]
811
+ fn test_named_task( ) {
812
+ use rt:: test:: run_in_newsched_task;
813
+
814
+ do run_in_newsched_task {
815
+ let mut t = task( ) ;
816
+ t. name( ~"ada lovelace") ;
817
+ do t. spawn {
818
+ do with_task_name |name| {
819
+ assert!( name. get( ) == "ada lovelace" ) ;
820
+ }
821
+ }
822
+ }
823
+ }
824
+
808
825
#[ test]
809
826
fn test_run_basic( ) {
810
827
let ( po, ch) = stream :: < ( ) > ( ) ;
@@ -1122,21 +1139,6 @@ fn test_unkillable_nested() {
1122
1139
po. recv( ) ;
1123
1140
}
1124
1141
1125
- #[ test] #[ should_fail] #[ ignore( cfg( windows) ) ]
1126
- fn test_atomically( ) {
1127
- unsafe { do atomically { yield( ) ; } }
1128
- }
1129
-
1130
- #[ test]
1131
- fn test_atomically2 ( ) {
1132
- unsafe { do atomically { } } yield ( ) ; // shouldn't fail
1133
- }
1134
-
1135
- #[ test] #[ should_fail] #[ ignore( cfg( windows) ) ]
1136
- fn test_atomically_nested ( ) {
1137
- unsafe { do atomically { do atomically { } yield( ) ; } }
1138
- }
1139
-
1140
1142
#[ test]
1141
1143
fn test_child_doesnt_ref_parent( ) {
1142
1144
// If the child refcounts the parent task, this will stack overflow when
0 commit comments