X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FSupport%2FCrashRecoveryContext.h;h=4c0a5e26f00f0e80fe7d043238eead8f79457cb8;hb=2fa8af224ea026f9432e833fd6f42a216423a010;hp=51752706d0e15f339c8de9729718f4218b5d4227;hpb=a4f983970133c934d6af66dc8dc50fbf908c31dd;p=oota-llvm.git diff --git a/include/llvm/Support/CrashRecoveryContext.h b/include/llvm/Support/CrashRecoveryContext.h index 51752706d0e..4c0a5e26f00 100644 --- a/include/llvm/Support/CrashRecoveryContext.h +++ b/include/llvm/Support/CrashRecoveryContext.h @@ -63,6 +63,10 @@ public: /// thread which is in a protected context. static CrashRecoveryContext *GetCurrent(); + /// \brief Return true if the current thread is recovering from a + /// crash. + static bool isRecoveringFromCrash(); + /// \brief Execute the provide callback function (with the given arguments) in /// a protected context. /// @@ -94,61 +98,101 @@ public: }; class CrashRecoveryContextCleanup { +protected: + CrashRecoveryContext *context; + CrashRecoveryContextCleanup(CrashRecoveryContext *context) + : context(context), cleanupFired(false) {} public: + bool cleanupFired; + virtual ~CrashRecoveryContextCleanup(); virtual void recoverResources() = 0; - - template static CrashRecoveryContextCleanup *create(T *); - + + CrashRecoveryContext *getContext() const { + return context; + } + private: friend class CrashRecoveryContext; CrashRecoveryContextCleanup *prev, *next; }; -template -class CrashRecoveryContextDestructorCleanup - : public CrashRecoveryContextCleanup -{ +template +class CrashRecoveryContextCleanupBase : public CrashRecoveryContextCleanup { +protected: T *resource; + CrashRecoveryContextCleanupBase(CrashRecoveryContext *context, T* resource) + : CrashRecoveryContextCleanup(context), resource(resource) {} public: - CrashRecoveryContextDestructorCleanup(T *resource) : resource(resource) {} - virtual void recoverResources() { - resource->~T(); + static DERIVED *create(T *x) { + if (x) { + if (CrashRecoveryContext *context = CrashRecoveryContext::GetCurrent()) + return new DERIVED(context, x); + } + return 0; } }; - + template -struct CrashRecoveryContextTrait { - static inline CrashRecoveryContextCleanup *createCleanup(T *resource) { - return new CrashRecoveryContextDestructorCleanup(resource); +class CrashRecoveryContextDestructorCleanup : public + CrashRecoveryContextCleanupBase, T> { +public: + CrashRecoveryContextDestructorCleanup(CrashRecoveryContext *context, + T *resource) + : CrashRecoveryContextCleanupBase< + CrashRecoveryContextDestructorCleanup, T>(context, resource) {} + + virtual void recoverResources() { + this->resource->~T(); } }; -template -inline CrashRecoveryContextCleanup* CrashRecoveryContextCleanup::create(T *x) { - return CrashRecoveryContext::GetCurrent() ? - CrashRecoveryContextTrait::createCleanup(x) : - 0; -} +template +class CrashRecoveryContextDeleteCleanup : public + CrashRecoveryContextCleanupBase, T> { +public: + CrashRecoveryContextDeleteCleanup(CrashRecoveryContext *context, T *resource) + : CrashRecoveryContextCleanupBase< + CrashRecoveryContextDeleteCleanup, T>(context, resource) {} + + virtual void recoverResources() { + delete this->resource; + } +}; + +template +class CrashRecoveryContextReleaseRefCleanup : public + CrashRecoveryContextCleanupBase, T> +{ +public: + CrashRecoveryContextReleaseRefCleanup(CrashRecoveryContext *context, + T *resource) + : CrashRecoveryContextCleanupBase, + T>(context, resource) {} + virtual void recoverResources() { + this->resource->Release(); + } +}; + +template > class CrashRecoveryContextCleanupRegistrar { - CrashRecoveryContext *context; CrashRecoveryContextCleanup *cleanup; public: - CrashRecoveryContextCleanupRegistrar(CrashRecoveryContextCleanup *cleanup) - : context(CrashRecoveryContext::GetCurrent()), - cleanup(cleanup) - { - if (context && cleanup) - context->registerCleanup(cleanup); + CrashRecoveryContextCleanupRegistrar(T *x) + : cleanup(Cleanup::create(x)) { + if (cleanup) + cleanup->getContext()->registerCleanup(cleanup); } + ~CrashRecoveryContextCleanupRegistrar() { - if (cleanup) { - if (context) - context->unregisterCleanup(cleanup); - else - delete cleanup; - } + unregister(); + } + + void unregister() { + if (cleanup && !cleanup->cleanupFired) + cleanup->getContext()->unregisterCleanup(cleanup); + cleanup = 0; } }; }