Skip to content

Commit 31eb00c

Browse files
committed
sync: Ensure try_send() wakes up receivers
This branch of try_send() just forgot to wake up any receiver waiting for data. Closes #15761
1 parent e288fc6 commit 31eb00c

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

src/libsync/comm/mod.rs

+19
Original file line numberDiff line numberDiff line change
@@ -2098,4 +2098,23 @@ mod sync_tests {
20982098
});
20992099
assert_eq!(rx.recv(), 1);
21002100
} #[ignore(reason = "flaky on libnative")])
2101+
2102+
test!(fn issue_15761() {
2103+
fn repro() {
2104+
let (tx1, rx1) = sync_channel::<()>(3);
2105+
let (tx2, rx2) = sync_channel::<()>(3);
2106+
2107+
spawn(proc() {
2108+
rx1.recv();
2109+
tx2.try_send(()).unwrap();
2110+
});
2111+
2112+
tx1.try_send(()).unwrap();
2113+
rx2.recv();
2114+
}
2115+
2116+
for _ in range(0u, 100) {
2117+
repro()
2118+
}
2119+
})
21012120
}

src/libsync/comm/sync.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -218,9 +218,15 @@ impl<T: Send> Packet<T> {
218218
}
219219
} else {
220220
// If the buffer has some space and the capacity isn't 0, then we
221-
// just enqueue the data for later retrieval.
221+
// just enqueue the data for later retrieval, ensuring to wake up
222+
// any blocked receiver if there is one.
222223
assert!(state.buf.size() < state.buf.cap());
223224
state.buf.enqueue(t);
225+
match mem::replace(&mut state.blocker, NoneBlocked) {
226+
BlockedReceiver(task) => wakeup(task, guard),
227+
NoneBlocked => {}
228+
BlockedSender(..) => unreachable!(),
229+
}
224230
Ok(())
225231
}
226232
}

0 commit comments

Comments
 (0)