#include "stdafx.h" #include "Thread.h" __declspec(thread) NamedThreadBase* g_tls_this_thread = nullptr; NamedThreadBase* GetCurrentNamedThread() { return g_tls_this_thread; } std::string NamedThreadBase::GetThreadName() const { return m_name; } void NamedThreadBase::SetThreadName(const std::string& name) { m_name = name; } ThreadBase::ThreadBase(const std::string& name) : NamedThreadBase(name) , m_executor(nullptr) , m_destroy(false) , m_alive(false) { } ThreadBase::~ThreadBase() { if(IsAlive()) Stop(false); } void ThreadBase::Start() { if(m_executor) Stop(); std::lock_guard lock(m_main_mutex); m_destroy = false; m_alive = true; m_executor = new std::thread( [this]() { g_tls_this_thread = this; Task(); m_alive = false; }); } void ThreadBase::Stop(bool wait, bool send_destroy) { std::lock_guard lock(m_main_mutex); if (send_destroy) m_destroy = true; if(!m_executor) return; if(wait && m_executor->joinable() && m_alive) { m_executor->join(); } else { m_executor->detach(); } delete m_executor; m_executor = nullptr; } bool ThreadBase::Join() const { std::lock_guard lock(m_main_mutex); if(m_executor->joinable() && m_alive && m_executor != nullptr) { m_executor->join(); return true; } return false; } bool ThreadBase::IsAlive() const { std::lock_guard lock(m_main_mutex); return m_alive; } bool ThreadBase::TestDestroy() const { return m_destroy; } thread::thread(const std::string& name, std::function func) : m_name(name) { start(func); } thread::thread(const std::string& name) : m_name(name) { } thread::thread() { } void thread::start(std::function func) { // got a crash related with strings m_thr = std::thread([this, func]() { try { NamedThreadBase info(m_name); g_tls_this_thread = &info; func(); } catch(...) { ConLog.Error("Crash :("); terminate(); } }); } void thread::detach() { m_thr.detach(); } void thread::join() { m_thr.join(); } bool thread::joinable() const { return m_thr.joinable(); }