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

Forcing Send on a guard when using genawaiter #37

Open
fabianmurariu opened this issue Mar 8, 2023 · 0 comments
Open

Forcing Send on a guard when using genawaiter #37

fabianmurariu opened this issue Mar 8, 2023 · 0 comments

Comments

@fabianmurariu
Copy link

This is more of a question rather than an issue, we're using parking_lot with genawaiter to get an iterator without lifetime from a struct.

   use genawaiter::sync::{gen, GenBoxed};
   use genawaiter::yield_;

    struct Example<T>(Arc<parking_lot::RwLock<Vec<T>>>);

    impl<T: Clone> Example<T> {
        fn iter(&self) -> impl Iterator<Item = T> {
            let tgshard = self.0.clone();
            let iter: GenBoxed<T> = GenBoxed::new_boxed(|co| async move {
                let g = tgshard.read();
                let iter = (*g).iter();
                for t in iter {
                    co.yield_(t.clone()).await;
                }
            });

            iter.into_iter()
        }
    }

this is not allowed by the rust compiler because the guard is not Send.

However, is forcing the guard in this scenario (using genawaiter ) to be Send an actual problem?
I don't think the guard will be moved onto another thread. (that being said I have no clue how genawaiter works)

Basically is this workable?

   use genawaiter::sync::{gen, GenBoxed};
   use genawaiter::yield_;
   
    struct MyLock<T>(parking_lot::RwLock<T>);
    struct MyGuard<'a, T>(parking_lot::RwLockReadGuard<'a, T>);

    impl<T: Clone> MyLock<T> {
        fn read(&self) -> MyGuard<T> {
            MyGuard(self.0.read())
        }
    }

    impl<T> Deref for MyGuard<'_, T> {
        type Target = T;
        fn deref(&self) -> &Self::Target {
            self.0.deref()
        }
    }

    unsafe impl<T> Send for MyGuard<'_, T> {}

    struct Example2<T>(Arc<MyLock<Vec<T>>>);

    impl<T: Clone + std::marker::Send + std::marker::Sync + 'static> Example2<T> {
        fn iter(&self) -> impl Iterator<Item = T> {
            let tgshard = self.0.clone();
            let iter: GenBoxed<T> = GenBoxed::new_boxed(|co| async move {
                let g = tgshard.read();
                let iter = (*g).iter();
                for t in iter {
                    co.yield_(t.clone()).await;
                }
            });

            iter.into_iter()
        }
    }
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

No branches or pull requests

1 participant