Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix race condition with socket close event from peer
There are a couple places where we can be notified that a TCP socket peer has closed the connection on us: 1. _event_notify(), via an event from the ASIO thread. 2. _pending_reads(), where we try to read from the socket (via the @pony_os_recv()? FFI call which is partial!) and get an error. If we discover the remote peer's close by path #2, then sometime later the ASIO thread may notify us of the close via path #1. Both paths will call `@pony_asio_event_unsubscribe(event)`. There's a sanity check + `pony_assert(0)` inside of the Pony runtime to prevent double calls to `@pony_asio_event_unsubscribe(event)`. However, `pony_assert()` will only act if using a Pony "debug" build of the runtime. So, in non-debug use (i.e., normal day-to-day use), nobody notices the problem: it's only visible when using a debug build (probably because you're debugging some *other* problem). This commit adds a comment + check to avoid double-calls to `@pony_asio_event_unsubscribe(event)`. It's done by adding a new Pony API FFI call, `@pony_asio_event_get_disposable`, that peeks into the event's flag status (and *not* the `flags` argument to `_event_notify()`!) to check if it's safe to unsubscribe. Many thanks to @dipinhora for discussing the merits of how the heck to fix this and to @nisanharamati for being curious about, "Why is this thing sometimes crashing, but only when using a debug build of Pony?"
- Loading branch information