The problem is that AlarmImpl doesn't meet the above guarantee.
So, IIUC AlarmImpl::update_timer()'s lambda grabs a "data" pointer fiddles about and *then releases its lock*.
Then the TimeoutFrameDroppingPolicy is deleted which destroys "this" which calls cancel() and sets data->state to "cancelled".
Regardless of ~AlarmImpl() and AlarmImpl::cancel() having been called, data->callback() is invoked and chaos ensues.
The problem is that AlarmImpl doesn't meet the above guarantee.
So, IIUC AlarmImpl: :update_ timer() 's lambda grabs a "data" pointer fiddles about and *then releases its lock*.
Then the TimeoutFrameDro ppingPolicy is deleted which destroys "this" which calls cancel() and sets data->state to "cancelled".
Regardless of ~AlarmImpl() and AlarmImpl::cancel() having been called, data->callback() is invoked and chaos ensues.