Commit addbfb9 1 parent 8182ecf commit addbfb9 Copy full SHA for addbfb9
File tree 3 files changed +63
-1
lines changed
src/runtime/scheduler/multi_thread
3 files changed +63
-1
lines changed Original file line number Diff line number Diff line change @@ -782,7 +782,13 @@ impl Context {
782
782
}
783
783
784
784
pub ( crate ) fn defer ( & self , waker : & Waker ) {
785
- self . defer . defer ( waker) ;
785
+ if self . core . borrow ( ) . is_none ( ) {
786
+ // If there is no core, then the worker is currently in a block_in_place. In this case,
787
+ // we cannot use the defer queue as we aren't really in the current runtime.
788
+ waker. wake_by_ref ( ) ;
789
+ } else {
790
+ self . defer . defer ( waker) ;
791
+ }
786
792
}
787
793
788
794
#[ allow( dead_code) ]
Original file line number Diff line number Diff line change @@ -126,6 +126,17 @@ fn unbounded_mpsc_channel() {
126
126
} )
127
127
}
128
128
129
+ #[ test]
130
+ fn yield_in_block_in_place ( ) {
131
+ test_with_runtimes ( || {
132
+ Handle :: current ( ) . block_on ( async {
133
+ tokio:: task:: block_in_place ( || {
134
+ Handle :: current ( ) . block_on ( tokio:: task:: yield_now ( ) ) ;
135
+ } ) ;
136
+ } ) ;
137
+ } )
138
+ }
139
+
129
140
#[ cfg( not( target_os = "wasi" ) ) ] // Wasi doesn't support file operations or bind
130
141
rt_test ! {
131
142
use tokio:: fs;
Original file line number Diff line number Diff line change @@ -647,6 +647,51 @@ fn test_nested_block_in_place_with_block_on_between() {
647
647
}
648
648
}
649
649
650
+ #[ test]
651
+ fn yield_now_in_block_in_place ( ) {
652
+ let rt = runtime:: Builder :: new_multi_thread ( )
653
+ . worker_threads ( 1 )
654
+ . build ( )
655
+ . unwrap ( ) ;
656
+
657
+ rt. block_on ( async {
658
+ tokio:: spawn ( async {
659
+ tokio:: task:: block_in_place ( || {
660
+ tokio:: runtime:: Handle :: current ( ) . block_on ( tokio:: task:: yield_now ( ) ) ;
661
+ } )
662
+ } )
663
+ . await
664
+ . unwrap ( )
665
+ } )
666
+ }
667
+
668
+ #[ test]
669
+ fn mutex_in_block_in_place ( ) {
670
+ const BUDGET : usize = 128 ;
671
+
672
+ let rt = runtime:: Builder :: new_multi_thread ( )
673
+ . worker_threads ( 1 )
674
+ . build ( )
675
+ . unwrap ( ) ;
676
+
677
+ rt. block_on ( async {
678
+ let lock = tokio:: sync:: Mutex :: new ( 0 ) ;
679
+
680
+ tokio:: spawn ( async move {
681
+ tokio:: task:: block_in_place ( || {
682
+ tokio:: runtime:: Handle :: current ( ) . block_on ( async move {
683
+ for i in 0 ..( BUDGET + 1 ) {
684
+ let mut guard = lock. lock ( ) . await ;
685
+ * guard = i;
686
+ }
687
+ } ) ;
688
+ } )
689
+ } )
690
+ . await
691
+ . unwrap ( ) ;
692
+ } )
693
+ }
694
+
650
695
// Testing the tuning logic is tricky as it is inherently timing based, and more
651
696
// of a heuristic than an exact behavior. This test checks that the interval
652
697
// changes over time based on load factors. There are no assertions, completion
You can’t perform that action at this time.
0 commit comments