Home | History | Annotate | Download | only in core
      1 //
      2 //  SkTLS.h
      3 //
      4 //
      5 //  Created by Mike Reed on 4/21/12.
      6 //  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
      7 //
      8 
      9 #ifndef SkTLS_DEFINED
     10 #define SkTLS_DEFINED
     11 
     12 #include "SkTypes.h"
     13 
     14 /**
     15  *  Maintains a per-thread cache, using a CreateProc as the key into that cache.
     16  */
     17 class SkTLS {
     18 public:
     19     typedef void* (*CreateProc)();
     20     typedef void  (*DeleteProc)(void*);
     21 
     22     /**
     23      *  If Get() has previously been called with this CreateProc, then this
     24      *  returns its cached data, otherwise it returns NULL. The CreateProc is
     25      *  never invoked in Find, it is only used as a key for searching the
     26      *  cache.
     27      */
     28     static void* Find(CreateProc);
     29 
     30     /**
     31      *  Return the cached data that was returned by the CreateProc. This proc
     32      *  is only called the first time Get is called, and there after it is
     33      *  cached (per-thread), using the CreateProc as a key to look it up.
     34      *
     35      *  When this thread, or Delete is called, the cached data is removed, and
     36      *  if a DeleteProc was specified, it is passed the pointer to the cached
     37      *  data.
     38      */
     39     static void* Get(CreateProc, DeleteProc);
     40 
     41     /**
     42      *  Remove (optionally calling the DeleteProc if it was specificed in Get)
     43      *  the cached data associated with this CreateProc. If no associated cached
     44      *  data is found, do nothing.
     45      */
     46     static void Delete(CreateProc);
     47 
     48 private:
     49     // Our implementation requires only 1 TLS slot, as we manage multiple values
     50     // ourselves in a list, with the platform specific value as our head.
     51 
     52     /**
     53      *  Implemented by the platform, to return the value of our (one) slot per-thread
     54      *
     55      *  If forceCreateTheSlot is true, then we must have created the "slot" for
     56      *  our TLS, even though we know that the return value will be NULL in that
     57      *  case (i.e. no-slot and first-time-slot both return NULL). This ensures
     58      *  that after calling GetSpecific, we know that we can legally call
     59      *  SetSpecific.
     60      *
     61      *  If forceCreateTheSlot is false, then the impl can either create the
     62      *  slot or not.
     63      */
     64     static void* PlatformGetSpecific(bool forceCreateTheSlot);
     65 
     66     /**
     67      *  Implemented by the platform, to set the value for our (one) slot per-thread
     68      *
     69      *  The implementation can rely on GetSpecific(true) having been previously
     70      *  called before SetSpecific is called.
     71      */
     72     static void  PlatformSetSpecific(void*);
     73 
     74 public:
     75     /**
     76      *  Will delete our internal list. To be called by the platform if/when its
     77      *  TLS slot is deleted (often at thread shutdown).
     78      *
     79      *  Public *only* for the platform's use, not to be called by a client.
     80      */
     81     static void Destructor(void* ptr);
     82 };
     83 
     84 #endif
     85