From 3a5e132bb3a6f92c55d74c2856154aa3fcaf61ba Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Thu, 27 Sep 2018 20:36:08 +0000 Subject: [PATCH] [ORC] Lock ThreadSafeContext during Module destructing in ThreadSafeModule. Failure to lock the context can lead to data races if other threads are operating on other ThreadSafeModules that share the same context. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@343261 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../ExecutionEngine/Orc/ThreadSafeModule.h | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h b/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h index c5490a0da99..f763b9b09cc 100644 --- a/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h +++ b/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h @@ -102,15 +102,29 @@ public: /// unique_ptr. This creates a new ThreadSafeContext from the /// given context. ThreadSafeModule(std::unique_ptr M, std::unique_ptr Ctx) - : TSCtx(std::move(Ctx)), M(std::move(M)) {} + : M(std::move(M)), TSCtx(std::move(Ctx)) {} + /// Construct a ThreadSafeModule from a unique_ptr and an + /// existing ThreadSafeContext. ThreadSafeModule(std::unique_ptr M, ThreadSafeContext TSCtx) - : TSCtx(std::move(TSCtx)), M(std::move(M)) {} + : M(std::move(M)), TSCtx(std::move(TSCtx)) {} + ~ThreadSafeModule() { + // We need to lock the context while we destruct the module. + if (M) { + auto L = getContextLock(); + M = nullptr; + } + } + + /// Get the module wrapped by this ThreadSafeModule. Module* getModule() { return M.get(); } + /// Take out a lock on the ThreadSafeContext for this module. ThreadSafeContext::Lock getContextLock() { return TSCtx.getLock(); } + /// Boolean conversion: This ThreadSafeModule will evaluate to true if it + /// wraps a non-null module. explicit operator bool() { if (M) { assert(TSCtx.getContext() && "Non-null module must have non-null context"); @@ -120,8 +134,8 @@ public: } private: - ThreadSafeContext TSCtx; std::unique_ptr M; + ThreadSafeContext TSCtx; }; using GVPredicate = std::function;