From 16632ce4c7a95a3a49e33577d6b31bb9e6e90c5d Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Tue, 2 Sep 2014 23:48:13 +0000 Subject: [PATCH] Cleaning up remaining static initializers in Signals.inc git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216996 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/Unix/Signals.inc | 55 ++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/lib/Support/Unix/Signals.inc b/lib/Support/Unix/Signals.inc index 36e521b2531..592674e95db 100644 --- a/lib/Support/Unix/Signals.inc +++ b/lib/Support/Unix/Signals.inc @@ -16,6 +16,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Mutex.h" #include "llvm/Support/UniqueLock.h" +#include "llvm/Support/ManagedStatic.h" #include #include #include @@ -42,13 +43,14 @@ using namespace llvm; static RETSIGTYPE SignalHandler(int Sig); // defined below. -static SmartMutex SignalsMutex; +static ManagedStatic > SignalsMutex; /// InterruptFunction - The function to call if ctrl-c is pressed. static void (*InterruptFunction)() = nullptr; -static std::vector FilesToRemove; -static std::vector > CallBacksToRun; +static ManagedStatic> FilesToRemove; +static ManagedStatic>> + CallBacksToRun; // IntSigs - Signals that represent requested termination. There's no bug // or failure, or if there is, it's not our direct responsibility. For whatever @@ -124,11 +126,12 @@ static void UnregisterHandlers() { static void RemoveFilesToRemove() { // We avoid iterators in case of debug iterators that allocate or release // memory. - for (unsigned i = 0, e = FilesToRemove.size(); i != e; ++i) { + std::vector& FilesToRemoveRef = *FilesToRemove; + for (unsigned i = 0, e = FilesToRemoveRef.size(); i != e; ++i) { // We rely on a std::string implementation for which repeated calls to // 'c_str()' don't allocate memory. We pre-call 'c_str()' on all of these // strings to try to ensure this is safe. - const char *path = FilesToRemove[i].c_str(); + const char *path = FilesToRemoveRef[i].c_str(); // Get the status so we can determine if it's a file or directory. If we // can't stat the file, ignore it. @@ -162,7 +165,7 @@ static RETSIGTYPE SignalHandler(int Sig) { sigprocmask(SIG_UNBLOCK, &SigMask, nullptr); { - unique_lock> Guard(SignalsMutex); + unique_lock> Guard(*SignalsMutex); RemoveFilesToRemove(); if (std::find(std::begin(IntSigs), std::end(IntSigs), Sig) @@ -182,8 +185,10 @@ static RETSIGTYPE SignalHandler(int Sig) { } // Otherwise if it is a fault (like SEGV) run any handler. - for (unsigned i = 0, e = CallBacksToRun.size(); i != e; ++i) - CallBacksToRun[i].first(CallBacksToRun[i].second); + std::vector>& CallBacksToRunRef = + *CallBacksToRun; + for (unsigned i = 0, e = CallBacksToRun->size(); i != e; ++i) + CallBacksToRunRef[i].first(CallBacksToRunRef[i].second); #ifdef __s390__ // On S/390, certain signals are delivered with PSW Address pointing to @@ -196,13 +201,13 @@ static RETSIGTYPE SignalHandler(int Sig) { } void llvm::sys::RunInterruptHandlers() { - sys::SmartScopedLock Guard(SignalsMutex); + sys::SmartScopedLock Guard(*SignalsMutex); RemoveFilesToRemove(); } void llvm::sys::SetInterruptFunction(void (*IF)()) { { - sys::SmartScopedLock Guard(SignalsMutex); + sys::SmartScopedLock Guard(*SignalsMutex); InterruptFunction = IF; } RegisterHandlers(); @@ -212,20 +217,22 @@ void llvm::sys::SetInterruptFunction(void (*IF)()) { bool llvm::sys::RemoveFileOnSignal(StringRef Filename, std::string* ErrMsg) { { - sys::SmartScopedLock Guard(SignalsMutex); - std::string *OldPtr = FilesToRemove.empty() ? nullptr : &FilesToRemove[0]; - FilesToRemove.push_back(Filename); + sys::SmartScopedLock Guard(*SignalsMutex); + std::vector& FilesToRemoveRef = *FilesToRemove; + std::string *OldPtr = + FilesToRemoveRef.empty() ? nullptr : &FilesToRemoveRef[0]; + FilesToRemoveRef.push_back(Filename); // We want to call 'c_str()' on every std::string in this vector so that if // the underlying implementation requires a re-allocation, it happens here // rather than inside of the signal handler. If we see the vector grow, we // have to call it on every entry. If it remains in place, we only need to // call it on the latest one. - if (OldPtr == &FilesToRemove[0]) - FilesToRemove.back().c_str(); + if (OldPtr == &FilesToRemoveRef[0]) + FilesToRemoveRef.back().c_str(); else - for (unsigned i = 0, e = FilesToRemove.size(); i != e; ++i) - FilesToRemove[i].c_str(); + for (unsigned i = 0, e = FilesToRemoveRef.size(); i != e; ++i) + FilesToRemoveRef[i].c_str(); } RegisterHandlers(); @@ -234,18 +241,18 @@ bool llvm::sys::RemoveFileOnSignal(StringRef Filename, // DontRemoveFileOnSignal - The public API void llvm::sys::DontRemoveFileOnSignal(StringRef Filename) { - sys::SmartScopedLock Guard(SignalsMutex); + sys::SmartScopedLock Guard(*SignalsMutex); std::vector::reverse_iterator RI = - std::find(FilesToRemove.rbegin(), FilesToRemove.rend(), Filename); - std::vector::iterator I = FilesToRemove.end(); - if (RI != FilesToRemove.rend()) - I = FilesToRemove.erase(RI.base()-1); + std::find(FilesToRemove->rbegin(), FilesToRemove->rend(), Filename); + std::vector::iterator I = FilesToRemove->end(); + if (RI != FilesToRemove->rend()) + I = FilesToRemove->erase(RI.base()-1); // We need to call c_str() on every element which would have been moved by // the erase. These elements, in a C++98 implementation where c_str() // requires a reallocation on the first call may have had the call to c_str() // made on insertion become invalid by being copied down an element. - for (std::vector::iterator E = FilesToRemove.end(); I != E; ++I) + for (std::vector::iterator E = FilesToRemove->end(); I != E; ++I) I->c_str(); } @@ -253,7 +260,7 @@ void llvm::sys::DontRemoveFileOnSignal(StringRef Filename) { /// to the process. The handler can have a cookie passed to it to identify /// what instance of the handler it is. void llvm::sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) { - CallBacksToRun.push_back(std::make_pair(FnPtr, Cookie)); + CallBacksToRun->push_back(std::make_pair(FnPtr, Cookie)); RegisterHandlers(); }