Skip to content

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

Closed

Description

@jdm
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.

Activity

  1. jdm commented on Sep 22, 2013

    @jdm
    ContributorAuthor

    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.

  2. brson commented on Sep 22, 2013

    @brson
    Contributor

    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.

  3. olsonjeffery commented on Sep 22, 2013

    @olsonjeffery
    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.life-white.ukwrote:

    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
    .

  4. jdm commented on Sep 22, 2013

    @jdm
    ContributorAuthor

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

  5. alexcrichton commented on Dec 17, 2013

    @alexcrichton
    Member

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

  6. alexcrichton commented on Dec 17, 2013

    @alexcrichton
    Member

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-concurrencyArea: ConcurrencyA-runtimeArea: std's runtime and "pre-main" init for handling backtraces, unwinds, stack overflows

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions