use ParkingLot to construct WaitableMutex will crash
EdagrHW opened this issue · comments
class WaitableMutex : public std::mutex {
using Lot = ParkingLot<std::function<bool(void)>>;
static Lot lot;
public:
void unlock() {
bool unparked = false;
lot.unpark(uint64_t(this), [&](std::function<bool(void)> wfunc) {
if (wfunc()) {
unparked = true;
return UnparkControl::RemoveBreak;
} else {
return UnparkControl::RemoveContinue;
}
});
if (!unparked) {
std::mutex::unlock();
}
}
template <typename Wait>
void wait(Wait wfunc) {
lot.park(
uint64_t(this), wfunc, [&]() { return !wfunc(); }, [&]() { std::mutex::unlock(); });
}
};
WaitableMutex::Lot WaitableMutex::lot;
int main() {
// test();
std::atomic<bool> go{false};
WaitableMutex mu;
std::thread t([&]() {
std::unique_lock<WaitableMutex> g(mu);
mu.wait([&]() { return go == true; });
});
std::this_thread::sleep_for(std::chrono::seconds(1));
{
std::lock_guard<WaitableMutex> g(mu);
go = true;
}
t.join();
}
/*
error: unlock of unowned mutex
reason:
"When destructed twice, the unlock method will be called twice. The first time it will not execute std::mutex::unlock(), but the second time it will. And during the wait operation, std::mutex::unlock() has already been called once."
*/