20
20
//! can be created in the future and there must be no active timers at that
21
21
//! time.
22
22
23
+ #![ macro_escape]
24
+
23
25
use prelude:: * ;
24
26
25
27
use cell:: UnsafeCell ;
@@ -68,6 +70,17 @@ struct RaceBox(helper_signal::signal);
68
70
unsafe impl Send for RaceBox { }
69
71
unsafe impl Sync for RaceBox { }
70
72
73
+ macro_rules! helper_init { ( static $name: ident: Helper <$m: ty>) => (
74
+ static $name: Helper <$m> = Helper {
75
+ lock: :: sync:: MUTEX_INIT ,
76
+ cond: :: sync:: CONDVAR_INIT ,
77
+ chan: :: cell:: UnsafeCell { value: 0 as * mut Sender <$m> } ,
78
+ signal: :: cell:: UnsafeCell { value: 0 } ,
79
+ initialized: :: cell:: UnsafeCell { value: false } ,
80
+ shutdown: :: cell:: UnsafeCell { value: false } ,
81
+ } ;
82
+ ) }
83
+
71
84
impl < M : Send > Helper < M > {
72
85
/// Lazily boots a helper thread, becoming a no-op if the helper has already
73
86
/// been spawned.
@@ -84,7 +97,7 @@ impl<M: Send> Helper<M> {
84
97
{
85
98
unsafe {
86
99
let _guard = self . lock . lock ( ) . unwrap ( ) ;
87
- if ! * self . initialized . get ( ) {
100
+ if * self . chan . get ( ) as uint == 0 {
88
101
let ( tx, rx) = channel ( ) ;
89
102
* self . chan . get ( ) = mem:: transmute ( box tx) ;
90
103
let ( receive, send) = helper_signal:: new ( ) ;
@@ -93,15 +106,17 @@ impl<M: Send> Helper<M> {
93
106
let receive = RaceBox ( receive) ;
94
107
95
108
let t = f ( ) ;
96
- Thread :: spawn ( move |: | {
109
+ Thread :: spawn ( move || {
97
110
helper ( receive. 0 , rx, t) ;
98
111
let _g = self . lock . lock ( ) . unwrap ( ) ;
99
112
* self . shutdown . get ( ) = true ;
100
113
self . cond . notify_one ( )
101
114
} ) . detach ( ) ;
102
115
103
- rt:: at_exit ( move | : | { self . shutdown ( ) } ) ;
116
+ rt:: at_exit ( move | | { self . shutdown ( ) } ) ;
104
117
* self . initialized . get ( ) = true ;
118
+ } else if * self . chan . get ( ) as uint == 1 {
119
+ panic ! ( "cannot continue usage after shutdown" ) ;
105
120
}
106
121
}
107
122
}
@@ -116,7 +131,9 @@ impl<M: Send> Helper<M> {
116
131
// Must send and *then* signal to ensure that the child receives the
117
132
// message. Otherwise it could wake up and go to sleep before we
118
133
// send the message.
119
- assert ! ( !self . chan. get( ) . is_null( ) ) ;
134
+ assert ! ( * self . chan. get( ) as uint != 0 ) ;
135
+ assert ! ( * self . chan. get( ) as uint != 1 ,
136
+ "cannot continue usage after shutdown" ) ;
120
137
( * * self . chan . get ( ) ) . send ( msg) ;
121
138
helper_signal:: signal ( * self . signal . get ( ) as helper_signal:: signal ) ;
122
139
}
@@ -129,9 +146,13 @@ impl<M: Send> Helper<M> {
129
146
// returns.
130
147
let mut guard = self . lock . lock ( ) . unwrap ( ) ;
131
148
149
+ let ptr = * self . chan . get ( ) ;
150
+ if ptr as uint == 1 {
151
+ panic ! ( "cannot continue usage after shutdown" ) ;
152
+ }
132
153
// Close the channel by destroying it
133
154
let chan: Box < Sender < M > > = mem:: transmute ( * self . chan . get ( ) ) ;
134
- * self . chan . get ( ) = 0 as * mut Sender < M > ;
155
+ * self . chan . get ( ) = 1 as * mut Sender < M > ;
135
156
drop ( chan) ;
136
157
helper_signal:: signal ( * self . signal . get ( ) as helper_signal:: signal ) ;
137
158
0 commit comments