Skip to content

Commit 3ba9bd8

Browse files
authored
Restore off-runtime creation of fixed buffer collections (tokio-rs#200)
tokio-rs#196 broke the ability to populate a collection of fixed buffers off-runtime and then have it registered inside a runtime. There is no need for the driver when a fixed buffer collection is populated. The driver comes in when registering and unregistering the buffers, and then as well, we don't currently need the collection to be affine to the driver. The driver always compares the pointer passed in to prevent unregistering the wrong buffers, so we can just grab the driver from the context. Change the doc examples to show and exercise off-runtime creation of `FixedBufPool` and `FixedBufRegistry`.
1 parent cdedbfc commit 3ba9bd8

File tree

3 files changed

+37
-31
lines changed

3 files changed

+37
-31
lines changed

src/buf/fixed/pool.rs

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use super::handle::CheckedOutBuf;
22
use super::{FixedBuf, FixedBuffers};
33

4-
use crate::runtime::driver::WeakHandle;
54
use crate::runtime::CONTEXT;
65
use libc::{iovec, UIO_MAXIOV};
76
use std::cell::RefCell;
@@ -84,7 +83,6 @@ use std::slice;
8483
#[derive(Clone)]
8584
pub struct FixedBufPool {
8685
inner: Rc<RefCell<Inner>>,
87-
driver: WeakHandle,
8886
}
8987

9088
impl FixedBufPool {
@@ -116,10 +114,11 @@ impl FixedBufPool {
116114
/// # let (memlock_limit, _) = getrlimit(Resource::RLIMIT_MEMLOCK)?;
117115
/// # let NUM_BUFFERS = std::cmp::max(memlock_limit as usize / 4096 / 8, 1);
118116
/// # let BUF_SIZE = 4096;
117+
/// let pool = FixedBufPool::new(
118+
/// iter::repeat(Vec::with_capacity(BUF_SIZE)).take(NUM_BUFFERS)
119+
/// );
120+
///
119121
/// tokio_uring::start(async {
120-
/// let pool = FixedBufPool::new(
121-
/// iter::repeat(Vec::with_capacity(BUF_SIZE)).take(NUM_BUFFERS)
122-
/// );
123122
/// pool.register()?;
124123
/// // ...
125124
/// Ok(())
@@ -139,10 +138,11 @@ impl FixedBufPool {
139138
/// # let (memlock_limit, _) = getrlimit(Resource::RLIMIT_MEMLOCK)?;
140139
/// # let NUM_BUFFERS = std::cmp::max(memlock_limit as usize / 4096 / 8, 1);
141140
/// # let BUF_SIZE = 4096;
141+
/// let pool = FixedBufPool::new(
142+
/// iter::repeat_with(|| Vec::with_capacity(BUF_SIZE)).take(NUM_BUFFERS)
143+
/// );
144+
///
142145
/// tokio_uring::start(async {
143-
/// let pool = FixedBufPool::new(
144-
/// iter::repeat_with(|| Vec::with_capacity(BUF_SIZE)).take(NUM_BUFFERS)
145-
/// );
146146
/// pool.register()?;
147147
/// // ...
148148
/// Ok(())
@@ -152,7 +152,6 @@ impl FixedBufPool {
152152
pub fn new(bufs: impl IntoIterator<Item = Vec<u8>>) -> Self {
153153
FixedBufPool {
154154
inner: Rc::new(RefCell::new(Inner::new(bufs.into_iter()))),
155-
driver: CONTEXT.with(|x| x.weak().expect("Not in a runtime context")),
156155
}
157156
}
158157

@@ -176,10 +175,12 @@ impl FixedBufPool {
176175
/// of the `tokio-uring` runtime this call is made in, the function returns
177176
/// an error.
178177
pub fn register(&self) -> io::Result<()> {
179-
self.driver
180-
.upgrade()
181-
.expect("Runtime context is no longer present")
182-
.register_buffers(Rc::clone(&self.inner) as _)
178+
CONTEXT.with(|x| {
179+
x.handle()
180+
.as_ref()
181+
.expect("Not in a runtime context")
182+
.register_buffers(Rc::clone(&self.inner) as _)
183+
})
183184
}
184185

185186
/// Unregisters this collection of buffers.
@@ -198,10 +199,12 @@ impl FixedBufPool {
198199
/// an error. Calling `unregister` when no `FixedBufPool` is currently
199200
/// registered on this runtime also returns an error.
200201
pub fn unregister(&self) -> io::Result<()> {
201-
self.driver
202-
.upgrade()
203-
.expect("Runtime context is no longer present")
204-
.unregister_buffers(Rc::clone(&self.inner) as _)
202+
CONTEXT.with(|x| {
203+
x.handle()
204+
.as_ref()
205+
.expect("Not in a runtime context")
206+
.unregister_buffers(Rc::clone(&self.inner) as _)
207+
})
205208
}
206209

207210
/// Returns a buffer of requested capacity from this pool

src/buf/fixed/registry.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use super::handle::CheckedOutBuf;
22
use super::{FixedBuf, FixedBuffers};
33

4-
use crate::runtime::driver::WeakHandle;
54
use crate::runtime::CONTEXT;
65
use libc::{iovec, UIO_MAXIOV};
76
use std::cell::RefCell;
@@ -37,7 +36,6 @@ use std::slice;
3736
#[derive(Clone)]
3837
pub struct FixedBufRegistry {
3938
inner: Rc<RefCell<Inner>>,
40-
driver: WeakHandle,
4139
}
4240

4341
impl FixedBufRegistry {
@@ -93,10 +91,11 @@ impl FixedBufRegistry {
9391
/// # let (memlock_limit, _) = getrlimit(Resource::RLIMIT_MEMLOCK)?;
9492
/// # let NUM_BUFFERS = std::cmp::max(memlock_limit as usize / 4096 / 8, 1);
9593
/// # let BUF_SIZE = 4096;
94+
/// let registry = FixedBufRegistry::new(
95+
/// iter::repeat_with(|| Vec::with_capacity(BUF_SIZE)).take(NUM_BUFFERS)
96+
/// );
97+
///
9698
/// tokio_uring::start(async {
97-
/// let registry = FixedBufRegistry::new(
98-
/// iter::repeat_with(|| Vec::with_capacity(BUF_SIZE)).take(NUM_BUFFERS)
99-
/// );
10099
/// registry.register()?;
101100
/// // ...
102101
/// Ok(())
@@ -106,7 +105,6 @@ impl FixedBufRegistry {
106105
pub fn new(bufs: impl IntoIterator<Item = Vec<u8>>) -> Self {
107106
FixedBufRegistry {
108107
inner: Rc::new(RefCell::new(Inner::new(bufs.into_iter()))),
109-
driver: CONTEXT.with(|x| x.weak().expect("Not in a runtime context")),
110108
}
111109
}
112110

@@ -130,10 +128,12 @@ impl FixedBufRegistry {
130128
/// of the `tokio-uring` runtime this call is made in, the function returns
131129
/// an error.
132130
pub fn register(&self) -> io::Result<()> {
133-
self.driver
134-
.upgrade()
135-
.expect("Runtime context is no longer present")
136-
.register_buffers(Rc::clone(&self.inner) as _)
131+
CONTEXT.with(|x| {
132+
x.handle()
133+
.as_ref()
134+
.expect("Not in a runtime context")
135+
.register_buffers(Rc::clone(&self.inner) as _)
136+
})
137137
}
138138

139139
/// Unregisters this collection of buffers.
@@ -152,10 +152,12 @@ impl FixedBufRegistry {
152152
/// an error. Calling `unregister` when no `FixedBufRegistry` is currently
153153
/// registered on this runtime also returns an error.
154154
pub fn unregister(&self) -> io::Result<()> {
155-
self.driver
156-
.upgrade()
157-
.expect("Runtime context is no longer present")
158-
.unregister_buffers(Rc::clone(&self.inner) as _)
155+
CONTEXT.with(|x| {
156+
x.handle()
157+
.as_ref()
158+
.expect("Not in a runtime context")
159+
.unregister_buffers(Rc::clone(&self.inner) as _)
160+
})
159161
}
160162

161163
/// Returns a buffer identified by the specified index for use by the

src/runtime/context.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ impl RuntimeContext {
4444
self.driver.borrow().clone()
4545
}
4646

47+
#[allow(dead_code)]
4748
pub(crate) fn weak(&self) -> Option<WeakHandle> {
4849
self.driver.borrow().as_ref().map(Into::into)
4950
}

0 commit comments

Comments
 (0)