Remove threads.h and replace its definitions with their C++11 equivalents (#5957)

This also changes threadProc's signature, since C++11 supports arbitrary
thread function signatures.
This commit is contained in:
ShadowNinja 2017-06-11 03:43:05 -04:00 committed by Loïc Blot
parent 5cc8ad946e
commit 6c5e5e2023
16 changed files with 82 additions and 160 deletions

View File

@ -386,7 +386,7 @@ public:
private: private:
// The id of the thread that is allowed to use irrlicht directly // The id of the thread that is allowed to use irrlicht directly
threadid_t m_main_thread; std::thread::id m_main_thread;
// The irrlicht device // The irrlicht device
IrrlichtDevice *m_device; IrrlichtDevice *m_device;
@ -445,7 +445,7 @@ TextureSource::TextureSource(IrrlichtDevice *device):
{ {
assert(m_device); // Pre-condition assert(m_device); // Pre-condition
m_main_thread = thr_get_current_thread_id(); m_main_thread = std::this_thread::get_id();
// Add a NULL TextureInfo as the first index, named "" // Add a NULL TextureInfo as the first index, named ""
m_textureinfo_cache.push_back(TextureInfo("")); m_textureinfo_cache.push_back(TextureInfo(""));
@ -508,7 +508,7 @@ u32 TextureSource::getTextureId(const std::string &name)
/* /*
Get texture Get texture
*/ */
if (thr_is_current_thread(m_main_thread)) if (std::this_thread::get_id() == m_main_thread)
{ {
return generateTexture(name); return generateTexture(name);
} }
@ -616,7 +616,7 @@ u32 TextureSource::generateTexture(const std::string &name)
/* /*
Calling only allowed from main thread Calling only allowed from main thread
*/ */
if (!thr_is_current_thread(m_main_thread)) { if (std::this_thread::get_id() != m_main_thread) {
errorstream<<"TextureSource::generateTexture() " errorstream<<"TextureSource::generateTexture() "
"called not from main thread"<<std::endl; "called not from main thread"<<std::endl;
return 0; return 0;
@ -695,7 +695,7 @@ video::ITexture* TextureSource::getTextureForMesh(const std::string &name, u32 *
Palette* TextureSource::getPalette(const std::string &name) Palette* TextureSource::getPalette(const std::string &name)
{ {
// Only the main thread may load images // Only the main thread may load images
sanity_check(thr_is_current_thread(m_main_thread)); sanity_check(std::this_thread::get_id() == m_main_thread);
if (name == "") if (name == "")
return NULL; return NULL;
@ -771,7 +771,7 @@ void TextureSource::insertSourceImage(const std::string &name, video::IImage *im
{ {
//infostream<<"TextureSource::insertSourceImage(): name="<<name<<std::endl; //infostream<<"TextureSource::insertSourceImage(): name="<<name<<std::endl;
sanity_check(thr_is_current_thread(m_main_thread)); sanity_check(std::this_thread::get_id() == m_main_thread);
m_sourcecache.insert(name, img, true, m_device->getVideoDriver()); m_sourcecache.insert(name, img, true, m_device->getVideoDriver());
m_source_image_existence.set(name, true); m_source_image_existence.set(name, true);

View File

@ -24,7 +24,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "irr_v3d.h" #include "irr_v3d.h"
#include <ITexture.h> #include <ITexture.h>
#include <IrrlichtDevice.h> #include <IrrlichtDevice.h>
#include "threads.h"
#include <string> #include <string>
#include <vector> #include <vector>
#include "util/numeric.h" #include "util/numeric.h"

View File

@ -21,12 +21,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "porting.h" #include "porting.h"
#include "debug.h" #include "debug.h"
#include "exceptions.h" #include "exceptions.h"
#include "threads.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <cstring> #include <cstring>
#include <map> #include <map>
#include <sstream> #include <sstream>
#include <thread>
#include "threading/mutex_auto_lock.h" #include "threading/mutex_auto_lock.h"
#include "config.h" #include "config.h"
@ -52,7 +52,7 @@ void sanity_check_fn(const char *assertion, const char *file,
#endif #endif
errorstream << std::endl << "In thread " << std::hex errorstream << std::endl << "In thread " << std::hex
<< thr_get_current_thread_id() << ":" << std::endl; << std::this_thread::get_id() << ":" << std::endl;
errorstream << file << ":" << line << ": " << function errorstream << file << ":" << line << ": " << function
<< ": An engine assumption '" << assertion << "' failed." << std::endl; << ": An engine assumption '" << assertion << "' failed." << std::endl;
@ -69,7 +69,7 @@ void fatal_error_fn(const char *msg, const char *file,
#endif #endif
errorstream << std::endl << "In thread " << std::hex errorstream << std::endl << "In thread " << std::hex
<< thr_get_current_thread_id() << ":" << std::endl; << std::this_thread::get_id() << ":" << std::endl;
errorstream << file << ":" << line << ": " << function errorstream << file << ":" << line << ": " << function
<< ": A fatal error occured: " << msg << std::endl; << ": A fatal error occured: " << msg << std::endl;
@ -84,19 +84,19 @@ void fatal_error_fn(const char *msg, const char *file,
struct DebugStack struct DebugStack
{ {
DebugStack(threadid_t id); DebugStack(std::thread::id id);
void print(FILE *file, bool everything); void print(FILE *file, bool everything);
void print(std::ostream &os, bool everything); void print(std::ostream &os, bool everything);
threadid_t threadid; std::thread::id thread_id;
char stack[DEBUG_STACK_SIZE][DEBUG_STACK_TEXT_SIZE]; char stack[DEBUG_STACK_SIZE][DEBUG_STACK_TEXT_SIZE];
int stack_i; // Points to the lowest empty position int stack_i; // Points to the lowest empty position
int stack_max_i; // Highest i that was seen int stack_max_i; // Highest i that was seen
}; };
DebugStack::DebugStack(threadid_t id) DebugStack::DebugStack(std::thread::id id)
{ {
threadid = id; thread_id = id;
stack_i = 0; stack_i = 0;
stack_max_i = 0; stack_max_i = 0;
memset(stack, 0, DEBUG_STACK_SIZE*DEBUG_STACK_TEXT_SIZE); memset(stack, 0, DEBUG_STACK_SIZE*DEBUG_STACK_TEXT_SIZE);
@ -105,52 +105,43 @@ DebugStack::DebugStack(threadid_t id)
void DebugStack::print(FILE *file, bool everything) void DebugStack::print(FILE *file, bool everything)
{ {
std::ostringstream os; std::ostringstream os;
os << threadid; os << thread_id;
fprintf(file, "DEBUG STACK FOR THREAD %s:\n", fprintf(file, "DEBUG STACK FOR THREAD %s:\n",
os.str().c_str()); os.str().c_str());
for(int i=0; i<stack_max_i; i++) for (int i = 0; i < stack_max_i; i++) {
{ if (i == stack_i && everything == false)
if(i == stack_i && everything == false)
break; break;
if(i < stack_i) if (i < stack_i)
fprintf(file, "#%d %s\n", i, stack[i]); fprintf(file, "#%d %s\n", i, stack[i]);
else else
fprintf(file, "(Leftover data: #%d %s)\n", i, stack[i]); fprintf(file, "(Leftover data: #%d %s)\n", i, stack[i]);
} }
if(stack_i == DEBUG_STACK_SIZE) if (stack_i == DEBUG_STACK_SIZE)
fprintf(file, "Probably overflown.\n"); fprintf(file, "Probably overflown.\n");
} }
void DebugStack::print(std::ostream &os, bool everything) void DebugStack::print(std::ostream &os, bool everything)
{ {
os<<"DEBUG STACK FOR THREAD "<<threadid<<": "<<std::endl; os<<"DEBUG STACK FOR THREAD "<<thread_id<<": "<<std::endl;
for(int i=0; i<stack_max_i; i++) for(int i = 0; i < stack_max_i; i++) {
{
if(i == stack_i && everything == false) if(i == stack_i && everything == false)
break; break;
if(i < stack_i) if (i < stack_i)
os<<"#"<<i<<" "<<stack[i]<<std::endl; os<<"#"<<i<<" "<<stack[i]<<std::endl;
else else
os<<"(Leftover data: #"<<i<<" "<<stack[i]<<")"<<std::endl; os<<"(Leftover data: #"<<i<<" "<<stack[i]<<")"<<std::endl;
} }
if(stack_i == DEBUG_STACK_SIZE) if (stack_i == DEBUG_STACK_SIZE)
os<<"Probably overflown."<<std::endl; os<<"Probably overflown."<<std::endl;
} }
// Note: Using pthread_t (that is, threadid_t on POSIX platforms) as the key to std::map<std::thread::id, DebugStack*> g_debug_stacks;
// a std::map is naughty. Formally, a pthread_t may only be compared using
// pthread_equal() - pthread_t lacks the well-ordered property needed for
// comparisons in binary searches. This should be fixed at some point by
// defining a custom comparator with an arbitrary but stable ordering of
// pthread_t, but it isn't too important since none of our supported platforms
// implement pthread_t as a non-ordinal type.
std::map<threadid_t, DebugStack*> g_debug_stacks;
std::mutex g_debug_stacks_mutex; std::mutex g_debug_stacks_mutex;
void debug_stacks_init() void debug_stacks_init()
@ -163,11 +154,8 @@ void debug_stacks_print_to(std::ostream &os)
os<<"Debug stacks:"<<std::endl; os<<"Debug stacks:"<<std::endl;
for(std::map<threadid_t, DebugStack*>::iterator for (auto it : g_debug_stacks) {
i = g_debug_stacks.begin(); it.second->print(os, false);
i != g_debug_stacks.end(); ++i)
{
i->second->print(os, false);
} }
} }
@ -178,36 +166,29 @@ void debug_stacks_print()
DebugStacker::DebugStacker(const char *text) DebugStacker::DebugStacker(const char *text)
{ {
threadid_t threadid = thr_get_current_thread_id(); std::thread::id thread_id = std::this_thread::get_id();
MutexAutoLock lock(g_debug_stacks_mutex); MutexAutoLock lock(g_debug_stacks_mutex);
std::map<threadid_t, DebugStack*>::iterator n; auto n = g_debug_stacks.find(thread_id);
n = g_debug_stacks.find(threadid); if (n != g_debug_stacks.end()) {
if(n != g_debug_stacks.end())
{
m_stack = n->second; m_stack = n->second;
} } else {
else
{
/*DEBUGPRINT("Creating new debug stack for thread %x\n", /*DEBUGPRINT("Creating new debug stack for thread %x\n",
(unsigned int)threadid);*/ (unsigned int)thread_id);*/
m_stack = new DebugStack(threadid); m_stack = new DebugStack(thread_id);
g_debug_stacks[threadid] = m_stack; g_debug_stacks[thread_id] = m_stack;
} }
if(m_stack->stack_i >= DEBUG_STACK_SIZE) if (m_stack->stack_i >= DEBUG_STACK_SIZE) {
{
m_overflowed = true; m_overflowed = true;
} } else {
else
{
m_overflowed = false; m_overflowed = false;
snprintf(m_stack->stack[m_stack->stack_i], snprintf(m_stack->stack[m_stack->stack_i],
DEBUG_STACK_TEXT_SIZE, "%s", text); DEBUG_STACK_TEXT_SIZE, "%s", text);
m_stack->stack_i++; m_stack->stack_i++;
if(m_stack->stack_i > m_stack->stack_max_i) if (m_stack->stack_i > m_stack->stack_max_i)
m_stack->stack_max_i = m_stack->stack_i; m_stack->stack_max_i = m_stack->stack_i;
} }
} }
@ -216,18 +197,17 @@ DebugStacker::~DebugStacker()
{ {
MutexAutoLock lock(g_debug_stacks_mutex); MutexAutoLock lock(g_debug_stacks_mutex);
if(m_overflowed == true) if (m_overflowed == true)
return; return;
m_stack->stack_i--; m_stack->stack_i--;
if(m_stack->stack_i == 0) if (m_stack->stack_i == 0) {
{ std::thread::id thread_id = m_stack->thread_id;
threadid_t threadid = m_stack->threadid;
/*DEBUGPRINT("Deleting debug stack for thread %x\n", /*DEBUGPRINT("Deleting debug stack for thread %x\n",
(unsigned int)threadid);*/ (unsigned int)thread_id);*/
delete m_stack; delete m_stack;
g_debug_stacks.erase(threadid); g_debug_stacks.erase(thread_id);
} }
} }

View File

@ -245,7 +245,7 @@ public:
{ {
#ifndef SERVER #ifndef SERVER
m_main_thread = thr_get_current_thread_id(); m_main_thread = std::this_thread::get_id();
#endif #endif
clear(); clear();
} }
@ -320,7 +320,7 @@ public:
<<name<<"\""<<std::endl; <<name<<"\""<<std::endl;
// This is not thread-safe // This is not thread-safe
sanity_check(thr_is_current_thread(m_main_thread)); sanity_check(std::this_thread::get_id() == m_main_thread);
// Skip if already in cache // Skip if already in cache
ClientCached *cc = NULL; ClientCached *cc = NULL;
@ -356,15 +356,12 @@ public:
{ {
ClientCached *cc = NULL; ClientCached *cc = NULL;
m_clientcached.get(name, &cc); m_clientcached.get(name, &cc);
if(cc) if (cc)
return cc; return cc;
if(thr_is_current_thread(m_main_thread)) if (std::this_thread::get_id() == m_main_thread) {
{
return createClientCachedDirect(name, client); return createClientCachedDirect(name, client);
} } else {
else
{
// We're gonna ask the result to be put into here // We're gonna ask the result to be put into here
static ResultQueue<std::string, ClientCached*, u8, u8> result_queue; static ResultQueue<std::string, ClientCached*, u8, u8> result_queue;
@ -580,7 +577,7 @@ private:
StringMap m_aliases; StringMap m_aliases;
#ifndef SERVER #ifndef SERVER
// The id of the thread that is allowed to use irrlicht directly // The id of the thread that is allowed to use irrlicht directly
threadid_t m_main_thread; std::thread::id m_main_thread;
// A reference to this can be returned when nothing is found, to avoid NULLs // A reference to this can be returned when nothing is found, to avoid NULLs
mutable ClientCached m_dummy_clientcached; mutable ClientCached m_dummy_clientcached;
// Cached textures and meshes // Cached textures and meshes

View File

@ -223,14 +223,14 @@ void Logger::setLevelSilenced(LogLevel lev, bool silenced)
void Logger::registerThread(const std::string &name) void Logger::registerThread(const std::string &name)
{ {
threadid_t id = thr_get_current_thread_id(); std::thread::id id = std::this_thread::get_id();
MutexAutoLock lock(m_mutex); MutexAutoLock lock(m_mutex);
m_thread_names[id] = name; m_thread_names[id] = name;
} }
void Logger::deregisterThread() void Logger::deregisterThread()
{ {
threadid_t id = thr_get_current_thread_id(); std::thread::id id = std::this_thread::get_id();
MutexAutoLock lock(m_mutex); MutexAutoLock lock(m_mutex);
m_thread_names.erase(id); m_thread_names.erase(id);
} }
@ -253,9 +253,9 @@ const std::string Logger::getLevelLabel(LogLevel lev)
const std::string Logger::getThreadName() const std::string Logger::getThreadName()
{ {
std::map<threadid_t, std::string>::const_iterator it; std::map<std::thread::id, std::string>::const_iterator it;
threadid_t id = thr_get_current_thread_id(); std::thread::id id = std::this_thread::get_id();
it = m_thread_names.find(id); it = m_thread_names.find(id);
if (it != m_thread_names.end()) if (it != m_thread_names.end())
return it->second; return it->second;

View File

@ -24,8 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <queue> #include <queue>
#include <string> #include <string>
#include <fstream> #include <fstream>
#include <thread>
#include <mutex> #include <mutex>
#include "threads.h"
#include "irrlichttypes.h" #include "irrlichttypes.h"
class ILogOutput; class ILogOutput;
@ -79,7 +79,7 @@ private:
// written to when one thread has access currently). // written to when one thread has access currently).
// Works on all known architectures (x86, ARM, MIPS). // Works on all known architectures (x86, ARM, MIPS).
volatile bool m_silenced_levels[LL_MAX]; volatile bool m_silenced_levels[LL_MAX];
std::map<threadid_t, std::string> m_thread_names; std::map<std::thread::id, std::string> m_thread_names;
mutable std::mutex m_mutex; mutable std::mutex m_mutex;
bool m_trace_enabled; bool m_trace_enabled;
}; };

View File

@ -40,7 +40,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "debug.h" #include "debug.h"
#include "constants.h" #include "constants.h"
#include "gettime.h" #include "gettime.h"
#include "threads.h"
#ifdef _MSC_VER #ifdef _MSC_VER
#define SWPRINTF_CHARSTRING L"%S" #define SWPRINTF_CHARSTRING L"%S"

View File

@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <thread>
#include "util/basic_macros.h" #include "util/basic_macros.h"
extern "C" { extern "C" {
@ -29,7 +30,6 @@ extern "C" {
} }
#include "irrlichttypes.h" #include "irrlichttypes.h"
#include "threads.h"
#include "threading/mutex_auto_lock.h" #include "threading/mutex_auto_lock.h"
#include "common/c_types.h" #include "common/c_types.h"
#include "common/c_internal.h" #include "common/c_internal.h"
@ -122,7 +122,7 @@ protected:
bool m_secure; bool m_secure;
#ifdef SCRIPTAPI_LOCK_DEBUG #ifdef SCRIPTAPI_LOCK_DEBUG
int m_lock_recursion_count; int m_lock_recursion_count;
threadid_t m_owning_thread; std::thread::id m_owning_thread;
#endif #endif
private: private:

View File

@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#ifndef S_INTERNAL_H_ #ifndef S_INTERNAL_H_
#define S_INTERNAL_H_ #define S_INTERNAL_H_
#include <thread>
#include "common/c_internal.h" #include "common/c_internal.h"
#include "cpp_api/s_base.h" #include "cpp_api/s_base.h"
@ -35,23 +36,24 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class LockChecker { class LockChecker {
public: public:
LockChecker(int *recursion_counter, threadid_t *owning_thread) LockChecker(int *recursion_counter, std::thread::id *owning_thread)
{ {
m_lock_recursion_counter = recursion_counter; m_lock_recursion_counter = recursion_counter;
m_owning_thread = owning_thread; m_owning_thread = owning_thread;
m_original_level = *recursion_counter; m_original_level = *recursion_counter;
if (*m_lock_recursion_counter > 0) if (*m_lock_recursion_counter > 0) {
assert(thr_is_current_thread(*m_owning_thread)); assert(*m_owning_thread == std::this_thread::get_id());
else } else {
*m_owning_thread = thr_get_current_thread_id(); *m_owning_thread = std::this_thread::get_id();
}
(*m_lock_recursion_counter)++; (*m_lock_recursion_counter)++;
} }
~LockChecker() ~LockChecker()
{ {
assert(thr_is_current_thread(*m_owning_thread)); assert(*m_owning_thread == std::this_thread::get_id());
assert(*m_lock_recursion_counter > 0); assert(*m_lock_recursion_counter > 0);
(*m_lock_recursion_counter)--; (*m_lock_recursion_counter)--;
@ -62,7 +64,7 @@ public:
private: private:
int *m_lock_recursion_counter; int *m_lock_recursion_counter;
int m_original_level; int m_original_level;
threadid_t *m_owning_thread; std::thread::id *m_owning_thread;
}; };
#define SCRIPTAPI_LOCK_CHECK \ #define SCRIPTAPI_LOCK_CHECK \

View File

@ -308,7 +308,7 @@ public:
private: private:
// The id of the thread that is allowed to use irrlicht directly // The id of the thread that is allowed to use irrlicht directly
threadid_t m_main_thread; std::thread::id m_main_thread;
// The irrlicht device // The irrlicht device
IrrlichtDevice *m_device; IrrlichtDevice *m_device;
@ -359,7 +359,7 @@ ShaderSource::ShaderSource(IrrlichtDevice *device):
{ {
assert(m_device); // Pre-condition assert(m_device); // Pre-condition
m_main_thread = thr_get_current_thread_id(); m_main_thread = std::this_thread::get_id();
// Add a dummy ShaderInfo as the first index, named "" // Add a dummy ShaderInfo as the first index, named ""
m_shaderinfo_cache.push_back(ShaderInfo()); m_shaderinfo_cache.push_back(ShaderInfo());
@ -387,7 +387,7 @@ u32 ShaderSource::getShader(const std::string &name,
Get shader Get shader
*/ */
if (thr_is_current_thread(m_main_thread)) { if (std::this_thread::get_id() == m_main_thread) {
return getShaderIdDirect(name, material_type, drawtype); return getShaderIdDirect(name, material_type, drawtype);
} else { } else {
/*errorstream<<"getShader(): Queued: name=\""<<name<<"\""<<std::endl;*/ /*errorstream<<"getShader(): Queued: name=\""<<name<<"\""<<std::endl;*/
@ -446,7 +446,7 @@ u32 ShaderSource::getShaderIdDirect(const std::string &name,
/* /*
Calling only allowed from main thread Calling only allowed from main thread
*/ */
if (!thr_is_current_thread(m_main_thread)) { if (std::this_thread::get_id() != m_main_thread) {
errorstream<<"ShaderSource::getShaderIdDirect() " errorstream<<"ShaderSource::getShaderIdDirect() "
"called not from main thread"<<std::endl; "called not from main thread"<<std::endl;
return 0; return 0;
@ -494,7 +494,7 @@ void ShaderSource::insertSourceShader(const std::string &name_of_shader,
"name_of_shader=\""<<name_of_shader<<"\", " "name_of_shader=\""<<name_of_shader<<"\", "
"filename=\""<<filename<<"\""<<std::endl;*/ "filename=\""<<filename<<"\""<<std::endl;*/
sanity_check(thr_is_current_thread(m_main_thread)); sanity_check(std::this_thread::get_id() == m_main_thread);
m_sourcecache.insert(name_of_shader, filename, program, true); m_sourcecache.insert(name_of_shader, filename, program, true);
} }

View File

@ -23,7 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <IMaterialRendererServices.h> #include <IMaterialRendererServices.h>
#include "irrlichttypes_extrabloated.h" #include "irrlichttypes_extrabloated.h"
#include "threads.h"
#include <string> #include <string>
class IGameDef; class IGameDef;

View File

@ -24,6 +24,7 @@ DEALINGS IN THE SOFTWARE.
*/ */
#include "threading/event.h" #include "threading/event.h"
#include "threading/mutex_auto_lock.h"
void Event::wait() void Event::wait()
{ {

View File

@ -26,10 +26,7 @@ DEALINGS IN THE SOFTWARE.
#ifndef THREADING_EVENT_H #ifndef THREADING_EVENT_H
#define THREADING_EVENT_H #define THREADING_EVENT_H
#include "threads.h"
#include <condition_variable> #include <condition_variable>
#include "threading/mutex_auto_lock.h"
/** A syncronization primitive that will wake up one waiting thread when signaled. /** A syncronization primitive that will wake up one waiting thread when signaled.
* Calling @c signal() multiple times before a waiting thread has had a chance * Calling @c signal() multiple times before a waiting thread has had a chance

View File

@ -180,10 +180,8 @@ bool Thread::getReturnValue(void **ret)
} }
void *Thread::threadProc(void *param) void Thread::threadProc(Thread *thr)
{ {
Thread *thr = (Thread *)param;
#ifdef _AIX #ifdef _AIX
thr->m_kernel_thread_id = thread_self(); thr->m_kernel_thread_id = thread_self();
#endif #endif
@ -201,9 +199,6 @@ void *Thread::threadProc(void *param)
thr->m_running = false; thr->m_running = false;
g_logger.deregisterThread(); g_logger.deregisterThread();
// 0 is returned here to avoid an unnecessary ifdef clause
return 0;
} }

View File

@ -26,10 +26,10 @@ DEALINGS IN THE SOFTWARE.
#pragma once #pragma once
#include "util/basic_macros.h" #include "util/basic_macros.h"
#include "threads.h"
#include <string> #include <string>
#include <atomic> #include <atomic>
#include <thread>
#include <mutex> #include <mutex>
#ifdef _AIX #ifdef _AIX
@ -49,10 +49,12 @@ DEALINGS IN THE SOFTWARE.
#endif #endif
class Thread { class Thread {
public: public:
Thread(const std::string &name=""); Thread(const std::string &name="");
virtual ~Thread(); virtual ~Thread();
DISABLE_CLASS_COPY(Thread)
/* /*
* Begins execution of a new thread at the pure virtual method Thread::run(). * Begins execution of a new thread at the pure virtual method Thread::run().
@ -87,13 +89,12 @@ public:
/* /*
* Returns true if the calling thread is this Thread object. * Returns true if the calling thread is this Thread object.
*/ */
bool isCurrentThread() { return thr_is_current_thread(getThreadId()); } bool isCurrentThread() { return std::this_thread::get_id() == getThreadId(); }
inline bool isRunning() { return m_running; } bool isRunning() { return m_running; }
inline bool stopRequested() { return m_request_stop; } bool stopRequested() { return m_request_stop; }
inline threadid_t getThreadId() { return m_thread_obj->get_id(); } std::thread::id getThreadId() { return m_thread_obj->get_id(); }
inline threadhandle_t getThreadHandle() { return m_thread_obj->native_handle(); }
/* /*
* Gets the thread return value. * Gets the thread return value.
@ -139,6 +140,11 @@ protected:
virtual void *run() = 0; virtual void *run() = 0;
private: private:
std::thread::native_handle_type getThreadHandle()
{ return m_thread_obj->native_handle(); }
static void threadProc(Thread *thr);
void *m_retval; void *m_retval;
bool m_joinable; bool m_joinable;
std::atomic<bool> m_request_stop; std::atomic<bool> m_request_stop;
@ -148,13 +154,11 @@ private:
std::thread *m_thread_obj; std::thread *m_thread_obj;
static ThreadStartFunc threadProc;
#ifdef _AIX #ifdef _AIX
// For AIX, there does not exist any mapping from pthread_t to tid_t // For AIX, there does not exist any mapping from pthread_t to tid_t
// available to us, so we maintain one ourselves. This is set on thread start. // available to us, so we maintain one ourselves. This is set on thread start.
tid_t m_kernel_thread_id; tid_t m_kernel_thread_id;
#endif #endif
Thread(const Thread &) = delete;
}; };

View File

@ -1,51 +0,0 @@
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#pragma once
///////////////
#include <thread>
//
// threadid_t, threadhandle_t
//
typedef std::thread::id threadid_t;
typedef std::thread::native_handle_type threadhandle_t;
//
// ThreadStartFunc
//
typedef void *ThreadStartFunc(void *param);
inline threadid_t thr_get_current_thread_id()
{
return std::this_thread::get_id();
}
inline bool thr_compare_thread_id(threadid_t thr1, threadid_t thr2)
{
return thr1 == thr2;
}
inline bool thr_is_current_thread(threadid_t thr)
{
return thr_compare_thread_id(thr_get_current_thread_id(), thr);
}