llvm.org GIT mirror llvm / afc9e06
Rework CrashRecoveryContextCleanup to provide a simpler way to create cleanup objects, and provide a new cleanup for decrementing reference counts of objects with intrusive reference counts. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128055 91177308-0d34-0410-b5e6-96231b3b80d8 Ted Kremenek 9 years ago
1 changed file(s) with 67 addition(s) and 59 deletion(s). Raw diff Collapse all Expand all
9797 };
9898
9999 class CrashRecoveryContextCleanup {
100 protected:
101 CrashRecoveryContext *context;
102 CrashRecoveryContextCleanup(CrashRecoveryContext *context)
103 : context(context) {}
100104 public:
101105 bool cleanupFired;
102 enum ProvidedCleanups { DeleteCleanup, DestructorCleanup };
103106
104107 CrashRecoveryContextCleanup() : cleanupFired(false) {}
105108 virtual ~CrashRecoveryContextCleanup();
106109 virtual void recoverResources() = 0;
107
108 template static CrashRecoveryContextCleanup *create(T *,
109 ProvidedCleanups cleanupKind =
110 CrashRecoveryContextCleanup::DeleteCleanup);
111
110
111 CrashRecoveryContext *getContext() const {
112 return context;
113 }
114
112115 private:
113116 friend class CrashRecoveryContext;
114117 CrashRecoveryContextCleanup *prev, *next;
115118 };
116119
117 template
118 class CrashRecoveryContextDestructorCleanup
119 : public CrashRecoveryContextCleanup
120 {
120 template
121 class CrashRecoveryContextCleanupBase : public CrashRecoveryContextCleanup {
122 protected:
121123 T *resource;
124 CrashRecoveryContextCleanupBase(CrashRecoveryContext *context, T* resource)
125 : CrashRecoveryContextCleanup(context), resource(resource) {}
122126 public:
123 CrashRecoveryContextDestructorCleanup(T *resource) : resource(resource) {}
124 virtual void recoverResources() {
125 resource->~T();
126 }
127 };
128
129 template
130 class CrashRecoveryContextDeleteCleanup
131 : public CrashRecoveryContextCleanup
132 {
133 T *resource;
134 public:
135 CrashRecoveryContextDeleteCleanup(T *resource) : resource(resource) {}
136 virtual void recoverResources() {
137 delete resource;
138 }
139 };
140
141 template
142 struct CrashRecoveryContextTrait {
143 static inline CrashRecoveryContextCleanup *
144 createCleanup(T *resource,
145 CrashRecoveryContextCleanup::ProvidedCleanups cleanup) {
146 switch (cleanup) {
147 case CrashRecoveryContextCleanup::DeleteCleanup:
148 return new CrashRecoveryContextDeleteCleanup(resource);
149 case CrashRecoveryContextCleanup::DestructorCleanup:
150 return new CrashRecoveryContextDestructorCleanup(resource);
127 static DERIVED *create(T *x) {
128 if (x) {
129 if (CrashRecoveryContext *context = CrashRecoveryContext::GetCurrent())
130 return new DERIVED(context, x);
151131 }
152132 return 0;
153133 }
154134 };
155135
156 template
157 inline CrashRecoveryContextCleanup*
158 CrashRecoveryContextCleanup::create(T *x,
159 CrashRecoveryContextCleanup::ProvidedCleanups cleanupKind) {
160 return CrashRecoveryContext::GetCurrent() ?
161 CrashRecoveryContextTrait::createCleanup(x, cleanupKind) :
162 0;
163 }
136 template
137 class CrashRecoveryContextDestructorCleanup : public
138 CrashRecoveryContextCleanupBase, T> {
139 public:
140 CrashRecoveryContextDestructorCleanup(CrashRecoveryContext *context,
141 T *resource)
142 : CrashRecoveryContextCleanupBase<
143 CrashRecoveryContextDestructorCleanup, T>(context, resource) {}
164144
145 virtual void recoverResources() {
146 this->resource->~T();
147 }
148 };
149
150 template
151 class CrashRecoveryContextDeleteCleanup : public
152 CrashRecoveryContextCleanupBase, T> {
153 public:
154 CrashRecoveryContextDeleteCleanup(CrashRecoveryContext *context, T *resource)
155 : CrashRecoveryContextCleanupBase<
156 CrashRecoveryContextDeleteCleanup, T>(context, resource) {}
157
158 virtual void recoverResources() {
159 delete this->resource;
160 }
161 };
162
163 template
164 class CrashRecoveryContextReleaseRefCleanup : public
165 CrashRecoveryContextCleanupBase, T>
166 {
167 public:
168 CrashRecoveryContextReleaseRefCleanup(CrashRecoveryContext *context,
169 T *resource)
170 : CrashRecoveryContextCleanupBase,
171 T>(context, resource) {}
172
173 virtual void recoverResources() {
174 this->resource->Release();
175 }
176 };
177
178 template >
165179 class CrashRecoveryContextCleanupRegistrar {
166 CrashRecoveryContext *context;
167180 CrashRecoveryContextCleanup *cleanup;
168181 public:
169 CrashRecoveryContextCleanupRegistrar(CrashRecoveryContextCleanup *cleanup)
170 : context(CrashRecoveryContext::GetCurrent()),
171 cleanup(cleanup)
172 {
173 if (context && cleanup)
174 context->registerCleanup(cleanup);
182 CrashRecoveryContextCleanupRegistrar(T *x)
183 : cleanup(Cleanup::create(x)) {
184 if (cleanup)
185 cleanup->getContext()->registerCleanup(cleanup);
175186 }
187
176188 ~CrashRecoveryContextCleanupRegistrar() {
177 if (cleanup && !cleanup->cleanupFired) {
178 if (context)
179 context->unregisterCleanup(cleanup);
180 else
181 delete cleanup;
182 }
189 if (cleanup && !cleanup->cleanupFired)
190 cleanup->getContext()->unregisterCleanup(cleanup);
183191 }
184192 };
185193 }