fix: use slot instead of trigger for async recv#172
Conversation
Use Hook::slot for async receivers to properly support rendezvous channels (bounded(0)). This fixes deadlock when sending non-ZST types. Closes zesterer#140.
|
This looks suspiciously like it was generated by an LLM. Before I spend time reviewing this, could you confirm that you have personally checked its reasoning thoroughly by hand? I would much rather a human-authored description. |
Sorry, I did indeed make use of Claude. The situation I encountered is exactly as shown in the example I described. I actually discovered this issue while testing performance: flume can deadlock, but this only happens in the latest version; the issue does not occur in 0.11.0. I did a preliminary review and confirmed the change, but my understanding of flume may be incomplete. It might still be necessary to trouble you to review the change from a broader, system-wide perspective to see whether it is correct. |
Fix async rendezvous channel deadlock (Issue #140)
Problem
Async receivers use
Hook::triggerwhich has no slot to store messages. When a sender finds a waiting async receiver on a rendezvous channel (bounded(0)), it:fire_send()which returns(Some(msg), signal)because trigger has no slotchan.queueOk(())immediatelyThis violates rendezvous semantics where the sender should block until the receiver actually takes the message. The premature return causes race conditions and deadlocks in high-throughput scenarios.
Root Cause
In
src/async.rs,RecvFut::poll_innercreates a trigger hook:Hook::triggerhas no slot (self.0 = None), so whenfire_sendis called:The message is returned back and placed in the queue instead of being delivered directly to the receiver.
Fix
Change async receivers to use
Hook::slotinstead ofHook::trigger:And check the slot first when polling:
Reproduction
Testing
flume-asyncruns to completionNotes
SendFut::pollshould returnPoll::Pendingfor rendezvous channels when no item is queued #140