Skip to content

Commit c069cc6

Browse files
authored
rt: refactor runtime to avoid Rc<RefCell<...>> (tokio-rs#142)
This change refactors the runtime to not use reference counting directly in the ops themselves. Instead, ops access the driver via thread local variables. This is sound because dropping the driver (which happens when it is removed from its thread-local state) blocks the thread until all ops complete, ensuring that we do not free the contents of the driver until after all operations have completed.
1 parent cb189fa commit c069cc6

File tree

6 files changed

+255
-172
lines changed

6 files changed

+255
-172
lines changed

src/driver/mod.rs

Lines changed: 6 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,11 @@ mod write;
4040
mod writev;
4141

4242
use io_uring::IoUring;
43-
use scoped_tls::scoped_thread_local;
4443
use slab::Slab;
45-
use std::cell::RefCell;
4644
use std::io;
4745
use std::os::unix::io::{AsRawFd, RawFd};
48-
use std::rc::Rc;
4946

5047
pub(crate) struct Driver {
51-
inner: Handle,
52-
}
53-
54-
type Handle = Rc<RefCell<Inner>>;
55-
56-
pub(crate) struct Inner {
5748
/// In-flight operations
5849
ops: Ops,
5950

@@ -67,45 +58,25 @@ struct Ops {
6758
lifecycle: Slab<op::Lifecycle>,
6859
}
6960

70-
scoped_thread_local!(pub(crate) static CURRENT: Rc<RefCell<Inner>>);
71-
7261
impl Driver {
7362
pub(crate) fn new(b: &crate::Builder) -> io::Result<Driver> {
7463
let uring = b.urb.build(b.entries)?;
7564

76-
let inner = Rc::new(RefCell::new(Inner {
65+
Ok(Driver {
7766
ops: Ops::new(),
7867
uring,
79-
}));
80-
81-
Ok(Driver { inner })
82-
}
83-
84-
/// Enter the driver context. This enables using uring types.
85-
pub(crate) fn with<R>(&self, f: impl FnOnce() -> R) -> R {
86-
CURRENT.set(&self.inner, f)
87-
}
88-
89-
pub(crate) fn tick(&self) {
90-
let mut inner = self.inner.borrow_mut();
91-
inner.tick();
68+
})
9269
}
9370

9471
fn wait(&self) -> io::Result<usize> {
95-
let mut inner = self.inner.borrow_mut();
96-
let inner = &mut *inner;
97-
98-
inner.uring.submit_and_wait(1)
72+
self.uring.submit_and_wait(1)
9973
}
10074

10175
fn num_operations(&self) -> usize {
102-
let inner = self.inner.borrow();
103-
inner.ops.lifecycle.len()
76+
self.ops.lifecycle.len()
10477
}
105-
}
10678

107-
impl Inner {
108-
fn tick(&mut self) {
79+
pub(crate) fn tick(&mut self) {
10980
let mut cq = self.uring.completion();
11081
cq.sync();
11182

@@ -143,7 +114,7 @@ impl Inner {
143114

144115
impl AsRawFd for Driver {
145116
fn as_raw_fd(&self) -> RawFd {
146-
self.inner.borrow().uring.as_raw_fd()
117+
self.uring.as_raw_fd()
147118
}
148119
}
149120

0 commit comments

Comments
 (0)