gfx/skia/trunk/src/core/SkTLS.cpp

branch
TOR_BUG_9701
changeset 11
deefc01c0e14
equal deleted inserted replaced
-1:000000000000 0:997ab5bcfac6
1 #include "SkTLS.h"
2
3 // enable to help debug TLS storage
4 //#define SK_TRACE_TLS_LIFETIME
5
6
7 #ifdef SK_TRACE_TLS_LIFETIME
8 #include "SkThread.h"
9 static int32_t gTLSRecCount;
10 #endif
11
12 struct SkTLSRec {
13 SkTLSRec* fNext;
14 void* fData;
15 SkTLS::CreateProc fCreateProc;
16 SkTLS::DeleteProc fDeleteProc;
17
18 #ifdef SK_TRACE_TLS_LIFETIME
19 SkTLSRec() {
20 int n = sk_atomic_inc(&gTLSRecCount);
21 SkDebugf(" SkTLSRec[%d]\n", n);
22 }
23 #endif
24
25 ~SkTLSRec() {
26 if (fDeleteProc) {
27 fDeleteProc(fData);
28 }
29 // else we leak fData, or it will be managed by the caller
30
31 #ifdef SK_TRACE_TLS_LIFETIME
32 int n = sk_atomic_dec(&gTLSRecCount);
33 SkDebugf("~SkTLSRec[%d]\n", n - 1);
34 #endif
35 }
36 };
37
38 void SkTLS::Destructor(void* ptr) {
39 #ifdef SK_TRACE_TLS_LIFETIME
40 SkDebugf("SkTLS::Destructor(%p)\n", ptr);
41 #endif
42
43 SkTLSRec* rec = (SkTLSRec*)ptr;
44 do {
45 SkTLSRec* next = rec->fNext;
46 SkDELETE(rec);
47 rec = next;
48 } while (NULL != rec);
49 }
50
51 void* SkTLS::Get(CreateProc createProc, DeleteProc deleteProc) {
52 if (NULL == createProc) {
53 return NULL;
54 }
55
56 void* ptr = SkTLS::PlatformGetSpecific(true);
57
58 if (ptr) {
59 const SkTLSRec* rec = (const SkTLSRec*)ptr;
60 do {
61 if (rec->fCreateProc == createProc) {
62 SkASSERT(rec->fDeleteProc == deleteProc);
63 return rec->fData;
64 }
65 } while ((rec = rec->fNext) != NULL);
66 // not found, so create a new one
67 }
68
69 // add a new head of our change
70 SkTLSRec* rec = new SkTLSRec;
71 rec->fNext = (SkTLSRec*)ptr;
72
73 SkTLS::PlatformSetSpecific(rec);
74
75 rec->fData = createProc();
76 rec->fCreateProc = createProc;
77 rec->fDeleteProc = deleteProc;
78 return rec->fData;
79 }
80
81 void* SkTLS::Find(CreateProc createProc) {
82 if (NULL == createProc) {
83 return NULL;
84 }
85
86 void* ptr = SkTLS::PlatformGetSpecific(false);
87
88 if (ptr) {
89 const SkTLSRec* rec = (const SkTLSRec*)ptr;
90 do {
91 if (rec->fCreateProc == createProc) {
92 return rec->fData;
93 }
94 } while ((rec = rec->fNext) != NULL);
95 }
96 return NULL;
97 }
98
99 void SkTLS::Delete(CreateProc createProc) {
100 if (NULL == createProc) {
101 return;
102 }
103
104 void* ptr = SkTLS::PlatformGetSpecific(false);
105
106 SkTLSRec* curr = (SkTLSRec*)ptr;
107 SkTLSRec* prev = NULL;
108 while (curr) {
109 SkTLSRec* next = curr->fNext;
110 if (curr->fCreateProc == createProc) {
111 if (prev) {
112 prev->fNext = next;
113 } else {
114 // we have a new head of our chain
115 SkTLS::PlatformSetSpecific(next);
116 }
117 SkDELETE(curr);
118 break;
119 }
120 prev = curr;
121 curr = next;
122 }
123 }

mercurial