CX Framework
Cross-platform C utility framework
Loading...
Searching...
No Matches
Task Queue

Modules

 Task Objects
 
 System Task Queue
 
 Task Queue Configuration
 
 Task Queue Lifecycle
 
 Task Operations
 
 Task State Queries
 
 Task Queue Types
 
 Task Requirements
 
 Task Resources
 

Detailed Description

The CX task queue system provides an object-oriented framework for managing asynchronous task execution in multithreaded applications. It supports everything from simple fire-and-forget tasks to complex dependency graphs with resource management.

Architecture Overview

The task queue system is built on several layers:

Task Types

BasicTask - Bare minimum task with no dependencies or scheduling. Just a run method and state tracking. Suitable for simple operations that need to run on a worker thread.

Task - Extends BasicTask with a name, timing information, and completion callbacks. Can wait for completion with timeouts.

ComplexTask - Extends Task with support for:

MultiphaseTask (MPTask) - Extends ComplexTask for multi-phase operations with an internal state machine. Phases can be added as an array of functions that execute sequentially, with optional fail phases for error handling.

Queue Modes and Presets

Task queues can be configured in various modes using preset functions:

Single Thread (tqPresetSingle) - One worker thread for UI or single-threaded work:

Minimal (tqPresetMinimal) - Lightweight threading for background work:

Balanced (tqPresetBalanced) - General-purpose configuration:

Heavy (tqPresetHeavy) - High-performance under sustained load:

Manual (tqPresetManual) - No worker threads, call tqTick() manually:

Configuration Flags

TQ_ManagerThread - Use a dedicated thread for queue maintenance instead of stealing idle worker time. Recommended for heavy workloads.

TQ_Monitor - Enable queue monitoring for debugging stuck tasks. Reports tasks that are running too long, waiting too long, or stalled without progress.

TQ_NoComplex - Restrict queue to BasicTask/Task only, disabling ComplexTask features. Reduces overhead when dependencies and scheduling aren't needed.

TQ_Manual - No thread pool; queue must be ticked manually with tqTick().

TQ_Oneshot - In manual mode, only run one task per tick instead of all available tasks.

Task Resources

ComplexTask can require resources before execution:

TRMutex - Mutex-based serialization. Simple and efficient for moderate contention. Tasks are woken in approximate FIFO order.

TRFifo - Strictly ordered FIFO queue. Guarantees serialized execution in registration order. Scales efficiently to large numbers of waiting tasks.

TRLifo - LIFO (stack) ordering for specialized use cases where most recent requesters should be serviced first.

TRGate - One-time event gate. Multiple tasks can wait on a gate that opens once, releasing all waiting tasks. Can be sealed to fail tasks that depend on it.

Task Dependencies

ComplexTask supports several types of dependencies:

ctaskDependOn(task, dep); // Wait for dep to complete successfully
ctaskWaitFor(task, dep); // Wait for dep, but don't fail if dep fails
ctaskRequireResource(task, res); // Acquire exclusive resource
ctaskRequireGate(task, gate); // Wait for gate to open
#define ctaskWaitFor(task, dep)
Definition complextask.h:56
#define ctaskRequireResource(self, res)
#define ctaskDependOn(task, dep)
Definition complextask.h:52
#define ctaskRequireGate(self, gate)

Dependencies can have timeouts:

ctaskDependOnTimeout(task, dep, timeS(30)); // Fail if dep not done in 30s
#define ctaskDependOnTimeout(task, dep, timeout)
Definition complextask.h:60
#define timeS(s)
Definition time.h:18

Task Scheduling

ComplexTask can be scheduled to run at future times:

tqSchedule(tq, task, timeMS(100)); // Run after 100ms delay
tqDefer(tq, task); // Hold until manually advanced
taskAdvance(task); // Release a deferred task
#define timeMS(ms)
Definition time.h:23
#define tqDefer(tq, task)
Definition taskqueue.h:168
#define tqSchedule(tq, task, delay)
Definition taskqueue.h:151

Tasks can also reschedule themselves by returning TASK_Result_Schedule or TASK_Result_Defer from their run method, with the delay specified in the TaskControl structure.

Queue Monitoring

Enable monitoring with tqEnableMonitor() to debug task queue issues:

Basic Usage Example

// Create and configure queue
TaskQueue *tq = tqCreate(_S"MyQueue", &config);
tqStart(tq);
// Create and run a task
MyTask *task = mytaskCreate();
tqRun(tq, &task); // Adds and releases
// Shutdown
tqShutdown(tq, timeS(5));
#define objRelease(pinst)
Definition objclass.h:223
#define _S
Creates a static ASCII string from a string literal.
Definition strbase.h:392
void tqPresetBalanced(TaskQueueConfig *tqconfig)
#define tqShutdown(tq, wait)
Definition taskqueue.h:104
#define tqStart
Definition taskqueue.h:87
TaskQueue * tqCreate(strref name, TaskQueueConfig *tqconfig)
#define tqRun(tq, ptask)
Definition taskqueue.h:134
Complete configuration for a task queue.