@@ -20,6 +20,7 @@ use rt::select::{SelectInner, SelectPortInner};
20
20
use rt:: local:: Local ;
21
21
use rt:: rtio:: EventLoop ;
22
22
use task;
23
+ use unstable:: finally:: Finally ;
23
24
use vec:: { OwnedVector , MutableVector } ;
24
25
25
26
/// Trait for message-passing primitives that can be select()ed on.
@@ -57,28 +58,32 @@ pub fn select<A: Select>(ports: &mut [A]) -> uint {
57
58
let p = Cell :: new ( p) ;
58
59
let c = Cell :: new ( c) ;
59
60
60
- let sched = Local :: take :: < Scheduler > ( ) ;
61
- do sched. deschedule_running_task_and_then |sched, task| {
62
- let task_handles = task. make_selectable ( ports. len ( ) ) ;
63
-
64
- for ( index, ( port, task_handle) ) in
65
- ports. mut_iter ( ) . zip ( task_handles. move_iter ( ) ) . enumerate ( ) {
66
- // If one of the ports has data by now, it will wake the handle.
67
- if port. block_on ( sched, task_handle) {
68
- ready_index = index;
69
- break ;
61
+ do ( || {
62
+ let c = Cell :: new ( c. take ( ) ) ;
63
+ let sched = Local :: take :: < Scheduler > ( ) ;
64
+ do sched. deschedule_running_task_and_then |sched, task| {
65
+ let task_handles = task. make_selectable ( ports. len ( ) ) ;
66
+
67
+ for ( index, ( port, task_handle) ) in
68
+ ports. mut_iter ( ) . zip ( task_handles. move_iter ( ) ) . enumerate ( ) {
69
+ // If one of the ports has data by now, it will wake the handle.
70
+ if port. block_on ( sched, task_handle) {
71
+ ready_index = index;
72
+ break ;
73
+ }
70
74
}
71
- }
72
75
73
- let c = Cell :: new ( c. take ( ) ) ;
74
- do sched. event_loop . callback { c. take ( ) . send_deferred ( ( ) ) }
76
+ let c = Cell :: new ( c. take ( ) ) ;
77
+ do sched. event_loop . callback { c. take ( ) . send_deferred ( ( ) ) }
78
+ }
79
+ } ) . finally {
80
+ let p = Cell :: new ( p. take ( ) ) ;
81
+ // Unkillable is necessary not because getting killed is dangerous here,
82
+ // but to force the recv not to use the same kill-flag that we used for
83
+ // selecting. Otherwise a user-sender could spuriously wakeup us here.
84
+ do task:: unkillable { p. take ( ) . recv ( ) ; }
75
85
}
76
86
77
- // Unkillable is necessary not because getting killed is dangerous here,
78
- // but to force the recv not to use the same kill-flag that we used for
79
- // selecting. Otherwise a user-sender could spuriously wakeup us here.
80
- do task:: unkillable { p. take ( ) . recv ( ) ; }
81
-
82
87
// Task resumes. Now unblock ourselves from all the ports we blocked on.
83
88
// If the success index wasn't reset, 'take' will just take all of them.
84
89
// Iterate in reverse so the 'earliest' index that's ready gets returned.
0 commit comments