llvm.org GIT mirror llvm / 1a06d57
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 Ted Kremenek 9 years ago
2 changed file(s) with 23 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
9494
9595 class CrashRecoveryContextCleanup {
9696 public:
97 bool cleanupFired;
98 enum ProvidedCleanups { DeleteCleanup, DestructorCleanup };
99
100 CrashRecoveryContextCleanup() : cleanupFired(false) {}
97101 virtual ~CrashRecoveryContextCleanup();
98102 virtual void recoverResources() = 0;
99103
100 template static CrashRecoveryContextCleanup *create(T *);
104 template static CrashRecoveryContextCleanup *create(T *,
105 ProvidedCleanups cleanupKind =
106 CrashRecoveryContextCleanup::DeleteCleanup);
101107
102108 private:
103109 friend class CrashRecoveryContext;
130136
131137 template
132138 struct CrashRecoveryContextTrait {
133 static inline CrashRecoveryContextCleanup *createCleanup(T *resource) {
134 return new CrashRecoveryContextDeleteCleanup(resource);
139 static inline CrashRecoveryContextCleanup *
140 createCleanup(T *resource,
141 CrashRecoveryContextCleanup::ProvidedCleanups cleanup) {
142 switch (cleanup) {
143 case CrashRecoveryContextCleanup::DeleteCleanup:
144 return new CrashRecoveryContextDeleteCleanup(resource);
145 case CrashRecoveryContextCleanup::DestructorCleanup:
146 return new CrashRecoveryContextDestructorCleanup(resource);
147 }
148 return 0;
135149 }
136150 };
137151
138152 template
139 inline CrashRecoveryContextCleanup* CrashRecoveryContextCleanup::create(T *x) {
153 inline CrashRecoveryContextCleanup*
154 CrashRecoveryContextCleanup::create(T *x,
155 CrashRecoveryContextCleanup::ProvidedCleanups cleanupKind) {
140156 return CrashRecoveryContext::GetCurrent() ?
141 CrashRecoveryContextTrait::createCleanup(x) :
157 CrashRecoveryContextTrait::createCleanup(x, cleanupKind) :
142158 0;
143159 }
144160
154170 context->registerCleanup(cleanup);
155171 }
156172 ~CrashRecoveryContextCleanupRegistrar() {
157 if (cleanup) {
173 if (cleanup && !cleanup->cleanupFired) {
158174 if (context)
159175 context->unregisterCleanup(cleanup);
160176 else
6464 while (i) {
6565 CrashRecoveryContextCleanup *tmp = i;
6666 i = tmp->next;
67 tmp->cleanupFired = true;
6768 tmp->recoverResources();
6869 delete tmp;
6970 }