FastLED 3.10.8
Loading...
Searching...
No Matches
fl::task Namespace Reference

Namespaces

namespace  anonymous_namespace{task.cpp.hpp}
 
namespace  detail
 

Classes

class  Coroutine
 
struct  CoroutineConfig
 Function and platform tuning for an OS-level coroutine task. More...
 
class  CoroutineTask
 
struct  Error
 Error type for promises. More...
 
class  Executor
 Task executor (singleton) — manages registered runners. More...
 
class  Handle
 Task Handle with fluent API (was class fl::task, renamed to avoid namespace collision) More...
 
class  ITaskImpl
 
class  Promise
 Promise class that provides fluent .then() and .catch_() semantics This is a lightweight wrapper around a shared PromiseImpl for easy copying/sharing. More...
 
class  PromiseResult
 Result type for promise operations. More...
 
class  Runner
 Generic task runner interface. More...
 
class  Scheduler
 
class  TimeTask
 

Enumerations

enum class  ExecFlags : u8 { TASKS = 1 << 0 , COROUTINES = 1 << 1 , SYSTEM = 1 << 2 , ALL = (1 << 0) | (1 << 1) | (1 << 2) }
 Flags controlling which subsystems run() pumps. More...
 
enum class  TaskType {
  kEveryMs , kAtFramerate , kBeforeFrame , kAfterFrame ,
  kCoroutine
}
 Identifies how a scheduled task is triggered. More...
 

Functions

size_t active_tasks () FL_NO_EXCEPT
 Get the number of active tasks across all systems.
 
Handle after_frame () FL_NO_EXCEPT
 Creates a task that runs after every FastLED frame until canceled.
 
Handle after_frame (const TracePoint &trace) FL_NO_EXCEPT
 Creates a traced task that runs after every FastLED frame until canceled.
 
Handle after_frame (function< void()> on_then) FL_NO_EXCEPT
 Creates an after-frame task, running until canceled, with its success callback already configured.
 
Handle after_frame (function< void()> on_then, const TracePoint &trace) FL_NO_EXCEPT
 Creates a traced after-frame task, running until canceled, with its success callback already configured.
 
Handle at_framerate (int fps) FL_NO_EXCEPT
 Creates a task that runs at a fixed frame rate.
 
Handle at_framerate (int fps, const TracePoint &trace) FL_NO_EXCEPT
 Creates a traced task that runs at a fixed frame rate.
 
template<typename T>
PromiseResult< T > await (Promise< T > p, fl::u32 timeout_ms=fl::platforms::kAwaitDefaultTimeoutMs) FL_NO_EXCEPT
 Await promise completion in a coroutine (Trampoline to platform implementation)
 
template<typename T>
PromiseResult< T > await_top_level (Promise< T > p) FL_NO_EXCEPT
 Synchronously wait for a promise to complete (ONLY safe in top-level contexts)
 
Handle before_frame () FL_NO_EXCEPT
 Frame tasks recur: every overload below schedules a task that runs once per FastLED frame and keeps doing so until Handle::cancel() is called on it, so keep the returned handle whenever the task will need to be canceled.
 
Handle before_frame (const TracePoint &trace) FL_NO_EXCEPT
 Creates a traced task that runs before every FastLED frame until canceled.
 
Handle coroutine (const CoroutineConfig &config) FL_NO_EXCEPT
 Creates and starts an OS-level coroutine task.
 
Handle every_ms (int interval_ms) FL_NO_EXCEPT
 Creates a task that runs at a fixed millisecond interval.
 
Handle every_ms (int interval_ms, const TracePoint &trace) FL_NO_EXCEPT
 Creates a traced task that runs at a fixed millisecond interval.
 
void exit_current () FL_NO_EXCEPT
 Terminates the currently executing coroutine.
 
bool has_tasks () FL_NO_EXCEPT
 Check if any systems have active tasks.
 
template<typename T>
PromiseResult< T > make_error (const char *message) FL_NO_EXCEPT
 Helper function to create an error result from C-string.
 
template<typename T>
PromiseResult< T > make_error (const Error &error) FL_NO_EXCEPT
 Helper function to create an error result.
 
template<typename T>
PromiseResult< T > make_error (const fl::string &message) FL_NO_EXCEPT
 Helper function to create an error result from string.
 
template<typename T>
PromiseResult< T > make_error (Error &&error) FL_NO_EXCEPT
 Helper function to create an error result (move)
 
template<typename T>
Promise< T > make_rejected_promise (const char *error_message) FL_NO_EXCEPT
 Convenience function to create a rejected Promise (const char* overload)
 
template<typename T>
Promise< T > make_rejected_promise (const fl::string &error_message) FL_NO_EXCEPT
 Convenience function to create a rejected Promise.
 
template<typename T>
Promise< T > make_resolved_promise (T value) FL_NO_EXCEPT
 Convenience function to create a resolved Promise.
 
template<typename T>
PromiseResult< T > make_success (const T &value) FL_NO_EXCEPT
 Helper function to create a successful result.
 
template<typename T>
PromiseResult< T > make_success (T &&value) FL_NO_EXCEPT
 Helper function to create a successful result (move)
 
bool operator& (ExecFlags a, ExecFlags b) FL_NO_EXCEPT
 
ExecFlags operator| (ExecFlags a, ExecFlags b) FL_NO_EXCEPT
 
void run (fl::u32 microseconds=1000, ExecFlags flags=ExecFlags::ALL) FL_NO_EXCEPT
 Run selected task subsystems.
 
void yield_system (fl::u32 microseconds) FL_NO_EXCEPT
 OS-level yield only: same behavior as run(us, ExecFlags::SYSTEM).
 

Only ESP32 honors it; a value outside [0, FL_CPU_CORES) is silently downgraded to no affinity, and single-core or non-RTOS platforms ignore the field.

function< void()> func Function executed by the coroutine, copied at creation time.

An empty function is legal: the coroutine starts, does nothing, and exits.

string name = "task" Diagnostic name reported by the platform. Defaults to "task". u8 priority = 5 Platform task priority relative to the platform idle priority, default 5.

On ESP32 the FreeRTOS priority becomes tskIDLE_PRIORITY + priority. FastLED does not clamp this against the platform maximum.

size_t stack_size = 4096 Requested stack size in bytes, default 4096.

A platform may raise a smaller request to its own floor (ESP32 clamps up to 2048) and platforms that emulate coroutines may ignore the field entirely.

optional< TracePoint > trace Optional location where the task was created, reported by Handle::trace_label().

Unset by default, in which case the label is empty.

Enumeration Type Documentation

◆ ExecFlags

enum class fl::task::ExecFlags : u8
strong

Flags controlling which subsystems run() pumps.

Enumerator
TASKS 
COROUTINES 
SYSTEM 
ALL 

Definition at line 64 of file executor.h.

64 : u8 {
65 TASKS = 1 << 0,
66 COROUTINES = 1 << 1,
67 SYSTEM = 1 << 2,
68 ALL = (1 << 0) | (1 << 1) | (1 << 2)
69};
unsigned char u8
Definition stdint.h:131

◆ TaskType

enum class fl::task::TaskType
strong

Identifies how a scheduled task is triggered.

Enumerator
kEveryMs 

Runs after a fixed time interval.

kAtFramerate 

Runs at a fixed number of times per second.

kBeforeFrame 

Runs immediately before each FastLED frame is rendered.

kAfterFrame 

Runs immediately after each FastLED frame is rendered.

kCoroutine 

Runs as an operating-system or RTOS task.

Definition at line 117 of file task.h.

117 {
118 kEveryMs,
123};
@ kBeforeFrame
Runs immediately before each FastLED frame is rendered.
Definition task.h:120
@ kAfterFrame
Runs immediately after each FastLED frame is rendered.
Definition task.h:121
@ kAtFramerate
Runs at a fixed number of times per second.
Definition task.h:119
@ kEveryMs
Runs after a fixed time interval.
Definition task.h:118
@ kCoroutine
Runs as an operating-system or RTOS task.
Definition task.h:122

Function Documentation

◆ active_tasks()

size_t fl::task::active_tasks ( )

Get the number of active tasks across all systems.

Returns
Total number of active tasks

Definition at line 188 of file executor.cpp.hpp.

188 {
190}
size_t total_active_tasks() const FL_NO_EXCEPT
Get total number of active tasks across all runners.
static Executor & instance() FL_NO_EXCEPT

References fl::FL_NO_EXCEPT, fl::task::Executor::instance(), and fl::task::Executor::total_active_tasks().

+ Here is the call graph for this function:

◆ after_frame() [1/4]

Handle fl::task::after_frame ( )

Creates a task that runs after every FastLED frame until canceled.

Returns
A handle for configuring and controlling the task.
Note
UI work usually belongs after the frame so it is ready for the next loop.

Definition at line 344 of file task.cpp.hpp.

344 {
346}
Task Handle with fluent API (was class fl::task, renamed to avoid namespace collision)
Definition task.h:156
shared_ptr< T > make_shared(Args &&... args) FL_NO_EXCEPT
Definition shared_ptr.h:423

References fl::FL_NO_EXCEPT, kAfterFrame, and fl::adl_barrier::make_shared().

Referenced by after_frame(), and after_frame().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ after_frame() [2/4]

Handle fl::task::after_frame ( const TracePoint & trace)

Creates a traced task that runs after every FastLED frame until canceled.

Parameters
traceLocation where the task was created.
Returns
A handle for configuring and controlling the task.

Definition at line 348 of file task.cpp.hpp.

348 {
350}

References fl::FL_NO_EXCEPT, kAfterFrame, and fl::adl_barrier::make_shared().

+ Here is the call graph for this function:

◆ after_frame() [3/4]

Handle fl::task::after_frame ( function< void()> on_then)

Creates an after-frame task, running until canceled, with its success callback already configured.

Parameters
on_thenCallback invoked after each FastLED frame.
Returns
A handle for controlling the task.

Definition at line 352 of file task.cpp.hpp.

352 {
353 Handle t = after_frame();
354 t.then(fl::move(on_then));
355 return t;
356}
constexpr remove_reference< T >::type && move(T &&t) FL_NO_EXCEPT
Definition move.h:30
Handle after_frame() FL_NO_EXCEPT
Creates a task that runs after every FastLED frame until canceled.
Definition task.cpp.hpp:344

References after_frame(), fl::FL_NO_EXCEPT, fl::adl_barrier::move(), and fl::t.

+ Here is the call graph for this function:

◆ after_frame() [4/4]

Handle fl::task::after_frame ( function< void()> on_then,
const TracePoint & trace )

Creates a traced after-frame task, running until canceled, with its success callback already configured.

Parameters
on_thenCallback invoked after each FastLED frame.
traceLocation where the task was created.
Returns
A handle for controlling the task.

Definition at line 358 of file task.cpp.hpp.

358 {
359 Handle t = after_frame(trace);
360 t.then(fl::move(on_then));
361 return t;
362}

References after_frame(), fl::FL_NO_EXCEPT, fl::adl_barrier::move(), and fl::t.

+ Here is the call graph for this function:

◆ at_framerate() [1/2]

Handle fl::task::at_framerate ( int fps)

Creates a task that runs at a fixed frame rate.

Parameters
fpsNumber of executions per second.
Returns
A handle for configuring and controlling the task.

Definition at line 328 of file task.cpp.hpp.

328 {
330}

References fl::FL_NO_EXCEPT, kAtFramerate, and fl::adl_barrier::make_shared().

Referenced by setup().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ at_framerate() [2/2]

Handle fl::task::at_framerate ( int fps,
const TracePoint & trace )

Creates a traced task that runs at a fixed frame rate.

Parameters
fpsNumber of executions per second.
traceLocation where the task was created.
Returns
A handle for configuring and controlling the task.

Definition at line 332 of file task.cpp.hpp.

332 {
333 return Handle(fl::make_shared<TimeTask>(TaskType::kAtFramerate, 1000 / fps, trace));
334}

References fl::FL_NO_EXCEPT, kAtFramerate, and fl::adl_barrier::make_shared().

+ Here is the call graph for this function:

◆ await()

template<typename T>
PromiseResult< T > fl::task::await ( Promise< T > p,
fl::u32 timeout_ms = fl::platforms::kAwaitDefaultTimeoutMs )
inline

Await promise completion in a coroutine (Trampoline to platform implementation)

Template Parameters
TThe type of value the promise resolves to
Parameters
pThe promise to await
Returns
A PromiseResult<T> containing either the resolved value or an error

This is the public API for awaiting promises in coroutines. It delegates to the platform-specific implementation in fl::platforms::await().

REQUIREMENTS:

SAFETY: Unlike await_top_level(), this does NOT busy-wait. The coroutine is suspended by the OS scheduler and wakes when the promise completes, with zero CPU overhead.

Examples

.func = []() {
auto result = fl::task::await(fl::fetch_get("http://example.com"));
if (result.ok()) {
process(result.value());
}
}
});
Handle coroutine(const CoroutineConfig &config) FL_NO_EXCEPT
Creates and starts an OS-level coroutine task.
Definition task.cpp.hpp:364
PromiseResult< T > await(Promise< T > p, fl::u32 timeout_ms=fl::platforms::kAwaitDefaultTimeoutMs) FL_NO_EXCEPT
Await promise completion in a coroutine (Trampoline to platform implementation)
Definition executor.h:316
expected< T, E > result
Alias for expected (Rust-style naming)
Definition result.h:31
Parameters
timeout_msWall-clock budget before the wait returns an error rather than continuing to poll. Defaults to fl::platforms::kAwaitDefaultTimeoutMs; see FastLED#4369 for why the wait is bounded at all.

Definition at line 316 of file executor.h.

318 {
319 return fl::platforms::await(p, timeout_ms);
320}

References fl::FL_NO_EXCEPT.

◆ await_top_level()

template<typename T>
PromiseResult< T > fl::task::await_top_level ( Promise< T > p)

Synchronously wait for a promise to complete (ONLY safe in top-level contexts)

Template Parameters
TThe type of value the promise resolves to (automatically deduced)
Parameters
pThe promise to wait for
Returns
A promise_result containing either the resolved value T or an Error

This function blocks until the promise is either resolved or rejected, then returns a promise_result that can be checked with ok() for success/failure. While waiting, it continuously calls run(1000) to pump async tasks and yield appropriately.

PERFORMANCE NOTE: This function busy-waits (high CPU usage) while the promise is pending. For coroutines on ESP32 or Host/Stub platforms, prefer fl::task::await() which truly blocks the coroutine with zero CPU overhead.

SAFETY WARNING: This function should ONLY be called from top-level contexts like Arduino loop() function. Never call this from:

The "_top_level" suffix emphasizes this safety requirement.

Examples

auto p = fl::fetch_get("http://example.com");
auto result = fl::task::await_top_level(p); // Type automatically deduced!
if (result.ok()) {
const Response& resp = result.value();
FL_WARN("Success: " << resp.text());
} else {
FL_WARN("Error: " << result.error().message);
}
#define FL_WARN(...)
Definition log.h:437
PromiseResult< T > await_top_level(Promise< T > p) FL_NO_EXCEPT
Synchronously wait for a promise to complete (ONLY safe in top-level contexts)
Definition executor.h:193

Definition at line 193 of file executor.h.

193 {
194 // Handle invalid promises
195 if (!p.valid()) {
196 return PromiseResult<T>(Error("Invalid promise"));
197 }
198
199 // If already completed, return immediately
200 if (p.is_completed()) {
201 if (p.is_resolved()) {
202 return PromiseResult<T>(p.value());
203 } else {
204 return PromiseResult<T>(p.error());
205 }
206 }
207
208 // Track recursion depth to prevent infinite loops
209 int& await_depth = detail::await_depth_tls();
210 if (await_depth > 10) {
211 return PromiseResult<T>(Error("await_top_level recursion limit exceeded - possible infinite loop"));
212 }
213
214 ++await_depth;
215
216 // Wait for promise to complete while pumping async tasks
217 int pump_count = 0;
218 const int max_pump_iterations = 10000; // Safety limit
219
220 while (!p.is_completed() && pump_count < max_pump_iterations) {
221 // Update the promise first (in case it's not managed by async system)
222 p.update();
223
224 // Check if completed after update
225 if (p.is_completed()) {
226 break;
227 }
228
229 // Platform-agnostic async pump and yield
230 run(1000);
231
232 ++pump_count;
233 }
234
235 --await_depth;
236
237 // Check for timeout
238 if (pump_count >= max_pump_iterations) {
239 return PromiseResult<T>(Error("await_top_level timeout - promise did not complete"));
240 }
241
242 // Return the result
243 if (p.is_resolved()) {
244 return PromiseResult<T>(p.value());
245 } else {
246 return PromiseResult<T>(p.error());
247 }
248}
const Error & error() const FL_NO_EXCEPT
Get the error (only valid if is_rejected() returns true)
Definition promise.h:167
bool valid() const FL_NO_EXCEPT
Check if Promise is valid.
Definition promise.h:108
void update() FL_NO_EXCEPT
Update Promise state in main loop - should be called periodically This processes pending callbacks wh...
Definition promise.h:134
const T & value() const FL_NO_EXCEPT
Get the result value (only valid if is_resolved() returns true)
Definition promise.h:158
bool is_completed() const FL_NO_EXCEPT
Check if Promise is completed (resolved or rejected)
Definition promise.h:140
bool is_resolved() const FL_NO_EXCEPT
Check if Promise is resolved (completed successfully)
Definition promise.h:146
Result type for promise operations.
int & await_depth_tls() FL_NO_EXCEPT
Get reference to thread-local await recursion depth.
void run(fl::u32 microseconds, ExecFlags flags) FL_NO_EXCEPT
Run selected task subsystems.

References await_top_level(), and fl::FL_NO_EXCEPT.

Referenced by await_top_level(), test_await_approach(), test_get_endpoint(), test_json_await(), test_json_endpoint(), and test_ping_endpoint().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ before_frame() [1/2]

Handle fl::task::before_frame ( )

Frame tasks recur: every overload below schedules a task that runs once per FastLED frame and keeps doing so until Handle::cancel() is called on it, so keep the returned handle whenever the task will need to be canceled.

Creates a task that runs before every FastLED frame until canceled.

Returns
A handle for configuring and controlling the task.
Note
Prefer after_frame() unless work must happen immediately before rendering.

Definition at line 336 of file task.cpp.hpp.

References fl::FL_NO_EXCEPT, kBeforeFrame, and fl::adl_barrier::make_shared().

+ Here is the call graph for this function:

◆ before_frame() [2/2]

Handle fl::task::before_frame ( const TracePoint & trace)

Creates a traced task that runs before every FastLED frame until canceled.

Parameters
traceLocation where the task was created.
Returns
A handle for configuring and controlling the task.

Definition at line 340 of file task.cpp.hpp.

340 {
342}

References fl::FL_NO_EXCEPT, kBeforeFrame, and fl::adl_barrier::make_shared().

+ Here is the call graph for this function:

◆ coroutine()

Handle fl::task::coroutine ( const CoroutineConfig & config)

Creates and starts an OS-level coroutine task.

Parameters
configFunction and platform-specific task configuration.
Returns
A handle for controlling the coroutine.

Definition at line 364 of file task.cpp.hpp.

364 {
366}

References fl::FL_NO_EXCEPT, and fl::adl_barrier::make_shared().

+ Here is the call graph for this function:

◆ every_ms() [1/2]

Handle fl::task::every_ms ( int interval_ms)

Creates a task that runs at a fixed millisecond interval.

Parameters
interval_msInterval between runs.
Returns
A handle for configuring and controlling the task.

Definition at line 320 of file task.cpp.hpp.

320 {
322}

References fl::FL_NO_EXCEPT, fl::task::ITaskImpl::interval_ms(), kEveryMs, and fl::adl_barrier::make_shared().

Referenced by fl::detail::AsyncLoggerServiceTask::AsyncLoggerServiceTask(), fl::audio::Processor::createWithAutoInput(), autoresearch::maybeRegisterStubAutorun(), setup(), and autoresearch::setupRpcAsyncTask().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ every_ms() [2/2]

Handle fl::task::every_ms ( int interval_ms,
const TracePoint & trace )

Creates a traced task that runs at a fixed millisecond interval.

Parameters
interval_msInterval between runs.
traceLocation where the task was created.
Returns
A handle for configuring and controlling the task.

Definition at line 324 of file task.cpp.hpp.

324 {
325 return Handle(fl::make_shared<TimeTask>(TaskType::kEveryMs, interval_ms, trace));
326}

References fl::FL_NO_EXCEPT, fl::task::ITaskImpl::interval_ms(), kEveryMs, and fl::adl_barrier::make_shared().

+ Here is the call graph for this function:

◆ exit_current()

void fl::task::exit_current ( )

Terminates the currently executing coroutine.

Note
This function does not return on platforms that support coroutines.

Definition at line 369 of file task.cpp.hpp.

static void exitCurrent() FL_NO_EXCEPT
Definition task.cpp.hpp:63

References fl::task::Coroutine::exitCurrent(), and fl::FL_NO_EXCEPT.

+ Here is the call graph for this function:

◆ has_tasks()

bool fl::task::has_tasks ( )

Check if any systems have active tasks.

Returns
True if any tasks are running

Definition at line 192 of file executor.cpp.hpp.

192 {
194}
bool has_active_tasks() const FL_NO_EXCEPT
Check if there are any active tasks.

References fl::FL_NO_EXCEPT, fl::task::Executor::has_active_tasks(), and fl::task::Executor::instance().

+ Here is the call graph for this function:

◆ make_error() [1/4]

template<typename T>
PromiseResult< T > fl::task::make_error ( const char * message)

Helper function to create an error result from C-string.

Template Parameters
TThe value type
Parameters
messageThe error message
Returns
result containing the error

Definition at line 179 of file promise_result.h.

179 {
180 return PromiseResult<T>(Error(message));
181}

References fl::Error, and fl::FL_NO_EXCEPT.

◆ make_error() [2/4]

template<typename T>
PromiseResult< T > fl::task::make_error ( const Error & error)

Helper function to create an error result.

Template Parameters
TThe value type
Parameters
errorThe error
Returns
result containing the error

Definition at line 152 of file promise_result.h.

152 {
153 return PromiseResult<T>(error);
154}

References fl::FL_NO_EXCEPT.

◆ make_error() [3/4]

template<typename T>
PromiseResult< T > fl::task::make_error ( const fl::string & message)

Helper function to create an error result from string.

Template Parameters
TThe value type
Parameters
messageThe error message
Returns
result containing the error

Definition at line 170 of file promise_result.h.

170 {
171 return PromiseResult<T>(Error(message));
172}

References fl::Error, and fl::FL_NO_EXCEPT.

◆ make_error() [4/4]

template<typename T>
PromiseResult< T > fl::task::make_error ( Error && error)

Helper function to create an error result (move)

Template Parameters
TThe value type
Parameters
errorThe error (moved)
Returns
result containing the error

Definition at line 161 of file promise_result.h.

161 {
162 return PromiseResult<T>(fl::move(error));
163}

References fl::FL_NO_EXCEPT, and fl::adl_barrier::move().

+ Here is the call graph for this function:

◆ make_rejected_promise() [1/2]

template<typename T>
Promise< T > fl::task::make_rejected_promise ( const char * error_message)

Convenience function to create a rejected Promise (const char* overload)

Definition at line 226 of file promise.h.

226 {
227 return Promise<T>::reject(Error(error_message));
228}
static Promise< T > reject(const Error &error) FL_NO_EXCEPT
Create a rejected Promise with error.
Definition promise.h:81

References fl::Error, fl::FL_NO_EXCEPT, and fl::task::Promise< T >::reject().

+ Here is the call graph for this function:

◆ make_rejected_promise() [2/2]

template<typename T>
Promise< T > fl::task::make_rejected_promise ( const fl::string & error_message)

Convenience function to create a rejected Promise.

Definition at line 220 of file promise.h.

220 {
221 return Promise<T>::reject(Error(error_message));
222}

References fl::Error, fl::FL_NO_EXCEPT, and fl::task::Promise< T >::reject().

+ Here is the call graph for this function:

◆ make_resolved_promise()

template<typename T>
Promise< T > fl::task::make_resolved_promise ( T value)

Convenience function to create a resolved Promise.

Definition at line 214 of file promise.h.

214 {
216}
static Promise< T > resolve(const T &value) FL_NO_EXCEPT
Create a resolved Promise with value.
Definition promise.h:67
constexpr int type_rank< T >::value

References fl::FL_NO_EXCEPT, fl::adl_barrier::move(), fl::task::Promise< T >::resolve(), and fl::type_rank< T >::value.

+ Here is the call graph for this function:

◆ make_success() [1/2]

template<typename T>
PromiseResult< T > fl::task::make_success ( const T & value)

Helper function to create a successful result.

Template Parameters
TThe value type
Parameters
valueThe success value
Returns
result containing the value

Definition at line 134 of file promise_result.h.

134 {
135 return PromiseResult<T>(value);
136}

References fl::FL_NO_EXCEPT, and fl::type_rank< T >::value.

◆ make_success() [2/2]

template<typename T>
PromiseResult< T > fl::task::make_success ( T && value)

Helper function to create a successful result (move)

Template Parameters
TThe value type
Parameters
valueThe success value (moved)
Returns
result containing the value

Definition at line 143 of file promise_result.h.

143 {
145}

References fl::FL_NO_EXCEPT, fl::adl_barrier::move(), and fl::type_rank< T >::value.

+ Here is the call graph for this function:

◆ operator&()

bool fl::task::operator& ( ExecFlags a,
ExecFlags b )
inline

Definition at line 75 of file executor.h.

75 {
76 return (static_cast<u8>(a) & static_cast<u8>(b)) != 0;
77}
unsigned char u8
Definition stdint.h:131

References fl::FL_NO_EXCEPT.

◆ operator|()

ExecFlags fl::task::operator| ( ExecFlags a,
ExecFlags b )
inline

Definition at line 71 of file executor.h.

71 {
72 return static_cast<ExecFlags>(static_cast<u8>(a) | static_cast<u8>(b));
73}
ExecFlags
Flags controlling which subsystems run() pumps.
Definition executor.h:64

References fl::FL_NO_EXCEPT.

◆ run()

void fl::task::run ( fl::u32 microseconds = 1000,
ExecFlags flags = ExecFlags::ALL )

Run selected task subsystems.

Pumps the requested subsystems and yields for up to microseconds.

Usage:

Parameters
microsecondsBudget in microseconds (default 1000 = 1ms)
flagsWhich subsystems to pump (default ALL)

Definition at line 76 of file executor.cpp.hpp.

76 {
77 // Re-entrancy guard: detect if run is called from within run
79 if (running) {
80 FL_WARN_ONCE("task::run re-entrancy detected, skipping nested call");
81 return;
82 }
83 running = true;
84 auto guard = fl::make_scope_exit([&running]() { running = false; });
85
86 const bool do_tasks = flags & ExecFlags::TASKS;
87 const bool do_coroutines = flags & ExecFlags::COROUTINES;
88 const bool do_system = flags & ExecFlags::SYSTEM;
89
90 // Calculate start time with rollover protection
91 fl::u32 begin_time = fl::micros();
92
93 // Lambda to get elapsed time (rollover-safe)
94 auto elapsed = [begin_time]() {
95 return fl::micros() - begin_time;
96 };
97
98 // Lambda to get remaining time until deadline expires
99 auto remaining = [elapsed, microseconds]() -> fl::u32 {
100 fl::u32 e = elapsed();
101 if (e >= microseconds) {
102 return 0;
103 }
104 return microseconds - e;
105 };
106
107 // Lambda to check if deadline has expired
108 auto expired = [remaining]() {
109 return remaining() == 0;
110 };
111
112 do {
113 // TASKS: Scheduler (fl::task timers) + Executor (fetch, HTTP server, audio)
114 if (do_tasks) {
117 }
118
119 // SYSTEM: OS-level yield.
120 //
121 // When the caller provided a non-zero microseconds budget we treat
122 // this as an explicit spin-wait on hardware (typical DMA / driver
123 // wait loops). In that case we MUST use a deep yield (>= 1 FreeRTOS
124 // tick on ESP32) so that lower-priority network tasks — WiFi,
125 // Ethernet lwIP, etc. — actually get CPU time. Previously this
126 // path was gated on an active WiFi mode check, which missed
127 // Ethernet-only deployments and also the pre-connection window
128 // where `esp_wifi_get_mode` still returns WIFI_MODE_NULL. That
129 // regression manifested as the ESP32-S3 I2S-vs-websockets
130 // starvation reported in https://github.com/FastLED/FastLED/issues/2254
131 // (Issue 1).
132 //
133 // When microseconds == 0 the caller wants the cheapest possible
134 // yield (we are between other pumped subsystems and will loop
135 // again immediately), so we keep the lightweight fl::yield() path.
136 //
137 // The sleep is clamped to whatever is left of the caller's budget,
138 // mirroring the COROUTINES branch below. This used to be a hardcoded
139 // pumpCoroutines(1000) that ignored `microseconds` entirely, so a
140 // caller asking for run(250, SYSTEM) slept 1000 us and overshot its
141 // own deadline by 750 us on every platform where pumpCoroutines
142 // honors the requested duration (host/stub -- CoroutineRunner::run).
143 //
144 // ESP32 behavior is unchanged: pumpCoroutines() there converts us to
145 // FreeRTOS ticks and floors at one tick for ANY non-zero request
146 // (coroutine_esp32.impl.hpp, the `if (ticks == 0) ticks = 1` branch
147 // added for #2254), so 250 and 1000 both yield exactly one tick. The
148 // deep-yield guarantee #2254 depends on still holds.
149 if (do_system) {
150 if (microseconds > 0) {
151 const fl::u32 time_left = remaining();
152 if (time_left) {
153 fl::platforms::ICoroutineRuntime::instance().pumpCoroutines(
154 fl::min(1000u, time_left));
155 }
156 } else {
157 fl::yield();
158 }
159 }
160
161 // COROUTINES: Platform cooperative coroutines (pumpCoroutines)
162 if (do_coroutines) {
163 auto time_left = remaining();
164 if (time_left) {
165 fl::u32 sleep_us = fl::min(1000u, time_left);
166 fl::platforms::ICoroutineRuntime::instance().pumpCoroutines(sleep_us);
167 }
168 }
169 } while (!expired());
170}
static T & instance() FL_NO_EXCEPT
Definition singleton.h:133
void update_all() FL_NO_EXCEPT
Update all registered runners.
static Scheduler & instance() FL_NO_EXCEPT
void update() FL_NO_EXCEPT
#define FL_WARN_ONCE(...)
Definition log.h:439
duration< fl::i64, fl::micro > microseconds
Microseconds - duration with period of 1/1,000,000 seconds.
Definition chrono.h:103
FL_DISABLE_WARNING_PUSH U constexpr common_type_t< T, U > min(T a, U b) FL_NO_EXCEPT
Definition math.h:71
fl::u32 micros() FL_NO_EXCEPT
Universal microsecond timer - returns microseconds since system startup.
scope_exit< decay_t< EF > > make_scope_exit(EF &&f)
Factory for C++11/14 (no CTAD).
Definition scope_exit.h:48
void yield() FL_NO_EXCEPT
Yield to the platform scheduler.
Definition yield.cpp.hpp:32

References COROUTINES, fl::FL_NO_EXCEPT, FL_WARN_ONCE, fl::SingletonThreadLocal< T, N >::instance(), fl::task::Executor::instance(), fl::task::Scheduler::instance(), fl::make_scope_exit(), fl::micros(), fl::min(), SYSTEM, TASKS, fl::task::Scheduler::update(), fl::task::Executor::update_all(), and fl::yield().

Referenced by fl::detail::delay_impl(), fl::net::http::fetch_update(), loop(), and fl::net::http::FetchEngineListener::onEndFrame().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ yield_system()

void fl::task::yield_system ( fl::u32 microseconds)

OS-level yield only: same behavior as run(us, ExecFlags::SYSTEM).

Prefer this in driver/DMA wait loops. run() dispatches on its flags at runtime, so even a SYSTEM-only call links the task Scheduler and Executor into every sketch; this entry point references neither (#4797). microseconds > 0 deep-yields (>= 1 FreeRTOS tick on ESP32) until the budget is spent; 0 is a single lightweight fl::yield().

Definition at line 172 of file executor.cpp.hpp.

172 {
173 // Mirrors the SYSTEM branch of run() without naming Scheduler/Executor.
174 const fl::u32 begin_time = fl::micros();
175 do {
176 if (microseconds > 0) {
177 const fl::u32 e = fl::micros() - begin_time;
178 if (e < microseconds) {
179 fl::platforms::ICoroutineRuntime::instance().pumpCoroutines(
180 fl::min(1000u, microseconds - e));
181 }
182 } else {
183 fl::yield();
184 }
185 } while (fl::micros() - begin_time < microseconds);
186}

References fl::FL_NO_EXCEPT, fl::micros(), fl::min(), and fl::yield().

Referenced by throttleToMaxRefreshRate(), fl::ChannelManager::waitForCondition(), and fl::IChannelDriver::waitForCondition().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: