The TaskRunner
The task runner runs long-running operations on a puzzle. It is used to run operations that take more than a frame to complete, and uses a thread to do so. Currently, there are four tasks that use it: The Word Solver, the Anagram Solver, the Theme Word Fitter, and the Grid Fill Task.
API and State
All tasks must inherit from PuzzleTask, and implement the run and
set_run_info class methods.
task_runner_run(): Transitions to RUNNING. Initializes a new TaskContext. If a previous COMPLETE task existed, it is reset first.task_runner_cancel(): Cancels the task. The task enters the COMPLETE state upon yielding. Results collected up to the cancellation point remain accessible viatask_runner_get_result().task_runner_reset(): Immediately transitions the runner to READY. If a thread is active, it is cancelled and marked for background cleanup; its results become inaccessible immediately.
Progress Updates
Tasks can provide intermediate results while they are running. There are two ways of doing this that are thread safe:
There’s a
countgint that can be used to indicate number of runs. It can be updated withg_atomic_int_inc ()There’s a results array (with associated
GMutex) that results (agpointer) can be placed in. Either unique results can be put there, or a single item that’s updated. In the case of the latter, care should be taken to lock it.
In the main thread, the UI can poll the task for updates in a
timeout. In addition, there’s a thread-safe TaskRunner::updated
signal that can be triggered within the job by calling
puzzle_task_update(). This can let the main thread know to check the
results array for updates.
When the task is done TaskRunner::finished is emitted.