-
Notifications
You must be signed in to change notification settings - Fork 341
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
Locking for stdin #229
Comments
I want to try this implementation! |
@k-nasa yay, thanks for volunteering! So there are two important things to be aware of here: // definition in async-std, `State` holds a reference to std's Stdin
pub struct Stdin(Mutex<State>); We want to have an The way I'd approach this by making our method acquire outer async lock, then call Hope this provides a good starting point; let me know if you need any more pointers! |
To add a little bit to that, since Moreover, the returned lazy_static! {
static ref STDIN: Stdin = std::io::stdin();
} A locking function might then look like this: use crate::task::blocking;
async fn lock() -> StdinLock<'static> {
blocking::spawn(async move { STDIN.lock() }).await
} |
@yoshuawuyts @stjepang Thx!! I try it. |
ref #131 |
Apparently, StdinLock does not implement the Send trait. So it doesn't seem to work with blocking :: spawn.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct StdinLock<'a> {
inner: MutexGuard<'a, BufReader<Maybe<StdinRaw>>>,
}
#[must_use = "if unused the Mutex will immediately unlock"]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct MutexGuard<'a, T: ?Sized + 'a> {
// funny underscores due to how Deref/DerefMut currently work (they
// disregard field privacy).
__lock: &'a Mutex<T>,
__poison: poison::Guard,
} What problems can be considered when locking is returned without blocking? pub async fn lock(&self) -> std::io::StdinLock<'static> {
STDIN.lock()
} |
ping @stjepang @yoshuawuyts |
@k-nasa I've been thinking about this and don't really have any good suggestions; sorry. This almost feels like something that should be solved in stdlib to ensure the internal lock is always acquired even through multiple interfaces. In lieu of that I think perhaps doing a blocking call directly inside the async block is fine for now. It's not ideal, but it provides the right interface. We already have work stealing which means that even if a current thread blocks, other threads will pick up work. Which in turn means that the effects of blocking tasks will be mitigated as we continue to improve our executor. edit though the guard here may make the current task non-send which is also not great. Having a It almost feels like perhaps we should have a global somewhere that we can instrument to take out the lock, and then write to it from other methods. And then once it's done close the lock again. |
I believe it should be just fine to use unsafe code to send |
@jonathandturner now that #334 is merged, the next release should work for your use case as part of the Apologies it took a few weeks to resolve, but the biggest hurdle has been overcome now! |
Close because #334 has been merged |
In sync std, you can lock stdin to ensure you maintain control of it. Something like:
Currently, there isn't a way to do the equivalent in async-std.
cc @yoshuawuyts
The text was updated successfully, but these errors were encountered: