| Index: include/core/SkOnce.h
|
| diff --git a/include/core/SkOnce.h b/include/core/SkOnce.h
|
| index 9c4ccd49d06ab403b1cebbc0f77e25cec4cca1c3..9663ef13bfc2af06b26484d619fccfef8c836473 100644
|
| --- a/include/core/SkOnce.h
|
| +++ b/include/core/SkOnce.h
|
| @@ -25,6 +25,8 @@
|
| // }
|
| //
|
| // OnceTest.cpp also should serve as a few other simple examples.
|
| +//
|
| +// You may optionally pass SkOnce a second function to be called at exit for cleanup.
|
|
|
| #include "SkThread.h"
|
| #include "SkTypes.h"
|
| @@ -35,7 +37,7 @@
|
| struct SkOnceFlag; // If manually created, initialize with SkOnceFlag once = SK_ONCE_INIT
|
|
|
| template <typename Func, typename Arg>
|
| -inline void SkOnce(SkOnceFlag* once, Func f, Arg arg);
|
| +inline void SkOnce(SkOnceFlag* once, Func f, Arg arg, void(*atExit)() = NULL);
|
|
|
| // ---------------------- Implementation details below here. -----------------------------
|
|
|
| @@ -92,10 +94,13 @@ inline static void acquire_barrier() {
|
| // This should be rarely called, so we separate it from SkOnce and don't mark it as inline.
|
| // (We don't mind if this is an actual function call, but odds are it'll be inlined anyway.)
|
| template <typename Func, typename Arg>
|
| -static void sk_once_slow(SkOnceFlag* once, Func f, Arg arg) {
|
| +static void sk_once_slow(SkOnceFlag* once, Func f, Arg arg, void (*atExit)()) {
|
| const SkAutoSpinlock lock(&once->lock);
|
| if (!once->done) {
|
| f(arg);
|
| + if (atExit != NULL) {
|
| + atexit(atExit);
|
| + }
|
| // Also known as a store-store/load-store barrier, this makes sure that the writes
|
| // done before here---in particular, those done by calling f(arg)---are observable
|
| // before the writes after the line, *done = true.
|
| @@ -127,10 +132,10 @@ void AnnotateBenignRace(const char* file, int line, const volatile void* mem, co
|
|
|
| // This is our fast path, called all the time. We do really want it to be inlined.
|
| template <typename Func, typename Arg>
|
| -inline void SkOnce(SkOnceFlag* once, Func f, Arg arg) {
|
| +inline void SkOnce(SkOnceFlag* once, Func f, Arg arg, void(*atExit)()) {
|
| SK_ANNOTATE_BENIGN_RACE(&(once->done), "Don't worry TSAN, we're sure this is safe.");
|
| if (!once->done) {
|
| - sk_once_slow(once, f, arg);
|
| + sk_once_slow(once, f, arg, atExit);
|
| }
|
| // Also known as a load-load/load-store barrier, this acquire barrier makes
|
| // sure that anything we read from memory---in particular, memory written by
|
|
|