/* * 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 SkNEW_ARGS(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 SkNEW(int). SkLazyPtr lazy; int* ptr = lazy.get(); REPORTER_ASSERT(r, ptr); REPORTER_ASSERT(r, lazy.get() == ptr); // Advanced usage: calls a functor. SkLazyPtr lazyFunctor; int* six = lazyFunctor.get(CreateIntFromFloat(6.4f)); REPORTER_ASSERT(r, six); REPORTER_ASSERT(r, 6 == *six); // Just makes sure this is safe. SkLazyPtr neverRead; // SkLazyPtr supports custom destroy methods. { SkLazyPtr 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. SkDELETE(ptr); } DEF_TEST(LazyPtr_Threaded, r) { static const int kRacers = 321; // Race to intialize the pointer by calling .get(). SkLazyPtr 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]); } }