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