11#include <condition_variable>
17#include <sys/syscall.h>
25 std::unique_ptr<std::thread> internalThread;
29 std::atomic<bool> isAlive{
false};
30 bool completed{
false};
32 std::condition_variable joinCv;
35 thread_local Thread* Thread::_currentThread =
nullptr;
39 : m_pImpl(new Impl()) {
40 m_pImpl->start = start;
44 : m_pImpl(new Impl()) {
45 m_pImpl->parameterizedStart = start;
49 : m_pImpl(new Impl()) {
50 m_pImpl->isAlive =
true;
55 if (!pThread || !pThread->joinable())
return;
59 if (pThread->get_id() == std::this_thread::get_id()) {
84 if (!m_pImpl || m_pImpl->isAlive)
return;
87 m_pImpl->isAlive =
true;
88 m_pImpl->completed =
false;
89 m_pImpl->internalThread = std::make_unique<std::thread>(&Thread::ThreadMain,
this, parameter);
94 if (!m_pImpl || !m_pImpl->internalThread || !m_pImpl->internalThread->joinable())
return;
95 if (m_pImpl->internalThread->get_id() == std::this_thread::get_id())
return;
98 m_pImpl->internalThread->join();
103 if (!m_pImpl)
return true;
104 if (!m_pImpl->isAlive && m_pImpl->completed)
return true;
105 if (!m_pImpl->internalThread)
return true;
108 std::unique_lock<std::mutex> lock(m_pImpl->joinMutex);
109 if (m_pImpl->joinCv.wait_for(lock, std::chrono::milliseconds(millisecondsTimeout), [
this]() { return m_pImpl->completed; })) {
110 if (m_pImpl->internalThread->joinable()) {
111 m_pImpl->internalThread->join();
117 throw TimeoutException(
"The thread did not terminate within the allotted time.");
122 std::this_thread::sleep_for(std::chrono::milliseconds(millisecondsTimeout));
126 return m_pImpl ? m_pImpl->isAlive.load() :
false;
130 return m_pImpl ? m_pImpl->name :
String(
"");
134 if (m_pImpl) m_pImpl->name = name;
139 if (_currentThread ==
nullptr) {
145 return _currentThread;
153 return static_cast<int>(::syscall(__NR_gettid));
161 void Thread::ThreadMain(
Object* parameter) {
163 _currentThread =
this;
167 if (m_pImpl->start) m_pImpl->start();
168 else if (m_pImpl->parameterizedStart) m_pImpl->parameterizedStart(parameter);
175 std::lock_guard<std::mutex> lock(m_pImpl->joinMutex);
176 m_pImpl->completed =
true;
177 m_pImpl->isAlive =
false;
181 m_pImpl->joinCv.notify_all();
Provides reference-counted and weak pointer memory management primitives ensuring zero raw ownership.
Creates and controls a thread, sets its priority, and gets its status mirroring .NET System....
Defines the exception thrown when the time allotted for a process or operation has expired.
Represents an unknown or unmapped exception encountered during execution.
Supports all classes in the DotNetDupe class hierarchy.
A unified smart pointer that supports both unique and shared ownership semantics.
friend class SmartPointer
Represents text as a sequence of UTF-8 code units with culture-invariant operations.
String()
Initializes a new instance of the String class to an empty string.
Creates and controls execution of operating system threads.
String GetName() const
Gets the friendly name of the thread.
static int GetCurrentThreadId()
Returns an integer identifier for the current managed thread.
Thread(ThreadStart start)
Initializes a new instance of the Thread class with a parameterless start delegate.
void Join()
Blocks the calling thread until the thread represented by this instance terminates.
void Start()
Causes the operating system to change the state of the current instance to Running.
static void Sleep(int millisecondsTimeout)
Suspends the current thread for the specified number of milliseconds.
bool IsAlive() const
Gets a value indicating the execution status of the current thread.
static Thread * GetCurrentThread()
Gets the currently running thread.
void SetName(const String &name)
Sets the friendly name of the thread.
TimeoutException(const String &sMessage)
Initializes a new instance of the TimeoutException class with a specified error message.
static void SafelyJoinOrDetach(const std::unique_ptr< std::thread > &pThread)
Action< Object * > ParameterizedThreadStart
static SmartPointer< Thread > s_pCurrentThreadStorage(nullptr)