1- use std:: cell:: { BorrowError , Cell , RefCell , RefMut } ;
1+ use std:: cell:: { Cell , UnsafeCell } ;
22use std:: collections:: VecDeque ;
33use std:: fmt;
44use std:: marker:: PhantomData ;
@@ -83,7 +83,7 @@ impl<'a> LocalExecutor<'a> {
8383 /// assert!(local_ex.is_empty());
8484 /// ```
8585 pub fn is_empty ( & self ) -> bool {
86- self . state ( ) . active ( ) . is_empty ( )
86+ unsafe { & * self . state ( ) . active . get ( ) } . is_empty ( )
8787 }
8888
8989 /// Spawns a task onto the executor.
@@ -100,8 +100,8 @@ impl<'a> LocalExecutor<'a> {
100100 /// });
101101 /// ```
102102 pub fn spawn < T : ' a > ( & self , future : impl Future < Output = T > + ' a ) -> Task < T > {
103- let mut active = self . state ( ) . active ( ) ;
104- self . spawn_inner ( future, & mut active)
103+ let active = unsafe { & mut * self . state ( ) . active . get ( ) } ;
104+ self . spawn_inner ( future, active)
105105 }
106106
107107 /// Spawns many tasks onto the executor.
@@ -149,12 +149,12 @@ impl<'a> LocalExecutor<'a> {
149149 futures : impl IntoIterator < Item = F > ,
150150 handles : & mut impl Extend < Task < F :: Output > > ,
151151 ) {
152- let mut active = self . state ( ) . active ( ) ;
152+ let active = unsafe { & mut * self . state ( ) . active . get ( ) } ;
153153
154154 // Convert the futures into tasks.
155155 let tasks = futures
156156 . into_iter ( )
157- . map ( move |future| self . spawn_inner ( future, & mut active) ) ;
157+ . map ( move |future| self . spawn_inner ( future, active) ) ;
158158
159159 // Push the tasks to the user's collection.
160160 handles. extend ( tasks) ;
@@ -170,7 +170,9 @@ impl<'a> LocalExecutor<'a> {
170170 let entry = active. vacant_entry ( ) ;
171171 let index = entry. key ( ) ;
172172 let state = self . state_as_rc ( ) ;
173- let future = AsyncCallOnDrop :: new ( future, move || drop ( state. active ( ) . try_remove ( index) ) ) ;
173+ let future = AsyncCallOnDrop :: new ( future, move || {
174+ drop ( unsafe { & mut * state. active . get ( ) } . try_remove ( index) )
175+ } ) ;
174176
175177 // Create the task and register it in the set of active tasks.
176178 //
@@ -276,7 +278,10 @@ impl<'a> LocalExecutor<'a> {
276278
277279 // TODO: If possible, push into the current local queue and notify the ticker.
278280 move |runnable| {
279- state. queue . borrow_mut ( ) . push_front ( runnable) ;
281+ {
282+ let queue = unsafe { & mut * state. queue . get ( ) } ;
283+ queue. push_front ( runnable) ;
284+ }
280285 state. notify ( ) ;
281286 }
282287 }
@@ -331,13 +336,14 @@ impl Drop for LocalExecutor<'_> {
331336 // via Arc::into_raw in state_ptr.
332337 let state = unsafe { Rc :: from_raw ( ptr) } ;
333338
334- let mut active = state. active ( ) ;
335- for w in active. drain ( ) {
336- w. wake ( ) ;
339+ {
340+ let active = unsafe { & mut * state. active . get ( ) } ;
341+ for w in active. drain ( ) {
342+ w. wake ( ) ;
343+ }
337344 }
338- drop ( active) ;
339345
340- state. queue . borrow_mut ( ) . clear ( ) ;
346+ unsafe { & mut * state. queue . get ( ) } . clear ( ) ;
341347 }
342348}
343349
@@ -350,44 +356,41 @@ impl<'a> Default for LocalExecutor<'a> {
350356/// The state of a executor.
351357pub ( crate ) struct State {
352358 /// The global queue.
353- pub ( crate ) queue : RefCell < VecDeque < Runnable > > ,
359+ pub ( crate ) queue : UnsafeCell < VecDeque < Runnable > > ,
354360
355361 /// A list of sleeping tickers.
356- sleepers : RefCell < Sleepers > ,
362+ sleepers : UnsafeCell < Sleepers > ,
357363
358364 /// Currently active tasks.
359- active : RefCell < Slab < Waker > > ,
365+ pub ( crate ) active : UnsafeCell < Slab < Waker > > ,
360366}
361367
362368impl State {
363369 /// Creates state for a new executor.
364370 pub ( crate ) const fn new ( ) -> State {
365371 State {
366- queue : RefCell :: new ( VecDeque :: new ( ) ) ,
367- sleepers : RefCell :: new ( Sleepers {
372+ queue : UnsafeCell :: new ( VecDeque :: new ( ) ) ,
373+ sleepers : UnsafeCell :: new ( Sleepers {
368374 count : 0 ,
369375 wakers : Vec :: new ( ) ,
370376 free_ids : Vec :: new ( ) ,
371377 } ) ,
372- active : RefCell :: new ( Slab :: new ( ) ) ,
378+ active : UnsafeCell :: new ( Slab :: new ( ) ) ,
373379 }
374380 }
375381
376- /// Returns a reference to currently active tasks.
377- pub ( crate ) fn active ( & self ) -> RefMut < ' _ , Slab < Waker > > {
378- self . active . borrow_mut ( )
379- }
380-
381382 /// Notifies a sleeping ticker.
382383 #[ inline]
383384 pub ( crate ) fn notify ( & self ) {
384- if let Some ( w) = self . sleepers . borrow_mut ( ) . notify ( ) {
385+ let waker = unsafe { & mut * self . sleepers . get ( ) } . notify ( ) ;
386+ if let Some ( w) = waker {
385387 w. wake ( ) ;
386388 }
387389 }
388390
389391 pub ( crate ) fn try_tick ( & self ) -> bool {
390- match self . queue . borrow_mut ( ) . pop_back ( ) {
392+ let runnable = unsafe { & mut * self . queue . get ( ) } . pop_back ( ) ;
393+ match runnable {
391394 None => false ,
392395 Some ( runnable) => {
393396 // Run the task.
@@ -443,16 +446,16 @@ impl Ticker<'_> {
443446 ///
444447 /// Returns `false` if the ticker was already sleeping and unnotified.
445448 fn sleep ( & mut self , waker : & Waker ) -> bool {
446- let mut sleepers = self . state . sleepers . borrow_mut ( ) ;
447-
448449 match self . sleeping {
449450 // Move to sleeping state.
450451 0 => {
452+ let sleepers = unsafe { & mut * self . state . sleepers . get ( ) } ;
451453 self . sleeping = sleepers. insert ( waker) ;
452454 }
453455
454456 // Already sleeping, check if notified.
455457 id => {
458+ let sleepers = unsafe { & mut * self . state . sleepers . get ( ) } ;
456459 if !sleepers. update ( id, waker) {
457460 return false ;
458461 }
@@ -465,7 +468,8 @@ impl Ticker<'_> {
465468 /// Moves the ticker into woken state.
466469 fn wake ( & mut self ) {
467470 if self . sleeping != 0 {
468- self . state . sleepers . borrow_mut ( ) . remove ( self . sleeping ) ;
471+ let sleepers = unsafe { & mut * self . state . sleepers . get ( ) } ;
472+ sleepers. remove ( self . sleeping ) ;
469473 }
470474 self . sleeping = 0 ;
471475 }
@@ -474,7 +478,7 @@ impl Ticker<'_> {
474478 async fn runnable ( & mut self ) -> Runnable {
475479 future:: poll_fn ( |cx| {
476480 loop {
477- match self . state . queue . borrow_mut ( ) . pop_back ( ) {
481+ match unsafe { & mut * self . state . queue . get ( ) } . pop_back ( ) {
478482 None => {
479483 // Move to sleeping and unnotified state.
480484 if !self . sleep ( cx. waker ( ) ) {
@@ -499,12 +503,13 @@ impl Drop for Ticker<'_> {
499503 fn drop ( & mut self ) {
500504 // If this ticker is in sleeping state, it must be removed from the sleepers list.
501505 if self . sleeping != 0 {
502- let mut sleepers = self . state . sleepers . borrow_mut ( ) ;
503- let notified = sleepers. remove ( self . sleeping ) ;
506+ let notified = {
507+ let sleepers = unsafe { & mut * self . state . sleepers . get ( ) } ;
508+ sleepers. remove ( self . sleeping )
509+ } ;
504510
505511 // If this ticker was notified, then notify another ticker.
506512 if notified {
507- drop ( sleepers) ;
508513 self . state . notify ( ) ;
509514 }
510515 }
@@ -543,32 +548,28 @@ fn debug_executor(
543548/// Debug implementation for `Executor` and `LocalExecutor`.
544549pub ( crate ) fn debug_state ( state : & State , name : & str , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
545550 /// Debug wrapper for the number of active tasks.
546- struct ActiveTasks < ' a > ( & ' a RefCell < Slab < Waker > > ) ;
551+ struct ActiveTasks < ' a > ( & ' a UnsafeCell < Slab < Waker > > ) ;
547552
548553 impl fmt:: Debug for ActiveTasks < ' _ > {
549554 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
550- match self . 0 . try_borrow ( ) {
551- Ok ( lock) => fmt:: Debug :: fmt ( & lock. len ( ) , f) ,
552- Err ( BorrowError { .. } ) => f. write_str ( "<blocked>" ) ,
553- }
555+ let active = unsafe { & * self . 0 . get ( ) } ;
556+ fmt:: Debug :: fmt ( & active. len ( ) , f)
554557 }
555558 }
556559
557560 /// Debug wrapper for the sleepers.
558- struct SleepCount < ' a > ( & ' a RefCell < Sleepers > ) ;
561+ struct SleepCount < ' a > ( & ' a UnsafeCell < Sleepers > ) ;
559562
560563 impl fmt:: Debug for SleepCount < ' _ > {
561564 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
562- match self . 0 . try_borrow ( ) {
563- Ok ( sleepers) => fmt:: Debug :: fmt ( & sleepers. count , f) ,
564- Err ( BorrowError { .. } ) => f. write_str ( "<blocked>" ) ,
565- }
565+ let sleepers = unsafe { & * self . 0 . get ( ) } ;
566+ fmt:: Debug :: fmt ( & sleepers. count , f)
566567 }
567568 }
568569
569570 f. debug_struct ( name)
570571 . field ( "active" , & ActiveTasks ( & state. active ) )
571- . field ( "global_tasks" , & state. queue . borrow ( ) . len ( ) )
572+ . field ( "global_tasks" , & unsafe { & * state. queue . get ( ) } . len ( ) )
572573 . field ( "sleepers" , & SleepCount ( & state. sleepers ) )
573574 . finish ( )
574575}
0 commit comments