12 #ifndef __UT_TASKLOCK_H_INCLUDED__
13 #define __UT_TASKLOCK_H_INCLUDED__
28 #ifndef UT_TASKLOCK_DBG
30 #define UT_TASKLOCK_DBG(ZZ) UT_DBGOUT(ZZ)
32 #define UT_TASKLOCK_DBG(ZZ)
48 template <
bool NESTED>
54 typedef hboost::mutex ut_Mutex;
55 typedef ut_Mutex::scoped_lock ut_MutexLock;
56 typedef hboost::condition_variable ut_Condition;
71 ut_Condition myCondition;
72 int myNumWaitingThreads;
76 bool unsafeTryLock(
const UT_TaskScope &task,
bool &was_first)
79 if (myData.myLockCount == 0 || myData.myOwner == &task)
81 UT_ASSERT(myData.myLockCount > 0 || myData.myOwner == NULL);
82 myDataStack.
append(myData);
83 myData.myOwner = &task;
85 was_first = (myData.myLockCount == 1);
87 this, myData.myOwner, myData.myLockCount));
91 "(count %d), waiting threads %d",
92 this, &task, myData.myOwner, myData.myLockCount,
93 myNumWaitingThreads));
98 bool privateLock(hboost::system_time
const &wait_until,
bool &was_first)
100 ut_MutexLock lock_scope(myMutex);
104 if (unsafeTryLock(task, was_first))
114 if (myData.myOwner == NULL
117 UT_ASSERT(myData.myOwner != NULL || myData.myLockCount == 0);
118 myDataStack.
append(myData);
119 myData.myOwner = &task;
120 myData.myLockCount = 1;
124 this, myData.myOwner,
125 myDataStack.
last().myOwner,
126 myDataStack.
last().myLockCount));
132 "prev waiting threads %d",
133 this, myData.myOwner, myData.myLockCount,
134 myNumWaitingThreads));
135 ++myNumWaitingThreads;
136 if (wait_until.is_pos_infinity())
138 myCondition.wait(lock_scope);
142 ok = myCondition.timed_wait(lock_scope, wait_until);
144 --myNumWaitingThreads;
151 bool privateTryLock()
153 ut_MutexLock lock_scope(myMutex);
155 bool was_first =
false;
157 return unsafeTryLock(task, was_first);
162 ut_MutexLock lock_scope(myMutex);
166 "new owner %p (count %d), waiting threads %d",
167 this, myData.myOwner,
168 myDataStack.
last().myOwner,
169 myDataStack.
last().myLockCount,
170 myNumWaitingThreads));
173 notify = (myData.myLockCount == 1);
175 myData = myDataStack.
last();
182 UT_ASSERT(myData.myLockCount > 0 || myData.myOwner == NULL);
188 if (myNumWaitingThreads > 0)
190 myCondition.notify_all();
195 bool privateHasLock()
197 ut_MutexLock lock_scope(myMutex);
199 return (myData.myLockCount > 0 && myData.myOwner == &task);
213 : myNumWaitingThreads(0)
224 return myNumWaitingThreads;
229 bool was_first =
false;
230 (
void) privateLock(hboost::system_time(hboost::posix_time::pos_infin),
238 (
void) privateLock(hboost::system_time(hboost::posix_time::pos_infin),
244 bool was_first =
false;
245 return privateLock(hboost::get_system_time()
246 + hboost::posix_time::milliseconds(timeout),
252 return privateTryLock();
268 return privateHasLock();
301 template <
typename F>
305 bool was_first =
false;
322 template <
typename F>
326 bool was_first =
false;
341 template <
typename F>
353 #endif // __UT_TASKLOCK_H_INCLUDED__
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
#define UT_TASKLOCK_DBG(ZZ)
static const UT_TaskScope & getOrCreateCurrent()
SYS_FORCE_INLINE void removeLast()
void lockedExecute(const F &functor, UT_TaskArena &arena)
int numWaitingThreads() const
static const UT_TaskScope & getOrCreateRoot()
UT_TaskLockT< false > UT_TaskRootLock
GLbitfield GLuint64 timeout
bool timedLock(int timeout)
#define UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
void lock(bool &was_first)
bool isAncestor(const UT_TaskScope &parent) const
Test if the given task scope is an ancestor of ours.
UT_TaskLockT< true > UT_TaskLock
UT_TaskLock that avoids deadlocks when used with TBB task scheduling.
void lockedExecuteWithoutArena(const F &functor)
void lockedExecute(const F &functor)