9
9
// except according to those terms.
10
10
11
11
use task;
12
+ use task:: local_data:: { local_data_pop, local_data_set} ;
12
13
13
14
// helper for transmutation, shown below.
14
- type RustClosure = ( int , int ) ;
15
+ type RustClosure = ( int , int ) ;
16
+
15
17
pub struct Handler < T , U > {
16
18
handle : RustClosure ,
17
19
prev : Option < @Handler < T , U > > ,
18
20
}
19
21
20
22
pub struct Condition < T , U > {
21
23
name : & static /str ,
22
- key : task:: local_data:: LocalDataKey < Handler < T , U > >
24
+ key : task:: local_data:: LocalDataKey < Handler < T , U > >
23
25
}
24
26
25
- impl < T , U > Condition < T , U > {
26
-
27
- fn trap ( & self , h : & self /fn ( & T ) ->U ) -> Trap /& self <T , U > {
27
+ impl < T , U > Condition < T , U > {
28
+ fn trap ( & self , h : & self /fn ( T ) -> U ) -> Trap /& self <T , U > {
28
29
unsafe {
29
30
let p : * RustClosure = :: cast:: transmute ( & h) ;
30
31
let prev = task:: local_data:: local_data_get ( self . key ) ;
31
- let h = @Handler { handle : * p, prev : prev} ;
32
- move Trap { cond : self , handler : h }
32
+ let h = @Handler { handle : * p, prev : prev } ;
33
+ Trap { cond : self , handler : h }
33
34
}
34
35
}
35
36
36
- fn raise ( t : & T ) -> U {
37
- do self . raise_default ( t) {
38
- fail fmt ! ( "Unhandled condition: %s: %?" ,
39
- self . name,
40
- t) ;
41
- }
37
+ fn raise ( t : T ) -> U {
38
+ let msg = fmt ! ( "Unhandled condition: %s: %?" , self . name, t) ;
39
+ self . raise_default ( t, || fail msg)
42
40
}
43
41
44
- fn raise_default ( t : & T , default : fn ( ) -> U ) -> U {
42
+ fn raise_default ( t : T , default : & fn ( ) -> U ) -> U {
45
43
unsafe {
46
- match task :: local_data :: local_data_pop ( self . key ) {
44
+ match local_data_pop ( self . key ) {
47
45
None => {
48
46
debug ! ( "Condition.raise: found no handler" ) ;
49
47
default ( )
50
48
}
51
-
52
49
Some ( handler) => {
53
50
debug ! ( "Condition.raise: found handler" ) ;
54
51
match handler. prev {
55
- None => ( ) ,
56
- Some ( hp) =>
57
- task:: local_data:: local_data_set ( self . key , hp)
52
+ None => { }
53
+ Some ( hp) => local_data_set ( self . key , hp)
58
54
}
59
- let handle : & fn ( & T ) -> U =
55
+ let handle : & fn ( T ) -> U =
60
56
:: cast:: transmute ( handler. handle ) ;
61
57
let u = handle ( t) ;
62
- task:: local_data:: local_data_set ( self . key ,
63
- handler) ;
64
- move u
58
+ local_data_set ( self . key , handler) ;
59
+ u
65
60
}
66
61
}
67
62
}
68
63
}
69
64
}
70
65
71
-
72
-
73
66
struct Trap < T , U > {
74
- cond : & Condition < T , U > ,
67
+ cond : & Condition < T , U > ,
75
68
handler : @Handler < T , U >
76
69
}
77
70
78
- impl < T , U > Trap < T , U > {
71
+ impl < T , U > Trap < T , U > {
79
72
fn in < V > ( & self , inner : & self /fn ( ) -> V ) -> V {
80
73
unsafe {
81
74
let _g = Guard { cond : self . cond } ;
82
75
debug ! ( "Trap: pushing handler to TLS" ) ;
83
- task :: local_data :: local_data_set ( self . cond . key , self . handler ) ;
76
+ local_data_set ( self . cond . key , self . handler ) ;
84
77
inner ( )
85
78
}
86
79
}
87
80
}
88
81
89
82
struct Guard < T , U > {
90
- cond : & Condition < T , U > ,
91
- drop {
83
+ cond : & Condition < T , U >
84
+ }
85
+
86
+ impl < T , U > Guard < T , U > : Drop {
87
+ fn finalize ( & self ) {
92
88
unsafe {
93
89
debug ! ( "Guard: popping handler from TLS" ) ;
94
- let curr = task :: local_data :: local_data_pop ( self . cond. key) ;
90
+ let curr = local_data_pop ( self . cond . key ) ;
95
91
match curr {
96
- None => ( ) ,
97
- Some ( h) =>
98
- match h. prev {
99
- None => ( ) ,
100
- Some ( hp) => {
101
- task:: local_data:: local_data_set ( self . cond . key , hp)
102
- }
92
+ None => { }
93
+ Some ( h) => match h. prev {
94
+ None => { }
95
+ Some ( hp) => local_data_set ( self . cond . key , hp)
103
96
}
104
97
}
105
98
}
106
99
}
107
100
}
108
101
109
-
110
102
#[ cfg( test) ]
111
103
mod test {
112
-
113
104
condition ! {
114
105
sadness: int -> int;
115
106
}
116
107
117
108
fn trouble ( i : int ) {
118
- debug ! ( "trouble: raising conition " ) ;
119
- let j = sadness:: cond. raise ( & i) ;
109
+ debug ! ( "trouble: raising condition " ) ;
110
+ let j = sadness:: cond. raise ( i) ;
120
111
debug ! ( "trouble: handler recovered with %d" , j) ;
121
112
}
122
113
123
114
fn nested_trap_test_inner ( ) {
124
-
125
115
let mut inner_trapped = false ;
126
116
127
117
do sadness:: cond. trap ( |_j| {
@@ -138,7 +128,6 @@ mod test {
138
128
139
129
#[ test]
140
130
fn nested_trap_test_outer ( ) {
141
-
142
131
let mut outer_trapped = false ;
143
132
144
133
do sadness:: cond. trap ( |_j| {
@@ -154,15 +143,14 @@ mod test {
154
143
}
155
144
156
145
fn nested_reraise_trap_test_inner ( ) {
157
-
158
146
let mut inner_trapped = false ;
159
147
160
148
do sadness:: cond. trap ( |_j| {
161
149
debug ! ( "nested_reraise_trap_test_inner: in handler" ) ;
162
150
inner_trapped = true ;
163
151
let i = 10 ;
164
152
debug ! ( "nested_reraise_trap_test_inner: handler re-raising" ) ;
165
- sadness:: cond. raise ( & i)
153
+ sadness:: cond. raise ( i)
166
154
} ) . in {
167
155
debug ! ( "nested_reraise_trap_test_inner: in protected block" ) ;
168
156
trouble ( 1 ) ;
@@ -173,7 +161,6 @@ mod test {
173
161
174
162
#[ test]
175
163
fn nested_reraise_trap_test_outer ( ) {
176
-
177
164
let mut outer_trapped = false ;
178
165
179
166
do sadness:: cond. trap ( |_j| {
@@ -189,18 +176,16 @@ mod test {
189
176
190
177
#[ test]
191
178
fn test_default ( ) {
192
-
193
179
let mut trapped = false ;
194
180
195
181
do sadness:: cond. trap ( |j| {
196
182
debug ! ( "test_default: in handler" ) ;
197
- sadness:: cond. raise_default ( j, || { trapped=true ; 5 } )
183
+ sadness:: cond. raise_default ( j, || { trapped=true ; 5 } )
198
184
} ) . in {
199
185
debug ! ( "test_default: in protected block" ) ;
200
186
trouble ( 1 ) ;
201
187
}
202
188
203
189
assert trapped;
204
190
}
205
-
206
191
}
0 commit comments