@@ -2,6 +2,7 @@ use crate::driver::Driver;
22
33use std:: future:: Future ;
44use std:: io;
5+ use std:: mem:: ManuallyDrop ;
56use std:: os:: unix:: io:: { AsRawFd , RawFd } ;
67use tokio:: io:: unix:: AsyncFd ;
78use tokio:: task:: LocalSet ;
@@ -20,19 +21,10 @@ pub struct Runtime {
2021 uring_fd : RawFd ,
2122
2223 /// LocalSet for !Send tasks
23- local : LocalSet ,
24+ local : ManuallyDrop < LocalSet > ,
2425
2526 /// Tokio runtime, always current-thread
26- rt : tokio:: runtime:: Runtime ,
27-
28- /// This is here for drop order reasons.
29- ///
30- /// We can't unset the driver in the runtime drop method, because the inner runtime needs to
31- /// be dropped first so that there are no tasks running.
32- ///
33- /// The rust drop order rules guarantee that the inner runtime will be dropped first, and
34- /// this last.
35- _driver_guard : RuntimeContextGuard ,
27+ rt : ManuallyDrop < tokio:: runtime:: Runtime > ,
3628}
3729
3830/// Spawns a new asynchronous task, returning a [`JoinHandle`] for it.
@@ -77,7 +69,9 @@ impl Runtime {
7769 . enable_all ( )
7870 . build ( ) ?;
7971
80- let local = LocalSet :: new ( ) ;
72+ let rt = ManuallyDrop :: new ( rt) ;
73+
74+ let local = ManuallyDrop :: new ( LocalSet :: new ( ) ) ;
8175
8276 let driver = Driver :: new ( b) ?;
8377
@@ -89,7 +83,6 @@ impl Runtime {
8983 uring_fd : driver_fd,
9084 local,
9185 rt,
92- _driver_guard : RuntimeContextGuard ,
9386 } )
9487 }
9588
@@ -124,10 +117,16 @@ impl Runtime {
124117 }
125118}
126119
127- struct RuntimeContextGuard ;
128-
129- impl Drop for RuntimeContextGuard {
120+ impl Drop for Runtime {
130121 fn drop ( & mut self ) {
122+ // drop tasks
123+ unsafe {
124+ ManuallyDrop :: drop ( & mut self . local ) ;
125+ ManuallyDrop :: drop ( & mut self . rt ) ;
126+ }
127+
128+ // once tasks are dropped, we can unset the driver
129+ // this will block until all completions are received
131130 CONTEXT . with ( |rc| rc. unset_driver ( ) )
132131 }
133132}
0 commit comments