@@ -151,20 +151,20 @@ where
151151
152152 pub fn is_started ( & mut self ) -> bool {
153153 let started_alive = self . started_alive . lock ( ) . unwrap ( ) ;
154- let & ( ref started, _) = & * started_alive;
154+ let ( started, _) = & * started_alive;
155155 started. load ( Ordering :: SeqCst )
156156 }
157157
158158 pub fn is_alive ( & mut self ) -> bool {
159159 let started_alive = self . started_alive . lock ( ) . unwrap ( ) ;
160- let & ( _, ref alive) = & * started_alive;
160+ let ( _, alive) = & * started_alive;
161161 alive. load ( Ordering :: SeqCst )
162162 }
163163
164164 pub fn stop ( & mut self ) {
165165 {
166166 let started_alive = self . started_alive . lock ( ) . unwrap ( ) ;
167- let & ( ref started, ref alive) = & * started_alive;
167+ let ( started, alive) = & * started_alive;
168168
169169 if !started. load ( Ordering :: SeqCst ) {
170170 return ;
@@ -174,7 +174,6 @@ where
174174 }
175175 alive. store ( false , Ordering :: SeqCst ) ;
176176 }
177-
178177 // NOTE: Kill thread <- OS depending
179178 // let mut join_handle = self.join_handle.lock().unwrap();
180179 // join_handle
@@ -193,7 +192,7 @@ where
193192 pub fn start ( & mut self ) {
194193 {
195194 let started_alive = self . started_alive . lock ( ) . unwrap ( ) ;
196- let & ( ref started, ref alive) = & * started_alive;
195+ let ( started, alive) = & * started_alive;
197196
198197 if started. load ( Ordering :: SeqCst ) {
199198 return ;
@@ -212,7 +211,7 @@ where
212211 self . join_handle = Arc :: new ( Mutex :: new ( Some ( thread:: spawn ( move || {
213212 while {
214213 let started_alive = started_alive_thread. lock ( ) . unwrap ( ) ;
215- let & ( _, ref alive) = & * started_alive;
214+ let ( _, alive) = & * started_alive;
216215
217216 alive. load ( Ordering :: SeqCst )
218217 } {
@@ -225,7 +224,7 @@ where
225224 }
226225 None => {
227226 let started_alive = started_alive_thread. lock ( ) . unwrap ( ) ;
228- let & ( _, ref alive) = & * started_alive;
227+ let ( _, alive) = & * started_alive;
229228
230229 alive. store ( false , Ordering :: SeqCst ) ;
231230 }
@@ -317,7 +316,7 @@ where
317316
318317#[ test]
319318fn test_actor_common ( ) {
320- use std:: time:: Duration ;
319+ use std:: time:: { Duration , Instant } ;
321320
322321 use super :: common:: LinkedListAsync ;
323322
@@ -407,15 +406,32 @@ fn test_actor_common() {
407406 // Send Shutdown
408407 root_handle. send ( Value :: Shutdown ) ;
409408
410- thread:: sleep ( Duration :: from_millis ( 10 ) ) ;
409+ // result_string receives the children-ids vec once the root handles Shutdown;
410+ // the 3 child actors push 6 ints across their own threads. Wait deterministically
411+ // rather than racing a fixed sleep (the 5s ceilings only bound a genuine hang).
412+ let ids_deadline = Instant :: now ( ) + Duration :: from_secs ( 5 ) ;
413+ let ids = loop {
414+ if let Some ( v) = result_string. pop_front ( ) {
415+ break Some ( v) ;
416+ }
417+ if Instant :: now ( ) >= ids_deadline {
418+ break None ;
419+ }
420+ thread:: yield_now ( ) ;
421+ } ;
411422 // 3 children Actors
412- assert_eq ! ( 3 , result_string . pop_front ( ) . unwrap ( ) . len( ) ) ;
423+ assert_eq ! ( Some ( 3 ) , ids . map ( |ids| ids . len( ) ) ) ;
413424
414425 let mut v = Vec :: < Option < i32 > > :: new ( ) ;
415- for _ in 1 ..7 {
416- let i = result_i32. pop_front ( ) ;
417- println ! ( "Actor {:?}" , i) ;
418- v. push ( i) ;
426+ let v_deadline = Instant :: now ( ) + Duration :: from_secs ( 5 ) ;
427+ while v. len ( ) < 6 {
428+ if let Some ( i) = result_i32. pop_front ( ) {
429+ v. push ( Some ( i) ) ;
430+ } else if Instant :: now ( ) >= v_deadline {
431+ break ;
432+ } else {
433+ thread:: yield_now ( ) ;
434+ }
419435 }
420436 v. sort ( ) ;
421437 assert_eq ! (
@@ -433,7 +449,7 @@ fn test_actor_common() {
433449
434450#[ test]
435451fn test_actor_ask ( ) {
436- use std:: time:: Duration ;
452+ use std:: time:: { Duration , Instant } ;
437453
438454 use super :: common:: LinkedListAsync ;
439455
@@ -466,37 +482,47 @@ fn test_actor_ask() {
466482 let mut root_handle = root. get_handle ( ) ;
467483 root. start ( ) ;
468484
469- // LinkedListAsync<i32>
485+ // LinkedListAsync<i32> exposes only a non-blocking pop_front(), so wait-poll
486+ // until the actor has pushed each value. This replaces a fixed sleep with a
487+ // deterministic wait; the deadline only guards against a genuine hang.
488+ let wait_pop = |q : & LinkedListAsync < i32 > | -> Option < i32 > {
489+ let deadline = Instant :: now ( ) + Duration :: from_secs ( 5 ) ;
490+ loop {
491+ if let Some ( v) = q. pop_front ( ) {
492+ return Some ( v) ;
493+ }
494+ if Instant :: now ( ) >= deadline {
495+ return None ;
496+ }
497+ thread:: yield_now ( ) ;
498+ }
499+ } ;
500+
470501 let result_i32 = LinkedListAsync :: < i32 > :: new ( ) ;
471502 root_handle. send ( Value :: AskIntByLinkedListAsync ( ( 1 , result_i32. clone ( ) ) ) ) ;
472503 root_handle. send ( Value :: AskIntByLinkedListAsync ( ( 2 , result_i32. clone ( ) ) ) ) ;
473504 root_handle. send ( Value :: AskIntByLinkedListAsync ( ( 3 , result_i32. clone ( ) ) ) ) ;
474- thread:: sleep ( Duration :: from_millis ( 5 ) ) ;
475- let i = result_i32. pop_front ( ) ;
476- assert_eq ! ( Some ( 10 ) , i) ;
477- let i = result_i32. pop_front ( ) ;
478- assert_eq ! ( Some ( 20 ) , i) ;
479- let i = result_i32. pop_front ( ) ;
480- assert_eq ! ( Some ( 30 ) , i) ;
481-
482- // BlockingQueue<i32>
505+ assert_eq ! ( Some ( 10 ) , wait_pop( & result_i32) ) ;
506+ assert_eq ! ( Some ( 20 ) , wait_pop( & result_i32) ) ;
507+ assert_eq ! ( Some ( 30 ) , wait_pop( & result_i32) ) ;
508+
509+ // BlockingQueue<i32>: take() with a timeout blocks until the actor offers,
510+ // so the data path is deterministic under load. The generous 5s ceiling only
511+ // bounds a genuine hang rather than racing a fixed sleep.
483512 let mut result_i32 = BlockingQueue :: < i32 > :: new ( ) ;
484- result_i32. timeout = Some ( Duration :: from_millis ( 1 ) ) ;
513+ result_i32. timeout = Some ( Duration :: from_secs ( 5 ) ) ;
485514 root_handle. send ( Value :: AskIntByBlockingQueue ( ( 4 , result_i32. clone ( ) ) ) ) ;
486515 root_handle. send ( Value :: AskIntByBlockingQueue ( ( 5 , result_i32. clone ( ) ) ) ) ;
487516 root_handle. send ( Value :: AskIntByBlockingQueue ( ( 6 , result_i32. clone ( ) ) ) ) ;
488- thread:: sleep ( Duration :: from_millis ( 5 ) ) ;
489- let i = result_i32. take ( ) ;
490- assert_eq ! ( Some ( 40 ) , i) ;
491- let i = result_i32. take ( ) ;
492- assert_eq ! ( Some ( 50 ) , i) ;
493- let i = result_i32. take ( ) ;
494- assert_eq ! ( Some ( 60 ) , i) ;
495-
496- // Timeout case:
517+ assert_eq ! ( Some ( 40 ) , result_i32. take( ) ) ;
518+ assert_eq ! ( Some ( 50 ) , result_i32. take( ) ) ;
519+ assert_eq ! ( Some ( 60 ) , result_i32. take( ) ) ;
520+
521+ // Timeout case: the actor returns early for negatives (never offers), so a
522+ // short timeout makes take() return None deterministically.
523+ result_i32. timeout = Some ( Duration :: from_millis ( 1 ) ) ;
497524 root_handle. send ( Value :: AskIntByBlockingQueue ( ( -1 , result_i32. clone ( ) ) ) ) ;
498- let i = result_i32. take ( ) ;
499- assert_eq ! ( None , i) ;
525+ assert_eq ! ( None , result_i32. take( ) ) ;
500526}
501527
502528#[ test]
0 commit comments