Index: tests/LazyPtrTest.cpp |
diff --git a/tests/LazyPtrTest.cpp b/tests/LazyPtrTest.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c6ffd72e2547385abc6fcf3b061dc3bb70e45f26 |
--- /dev/null |
+++ b/tests/LazyPtrTest.cpp |
@@ -0,0 +1,70 @@ |
+/* |
+ * Copyright 2014 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#include "Test.h" |
+#include "SkLazyPtr.h" |
+#include "SkRunnable.h" |
+#include "SkTaskGroup.h" |
+ |
+namespace { |
+ |
+struct CreateIntFromFloat { |
+ CreateIntFromFloat(float val) : fVal(val) {} |
+ int* operator()() const { return new int((int)fVal); } |
+ float fVal; |
+}; |
+ |
+// As a template argument this must have external linkage. |
+void custom_destroy(int* ptr) { *ptr = 99; } |
+ |
+} // namespace |
+ |
+DEF_TEST(LazyPtr, r) { |
+ // Basic usage: calls new int. |
+ SkLazyPtr<int> lazy; |
+ int* ptr = lazy.get(); |
+ REPORTER_ASSERT(r, ptr); |
+ REPORTER_ASSERT(r, lazy.get() == ptr); |
+ |
+ // Advanced usage: calls a functor. |
+ SkLazyPtr<int> lazyFunctor; |
+ int* six = lazyFunctor.get(CreateIntFromFloat(6.4f)); |
+ REPORTER_ASSERT(r, six); |
+ REPORTER_ASSERT(r, 6 == *six); |
+ |
+ // Just makes sure this is safe. |
+ SkLazyPtr<double> neverRead; |
+ |
+ // SkLazyPtr supports custom destroy methods. |
+ { |
+ SkLazyPtr<int, custom_destroy> customDestroy; |
+ ptr = customDestroy.get(); |
+ // custom_destroy called here. |
+ } |
+ REPORTER_ASSERT(r, ptr); |
+ REPORTER_ASSERT(r, 99 == *ptr); |
+ // Since custom_destroy didn't actually delete ptr, we do now. |
+ delete ptr; |
+} |
+ |
+DEF_TEST(LazyPtr_Threaded, r) { |
+ static const int kRacers = 321; |
+ |
+ // Race to intialize the pointer by calling .get(). |
+ SkLazyPtr<int> lazy; |
+ int* seen[kRacers]; |
+ |
+ sk_parallel_for(kRacers, [&](int i) { |
+ seen[i] = lazy.get(); |
+ }); |
+ |
+ // lazy.get() should return the same pointer to all threads. |
+ for (int i = 1; i < kRacers; i++) { |
+ REPORTER_ASSERT(r, seen[i] != nullptr); |
+ REPORTER_ASSERT(r, seen[i] == seen[0]); |
+ } |
+} |