-
Notifications
You must be signed in to change notification settings - Fork 61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Task wakes too often in release mode when used with async_std
#133
Comments
If you do the same with tokio, does it behave correctly? |
I've tested it with ed.: |
This, to me, looks a lot like some sort of soft race condition, because it goes away if I add some overhead (or run the thing in async_std::task::spawn(futures_util::future::pending::<()>()); |
Update: this seems to affect anything that uses |
I found the reason ( let waker = match kind {
ContextWaker::Read => task::waker_ref(&self.read_waker_proxy),
ContextWaker::Write => task::waker_ref(&self.write_waker_proxy),
}; and the "fix" (for now I can't figure out much better): let waker = match kind {
ContextWaker::Read => task::waker_ref(&self.read_waker_proxy),
ContextWaker::Write => task::waker_ref(&self.write_waker_proxy),
}
.clone(); why:
as for why |
Okay, so I've added a print: let waker = match kind {
ContextWaker::Read => task::waker_ref(&self.read_waker_proxy),
ContextWaker::Write => task::waker_ref(&self.write_waker_proxy),
};
eprintln!("{waker:?} {:?}", waker.clone()); In debug builds (some parts omitted): ... data: 0x563a8f431fa0, vtable: 0x563a8e701368 ... data: 0x563a8f431fa0, vtable: 0x563a8e701368 ... In release builds on 1.78/1.79: ... data: 0x563ac7b8cf30, vtable: 0x563ac5b80238 ... data: 0x563ac7b8cf30, vtable: 0x563ac5b80178 ... ??????? compiler bug? Seems like it's making the same vtable be at different addresses. ed.: it was indeed a compiler bug: rust-lang/futures-rs#2829 (comment) |
There's been a change in how |
I don't have time to look into this in more detail until some time next week, but this sounds like a bug in the code doing the comparison. If multiple codegen units are involved, it's not guaranteed that the vtable is always the same for the same object. That's why e.g. https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#method.ptr_eq exists. |
I'll list all the parts of code I found relevant so far in one place,
async-tungstenite/src/compat.rs Lines 128 to 129 in 6ff28b3
Patch to
|
That seems like a solution that will just fail again some time in the future. This sounds to me like
Doing this as a workaround for now seems acceptable. Do you want to provide a PR for that? |
Intentionally keeping this open here so there's a reminder to revert the change once that's safe to do again. |
Tested with |
Thanks, I'll update the minimum version for futures with the next release and drop the workaround |
This may cause a CPU core to be constantly at
100%
after a client connects and sends nothing:(the same also happens after the handshake when the client is idle; using only
accept_async
as the example, because shorter)It could be an issue with
async-std
but I haven't yet been able to replicate it withoutasync-tungstenite
(both codebases are still a bit hard for me to navigate).The text was updated successfully, but these errors were encountered: