mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-17 22:20:55 +00:00
Fix pthread implementation of base::thread class (problems joining threads, initializing m_id field, etc.).
This commit is contained in:
parent
b66371f95a
commit
3f7333b9ed
@ -39,7 +39,7 @@ namespace {
|
||||
|
||||
base::thread::thread()
|
||||
: m_native_handle(NULL)
|
||||
, m_id()
|
||||
, m_id(this_thread::get_id())
|
||||
{
|
||||
}
|
||||
|
||||
@ -47,15 +47,11 @@ base::thread::~thread()
|
||||
{
|
||||
if (joinable())
|
||||
detach();
|
||||
|
||||
#ifdef USE_PTHREADS
|
||||
delete (pthread_t*)m_native_handle;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool base::thread::joinable() const
|
||||
{
|
||||
return (m_id != this_thread::get_id());
|
||||
return (m_id != 0 && m_id != this_thread::get_id());
|
||||
}
|
||||
|
||||
void base::thread::join()
|
||||
@ -64,7 +60,7 @@ void base::thread::join()
|
||||
#ifdef WIN32
|
||||
::WaitForSingleObject(m_native_handle, INFINITE);
|
||||
#else
|
||||
::pthread_join(*(pthread_t*)m_native_handle, NULL);
|
||||
::pthread_join(m_id.m_native_id, NULL);
|
||||
#endif
|
||||
detach();
|
||||
}
|
||||
@ -75,32 +71,47 @@ void base::thread::detach()
|
||||
if (joinable()) {
|
||||
#ifdef WIN32
|
||||
::CloseHandle(m_native_handle);
|
||||
#else
|
||||
::pthread_detach(*(pthread_t*)m_native_handle);
|
||||
delete (pthread_t*)m_native_handle;
|
||||
#endif
|
||||
m_native_handle = NULL;
|
||||
#else
|
||||
::pthread_detach(m_id.m_native_id);
|
||||
#endif
|
||||
m_id = id();
|
||||
}
|
||||
}
|
||||
|
||||
base::thread::id base::thread::get_id() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
base::thread::native_handle_type base::thread::native_handle()
|
||||
{
|
||||
#ifdef WIN32
|
||||
return (native_handle_type)m_native_handle;
|
||||
#else
|
||||
return (native_handle_type)m_id.m_native_id;
|
||||
#endif
|
||||
}
|
||||
|
||||
void base::thread::launch_thread(func_wrapper* f)
|
||||
{
|
||||
m_native_handle = NULL;
|
||||
m_id = id();
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
DWORD native_id;
|
||||
m_native_handle = ::CreateThread(NULL, 0, win32_thread_proxy, (LPVOID)f,
|
||||
CREATE_SUSPENDED, &native_id);
|
||||
m_id.m_native_id = native_id;
|
||||
m_id = id((unsigned int)native_id);
|
||||
|
||||
ResumeThread(m_native_handle);
|
||||
|
||||
#else
|
||||
|
||||
pthread_t thread;
|
||||
if (::pthread_create(&thread, NULL, pthread_thread_proxy, f))
|
||||
m_native_handle = new pthread_t(thread);
|
||||
else
|
||||
m_native_handle = NULL;
|
||||
if (::pthread_create(&thread, NULL, pthread_thread_proxy, f) == 0)
|
||||
m_id = id((unsigned int)thread);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
@ -28,8 +28,7 @@ namespace base { // Based on C++0x threads lib
|
||||
bool operator> (const id& y) const { return m_native_id > y.m_native_id; }
|
||||
bool operator>=(const id& y) const { return m_native_id >= y.m_native_id; }
|
||||
|
||||
// TODO should we replace this with support for iostreams?
|
||||
//unsigned get_native_id() { return m_native_id; }
|
||||
id& operator=(const id& y) { m_native_id = y.m_native_id; }
|
||||
};
|
||||
|
||||
typedef void* native_handle_type;
|
||||
@ -63,13 +62,8 @@ namespace base { // Based on C++0x threads lib
|
||||
void join();
|
||||
void detach();
|
||||
|
||||
id get_id() const {
|
||||
return m_id;
|
||||
}
|
||||
|
||||
native_handle_type native_handle() {
|
||||
return m_native_handle;
|
||||
}
|
||||
id get_id() const;
|
||||
native_handle_type native_handle();
|
||||
|
||||
class details {
|
||||
public:
|
||||
|
@ -8,23 +8,37 @@
|
||||
|
||||
#include "base/thread.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using std::cout;
|
||||
using namespace base;
|
||||
|
||||
static bool flag = false;
|
||||
void nothing() { }
|
||||
|
||||
static void func0() {
|
||||
TEST(Thread, NotJoinable)
|
||||
{
|
||||
thread t;
|
||||
EXPECT_FALSE(t.joinable());
|
||||
}
|
||||
|
||||
TEST(Thread, Joinable)
|
||||
{
|
||||
thread t(¬hing);
|
||||
EXPECT_TRUE(t.joinable());
|
||||
t.join();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool flag = false;
|
||||
|
||||
void func0() {
|
||||
flag = true;
|
||||
}
|
||||
|
||||
static void func1(int x) {
|
||||
void func1(int x) {
|
||||
flag = true;
|
||||
EXPECT_EQ(2, x);
|
||||
}
|
||||
|
||||
static void func2(int x, int y) {
|
||||
void func2(int x, int y) {
|
||||
flag = true;
|
||||
EXPECT_EQ(2, x);
|
||||
EXPECT_EQ(4, y);
|
||||
|
Loading…
x
Reference in New Issue
Block a user