Files
mc-lce/src/world/C4JThread.cpp
2026-03-01 23:19:08 +02:00

161 lines
3.2 KiB
C++

#include "C4JThread.h"
std::vector<C4JThread*> C4JThread::ms_threadList;
ThreadLock C4JThread::ms_threadListLock;
thread_local C4JThread* C4JThread::tls_currentThread = nullptr;
C4JThread C4JThread::m_mainThread("MainThread");
C4JThread::Event::Event(EMode mode)
: m_mode(mode)
{
}
void C4JThread::Event::Set()
{
m_lock.lock();
m_signaled = true;
m_cv.notify_all();
m_lock.unlock();
}
void C4JThread::Event::Clear()
{
m_lock.lock();
m_signaled = false;
m_lock.unlock();
}
unsigned long C4JThread::Event::WaitForSignal(int timeoutMs)
{
m_lock.lock();
if (timeoutMs < 0)
{
m_cv.wait(lock, [&] { return m_signaled; });
}
else
{
if (!m_cv.wait_for(lock, std::chrono::milliseconds(timeoutMs), [&] { return m_signaled; }))
return 0x102;
}
if (m_mode == e_modeAutoClear)
m_signaled = false;
m_lock.unlock();
return 0;
}
C4JThread::EventArray::EventArray(int size, Event::EMode mode)
{
m_events.reserve(size);
for (int i = 0; i < size; ++i)
{
m_events.push_back(std::unique_ptr<Event>(new Event(mode)));
}
}
void C4JThread::EventArray::Set(int i)
{
m_events[i]->Set();
}
void C4JThread::EventArray::Clear(int i)
{
m_events[i]->Clear();
}
void C4JThread::EventArray::SetAll()
{
for (auto& e : m_events) e->Set();
}
void C4JThread::EventArray::ClearAll()
{
for (auto& e : m_events) e->Clear();
}
unsigned long C4JThread::EventArray::WaitForSingle(int index, int timeoutMs)
{
return m_events[index]->WaitForSignal(timeoutMs);
}
unsigned long C4JThread::EventArray::WaitForAll(int timeoutMs)
{
for (auto& e : m_events)
e->WaitForSignal(timeoutMs);
return 0;
}
unsigned long C4JThread::EventArray::WaitForAny(int timeoutMs)
{
while (true)
{
for (auto& e : m_events)
{
if (e->WaitForSignal(0) == 0)
return 0;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
C4JThread::C4JThread(C4JThreadStartFunc* startFunc, void* param, const char* name, int)
: m_threadParam(param), m_startFunc(startFunc)
{
std::strncpy(m_threadName, name, sizeof(m_threadName));
ms_threadListLock.lock();
ms_threadList.push_back(this);
ms_threadListLock.unlock();
}
C4JThread::C4JThread(const char* mainThreadName)
{
std::strncpy(m_threadName, mainThreadName, sizeof(m_threadName));
tls_currentThread = this;
m_isRunning = true;
m_hasStarted = true;
}
C4JThread::~C4JThread()
{
if (m_thread.joinable())
m_thread.join();
}
void C4JThread::threadEntry()
{
tls_currentThread = this;
m_isRunning = true;
m_exitCode = (*m_startFunc)(m_threadParam);
m_isRunning = false;
}
void C4JThread::Run()
{
m_hasStarted = true;
m_thread = std::thread(&C4JThread::threadEntry, this);
}
unsigned long C4JThread::WaitForCompletion(int)
{
if (m_thread.joinable())
m_thread.join();
return 0;
}
void C4JThread::Sleep(int ms)
{
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
}
C4JThread* C4JThread::getCurrentThread()
{
return tls_currentThread ? tls_currentThread : &m_mainThread;
}
bool C4JThread::isMainThread()
{
return getCurrentThread() == &m_mainThread;
}