You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Prevent IPC server crash if disconnected during IPC call
Antoine Poinsot <[email protected]> reported a bug with details in
#182 (comment)
where an IPC client rapidly connecting and disconnecting to the server in a
loop could cause problems.
One problem this uncovered was hangs on shutdown fixed by the previous commit.
Another problem it uncovered is that if a disconnect happened while the IPC
server was executing an IPC call, and the onDisconnect() handling code ran
before the IPC call finished, memory corruption would occur usually leading to
a hang or crash.
This happend because the ~ProxyServerBase() destructor was written with the
assumption that it would always be called either from the ~Connection()
destructor, or before that point, so its m_context.connection pointer would
always be valid. Typically this was the case, but not if the connection was
closed during an active IPC call.
A unit test to reproduce this error is added in the subsequent commit.
The fix for the bug here is actually a code simplification. Previously
~ProxyServerBase() destructor would append a std::function callback destroying
the ProxyServerBase::m_impl object to
m_context.connection->m_async_cleanup_fns, so the object destructor could be
called asynchronously without blocking the event loop. Now it just appends the
same callback function to m_context.loop->m_async_fns without going through the
Connection object.
The new code is an improvement over the previous code in two other ways:
- It is a code simplification since previous code was needlessly complicated.
- In the case where there is no disconnect, and the remote ProxyClient is
destroyed, and no "destroy" method is declared, this change causes the
ProxyServer::m_impl object to be freed shortly after the client is freed,
instead of being delayed until the connection is closed. (If a "destroy"
method is declared, this change has no effect because in that case destroying
the ProxyClient calls destroy and destroys ProxyServer::m_impl synchronously.)
The previous code was trying to make the ProxyServer cleanup with
Connection::m_async_cleanup_fns mirror the ProxyClient cleanup with
Connection::m_sync_cleanup_fns, but it was just fragile and unncecessarily
complicated.
Some comments about ProxyClient cleanup code are updated for clarity here but
no changes are made.
0 commit comments