2012-11-15 00:39:56 +01:00
|
|
|
#include "stdafx.h"
|
|
|
|
#include "Thread.h"
|
|
|
|
|
2014-02-02 20:42:32 +01:00
|
|
|
__declspec(thread) NamedThreadBase* g_tls_this_thread = nullptr;
|
2014-01-31 19:40:18 +01:00
|
|
|
|
|
|
|
NamedThreadBase* GetCurrentNamedThread()
|
|
|
|
{
|
2014-02-02 20:42:32 +01:00
|
|
|
return g_tls_this_thread;
|
2013-06-30 10:46:29 +02:00
|
|
|
}
|
|
|
|
|
2014-01-31 19:40:18 +01:00
|
|
|
std::string NamedThreadBase::GetThreadName() const
|
2013-06-30 10:46:29 +02:00
|
|
|
{
|
2014-01-31 19:40:18 +01:00
|
|
|
return m_name;
|
2013-06-30 10:46:29 +02:00
|
|
|
}
|
|
|
|
|
2014-01-31 19:40:18 +01:00
|
|
|
void NamedThreadBase::SetThreadName(const std::string& name)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-01-31 19:40:18 +01:00
|
|
|
m_name = name;
|
|
|
|
}
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-01-31 19:40:18 +01:00
|
|
|
ThreadBase::ThreadBase(const std::string& name)
|
|
|
|
: NamedThreadBase(name)
|
|
|
|
, m_executor(nullptr)
|
|
|
|
, m_destroy(false)
|
|
|
|
, m_alive(false)
|
|
|
|
{
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
2014-01-31 19:40:18 +01:00
|
|
|
ThreadBase::~ThreadBase()
|
2013-06-30 10:46:29 +02:00
|
|
|
{
|
2014-01-31 19:40:18 +01:00
|
|
|
if(IsAlive())
|
|
|
|
Stop(false);
|
2013-06-30 10:46:29 +02:00
|
|
|
}
|
|
|
|
|
2014-01-31 19:40:18 +01:00
|
|
|
void ThreadBase::Start()
|
2013-06-30 10:46:29 +02:00
|
|
|
{
|
2014-01-31 19:40:18 +01:00
|
|
|
if(m_executor) Stop();
|
|
|
|
|
|
|
|
std::lock_guard<std::mutex> lock(m_main_mutex);
|
|
|
|
|
|
|
|
m_destroy = false;
|
|
|
|
m_alive = true;
|
|
|
|
|
|
|
|
m_executor = new std::thread(
|
|
|
|
[this]()
|
|
|
|
{
|
2014-02-02 20:42:32 +01:00
|
|
|
g_tls_this_thread = this;
|
2014-01-31 19:40:18 +01:00
|
|
|
|
|
|
|
Task();
|
|
|
|
|
|
|
|
m_alive = false;
|
|
|
|
});
|
2013-06-30 10:46:29 +02:00
|
|
|
}
|
|
|
|
|
2014-02-14 20:50:02 +01:00
|
|
|
void ThreadBase::Stop(bool wait, bool send_destroy)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-01-31 19:40:18 +01:00
|
|
|
std::lock_guard<std::mutex> lock(m_main_mutex);
|
2013-06-30 10:46:29 +02:00
|
|
|
|
2014-02-14 20:50:02 +01:00
|
|
|
if (send_destroy)
|
|
|
|
m_destroy = true;
|
2013-06-30 10:46:29 +02:00
|
|
|
|
2014-01-31 19:40:18 +01:00
|
|
|
if(!m_executor)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(wait && m_executor->joinable() && m_alive)
|
|
|
|
{
|
|
|
|
m_executor->join();
|
2013-06-30 10:46:29 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-01-31 19:40:18 +01:00
|
|
|
m_executor->detach();
|
2013-06-30 10:46:29 +02:00
|
|
|
}
|
2014-01-31 19:40:18 +01:00
|
|
|
|
|
|
|
delete m_executor;
|
|
|
|
m_executor = nullptr;
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
2014-01-31 19:40:18 +01:00
|
|
|
bool ThreadBase::Join() const
|
2013-06-30 10:46:29 +02:00
|
|
|
{
|
2014-01-31 19:40:18 +01:00
|
|
|
std::lock_guard<std::mutex> lock(m_main_mutex);
|
|
|
|
if(m_executor->joinable() && m_alive && m_executor != nullptr)
|
|
|
|
{
|
|
|
|
m_executor->join();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2013-06-30 10:46:29 +02:00
|
|
|
}
|
|
|
|
|
2014-01-31 19:40:18 +01:00
|
|
|
bool ThreadBase::IsAlive() const
|
2013-06-30 10:46:29 +02:00
|
|
|
{
|
2014-01-31 19:40:18 +01:00
|
|
|
std::lock_guard<std::mutex> lock(m_main_mutex);
|
|
|
|
return m_alive;
|
2013-06-30 10:46:29 +02:00
|
|
|
}
|
|
|
|
|
2014-01-31 19:40:18 +01:00
|
|
|
bool ThreadBase::TestDestroy() const
|
2013-06-30 10:46:29 +02:00
|
|
|
{
|
2014-01-31 19:40:18 +01:00
|
|
|
return m_destroy;
|
2013-06-30 10:46:29 +02:00
|
|
|
}
|
|
|
|
|
2014-01-31 19:40:18 +01:00
|
|
|
thread::thread(const std::string& name, std::function<void()> func) : m_name(name)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-01-31 19:40:18 +01:00
|
|
|
start(func);
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|
|
|
|
|
2014-01-31 19:40:18 +01:00
|
|
|
thread::thread(const std::string& name) : m_name(name)
|
2012-11-15 00:39:56 +01:00
|
|
|
{
|
2014-01-31 19:40:18 +01:00
|
|
|
}
|
2012-11-15 00:39:56 +01:00
|
|
|
|
2014-01-31 19:40:18 +01:00
|
|
|
thread::thread()
|
|
|
|
{
|
2013-06-30 10:46:29 +02:00
|
|
|
}
|
|
|
|
|
2014-01-31 19:40:18 +01:00
|
|
|
void thread::start(std::function<void()> func)
|
2014-02-13 12:13:05 +01:00
|
|
|
{ // got a crash related with strings
|
2014-02-19 18:27:52 +01:00
|
|
|
m_thr = std::thread([this, func]()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
NamedThreadBase info(m_name);
|
|
|
|
g_tls_this_thread = &info;
|
|
|
|
func();
|
|
|
|
}
|
|
|
|
catch(...)
|
|
|
|
{
|
|
|
|
ConLog.Error("Crash :(");
|
|
|
|
terminate();
|
|
|
|
}
|
|
|
|
});
|
2013-06-30 10:46:29 +02:00
|
|
|
}
|
|
|
|
|
2014-01-31 19:40:18 +01:00
|
|
|
void thread::detach()
|
2013-06-30 10:46:29 +02:00
|
|
|
{
|
2014-01-31 19:40:18 +01:00
|
|
|
m_thr.detach();
|
|
|
|
}
|
|
|
|
|
|
|
|
void thread::join()
|
|
|
|
{
|
|
|
|
m_thr.join();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool thread::joinable() const
|
|
|
|
{
|
|
|
|
return m_thr.joinable();
|
2012-11-15 00:39:56 +01:00
|
|
|
}
|