fix lock order inversion in SharedPromise interrupt handler setting exn
Summary: The approach taken to fixing the lock inversion is not to use locks. Instead, we take a page from the existing futures playbook and use an atomic acyclic finite state machine! In this case, we have a single atomic pointer which may own either a raised object of type `exception_wrapper` or an interrupt-handler. Both are at least 4-byte aligned (8-byte aligned on 64-bit architectures) so both have the bottom two bits free. We use the bottom two bits as the state machine to identify whether `0x0u` initial where nothing is owned, `0x1u` where an interrupt-handler is owned, `0x2u` where a raised object is owned, or `0x3u` terminal where both an interrupt-handler and a raised object have been set and the handler has been invoked on the object. As choices, we forbid repeated calls to set the interrupt handler but permit repeated calls to raise an object. Calls after the first to set an interrupt handler terminate while calls to raise an object after the first are ignored. Existing tests demonstrate raising twice so we may like to be cautious about breaking that behavior. Some semantics are changed. Raised objects and interrupt handlers are destroyed earlier than before: they are now destroyed immediately after invoking handlers on objects. The lock order inversion is observed by thread sanitizer (tsan) in the new shared-promise test. Differential Revision: D29250149 fbshipit-source-id: 63e257d03cebbf8dba95a514b7e89680cae569a7
Showing
Please register or sign in to comment