Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Unified Diff: include/core/SkOnce.h

Issue 132803005: SkOnce: add option to call another cleanup function once at exit. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: add static Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « include/core/SkData.h ('k') | include/core/SkPathRef.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « include/core/SkData.h ('k') | include/core/SkPathRef.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698