Based on my understanding, it looks like the lock cycle is happening because of the following set up:
On one thread, the `_monitorMutex` mutex is taken here before calling notify(), and then the `mutex` mutex (defined here) is being taken here when we actually enter the listener and call notify.
On another thread, we take the `mutex` mutex here, and then with that mutex still in scope we take the `_monitorMutex` here inside the call to removeListener here.
Meaning, we have a lock inversion order: `_monitorMutex` -> `mutex` on one thread, and `mutex` -> `_monitorMutex` on another.
This can be resolved by wrapping up this acquisition of the `mutex` mutex inside an anonymous namespace, so that after we have waited on the listeners all changing the conditioned_variable the mutex goes out of scope, allowing us to call removeListener without a cycle.