#include "C4JThread.h" std::vector 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(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; }