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

Peeking at a port that is used after a sleep rarely terminates #9396

Closed
jdm opened this issue Sep 22, 2013 · 6 comments
Closed

Peeking at a port that is used after a sleep rarely terminates #9396

jdm opened this issue Sep 22, 2013 · 6 comments
Labels
A-concurrency Area: Concurrency related issues. A-runtime Area: std's runtime and "pre-main" init for handling backtraces, unwinds, stack overflows

Comments

@jdm
Copy link
Contributor

jdm commented Sep 22, 2013

use std::comm;
use std::rt::io::timer::Timer;

fn main() {
    let (port, chan) = comm::stream();
    do spawn {
        let mut timer = Timer::new().unwrap();
        timer.sleep(10);
        chan.send(());
    }
    loop {
        if port.peek() {
            break;
        }
    }
    port.recv();
}

This will often never leave the loop. If the timer is removed, it always succeeds instantly. If the peek is removed (so we block on receiving), it always succeeds once the sleep terminates.

@jdm
Copy link
Contributor Author

jdm commented Sep 22, 2013

In addition, if I add error! statements after the sleep call, I don't see any output when the program doesn't terminate. Whether that means that the output is buffered or the timer simply doesn't wake up, I don't know.

@brson
Copy link
Contributor

brson commented Sep 22, 2013

This is happening because peek never yields control to the scheduler, so the sleeping task is starved. It probably should work. I have an unmerged patch that makes task::deschedule work more correctly, a call to which thrown into the loop would make this work reliably.

@olsonjeffery
Copy link
Contributor

I can kinda sorta verify this on OSX mountain lion.

The provided code sample works, as is.. but if I increase the timeout to
over 100 msecs (to include 101), then it hangs..

based on my println!()-based debugging.. it seemed like it was hanging on
waking up from the sleep..

On Sat, Sep 21, 2013 at 5:16 PM, Josh Matthews notifications@github.comwrote:

use std::comm;use std::rt::io::timer::Timer;
fn main() {
let (port, chan) = comm::stream();
do spawn {
let mut timer = Timer::new().unwrap();
timer.sleep(10);
chan.send(());
}
loop {
if port.peek() {
break;
}
}
port.recv();}

This will often never leave the loop. If the timer is removed, it always
succeeds instantly. If the peek is removed (so we block on receiving), it
always succeeds once the sleep terminates.


Reply to this email directly or view it on GitHubhttps://github.com//issues/9396
.

@jdm
Copy link
Contributor Author

jdm commented Sep 22, 2013

Adding a deschedule call to both my sample and my original code did make it work consistently for me.

@alexcrichton
Copy link
Member

Closed by #10830, both sends and receives will yield now, and peek no longer exists.

@alexcrichton
Copy link
Member

On second though, I need to investigate this more to be sure.

@alexcrichton alexcrichton reopened this Dec 17, 2013
alexcrichton added a commit to alexcrichton/rust that referenced this issue Feb 3, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-concurrency Area: Concurrency related issues. A-runtime Area: std's runtime and "pre-main" init for handling backtraces, unwinds, stack overflows
Projects
None yet
Development

No branches or pull requests

4 participants