Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

async map functions for tokio::sync::RwLock #4305

Open
agraven opened this issue Dec 7, 2021 · 1 comment
Open

async map functions for tokio::sync::RwLock #4305

agraven opened this issue Dec 7, 2021 · 1 comment
Labels
A-tokio Area: The main tokio crate C-feature-request Category: A feature request. M-sync Module: tokio/sync

Comments

@agraven
Copy link

agraven commented Dec 7, 2021

Is your feature request related to a problem? Please describe.
It's currently not possible to use async code in tokio::sync::RwLock(Read|Write)Guard::map.

Describe the solution you'd like
Additional .map methods that accept mapping closures that return a future, looking something like

    pub async fn map_async<F, Fut, U: ?Sized>(this: Self, f: F) -> RwLockReadGuard<'a, U>
    where
        F: FnOnce(&T) -> Fut,
        Fut: Future<Output = &U>,
    {
        let data = f(&*this).await as *const U;
        let s = this.s;
        // NB: Forget to avoid drop impl from being called.
        mem::forget(this);
        RwLockReadGuard {
            s,
            data,
            marker: marker::PhantomData,
        }
    }

Describe alternatives you've considered
The owning variants of the guards could be used to solve my particular case, but doing so introduces significant complexity to reasoning about the code, since it means that inner locks can outlive outer locks.

Additional context
I'm trying to solve a problem similar to the one described in this reddit thread, where I have an outer RwLock to an object containing a Vec of inner RwLocks, and I need make a function that returns an object that derefs to data inside one of the inner locks without causing lifetime problems. The Ideal approach in my mind would be to solve the problem with RwLock(Read|Write)Guard::map, but that doesn't work because I need to use async code inside the map invocation. To describe it in pseudocode, I'm trying to do something like

RwLockReadGuard::try_map(self.outer.read.await(), |outer| {
    RwLockReadGuard::try_map(outer.inner.read().await, |inner| inner.returns_option())
}

In other words, I need a a way to get a RwLockReadGuard<RwLockReadGuard<U>>

@agraven agraven added A-tokio Area: The main tokio crate C-feature-request Category: A feature request. labels Dec 7, 2021
@Darksonn Darksonn added the M-sync Module: tokio/sync label Dec 7, 2021
@Darksonn
Copy link
Contributor

Darksonn commented Dec 7, 2021

Although this could be useful, it wont help with your use-case. You have to return a reference from the closure, and RwLockReadGuard<U> is not a reference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tokio Area: The main tokio crate C-feature-request Category: A feature request. M-sync Module: tokio/sync
Projects
None yet
Development

No branches or pull requests

2 participants