mirror of
				https://github.com/thunderbrewhq/thunderbrew
				synced 2025-10-31 08:16:03 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			547 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			547 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|   Simple DirectMedia Layer
 | |
|   Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
 | |
| 
 | |
|   This software is provided 'as-is', without any express or implied
 | |
|   warranty.  In no event will the authors be held liable for any damages
 | |
|   arising from the use of this software.
 | |
| 
 | |
|   Permission is granted to anyone to use this software for any purpose,
 | |
|   including commercial applications, and to alter it and redistribute it
 | |
|   freely, subject to the following restrictions:
 | |
| 
 | |
|   1. The origin of this software must not be misrepresented; you must not
 | |
|      claim that you wrote the original software. If you use this software
 | |
|      in a product, an acknowledgment in the product documentation would be
 | |
|      appreciated but is not required.
 | |
|   2. Altered source versions must be plainly marked as such, and must not be
 | |
|      misrepresented as being the original software.
 | |
|   3. This notice may not be removed or altered from any source distribution.
 | |
| */
 | |
| 
 | |
| /* WIKI CATEGORY: AsyncIO */
 | |
| 
 | |
| /**
 | |
|  * # CategoryAsyncIO
 | |
|  *
 | |
|  * SDL offers a way to perform I/O asynchronously. This allows an app to read
 | |
|  * or write files without waiting for data to actually transfer; the functions
 | |
|  * that request I/O never block while the request is fulfilled.
 | |
|  *
 | |
|  * Instead, the data moves in the background and the app can check for results
 | |
|  * at their leisure.
 | |
|  *
 | |
|  * This is more complicated than just reading and writing files in a
 | |
|  * synchronous way, but it can allow for more efficiency, and never having
 | |
|  * framerate drops as the hard drive catches up, etc.
 | |
|  *
 | |
|  * The general usage pattern for async I/O is:
 | |
|  *
 | |
|  * - Create one or more SDL_AsyncIOQueue objects.
 | |
|  * - Open files with SDL_AsyncIOFromFile.
 | |
|  * - Start I/O tasks to the files with SDL_ReadAsyncIO or SDL_WriteAsyncIO,
 | |
|  *   putting those tasks into one of the queues.
 | |
|  * - Later on, use SDL_GetAsyncIOResult on a queue to see if any task is
 | |
|  *   finished without blocking. Tasks might finish in any order with success
 | |
|  *   or failure.
 | |
|  * - When all your tasks are done, close the file with SDL_CloseAsyncIO. This
 | |
|  *   also generates a task, since it might flush data to disk!
 | |
|  *
 | |
|  * This all works, without blocking, in a single thread, but one can also wait
 | |
|  * on a queue in a background thread, sleeping until new results have arrived:
 | |
|  *
 | |
|  * - Call SDL_WaitAsyncIOResult from one or more threads to efficiently block
 | |
|  *   until new tasks complete.
 | |
|  * - When shutting down, call SDL_SignalAsyncIOQueue to unblock any sleeping
 | |
|  *   threads despite there being no new tasks completed.
 | |
|  *
 | |
|  * And, of course, to match the synchronous SDL_LoadFile, we offer
 | |
|  * SDL_LoadFileAsync as a convenience function. This will handle allocating a
 | |
|  * buffer, slurping in the file data, and null-terminating it; you still check
 | |
|  * for results later.
 | |
|  *
 | |
|  * Behind the scenes, SDL will use newer, efficient APIs on platforms that
 | |
|  * support them: Linux's io_uring and Windows 11's IoRing, for example. If
 | |
|  * those technologies aren't available, SDL will offload the work to a thread
 | |
|  * pool that will manage otherwise-synchronous loads without blocking the app.
 | |
|  *
 | |
|  * ## Best Practices
 | |
|  *
 | |
|  * Simple non-blocking I/O--for an app that just wants to pick up data
 | |
|  * whenever it's ready without losing framerate waiting on disks to spin--can
 | |
|  * use whatever pattern works well for the program. In this case, simply call
 | |
|  * SDL_ReadAsyncIO, or maybe SDL_LoadFileAsync, as needed. Once a frame, call
 | |
|  * SDL_GetAsyncIOResult to check for any completed tasks and deal with the
 | |
|  * data as it arrives.
 | |
|  *
 | |
|  * If two separate pieces of the same program need their own I/O, it is legal
 | |
|  * for each to create their own queue. This will prevent either piece from
 | |
|  * accidentally consuming the other's completed tasks. Each queue does require
 | |
|  * some amount of resources, but it is not an overwhelming cost. Do not make a
 | |
|  * queue for each task, however. It is better to put many tasks into a single
 | |
|  * queue. They will be reported in order of completion, not in the order they
 | |
|  * were submitted, so it doesn't generally matter what order tasks are
 | |
|  * started.
 | |
|  *
 | |
|  * One async I/O queue can be shared by multiple threads, or one thread can
 | |
|  * have more than one queue, but the most efficient way--if ruthless
 | |
|  * efficiency is the goal--is to have one queue per thread, with multiple
 | |
|  * threads working in parallel, and attempt to keep each queue loaded with
 | |
|  * tasks that are both started by and consumed by the same thread. On modern
 | |
|  * platforms that can use newer interfaces, this can keep data flowing as
 | |
|  * efficiently as possible all the way from storage hardware to the app, with
 | |
|  * no contention between threads for access to the same queue.
 | |
|  *
 | |
|  * Written data is not guaranteed to make it to physical media by the time a
 | |
|  * closing task is completed, unless SDL_CloseAsyncIO is called with its
 | |
|  * `flush` parameter set to true, which is to say that a successful result
 | |
|  * here can still result in lost data during an unfortunately-timed power
 | |
|  * outage if not flushed. However, flushing will take longer and may be
 | |
|  * unnecessary, depending on the app's needs.
 | |
|  */
 | |
| 
 | |
| #ifndef SDL_asyncio_h_
 | |
| #define SDL_asyncio_h_
 | |
| 
 | |
| #include <SDL3/SDL_stdinc.h>
 | |
| 
 | |
| #include <SDL3/SDL_begin_code.h>
 | |
| /* Set up for C function definitions, even when using C++ */
 | |
| #ifdef __cplusplus
 | |
| extern "C" {
 | |
| #endif
 | |
| 
 | |
| /**
 | |
|  * The asynchronous I/O operation structure.
 | |
|  *
 | |
|  * This operates as an opaque handle. One can then request read or write
 | |
|  * operations on it.
 | |
|  *
 | |
|  * \since This struct is available since SDL 3.2.0.
 | |
|  *
 | |
|  * \sa SDL_AsyncIOFromFile
 | |
|  */
 | |
| typedef struct SDL_AsyncIO SDL_AsyncIO;
 | |
| 
 | |
| /**
 | |
|  * Types of asynchronous I/O tasks.
 | |
|  *
 | |
|  * \since This enum is available since SDL 3.2.0.
 | |
|  */
 | |
| typedef enum SDL_AsyncIOTaskType
 | |
| {
 | |
|     SDL_ASYNCIO_TASK_READ,   /**< A read operation. */
 | |
|     SDL_ASYNCIO_TASK_WRITE,  /**< A write operation. */
 | |
|     SDL_ASYNCIO_TASK_CLOSE   /**< A close operation. */
 | |
| } SDL_AsyncIOTaskType;
 | |
| 
 | |
| /**
 | |
|  * Possible outcomes of an asynchronous I/O task.
 | |
|  *
 | |
|  * \since This enum is available since SDL 3.2.0.
 | |
|  */
 | |
| typedef enum SDL_AsyncIOResult
 | |
| {
 | |
|     SDL_ASYNCIO_COMPLETE,  /**< request was completed without error */
 | |
|     SDL_ASYNCIO_FAILURE,   /**< request failed for some reason; check SDL_GetError()! */
 | |
|     SDL_ASYNCIO_CANCELED   /**< request was canceled before completing. */
 | |
| } SDL_AsyncIOResult;
 | |
| 
 | |
| /**
 | |
|  * Information about a completed asynchronous I/O request.
 | |
|  *
 | |
|  * \since This struct is available since SDL 3.2.0.
 | |
|  */
 | |
| typedef struct SDL_AsyncIOOutcome
 | |
| {
 | |
|     SDL_AsyncIO *asyncio;   /**< what generated this task. This pointer will be invalid if it was closed! */
 | |
|     SDL_AsyncIOTaskType type;  /**< What sort of task was this? Read, write, etc? */
 | |
|     SDL_AsyncIOResult result;  /**< the result of the work (success, failure, cancellation). */
 | |
|     void *buffer;  /**< buffer where data was read/written. */
 | |
|     Uint64 offset;  /**< offset in the SDL_AsyncIO where data was read/written. */
 | |
|     Uint64 bytes_requested;  /**< number of bytes the task was to read/write. */
 | |
|     Uint64 bytes_transferred;  /**< actual number of bytes that were read/written. */
 | |
|     void *userdata;    /**< pointer provided by the app when starting the task */
 | |
| } SDL_AsyncIOOutcome;
 | |
| 
 | |
| /**
 | |
|  * A queue of completed asynchronous I/O tasks.
 | |
|  *
 | |
|  * When starting an asynchronous operation, you specify a queue for the new
 | |
|  * task. A queue can be asked later if any tasks in it have completed,
 | |
|  * allowing an app to manage multiple pending tasks in one place, in whatever
 | |
|  * order they complete.
 | |
|  *
 | |
|  * \since This struct is available since SDL 3.2.0.
 | |
|  *
 | |
|  * \sa SDL_CreateAsyncIOQueue
 | |
|  * \sa SDL_ReadAsyncIO
 | |
|  * \sa SDL_WriteAsyncIO
 | |
|  * \sa SDL_GetAsyncIOResult
 | |
|  * \sa SDL_WaitAsyncIOResult
 | |
|  */
 | |
| typedef struct SDL_AsyncIOQueue SDL_AsyncIOQueue;
 | |
| 
 | |
| /**
 | |
|  * Use this function to create a new SDL_AsyncIO object for reading from
 | |
|  * and/or writing to a named file.
 | |
|  *
 | |
|  * The `mode` string understands the following values:
 | |
|  *
 | |
|  * - "r": Open a file for reading only. It must exist.
 | |
|  * - "w": Open a file for writing only. It will create missing files or
 | |
|  *   truncate existing ones.
 | |
|  * - "r+": Open a file for update both reading and writing. The file must
 | |
|  *   exist.
 | |
|  * - "w+": Create an empty file for both reading and writing. If a file with
 | |
|  *   the same name already exists its content is erased and the file is
 | |
|  *   treated as a new empty file.
 | |
|  *
 | |
|  * There is no "b" mode, as there is only "binary" style I/O, and no "a" mode
 | |
|  * for appending, since you specify the position when starting a task.
 | |
|  *
 | |
|  * This function supports Unicode filenames, but they must be encoded in UTF-8
 | |
|  * format, regardless of the underlying operating system.
 | |
|  *
 | |
|  * This call is _not_ asynchronous; it will open the file before returning,
 | |
|  * under the assumption that doing so is generally a fast operation. Future
 | |
|  * reads and writes to the opened file will be async, however.
 | |
|  *
 | |
|  * \param file a UTF-8 string representing the filename to open.
 | |
|  * \param mode an ASCII string representing the mode to be used for opening
 | |
|  *             the file.
 | |
|  * \returns a pointer to the SDL_AsyncIO structure that is created or NULL on
 | |
|  *          failure; call SDL_GetError() for more information.
 | |
|  *
 | |
|  * \since This function is available since SDL 3.2.0.
 | |
|  *
 | |
|  * \sa SDL_CloseAsyncIO
 | |
|  * \sa SDL_ReadAsyncIO
 | |
|  * \sa SDL_WriteAsyncIO
 | |
|  */
 | |
| extern SDL_DECLSPEC SDL_AsyncIO * SDLCALL SDL_AsyncIOFromFile(const char *file, const char *mode);
 | |
| 
 | |
| /**
 | |
|  * Use this function to get the size of the data stream in an SDL_AsyncIO.
 | |
|  *
 | |
|  * This call is _not_ asynchronous; it assumes that obtaining this info is a
 | |
|  * non-blocking operation in most reasonable cases.
 | |
|  *
 | |
|  * \param asyncio the SDL_AsyncIO to get the size of the data stream from.
 | |
|  * \returns the size of the data stream in the SDL_IOStream on success or a
 | |
|  *          negative error code on failure; call SDL_GetError() for more
 | |
|  *          information.
 | |
|  *
 | |
|  * \threadsafety It is safe to call this function from any thread.
 | |
|  *
 | |
|  * \since This function is available since SDL 3.2.0.
 | |
|  */
 | |
| extern SDL_DECLSPEC Sint64 SDLCALL SDL_GetAsyncIOSize(SDL_AsyncIO *asyncio);
 | |
| 
 | |
| /**
 | |
|  * Start an async read.
 | |
|  *
 | |
|  * This function reads up to `size` bytes from `offset` position in the data
 | |
|  * source to the area pointed at by `ptr`. This function may read less bytes
 | |
|  * than requested.
 | |
|  *
 | |
|  * This function returns as quickly as possible; it does not wait for the read
 | |
|  * to complete. On a successful return, this work will continue in the
 | |
|  * background. If the work begins, even failure is asynchronous: a failing
 | |
|  * return value from this function only means the work couldn't start at all.
 | |
|  *
 | |
|  * `ptr` must remain available until the work is done, and may be accessed by
 | |
|  * the system at any time until then. Do not allocate it on the stack, as this
 | |
|  * might take longer than the life of the calling function to complete!
 | |
|  *
 | |
|  * An SDL_AsyncIOQueue must be specified. The newly-created task will be added
 | |
|  * to it when it completes its work.
 | |
|  *
 | |
|  * \param asyncio a pointer to an SDL_AsyncIO structure.
 | |
|  * \param ptr a pointer to a buffer to read data into.
 | |
|  * \param offset the position to start reading in the data source.
 | |
|  * \param size the number of bytes to read from the data source.
 | |
|  * \param queue a queue to add the new SDL_AsyncIO to.
 | |
|  * \param userdata an app-defined pointer that will be provided with the task
 | |
|  *                 results.
 | |
|  * \returns true on success or false on failure; call SDL_GetError() for more
 | |
|  *          information.
 | |
|  *
 | |
|  * \threadsafety It is safe to call this function from any thread.
 | |
|  *
 | |
|  * \since This function is available since SDL 3.2.0.
 | |
|  *
 | |
|  * \sa SDL_WriteAsyncIO
 | |
|  * \sa SDL_CreateAsyncIOQueue
 | |
|  */
 | |
| extern SDL_DECLSPEC bool SDLCALL SDL_ReadAsyncIO(SDL_AsyncIO *asyncio, void *ptr, Uint64 offset, Uint64 size, SDL_AsyncIOQueue *queue, void *userdata);
 | |
| 
 | |
| /**
 | |
|  * Start an async write.
 | |
|  *
 | |
|  * This function writes `size` bytes from `offset` position in the data source
 | |
|  * to the area pointed at by `ptr`.
 | |
|  *
 | |
|  * This function returns as quickly as possible; it does not wait for the
 | |
|  * write to complete. On a successful return, this work will continue in the
 | |
|  * background. If the work begins, even failure is asynchronous: a failing
 | |
|  * return value from this function only means the work couldn't start at all.
 | |
|  *
 | |
|  * `ptr` must remain available until the work is done, and may be accessed by
 | |
|  * the system at any time until then. Do not allocate it on the stack, as this
 | |
|  * might take longer than the life of the calling function to complete!
 | |
|  *
 | |
|  * An SDL_AsyncIOQueue must be specified. The newly-created task will be added
 | |
|  * to it when it completes its work.
 | |
|  *
 | |
|  * \param asyncio a pointer to an SDL_AsyncIO structure.
 | |
|  * \param ptr a pointer to a buffer to write data from.
 | |
|  * \param offset the position to start writing to the data source.
 | |
|  * \param size the number of bytes to write to the data source.
 | |
|  * \param queue a queue to add the new SDL_AsyncIO to.
 | |
|  * \param userdata an app-defined pointer that will be provided with the task
 | |
|  *                 results.
 | |
|  * \returns true on success or false on failure; call SDL_GetError() for more
 | |
|  *          information.
 | |
|  *
 | |
|  * \threadsafety It is safe to call this function from any thread.
 | |
|  *
 | |
|  * \since This function is available since SDL 3.2.0.
 | |
|  *
 | |
|  * \sa SDL_ReadAsyncIO
 | |
|  * \sa SDL_CreateAsyncIOQueue
 | |
|  */
 | |
| extern SDL_DECLSPEC bool SDLCALL SDL_WriteAsyncIO(SDL_AsyncIO *asyncio, void *ptr, Uint64 offset, Uint64 size, SDL_AsyncIOQueue *queue, void *userdata);
 | |
| 
 | |
| /**
 | |
|  * Close and free any allocated resources for an async I/O object.
 | |
|  *
 | |
|  * Closing a file is _also_ an asynchronous task! If a write failure were to
 | |
|  * happen during the closing process, for example, the task results will
 | |
|  * report it as usual.
 | |
|  *
 | |
|  * Closing a file that has been written to does not guarantee the data has
 | |
|  * made it to physical media; it may remain in the operating system's file
 | |
|  * cache, for later writing to disk. This means that a successfully-closed
 | |
|  * file can be lost if the system crashes or loses power in this small window.
 | |
|  * To prevent this, call this function with the `flush` parameter set to true.
 | |
|  * This will make the operation take longer, and perhaps increase system load
 | |
|  * in general, but a successful result guarantees that the data has made it to
 | |
|  * physical storage. Don't use this for temporary files, caches, and
 | |
|  * unimportant data, and definitely use it for crucial irreplaceable files,
 | |
|  * like game saves.
 | |
|  *
 | |
|  * This function guarantees that the close will happen after any other pending
 | |
|  * tasks to `asyncio`, so it's safe to open a file, start several operations,
 | |
|  * close the file immediately, then check for all results later. This function
 | |
|  * will not block until the tasks have completed.
 | |
|  *
 | |
|  * Once this function returns true, `asyncio` is no longer valid, regardless
 | |
|  * of any future outcomes. Any completed tasks might still contain this
 | |
|  * pointer in their SDL_AsyncIOOutcome data, in case the app was using this
 | |
|  * value to track information, but it should not be used again.
 | |
|  *
 | |
|  * If this function returns false, the close wasn't started at all, and it's
 | |
|  * safe to attempt to close again later.
 | |
|  *
 | |
|  * An SDL_AsyncIOQueue must be specified. The newly-created task will be added
 | |
|  * to it when it completes its work.
 | |
|  *
 | |
|  * \param asyncio a pointer to an SDL_AsyncIO structure to close.
 | |
|  * \param flush true if data should sync to disk before the task completes.
 | |
|  * \param queue a queue to add the new SDL_AsyncIO to.
 | |
|  * \param userdata an app-defined pointer that will be provided with the task
 | |
|  *                 results.
 | |
|  * \returns true on success or false on failure; call SDL_GetError() for more
 | |
|  *          information.
 | |
|  *
 | |
|  * \threadsafety It is safe to call this function from any thread, but two
 | |
|  *               threads should not attempt to close the same object.
 | |
|  *
 | |
|  * \since This function is available since SDL 3.2.0.
 | |
|  */
 | |
| extern SDL_DECLSPEC bool SDLCALL SDL_CloseAsyncIO(SDL_AsyncIO *asyncio, bool flush, SDL_AsyncIOQueue *queue, void *userdata);
 | |
| 
 | |
| /**
 | |
|  * Create a task queue for tracking multiple I/O operations.
 | |
|  *
 | |
|  * Async I/O operations are assigned to a queue when started. The queue can be
 | |
|  * checked for completed tasks thereafter.
 | |
|  *
 | |
|  * \returns a new task queue object or NULL if there was an error; call
 | |
|  *          SDL_GetError() for more information.
 | |
|  *
 | |
|  * \threadsafety It is safe to call this function from any thread.
 | |
|  *
 | |
|  * \since This function is available since SDL 3.2.0.
 | |
|  *
 | |
|  * \sa SDL_DestroyAsyncIOQueue
 | |
|  * \sa SDL_GetAsyncIOResult
 | |
|  * \sa SDL_WaitAsyncIOResult
 | |
|  */
 | |
| extern SDL_DECLSPEC SDL_AsyncIOQueue * SDLCALL SDL_CreateAsyncIOQueue(void);
 | |
| 
 | |
| /**
 | |
|  * Destroy a previously-created async I/O task queue.
 | |
|  *
 | |
|  * If there are still tasks pending for this queue, this call will block until
 | |
|  * those tasks are finished. All those tasks will be deallocated. Their
 | |
|  * results will be lost to the app.
 | |
|  *
 | |
|  * Any pending reads from SDL_LoadFileAsync() that are still in this queue
 | |
|  * will have their buffers deallocated by this function, to prevent a memory
 | |
|  * leak.
 | |
|  *
 | |
|  * Once this function is called, the queue is no longer valid and should not
 | |
|  * be used, including by other threads that might access it while destruction
 | |
|  * is blocking on pending tasks.
 | |
|  *
 | |
|  * Do not destroy a queue that still has threads waiting on it through
 | |
|  * SDL_WaitAsyncIOResult(). You can call SDL_SignalAsyncIOQueue() first to
 | |
|  * unblock those threads, and take measures (such as SDL_WaitThread()) to make
 | |
|  * sure they have finished their wait and won't wait on the queue again.
 | |
|  *
 | |
|  * \param queue the task queue to destroy.
 | |
|  *
 | |
|  * \threadsafety It is safe to call this function from any thread, so long as
 | |
|  *               no other thread is waiting on the queue with
 | |
|  *               SDL_WaitAsyncIOResult.
 | |
|  *
 | |
|  * \since This function is available since SDL 3.2.0.
 | |
|  */
 | |
| extern SDL_DECLSPEC void SDLCALL SDL_DestroyAsyncIOQueue(SDL_AsyncIOQueue *queue);
 | |
| 
 | |
| /**
 | |
|  * Query an async I/O task queue for completed tasks.
 | |
|  *
 | |
|  * If a task assigned to this queue has finished, this will return true and
 | |
|  * fill in `outcome` with the details of the task. If no task in the queue has
 | |
|  * finished, this function will return false. This function does not block.
 | |
|  *
 | |
|  * If a task has completed, this function will free its resources and the task
 | |
|  * pointer will no longer be valid. The task will be removed from the queue.
 | |
|  *
 | |
|  * It is safe for multiple threads to call this function on the same queue at
 | |
|  * once; a completed task will only go to one of the threads.
 | |
|  *
 | |
|  * \param queue the async I/O task queue to query.
 | |
|  * \param outcome details of a finished task will be written here. May not be
 | |
|  *                NULL.
 | |
|  * \returns true if a task has completed, false otherwise.
 | |
|  *
 | |
|  * \threadsafety It is safe to call this function from any thread.
 | |
|  *
 | |
|  * \since This function is available since SDL 3.2.0.
 | |
|  *
 | |
|  * \sa SDL_WaitAsyncIOResult
 | |
|  */
 | |
| extern SDL_DECLSPEC bool SDLCALL SDL_GetAsyncIOResult(SDL_AsyncIOQueue *queue, SDL_AsyncIOOutcome *outcome);
 | |
| 
 | |
| /**
 | |
|  * Block until an async I/O task queue has a completed task.
 | |
|  *
 | |
|  * This function puts the calling thread to sleep until there a task assigned
 | |
|  * to the queue that has finished.
 | |
|  *
 | |
|  * If a task assigned to the queue has finished, this will return true and
 | |
|  * fill in `outcome` with the details of the task. If no task in the queue has
 | |
|  * finished, this function will return false.
 | |
|  *
 | |
|  * If a task has completed, this function will free its resources and the task
 | |
|  * pointer will no longer be valid. The task will be removed from the queue.
 | |
|  *
 | |
|  * It is safe for multiple threads to call this function on the same queue at
 | |
|  * once; a completed task will only go to one of the threads.
 | |
|  *
 | |
|  * Note that by the nature of various platforms, more than one waiting thread
 | |
|  * may wake to handle a single task, but only one will obtain it, so
 | |
|  * `timeoutMS` is a _maximum_ wait time, and this function may return false
 | |
|  * sooner.
 | |
|  *
 | |
|  * This function may return false if there was a system error, the OS
 | |
|  * inadvertently awoke multiple threads, or if SDL_SignalAsyncIOQueue() was
 | |
|  * called to wake up all waiting threads without a finished task.
 | |
|  *
 | |
|  * A timeout can be used to specify a maximum wait time, but rather than
 | |
|  * polling, it is possible to have a timeout of -1 to wait forever, and use
 | |
|  * SDL_SignalAsyncIOQueue() to wake up the waiting threads later.
 | |
|  *
 | |
|  * \param queue the async I/O task queue to wait on.
 | |
|  * \param outcome details of a finished task will be written here. May not be
 | |
|  *                NULL.
 | |
|  * \param timeoutMS the maximum time to wait, in milliseconds, or -1 to wait
 | |
|  *                  indefinitely.
 | |
|  * \returns true if task has completed, false otherwise.
 | |
|  *
 | |
|  * \threadsafety It is safe to call this function from any thread.
 | |
|  *
 | |
|  * \since This function is available since SDL 3.2.0.
 | |
|  *
 | |
|  * \sa SDL_SignalAsyncIOQueue
 | |
|  */
 | |
| extern SDL_DECLSPEC bool SDLCALL SDL_WaitAsyncIOResult(SDL_AsyncIOQueue *queue, SDL_AsyncIOOutcome *outcome, Sint32 timeoutMS);
 | |
| 
 | |
| /**
 | |
|  * Wake up any threads that are blocking in SDL_WaitAsyncIOResult().
 | |
|  *
 | |
|  * This will unblock any threads that are sleeping in a call to
 | |
|  * SDL_WaitAsyncIOResult for the specified queue, and cause them to return
 | |
|  * from that function.
 | |
|  *
 | |
|  * This can be useful when destroying a queue to make sure nothing is touching
 | |
|  * it indefinitely. In this case, once this call completes, the caller should
 | |
|  * take measures to make sure any previously-blocked threads have returned
 | |
|  * from their wait and will not touch the queue again (perhaps by setting a
 | |
|  * flag to tell the threads to terminate and then using SDL_WaitThread() to
 | |
|  * make sure they've done so).
 | |
|  *
 | |
|  * \param queue the async I/O task queue to signal.
 | |
|  *
 | |
|  * \threadsafety It is safe to call this function from any thread.
 | |
|  *
 | |
|  * \since This function is available since SDL 3.2.0.
 | |
|  *
 | |
|  * \sa SDL_WaitAsyncIOResult
 | |
|  */
 | |
| extern SDL_DECLSPEC void SDLCALL SDL_SignalAsyncIOQueue(SDL_AsyncIOQueue *queue);
 | |
| 
 | |
| /**
 | |
|  * Load all the data from a file path, asynchronously.
 | |
|  *
 | |
|  * This function returns as quickly as possible; it does not wait for the read
 | |
|  * to complete. On a successful return, this work will continue in the
 | |
|  * background. If the work begins, even failure is asynchronous: a failing
 | |
|  * return value from this function only means the work couldn't start at all.
 | |
|  *
 | |
|  * The data is allocated with a zero byte at the end (null terminated) for
 | |
|  * convenience. This extra byte is not included in SDL_AsyncIOOutcome's
 | |
|  * bytes_transferred value.
 | |
|  *
 | |
|  * This function will allocate the buffer to contain the file. It must be
 | |
|  * deallocated by calling SDL_free() on SDL_AsyncIOOutcome's buffer field
 | |
|  * after completion.
 | |
|  *
 | |
|  * An SDL_AsyncIOQueue must be specified. The newly-created task will be added
 | |
|  * to it when it completes its work.
 | |
|  *
 | |
|  * \param file the path to read all available data from.
 | |
|  * \param queue a queue to add the new SDL_AsyncIO to.
 | |
|  * \param userdata an app-defined pointer that will be provided with the task
 | |
|  *                 results.
 | |
|  * \returns true on success or false on failure; call SDL_GetError() for more
 | |
|  *          information.
 | |
|  *
 | |
|  * \since This function is available since SDL 3.2.0.
 | |
|  *
 | |
|  * \sa SDL_LoadFile_IO
 | |
|  */
 | |
| extern SDL_DECLSPEC bool SDLCALL SDL_LoadFileAsync(const char *file, SDL_AsyncIOQueue *queue, void *userdata);
 | |
| 
 | |
| /* Ends C function definitions when using C++ */
 | |
| #ifdef __cplusplus
 | |
| }
 | |
| #endif
 | |
| #include <SDL3/SDL_close_code.h>
 | |
| 
 | |
| #endif /* SDL_asyncio_h_ */
 | 
