idfxx 1.0.0
Modern C++23 components for ESP-IDF
Loading...
Searching...
No Matches
idfxx::task Class Reference

Task lifecycle management. More...

Classes

struct  config
 Task configuration parameters. More...
 
class  self
 Handle for task self-interaction. More...
 

Public Member Functions

 task (const config &cfg, std::move_only_function< void(self &)> task_func)
 Creates a task with a std::move_only_function callback.
 
 task (const config &cfg, void(*task_func)(self &, void *), void *arg)
 Creates a task with a raw function pointer callback.
 
 ~task ()
 Destroys the task, requesting stop and blocking until the task function completes.
 
 task (const task &)=delete
 
taskoperator= (const task &)=delete
 
 task (task &&)=delete
 
taskoperator= (task &&)=delete
 
TaskHandle_t idf_handle () const noexcept
 Returns the underlying FreeRTOS task handle.
 
const std::string & name () const noexcept
 Returns the task name.
 
unsigned int priority () const noexcept
 Returns the current task priority.
 
size_t stack_high_water_mark () const noexcept
 Returns the minimum free stack space (in bytes) since the task started.
 
bool is_completed () const noexcept
 Checks if the task function has returned.
 
bool joinable () const noexcept
 Checks if this task object owns the task.
 
bool request_stop () noexcept
 Requests the task to stop.
 
bool stop_requested () const noexcept
 Checks if a stop has been requested for this task.
 
void suspend ()
 Suspends the task.
 
void resume ()
 Resumes a suspended task.
 
result< void > try_suspend ()
 Suspends the task.
 
result< void > try_resume ()
 Resumes a suspended task.
 
bool resume_from_isr () noexcept
 Resumes a suspended task from ISR context.
 
void notify ()
 Sends a notification to the task.
 
result< void > try_notify ()
 Sends a notification to the task.
 
bool notify_from_isr () noexcept
 Sends a notification to the task from ISR context.
 
void set_priority (unsigned int new_priority)
 Changes the task priority.
 
result< void > try_set_priority (unsigned int new_priority)
 Changes the task priority.
 
void detach ()
 Releases ownership of the task.
 
result< void > try_detach ()
 Releases ownership of the task.
 
void kill ()
 Immediately terminates the task without waiting for completion.
 
result< void > try_kill ()
 Immediately terminates the task without waiting for completion.
 
void join ()
 Blocks until the task function completes.
 
template<typename Rep , typename Period >
void join (const std::chrono::duration< Rep, Period > &timeout)
 Blocks until the task function completes or the timeout expires.
 
template<typename Clock , typename Duration >
void join_until (const std::chrono::time_point< Clock, Duration > &deadline)
 Blocks until the task function completes or the deadline is reached.
 
result< void > try_join ()
 Blocks until the task function completes.
 
template<typename Rep , typename Period >
result< void > try_join (const std::chrono::duration< Rep, Period > &timeout)
 Blocks until the task function completes or the timeout expires.
 
template<typename Clock , typename Duration >
result< void > try_join_until (const std::chrono::time_point< Clock, Duration > &deadline)
 Blocks until the task function completes or the deadline is reached.
 

Static Public Member Functions

static result< std::unique_ptr< task > > make (config cfg, std::move_only_function< void(self &)> task_func)
 Creates a task with a std::move_only_function callback.
 
static result< std::unique_ptr< task > > make (config cfg, void(*task_func)(self &, void *), void *arg)
 Creates a task with a raw function pointer callback.
 
static void spawn (config cfg, std::move_only_function< void(self &)> task_func)
 Creates a fire-and-forget task with a std::move_only_function callback.
 
static void spawn (config cfg, void(*task_func)(self &, void *), void *arg)
 Creates a fire-and-forget task with a raw function pointer callback.
 
static result< void > try_spawn (config cfg, std::move_only_function< void(self &)> task_func)
 Creates a fire-and-forget task with a std::move_only_function callback.
 
static result< void > try_spawn (config cfg, void(*task_func)(self &, void *), void *arg)
 Creates a fire-and-forget task with a raw function pointer callback.
 
static TaskHandle_t current_handle () noexcept
 Returns the handle of the currently executing task.
 
static std::string current_name ()
 Returns the name of the currently executing task.
 

Detailed Description

Task lifecycle management.

Manages a task with automatic cleanup on destruction.

Tasks are non-copyable and non-movable. Use the factory method make() for result-based construction or the throwing constructor when exceptions are enabled.

Note
The task function runs in the created task's context, not the caller's context.

Definition at line 47 of file task.hpp.

Constructor & Destructor Documentation

◆ task() [1/4]

idfxx::task::task ( const config cfg,
std::move_only_function< void(self &)>  task_func 
)
explicit

Creates a task with a std::move_only_function callback.

The task starts executing immediately after construction.

Parameters
cfgTask configuration.
task_funcFunction to execute in the task context. Receives a self reference for task self-interaction.
Note
Only available when CONFIG_COMPILER_CXX_EXCEPTIONS is enabled.
Exceptions
std::system_erroron failure.

◆ task() [2/4]

idfxx::task::task ( const config cfg,
void(*)(self &, void *)  task_func,
void *  arg 
)
explicit

Creates a task with a raw function pointer callback.

The task starts executing immediately after construction.

Parameters
cfgTask configuration.
task_funcFunction to execute in the task context. Receives a self reference for task self-interaction and the user argument.
argArgument passed to the task function.
Note
Only available when CONFIG_COMPILER_CXX_EXCEPTIONS is enabled.
Exceptions
std::system_erroron failure.

◆ ~task()

idfxx::task::~task ( )

Destroys the task, requesting stop and blocking until the task function completes.

If the task is still joinable (not detached), the destructor calls request_stop() and then blocks until the task function returns, similar to std::jthread. If the task is suspended, it is automatically resumed so it can observe the stop request and exit. The destructor repeatedly resumes the task to ensure it doesn't suspend again. Tasks that check stop_requested() in their loops will exit cleanly.

Warning
For tasks that ignore the stop request and never return, this will block indefinitely. Call join() with a timeout or detach() explicitly before destruction to avoid indefinite blocking.

◆ task() [3/4]

idfxx::task::task ( const task )
delete

◆ task() [4/4]

idfxx::task::task ( task &&  )
delete

Member Function Documentation

◆ current_handle()

static TaskHandle_t idfxx::task::current_handle ( )
inlinestaticnoexcept

Returns the handle of the currently executing task.

Returns
The current task's TaskHandle_t.

Definition at line 788 of file task.hpp.

◆ current_name()

static std::string idfxx::task::current_name ( )
inlinestatic

Returns the name of the currently executing task.

Returns
The current task's name.

Definition at line 795 of file task.hpp.

◆ detach()

void idfxx::task::detach ( )
inline

Releases ownership of the task.

After detaching, the task becomes self-managing and cleans up its resources automatically when the task function returns. The task object becomes non-joinable and the destructor becomes a no-op.

Note
Only available when CONFIG_COMPILER_CXX_EXCEPTIONS is enabled.
Exceptions
std::system_errorif the task has already been detached.

Definition at line 604 of file task.hpp.

References try_detach(), and idfxx::unwrap().

◆ idf_handle()

TaskHandle_t idfxx::task::idf_handle ( ) const
inlinenoexcept

Returns the underlying FreeRTOS task handle.

Returns
The TaskHandle_t, or nullptr if the task has been detached.
Note
The handle may be invalid after the task function completes. Use is_completed() to check before using the handle.

Definition at line 402 of file task.hpp.

◆ is_completed()

bool idfxx::task::is_completed ( ) const
noexcept

Checks if the task function has returned.

Returns
true if the task function has completed, false otherwise.

◆ join() [1/2]

void idfxx::task::join ( )
inline

Blocks until the task function completes.

Waits indefinitely for the task to finish. After a successful join, the task becomes non-joinable. Prefer join() with a timeout to avoid blocking indefinitely on tasks that may not return promptly.

Note
Only available when CONFIG_COMPILER_CXX_EXCEPTIONS is enabled.
Exceptions
std::system_errorif the task has been detached or already joined (idfxx::errc::invalid_state), or if called from within the task itself (std::errc::resource_deadlock_would_occur).

Definition at line 687 of file task.hpp.

References try_join(), and idfxx::unwrap().

◆ join() [2/2]

template<typename Rep , typename Period >
void idfxx::task::join ( const std::chrono::duration< Rep, Period > &  timeout)
inline

Blocks until the task function completes or the timeout expires.

Template Parameters
RepThe representation type of the duration.
PeriodThe period type of the duration.
Parameters
timeoutMaximum time to wait for the task to complete.
Note
Only available when CONFIG_COMPILER_CXX_EXCEPTIONS is enabled.
Exceptions
std::system_errorif the task has been detached or already joined (idfxx::errc::invalid_state), if called from within the task itself (std::errc::resource_deadlock_would_occur), or if the timeout expires (idfxx::errc::timeout).

Definition at line 702 of file task.hpp.

References idfxx::timeout, try_join(), and idfxx::unwrap().

◆ join_until()

template<typename Clock , typename Duration >
void idfxx::task::join_until ( const std::chrono::time_point< Clock, Duration > &  deadline)
inline

Blocks until the task function completes or the deadline is reached.

Template Parameters
ClockThe clock type.
DurationThe duration type of the time point.
Parameters
deadlineThe time point at which to stop waiting.
Note
Only available when CONFIG_COMPILER_CXX_EXCEPTIONS is enabled.
Exceptions
std::system_errorif the task has been detached or already joined (idfxx::errc::invalid_state), if called from within the task itself (std::errc::resource_deadlock_would_occur), or if the deadline is reached (idfxx::errc::timeout).

Definition at line 719 of file task.hpp.

References try_join_until(), and idfxx::unwrap().

◆ joinable()

bool idfxx::task::joinable ( ) const
inlinenoexcept

Checks if this task object owns the task.

Returns false if the task has been detached or was never successfully created.

Returns
true if this object owns the task handle, false otherwise.

Definition at line 443 of file task.hpp.

◆ kill()

void idfxx::task::kill ( )
inline

Immediately terminates the task without waiting for completion.

Immediately terminates the task. After killing, the task becomes non-joinable.

Warning
This is a dangerous operation that should only be used as a last resort. The task is terminated abruptly at whatever point it is executing:
  • C++ destructors for stack-allocated objects will not run
  • Mutexes and locks held by the task will not be released
  • Dynamic memory allocated by the task will not be freed
  • Any invariants the task was maintaining may be left in an inconsistent state

These consequences can lead to resource leaks, deadlocks, and undefined behavior in the rest of the system. Prefer using request_stop() and join() to allow the task to complete gracefully, or allow the destructor to block.

If the task function has already returned by the time this method is called, this method simply cleans up resources.

Note
Only available when CONFIG_COMPILER_CXX_EXCEPTIONS is enabled.
Exceptions
std::system_errorif the task has been detached, already joined, or if called from within the task itself.

Definition at line 646 of file task.hpp.

References try_kill(), and idfxx::unwrap().

◆ make() [1/2]

static result< std::unique_ptr< task > > idfxx::task::make ( config  cfg,
std::move_only_function< void(self &)>  task_func 
)
static

Creates a task with a std::move_only_function callback.

The task starts executing immediately after creation.

Parameters
cfgTask configuration.
task_funcFunction to execute in the task context. Receives a self reference for task self-interaction.
Returns
The new task, or an error.
Return values
no_memMemory allocation failed or insufficient stack.

◆ make() [2/2]

static result< std::unique_ptr< task > > idfxx::task::make ( config  cfg,
void(*)(self &, void *)  task_func,
void *  arg 
)
static

Creates a task with a raw function pointer callback.

The task starts executing immediately after creation.

Parameters
cfgTask configuration.
task_funcFunction to execute in the task context. Receives a self reference for task self-interaction and the user argument.
argArgument passed to the task function.
Returns
The new task, or an error.
Return values
no_memMemory allocation failed or insufficient stack.

◆ name()

const std::string & idfxx::task::name ( ) const
inlinenoexcept

Returns the task name.

Returns
The task name.

Definition at line 409 of file task.hpp.

◆ notify()

void idfxx::task::notify ( )
inline

Sends a notification to the task.

Increments the task's notification value, waking the task if it is blocked in wait() or take(). Can be called multiple times before the task receives — each call increments the notification count.

Uses notification index 0, which is reserved for this purpose.

Note
Only available when CONFIG_COMPILER_CXX_EXCEPTIONS is enabled.
Exceptions
std::system_errorif the task has been detached or completed.

Definition at line 533 of file task.hpp.

References try_notify(), and idfxx::unwrap().

◆ notify_from_isr()

bool idfxx::task::notify_from_isr ( )
noexcept

Sends a notification to the task from ISR context.

Increments the task's notification value, waking the task if it is blocked in wait() or take().

Uses notification index 0, which is reserved for this purpose.

Returns
true if a context switch should be requested, false otherwise. Returns false if the task has been detached or completed.
Note
Pass the return value to idfxx::yield_from_isr() to perform the context switch if needed.
void IRAM_ATTR my_isr() {
bool need_yield = worker_task->notify_from_isr();
idfxx::yield_from_isr(need_yield);
}
void yield_from_isr(bool higher_priority_task_woken=true) noexcept
Requests a context switch from ISR context.

◆ operator=() [1/2]

task & idfxx::task::operator= ( const task )
delete

◆ operator=() [2/2]

task & idfxx::task::operator= ( task &&  )
delete

◆ priority()

unsigned int idfxx::task::priority ( ) const
noexcept

Returns the current task priority.

Returns
The task priority, or 0 if the task has been detached or completed.

◆ request_stop()

bool idfxx::task::request_stop ( )
noexcept

Requests the task to stop.

Requests the task to stop cooperatively. The task function can observe this via self::stop_requested(). Also requested automatically by the destructor before joining.

Returns
true if the stop was newly requested (flag was previously false), false if stop was already requested or the task is not joinable.

◆ resume()

void idfxx::task::resume ( )
inline

Resumes a suspended task.

Note
Only available when CONFIG_COMPILER_CXX_EXCEPTIONS is enabled.
Exceptions
std::system_errorif the task has been detached or completed.

Definition at line 481 of file task.hpp.

References try_resume(), and idfxx::unwrap().

◆ resume_from_isr()

bool idfxx::task::resume_from_isr ( )
noexcept

Resumes a suspended task from ISR context.

Returns
true if a context switch should be requested, false otherwise. Returns false if the task has been detached or completed.
Note
Pass the return value to idfxx::yield_from_isr() to perform the context switch if needed.
void IRAM_ATTR my_isr() {
bool need_yield = worker_task->resume_from_isr();
idfxx::yield_from_isr(need_yield);
}

◆ set_priority()

void idfxx::task::set_priority ( unsigned int  new_priority)
inline

Changes the task priority.

Parameters
new_priorityThe new priority level.
Note
Only available when CONFIG_COMPILER_CXX_EXCEPTIONS is enabled.
Exceptions
std::system_errorif the task has been detached or completed.

Definition at line 581 of file task.hpp.

References try_set_priority(), and idfxx::unwrap().

◆ spawn() [1/2]

static void idfxx::task::spawn ( config  cfg,
std::move_only_function< void(self &)>  task_func 
)
inlinestatic

Creates a fire-and-forget task with a std::move_only_function callback.

The task starts executing immediately and cleans up its resources when complete.

Parameters
cfgTask configuration.
task_funcFunction to execute in the task context. Receives a self reference for task self-interaction.
Note
Only available when CONFIG_COMPILER_CXX_EXCEPTIONS is enabled.
Exceptions
std::system_erroron failure.

Definition at line 325 of file task.hpp.

References try_spawn(), and idfxx::unwrap().

◆ spawn() [2/2]

static void idfxx::task::spawn ( config  cfg,
void(*)(self &, void *)  task_func,
void *  arg 
)
inlinestatic

Creates a fire-and-forget task with a raw function pointer callback.

The task starts executing immediately and cleans up its resources when complete.

Parameters
cfgTask configuration.
task_funcFunction to execute in the task context. Receives a self reference for task self-interaction and the user argument.
argArgument passed to the task function.
Note
Only available when CONFIG_COMPILER_CXX_EXCEPTIONS is enabled.
Exceptions
std::system_erroron failure.

Definition at line 341 of file task.hpp.

References try_spawn(), and idfxx::unwrap().

◆ stack_high_water_mark()

size_t idfxx::task::stack_high_water_mark ( ) const
noexcept

Returns the minimum free stack space (in bytes) since the task started.

This is useful for tuning stack sizes — a value approaching zero indicates potential stack overflow.

Returns
The minimum free stack space in bytes, or 0 if the task has been detached or completed.

◆ stop_requested()

bool idfxx::task::stop_requested ( ) const
noexcept

Checks if a stop has been requested for this task.

Returns
true if request_stop() has been called, false if not or if the task is not joinable.

◆ suspend()

void idfxx::task::suspend ( )
inline

Suspends the task.

A suspended task will not run until resume() is called.

Note
Only available when CONFIG_COMPILER_CXX_EXCEPTIONS is enabled.
Exceptions
std::system_errorif the task has been detached or completed.

Definition at line 473 of file task.hpp.

References try_suspend(), and idfxx::unwrap().

◆ try_detach()

result< void > idfxx::task::try_detach ( )

Releases ownership of the task.

After detaching, the task becomes self-managing and cleans up its resources automatically when the task function returns. The task object becomes non-joinable and the destructor becomes a no-op.

If the task has already completed, ownership is released and resources are cleaned up immediately.

Returns
Success, or an error.
Return values
invalid_stateThe task has already been detached.

Referenced by detach().

◆ try_join() [1/2]

result< void > idfxx::task::try_join ( )

Blocks until the task function completes.

Waits indefinitely for the task to finish. After a successful join, the task becomes non-joinable. Prefer try_join() with a timeout to avoid blocking indefinitely on tasks that may not return promptly.

Returns
Success, or an error.
Return values
invalid_stateThe task has been detached or already joined.
std::errc::resource_deadlock_would_occurCalled from within the task itself.

Referenced by join(), and join().

◆ try_join() [2/2]

template<typename Rep , typename Period >
result< void > idfxx::task::try_join ( const std::chrono::duration< Rep, Period > &  timeout)
inline

Blocks until the task function completes or the timeout expires.

After a successful join, the task becomes non-joinable.

Template Parameters
RepThe representation type of the duration.
PeriodThe period type of the duration.
Parameters
timeoutMaximum time to wait for the task to complete.
Returns
Success, or an error.
Return values
invalid_stateThe task has been detached or already joined.
std::errc::resource_deadlock_would_occurCalled from within the task itself.
timeoutThe task did not complete within the specified duration. The task remains joinable and can be joined again.

Definition at line 752 of file task.hpp.

References idfxx::chrono::ticks(), and idfxx::timeout.

◆ try_join_until()

template<typename Clock , typename Duration >
result< void > idfxx::task::try_join_until ( const std::chrono::time_point< Clock, Duration > &  deadline)
inline

Blocks until the task function completes or the deadline is reached.

After a successful join, the task becomes non-joinable.

Template Parameters
ClockThe clock type.
DurationThe duration type of the time point.
Parameters
deadlineThe time point at which to stop waiting.
Returns
Success, or an error.
Return values
invalid_stateThe task has been detached or already joined.
std::errc::resource_deadlock_would_occurCalled from within the task itself.
timeoutThe task did not complete before the deadline. The task remains joinable and can be joined again.

Definition at line 771 of file task.hpp.

References idfxx::chrono::ticks().

Referenced by join_until().

◆ try_kill()

result< void > idfxx::task::try_kill ( )

Immediately terminates the task without waiting for completion.

Immediately terminates the task. After killing, the task becomes non-joinable.

Warning
This is a dangerous operation that should only be used as a last resort. The task is terminated abruptly at whatever point it is executing:
  • C++ destructors for stack-allocated objects will not run
  • Mutexes and locks held by the task will not be released
  • Dynamic memory allocated by the task will not be freed
  • Any invariants the task was maintaining may be left in an inconsistent state

These consequences can lead to resource leaks, deadlocks, and undefined behavior in the rest of the system. Prefer using request_stop() and try_join() to allow the task to complete gracefully, or allow the destructor to block.

If the task function has already returned by the time this method is called, this method simply cleans up resources.

Returns
Success, or an error.
Return values
invalid_stateThe task has been detached, already joined, or called from within the task itself.

Referenced by kill().

◆ try_notify()

result< void > idfxx::task::try_notify ( )

Sends a notification to the task.

Increments the task's notification value, waking the task if it is blocked in wait() or take(). Can be called multiple times before the task receives — each call increments the notification count.

Uses notification index 0, which is reserved for this purpose.

Returns
Success, or an error.
Return values
invalid_stateThe task has been detached or completed.

Referenced by notify().

◆ try_resume()

result< void > idfxx::task::try_resume ( )

Resumes a suspended task.

Returns
Success, or an error.
Return values
invalid_stateThe task has been detached or completed.

Referenced by resume().

◆ try_set_priority()

result< void > idfxx::task::try_set_priority ( unsigned int  new_priority)

Changes the task priority.

Parameters
new_priorityThe new priority level.
Returns
Success, or an error.
Return values
invalid_stateThe task has been detached or completed.

Referenced by set_priority().

◆ try_spawn() [1/2]

static result< void > idfxx::task::try_spawn ( config  cfg,
std::move_only_function< void(self &)>  task_func 
)
static

Creates a fire-and-forget task with a std::move_only_function callback.

The task starts executing immediately and cleans up its resources when complete.

Parameters
cfgTask configuration.
task_funcFunction to execute in the task context. Receives a self reference for task self-interaction.
Returns
Success, or an error.
Return values
no_memMemory allocation failed or insufficient stack.

Referenced by spawn(), and spawn().

◆ try_spawn() [2/2]

static result< void > idfxx::task::try_spawn ( config  cfg,
void(*)(self &, void *)  task_func,
void *  arg 
)
static

Creates a fire-and-forget task with a raw function pointer callback.

The task starts executing immediately and cleans up its resources when complete.

Parameters
cfgTask configuration.
task_funcFunction to execute in the task context. Receives a self reference for task self-interaction and the user argument.
argArgument passed to the task function.
Returns
Success, or an error.
Return values
no_memMemory allocation failed or insufficient stack.

◆ try_suspend()

result< void > idfxx::task::try_suspend ( )

Suspends the task.

A suspended task will not run until resume() is called.

Returns
Success, or an error.
Return values
invalid_stateThe task has been detached or completed.

Referenced by suspend().


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