libp2p / libp2p/rust-yamux

Yamux deadlock when splitting stream

Open
#232 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
250
Forks
62
PR merge metrics
No merged PRs in 30d

Description

https://github.com/stormshield-pj50/yamux_race is a small example that reproduces a deadlock in Yamux when a stream is split.

The program launches a server and a client. The client establishes a TCP connection to the server and opens a single Yamux stream. Both the server and the client then split that stream into a read half and a write half, and each side spawns two asynchronous tasks: one that continuously writes to the stream and another that continuously reads from it.

After the writer has performed ten writes, the deadlock occurs. The issue appears to arise when the internal MPSC sender on the Yamux stream becomes full. At that point the writer task is never woken up again because the reader registers another waker when it sends a WindowUpdate frame on the MPSC channel. The Yamux internal MPSC sender is shared by both the reader and the writer tasks. The MPSC implementation of the future crate wakes up only the last waker. So the writer task waker is definitely lost.

The deadlock pattern is reproduced by this simple example: https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=5fb34c6f773d51b0fd12bba6a2b5d798

Tokio references this issue : https://github.com/tokio-rs/tls/issues/40

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the linked yamux_race example and Rust Playground reproducer, then trace the split stream's reader and writer tasks through the shared internal MPSC sender. Confirm the deadlock after ten writes and verify that the reproducer completes without hanging when both halves continue reading and writing.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.