Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Try improving
relay_datagram_send_channel()
(#3118)
## Description <!-- A summary of what this pull request achieves and a rough list of changes. --> Closes #3067 Since multiple `Connection`s can have multiple `AsyncUdpSocket` `IpPollers`, it's incorrect to assume that a single `AtomicWaker` can wake up these tasks correctly. Instead, if there's only one `AtomicWaker` for all of them, only the last registered waker will be woken when there's capacity again. I'm changing this such that `poll_writable` will actually add the current task's waker to a list, if it hasn't been added yet. And successfully `recv`ing an item will wake all tasks. A second issue was that *between* the call to `self.sender.capacity()` (it being 0) and `self.waker.register`, another thread might have successfully `recv`d an item *and* called `self.waker.wake()`. This means that the first thread could've registered a waker, while the capacity is actually non-zero. Not terrible (it's very likely that it'll be woken up when the capacity jumps to 2 this time), but also not great. The fix is to re-check the capacity after registering the waker. The downside is that we keep the waker and thus potentially get a spurious wakeup, but that's fine. ## Notes & open questions <!-- Any notes, remarks or open questions you have to make about the PR. --> This... "fixes" the concerns, but I'd actually like to write a loom test for the concerns eventually. It's just... a *lot* of work, and I'd rather prioritize other things, but also improve this part of the code at the same time. ## Change checklist - [x] Self-review. - [x] Documentation updates following the [style guide](https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#appendix-a-full-conventions-text), if relevant. - [ ] Tests if relevant. - [x] All breaking changes documented.
- Loading branch information