summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLang Hames <lhames@gmail.com>2018-09-27 20:36:08 +0000
committerLang Hames <lhames@gmail.com>2018-09-27 20:36:08 +0000
commitcf0949aa9f75eb6af9d93510e5b0325fb45d9c6e (patch)
treede4a70b7792bf8692678f6f035bb8f3257333f71
parent8233af90e1e459425042d43075c13aef5b81e0fc (diff)
downloadbcm5719-llvm-cf0949aa9f75eb6af9d93510e5b0325fb45d9c6e.tar.gz
bcm5719-llvm-cf0949aa9f75eb6af9d93510e5b0325fb45d9c6e.zip
[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. llvm-svn: 343261
-rw-r--r--llvm/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h20
1 files changed, 17 insertions, 3 deletions
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h b/llvm/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h
index c5490a0da99..f763b9b09cc 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h
@@ -102,15 +102,29 @@ public:
/// unique_ptr<LLVMContext>. This creates a new ThreadSafeContext from the
/// given context.
ThreadSafeModule(std::unique_ptr<Module> M, std::unique_ptr<LLVMContext> Ctx)
- : TSCtx(std::move(Ctx)), M(std::move(M)) {}
+ : M(std::move(M)), TSCtx(std::move(Ctx)) {}
+ /// Construct a ThreadSafeModule from a unique_ptr<Module> and an
+ /// existing ThreadSafeContext.
ThreadSafeModule(std::unique_ptr<Module> 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<Module> M;
+ ThreadSafeContext TSCtx;
};
using GVPredicate = std::function<bool(const GlobalValue&)>;
OpenPOWER on IntegriCloud