rollup merge of #23087: nagisa/std-undeadlock

Being a person who somehow has taken a liking to premature optimisation, my knee-jerk reaction to
locking in std handles was preamble resembling following snippet:

    let stdout = stdout();
    let lstdout = stdout.lock();
    let stdin = stdin();
    let lstdin = stdin.lock();

and then reading from the locked handle like this:

    let mut letter = [0; 1];
    lstdin.read(&mut letter).unwrap();

As it is now this code will deadlock because the `read` method attempts to lock stdout as well!

r? @alexcrichton

---

Either way, I find flushing stdout when stdin is used debatable. I believe people who write prompts should take care to flush stdout when necessary themselves.

Another idea: Would be cool if locks on std handles would be taken for a thread, rather than a handle, so given preamble (first code snippet)

    stdin.lock()

or more generally

    stdin.read(…)

worked fine. I.e. if more than a single lock are all taken inside the same thread, it would work, though not sure if our synchronisation primitives are expressive enough to make it possible.
This commit is contained in:
Alex Crichton 2015-03-06 15:37:47 -08:00
commit 697de42f69

View File

@ -157,9 +157,6 @@ impl Read for Stdin {
impl<'a> Read for StdinLock<'a> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
// Flush stdout so that weird issues like a print!'d prompt not being
// shown until after the user hits enter.
drop(stdout().flush());
self.inner.read(buf)
}
}