@@ -63,7 +63,9 @@ impl<J: 'static + AsyncJob, T: Copy + Send + 'static>
6363 }
6464 }
6565
66- /// spawns `task` if nothing is running currently, otherwise schedules as `next` overwriting if `next` was set before
66+ /// spawns `task` if nothing is running currently,
67+ /// otherwise schedules as `next` overwriting if `next` was set before.
68+ /// return `true` if the new task gets started right away.
6769 pub fn spawn ( & mut self , task : J ) -> bool {
6870 self . schedule_next ( task) ;
6971 self . check_for_job ( )
@@ -129,23 +131,35 @@ mod test {
129131 use crossbeam_channel:: unbounded;
130132 use pretty_assertions:: assert_eq;
131133 use std:: {
132- sync:: atomic:: AtomicU32 , thread:: sleep, time:: Duration ,
134+ sync:: atomic:: { AtomicBool , AtomicU32 , Ordering } ,
135+ thread,
136+ time:: Duration ,
133137 } ;
134138
135139 #[ derive( Clone ) ]
136140 struct TestJob {
137141 v : Arc < AtomicU32 > ,
142+ finish : Arc < AtomicBool > ,
138143 value_to_add : u32 ,
139144 }
140145
141146 impl AsyncJob for TestJob {
142147 fn run ( & mut self ) {
143- sleep ( Duration :: from_millis ( 100 ) ) ;
148+ self . finish . store ( false , Ordering :: Relaxed ) ;
144149
145- self . v . fetch_add (
146- self . value_to_add ,
147- std:: sync:: atomic:: Ordering :: Relaxed ,
148- ) ;
150+ println ! ( "[job] wait" ) ;
151+
152+ while self . finish . load ( Ordering :: Relaxed ) {
153+ std:: thread:: yield_now ( ) ;
154+ }
155+
156+ println ! ( "[job] sleep" ) ;
157+
158+ thread:: sleep ( Duration :: from_millis ( 100 ) ) ;
159+
160+ println ! ( "[job] done sleeping" ) ;
161+
162+ self . v . fetch_add ( self . value_to_add , Ordering :: Relaxed ) ;
149163 }
150164 }
151165
@@ -160,15 +174,20 @@ mod test {
160174
161175 let task = TestJob {
162176 v : Arc :: new ( AtomicU32 :: new ( 1 ) ) ,
177+ finish : Arc :: new ( AtomicBool :: new ( false ) ) ,
163178 value_to_add : 1 ,
164179 } ;
165180
166181 assert ! ( job. spawn( task. clone( ) ) ) ;
167- sleep ( Duration :: from_millis ( 1 ) ) ;
182+ thread:: sleep ( Duration :: from_millis ( 10 ) ) ;
183+
168184 for _ in 0 ..5 {
185+ println ! ( "spawn" ) ;
169186 assert ! ( !job. spawn( task. clone( ) ) ) ;
170187 }
171188
189+ task. finish . store ( true , Ordering :: Relaxed ) ;
190+
172191 let _foo = receiver. recv ( ) . unwrap ( ) ;
173192 let _foo = receiver. recv ( ) . unwrap ( ) ;
174193 assert ! ( receiver. is_empty( ) ) ;
@@ -179,6 +198,12 @@ mod test {
179198 ) ;
180199 }
181200
201+ fn wait_for_job ( job : & AsyncSingleJob < TestJob , Notificaton > ) {
202+ while job. is_pending ( ) {
203+ thread:: sleep ( Duration :: from_millis ( 10 ) ) ;
204+ }
205+ }
206+
182207 #[ test]
183208 fn test_cancel ( ) {
184209 let ( sender, receiver) = unbounded ( ) ;
@@ -188,17 +213,26 @@ mod test {
188213
189214 let task = TestJob {
190215 v : Arc :: new ( AtomicU32 :: new ( 1 ) ) ,
216+ finish : Arc :: new ( AtomicBool :: new ( false ) ) ,
191217 value_to_add : 1 ,
192218 } ;
193219
194220 assert ! ( job. spawn( task. clone( ) ) ) ;
195- sleep ( Duration :: from_millis ( 1 ) ) ;
221+ task. finish . store ( true , Ordering :: Relaxed ) ;
222+ thread:: sleep ( Duration :: from_millis ( 10 ) ) ;
196223
197224 for _ in 0 ..5 {
225+ println ! ( "spawn" ) ;
198226 assert ! ( !job. spawn( task. clone( ) ) ) ;
199227 }
228+
229+ println ! ( "cancel" ) ;
200230 assert ! ( job. cancel( ) ) ;
201231
232+ task. finish . store ( true , Ordering :: Relaxed ) ;
233+
234+ wait_for_job ( & job) ;
235+
202236 let _foo = receiver. recv ( ) . unwrap ( ) ;
203237
204238 assert_eq ! (
0 commit comments