aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2011-03-19 00:59:37 +0000
committerTed Kremenek <kremenek@apple.com>2011-03-19 00:59:37 +0000
commit1a06d5721acb9a2b69217fc8872ed5b14a482104 (patch)
treea4ec4fdd2cc829ea5a1d7649142f628bed0b6664
parentfb200e30a48c3e682742174453d9550d1dc589d5 (diff)
Tweak CrashRecoveryContextCleanup to provide an easy method for clients to select between 'delete' and 'destructor' cleanups, and allow the destructor of CrashRecoveryContextCleanupRegister to be pseudo re-entrant.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127929 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Support/CrashRecoveryContext.h28
-rw-r--r--lib/Support/CrashRecoveryContext.cpp1
2 files changed, 23 insertions, 6 deletions
diff --git a/include/llvm/Support/CrashRecoveryContext.h b/include/llvm/Support/CrashRecoveryContext.h
index 40b5286d90..6e975fe3a1 100644
--- a/include/llvm/Support/CrashRecoveryContext.h
+++ b/include/llvm/Support/CrashRecoveryContext.h
@@ -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
diff --git a/lib/Support/CrashRecoveryContext.cpp b/lib/Support/CrashRecoveryContext.cpp
index d4e21a3a82..e558662611 100644
--- a/lib/Support/CrashRecoveryContext.cpp
+++ b/lib/Support/CrashRecoveryContext.cpp
@@ -65,6 +65,7 @@ CrashRecoveryContext::~CrashRecoveryContext() {
while (i) {
CrashRecoveryContextCleanup *tmp = i;
i = tmp->next;
+ tmp->cleanupFired = true;
tmp->recoverResources();
delete tmp;
}