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_NOEXCEPT : mDefaultValue(), mHasDefault(
false) {
43 explicit ThreadLocalReal(
const U &defaultVal) : mDefaultValue(defaultVal), mHasDefault(
true) {
49 if (mKeyInitialized) {
53 ThreadStorage* storage = getStorage();
55 pthread_setspecific(mKey,
nullptr);
58 pthread_key_delete(mKey);
63 ThreadLocalReal(
const ThreadLocalReal& other)
FL_NOEXCEPT : mDefaultValue(other.mDefaultValue), mHasDefault(other.mHasDefault) {
68 ThreadLocalReal& operator=(
const ThreadLocalReal& other)
FL_NOEXCEPT {
70 mDefaultValue = other.mDefaultValue;
71 mHasDefault = other.mHasDefault;
79 ThreadStorage* storage = getStorage();
81 storage = createStorage();
83 if (mHasDefault && !storage->initialized) {
84 copyValue(storage->value, mDefaultValue);
85 storage->initialized =
true;
87 return storage->value;
90 const T &access()
const {
91 ThreadStorage* storage = getStorage();
93 storage = createStorage();
95 if (mHasDefault && !storage->initialized) {
96 copyValue(storage->value, mDefaultValue);
97 storage->initialized =
true;
99 return storage->value;
104 copyValue(access(),
value);
108 operator T &() {
return access(); }
109 operator const T &()
const {
return access(); }
111 ThreadLocalReal &operator=(
const T &v)
FL_NOEXCEPT {
119 static void copyValue(U& dest,
const U& src) {
124 template<
typename U,
size_t N>
125 static void copyValue(U (&dest)[N],
const U (&src)[N]) {
126 for (
size_t i = 0; i < N; ++i) {
127 copyValue(dest[i], src[i]);
132 struct ThreadStorage {
134 bool initialized =
false;
139 bool mKeyInitialized =
false;
141 bool mHasDefault =
false;
144 void initializeKey() {
145 int result = pthread_key_create(&mKey, cleanupThreadStorage);
147 mKeyInitialized =
true;
150 mKeyInitialized =
false;
155 ThreadStorage* getStorage()
const {
156 if (!mKeyInitialized) {
159 return static_cast<ThreadStorage*
>(pthread_getspecific(mKey));
163 ThreadStorage* createStorage()
const {
164 if (!mKeyInitialized) {
168 ThreadStorage* storage =
new ThreadStorage();
169 int result = pthread_setspecific(mKey, storage);
178 static void cleanupThreadStorage(
void* data) {
180 delete static_cast<ThreadStorage*
>(data);
195 template <
typename U>
void set(const T &value) FL_NOEXCEPT
ThreadLocalFake() FL_NOEXCEPT
ThreadLocalFake(const U &defaultVal) FL_NOEXCEPT
ThreadLocalFake & operator=(const T &v) FL_NOEXCEPT
const T & access() const FL_NOEXCEPT
constexpr int type_rank< T >::value
ThreadLocalFake< T > ThreadLocal
expected< T, E > result
Alias for expected (Rust-style naming)
Base definition for an LED controller.