mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-26 01:38:43 +00:00
Augment CrashRecoveryContext to have registered "cleanup" objects that can be used to release resources during a crash.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127849 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
efdc115c82
commit
a4f9839701
@ -15,6 +15,8 @@
|
|||||||
namespace llvm {
|
namespace llvm {
|
||||||
class StringRef;
|
class StringRef;
|
||||||
|
|
||||||
|
class CrashRecoveryContextCleanup;
|
||||||
|
|
||||||
/// \brief Crash recovery helper object.
|
/// \brief Crash recovery helper object.
|
||||||
///
|
///
|
||||||
/// This class implements support for running operations in a safe context so
|
/// This class implements support for running operations in a safe context so
|
||||||
@ -42,10 +44,14 @@ class StringRef;
|
|||||||
/// Crash recovery contexts may not be nested.
|
/// Crash recovery contexts may not be nested.
|
||||||
class CrashRecoveryContext {
|
class CrashRecoveryContext {
|
||||||
void *Impl;
|
void *Impl;
|
||||||
|
CrashRecoveryContextCleanup *head;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CrashRecoveryContext() : Impl(0) {}
|
CrashRecoveryContext() : Impl(0), head(0) {}
|
||||||
~CrashRecoveryContext();
|
~CrashRecoveryContext();
|
||||||
|
|
||||||
|
void registerCleanup(CrashRecoveryContextCleanup *cleanup);
|
||||||
|
void unregisterCleanup(CrashRecoveryContextCleanup *cleanup);
|
||||||
|
|
||||||
/// \brief Enable crash recovery.
|
/// \brief Enable crash recovery.
|
||||||
static void Enable();
|
static void Enable();
|
||||||
@ -87,6 +93,64 @@ public:
|
|||||||
const std::string &getBacktrace() const;
|
const std::string &getBacktrace() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CrashRecoveryContextCleanup {
|
||||||
|
public:
|
||||||
|
virtual ~CrashRecoveryContextCleanup();
|
||||||
|
virtual void recoverResources() = 0;
|
||||||
|
|
||||||
|
template <typename T> static CrashRecoveryContextCleanup *create(T *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class CrashRecoveryContext;
|
||||||
|
CrashRecoveryContextCleanup *prev, *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class CrashRecoveryContextDestructorCleanup
|
||||||
|
: public CrashRecoveryContextCleanup
|
||||||
|
{
|
||||||
|
T *resource;
|
||||||
|
public:
|
||||||
|
CrashRecoveryContextDestructorCleanup(T *resource) : resource(resource) {}
|
||||||
|
virtual void recoverResources() {
|
||||||
|
resource->~T();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct CrashRecoveryContextTrait {
|
||||||
|
static inline CrashRecoveryContextCleanup *createCleanup(T *resource) {
|
||||||
|
return new CrashRecoveryContextDestructorCleanup<T>(resource);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline CrashRecoveryContextCleanup* CrashRecoveryContextCleanup::create(T *x) {
|
||||||
|
return CrashRecoveryContext::GetCurrent() ?
|
||||||
|
CrashRecoveryContextTrait<T>::createCleanup(x) :
|
||||||
|
0;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CrashRecoveryContextCleanupRegistrar {
|
||||||
|
CrashRecoveryContext *context;
|
||||||
|
CrashRecoveryContextCleanup *cleanup;
|
||||||
|
public:
|
||||||
|
CrashRecoveryContextCleanupRegistrar(CrashRecoveryContextCleanup *cleanup)
|
||||||
|
: context(CrashRecoveryContext::GetCurrent()),
|
||||||
|
cleanup(cleanup)
|
||||||
|
{
|
||||||
|
if (context && cleanup)
|
||||||
|
context->registerCleanup(cleanup);
|
||||||
|
}
|
||||||
|
~CrashRecoveryContextCleanupRegistrar() {
|
||||||
|
if (cleanup) {
|
||||||
|
if (context)
|
||||||
|
context->unregisterCleanup(cleanup);
|
||||||
|
else
|
||||||
|
delete cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -57,7 +57,18 @@ public:
|
|||||||
static sys::Mutex gCrashRecoveryContexMutex;
|
static sys::Mutex gCrashRecoveryContexMutex;
|
||||||
static bool gCrashRecoveryEnabled = false;
|
static bool gCrashRecoveryEnabled = false;
|
||||||
|
|
||||||
|
CrashRecoveryContextCleanup::~CrashRecoveryContextCleanup() {}
|
||||||
|
|
||||||
CrashRecoveryContext::~CrashRecoveryContext() {
|
CrashRecoveryContext::~CrashRecoveryContext() {
|
||||||
|
// Reclaim registered resources.
|
||||||
|
CrashRecoveryContextCleanup *i = head;
|
||||||
|
while (i) {
|
||||||
|
CrashRecoveryContextCleanup *tmp = i;
|
||||||
|
i = tmp->next;
|
||||||
|
tmp->recoverResources();
|
||||||
|
delete tmp;
|
||||||
|
}
|
||||||
|
|
||||||
CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl;
|
CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl;
|
||||||
delete CRCI;
|
delete CRCI;
|
||||||
}
|
}
|
||||||
@ -70,6 +81,33 @@ CrashRecoveryContext *CrashRecoveryContext::GetCurrent() {
|
|||||||
return CRCI->CRC;
|
return CRCI->CRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CrashRecoveryContext::registerCleanup(CrashRecoveryContextCleanup *cleanup)
|
||||||
|
{
|
||||||
|
if (!cleanup)
|
||||||
|
return;
|
||||||
|
if (head)
|
||||||
|
head->prev = cleanup;
|
||||||
|
cleanup->next = head;
|
||||||
|
head = cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CrashRecoveryContext::unregisterCleanup(CrashRecoveryContextCleanup *cleanup) {
|
||||||
|
if (!cleanup)
|
||||||
|
return;
|
||||||
|
if (cleanup == head) {
|
||||||
|
head = cleanup->next;
|
||||||
|
if (head)
|
||||||
|
head->prev = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cleanup->prev->next = cleanup->next;
|
||||||
|
if (cleanup->next)
|
||||||
|
cleanup->next->prev = cleanup->prev;
|
||||||
|
}
|
||||||
|
delete cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef LLVM_ON_WIN32
|
#ifdef LLVM_ON_WIN32
|
||||||
|
|
||||||
// FIXME: No real Win32 implementation currently.
|
// FIXME: No real Win32 implementation currently.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user