openshot-audio  0.1.7
juce_ThreadLocalValue.h
Go to the documentation of this file.
1 /*
2  ==============================================================================
3 
4  This file is part of the juce_core module of the JUCE library.
5  Copyright (c) 2015 - ROLI Ltd.
6 
7  Permission to use, copy, modify, and/or distribute this software for any purpose with
8  or without fee is hereby granted, provided that the above copyright notice and this
9  permission notice appear in all copies.
10 
11  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
12  TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
13  NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
15  IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16  CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 
18  ------------------------------------------------------------------------------
19 
20  NOTE! This permissive ISC license applies ONLY to files within the juce_core module!
21  All other JUCE modules are covered by a dual GPL/commercial license, so if you are
22  using any other modules, be sure to check that you also comply with their license.
23 
24  For more details, visit www.juce.com
25 
26  ==============================================================================
27 */
28 
29 #ifndef JUCE_THREADLOCALVALUE_H_INCLUDED
30 #define JUCE_THREADLOCALVALUE_H_INCLUDED
31 
32 // (NB: on win32, native thread-locals aren't possible in a dynamically loaded DLL in XP).
33 #if ! ((JUCE_MSVC && (JUCE_64BIT || ! defined (JucePlugin_PluginCode))) \
34  || (JUCE_MAC && JUCE_CLANG && defined (MAC_OS_X_VERSION_10_7) \
35  && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7))
36  #define JUCE_NO_COMPILER_THREAD_LOCAL 1
37 #endif
38 
39 //==============================================================================
57 template <typename Type>
59 {
60 public:
63  {
64  }
65 
70  {
71  #if JUCE_NO_COMPILER_THREAD_LOCAL
72  for (ObjectHolder* o = first.value; o != nullptr;)
73  {
74  ObjectHolder* const next = o->next;
75  delete o;
76  o = next;
77  }
78  #endif
79  }
80 
86  Type& operator*() const noexcept { return get(); }
87 
93  operator Type*() const noexcept { return &get(); }
94 
100  Type* operator->() const noexcept { return &get(); }
101 
103  ThreadLocalValue& operator= (const Type& newValue) { get() = newValue; return *this; }
104 
110  Type& get() const noexcept
111  {
112  #if JUCE_NO_COMPILER_THREAD_LOCAL
113  const Thread::ThreadID threadId = Thread::getCurrentThreadId();
114 
115  for (ObjectHolder* o = first.get(); o != nullptr; o = o->next)
116  if (o->threadId == threadId)
117  return o->object;
118 
119  for (ObjectHolder* o = first.get(); o != nullptr; o = o->next)
120  {
121  if (o->threadId == nullptr)
122  {
123  {
124  SpinLock::ScopedLockType sl (lock);
125 
126  if (o->threadId != nullptr)
127  continue;
128 
129  o->threadId = threadId;
130  }
131 
132  o->object = Type();
133  return o->object;
134  }
135  }
136 
137  ObjectHolder* const newObject = new ObjectHolder (threadId);
138 
139  do
140  {
141  newObject->next = first.get();
142  }
143  while (! first.compareAndSetBool (newObject, newObject->next));
144 
145  return newObject->object;
146  #elif JUCE_MAC
147  static __thread Type object;
148  return object;
149  #elif JUCE_MSVC
150  static __declspec(thread) Type object;
151  return object;
152  #endif
153  }
154 
159  {
160  #if JUCE_NO_COMPILER_THREAD_LOCAL
161  const Thread::ThreadID threadId = Thread::getCurrentThreadId();
162 
163  for (ObjectHolder* o = first.get(); o != nullptr; o = o->next)
164  {
165  if (o->threadId == threadId)
166  {
167  SpinLock::ScopedLockType sl (lock);
168  o->threadId = nullptr;
169  }
170  }
171  #endif
172  }
173 
174 private:
175  //==============================================================================
176  #if JUCE_NO_COMPILER_THREAD_LOCAL
177  struct ObjectHolder
178  {
179  ObjectHolder (const Thread::ThreadID& tid)
180  : threadId (tid), next (nullptr), object()
181  {}
182 
183  Thread::ThreadID threadId;
184  ObjectHolder* next;
185  Type object;
186 
187  JUCE_DECLARE_NON_COPYABLE (ObjectHolder)
188  };
189 
190  mutable Atomic<ObjectHolder*> first;
191  SpinLock lock;
192  #endif
193 
195 };
196 
197 
198 #endif // JUCE_THREADLOCALVALUE_H_INCLUDED
void * ThreadID
Definition: juce_Thread.h:224
volatile Type value
Definition: juce_core.h:154
#define noexcept
Definition: juce_CompilerSupport.h:141
Definition: juce_Atomic.h:41
Definition: juce_ScopedLock.h:59
static ThreadID JUCE_CALLTYPE getCurrentThreadId()
Definition: juce_posix_SharedCode.h:935
Definition: juce_SpinLock.h:46
Type & operator*() const noexcept
Definition: juce_ThreadLocalValue.h:86
~ThreadLocalValue()
Definition: juce_ThreadLocalValue.h:69
#define const
Type * operator->() const noexcept
Definition: juce_ThreadLocalValue.h:100
void releaseCurrentThreadStorage()
Definition: juce_ThreadLocalValue.h:158
bool compareAndSetBool(Type newValue, Type valueToCompare) noexcept
Definition: juce_core.h:348
Type get() const noexcept
Definition: juce_core.h:270
#define JUCE_DECLARE_NON_COPYABLE(className)
Definition: juce_PlatformDefs.h:191
Definition: juce_ThreadLocalValue.h:58
#define nullptr
Definition: juce_CompilerSupport.h:151
ThreadLocalValue() noexcept
Definition: juce_ThreadLocalValue.h:62
void * object
Definition: jmemsys.h:50
ThreadLocalValue & operator=(const Type &newValue)
Definition: juce_ThreadLocalValue.h:103