================
@@ -12,41 +12,62 @@
 #include "llvm/Support/AdvisoryLock.h"
 #include "llvm/Support/Chrono.h"
 
-#include <mutex>
-
 using namespace clang;
 using namespace dependencies;
 
 namespace {
 class ReaderWriterLock : public llvm::AdvisoryLock {
-  // TODO: Consider using std::atomic::{wait,notify_all} when we move to C++20.
-  std::unique_lock<std::shared_mutex> OwningLock;
+  ModuleCacheEntry &Entry;
+  std::optional<unsigned> OwnedGeneration;
 
 public:
-  ReaderWriterLock(std::shared_mutex &Mutex)
-      : OwningLock(Mutex, std::defer_lock) {}
-
-  Expected<bool> tryLock() override { return OwningLock.try_lock(); }
+  explicit ReaderWriterLock(ModuleCacheEntry &Entry) : Entry(Entry) {}
+
+  Expected<bool> tryLock() override {
+    std::lock_guard<std::mutex> Lock(Entry.Mutex);
+    if (Entry.Locked)
+      return false;
+    Entry.Locked = true;
+    OwnedGeneration = Entry.Generation;
+    return true;
+  }
 
   llvm::WaitForUnlockResult
   waitForUnlockFor(std::chrono::seconds MaxSeconds) override {
-    assert(!OwningLock);
-    // We do not respect the timeout here. It's very generous for implicit
-    // modules, so we'd typically only reach it if the owner crashed (but so 
did
-    // we, since we run in the same process), or encountered deadlock.
-    (void)MaxSeconds;
-    std::shared_lock<std::shared_mutex> Lock(*OwningLock.mutex());
-    return llvm::WaitForUnlockResult::Success;
+    assert(!OwnedGeneration);
+    std::unique_lock<std::mutex> Lock(Entry.Mutex);
+    unsigned CurrentGeneration = Entry.Generation;
+    bool Success = Entry.CondVar.wait_for(Lock, MaxSeconds, [&] {
+      // We check not only Locked, but also Generation to break the wait in 
case
+      // of unsafeUnlock() and successful tryLock().
+      return !Entry.Locked || Entry.Generation != CurrentGeneration;
+    });
----------------
jansvoboda11 wrote:

Fair enough. Do you see any other cross-platform solution that:
1. implements the timeout,
2. implements the unsafe unlock from any thread,
3. wakes existing threads out of the wait on the old lock?

https://github.com/llvm/llvm-project/pull/182722
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to