add SkTLS::Delete
git-svn-id: http://skia.googlecode.com/svn/trunk@3752 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
098370137f
commit
ae1b6b61ce
@ -11,19 +11,14 @@
|
||||
|
||||
#include "SkTypes.h"
|
||||
|
||||
/**
|
||||
* Maintains a per-thread cache, using a CreateProc as the key into that cache.
|
||||
*/
|
||||
class SkTLS {
|
||||
public:
|
||||
typedef void* (*CreateProc)();
|
||||
typedef void (*DeleteProc)(void*);
|
||||
|
||||
/**
|
||||
* Create proc is called once per thread, and its return value is cached
|
||||
* and returned by this call, treating the proc as a key. When this thread
|
||||
* exists, if DeleteProc is not NULL, it is called and passed the value
|
||||
* that was returned by CreateProc.
|
||||
*/
|
||||
static void* Get(CreateProc, DeleteProc);
|
||||
|
||||
|
||||
/**
|
||||
* If Get() has previously been called with this CreateProc, then this
|
||||
* returns its cached data, otherwise it returns NULL. The CreateProc is
|
||||
@ -31,6 +26,24 @@ public:
|
||||
* cache.
|
||||
*/
|
||||
static void* Find(CreateProc);
|
||||
|
||||
/**
|
||||
* Return the cached data that was returned by the CreateProc. This proc
|
||||
* is only called the first time Get is called, and there after it is
|
||||
* cached (per-thread), using the CreateProc as a key to look it up.
|
||||
*
|
||||
* When this thread, or Delete is called, the cached data is removed, and
|
||||
* if a DeleteProc was specified, it is passed the pointer to the cached
|
||||
* data.
|
||||
*/
|
||||
static void* Get(CreateProc, DeleteProc);
|
||||
|
||||
/**
|
||||
* Remove (optionally calling the DeleteProc if it was specificed in Get)
|
||||
* the cached data associated with this CreateProc. If no associated cached
|
||||
* data is found, do nothing.
|
||||
*/
|
||||
static void Delete(CreateProc);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -159,16 +159,20 @@ struct SkTLSRec {
|
||||
void* fData;
|
||||
SkTLS::CreateProc fCreateProc;
|
||||
SkTLS::DeleteProc fDeleteProc;
|
||||
|
||||
~SkTLSRec() {
|
||||
if (fDeleteProc) {
|
||||
fDeleteProc(fData);
|
||||
}
|
||||
// else we leak fData, or it will be managed by the caller
|
||||
}
|
||||
};
|
||||
|
||||
static void sk_tls_destructor(void* ptr) {
|
||||
SkTLSRec* rec = (SkTLSRec*)ptr;
|
||||
do {
|
||||
SkTLSRec* next = rec->fNext;
|
||||
if (rec->fDeleteProc) {
|
||||
rec->fDeleteProc(rec->fData);
|
||||
}
|
||||
delete rec;
|
||||
SkDELETE(rec);
|
||||
rec = next;
|
||||
} while (NULL != rec);
|
||||
}
|
||||
@ -229,3 +233,30 @@ void* SkTLS::Find(CreateProc createProc) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SkTLS::Delete(CreateProc createProc) {
|
||||
if (NULL == createProc) {
|
||||
return;
|
||||
}
|
||||
|
||||
(void)pthread_once(&gSkTLSKey_Once, sk_tls_make_key);
|
||||
void* ptr = pthread_getspecific(gSkTLSKey);
|
||||
|
||||
SkTLSRec* curr = (const SkTLSRec*)ptr;
|
||||
SkTLSRec* prev = NULL;
|
||||
while (curr) {
|
||||
SkTLSRec* next = curr->fNext;
|
||||
if (rec->fCreateProc == createProc) {
|
||||
if (prev) {
|
||||
prev->fNext = next;
|
||||
} else {
|
||||
// we have a new head of our chain
|
||||
(void)pthread_setspecific(gSkTLSKey, next);
|
||||
}
|
||||
SkDELETE(curr);
|
||||
break;
|
||||
}
|
||||
prev = curr;
|
||||
curr = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user