dius 0.1.0
Loading...
Searching...
No Matches
thread.h
Go to the documentation of this file.
1#pragma once
2
3#include "di/assert/prelude.h"
4#include "di/chrono/duration/duration_literals.h"
5#include "di/function/prelude.h"
6#include "di/meta/util.h"
7#include "di/util/prelude.h"
8#include "dius/error.h"
9#include "dius/platform_thread.h"
10#include "steady_clock.h"
11
12namespace dius {
13namespace this_thread {
14 void sleep_for(di::Nanoseconds duration);
16}
17
23class Thread {
24private:
25 static auto do_start(di::Function<void()>) -> di::Result<Thread>;
26
27 explicit Thread(di::Box<PlatformThread, PlatformThreadDeleter> platform_thread)
28 : m_platform_thread(di::move(platform_thread)) {}
29
30public:
31 using Id = di::ThreadId;
32
33 template<di::concepts::MovableValue F, di::concepts::MovableValue... Args>
34 requires(di::concepts::InvocableTo<F, void, Args...>)
35 static auto create(F&& function, Args&&... args) -> di::Result<Thread> {
36 auto copied_function = di::bind_front(di::forward<F>(function), di::forward<Args>(args)...);
37 auto erased_function = di::make_function<void()>(di::move(copied_function));
38 return do_start(di::move(erased_function));
39 }
40
41 Thread() = default;
42
43 Thread(Thread const&) = delete;
44 Thread(Thread&& other) : m_platform_thread(di::move(other.m_platform_thread)) {}
45
46 ~Thread() { ASSERT(!joinable()); }
47
48 auto operator=(Thread const&) -> Thread& = delete;
49 auto operator=(Thread&& other) -> Thread& {
50 ASSERT(!joinable());
51 m_platform_thread = di::move(other.m_platform_thread);
52 return *this;
53 }
54
55 [[nodiscard]] auto joinable() const -> bool { return Id() != get_id(); }
56 [[nodiscard]] auto get_id() const -> Id { return m_platform_thread ? m_platform_thread->id() : Id(); }
57
63 auto join() -> di::Result<void> {
64 if (!m_platform_thread) {
65 return di::Unexpected(PosixError::InvalidArgument);
66 }
67 auto guard = di::ScopeExit([&] {
68 m_platform_thread.reset();
69 });
70 return m_platform_thread->join();
71 }
72
73private:
74 friend void tag_invoke(di::Tag<di::swap>, Thread& a, Thread& b) {
75 di::swap(a.m_platform_thread, b.m_platform_thread);
76 }
77
78 di::Box<PlatformThread, PlatformThreadDeleter> m_platform_thread;
79};
80}
di::TimePoint< SteadyClock > TimePoint
Definition steady_clock.h:13
Thread(Thread const &)=delete
auto joinable() const -> bool
Definition thread.h:55
di::ThreadId Id
Definition thread.h:31
~Thread()
Definition thread.h:46
auto operator=(Thread const &) -> Thread &=delete
friend void tag_invoke(di::Tag< di::swap >, Thread &a, Thread &b)
Definition thread.h:74
Thread(Thread &&other)
Definition thread.h:44
Thread()=default
auto operator=(Thread &&other) -> Thread &
Definition thread.h:49
auto get_id() const -> Id
Definition thread.h:56
static auto create(F &&function, Args &&... args) -> di::Result< Thread >
Definition thread.h:35
auto join() -> di::Result< void >
Wait for the spawned thread's execution to terminate.
Definition thread.h:63
Definition error.h:7
Definition thread.h:13
void sleep_for(di::Nanoseconds duration)
void sleep_until(SteadyClock::TimePoint time_point)
Definition directory_entry.h:11