summaryrefslogtreecommitdiff
path: root/include/llvm/Support/CrashRecoveryContext.h
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 /include/llvm/Support/CrashRecoveryContext.h
parentfb200e30a48c3e682742174453d9550d1dc589d5 (diff)
downloadllvm-1a06d5721acb9a2b69217fc8872ed5b14a482104.tar.gz
llvm-1a06d5721acb9a2b69217fc8872ed5b14a482104.tar.bz2
llvm-1a06d5721acb9a2b69217fc8872ed5b14a482104.tar.xz
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
Diffstat (limited to 'include/llvm/Support/CrashRecoveryContext.h')
-rw-r--r--include/llvm/Support/CrashRecoveryContext.h28
1 files changed, 22 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