Implement SetInterruptFunction for Windows.
authorJeff Cohen <jeffc@jolt-lang.org>
Tue, 2 Aug 2005 03:04:47 +0000 (03:04 +0000)
committerJeff Cohen <jeffc@jolt-lang.org>
Tue, 2 Aug 2005 03:04:47 +0000 (03:04 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22582 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/System/Signals.h
lib/System/Win32/Signals.inc

index f29fae9ab541121718083c7965c6e9408be77bc2..1d5286f3bd98124493c95328e7212fe407455be5 100644 (file)
@@ -42,7 +42,8 @@ namespace sys {
   /// being killed, and the interrupt function automatically disabled.  Note
   /// that interrupt functions are not allowed to call any non-reentrant
   /// functions.  An null interrupt function pointer disables the current
-  /// installed function.
+  /// installed function.  Note also that the handler may be executed on a
+  /// different thread on some platforms.
   /// @brief Register a function to be called when ctrl-c is pressed.
   void SetInterruptFunction(void (*IF)());
 } // End sys namespace
index a2c7ae2c307a4bc8b4ff7dd5341343fad6109346..cf5cb40d4d0592eaa7fd82eee533dcf3192ac461 100644 (file)
@@ -29,6 +29,9 @@
 static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep);
 static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType);
 
+// InterruptFunction - The function to call if ctrl-c is pressed.
+static void (*InterruptFunction)() = 0;
+
 static std::vector<llvm::sys::Path> *FilesToRemove = NULL;
 static std::vector<llvm::sys::Path> *DirectoriesToRemove = NULL;
 static bool RegisteredUnhandledExceptionFilter = false;
@@ -111,7 +114,9 @@ void sys::PrintStackTraceOnErrorSignal() {
 
 
 void sys::SetInterruptFunction(void (*IF)()) {
-  // Currently unimplemented.
+  InterruptFunction = IF;
+  RegisterHandler();
+  LeaveCriticalSection(&CriticalSection);
 }
 }
 
@@ -234,9 +239,28 @@ static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) {
 }
 
 static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType) {
+  EnterCriticalSection(&CriticalSection);
   Cleanup();
 
+  // If an interrupt function has been set, go and run one it; otherwise,
+  // the process dies.
+  void (*IF)() = InterruptFunction;
+  InterruptFunction = 0;      // Don't run it on another CTRL-C.
+
+  if (IF) {
+    try {
+      IF();                   // Run it now.
+    } catch (...) {
+      // Kill the process on an exception.
+      LeaveCriticalSection(&CriticalSection);
+      return FALSE;
+    }
+    LeaveCriticalSection(&CriticalSection);
+    return TRUE;              // Don't kill the process.
+  }
+
   // Allow normal processing to take place; i.e., the process dies.
+  LeaveCriticalSection(&CriticalSection);
   return FALSE;
 }