blob: 1b845bc502777c361782694ba4ed539acad44b83 [file] [log] [blame]
mtkleine9e0dea2014-10-21 12:20:04 -07001#include "Test.h"
2#include "SkLazyPtr.h"
reed89889b62014-10-29 12:36:45 -07003#include "SkRunnable.h"
mtkleine9e0dea2014-10-21 12:20:04 -07004#include "SkTaskGroup.h"
5
6namespace {
7
8struct CreateIntFromFloat {
9 CreateIntFromFloat(float val) : fVal(val) {}
10 int* operator()() const { return SkNEW_ARGS(int, ((int)fVal)); }
11 float fVal;
12};
13
14// As a template argument this must have external linkage.
15void custom_destroy(int* ptr) { *ptr = 99; }
16
17} // namespace
18
19DEF_TEST(LazyPtr, r) {
20 // Basic usage: calls SkNEW(int).
21 SkLazyPtr<int> lazy;
22 int* ptr = lazy.get();
23 REPORTER_ASSERT(r, ptr);
24 REPORTER_ASSERT(r, lazy.get() == ptr);
25
26 // Advanced usage: calls a functor.
27 SkLazyPtr<int> lazyFunctor;
28 int* six = lazyFunctor.get(CreateIntFromFloat(6.4f));
29 REPORTER_ASSERT(r, six);
30 REPORTER_ASSERT(r, 6 == *six);
31
32 // Just makes sure this is safe.
33 SkLazyPtr<double> neverRead;
34
35 // SkLazyPtr supports custom destroy methods.
36 {
37 SkLazyPtr<int, custom_destroy> customDestroy;
38 ptr = customDestroy.get();
39 // custom_destroy called here.
40 }
41 REPORTER_ASSERT(r, ptr);
42 REPORTER_ASSERT(r, 99 == *ptr);
43 // Since custom_destroy didn't actually delete ptr, we do now.
44 SkDELETE(ptr);
45}
46
47namespace {
48
49struct Racer : public SkRunnable {
50 Racer() : fLazy(NULL), fSeen(NULL) {}
51
mtklein36352bf2015-03-25 18:17:31 -070052 void run() override { fSeen = fLazy->get(); }
mtkleine9e0dea2014-10-21 12:20:04 -070053
54 SkLazyPtr<int>* fLazy;
55 int* fSeen;
56};
57
58} // namespace
59
60DEF_TEST(LazyPtr_Threaded, r) {
61 static const int kRacers = 321;
62
63 SkLazyPtr<int> lazy;
64
65 Racer racers[kRacers];
66 for (int i = 0; i < kRacers; i++) {
67 racers[i].fLazy = &lazy;
68 }
69
70 SkTaskGroup tg;
71 for (int i = 0; i < kRacers; i++) {
72 tg.add(racers + i);
73 }
74 tg.wait();
75
76 for (int i = 1; i < kRacers; i++) {
77 REPORTER_ASSERT(r, racers[i].fSeen);
78 REPORTER_ASSERT(r, racers[i].fSeen == racers[0].fSeen);
79 }
80}