|  | /* | 
|  | * Copyright 2012 Google Inc. | 
|  | * | 
|  | * Use of this source code is governed by a BSD-style license that can be | 
|  | * found in the LICENSE file. | 
|  | */ | 
|  |  | 
|  | #ifndef SkTLS_DEFINED | 
|  | #define SkTLS_DEFINED | 
|  |  | 
|  | #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*); | 
|  |  | 
|  | /** | 
|  | *  If Get() has previously been called with this CreateProc, then this | 
|  | *  returns its cached data, otherwise it returns nullptr. The CreateProc is | 
|  | *  never invoked in Find, it is only used as a key for searching the | 
|  | *  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); | 
|  |  | 
|  | private: | 
|  | // Our implementation requires only 1 TLS slot, as we manage multiple values | 
|  | // ourselves in a list, with the platform specific value as our head. | 
|  |  | 
|  | /** | 
|  | *  Implemented by the platform, to return the value of our (one) slot per-thread | 
|  | * | 
|  | *  If forceCreateTheSlot is true, then we must have created the "slot" for | 
|  | *  our TLS, even though we know that the return value will be nullptr in that | 
|  | *  case (i.e. no-slot and first-time-slot both return nullptr). This ensures | 
|  | *  that after calling GetSpecific, we know that we can legally call | 
|  | *  SetSpecific. | 
|  | * | 
|  | *  If forceCreateTheSlot is false, then the impl can either create the | 
|  | *  slot or not. | 
|  | */ | 
|  | static void* PlatformGetSpecific(bool forceCreateTheSlot); | 
|  |  | 
|  | /** | 
|  | *  Implemented by the platform, to set the value for our (one) slot per-thread | 
|  | * | 
|  | *  The implementation can rely on GetSpecific(true) having been previously | 
|  | *  called before SetSpecific is called. | 
|  | */ | 
|  | static void  PlatformSetSpecific(void*); | 
|  |  | 
|  | public: | 
|  | /** | 
|  | *  Will delete our internal list. To be called by the platform if/when its | 
|  | *  TLS slot is deleted (often at thread shutdown). | 
|  | * | 
|  | *  Public *only* for the platform's use, not to be called by a client. | 
|  | */ | 
|  | static void Destructor(void* ptr); | 
|  | }; | 
|  |  | 
|  | #endif |