RpcMessageStream::try_start_send()1can miss pending messages because it first performs a relaxed load of _send_token which can miss store/store_release of _send_token.
RpcMessageStream::get_from_pending_queue()2can miss pending messages because it performs a relaxed load of _pending_message_count before entering the critical section guarded by _pending_lock, again, the relaxed load can miss store/store_release of _pending_message_count.
With the above two defects combined, the current message calling try_start_send() and the previous message calling get_from_pending_queue() (on_write_some() ---> try_start_send() ---> get_from_pending_queue() ) both may miss the chance to send the current pending message, which lead to the current pending message siting idle in _pending_callsuntil timeout.
I believe the scenario described above is quite likely to happen under weak memory model such as aarch64 and ppc64.
RpcMessageStream::try_start_send()
1can miss pending messages because it first performs a relaxed load of_send_token
which can miss store/store_release of_send_token
.RpcMessageStream::get_from_pending_queue()
2can miss pending messages because it performs a relaxed load of_pending_message_count
before entering the critical section guarded by _pending_lock, again, the relaxed load can miss store/store_release of_pending_message_count
.With the above two defects combined, the current message calling
try_start_send()
and the previous message callingget_from_pending_queue()
(on_write_some() ---> try_start_send() ---> get_from_pending_queue() ) both may miss the chance to send the current pending message, which lead to the current pending message siting idle in_pending_calls
until timeout.I believe the scenario described above is quite likely to happen under weak memory model such as aarch64 and ppc64.