RetroArch/libretro-common/include/queues/task_queue.h
Jesse Talavera b7ddac2431
Add Doxygen-styled comments to parts of the libretro API (#15641)
* Touch up the documentation for a few environment calls

* Touch up more comments

* Update docs for more environment calls

* Add doc comments for more environment calls

* Change various @returns to indicate that the environment call is available

- Some environment calls might be recognized but ignored (e.g. when fast-forwarding during netplay)

* Note some deprecated symbols

* Touch up the docs for RETRO_ENVIRONMENT_SET_MESSAGE

* Touch up the docs for RETRO_ENVIRONMENT_SET_PIXEL_FORMAT

* Add more doc comments

* (libretro) Add more doxygen documentation for the libretro API

* (libretro) Add doxygen comments for the callbacks

* Document retro_init and retro_deinit

* Add comments for retro_log-related symbols

* Add a comment

* Clean up some camera-related comments

* Clean up frame time-related callbacks

* Correct some information about major callbacks

* Clarify some parameter info

* Fix incorrect info about retro_set_environment

* Update libretro-common/include/libretro.h

Co-authored-by: Rob Loach <robloach@gmail.com>

* (libretro) Add doxygen docs on RETRO_THROTTLE

* Touch up the docs for RETRO_ENVIRONMENT_SET_AUDIO_CALLBACK

* Touch up the docs for some macros

* Touch up the docs for some more environment calls

* Update libretro-common/include/libretro.h

Co-authored-by: Rob Loach <robloach@gmail.com>

* Update libretro-common/include/libretro.h

Co-authored-by: Rob Loach <robloach@gmail.com>

* Update libretro-common/include/libretro.h

Co-authored-by: Rob Loach <robloach@gmail.com>

* Update libretro-common/include/libretro.h

Co-authored-by: Rob Loach <robloach@gmail.com>

* Tidy up the doc comments for clamping.h

- It was a low-hanging fruit

* Define some sections for constants

- Doxygen will group all contained symbols on one page

* Fix a duplicate @see

* Polish up the docs for the rumble interface

* Polish up the docs for RETRO_ENVIRONMENT_GET_INPUT_DEVICE_CAPABILITIES

* Update libretro-common/include/libretro.h

Co-authored-by: Rob Loach <robloach@gmail.com>

* Document INLINE

* Clean up some tags

* Touch up the docs for the sensor interface

* Add docs for RETRO_ENVIRONMENT_SET_PROC_ADDRESS_CALLBACK

* Update docs for RETRO_ENVIRONMENT_GET_INPUT_BITMASKS and accompanying names

* Update some group definitions

* Spiff up the docs for retro_dirent.h

* Document dylib.h

* Document base64.h

* Document crc32.h

* Touch up the docs for audio conversion functions

* Clean up some Doxygen tags

* Refine the docs for RETRO_ENVIRONMENT_GET_PERF_INTERFACE

* Fix incorrect infor in dylib.h

* Touch up the docs for RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE

* Revise the docs for RETRO_ENVIRONMENT_SET_GEOMETRY

* Revise the docs for RETRO_ENVIRONMENT_GET_LOCATION_INTERFACE

* Revise a function's doc

* Touch up most of the rthreads docs

* Touch up the retro_timers.h docs

* Revise the subsystem docs

* Fix some incorrect @see's

* Touch up the docs for RETRO_ENVIRONMENT_GET_LED_INTERFACE

* Give the RETRO_ENVIRONMENT_GET_SAVESTATE_CONTEXT docs a makeover

* Slight cleanup to the microphone docs

* Slight cleanup to the device power docs

* Touch up serialization quirk docs

* Give the MIDI docs a haircut

* Update libretro-common/include/libretro.h

Co-authored-by: Rob Loach <robloach@gmail.com>

* Freshen up rtime's docs

* Improve the docs and accompanying definitions for RETRO_ENVIRONMENT_GET_AUDIO_VIDEO_ENABLE

- Revise the text of the documentation
- Introduce an enum that defines the flags (it's still an int, so ABI compatibility will be fine)
- Move the documentation for each bit to its corresponding enum

* Shine the shoes of RETRO_ENVIRONMENT_GET_INPUT_MAX_USERS's docs

* Freshen up the docs for fifo_queue.h

* Document most of task_queue.h

* Put retro_dirent's symbols in a group

* Finish documenting task_queue.h

* Document some compatibility headers

* Document read_stdin

* Document file_stream_transforms.h

* Document the VFS API

- Not the wrappers, just the plain API itself

* (Docs) Add doxygen notes about RETRO_DEVICE_*

* Fix some line breaks

* Revise RETRO_DEVICE docs

* Document strl.h

* Update the features_cpu.h docs

* Rewrite the docs for file_stream.h

* Update the docs for retro_endianness.h

* Update the docs for retro_miscellaneous.h

* Document the RETRO_VFS_SEEK_POSITION constants

* Finish documenting rthreads.h

* Document network_stream.h

* Put the RETRO_MEMORY defines in a defgroup

* Move a doc comment in retro_common.h to file scope

* Revise the docs for RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, and accompanying symbols

* Fix the @param/in/out order in libretro.h's @param declarations

* Tidy up the docs for RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION

* Spiff up the docs for RETRO_ENVIRONMENT_GET_CURRENT_SOFTWARE_FRAMEBUFFER

* Fix some tags

* Polish up RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE's docs

* libretro: Add header doxygen

* Update libretro-common/include/libretro.h

Co-authored-by: Rob Loach <robloach@gmail.com>

* Update libretro-common/include/libretro.h

Co-authored-by: Rob Loach <robloach@gmail.com>

* Clean up the docs for RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY

* Clean up the docs for RETRO_ENVIRONMENT_SET_HW_RENDER_CONTEXT_NEGOTIATION_INTERFACE

* Touch up some comment syntax for RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE

* Fix some inaccuracies

* Re-add the license statement for libretro.h

* Touch up the docs for RETRO_ENVIRONMENT_SET_CORE_OPTIONS_V2

* Touch up docs for RETRO_ENVIRONMENT_SET_CORE_OPTIONS_DISPLAY

* Touch up docs for some options-related symbols

* Fix some syntax that was preventing most doc files from being generated

* Express retro_core_option_definition docs in terms of retro_core_option_v2_definition

* Finalize some core option-related docs

* Fix some incorrect info about achievements

* Polish up the docs for RETRO_ENVIRONMENT_SET_MEMORY_MAPS

* Polish up the docs for RETRO_ENVIRONMENT_GET_DISK_CONTROL_INTERFACE_VERSION

* Add a notice for `RETRO_ENVIRONMENT_GET_LOG_INTERFACE`

* Update the disk control interface docs

* Add a sentence to a doc comment

* Update a comment

* Remove an irrelevant @todo

* Touch up the docs for `retro_message_target`

* Touch up the docs for `retro_message_type`

* Touch up the docs for `RETRO_ENVIRONMENT_SET_MESSAGE_EXT`

* Touch up the docs for `RETRO_ENVIRONMENT_SET_AUDIO_BUFFER_STATUS_CALLBACK`

* Touch up the docs for `RETRO_ENVIRONMENT_SET_MINIMUM_AUDIO_LATENCY`

* Revise a comment

* Revise the docs for `RETRO_ENVIRONMENT_SET_VARIABLE`

* Add a `@see`

* Clean up the `RETRO_ENVIRONMENT_SET_FASTFORWARDING_OVERRIDE` docs

* Update the Doxyfile

* libretro: Add three more environment callback doxygen docs

* doxygen: Remove @example reference

---------

Co-authored-by: Rob Loach <robloach@gmail.com>
2024-03-09 17:24:01 -08:00

747 lines
22 KiB
C

/* Copyright (C) 2010-2020 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (task_queue.h).
* ---------------------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge,
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __LIBRETRO_SDK_TASK_QUEUE_H__
#define __LIBRETRO_SDK_TASK_QUEUE_H__
#include <stdint.h>
#include <stddef.h>
#include <boolean.h>
#include <retro_common.h>
#include <retro_common_api.h>
#include <libretro.h>
RETRO_BEGIN_DECLS
enum task_type
{
/** A regular task. The vast majority of tasks will use this type. */
TASK_TYPE_NONE,
/**
* Only one blocking task can exist in the queue at a time.
* Attempts to add a new one while another is running will fail.
*/
TASK_TYPE_BLOCKING
};
enum task_style
{
TASK_STYLE_NONE,
TASK_STYLE_POSITIVE,
TASK_STYLE_NEGATIVE
};
typedef struct retro_task retro_task_t;
/** @copydoc retro_task::callback */
typedef void (*retro_task_callback_t)(retro_task_t *task,
void *task_data,
void *user_data, const char *error);
/** @copydoc retro_task::handler */
typedef void (*retro_task_handler_t)(retro_task_t *task);
/** @copydoc task_finder_data::func */
typedef bool (*retro_task_finder_t)(retro_task_t *task,
void *userdata);
/**
* Displays a message output by a task.
*/
typedef void (*retro_task_queue_msg_t)(retro_task_t *task,
const char *msg,
unsigned prio, unsigned duration, bool flush);
/** @copydoc task_retriever_data::func */
typedef bool (*retro_task_retriever_t)(retro_task_t *task, void *data);
/**
* Called by \c task_queue_wait after each task executes
* (i.e. once per pass over the queue).
* @param data Arbitrary data.
* The function should cast this to a known type.
* @return \c true if \c task_queue_wait should continue waiting,
* \c false if it should return early.
* @see task_queue_wait
*/
typedef bool (*retro_task_condition_fn_t)(void *data);
typedef struct
{
char *source_file;
} decompress_task_data_t;
/**
* A unit of work executed by the task system,
* spread across one or more frames.
*
* Some fields are set by the caller,
* others are set by the task system.
*/
struct retro_task
{
/**
* The time (in microseconds) when the task should start running,
* or 0 if it should start as soon as possible.
* The exact time this task starts will depend on when the queue is next updated.
* Set by the caller.
* @note This is a point in time, not a duration.
* It is not affected by a frontend's time manipulation (pausing, fast-forward, etc.).
* @see cpu_features_get_time_usec
*/
retro_time_t when;
/**
* The main body of work for a task.
* Should be as fast as possible,
* as it will be called with each task queue update
* (usually once per frame).
* Must not be \c NULL.
*
* @param task The task that this handler is associated with.
* Can be used to configure or query the task.
* Will never be \c NULL.
* @see task_queue_check
*/
retro_task_handler_t handler;
/**
* Called when this task finishes;
* executed during the next task queue update
* after \c finished is set to \c true.
* May be \c NULL, in which case this function is skipped.
*
* @param task The task that is being cleaned up.
* Will never be \c NULL.
* @param task_data \c task's \c task_data field.
* @param user_data \c task's \c user_data field.
* @param error \c task's \c error field.
* @see task_queue_check
* @see retro_task_callback_t
*/
retro_task_callback_t callback;
/**
* Called when this task finishes immediately after \c callback is run.
* Used to clean up any resources or state owned by the task.
* May be \c NULL, in which case this function is skipped.
*
* @param task The task that is being cleaned up.
* Will never be \c NULL.
*/
retro_task_handler_t cleanup;
/**
* Pointer to arbitrary data, intended for "returning" an object from the task
* (although it can be used for any purpose).
* If owned by the task, it should be cleaned up within \c cleanup.
* Not modified or freed by the task queue.
*/
void *task_data;
/**
* Pointer to arbitrary data, intended for passing parameters to the task.
* If owned by the task, it should be cleaned up within \c cleanup.
* Not modified or freed by the task queue.
*/
void *user_data;
/**
* Pointer to arbitrary data, intended for state that exists for the task's lifetime.
* If owned by the task, it should be cleaned up within \c cleanup.
* Not modified or freed by the task queue.
*/
void *state;
/**
* Human-readable details about an error that occurred while running the task.
* Should be created and assigned within \c handler if there was an error.
* Will be cleaned up by the task queue with \c free() upon this task's completion.
* @see task_set_error
*/
char *error;
/**
* Called to update a task's \c progress,
* or to update some view layer (e.g. an on-screen display)
* about the task's progress.
*
* Skipped if \c NULL or if \c mute is set.
*
* @param task The task whose progress is being updated or reported.
* @see progress
*/
void (*progress_cb)(retro_task_t*);
/**
* Human-readable description of this task.
* May be \c NULL,
* but if not then it will be disposed of by the task system with \c free()
* upon this task's completion.
* Can be modified or replaced at any time.
* @see strdup
*/
char *title;
/**
* Pointer to arbitrary data, intended for use by a frontend
* (for example, to associate a sticky notification with a task).
*
* This should be cleaned up within \c cleanup if necessary.
* Cores may use this for any purpose.
*/
void *frontend_userdata;
/**
* @private Pointer to the next task in the queue.
* Do not touch this; it is managed by the task system.
*/
retro_task_t *next;
/**
* Indicates the current progress of the task.
*
* -1 means the task is indefinite or not measured,
* 0-100 is a percentage of the task's completion.
*
* Set by the caller.
*
* @see progress_cb
*/
int8_t progress;
/**
* A unique identifier assigned to a task when it's created.
* Set by the task system.
*/
uint32_t ident;
/**
* The type of task this is.
* Set by the caller.
*/
enum task_type type;
enum task_style style;
/**
* If \c true, the frontend should use some alternative means
* of displaying this task's progress or messages.
* Not used within cores.
*/
bool alternative_look;
/**
* Set to \c true by \c handler to indicate that this task has finished.
* At this point the task queue will call \c callback and \c cleanup,
* then deallocate the task.
*/
bool finished;
/**
* Set to true by the task queue to signal that this task \em must end.
* \c handler should check to see if this is set,
* aborting or completing its work as soon as possible afterward.
* \c callback and \c cleanup will still be called as normal.
*
* @see task_queue_reset
*/
bool cancelled;
/**
* If set, the task queue will not call \c progress_cb
* and will not display any messages from this task.
*/
bool mute;
};
/**
* Parameters for \c task_queue_find.
*
* @see task_queue_find
*/
typedef struct task_finder_data
{
/**
* Predicate to call for each task.
* Must not be \c NULL.
*
* @param task The task to query.
* @param userdata \c userdata from this struct.
* @return \c true if this task matches the search criteria,
* at which point \c task_queue_find will stop searching and return \c true.
*/
retro_task_finder_t func;
/**
* Pointer to arbitrary data.
* Passed directly to \c func.
* May be \c NULL.
*/
void *userdata;
} task_finder_data_t;
/**
* Contains the result of a call to \c task_retriever_data::func.
* Implemented as an intrusive singly-linked list.
*/
typedef struct task_retriever_info
{
/**
* The next item in the result list,
* or \c NULL if this is the last one.
*/
struct task_retriever_info *next;
/**
* Arbitrary data returned by \c func.
* Can be anything, but should be a simple \c struct
* so that it can be freed by \c task_queue_retriever_info_free.
*/
void *data;
} task_retriever_info_t;
/**
* Parameters for \c task_queue_retrieve.
*
* @see task_queue_retrieve
*/
typedef struct task_retriever_data
{
/**
* Contains the result of each call to \c func that returned \c true.
* Should be initialized to \c NULL.
* Will remain \c NULL after \c task_queue_retrieve if no tasks matched.
* Must be freed by \c task_queue_retriever_info_free.
* @see task_queue_retriever_info_free
*/
task_retriever_info_t *list;
/**
* The handler to compare against.
* Only tasks with this handler will be considered for retrieval.
* Must not be \c NULL.
*/
retro_task_handler_t handler;
/**
* The predicate that determines if the given task will be retrieved.
* Must not be \c NULL.
*
* @param task[in] The task to query.
* @param data[out] Arbitrary data that the retriever should return.
* Allocated by the task queue based on \c element_size.
* @return \c true if \c data should be appended to \c list.
*/
retro_task_retriever_t func;
/**
* The size of the output that \c func may write to.
* Must not be zero.
*/
size_t element_size;
} task_retriever_data_t;
/**
* Returns the next item in the result list.
* Here's a usage example, assuming that \c results is used to store strings:
*
* @code{.c}
* void print_results(task_retriever_info_t *results)
* {
* char* text = NULL;
* task_retriever_info_t *current = results;
* while (text = task_queue_retriever_info_next(&current))
* {
* printf("%s\n", text);
* }
* }
* @endcode
*
* @param link Pointer to the first element in the result list.
* Must not be \c NULL.
* @return The next item in the result list.
*/
void *task_queue_retriever_info_next(task_retriever_info_t **link);
/**
* Frees the result of a call to \c task_queue_retrieve.
* @param list The result list to free.
* May be \c NULL, in which case this function does nothing.
* The list, its nodes, and its elements will all be freed.
*
* If the list's elements must be cleaned up with anything besides \c free,
* then the caller must do that itself before invoking this function.
*/
void task_queue_retriever_info_free(task_retriever_info_t *list);
/**
* Cancels the provided task.
* The task should finish its work as soon as possible afterward.
*
* @param task The task to cancel.
* @see task_set_cancelled
*/
void task_queue_cancel_task(void *task);
/**
* Sets \c task::finished to the given value.
* Thread-safe if the task queue is threaded.
*
* @param task The task to modify.
* Behavior is undefined if \c NULL.
* @param finished Whether the task should be considered finished.
* @see retro_task::finished
*/
void task_set_finished(retro_task_t *task, bool finished);
/**
* Sets \c task::mute to the given value.
* Thread-safe if the task queue is threaded.
*
* @param task The task to modify.
* Behavior is undefined if \c NULL.
* @param mute Whether the task should be considered muted.
* @see retro_task::mute
*/
void task_set_mute(retro_task_t *task, bool mute);
/**
* Sets \c task::error to the given value.
* Thread-safe if the task queue is threaded.
*
* @param task The task to modify.
* Behavior is undefined if \c NULL.
* @param error The error message to set.
* @see retro_task::error
* @warning This does not free the existing error message.
* The caller must do that itself.
*/
void task_set_error(retro_task_t *task, char *error);
/**
* Sets \c task::progress to the given value.
* Thread-safe if the task queue is threaded.
*
* @param task The task to modify.
* Behavior is undefined if \c NULL.
* @param progress The progress value to set.
* @see retro_task::progress
*/
void task_set_progress(retro_task_t *task, int8_t progress);
/**
* Sets \c task::title to the given value.
* Thread-safe if the task queue is threaded.
*
* @param task The task to modify.
* Behavior is undefined if \c NULL.
* @param title The title to set.
* @see retro_task::title
* @see task_free_title
* @warning This does not free the existing title.
* The caller must do that itself.
*/
void task_set_title(retro_task_t *task, char *title);
/**
* Sets \c task::data to the given value.
* Thread-safe if the task queue is threaded.
*
* @param task The task to modify.
* Behavior is undefined if \c NULL.
* @param data The data to set.
* @see retro_task::data
*/
void task_set_data(retro_task_t *task, void *data);
/**
* Sets \c task::cancelled to the given value.
* Thread-safe if the task queue is threaded.
*
* @param task The task to modify.
* Behavior is undefined if \c NULL.
* @param cancelled Whether the task should be considered cancelled.
* @see retro_task::cancelled
*/
void task_set_cancelled(retro_task_t *task, bool cancelled);
/**
* Frees the \c task's title, if any.
* Thread-safe if the task queue is threaded.
*
* @param task The task to modify.
* @see task_set_title
*/
void task_free_title(retro_task_t *task);
/**
* Returns \c task::cancelled.
* Thread-safe if the task queue is threaded.
*
* @param task The task to query.
* Behavior is undefined if \c NULL.
* @return The value of \c task::cancelled.
* @see retro_task::cancelled
*/
bool task_get_cancelled(retro_task_t *task);
/**
* Returns \c task::finished.
* Thread-safe if the task queue is threaded.
*
* @param task The task to query.
* Behavior is undefined if \c NULL.
* @return The value of \c task::finished.
* @see retro_task::finished
*/
bool task_get_finished(retro_task_t *task);
/**
* Returns \c task::mute.
* Thread-safe if the task queue is threaded.
*
* @param task The task to query.
* Behavior is undefined if \c NULL.
* @return The value of \c task::mute.
* @see retro_task::mute
*/
bool task_get_mute(retro_task_t *task);
/**
* Returns \c task::error.
* Thread-safe if the task queue is threaded.
*
* @param task The task to query.
* Behavior is undefined if \c NULL.
* @return The value of \c task::error.
* @see retro_task::error
*/
char* task_get_error(retro_task_t *task);
/**
* Returns \c task::progress.
* Thread-safe if the task queue is threaded.
*
* @param task The task to query.
* Behavior is undefined if \c NULL.
* @return The value of \c task::progress.
* @see retro_task::progress
*/
int8_t task_get_progress(retro_task_t *task);
/**
* Returns \c task::title.
* Thread-safe if the task queue is threaded.
*
* @param task The task to query.
* Behavior is undefined if \c NULL.
* @return The value of \c task::title.
* @see retro_task::title
*/
char* task_get_title(retro_task_t *task);
/**
* Returns \c task::data.
* Thread-safe if the task queue is threaded.
*
* @param task The task to query.
* Behavior is undefined if \c NULL.
* @return The value of \c task::data.
* @see retro_task::data
*/
void* task_get_data(retro_task_t *task);
/**
* Returns whether the task queue is running
* on the same thread that called \c task_queue_init.
*
* @return \c true if the caller is running
* on the same thread that called \c task_queue_init.
*/
bool task_is_on_main_thread(void);
/**
* Ensures that the task queue is in threaded mode.
*
* Next time \c retro_task_queue_check is called,
* the task queue will be recreated with threading enabled.
* Existing tasks will continue to run on the new thread.
*/
void task_queue_set_threaded(void);
/**
* Ensures that the task queue is not in threaded mode.
*
* Next time \c retro_task_queue_check is called,
* the task queue will be recreated with threading disabled.
* Existing tasks will continue to run on whichever thread updates the queue.
*
* @see task_queue_set_threaded
* @see task_queue_is_threaded
*/
void task_queue_unset_threaded(void);
/**
* Returns whether the task queue is running in threaded mode.
*
* @return \c true if the task queue is running its tasks on a separate thread.
*/
bool task_queue_is_threaded(void);
/**
* Calls the function given in \c find_data for each task
* until it returns \c true for one of them,
* or until all tasks have been searched.
*
* @param find_data Parameters for the search.
* Behavior is undefined if \c NULL.
* @return \c true if \c find_data::func returned \c true for any task.
* @see task_finder_data_t
*/
bool task_queue_find(task_finder_data_t *find_data);
/**
* Retrieves arbitrary data from every task
* whose handler matches \c data::handler.
*
* @param data[in, out] Parameters for retrieving data from the task queue,
* including the results themselves.
* Behavior is undefined if \c NULL.
* @see task_retriever_data_t
*/
void task_queue_retrieve(task_retriever_data_t *data);
/**
* Runs each task.
* If a task is finished or cancelled,
* its callback and cleanup handler will be called.
* Afterwards, the task will be deallocated.
* If used in a core, generally called in \c retro_run
* and just before \c task_queue_deinit.
* @warning This must only be called from the main thread.
*/
void task_queue_check(void);
/**
* Schedules a task to start running.
* If \c task::when is 0, it will start as soon as possible.
*
* Tasks with the same \c task::when value
* will be executed in the order they were scheduled.
*
* @param task The task to schedule.
* @return \c true unless \c task's type is \c TASK_TYPE_BLOCKING
* and there's already a blocking task in the queue.
*/
bool task_queue_push(retro_task_t *task);
/**
* Block until all active (i.e. current time > \c task::when) tasks have finished,
* or until the given function returns \c false.
* If a scheduled task's \c when is passed while within this function,
* it will start executing.
*
* Must only be called from the main thread.
*
* @param cond Function to call after all tasks in the queue have executed
* (i.e. once per pass over the task queue).
* May be \c NULL, in which case the task queue will wait unconditionally.
* @param data Pointer to arbitrary data, passed directly into \c cond.
* May be \c NULL.
* @see retro_task_condition_fn_t
* @see task_queue_deinit
* @see task_queue_reset
* @warning Passing \c NULL to \c cond is strongly discouraged.
* If you use tasks that run indefinitely
* (e.g. for the lifetime of the core),
* you will need a way to stop these tasks externally;
* otherwise, you risk the frontend and core freezing.
*/
void task_queue_wait(retro_task_condition_fn_t cond, void* data);
/**
* Marks all tasks in the queue as cancelled.
*
* The tasks won't immediately be terminated;
* each task may finish its work,
* but must do so as quickly as possible.
*
* Must only be called from the main thread.
*
* @see task_queue_wait
* @see task_queue_deinit
* @see task_set_finished
* @see task_get_cancelled
*/
void task_queue_reset(void);
/**
* Deinitializes the task system.
*
* Outstanding tasks will not be cleaned up;
* if the intent is to finish the core or frontend's work,
* then all tasks must be finished before calling this function.
* May be safely called multiple times in a row,
* but only from the main thread.
* @see task_queue_wait
* @see task_queue_reset
*/
void task_queue_deinit(void);
/**
* Initializes the task system with the provided parameters.
* Must be called before any other task_queue_* function,
* and must only be called from the main thread.
*
* @param threaded \c true if tasks should run on a separate thread,
* \c false if they should remain on the calling thread.
* All tasks run in sequence on a single thread.
* If you want to scale a task to multiple threads,
* you must do so within the task itself.
* @param msg_push The task system will call this function to output messages.
* If \c NULL, no messages will be output.
* @note Calling this function while the task system is already initialized
* will reinitialize it with the new parameters,
* but it will not reset the task queue;
* all existing tasks will continue to run
* when the queue is updated.
* @see task_queue_deinit
* @see retro_task_queue_msg_t
*/
void task_queue_init(bool threaded, retro_task_queue_msg_t msg_push);
/**
* Allocates and initializes a new task.
* Deallocated by the task queue after it finishes executing.
*
* @returns Pointer to a newly allocated task,
* or \c NULL if allocation fails.
*/
retro_task_t *task_init(void);
RETRO_END_DECLS
#endif