async_hooks: avoid decrementing iterator after erase
decrementing an iterator returned by std::vector::erase
may have
undefined behaviour and should not be used. Decrementing end()
on an empty container is undefined and .erase()
could leave
the container empty.
Instead, by calling vec.erase(it--)
we decrement the valid iterator
before the erase operation but after being passed to the erase method.
In case of AsyncHooks::RemoveContext
perform the cleanup of empty
contexts upfront using std::remove_if
because the iteration gets
interrupted as soon as the context to be removed has been found.