Thread System 0.3.1
High-performance C++20 thread pool with work stealing and DAG scheduling
Loading...
Searching...
No Matches
kcenon::thread::lifecycle_controller Class Reference

Centralized thread lifecycle state and synchronization management. More...

#include <lifecycle_controller.h>

Collaboration diagram for kcenon::thread::lifecycle_controller:
Collaboration graph

Public Member Functions

 lifecycle_controller (const lifecycle_controller &)=delete
 
lifecycle_controlleroperator= (const lifecycle_controller &)=delete
 
 lifecycle_controller (lifecycle_controller &&)=delete
 
lifecycle_controlleroperator= (lifecycle_controller &&)=delete
 
 lifecycle_controller ()
 Constructs a new lifecycle_controller in Created state.
 
 ~lifecycle_controller ()=default
 Destructor.
 
auto get_state () const noexcept -> thread_conditions
 Gets the current thread condition/state.
 
auto set_state (thread_conditions state) noexcept -> void
 Sets the thread condition/state.
 
auto is_running () const noexcept -> bool
 Checks if the thread is currently running.
 
auto set_stopped () noexcept -> void
 Marks the thread as stopped.
 
auto initialize_for_start () -> void
 Initializes the controller for a new thread start.
 
auto request_stop () noexcept -> void
 Requests the thread to stop.
 
auto is_stop_requested () const noexcept -> bool
 Checks if a stop has been requested.
 
auto has_active_source () const noexcept -> bool
 Checks if the controller has an active stop source (C++20 only).
 
auto reset_stop_source () noexcept -> void
 Resets the stop control mechanism after thread completion.
 
auto acquire_lock () -> std::unique_lock< std::mutex >
 Acquires a unique lock on the condition variable mutex.
 
template<typename Predicate >
auto wait (std::unique_lock< std::mutex > &lock, Predicate pred) -> void
 Waits on the condition variable with a predicate.
 
template<typename Rep , typename Period , typename Predicate >
auto wait_for (std::unique_lock< std::mutex > &lock, const std::chrono::duration< Rep, Period > &timeout, Predicate pred) -> bool
 Waits on the condition variable with a timeout and predicate.
 
auto notify_one () -> void
 Notifies one waiting thread.
 
auto notify_all () -> void
 Notifies all waiting threads.
 

Private Attributes

std::mutex cv_mutex_
 Mutex for condition variable operations.
 
std::condition_variable condition_
 Condition variable for thread signaling.
 
std::atomic< thread_conditionsstate_ {thread_conditions::Created}
 Current thread state.
 
std::atomic< bool > stop_requested_ {false}
 Atomic flag for stop request (legacy mode).
 

Detailed Description

Centralized thread lifecycle state and synchronization management.

The lifecycle_controller class consolidates duplicated thread lifecycle management patterns (start, stop, state transitions, condition variables) into a single reusable component. Thread classes can use composition with this controller instead of implementing these patterns themselves.

Key Features

  • Thread state management (Created, Waiting, Working, Stopping, Stopped)
  • Condition variable signaling for wake-ups
  • Stop request handling (supports both std::jthread and legacy std::thread)
  • Thread-safe state queries and transitions

Thread Safety

All public methods are thread-safe. The class uses internal synchronization to protect state transitions and condition variable operations.

Example Usage

class my_thread {
private:
public:
void start() {
lifecycle_.initialize_for_start();
// spawn thread...
}
void stop() {
lifecycle_.request_stop();
lifecycle_.notify_all();
// join thread...
lifecycle_.set_stopped();
}
void worker_loop() {
while (!lifecycle_.is_stop_requested() || has_work()) {
lifecycle_.set_state(thread_conditions::Waiting);
lifecycle_.wait_for(timeout, [this] { return has_work(); });
lifecycle_.set_state(thread_conditions::Working);
do_work();
}
}
};
Centralized thread lifecycle state and synchronization management.
auto is_stop_requested() const noexcept -> bool
Checks if a stop has been requested.
auto set_state(thread_conditions state) noexcept -> void
Sets the thread condition/state.
auto wait_for(std::unique_lock< std::mutex > &lock, const std::chrono::duration< Rep, Period > &timeout, Predicate pred) -> bool
Waits on the condition variable with a timeout and predicate.
auto notify_all() -> void
Notifies all waiting threads.
auto request_stop() noexcept -> void
Requests the thread to stop.
auto initialize_for_start() -> void
Initializes the controller for a new thread start.
auto set_stopped() noexcept -> void
Marks the thread as stopped.

Definition at line 79 of file lifecycle_controller.h.

Constructor & Destructor Documentation

◆ lifecycle_controller() [1/3]

kcenon::thread::lifecycle_controller::lifecycle_controller ( const lifecycle_controller & )
delete

◆ lifecycle_controller() [2/3]

kcenon::thread::lifecycle_controller::lifecycle_controller ( lifecycle_controller && )
delete

◆ lifecycle_controller() [3/3]

kcenon::thread::lifecycle_controller::lifecycle_controller ( )

Constructs a new lifecycle_controller in Created state.

Definition at line 9 of file lifecycle_controller.cpp.

11#ifdef USE_STD_JTHREAD
12 , stop_source_(std::nullopt)
13#else
14 , stop_requested_(false)
15#endif
16 {
17 }
std::atomic< bool > stop_requested_
Atomic flag for stop request (legacy mode).
std::atomic< thread_conditions > state_
Current thread state.
@ Created
Thread created but not started.

◆ ~lifecycle_controller()

kcenon::thread::lifecycle_controller::~lifecycle_controller ( )
default

Destructor.

Member Function Documentation

◆ acquire_lock()

auto kcenon::thread::lifecycle_controller::acquire_lock ( ) -> std::unique_lock<std::mutex>
nodiscard

Acquires a unique lock on the condition variable mutex.

Returns
A unique_lock holding the mutex.

Use this to prepare for wait operations.

Definition at line 95 of file lifecycle_controller.cpp.

96 {
97 return std::unique_lock<std::mutex>(cv_mutex_);
98 }
std::mutex cv_mutex_
Mutex for condition variable operations.

◆ get_state()

auto kcenon::thread::lifecycle_controller::get_state ( ) const -> thread_conditions
nodiscardnoexcept

Gets the current thread condition/state.

Returns
The current thread_conditions value.

Thread Safety:

  • Safe to call from any thread
  • Uses atomic load with acquire memory ordering

Definition at line 19 of file lifecycle_controller.cpp.

20 {
21 return state_.load(std::memory_order_acquire);
22 }

References state_.

◆ has_active_source()

auto kcenon::thread::lifecycle_controller::has_active_source ( ) const -> bool
nodiscardnoexcept

Checks if the controller has an active stop source (C++20 only).

Returns
true if a stop_source is active, false otherwise.

In legacy mode, checks if stop has NOT been requested (indicating active state).

Definition at line 76 of file lifecycle_controller.cpp.

77 {
78#ifdef USE_STD_JTHREAD
79 return stop_source_.has_value();
80#else
81 // In legacy mode, check if we're in an active state (not stopped/created)
82 auto state = state_.load(std::memory_order_acquire);
83 return state == thread_conditions::Working ||
85#endif
86 }
@ Waiting
Thread waiting for work or tasks.
@ Working
Thread currently processing a task.

References state_, kcenon::thread::Waiting, and kcenon::thread::Working.

◆ initialize_for_start()

auto kcenon::thread::lifecycle_controller::initialize_for_start ( ) -> void

Initializes the controller for a new thread start.

Resets the stop request flag and prepares for a new thread lifecycle. In C++20 jthread mode, creates a new stop_source.

Note
Must be called before spawning the worker thread.

Definition at line 41 of file lifecycle_controller.cpp.

42 {
43#ifdef USE_STD_JTHREAD
44 stop_source_ = std::stop_source();
45#else
46 stop_requested_.store(false, std::memory_order_release);
47#endif
49 }

References kcenon::thread::Created.

◆ is_running()

auto kcenon::thread::lifecycle_controller::is_running ( ) const -> bool
nodiscardnoexcept

Checks if the thread is currently running.

Returns
true if state is Working or Waiting, false otherwise.

Definition at line 29 of file lifecycle_controller.cpp.

30 {
31 auto condition = state_.load(std::memory_order_acquire);
32 return condition == thread_conditions::Working ||
33 condition == thread_conditions::Waiting;
34 }

References state_, kcenon::thread::Waiting, and kcenon::thread::Working.

◆ is_stop_requested()

auto kcenon::thread::lifecycle_controller::is_stop_requested ( ) const -> bool
nodiscardnoexcept

Checks if a stop has been requested.

Returns
true if stop has been requested, false otherwise.

Thread Safety:

  • Safe to call from any thread

Definition at line 63 of file lifecycle_controller.cpp.

64 {
65#ifdef USE_STD_JTHREAD
66 if (stop_source_.has_value())
67 {
68 return stop_source_.value().stop_requested();
69 }
70 return true;
71#else
72 return stop_requested_.load(std::memory_order_acquire);
73#endif
74 }

References stop_requested_.

◆ notify_all()

auto kcenon::thread::lifecycle_controller::notify_all ( ) -> void

Notifies all waiting threads.

Thread Safety:

  • Safe to call from any thread

Definition at line 106 of file lifecycle_controller.cpp.

107 {
108 std::scoped_lock<std::mutex> lock(cv_mutex_);
109 condition_.notify_all();
110 }
std::condition_variable condition_
Condition variable for thread signaling.

◆ notify_one()

auto kcenon::thread::lifecycle_controller::notify_one ( ) -> void

Notifies one waiting thread.

Thread Safety:

  • Safe to call from any thread

Definition at line 100 of file lifecycle_controller.cpp.

101 {
102 std::scoped_lock<std::mutex> lock(cv_mutex_);
103 condition_.notify_one();
104 }

◆ operator=() [1/2]

lifecycle_controller & kcenon::thread::lifecycle_controller::operator= ( const lifecycle_controller & )
delete

◆ operator=() [2/2]

lifecycle_controller & kcenon::thread::lifecycle_controller::operator= ( lifecycle_controller && )
delete

◆ request_stop()

auto kcenon::thread::lifecycle_controller::request_stop ( ) -> void
noexcept

Requests the thread to stop.

In C++20 mode, calls request_stop() on the stop_source. In legacy mode, sets the atomic stop_requested_ flag to true.

Thread Safety:

  • Safe to call from any thread
  • The request is visible to the worker thread immediately

Definition at line 51 of file lifecycle_controller.cpp.

52 {
53#ifdef USE_STD_JTHREAD
54 if (stop_source_.has_value())
55 {
56 stop_source_.value().request_stop();
57 }
58#else
59 stop_requested_.store(true, std::memory_order_release);
60#endif
61 }

References stop_requested_.

◆ reset_stop_source()

auto kcenon::thread::lifecycle_controller::reset_stop_source ( ) -> void
noexcept

Resets the stop control mechanism after thread completion.

In C++20 mode, resets the stop_source. Should be called after thread join to clean up resources.

Definition at line 88 of file lifecycle_controller.cpp.

89 {
90#ifdef USE_STD_JTHREAD
91 stop_source_.reset();
92#endif
93 }

◆ set_state()

auto kcenon::thread::lifecycle_controller::set_state ( thread_conditions state) -> void
noexcept

Sets the thread condition/state.

Parameters
stateThe new thread_conditions value.

Thread Safety:

  • Safe to call from any thread
  • Uses atomic store with release memory ordering

Definition at line 24 of file lifecycle_controller.cpp.

25 {
26 state_.store(state, std::memory_order_release);
27 }

Referenced by set_stopped().

Here is the caller graph for this function:

◆ set_stopped()

auto kcenon::thread::lifecycle_controller::set_stopped ( ) -> void
noexcept

Marks the thread as stopped.

Convenience method equivalent to set_state(thread_conditions::Stopped).

Definition at line 36 of file lifecycle_controller.cpp.

References set_state(), and kcenon::thread::Stopped.

Here is the call graph for this function:

◆ wait()

template<typename Predicate >
auto kcenon::thread::lifecycle_controller::wait ( std::unique_lock< std::mutex > & lock,
Predicate pred ) -> void
inline

Waits on the condition variable with a predicate.

Template Parameters
PredicateA callable returning bool.
Parameters
lockThe unique_lock (must be holding cv_mutex_).
predThe predicate to check.

Waits until pred() returns true OR stop is requested.

Definition at line 206 of file lifecycle_controller.h.

207 {
208#ifdef USE_STD_JTHREAD
209 if (stop_source_.has_value())
210 {
211 auto stop_token = stop_source_.value().get_token();
212 condition_.wait(lock, [this, &stop_token, &pred]() {
213 return stop_token.stop_requested() || pred();
214 });
215 }
216 else
217 {
218 condition_.wait(lock, pred);
219 }
220#else
221 condition_.wait(lock, [this, &pred]() {
222 return stop_requested_.load(std::memory_order_acquire) || pred();
223 });
224#endif
225 }

◆ wait_for()

template<typename Rep , typename Period , typename Predicate >
auto kcenon::thread::lifecycle_controller::wait_for ( std::unique_lock< std::mutex > & lock,
const std::chrono::duration< Rep, Period > & timeout,
Predicate pred ) -> bool
inline

Waits on the condition variable with a timeout and predicate.

Template Parameters
RepDuration rep type.
PeriodDuration period type.
PredicateA callable returning bool.
Parameters
lockThe unique_lock (must be holding cv_mutex_).
timeoutThe maximum duration to wait.
predThe predicate to check.
Returns
true if pred() is satisfied, false if timed out.

Definition at line 238 of file lifecycle_controller.h.

241 {
242#ifdef USE_STD_JTHREAD
243 if (stop_source_.has_value())
244 {
245 auto stop_token = stop_source_.value().get_token();
246 return condition_.wait_for(lock, timeout, [this, &stop_token, &pred]() {
247 return stop_token.stop_requested() || pred();
248 });
249 }
250 else
251 {
252 return condition_.wait_for(lock, timeout, pred);
253 }
254#else
255 return condition_.wait_for(lock, timeout, [this, &pred]() {
256 return stop_requested_.load(std::memory_order_acquire) || pred();
257 });
258#endif
259 }

Member Data Documentation

◆ condition_

std::condition_variable kcenon::thread::lifecycle_controller::condition_
private

Condition variable for thread signaling.

Definition at line 282 of file lifecycle_controller.h.

◆ cv_mutex_

std::mutex kcenon::thread::lifecycle_controller::cv_mutex_
private

Mutex for condition variable operations.

Definition at line 279 of file lifecycle_controller.h.

◆ state_

std::atomic<thread_conditions> kcenon::thread::lifecycle_controller::state_ {thread_conditions::Created}
private

Current thread state.

Definition at line 285 of file lifecycle_controller.h.

Referenced by get_state(), has_active_source(), and is_running().

◆ stop_requested_

std::atomic<bool> kcenon::thread::lifecycle_controller::stop_requested_ {false}
private

Atomic flag for stop request (legacy mode).

Definition at line 292 of file lifecycle_controller.h.

292{false};

Referenced by is_stop_requested(), and request_stop().


The documentation for this class was generated from the following files: