Files
mc-lce/src/world/C4JThread.cpp
2026-03-01 20:06:25 +02:00

148 lines
3.2 KiB
C++

#include "C4JThread.h"
std::vector<C4JThread*> C4JThread::ms_threadList;
std::mutex C4JThread::ms_threadListMutex;
thread_local C4JThread* C4JThread::tls_currentThread = nullptr;
C4JThread C4JThread::m_mainThread("MainThread");
C4JThread::Event::Event(EMode mode)
: m_mode(mode)
{
}
void C4JThread::Event::Set()
{
std::lock_guard<std::mutex> lock(m_mutex);
m_signaled = true;
m_cv.notify_all();
}
void C4JThread::Event::Clear()
{
std::lock_guard<std::mutex> lock(m_mutex);
m_signaled = false;
}
unsigned long C4JThread::Event::WaitForSignal(int timeoutMs)
{
std::unique_lock<std::mutex> lock(m_mutex);
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;
return 0;
}
C4JThread::EventArray::EventArray(int size, Event::EMode mode)
{
m_events.reserve(size);
for (int i = 0; i < size; ++i)
m_events.emplace_back(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));
std::lock_guard<std::mutex> lock(ms_threadListMutex);
ms_threadList.push_back(this);
}
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;
}