fennec
Loading...
Searching...
No Matches
thread.h
Go to the documentation of this file.
1// =====================================================================================================================
2// fennec, a free and open source game engine
3// Copyright © 2025 Medusa Slockbower
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <https://www.gnu.org/licenses/>.
17// =====================================================================================================================
18
30
31
32#ifndef FENNEC_THREADING_THREAD_H
33#define FENNEC_THREADING_THREAD_H
34
35#include <pthread.h>
39#include <fennec/memory/bytes.h>
40#include <fennec/threading/detail/_thread.h>
41
42namespace fennec
43{
44
45class thread {
46private:
47 static constexpr pthread_t nullthread = 0;
48
49public:
50 using native_handle_type = pthread_t;
51
52 class id {
53 public:
54 constexpr id() noexcept : _id(0) {}
55
56 constexpr friend bool operator==(id x, id y) noexcept {
57 if (x._id == 0) {
58 return y._id == 0;
59 }
60 if (y._id == 0) {
61 return false;
62 }
63 return pthread_equal(x._id, y._id) != 0;
64 }
65 constexpr friend bool operator!=(id x, id y) noexcept { return !(x == y); }
66
67 private:
68 friend class thread;
69 friend struct hash<id>;
70 friend struct formatter<id>;
71
72 constexpr id(pthread_t id) : _id(id) {}
73
74 pthread_t _id;
75 };
76
77 thread() noexcept
78 : _handle(nullthread) {
79 }
80
81 thread(thread&& th)
82 : _handle(th._handle) {
83 th._handle = nullthread;
84 }
85
86 thread(const thread&) = delete;
87
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)...);
94
95 int_t res = ::pthread_create(&_handle, nullptr, &detail::_run_thread<proxy_t>(), proxy.get());
96 assertf(res == 0, "Thread creation failed!");
97
98 proxy.release();
99 }
100
101 thread& operator=(thread&& th) noexcept {
102 assertf(_handle == nullthread, "Attempted to overwrite running thread!");
103
104 _handle = th._handle;
105 th._handle = nullthread;
106
107 return *this;
108 }
109
110 ~thread() {
111 assertf(_handle == 0, "Attempted to destruct a running thread!");
112 }
113
114 bool joinable() const noexcept {
115 return _handle != nullthread and pthread_self() != _handle;
116 }
117
118 void join() {
119 if (not joinable()) {
120 return;
121 }
122
123 int_t res = pthread_join(_handle, nullptr);
124 assertf(res == 0, "Failed to join thread!");
125 _handle = nullthread;
126 }
127
128 void detatch() {
129 if (not joinable()) {
130 return;
131 }
132
133 int_t res = pthread_detach(_handle);
134 assertf(res == 0, "Failed to detatch thread!");
135 _handle = nullthread;
136 }
137
138 void swap(thread& other) {
139 fennec::swap(_handle, other._handle);
140 }
141
142 static id current() {
143 return pthread_self();
144 }
145
146 id get_id() const {
147 return _handle;
148 }
149
150
151private:
152 pthread_t _handle;
153};
154
155template <>
156struct hash<thread::id> {
157 size_t operator()(thread::id v) const noexcept {
158 return hash<thread::native_handle_type>()(v._id);
159 }
160};
161
162template<>
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);
166 }
167};
168
169}
170
171#endif // FENNEC_THREADING_THREAD_H
constexpr genType y()
Definition constants.h:672
Type Traits
Type Transforms
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