Thread A is calling BufferQueue::release, owns BufferQueue::guard, and it's about to call TimeoutFrameDroppingPolicy::swap_unblocked() gets pre-empted
Thread B is executing the alarm handler in TimeoutFrameDroppingPolicy, which invokes the callback installed by BufferQueue to drop a frame, attempts to own BufferQueue::guard so it blocks.
Thread A resumes, calls TimeoutFrameDroppingPolicy::swap_unblocked() and calls alarm->cancel(), it deadlocks, since data->callbacks_running will never be decremented (waiting for the alarm handler invocation to return).
Thread A is calling BufferQueue: :release, owns BufferQueue::guard, and it's about to call TimeoutFrameDro ppingPolicy: :swap_unblocked () gets pre-empted
Thread B is executing the alarm handler in TimeoutFrameDro ppingPolicy, which invokes the callback installed by BufferQueue to drop a frame, attempts to own BufferQueue::guard so it blocks.
Thread A resumes, calls TimeoutFrameDro ppingPolicy: :swap_unblocked () and calls alarm->cancel(), it deadlocks, since data->callbacks _running will never be decremented (waiting for the alarm handler invocation to return).