Add locking around signal handler registration.
authorOwen Anderson <resistor@mac.com>
Mon, 17 Aug 2009 17:07:22 +0000 (17:07 +0000)
committerOwen Anderson <resistor@mac.com>
Mon, 17 Aug 2009 17:07:22 +0000 (17:07 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@79254 91177308-0d34-0410-b5e6-96231b3b80d8

lib/System/Unix/Signals.inc

index e385e0c5566257b0eb7d09fa301250d9fff4046b..d39e1e99a0c5dd055e14de72f1307b7c7c9b08f7 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "Unix.h"
 #include "llvm/ADT/STLExtras.h"
 
 #include "Unix.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/System/Mutex.h"
 #include <vector>
 #include <algorithm>
 #if HAVE_EXECINFO_H
 #include <vector>
 #include <algorithm>
 #if HAVE_EXECINFO_H
@@ -33,6 +34,8 @@ using namespace llvm;
 
 static RETSIGTYPE SignalHandler(int Sig);  // defined below.
 
 
 static RETSIGTYPE SignalHandler(int Sig);  // defined below.
 
+static SmartMutex<true> SignalsMutex;
+
 /// InterruptFunction - The function to call if ctrl-c is pressed.
 static void (*InterruptFunction)() = 0;
 
 /// InterruptFunction - The function to call if ctrl-c is pressed.
 static void (*InterruptFunction)() = 0;
 
@@ -113,6 +116,7 @@ static RETSIGTYPE SignalHandler(int Sig) {
   sigfillset(&SigMask);
   sigprocmask(SIG_UNBLOCK, &SigMask, 0);
 
   sigfillset(&SigMask);
   sigprocmask(SIG_UNBLOCK, &SigMask, 0);
 
+  SignalsMutex.acquire();
   if (FilesToRemove != 0)
     while (!FilesToRemove->empty()) {
       FilesToRemove->back().eraseFromDisk(true);
   if (FilesToRemove != 0)
     while (!FilesToRemove->empty()) {
       FilesToRemove->back().eraseFromDisk(true);
@@ -122,14 +126,19 @@ static RETSIGTYPE SignalHandler(int Sig) {
   if (std::find(IntSigs, IntSigsEnd, Sig) != IntSigsEnd) {
     if (InterruptFunction) {
       void (*IF)() = InterruptFunction;
   if (std::find(IntSigs, IntSigsEnd, Sig) != IntSigsEnd) {
     if (InterruptFunction) {
       void (*IF)() = InterruptFunction;
+      SignalsMutex.release();
       InterruptFunction = 0;
       IF();        // run the interrupt function.
       return;
     }
       InterruptFunction = 0;
       IF();        // run the interrupt function.
       return;
     }
+    
+    SignalsMutex.release();
     raise(Sig);   // Execute the default handler.
     return;
   }
 
     raise(Sig);   // Execute the default handler.
     return;
   }
 
+  SignalsMutex.release();
+
   // Otherwise if it is a fault (like SEGV) run any handler.
   if (CallBacksToRun)
     for (unsigned i = 0, e = CallBacksToRun->size(); i != e; ++i)
   // Otherwise if it is a fault (like SEGV) run any handler.
   if (CallBacksToRun)
     for (unsigned i = 0, e = CallBacksToRun->size(); i != e; ++i)
@@ -139,18 +148,23 @@ static RETSIGTYPE SignalHandler(int Sig) {
 
 
 void llvm::sys::SetInterruptFunction(void (*IF)()) {
 
 
 void llvm::sys::SetInterruptFunction(void (*IF)()) {
+  SignalsMutex.acquire();
   InterruptFunction = IF;
   InterruptFunction = IF;
+  SignalsMutex.release();
   RegisterHandlers();
 }
 
 // RemoveFileOnSignal - The public API
 bool llvm::sys::RemoveFileOnSignal(const sys::Path &Filename,
                                    std::string* ErrMsg) {
   RegisterHandlers();
 }
 
 // RemoveFileOnSignal - The public API
 bool llvm::sys::RemoveFileOnSignal(const sys::Path &Filename,
                                    std::string* ErrMsg) {
+  SignalsMutex.acquire();
   if (FilesToRemove == 0)
     FilesToRemove = new std::vector<sys::Path>();
 
   FilesToRemove->push_back(Filename);
 
   if (FilesToRemove == 0)
     FilesToRemove = new std::vector<sys::Path>();
 
   FilesToRemove->push_back(Filename);
 
+  SignalsMutex.release();
+
   RegisterHandlers();
   return false;
 }
   RegisterHandlers();
   return false;
 }