Commit 47d37c8e authored by Matthew Tolton's avatar Matthew Tolton Committed by Facebook Github Bot

Fix deadlock in TimedMutex

Summary:
If a lock is stolen from fiber f1, and then fiber f2 is notified before f1 one
wakes up and discovers the crime, then f1 will clear notifiedFiber_ so that f2
thinks the lock was stolen from it as well and hence recurses back into lock().

Reviewed By: andriigrynenko

Differential Revision: D5896323

fbshipit-source-id: 528ec1ed983175d3e08f3dc07b69bbc783a86cfb
parent aee7113e
...@@ -64,7 +64,9 @@ TimedMutex::LockResult TimedMutex::lockHelper(WaitFunc&& waitFunc) { ...@@ -64,7 +64,9 @@ TimedMutex::LockResult TimedMutex::lockHelper(WaitFunc&& waitFunc) {
std::lock_guard<folly::SpinLock> lg(lock_); std::lock_guard<folly::SpinLock> lg(lock_);
auto stolen = notifiedFiber_ != &waiter; auto stolen = notifiedFiber_ != &waiter;
if (!stolen) {
notifiedFiber_ = nullptr; notifiedFiber_ = nullptr;
}
return stolen; return stolen;
}(); }();
......
...@@ -2073,6 +2073,43 @@ TEST(FiberManager, VirtualEventBase) { ...@@ -2073,6 +2073,43 @@ TEST(FiberManager, VirtualEventBase) {
EXPECT_TRUE(done2); EXPECT_TRUE(done2);
} }
TEST(TimedMutex, ThreadsAndFibersDontDeadlock) {
folly::EventBase evb;
auto& fm = getFiberManager(evb);
TimedMutex mutex;
std::thread testThread([&] {
for (int i = 0; i < 100; i++) {
mutex.lock();
mutex.unlock();
{
Baton b;
b.timed_wait(std::chrono::milliseconds(1));
}
}
});
for (int numFibers = 0; numFibers < 100; numFibers++) {
fm.addTask([&] {
for (int i = 0; i < 20; i++) {
mutex.lock();
{
Baton b;
b.timed_wait(std::chrono::milliseconds(1));
}
mutex.unlock();
{
Baton b;
b.timed_wait(std::chrono::milliseconds(1));
}
}
});
}
evb.loop();
EXPECT_EQ(0, fm.hasTasks());
testThread.join();
}
TEST(TimedMutex, ThreadFiberDeadlockOrder) { TEST(TimedMutex, ThreadFiberDeadlockOrder) {
folly::EventBase evb; folly::EventBase evb;
auto& fm = getFiberManager(evb); auto& fm = getFiberManager(evb);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment