Skip to content

A potential mpsc::channel bug #48927

Closed
Closed
@UncP

Description

@UncP

rustc 1.25.0-nightly (73ac5d6a8 2018-01-11)

use std::thread;
use std::sync::mpsc;
use std::time::Duration;

fn main() {
	let (tx, rx) = mpsc::channel::<u32>();

	let r_handle = thread::spawn(move || {
		match rx.recv_timeout(Duration::from_secs(10)){
			Err(mpsc::RecvTimeoutError::Timeout) => {}
			_ => assert!(false),
		}
                 // next line panics every time.
		rx.recv_timeout(Duration::from_secs(10)).unwrap();
	});

	let t_handle = thread::spawn(move || {
		thread::sleep(Duration::from_secs(2));
		let _ = tx.clone();
		thread::sleep(Duration::from_secs(10));
	});

	r_handle.join().unwrap();
	t_handle.join().unwrap();
}
  1. receiver calls recv_timeout
  2. sender clone itself
  3. recv_timeout returns timeout
  4. receiver calls recv_timeout the second time
  5. boom!

2018-03-11 1 58 49

This is what I know, when sender calls clone, it will call inherit_blocker, and then change to_wake in it. The first recv_timeout returns timeout, when the second recv_timeout is called, it will panic in decrement in shared.rs because it needs to check that to_wake equals 0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions