|
@@ -30,6 +30,7 @@
|
|
|
|
|
|
#include <SDL3/SDL_stdinc.h>
|
|
|
#include <SDL3/SDL_error.h>
|
|
|
+#include <SDL3/SDL_thread.h>
|
|
|
|
|
|
/******************************************************************************/
|
|
|
/* Enable thread safety attributes only with clang.
|
|
@@ -757,6 +758,140 @@ extern SDL_DECLSPEC bool SDLCALL SDL_WaitConditionTimeout(SDL_Condition *cond,
|
|
|
|
|
|
/* @} *//* Condition variable functions */
|
|
|
|
|
|
+/**
|
|
|
+ * \name Thread-safe initialization state functions
|
|
|
+ */
|
|
|
+/* @{ */
|
|
|
+
|
|
|
+/**
|
|
|
+ * The current status of an SDL_InitState structure.
|
|
|
+ *
|
|
|
+ * \since This enum is available since SDL 3.0.0.
|
|
|
+ */
|
|
|
+typedef enum SDL_InitStatus
|
|
|
+{
|
|
|
+ SDL_INIT_STATUS_UNINITIALIZED,
|
|
|
+ SDL_INIT_STATUS_INITIALIZING,
|
|
|
+ SDL_INIT_STATUS_INITIALIZED,
|
|
|
+ SDL_INIT_STATUS_UNINITIALIZING
|
|
|
+} SDL_InitStatus;
|
|
|
+
|
|
|
+/**
|
|
|
+ * A structure used for thread-safe initialization and shutdown.
|
|
|
+ *
|
|
|
+ * Here is an example of using this:
|
|
|
+ *
|
|
|
+ * ```c
|
|
|
+ * static SDL_AtomicInitState init;
|
|
|
+ *
|
|
|
+ * bool InitSystem(void)
|
|
|
+ * {
|
|
|
+ * if (!SDL_ShouldInit(&init)) {
|
|
|
+ * // The system is initialized
|
|
|
+ * return true;
|
|
|
+ * }
|
|
|
+ *
|
|
|
+ * // At this point, you should not leave this function without calling SDL_SetInitialized()
|
|
|
+ *
|
|
|
+ * bool initialized = DoInitTasks();
|
|
|
+ * SDL_SetInitialized(&init, initialized);
|
|
|
+ * return initialized;
|
|
|
+ * }
|
|
|
+ *
|
|
|
+ * bool UseSubsystem(void)
|
|
|
+ * {
|
|
|
+ * if (SDL_ShouldInit(&init)) {
|
|
|
+ * // Error, the subsystem isn't initialized
|
|
|
+ * SDL_SetInitialized(&init, false);
|
|
|
+ * return false;
|
|
|
+ * }
|
|
|
+ *
|
|
|
+ * // Do work using the initialized subsystem
|
|
|
+ *
|
|
|
+ * return true;
|
|
|
+ * }
|
|
|
+ *
|
|
|
+ * void QuitSystem(void)
|
|
|
+ * {
|
|
|
+ * if (!SDL_ShouldQuit(&init)) {
|
|
|
+ * // The system is not initialized
|
|
|
+ * return true;
|
|
|
+ * }
|
|
|
+ *
|
|
|
+ * // At this point, you should not leave this function without calling SDL_SetInitialized()
|
|
|
+ *
|
|
|
+ * DoQuitTasks();
|
|
|
+ * SDL_SetInitialized(&init, false);
|
|
|
+ * }
|
|
|
+ * ```
|
|
|
+ *
|
|
|
+ * Note that this doesn't protect any resources created during initialization, or guarantee that nobody is using those resources during cleanup. You should use other mechanisms to protect those, if that's a concern for your code.
|
|
|
+ *
|
|
|
+ * \since This struct is available since SDL 3.0.0.
|
|
|
+ */
|
|
|
+typedef struct SDL_InitState
|
|
|
+{
|
|
|
+ SDL_AtomicInt status;
|
|
|
+ SDL_ThreadID thread;
|
|
|
+ void *reserved;
|
|
|
+} SDL_InitState;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Return whether initialization should be done.
|
|
|
+ *
|
|
|
+ * This function checks the passed in state and if initialization should be done, sets the status to `SDL_INIT_STATUS_INITIALIZING` and returns true. If another thread is already modifying this state, it will wait until that's done before returning.
|
|
|
+ *
|
|
|
+ * If this function returns true, the calling code must call SDL_SetInitialized() to complete the initialization.
|
|
|
+ *
|
|
|
+ * \param state the initialization state to check.
|
|
|
+ * \returns true if initialization needs to be done, false otherwise.
|
|
|
+ *
|
|
|
+ * \threadsafety It is safe to call this function from any thread.
|
|
|
+ *
|
|
|
+ * \since This function is available since SDL 3.0.0.
|
|
|
+ *
|
|
|
+ * \sa SDL_SetInitialized
|
|
|
+ * \sa SDL_ShouldQuit
|
|
|
+ */
|
|
|
+extern SDL_DECLSPEC bool SDLCALL SDL_ShouldInit(SDL_InitState *state);
|
|
|
+
|
|
|
+/**
|
|
|
+ * Return whether cleanup should be done.
|
|
|
+ *
|
|
|
+ * This function checks the passed in state and if cleanup should be done, sets the status to `SDL_INIT_STATUS_UNINITIALIZING` and returns true.
|
|
|
+ *
|
|
|
+ * If this function returns true, the calling code must call SDL_SetInitialized() to complete the cleanup.
|
|
|
+ *
|
|
|
+ * \param state the initialization state to check.
|
|
|
+ * \returns true if cleanup needs to be done, false otherwise.
|
|
|
+ *
|
|
|
+ * \threadsafety It is safe to call this function from any thread.
|
|
|
+ *
|
|
|
+ * \since This function is available since SDL 3.0.0.
|
|
|
+ *
|
|
|
+ * \sa SDL_SetInitialized
|
|
|
+ * \sa SDL_ShouldInit
|
|
|
+ */
|
|
|
+extern SDL_DECLSPEC bool SDLCALL SDL_ShouldQuit(SDL_InitState *state);
|
|
|
+
|
|
|
+/**
|
|
|
+ * Finish an initialization state transition.
|
|
|
+ *
|
|
|
+ * This function sets the status of the passed in state to `SDL_INIT_STATUS_INITIALIZED` or `SDL_INIT_STATUS_UNINITIALIZED` and allows any threads waiting for the status to proceed.
|
|
|
+ *
|
|
|
+ * \param state the initialization state to check.
|
|
|
+ * \param initialized the new initialization state.
|
|
|
+ *
|
|
|
+ * \threadsafety It is safe to call this function from any thread.
|
|
|
+ *
|
|
|
+ * \since This function is available since SDL 3.0.0.
|
|
|
+ *
|
|
|
+ * \sa SDL_ShouldInit
|
|
|
+ * \sa SDL_ShouldQuit
|
|
|
+ */
|
|
|
+extern SDL_DECLSPEC void SDLCALL SDL_SetInitialized(SDL_InitState *state, bool initialized);
|
|
|
+
|
|
|
+/* @} *//* Thread-safe initialization state functions */
|
|
|
|
|
|
/* Ends C function definitions when using C++ */
|
|
|
#ifdef __cplusplus
|