Tweak CrashRecoveryContextCleanup to provide an easy method for clients to select...
authorTed Kremenek <kremenek@apple.com>
Sat, 19 Mar 2011 00:59:37 +0000 (00:59 +0000)
committerTed Kremenek <kremenek@apple.com>
Sat, 19 Mar 2011 00:59:37 +0000 (00:59 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127929 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Support/CrashRecoveryContext.h
lib/Support/CrashRecoveryContext.cpp

index 40b5286d901d651ac6433396f35fff4da1169566..6e975fe3a1cc6dd9cc56bc15953c71f6ab172d8c 100644 (file)
@@ -95,10 +95,16 @@ public:
 
 class CrashRecoveryContextCleanup {
 public:
+  bool cleanupFired;
+  enum ProvidedCleanups { DeleteCleanup, DestructorCleanup };
+  
+  CrashRecoveryContextCleanup() : cleanupFired(false) {}
   virtual ~CrashRecoveryContextCleanup();
   virtual void recoverResources() = 0;
   
-  template <typename T> static CrashRecoveryContextCleanup *create(T *);
+  template <typename T> static CrashRecoveryContextCleanup *create(T *,
+                          ProvidedCleanups cleanupKind =
+                            CrashRecoveryContextCleanup::DeleteCleanup);
   
 private:
   friend class CrashRecoveryContext;
@@ -131,15 +137,25 @@ public:
 
 template <typename T>
 struct CrashRecoveryContextTrait {
-  static inline CrashRecoveryContextCleanup *createCleanup(T *resource) {
-    return new CrashRecoveryContextDeleteCleanup<T>(resource);
+  static inline CrashRecoveryContextCleanup *
+  createCleanup(T *resource,
+                CrashRecoveryContextCleanup::ProvidedCleanups cleanup) {
+    switch (cleanup) {
+      case CrashRecoveryContextCleanup::DeleteCleanup:
+        return new CrashRecoveryContextDeleteCleanup<T>(resource);
+      case CrashRecoveryContextCleanup::DestructorCleanup:
+        return new CrashRecoveryContextDestructorCleanup<T>(resource);
+    }
+    return 0;
   }
 };
 
 template<typename T>
-inline CrashRecoveryContextCleanup* CrashRecoveryContextCleanup::create(T *x) {
+inline CrashRecoveryContextCleanup*
+CrashRecoveryContextCleanup::create(T *x,
+          CrashRecoveryContextCleanup::ProvidedCleanups cleanupKind) {
   return CrashRecoveryContext::GetCurrent() ?
-          CrashRecoveryContextTrait<T>::createCleanup(x) : 
+          CrashRecoveryContextTrait<T>::createCleanup(x, cleanupKind) : 
           0;
 }
 
@@ -155,7 +171,7 @@ public:
       context->registerCleanup(cleanup);
   }
   ~CrashRecoveryContextCleanupRegistrar() {
-    if (cleanup) {
+    if (cleanup && !cleanup->cleanupFired) {
       if (context)
         context->unregisterCleanup(cleanup);
       else
index d4e21a3a82672b82175ad91fad1b89a246079b03..e558662611f66e17023fd0146746b3aced413b4b 100644 (file)
@@ -65,6 +65,7 @@ CrashRecoveryContext::~CrashRecoveryContext() {
   while (i) {
     CrashRecoveryContextCleanup *tmp = i;
     i = tmp->next;
+    tmp->cleanupFired = true;
     tmp->recoverResources();
     delete tmp;
   }