Is there a way to ensure that blocked threads get woken up in the same order as they got blocked? I read somewhere that this would be called a \"strong lock\" but I found no
I tried Chris Dodd solution https://stackoverflow.com/a/14792685/4834897
but the compiler returned errors because queues allows only standard containers that are capable. while references (&) are not copyable as you can see in the following answer by Akira Takahashi : https://stackoverflow.com/a/10475855/4834897
so I corrected the solution using reference_wrapper which allows copyable references.
EDIT: @Parvez Shaikh suggested small alteration to make the code more readable by moving cvar.pop() after signal.wait() in lock() function
#include
#include
#include
#include
#include
#include // std::reference_wrapper, std::ref
using namespace std;
class ordered_lock {
queue> cvar;
mutex cvar_lock;
bool locked;
public:
ordered_lock() : locked(false) {}
void lock() {
unique_lock acquire(cvar_lock);
if (locked) {
condition_variable signal;
cvar.emplace(std::ref(signal));
signal.wait(acquire);
cvar.pop();
} else {
locked = true;
}
}
void unlock() {
unique_lock acquire(cvar_lock);
if (cvar.empty()) {
locked = false;
} else {
cvar.front().get().notify_one();
}
}
};
Another option is to use pointers instead of references, but it seems less safe.