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