llvm.org GIT mirror llvm / 6e5887e
Remove dependence on std::function. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202902 91177308-0d34-0410-b5e6-96231b3b80d8 Richard Smith 6 years ago
2 changed file(s) with 28 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
99 #ifndef LLVM_SUPPORT_CRASHRECOVERYCONTEXT_H
1010 #define LLVM_SUPPORT_CRASHRECOVERYCONTEXT_H
1111
12 #include
1312 #include
1413
1514 namespace llvm {
4544 class CrashRecoveryContext {
4645 void *Impl;
4746 CrashRecoveryContextCleanup *head;
47
48 /// An adaptor to convert an arbitrary functor into a void(void*), void* pair.
49 template struct FunctorAdaptor {
50 T Fn;
51 static void invoke(void *Data) {
52 return static_cast*>(Data)->Fn();
53 }
54 typedef void Callback(void*);
55 Callback *fn() { return &invoke; }
56 void *arg() { return this; }
57 };
4858
4959 public:
5060 CrashRecoveryContext() : Impl(0), head(0) {}
7585 /// make as little assumptions as possible about the program state when
7686 /// RunSafely has returned false. Clients can use getBacktrace() to retrieve
7787 /// the backtrace of the crash on failures.
78 bool RunSafely(std::function Fn);
7988 bool RunSafely(void (*Fn)(void*), void *UserData);
89 template
90 bool RunSafely(Functor Fn) {
91 FunctorAdaptor Adaptor = { Fn };
92 return RunSafely(Adaptor.fn(), Adaptor.arg());
93 }
8094
8195 /// \brief Execute the provide callback function (with the given arguments) in
8296 /// a protected context which is run in another thread (optionally with a
8599 /// See RunSafely() and llvm_execute_on_thread().
86100 bool RunSafelyOnThread(void (*Fn)(void*), void *UserData,
87101 unsigned RequestedStackSize = 0);
88 bool RunSafelyOnThread(std::function Fn,
89 unsigned RequestedStackSize = 0);
102 template
103 bool RunSafelyOnThread(Functor Fn, unsigned RequestedStackSize = 0) {
104 FunctorAdaptor Adaptor = { Fn };
105 return RunSafelyOnThread(Adaptor.fn(), Adaptor.arg(), RequestedStackSize);
106 }
90107
91108 /// \brief Explicitly trigger a crash recovery in the current process, and
92109 /// return failure from RunSafely(). This function does not return.
301301 #endif
302302
303303 bool CrashRecoveryContext::RunSafely(void (*Fn)(void*), void *UserData) {
304 return RunSafely([&]() { Fn(UserData); });
305 }
306
307 bool CrashRecoveryContext::RunSafely(std::function Fn) {
308304 // If crash recovery is disabled, do nothing.
309305 if (gCrashRecoveryEnabled) {
310306 assert(!Impl && "Crash recovery context already initialized!");
316312 }
317313 }
318314
319 Fn();
315 Fn(UserData);
320316 return true;
321317 }
322318
335331
336332 //
337333
338 bool CrashRecoveryContext::RunSafelyOnThread(void (*Fn)(void*), void *UserData,
339 unsigned RequestedStackSize) {
340 return RunSafelyOnThread([&]() { Fn(UserData); }, RequestedStackSize);
341 }
342
343334 namespace {
344335 struct RunSafelyOnThreadInfo {
345 std::function Fn;
336 void (*Fn)(void*);
337 void *Data;
346338 CrashRecoveryContext *CRC;
347339 bool Result;
348340 };
351343 static void RunSafelyOnThread_Dispatch(void *UserData) {
352344 RunSafelyOnThreadInfo *Info =
353345 reinterpret_cast(UserData);
354 Info->Result = Info->CRC->RunSafely(Info->Fn);
355 }
356
357 bool CrashRecoveryContext::RunSafelyOnThread(std::function Fn,
346 Info->Result = Info->CRC->RunSafely(Info->Fn, Info->Data);
347 }
348 bool CrashRecoveryContext::RunSafelyOnThread(void (*Fn)(void*), void *UserData,
358349 unsigned RequestedStackSize) {
359 RunSafelyOnThreadInfo Info = { Fn, this, false };
350 RunSafelyOnThreadInfo Info = { Fn, UserData, this, false };
360351 llvm_execute_on_thread(RunSafelyOnThread_Dispatch, &Info, RequestedStackSize);
361352 if (CrashRecoveryContextImpl *CRC = (CrashRecoveryContextImpl *)Impl)
362353 CRC->setSwitchedThread();