I wanted to demonstrate / log some std::mutex behaviour. I would like to log every call to lock() and unlock() (regardless whether they succeed or have to block). Originally, since those methods are not virtual, I tried to wrap the standard std::mutex in the following way, instead of using inheritance:
struct mutex_wrapper {
std::mutex mut = std::mutex();
void lock() {
std::cout << "LOCKING MUTEX\n";
mut.lock();
}
void unlock() {
std::cout << "UNLOCKING MUTEX\n";
mut.unlock();
}
};
Ignore the fact that calls to std::cout << could produce mangled output when called within multiple threads.
Then I wanted to inspect the output of a simple std::condition_variable example, as such:
int main() {
auto ready = false;
auto mutex = mutex_wrapper();
auto cvar = std::condition_variable();
auto t = std::thread([&mutex, &cvar, &ready] {
std::unique_lock lock(mutex);
cvar.wait(lock, [&ready] { return ready; });
std::cout << "woke up\n";
});
std::this_thread::sleep_for(std::chrono::seconds(2));
{
std::lock_guard lock(mutex);
ready = true;
}
std::cout << "notifying\n";
cvar.notify_one();
t.join();
}
The problem is that it doesn't compile because, apparently, wait() requires that the corresponding std::unique_lock is instantiated with the regular std::mutex while I tried to use it with my own mutex_wrapper.
Is there any way to log the internal usage of locking and unlocking of a standard mutex? Or is there a way to make std::condition_variable work with wrappers?