32#ifndef FENNEC_THREADING_THREAD_H
33#define FENNEC_THREADING_THREAD_H
39#include <fennec/memory/bytes.h>
40#include <fennec/threading/detail/_thread.h>
47 static constexpr pthread_t nullthread = 0;
50 using native_handle_type = pthread_t;
54 constexpr id() noexcept : _id(0) {}
56 constexpr friend bool operator==(
id x,
id y)
noexcept {
63 return pthread_equal(x._id,
y._id) != 0;
65 constexpr friend bool operator!=(
id x,
id y)
noexcept {
return !(x ==
y); }
69 friend struct hash<id>;
70 friend struct formatter<id>;
72 constexpr id(pthread_t
id) : _id(id) {}
78 : _handle(nullthread) {
82 : _handle(th._handle) {
83 th._handle = nullthread;
86 thread(
const thread&) =
delete;
88 template<
typename FuncT,
typename...ArgsT>
89 requires(not is_same_v<thread, remove_cvref_t<FuncT>>)
90 thread(FuncT&& func, ArgsT&&...args)
91 : _handle(nullthread) {
92 using proxy_t = detail::thread_proxy_t<function<FuncT>, ArgsT...>;
93 unique_ptr<proxy_t> proxy = fennec::make_unique<proxy_t>(fennec::forward<FuncT>(func), fennec::forward<ArgsT>(args)...);
95 int_t res = ::pthread_create(&_handle,
nullptr, &detail::_run_thread<proxy_t>(), proxy.get());
96 assertf(res == 0,
"Thread creation failed!");
101 thread& operator=(thread&& th)
noexcept {
102 assertf(_handle == nullthread,
"Attempted to overwrite running thread!");
104 _handle = th._handle;
105 th._handle = nullthread;
111 assertf(_handle == 0,
"Attempted to destruct a running thread!");
114 bool joinable() const noexcept {
115 return _handle != nullthread and pthread_self() != _handle;
119 if (not joinable()) {
123 int_t res = pthread_join(_handle,
nullptr);
124 assertf(res == 0,
"Failed to join thread!");
125 _handle = nullthread;
129 if (not joinable()) {
133 int_t res = pthread_detach(_handle);
134 assertf(res == 0,
"Failed to detatch thread!");
135 _handle = nullthread;
138 void swap(thread& other) {
142 static id current() {
143 return pthread_self();
156struct hash<thread::id> {
157 size_t operator()(thread::id v)
const noexcept {
158 return hash<thread::native_handle_type>()(v._id);
163struct formatter<thread::id> {
164 string operator()(
const format_arg& fmt, thread::id v)
const noexcept {
165 return formatter<thread::native_handle_type>()(fmt, v._id);
constexpr genType y()
Definition constants.h:672
signed int int_t
A signed integer type, size varies by implementation, but typically 32-bit.
Definition types.h:225
constexpr void swap(T &x, T &y) noexcept
Swaps x and y.
Definition utility.h:114