SDL3pp
A slim C++ wrapper for SDL3
Loading...
Searching...
No Matches

SDL offers a way to perform I/O asynchronously. More...

Classes

struct  SDL::AsyncIO
 The asynchronous I/O operation structure. More...
struct  SDL::AsyncIOQueue
 A queue of completed asynchronous I/O tasks. More...

Typedefs

using SDL::AsyncIORaw = SDL_AsyncIO*
 Alias to raw representation for AsyncIO.
using SDL::AsyncIORef = ResourceRef<AsyncIO>
 Reference for AsyncIO.
using SDL::AsyncIOQueueRaw = SDL_AsyncIOQueue*
 Alias to raw representation for AsyncIOQueue.
using SDL::AsyncIOQueueRef = ResourceRef<AsyncIOQueue>
 Reference for AsyncIOQueue.
using SDL::AsyncIOTaskType = SDL_AsyncIOTaskType
 Types of asynchronous I/O tasks.
using SDL::AsyncIOResult = SDL_AsyncIOResult
 Possible outcomes of an asynchronous I/O task.
using SDL::AsyncIOOutcome = SDL_AsyncIOOutcome
 Information about a completed asynchronous I/O request.

Functions

AsyncIO SDL::AsyncIOFromFile (StringParam file, StringParam mode)
 Use this function to create a new AsyncIO object for reading from and/or writing to a named file.
Sint64 SDL::GetAsyncIOSize (AsyncIORef asyncio)
 Use this function to get the size of the data stream in an AsyncIO.
void SDL::ReadAsyncIO (AsyncIORef asyncio, void *ptr, Uint64 offset, Uint64 size, AsyncIOQueueRef queue, void *userdata)
 Start an async read.
void SDL::WriteAsyncIO (AsyncIORef asyncio, void *ptr, Uint64 offset, Uint64 size, AsyncIOQueueRef queue, void *userdata)
 Start an async write.
bool SDL::CloseAsyncIO (AsyncIORaw asyncio, bool flush, AsyncIOQueueRef queue, void *userdata)
 Close and free any allocated resources for an async I/O object.
AsyncIOQueue SDL::CreateAsyncIOQueue ()
 Create a task queue for tracking multiple I/O operations.
void SDL::DestroyAsyncIOQueue (AsyncIOQueueRaw queue)
 Destroy a previously-created async I/O task queue.
std::optional< AsyncIOOutcomeSDL::GetAsyncIOResult (AsyncIOQueueRef queue)
 Query an async I/O task queue for completed tasks.
std::optional< AsyncIOOutcomeSDL::WaitAsyncIOResult (AsyncIOQueueRef queue, Milliseconds timeout)
 Block until an async I/O task queue has a completed task.
std::optional< AsyncIOOutcomeSDL::WaitAsyncIOResult (AsyncIOQueueRef queue)
 Block until an async I/O task queue has a completed task.
void SDL::SignalAsyncIOQueue (AsyncIOQueueRef queue)
 Wake up any threads that are blocking in AsyncIOQueue.WaitResult().
void SDL::LoadFileAsync (StringParam file, AsyncIOQueueRef queue, void *userdata)
 Load all the data from a file path, asynchronously.
 SDL::AsyncIO::AsyncIO (StringParam file, StringParam mode)
 Use this function to create a new AsyncIO object for reading from and/or writing to a named file.
Sint64 SDL::AsyncIO::GetSize ()
 Use this function to get the size of the data stream in an AsyncIO.
void SDL::AsyncIO::Read (void *ptr, Uint64 offset, Uint64 size, AsyncIOQueueRef queue, void *userdata)
 Start an async read.
void SDL::AsyncIO::Write (void *ptr, Uint64 offset, Uint64 size, AsyncIOQueueRef queue, void *userdata)
 Start an async write.
bool SDL::AsyncIO::Close (bool flush, AsyncIOQueueRef queue, void *userdata)
 Close and free any allocated resources for an async I/O object.
 SDL::AsyncIOQueue::AsyncIOQueue ()
 Create a task queue for tracking multiple I/O operations.
void SDL::AsyncIOQueue::Destroy ()
 Destroy a previously-created async I/O task queue.
std::optional< AsyncIOOutcomeSDL::AsyncIOQueue::GetResult ()
 Query an async I/O task queue for completed tasks.
std::optional< AsyncIOOutcomeSDL::AsyncIOQueue::WaitResult (Milliseconds timeout)
 Block until an async I/O task queue has a completed task.
std::optional< AsyncIOOutcomeSDL::AsyncIOQueue::WaitResult ()
 Block until an async I/O task queue has a completed task.
void SDL::AsyncIOQueue::Signal ()
 Wake up any threads that are blocking in AsyncIOQueue.WaitResult().

Variables

constexpr AsyncIOTaskType SDL::ASYNCIO_TASK_READ
 A read operation.
constexpr AsyncIOTaskType SDL::ASYNCIO_TASK_WRITE
 A write operation.
constexpr AsyncIOTaskType SDL::ASYNCIO_TASK_CLOSE
 A close operation.
constexpr AsyncIOResult SDL::ASYNCIO_COMPLETE
 request was completed without error
constexpr AsyncIOResult SDL::ASYNCIO_FAILURE
 request failed for some reason; check GetError()!
constexpr AsyncIOResult SDL::ASYNCIO_CANCELED
 request was canceled before completing.

Detailed Description

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 AsyncIOQueue objects.
  • Open files with AsyncIOFromFile.
  • Start I/O tasks to the files with AsyncIO.Read or AsyncIO.Write, putting those tasks into one of the queues.
  • Later on, use AsyncIOQueue.GetResult 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 AsyncIO.Close. 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 AsyncIOQueue.WaitResult from one or more threads to efficiently block until new tasks complete.
  • When shutting down, call AsyncIOQueue.Signal to unblock any sleeping threads despite there being no new tasks completed.

And, of course, to match the synchronous LoadFile, we offer 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 AsyncIO.Read, or maybe LoadFileAsync, as needed. Once a frame, call AsyncIOQueue.GetResult 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 AsyncIO.Close 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.

Typedef Documentation

◆ AsyncIOOutcome

using SDL::AsyncIOOutcome = SDL_AsyncIOOutcome

Information about a completed asynchronous I/O request.

Since
This struct is available since SDL 3.2.0.

◆ AsyncIOQueueRef

Reference for AsyncIOQueue.

This does not take ownership!

◆ AsyncIORef

Reference for AsyncIO.

This does not take ownership!

◆ AsyncIOResult

using SDL::AsyncIOResult = SDL_AsyncIOResult

Possible outcomes of an asynchronous I/O task.

Since
This enum is available since SDL 3.2.0.

◆ AsyncIOTaskType

using SDL::AsyncIOTaskType = SDL_AsyncIOTaskType

Types of asynchronous I/O tasks.

Since
This enum is available since SDL 3.2.0.

Function Documentation

◆ AsyncIO()

SDL::AsyncIO::AsyncIO ( StringParam file,
StringParam mode )
inline

Use this function to create a new 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.

Parameters
filea UTF-8 string representing the filename to open.
modean ASCII string representing the mode to be used for opening the file.
Postcondition
a pointer to the AsyncIO structure that is created or nullptr on failure; call GetError() for more information.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL 3.2.0.
See also
AsyncIO.Close
AsyncIO.Read
AsyncIO.Write

◆ AsyncIOFromFile()

AsyncIO SDL::AsyncIOFromFile ( StringParam file,
StringParam mode )
inline

Use this function to create a new 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.

Parameters
filea UTF-8 string representing the filename to open.
modean ASCII string representing the mode to be used for opening the file.
Returns
a pointer to the AsyncIO structure that is created or nullptr on failure; call GetError() for more information.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL 3.2.0.
See also
AsyncIO.Close
AsyncIO.Read
AsyncIO.Write

◆ AsyncIOQueue()

SDL::AsyncIOQueue::AsyncIOQueue ( )
inline

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.

Postcondition
a new task queue object or nullptr if there was an error; call GetError() for more information.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL 3.2.0.
See also
AsyncIOQueue.Destroy
AsyncIOQueue.GetResult
AsyncIOQueue.WaitResult

◆ Close()

bool SDL::AsyncIO::Close ( bool flush,
AsyncIOQueueRef queue,
void * userdata )
inline

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 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 AsyncIOQueue must be specified. The newly-created task will be added to it when it completes its work.

Parameters
flushtrue if data should sync to disk before the task completes.
queuea queue to add the new AsyncIO to.
userdataan app-defined pointer that will be provided with the task results.
Returns
true on success or false on failure; call GetError() for more information.
Thread safety:
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.

◆ CloseAsyncIO()

bool SDL::CloseAsyncIO ( AsyncIORaw asyncio,
bool flush,
AsyncIOQueueRef queue,
void * userdata )
inline

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 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 AsyncIOQueue must be specified. The newly-created task will be added to it when it completes its work.

Parameters
asyncioa pointer to an AsyncIO structure to close.
flushtrue if data should sync to disk before the task completes.
queuea queue to add the new AsyncIO to.
userdataan app-defined pointer that will be provided with the task results.
Returns
true on success or false on failure; call GetError() for more information.
Thread safety:
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.

◆ CreateAsyncIOQueue()

AsyncIOQueue SDL::CreateAsyncIOQueue ( )
inline

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 nullptr if there was an error; call GetError() for more information.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL 3.2.0.
See also
AsyncIOQueue.Destroy
AsyncIOQueue.GetResult
AsyncIOQueue.WaitResult

◆ Destroy()

void SDL::AsyncIOQueue::Destroy ( )
inline

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 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 AsyncIOQueue.WaitResult(). You can call AsyncIOQueue.Signal() first to unblock those threads, and take measures (such as Thread.Wait()) to make sure they have finished their wait and won't wait on the queue again.

Thread safety:
It is safe to call this function from any thread, so long as no other thread is waiting on the queue with AsyncIOQueue.WaitResult.
Since
This function is available since SDL 3.2.0.

◆ DestroyAsyncIOQueue()

void SDL::DestroyAsyncIOQueue ( AsyncIOQueueRaw queue)
inline

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 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 AsyncIOQueue.WaitResult(). You can call AsyncIOQueue.Signal() first to unblock those threads, and take measures (such as Thread.Wait()) to make sure they have finished their wait and won't wait on the queue again.

Parameters
queuethe task queue to destroy.
Thread safety:
It is safe to call this function from any thread, so long as no other thread is waiting on the queue with AsyncIOQueue.WaitResult.
Since
This function is available since SDL 3.2.0.

◆ GetAsyncIOResult()

std::optional< AsyncIOOutcome > SDL::GetAsyncIOResult ( AsyncIOQueueRef queue)
inline

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.

Parameters
queuethe async I/O task queue to query.
Returns
details of a finished task if a task has completed, std::nullopt otherwise.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL 3.2.0.
See also
AsyncIOQueue.WaitResult

◆ GetAsyncIOSize()

Sint64 SDL::GetAsyncIOSize ( AsyncIORef asyncio)
inline

Use this function to get the size of the data stream in an AsyncIO.

This call is not asynchronous; it assumes that obtaining this info is a non-blocking operation in most reasonable cases.

Parameters
asynciothe AsyncIO to get the size of the data stream from.
Returns
the size of the data stream in the IOStream on success.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL 3.2.0.

◆ GetResult()

std::optional< AsyncIOOutcome > SDL::AsyncIOQueue::GetResult ( )
inline

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.

Returns
details of a finished task if a task has completed, std::nullopt otherwise.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL 3.2.0.
See also
AsyncIOQueue.WaitResult

◆ GetSize()

Sint64 SDL::AsyncIO::GetSize ( )
inline

Use this function to get the size of the data stream in an AsyncIO.

This call is not asynchronous; it assumes that obtaining this info is a non-blocking operation in most reasonable cases.

Returns
the size of the data stream in the IOStream on success.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL 3.2.0.

◆ LoadFileAsync()

void SDL::LoadFileAsync ( StringParam file,
AsyncIOQueueRef queue,
void * userdata )
inline

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 AsyncIOOutcome's bytes_transferred value.

This function will allocate the buffer to contain the file. It must be deallocated by calling free() on AsyncIOOutcome's buffer field after completion.

An AsyncIOQueue must be specified. The newly-created task will be added to it when it completes its work.

Parameters
filethe path to read all available data from.
queuea queue to add the new AsyncIO to.
userdataan app-defined pointer that will be provided with the task results.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL 3.2.0.
See also
IOStream.LoadFile

◆ Read()

void SDL::AsyncIO::Read ( void * ptr,
Uint64 offset,
Uint64 size,
AsyncIOQueueRef queue,
void * userdata )
inline

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 AsyncIOQueue must be specified. The newly-created task will be added to it when it completes its work.

Parameters
ptra pointer to a buffer to read data into.
offsetthe position to start reading in the data source.
sizethe number of bytes to read from the data source.
queuea queue to add the new AsyncIO to.
userdataan app-defined pointer that will be provided with the task results.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL 3.2.0.
See also
AsyncIO.Write
CreateAsyncIOQueue

◆ ReadAsyncIO()

void SDL::ReadAsyncIO ( AsyncIORef asyncio,
void * ptr,
Uint64 offset,
Uint64 size,
AsyncIOQueueRef queue,
void * userdata )
inline

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 AsyncIOQueue must be specified. The newly-created task will be added to it when it completes its work.

Parameters
asyncioa pointer to an AsyncIO structure.
ptra pointer to a buffer to read data into.
offsetthe position to start reading in the data source.
sizethe number of bytes to read from the data source.
queuea queue to add the new AsyncIO to.
userdataan app-defined pointer that will be provided with the task results.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL 3.2.0.
See also
AsyncIO.Write
CreateAsyncIOQueue

◆ Signal()

void SDL::AsyncIOQueue::Signal ( )
inline

Wake up any threads that are blocking in AsyncIOQueue.WaitResult().

This will unblock any threads that are sleeping in a call to AsyncIOQueue.WaitResult 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 Thread.Wait() to make sure they've done so).

Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL 3.2.0.
See also
AsyncIOQueue.WaitResult

◆ SignalAsyncIOQueue()

void SDL::SignalAsyncIOQueue ( AsyncIOQueueRef queue)
inline

Wake up any threads that are blocking in AsyncIOQueue.WaitResult().

This will unblock any threads that are sleeping in a call to AsyncIOQueue.WaitResult 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 Thread.Wait() to make sure they've done so).

Parameters
queuethe async I/O task queue to signal.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL 3.2.0.
See also
AsyncIOQueue.WaitResult

◆ WaitAsyncIOResult() [1/2]

std::optional< AsyncIOOutcome > SDL::WaitAsyncIOResult ( AsyncIOQueueRef queue)
inline

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 AsyncIOQueue.Signal() 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 AsyncIOQueue.Signal() to wake up the waiting threads later.

Parameters
queuethe async I/O task queue to wait on.
Returns
details of a finished task if a task has completed, std::nullopt otherwise.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL 3.2.0.
See also
AsyncIOQueue.Signal

◆ WaitAsyncIOResult() [2/2]

std::optional< AsyncIOOutcome > SDL::WaitAsyncIOResult ( AsyncIOQueueRef queue,
Milliseconds timeout )
inline

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 AsyncIOQueue.Signal() 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 AsyncIOQueue.Signal() to wake up the waiting threads later.

Parameters
queuethe async I/O task queue to wait on.
timeoutthe maximum time to wait, in milliseconds.
Returns
details of a finished task if a task has completed, std::nullopt otherwise.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL 3.2.0.
See also
AsyncIOQueue.Signal

◆ WaitResult() [1/2]

std::optional< AsyncIOOutcome > SDL::AsyncIOQueue::WaitResult ( )
inline

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 AsyncIOQueue.Signal() 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 AsyncIOQueue.Signal() to wake up the waiting threads later.

Returns
details of a finished task if a task has completed, std::nullopt otherwise.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL 3.2.0.
See also
AsyncIOQueue.Signal

◆ WaitResult() [2/2]

std::optional< AsyncIOOutcome > SDL::AsyncIOQueue::WaitResult ( Milliseconds timeout)
inline

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 AsyncIOQueue.Signal() 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 AsyncIOQueue.Signal() to wake up the waiting threads later.

Parameters
timeoutthe maximum time to wait, in milliseconds.
Returns
details of a finished task if a task has completed, std::nullopt otherwise.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL 3.2.0.
See also
AsyncIOQueue.Signal

◆ Write()

void SDL::AsyncIO::Write ( void * ptr,
Uint64 offset,
Uint64 size,
AsyncIOQueueRef queue,
void * userdata )
inline

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 AsyncIOQueue must be specified. The newly-created task will be added to it when it completes its work.

Parameters
ptra pointer to a buffer to write data from.
offsetthe position to start writing to the data source.
sizethe number of bytes to write to the data source.
queuea queue to add the new AsyncIO to.
userdataan app-defined pointer that will be provided with the task results.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL 3.2.0.
See also
AsyncIO.Read
CreateAsyncIOQueue

◆ WriteAsyncIO()

void SDL::WriteAsyncIO ( AsyncIORef asyncio,
void * ptr,
Uint64 offset,
Uint64 size,
AsyncIOQueueRef queue,
void * userdata )
inline

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 AsyncIOQueue must be specified. The newly-created task will be added to it when it completes its work.

Parameters
asyncioa pointer to an AsyncIO structure.
ptra pointer to a buffer to write data from.
offsetthe position to start writing to the data source.
sizethe number of bytes to write to the data source.
queuea queue to add the new AsyncIO to.
userdataan app-defined pointer that will be provided with the task results.
Exceptions
Erroron failure.
Thread safety:
It is safe to call this function from any thread.
Since
This function is available since SDL 3.2.0.
See also
AsyncIO.Read
CreateAsyncIOQueue

Variable Documentation

◆ ASYNCIO_CANCELED

AsyncIOResult SDL::ASYNCIO_CANCELED
constexpr
Initial value:
=
SDL_ASYNCIO_CANCELED

request was canceled before completing.

◆ ASYNCIO_COMPLETE

AsyncIOResult SDL::ASYNCIO_COMPLETE
constexpr
Initial value:
=
SDL_ASYNCIO_COMPLETE

request was completed without error

◆ ASYNCIO_FAILURE

AsyncIOResult SDL::ASYNCIO_FAILURE
constexpr
Initial value:
=
SDL_ASYNCIO_FAILURE

request failed for some reason; check GetError()!

◆ ASYNCIO_TASK_CLOSE

AsyncIOTaskType SDL::ASYNCIO_TASK_CLOSE
constexpr
Initial value:
=
SDL_ASYNCIO_TASK_CLOSE

A close operation.

◆ ASYNCIO_TASK_READ

AsyncIOTaskType SDL::ASYNCIO_TASK_READ
constexpr
Initial value:
=
SDL_ASYNCIO_TASK_READ

A read operation.

◆ ASYNCIO_TASK_WRITE

AsyncIOTaskType SDL::ASYNCIO_TASK_WRITE
constexpr
Initial value:
=
SDL_ASYNCIO_TASK_WRITE

A write operation.