Skip to content

Commit cecf23b

Browse files
committed
webrtc: Remove test timeout and add atomic state issue doc
1 parent d537573 commit cecf23b

File tree

2 files changed

+70
-5
lines changed

2 files changed

+70
-5
lines changed

ATOMIC_STATE_ISSUE.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Replace Mutex<State> with lock-free AtomicU8 and consolidate wakers for WebRTC substream
2+
3+
## Summary
4+
5+
Replace the current `Arc<Mutex<State>>` with a lock-free `AtomicU8` for managing WebRTC substream state, as suggested in PR #513.
6+
7+
This change also proposes merging the two separate wakers (`shutdown_waker` and `write_waker`) into a single `state_waker`. Before implementing, we need to verify this waker consolidation is safe and won't cause issues like infinite poll loops or unacceptable spurious wakeups.
8+
9+
## Current Implementation
10+
11+
```rust
12+
state: Arc<Mutex<State>>,
13+
```
14+
15+
With separate wakers:
16+
- `shutdown_waker: Arc<AtomicWaker>` - notifies when FIN_ACK received
17+
- `write_waker: Arc<AtomicWaker>` - notifies when STOP_SENDING/RESET_STREAM received
18+
19+
## Proposed Implementation
20+
21+
```rust
22+
struct SharedState {
23+
// lock-free / more efficient
24+
// BITS 0 to 3
25+
// 0: open 1: sendClosed 2: closing 3: FinSent (our states) 4: FinAck
26+
27+
// BIT 4: remote recv closed via FIN recv
28+
// BIT 5: STOP_SENDING remote send closed
29+
state: AtomicU8,
30+
31+
// Waker for tasks waiting on state changes (ie poll write blocked on state, but poll shutdown has
32+
state_waker: AtomicWaker,
33+
}
34+
```
35+
36+
## Investigation Required
37+
38+
Before implementing, we need to verify that we can **merge all wakers into a single `state_waker`**:
39+
40+
1. **`shutdown_waker`** - currently woken when:
41+
- FIN_ACK received (`on_message``State::FinAcked`)
42+
- Registered in `poll_shutdown` when waiting for FIN_ACK
43+
44+
2. **`write_waker`** - currently woken when:
45+
- STOP_SENDING received (`on_message``State::SendClosed`)
46+
- RESET_STREAM received (`on_message``State::SendClosed`)
47+
- Registered in `poll_write` when blocked due to backpressure
48+
49+
The key question: Can we safely wake a single `state_waker` on any state transition without causing spurious wakeups that degrade performance?
50+
51+
Since `Substream` is owned and polled by exactly one task, merging should be safe - the same task handles both `poll_write` and `poll_shutdown`. However, we should verify:
52+
- No scenario where waking causes infinite poll loops
53+
- Performance impact of spurious wakeups is acceptable (state transitions are rare)
54+
55+
## Benefits
56+
57+
- Lock-free state access (no mutex contention)
58+
- More efficient for concurrent access patterns
59+
- Reduced memory overhead (single AtomicU8 vs Mutex)
60+
61+
## Trade-offs
62+
63+
- Slightly more complex bit manipulation
64+
- May need careful ordering semantics (SeqCst vs Relaxed)
65+
- Single waker approach requires validation
66+
67+
## Reference
68+
69+
- PR #513: https://github.com/paritytech/litep2p/pull/513
70+
- Comment from @lexnv suggesting the change

src/transport/webrtc/substream.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,8 @@ const MAX_FRAME_SIZE: usize = 16384;
4141

4242
/// Timeout for waiting on FIN_ACK after sending FIN.
4343
/// Matches go-libp2p's 5 second stream close timeout.
44-
#[cfg(not(test))]
4544
const FIN_ACK_TIMEOUT: Duration = Duration::from_secs(5);
4645

47-
/// Shorter timeout for tests.
48-
#[cfg(test)]
49-
const FIN_ACK_TIMEOUT: Duration = Duration::from_secs(2);
50-
5146
/// Substream event.
5247
#[derive(Debug, PartialEq, Eq)]
5348
pub enum Event {

0 commit comments

Comments
 (0)