bool Thread::Start() { assert(!IsDefined()); #ifdef HAVE_POSIX #ifndef NDEBUG creating = true; #endif defined = pthread_create(&handle, NULL, ThreadProc, this) == 0; #ifndef NDEBUG creating = false; #endif bool success = defined; #else handle = ::CreateThread(NULL, 0, ThreadProc, this, 0, &id); bool success = handle != NULL; #endif #ifndef NDEBUG if (success) { all_threads_mutex.Lock(); siblings.InsertAfter(all_threads); all_threads_mutex.Unlock(); } #endif return success; }
/** * Determine if the current thread has locked this mutex. This is a * debug-only method meant for assert() calls, and is not available * in optimised builds. */ gcc_pure bool IsLockedByCurrent() const { debug_mutex.Lock(); bool result = locked && owner.IsInside(); debug_mutex.Unlock(); return result; }
bool Thread::Start() { assert(!IsDefined()); #ifdef HAVE_POSIX #ifndef NDEBUG creating = true; #endif defined = pthread_create(&handle, nullptr, ThreadProc, this) == 0; #ifndef NDEBUG creating = false; #endif bool success = defined; #else handle = ::CreateThread(nullptr, 0, ThreadProc, this, 0, &id); bool success = handle != nullptr; #endif #ifndef NDEBUG if (success) { all_threads_mutex.Lock(); all_threads.push_back(*this); all_threads_mutex.Unlock(); } #endif return success; }
bool ExistsAnyThread() { all_threads_mutex.Lock(); bool result = !all_threads.IsEmpty(); all_threads_mutex.Unlock(); return result; }
/** * Locks the Mutex */ void Lock() { #ifdef NDEBUG mutex.Lock(); #else if (!mutex.TryLock()) { /* locking has failed - at this point, "locked" and "owner" are either not yet update, or "owner" is set to another thread */ assert(!IsLockedByCurrent()); mutex.Lock(); } /* we have just obtained the mutex; the "locked" flag must not be set */ debug_mutex.Lock(); assert(!locked); locked = true; owner = ThreadHandle::GetCurrent(); debug_mutex.Unlock(); ++thread_locks_held; #endif };
/** * Unlocks the Mutex */ void Unlock() { #ifndef NDEBUG debug_mutex.Lock(); assert(locked); assert(owner.IsInside()); locked = false; debug_mutex.Unlock(); #endif mutex.Unlock(); #ifndef NDEBUG --thread_locks_held; #endif }
/** * Tries to lock the Mutex */ bool TryLock() { if (!mutex.TryLock()) { #ifndef NDEBUG assert(!IsLockedByCurrent()); #endif return false; } #ifndef NDEBUG debug_mutex.Lock(); assert(!locked); locked = true; owner = ThreadHandle::GetCurrent(); debug_mutex.Unlock(); ++thread_locks_held; #endif return true; };
void Thread::Join() { assert(IsDefined()); assert(!IsInside()); #ifdef HAVE_POSIX pthread_join(handle, NULL); defined = false; #else ::WaitForSingleObject(handle, INFINITE); ::CloseHandle(handle); handle = NULL; #endif #ifndef NDEBUG all_threads_mutex.Lock(); siblings.Remove(); all_threads_mutex.Unlock(); #endif }
void Thread::Join() { assert(IsDefined()); assert(!IsInside()); #ifdef HAVE_POSIX pthread_join(handle, nullptr); defined = false; #else ::WaitForSingleObject(handle, INFINITE); ::CloseHandle(handle); handle = nullptr; #endif #ifndef NDEBUG all_threads_mutex.Lock(); all_threads.erase(all_threads.iterator_to(*this)); all_threads_mutex.Unlock(); #endif }
bool Thread::Join(unsigned timeout_ms) { assert(IsDefined()); assert(!IsInside()); bool result = ::WaitForSingleObject(handle, timeout_ms) == WAIT_OBJECT_0; if (result) { ::CloseHandle(handle); handle = NULL; #ifndef NDEBUG { all_threads_mutex.Lock(); siblings.Remove(); all_threads_mutex.Unlock(); } #endif } return result; }
bool Thread::Join(unsigned timeout_ms) { assert(IsDefined()); assert(!IsInside()); bool result = ::WaitForSingleObject(handle, timeout_ms) == WAIT_OBJECT_0; if (result) { ::CloseHandle(handle); handle = nullptr; #ifndef NDEBUG { all_threads_mutex.Lock(); all_threads.erase(all_threads.iterator_to(*this)); all_threads_mutex.Unlock(); } #endif } return result; }