Skip to content

Conversation

@kobi2187
Copy link
Contributor

The channel implementation had unsafe unsynchronized access to the mask field across threads:

  1. tryRecv() checked q.mask != ChannelDeadMask BEFORE acquiring the lock
  2. sendImpl() checked q.mask == ChannelDeadMask BEFORE acquiring the lock
  3. rawSend() modified q.mask WHILE HOLDING the lock

This created a race condition detected by ThreadSanitizer where one thread reads the mask while another thread modifies it under lock protection.

The fix moves both mask checks inside their respective critical sections:

  • tryRecv: Now acquires lock first, then checks mask
  • sendImpl: Now acquires lock first, then checks mask (releasing before fatal)

This ensures all accesses to the shared mask field are properly synchronized.

Fixes #23174

The channel implementation had unsafe unsynchronized access to the `mask`
field across threads:

1. tryRecv() checked `q.mask != ChannelDeadMask` BEFORE acquiring the lock
2. sendImpl() checked `q.mask == ChannelDeadMask` BEFORE acquiring the lock
3. rawSend() modified `q.mask` WHILE HOLDING the lock

This created a race condition detected by ThreadSanitizer where one thread
reads the mask while another thread modifies it under lock protection.

The fix moves both mask checks inside their respective critical sections:
- tryRecv: Now acquires lock first, then checks mask
- sendImpl: Now acquires lock first, then checks mask (releasing before fatal)

This ensures all accesses to the shared `mask` field are properly synchronized.

Fixes nim-lang#23174
@Araq
Copy link
Member

Araq commented Dec 17, 2025

But the idea was that a Dead channel also has no lock in a valid state. These reads must use atomics, not the lock. Use a better AI model.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Channel.trySend/tryRecv contains a data-race according to thread-sanitizer

3 participants