4#if FASTLED_USE_THREAD_LOCAL
10#if FASTLED_USE_THREAD_LOCAL
14#if FASTLED_MULTITHREADED
16 "ThreadLocal is not implemented, using the fake version with globally shared data"
22#if FASTLED_USE_THREAD_LOCAL
23template <
typename T>
class ThreadLocalReal;
24template <
typename T>
using ThreadLocal = ThreadLocalReal<T>;
32#if FASTLED_USE_THREAD_LOCAL
33template <
typename T>
class ThreadLocalReal {
36 ThreadLocalReal() : mDefaultValue(), mHasDefault(
false) {
42 explicit ThreadLocalReal(
const U &defaultVal) : mDefaultValue(defaultVal), mHasDefault(
true) {
48 if (mKeyInitialized) {
49 pthread_key_delete(mKey);
54 ThreadLocalReal(
const ThreadLocalReal& other) : mDefaultValue(other.mDefaultValue), mHasDefault(other.mHasDefault) {
59 ThreadLocalReal& operator=(
const ThreadLocalReal& other) {
61 mDefaultValue = other.mDefaultValue;
62 mHasDefault = other.mHasDefault;
70 ThreadStorage* storage = getStorage();
72 storage = createStorage();
74 if (mHasDefault && !storage->initialized) {
75 copyValue(storage->value, mDefaultValue);
76 storage->initialized =
true;
78 return storage->value;
81 const T &access()
const {
82 ThreadStorage* storage = getStorage();
84 storage = createStorage();
86 if (mHasDefault && !storage->initialized) {
87 copyValue(storage->value, mDefaultValue);
88 storage->initialized =
true;
90 return storage->value;
94 void set(
const T& value) {
95 copyValue(access(), value);
99 operator T &() {
return access(); }
100 operator const T &()
const {
return access(); }
102 ThreadLocalReal &operator=(
const T &v) {
110 static void copyValue(U& dest,
const U& src) {
115 template<
typename U,
size_t N>
116 static void copyValue(U (&dest)[N],
const U (&src)[N]) {
117 for (
size_t i = 0; i < N; ++i) {
118 copyValue(dest[i], src[i]);
123 struct ThreadStorage {
125 bool initialized =
false;
130 bool mKeyInitialized =
false;
132 bool mHasDefault =
false;
135 void initializeKey() {
136 int result = pthread_key_create(&mKey, cleanupThreadStorage);
138 mKeyInitialized =
true;
141 mKeyInitialized =
false;
146 ThreadStorage* getStorage()
const {
147 if (!mKeyInitialized) {
150 return static_cast<ThreadStorage*
>(pthread_getspecific(mKey));
154 ThreadStorage* createStorage()
const {
155 if (!mKeyInitialized) {
159 ThreadStorage* storage =
new ThreadStorage();
160 int result = pthread_setspecific(mKey, storage);
169 static void cleanupThreadStorage(
void* data) {
171 delete static_cast<ThreadStorage*
>(data);
186 template <
typename U>
194 void set(
const T& value) {
200 operator const T &()
const {
return access(); }
ThreadLocalFake(const U &defaultVal)
ThreadLocalFake & operator=(const T &v)
Result type for promise operations.
ThreadLocalFake< T > ThreadLocal