/* * 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