Skip to content

ch20 multi-threaded example does not work #3435

@horriblename

Description

@horriblename
  • I have searched open and closed issues and pull requests for duplicates, using these search terms:
    • ch20
    • multi thread
  • I have checked the latest main branch to see if this has already been fixed, in this file:
    • ch20-02-multithreaded.md

URL to the section(s) of the book with this problem:
https://doc.rust-lang.org/book/ch20-02-multithreaded.html#creating-a-finite-number-of-threads

Description of the problem:
The multi-threaded server example does not work, from my testing it seems that the problem lies in TcpListener::incoming, it seems that incoming blocks until the previous stream is dropped. A snippet to demonstrate the issue:

fn main() {
    let listener = TcpListener::bind("127.0.0.1:7878").unwrap();
    let pool = ThreadPool::new(4);

    for stream in listener.incoming() {
        // ^^^ incoming() blocks until the previous instance of
        // stream is dropped
        let stream = stream.unwrap();

        pool.execute(|| {
            handle_connection(stream);
        });
    }
}

fn handle_connection(mut stream: TcpStream) {
    // ...
    let (status_line, filename) = match &request_line[..] {
        "GET /sleep HTTP/1.1" => {
            thread::sleep(Duration::from_secs(5));

            // to kinda prove dropping stream would unblock `incoming` in main
            drop(stream);
            thread::sleep(Duration::from_secs(5));
            return;
        }
    };

    // ...
}

Suggested fix:

I don't know

I've looked in the docs for TcpListener::incoming and TcpListener::accept (which is used by incoming), but there is no mentioned that it would block until the previous stream is dropped, so I am at a lost as to how to solve this issue. I am not experienced in TCP nor rust, I hope someone who has better insight can give their thoughts.

In case it matters: tested on linux 6.0.9 with rustc version 1.65.0 (897e37553 2022-11-02)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions