================
@@ -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