Skip to content

Conversation

@Noah-Kennedy
Copy link
Contributor

@Noah-Kennedy Noah-Kennedy commented Dec 4, 2022

This opens up a lot of further cleanup opportunities, especially around shutdown logic. It also opens up the opportunity for us to eventually provide a public Handle API.

I am trying to make it so that we don't need to orchestrate our entire shutdown logic around the thread locals rather than purely the CONTEXT thread local, which is slightly broken to begin with (I believe that there are currently issues around creating two runtimes at the same time).

Now the CONTEXT behaves more like in tokio. When you enter a runtime context via block_on, we set the context. When we leave that call, we unset the context.

This also allows us to have a bit more flexibility with things like sending ops between multiple runtimes as well, so you can now in theory await ops created from another runtime.

Part of the goal of this is to add new options around things like fixed or provided buffers. This potentially allows us to work towards things like transferring buffers between uring runtimes.

More importantly however, it is a crucial first step towards having a handle to a uring runtime.

More refactoring to come.

@Noah-Kennedy
Copy link
Contributor Author

I still need to fix the tests.

@Noah-Kennedy
Copy link
Contributor Author

Might be a good idea to hide whitespace when reviewing.

.build()
},
)
CONTEXT.with(|x| {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For many of these op constructors, I plan to have the weak handle in the socket object.

self.inner.borrow_mut().uring.submit()
}

pub(crate) fn register_buffers(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm going to move a bunch of these methods into the Driver and do delegated calls here, but in another PR.

// only used in tests rn
#[allow(unused)]
fn num_operations(&self) -> usize {
pub(super) fn num_operations(&self) -> usize {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice if things like this were exposed to the tracing tool, tokio console.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this is a good idea to expose eventually.

This opens up a lot of further cleanup opportunities, especially around shutdown logic. It also opens up the opportunity for us to eventually provide a public Handle API.

More refactoring to come.
@Noah-Kennedy Noah-Kennedy marked this pull request as ready for review December 4, 2022 05:13
@Noah-Kennedy
Copy link
Contributor Author

I've fixed the tests and marked this and removed the draft label.

@Noah-Kennedy Noah-Kennedy requested a review from FrankReh December 4, 2022 05:32
@FrankReh
Copy link
Collaborator

FrankReh commented Dec 4, 2022

Not as part of this PR, but perhaps a quick follow-on. What would you think about moving the definitions from all the mod.rs files into their own files? So the mod files are just lines of use and mod themselves? Like most of runtime/mod.rs goes into runtime/runtime.rs and most of runtime/driver/mod.rs goes in runtime/driver/driver.rs and so on.

@FrankReh
Copy link
Collaborator

FrankReh commented Dec 4, 2022

Please remind me, why does the tokio_uring::spawn call tokio::task::spawn_local and not use the Runtime's local?

pub fn spawn<T: Future + 'static>(task: T) -> tokio::task::JoinHandle<T::Output> {
tokio::task::spawn_local(task)
}

@Noah-Kennedy
Copy link
Contributor Author

Not as part of this PR, but perhaps a quick follow-on. What would you think about moving the definitions from all the mod.rs files into their own files? So the mod files are just lines of use and mod themselves? Like most of runtime/mod.rs goes into runtime/runtime.rs and most of runtime/driver/mod.rs goes in runtime/driver/driver.rs and so on.

This is a really good idea.

@Noah-Kennedy
Copy link
Contributor Author

Please remind me, why does the tokio_uring::spawn call tokio::task::spawn_local and not use the Runtime's local?

pub fn spawn<T: Future + 'static>(task: T) -> tokio::task::JoinHandle<T::Output> {
tokio::task::spawn_local(task)
}

Because this spawn method is static and thus happens via the thread local context in tokio.

@FrankReh
Copy link
Collaborator

FrankReh commented Dec 4, 2022

Because this spawn method is static and thus happens via the thread local context in tokio.

But Tokio still adds it to this crate's runtime's localset because that localset is in some sense active, because it all happens in the context of calling rt.block_on(self.local.run_until(..))?

@Noah-Kennedy
Copy link
Contributor Author

Entering a LocalSet context (e.g run_until) sets thread locals within tokio to denote the "current" runtime, kinda like we now are with the drivers.

@Noah-Kennedy
Copy link
Contributor Author

Noah-Kennedy commented Dec 4, 2022

Regarding the goal of this PR, I am trying to make it so that we don't need to orchestrate our entire shutdown logic around the thread locals rather than purely the CONTEXT thread local, which is slightly broken to begin with (I believe that there are currently issues around creating two runtimes at the same time).

Now the CONTEXT behaves more like in tokio. When you enter a runtime context via block_on, we set the context. When we leave that call, we unset the context.

This also allows us to have a bit more flexibility with things like sending ops between multiple runtimes as well, so you can now await ops created from another runtime.

Part of the goal of this is to add new options around things like fixed or provided buffers. This potentially allows us to work towards things like transferring buffers between uring runtimes.

More importantly however, it is a crucial first step towards having a handle to a uring runtime.

@Noah-Kennedy Noah-Kennedy merged commit e1b2f1a into master Dec 4, 2022
@Noah-Kennedy Noah-Kennedy deleted the noah/handle branch December 4, 2022 17:59
Noah-Kennedy added a commit that referenced this pull request Dec 4, 2022
This cleans up a few different pieces and is a followup change from #196.
Noah-Kennedy added a commit that referenced this pull request Dec 6, 2022
This cleans up a few different pieces and is a followup change from
#196.
FrankReh pushed a commit that referenced this pull request Dec 10, 2022
#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`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants