@@ -587,6 +587,126 @@ mod test {
587
587
assert_eq!( COUNT . load( Ordering :: Relaxed ) , 2 ) ;
588
588
} ) ;
589
589
590
+ async_test_case ! ( ctx_poll => ( rt, ctx) {
591
+
592
+ use std:: {
593
+
594
+ future:: { poll_fn, Future } ,
595
+ pin:: pin,
596
+ sync:: Arc ,
597
+ task:: Poll ,
598
+ } ;
599
+
600
+ use tokio:: { runtime:: Handle , task} ;
601
+
602
+ use crate :: { function:: Func , * } ;
603
+
604
+ fn spawn_timeout<' js>(
605
+ ctx: Ctx <' js>,
606
+ callback: Function <' js>,
607
+ timeout: usize ,
608
+ ) -> Result <( ) > {
609
+ ctx. spawn( async move {
610
+ tokio:: time:: sleep( std:: time:: Duration :: from_millis( timeout as u64 ) ) . await ;
611
+ callback. call:: <_, ( ) >( ( ) ) . unwrap( ) ;
612
+ } ) ;
613
+
614
+ Ok ( ( ) )
615
+ }
616
+
617
+ fn blocking_async<' js>( ctx: Ctx <' js>, promise: Promise <' js>) -> Result <Value <' js>>{
618
+ let mut fut = pin!( promise. into_future:: <Value >( ) ) ;
619
+ task:: block_in_place( move || {
620
+ Handle :: current( ) . block_on( async move {
621
+ poll_fn( move |cx| {
622
+ if let Poll :: Ready ( x) = fut. as_mut( ) . poll( cx) {
623
+ return Poll :: Ready ( x) ;
624
+ }
625
+ ctx. poll( cx) ;
626
+ cx. waker( ) . wake_by_ref( ) ;
627
+ Poll :: Pending
628
+ } )
629
+ . await
630
+ } )
631
+ } )
632
+ }
633
+
634
+
635
+ let order_vec = Arc :: new( std:: sync:: Mutex :: new( Vec :: <u8 >:: new( ) ) ) ;
636
+ let order_vec2 = order_vec. clone( ) ;
637
+
638
+ ctx. with( |ctx|{
639
+
640
+ let res = || {
641
+ let globals = ctx. globals( ) ;
642
+ globals. set( "setTimeout" , Func :: from( spawn_timeout) ) ?;
643
+ globals. set( "blockingAsync" , Func :: from( blocking_async) ) ?;
644
+ globals. set( "done" , Func :: from( || {
645
+
646
+ } ) ) ?;
647
+ globals. set( "storeOrder" , Func :: from( move |value: u8 | {
648
+ order_vec2. clone( ) . lock( ) . unwrap( ) . push( value) ;
649
+ } ) ) ?;
650
+
651
+
652
+ let mut options = EvalOptions :: default ( ) ;
653
+ options. global = false ;
654
+
655
+ ctx. eval_with_options( r#"
656
+
657
+ await new Promise((res) => setTimeout(res, 1));
658
+
659
+ storeOrder(1);
660
+
661
+ blockingAsync(
662
+ new Promise((res) =>
663
+ setTimeout(() => {
664
+ storeOrder(2);
665
+ res();
666
+ }, 1),
667
+ ),
668
+ );
669
+
670
+ storeOrder(3);
671
+
672
+ setTimeout(() => {
673
+ setTimeout(async () => {
674
+ await new Promise((res) => setTimeout(res, 1));
675
+ storeOrder(4);
676
+ blockingAsync(
677
+ new Promise((res) =>
678
+ setTimeout(() => {
679
+ storeOrder(5);
680
+ res();
681
+ }, 1),
682
+ ),
683
+ );
684
+ storeOrder(6);
685
+ }, 1);
686
+ }, 1);
687
+
688
+
689
+ "# , options) ?;
690
+
691
+ Ok :: <_, Error >( ( ) )
692
+ } ;
693
+ res( ) . catch( & ctx) . unwrap( ) ;
694
+ } ) . await ;
695
+
696
+
697
+ rt. idle( ) . await ;
698
+
699
+ //assert that order is correct using a loop
700
+ let mut order = order_vec. lock( ) . unwrap( ) ;
701
+ let mut i = order. len( ) ;
702
+ while let Some ( value) = order. pop( ) {
703
+ assert_eq!( value as usize , i) ;
704
+ i -= 1 ;
705
+ }
706
+
707
+
708
+ } ) ;
709
+
590
710
#[ cfg( feature = "parallel" ) ]
591
711
fn assert_is_send < T : Send > ( t : T ) -> T {
592
712
t
0 commit comments