SkLazyPtr, mk. 2

SK_DECLARE_STATIC_LAZY_PTR and
SK_DECLARE_STATIC_LAZY_PTR_ARRAY let you declare a single or
array of static pointers that are lazily initialized.

You can think of this as a restricted, lighter-weight
version of SkOnce.  There's no guarantee that Create will be
called exactly once, but we do guarantee all threads will
agree on the resulting pointer.

We'll clean up any other extra pointers we Create()ed by
calling Destroy(), which defaults to SkDELETE.  In debug
mode, we also clean up the winning pointer at process exit,
so we can make sure we didn't leak it or free it early.

I've ported SkData (singleton) and SkXfermode (array) as
examples.  Once this lands I'll port most other users of
SkOnce.

BUG=skia:
R=bungeman@google.com, mtklein@google.com, reed@google.com

Author: mtklein@chromium.org

Review URL: https://codereview.chromium.org/306943003

git-svn-id: http://skia.googlecode.com/svn/trunk@14976 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkData.cpp b/src/core/SkData.cpp
index 2f07914..c653287 100644
--- a/src/core/SkData.cpp
+++ b/src/core/SkData.cpp
@@ -6,10 +6,10 @@
  */
 
 #include "SkData.h"
+#include "SkLazyPtr.h"
+#include "SkOSFile.h"
 #include "SkReadBuffer.h"
 #include "SkWriteBuffer.h"
-#include "SkOSFile.h"
-#include "SkOnce.h"
 
 SkData::SkData(const void* ptr, size_t size, ReleaseProc proc, void* context) {
     fPtr = ptr;
@@ -49,18 +49,14 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static SkData* gEmptyDataRef = NULL;
-static void cleanup_gEmptyDataRef() { gEmptyDataRef->unref(); }
-
-void SkData::NewEmptyImpl(int) {
-    gEmptyDataRef = new SkData(NULL, 0, NULL, NULL);
+SkData* SkData::NewEmptyImpl() {
+    return new SkData(NULL, 0, NULL, NULL);
 }
+void SkData::DeleteEmpty(SkData* ptr) { SkDELETE(ptr); }
 
 SkData* SkData::NewEmpty() {
-    SK_DECLARE_STATIC_ONCE(once);
-    SkOnce(&once, SkData::NewEmptyImpl, 0, cleanup_gEmptyDataRef);
-    gEmptyDataRef->ref();
-    return gEmptyDataRef;
+    SK_DECLARE_STATIC_LAZY_PTR(SkData, empty, NewEmptyImpl, DeleteEmpty);
+    return SkRef(empty.get());
 }
 
 // assumes fPtr was allocated via sk_malloc