1
0
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:
David Capello 2010-10-02 20:20:59 -03:00
parent b66371f95a
commit 3f7333b9ed
3 changed files with 51 additions and 32 deletions

@ -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(&nothing);
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);