-
Notifications
You must be signed in to change notification settings - Fork 24
Rework ScopedCoroutine by using a scope in addition to Pin
#60
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
Conversation
|
use std::{mem, sync::mpsc};
use corosensei::ScopedCoroutine;
fn main() {
ScopedCoroutine::new(
|_, ()| (),
|outer_coroutine| {
let mut s = "Happy".to_owned();
let (tx1, rx1) = mpsc::sync_channel(1);
let (tx2, rx2) = mpsc::sync_channel(1);
{
let s = s.as_str();
ScopedCoroutine::new(
|yielder, ()| {
std::thread::scope(move |scope| {
let _thrd = scope.spawn(move || {
rx1.recv().unwrap();
tx2.send(s.to_owned()).unwrap();
});
let () = yielder.suspend(());
});
},
|mut coroutine| {
coroutine.as_mut().resume(());
mem::swap(coroutine.get_mut(), outer_coroutine.get_mut());
},
);
}
s.clear();
s.push_str("Sad");
tx1.send(()).unwrap();
let data_race_s = rx2.recv().unwrap();
dbg!(&s, &data_race_s);
},
);
}Prints out: |
|
Added |
|
This variant is not as flexible as my suggestion for But you have effectively almost recreated I don't think this is unsound. |
|
LGTM i guess |
|
The problem with a I do think that the API is quite ugly to use though, I'll try and see if it can be improved. |
|
You know, this looks like |
|
I reworked the API to separate creating the coroutine from executing it in a scope: use corosensei::ScopedCoroutine;
let mut counter = 0;
let coroutine = ScopedCoroutine::new(|yielder, input| {
if input == 0 {
return;
}
counter += input;
loop {
let input = yielder.suspend(());
if input == 0 {
break;
}
counter += input;
}
});
coroutine.scope(|mut coroutine| {
coroutine.as_mut().resume(1);
coroutine.as_mut().resume(2);
coroutine.as_mut().resume(3);
coroutine.as_mut().resume(4);
coroutine.as_mut().resume(5);
});
assert_eq!(counter, 15); |
|
Lifetime of closure use std::sync::mpsc;
use corosensei::ScopedCoroutine;
fn main() {
let mut s = "Happy".to_owned();
let (tx1, rx1) = mpsc::sync_channel(1);
let (tx2, rx2) = mpsc::sync_channel(1);
{
let s1 = s.as_str();
let coroutine = ScopedCoroutine::new(|yielder, ()| {
std::thread::scope(move |scope| {
let _thrd = scope.spawn(move || {
rx1.recv().unwrap();
tx2.send(s1.to_owned()).unwrap();
});
let () = yielder.suspend(());
});
});
coroutine.scope(|mut coroutine| {
coroutine.resume(());
s.clear();
s.push_str("Sad");
tx1.send(()).unwrap();
let data_race_s = rx2.recv().unwrap();
dbg!(&s, &data_race_s);
});
}
}Prints out: |
|
Should hopefully be fixed now. |
Fixes #59