forked from OSchip/llvm-project
Revert "ManagedStatic: remove from DynamicLibrary"
This reverts commit 38817af6a7
.
Buildbots report a Windows build error. Revert until I can look at it
more carefully.
This commit is contained in:
parent
569a7f6aa3
commit
5c7c83885f
|
@ -15,6 +15,7 @@
|
|||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/Config/config.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include "llvm/Support/Mutex.h"
|
||||
#include <vector>
|
||||
|
||||
|
@ -106,22 +107,12 @@ public:
|
|||
};
|
||||
|
||||
namespace {
|
||||
|
||||
struct Globals {
|
||||
// Collection of symbol name/value pairs to be searched prior to any
|
||||
// libraries.
|
||||
llvm::StringMap<void *> ExplicitSymbols;
|
||||
// Collection of known library handles.
|
||||
DynamicLibrary::HandleSet OpenedHandles;
|
||||
// Lock for ExplicitSymbols and OpenedHandles.
|
||||
llvm::sys::SmartMutex<true> SymbolsMutex;
|
||||
};
|
||||
|
||||
Globals &getGlobals() {
|
||||
static Globals G;
|
||||
return G;
|
||||
}
|
||||
|
||||
// Collection of symbol name/value pairs to be searched prior to any libraries.
|
||||
static llvm::ManagedStatic<llvm::StringMap<void *>> ExplicitSymbols;
|
||||
// Collection of known library handles.
|
||||
static llvm::ManagedStatic<DynamicLibrary::HandleSet> OpenedHandles;
|
||||
// Lock for ExplicitSymbols and OpenedHandles.
|
||||
static llvm::ManagedStatic<llvm::sys::SmartMutex<true>> SymbolsMutex;
|
||||
} // namespace
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -145,18 +136,20 @@ void *SearchForAddressOfSpecialSymbol(const char *SymbolName) {
|
|||
} // namespace llvm
|
||||
|
||||
void DynamicLibrary::AddSymbol(StringRef SymbolName, void *SymbolValue) {
|
||||
auto &G = getGlobals();
|
||||
SmartScopedLock<true> Lock(G.SymbolsMutex);
|
||||
G.ExplicitSymbols[SymbolName] = SymbolValue;
|
||||
SmartScopedLock<true> Lock(*SymbolsMutex);
|
||||
(*ExplicitSymbols)[SymbolName] = SymbolValue;
|
||||
}
|
||||
|
||||
DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *FileName,
|
||||
std::string *Err) {
|
||||
auto &G = getGlobals();
|
||||
// Force OpenedHandles to be added into the ManagedStatic list before any
|
||||
// ManagedStatic can be added from static constructors in HandleSet::DLOpen.
|
||||
HandleSet& HS = *OpenedHandles;
|
||||
|
||||
void *Handle = HandleSet::DLOpen(FileName, Err);
|
||||
if (Handle != &Invalid) {
|
||||
SmartScopedLock<true> Lock(G.SymbolsMutex);
|
||||
G.OpenedHandles.AddLibrary(Handle, /*IsProcess*/ FileName == nullptr);
|
||||
SmartScopedLock<true> Lock(*SymbolsMutex);
|
||||
HS.AddLibrary(Handle, /*IsProcess*/ FileName == nullptr);
|
||||
}
|
||||
|
||||
return DynamicLibrary(Handle);
|
||||
|
@ -164,11 +157,9 @@ DynamicLibrary DynamicLibrary::getPermanentLibrary(const char *FileName,
|
|||
|
||||
DynamicLibrary DynamicLibrary::addPermanentLibrary(void *Handle,
|
||||
std::string *Err) {
|
||||
auto &G = getGlobals();
|
||||
SmartScopedLock<true> Lock(G.SymbolsMutex);
|
||||
SmartScopedLock<true> Lock(*SymbolsMutex);
|
||||
// If we've already loaded this library, tell the caller.
|
||||
if (!G.OpenedHandles.AddLibrary(Handle, /*IsProcess*/ false,
|
||||
/*CanClose*/ false))
|
||||
if (!OpenedHandles->AddLibrary(Handle, /*IsProcess*/false, /*CanClose*/false))
|
||||
*Err = "Library already loaded";
|
||||
|
||||
return DynamicLibrary(Handle);
|
||||
|
@ -182,18 +173,21 @@ void *DynamicLibrary::getAddressOfSymbol(const char *SymbolName) {
|
|||
|
||||
void *DynamicLibrary::SearchForAddressOfSymbol(const char *SymbolName) {
|
||||
{
|
||||
auto &G = getGlobals();
|
||||
SmartScopedLock<true> Lock(G.SymbolsMutex);
|
||||
SmartScopedLock<true> Lock(*SymbolsMutex);
|
||||
|
||||
// First check symbols added via AddSymbol().
|
||||
StringMap<void *>::iterator i = G.ExplicitSymbols.find(SymbolName);
|
||||
if (ExplicitSymbols.isConstructed()) {
|
||||
StringMap<void *>::iterator i = ExplicitSymbols->find(SymbolName);
|
||||
|
||||
if (i != G.ExplicitSymbols.end())
|
||||
return i->second;
|
||||
if (i != ExplicitSymbols->end())
|
||||
return i->second;
|
||||
}
|
||||
|
||||
// Now search the libraries.
|
||||
if (void *Ptr = G.OpenedHandles.Lookup(SymbolName, SearchOrder))
|
||||
return Ptr;
|
||||
if (OpenedHandles.isConstructed()) {
|
||||
if (void *Ptr = OpenedHandles->Lookup(SymbolName, SearchOrder))
|
||||
return Ptr;
|
||||
}
|
||||
}
|
||||
|
||||
return llvm::SearchForAddressOfSpecialSymbol(SymbolName);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "llvm/Support/DynamicLibrary.h"
|
||||
#include "llvm/Config/config.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
|
@ -58,6 +59,7 @@ std::string StdString(const char *Ptr) { return Ptr ? Ptr : ""; }
|
|||
TEST(DynamicLibrary, Overload) {
|
||||
{
|
||||
std::string Err;
|
||||
llvm_shutdown_obj Shutdown;
|
||||
DynamicLibrary DL =
|
||||
DynamicLibrary::getPermanentLibrary(LibPath().c_str(), &Err);
|
||||
EXPECT_TRUE(DL.isValid());
|
||||
|
@ -105,6 +107,68 @@ TEST(DynamicLibrary, Overload) {
|
|||
EXPECT_EQ(GS, &OverloadTestA);
|
||||
EXPECT_EQ(StdString(GS()), "OverloadCall");
|
||||
}
|
||||
EXPECT_TRUE(FuncPtr<GetString>(DynamicLibrary::SearchForAddressOfSymbol(
|
||||
"TestA")) == nullptr);
|
||||
|
||||
// Check serach ordering is reset to default after call to llvm_shutdown
|
||||
EXPECT_EQ(DynamicLibrary::SearchOrder, DynamicLibrary::SO_Linker);
|
||||
}
|
||||
|
||||
TEST(DynamicLibrary, Shutdown) {
|
||||
std::string A("PipSqueak"), B, C("SecondLib");
|
||||
std::vector<std::string> Order;
|
||||
{
|
||||
std::string Err;
|
||||
llvm_shutdown_obj Shutdown;
|
||||
DynamicLibrary DL =
|
||||
DynamicLibrary::getPermanentLibrary(LibPath(A).c_str(), &Err);
|
||||
EXPECT_TRUE(DL.isValid());
|
||||
EXPECT_TRUE(Err.empty());
|
||||
|
||||
SetStrings SS_0 = FuncPtr<SetStrings>(
|
||||
DynamicLibrary::SearchForAddressOfSymbol("SetStrings"));
|
||||
EXPECT_NE(SS_0, nullptr);
|
||||
|
||||
SS_0(A, B);
|
||||
EXPECT_EQ(B, "Local::Local(PipSqueak)");
|
||||
|
||||
TestOrder TO_0 = FuncPtr<TestOrder>(
|
||||
DynamicLibrary::SearchForAddressOfSymbol("TestOrder"));
|
||||
EXPECT_NE(TO_0, nullptr);
|
||||
|
||||
DynamicLibrary DL2 =
|
||||
DynamicLibrary::getPermanentLibrary(LibPath(C).c_str(), &Err);
|
||||
EXPECT_TRUE(DL2.isValid());
|
||||
EXPECT_TRUE(Err.empty());
|
||||
|
||||
// Should find latest version of symbols in SecondLib
|
||||
SetStrings SS_1 = FuncPtr<SetStrings>(
|
||||
DynamicLibrary::SearchForAddressOfSymbol("SetStrings"));
|
||||
EXPECT_NE(SS_1, nullptr);
|
||||
EXPECT_NE(SS_0, SS_1);
|
||||
|
||||
TestOrder TO_1 = FuncPtr<TestOrder>(
|
||||
DynamicLibrary::SearchForAddressOfSymbol("TestOrder"));
|
||||
EXPECT_NE(TO_1, nullptr);
|
||||
EXPECT_NE(TO_0, TO_1);
|
||||
|
||||
B.clear();
|
||||
SS_1(C, B);
|
||||
EXPECT_EQ(B, "Local::Local(SecondLib)");
|
||||
|
||||
TO_0(Order);
|
||||
TO_1(Order);
|
||||
}
|
||||
EXPECT_EQ(A, "Global::~Global");
|
||||
EXPECT_EQ(B, "Local::~Local");
|
||||
EXPECT_EQ(FuncPtr<SetStrings>(
|
||||
DynamicLibrary::SearchForAddressOfSymbol("SetStrings")),
|
||||
nullptr);
|
||||
|
||||
// Test unload/destruction ordering
|
||||
EXPECT_EQ(Order.size(), 2UL);
|
||||
EXPECT_EQ(Order.front(), "SecondLib");
|
||||
EXPECT_EQ(Order.back(), "PipSqueak");
|
||||
}
|
||||
|
||||
#else
|
||||
|
|
Loading…
Reference in New Issue