4#if FASTLED_USE_THREAD_LOCAL
11#if FASTLED_USE_THREAD_LOCAL
15#if FASTLED_MULTITHREADED
17 "ThreadLocal is not implemented, using the fake version with globally shared data"
23#if FASTLED_USE_THREAD_LOCAL
24template <
typename T>
class ThreadLocalReal;
25template <
typename T>
using ThreadLocal = ThreadLocalReal<T>;
33#if FASTLED_USE_THREAD_LOCAL
34template <
typename T>
class ThreadLocalReal {
37 ThreadLocalReal()
FL_NO_EXCEPT : mDefaultValue(), mHasDefault(
false) {
43 explicit ThreadLocalReal(
const U &defaultVal)
FL_NO_EXCEPT
44 : mDefaultValue(defaultVal), mHasDefault(
true) {
50 if (mKeyInitialized) {
54 ThreadStorage* storage = getStorage();
56 pthread_setspecific(mKey,
nullptr);
59 pthread_key_delete(mKey);
64 ThreadLocalReal(
const ThreadLocalReal& other)
FL_NO_EXCEPT : mDefaultValue(other.mDefaultValue), mHasDefault(other.mHasDefault) {
69 ThreadLocalReal& operator=(
const ThreadLocalReal& other)
FL_NO_EXCEPT {
71 mDefaultValue = other.mDefaultValue;
72 mHasDefault = other.mHasDefault;
80 ThreadStorage* storage = getStorage();
82 storage = createStorage();
84 if (mHasDefault && !storage->initialized) {
85 copyValue(storage->value, mDefaultValue);
86 storage->initialized =
true;
88 return storage->value;
92 ThreadStorage* storage = getStorage();
94 storage = createStorage();
96 if (mHasDefault && !storage->initialized) {
97 copyValue(storage->value, mDefaultValue);
98 storage->initialized =
true;
100 return storage->value;
105 copyValue(access(),
value);
110 operator const T &()
const FL_NO_EXCEPT {
return access(); }
120 static void copyValue(U& dest,
const U& src)
FL_NO_EXCEPT {
125 template<
typename U,
size_t N>
126 static void copyValue(U (&dest)[N],
const U (&src)[N])
FL_NO_EXCEPT {
127 for (
size_t i = 0; i < N; ++i) {
128 copyValue(dest[i], src[i]);
133 struct ThreadStorage {
135 bool initialized =
false;
140 bool mKeyInitialized =
false;
142 bool mHasDefault =
false;
146 int result = pthread_key_create(&mKey, cleanupThreadStorage);
148 mKeyInitialized =
true;
151 mKeyInitialized =
false;
157 if (!mKeyInitialized) {
160 return static_cast<ThreadStorage*
>(pthread_getspecific(mKey));
165 if (!mKeyInitialized) {
169 ThreadStorage* storage =
new ThreadStorage();
170 int result = pthread_setspecific(mKey, storage);
179 static void cleanupThreadStorage(
void* data)
FL_NO_EXCEPT {
181 delete static_cast<ThreadStorage*
>(data);
196 template <
typename U>
const T & access() const FL_NO_EXCEPT
void set(const T &value) FL_NO_EXCEPT
ThreadLocalFake & operator=(const T &v) FL_NO_EXCEPT
ThreadLocalFake() FL_NO_EXCEPT
T & access() FL_NO_EXCEPT
ThreadLocalFake(const U &defaultVal) FL_NO_EXCEPT
constexpr int type_rank< T >::value
ThreadLocalFake< T > ThreadLocal
expected< T, E > result
Alias for expected (Rust-style naming)
InputGamut g FL_NO_EXCEPT
Base definition for an LED controller.