Skip to content

Commit

Permalink
gral_thread
Browse files Browse the repository at this point in the history
  • Loading branch information
eyelash committed Sep 17, 2024
1 parent ec60c06 commit f586cd5
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 0 deletions.
4 changes: 4 additions & 0 deletions demos/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ target_link_libraries(file_dialogs gral)

add_executable(text text.c)
target_link_libraries(text gral)

add_executable(thread thread.cpp)
target_link_libraries(thread gral)
target_compile_features(thread PUBLIC cxx_std_11)
11 changes: 11 additions & 0 deletions demos/thread.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <gral_thread.hpp>

struct Foo {
void hello() {}
};

Foo foo;

int main() {
auto thread = gral::Thread::create<Foo, &Foo::hello>(&foo);
}
71 changes: 71 additions & 0 deletions gral_thread.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#ifndef GRAL_THREAD_HPP
#define GRAL_THREAD_HPP

#ifdef GRAL_WINDOWS
#include <Windows.h>
#include <process.h>
#else
#include <pthread.h>
#endif

namespace gral {

class Thread {
#ifdef GRAL_WINDOWS
HANDLE thread;
template <class C, void (C::*M)()> static unsigned WINAPI thread_function(LPVOID user_data) {
C *object = static_cast<C *>(user_data);
(object->*M)();
return 0;
}
Thread(unsigned (*function)(LPVOID), LPVOID user_data) {
thread = reinterpret_cast<HANDLE>(_beginthreadex(nullptr, 0, function, user_data, 0, nullptr));
}
#else
pthread_t thread;
template <class C, void (C::*M)()> static void *thread_function(void *user_data) {
C *object = static_cast<C *>(user_data);
(object->*M)();
return nullptr;
}
Thread(void *(*function)(void *), void *user_data) {
pthread_create(&thread, nullptr, function, user_data);
}
#endif
public:
Thread(): thread(0) {}
Thread(Thread const &) = delete;
Thread(Thread &&thread): thread(thread.thread) {
this->thread = thread.thread;
thread.thread = 0;
}
~Thread() {
if (thread) {
#ifdef GRAL_WINDOWS
CloseHandle(thread);
#else
pthread_detach(thread);
#endif
}
}
Thread &operator =(Thread const &) = delete;
explicit operator bool() const {
return thread;
}
template <class C, void (C::*M)()> static Thread create(C *object) {
return Thread(&thread_function<C, M>, object);
}
void join() {
#ifdef GRAL_WINDOWS
WaitForSingleObject(thread, INFINITE);
CloseHandle(thread);
#else
pthread_join(thread, NULL);
#endif
thread = 0;
}
};

}

#endif

0 comments on commit f586cd5

Please sign in to comment.