Fix race condition on wait()#504
Fix race condition on wait()#504tomusdrw merged 1 commit intoparitytech:masterfrom foriequal0:fix/wait-race-2
wait()#504Conversation
|
It looks like @foriequal0 signed our Contributor License Agreement. 👍 Many thanks, Parity Technologies CLA Bot |
tomusdrw
left a comment
There was a problem hiding this comment.
Looks good, thank you! The code looks a bit mystical at first sight, so I think it would be good to add a short comment explaining what we do and pointing to this PR.
http/src/lib.rs
Outdated
| }) | ||
| .and_then(|_| done_tx.send(())) | ||
| .and_then(|(_, other)| { | ||
| drop(other); |
There was a problem hiding this comment.
Could you add a comment what are we dropping here and why? Something like:
"We drop the Server first to prevent a situation where main thread terminates before the Server is properly dropped (see #504 for more details)".
There was a problem hiding this comment.
maybe s/other/server/ then?
ipc/src/server.rs
Outdated
| .for_each(|_| Ok(())) | ||
| .select(stop) | ||
| .map(|_| { | ||
| .map(|(_, other)| { |
There was a problem hiding this comment.
Same here if you don't mind.
|
Thank you! I added comments to them. |
dvdplm
left a comment
There was a problem hiding this comment.
lgtm, modulo the variable naming, "other" is a bit obscure.
http/src/lib.rs
Outdated
| }) | ||
| .and_then(|_| done_tx.send(())) | ||
| .and_then(|(_, other)| { | ||
| drop(other); |
There was a problem hiding this comment.
maybe s/other/server/ then?
|
@foriequal0 please rebase as well while you address @dvdplm's grumble. |
Manually dropping the future passed from `Future::select` before sending `done_tx` prevents the race condition. `Future::select` pass the unresolved future, which is a `Server` holding `rpc_handler`, to the following callback. Therefore, it is dropped after the `done_tx.send(())` after the callback exits. It is possible that the thread that has executed `wait()`, which is usually the main thread, terminates before the thread sending `done_tx` drops `rpc_handler`. Static variables are destructed at the end of termination of the main thread, and then a segfault occurs when the thread dropping the rpc_handler accesses the variables.
The fix (paritytech/jsonrpc#504) has been merged to `master`. It'll take times to relase, so use the merged master directly.
The fix (paritytech/jsonrpc#504) has been merged to `master`. It'll take times to relase, so use the merged master directly.
The fix (paritytech/jsonrpc#504) has been merged to `master`. It'll take times to relase, so use the merged master directly.
The fix (paritytech/jsonrpc#504) has been merged to `master`. It'll take times to relase, so use the merged master directly.
The fix (paritytech/jsonrpc#504) has been merged to `master`. It'll take times to relase, so use the merged master directly.
Manually dropping the future passed from
Future::selectbefore sendingdone_txprevents the race condition.Future::selectpass the unresolved future, which is aServerholdingrpc_handler, to the following callback. Therefore, it is dropped afterthe
done_tx.send(())after the callback exits.It is possible that the thread that has executed
wait(), which isusually the main thread, terminates before the thread sending
done_txdrops
rpc_handler.Static variables are destructed at the end of termination of the main
thread, and then a segfault occurs when the thread dropping the
rpc_handler accesses the variables.
I closed the previous PR (#501).
Sorry for the confusion.