3232#include < utility>
3333#include < vector>
3434
35- // Global lock to prevent reading JSON manifest files at the same time.
36- std::mutex &GetLoaderJsonMutex () {
37- static std::mutex loader_json_mutex;
38- return loader_json_mutex;
39- }
40-
41- // Global lock to prevent simultaneous instance creation/destruction
42- std::mutex &GetInstanceCreateDestroyMutex () {
43- static std::mutex instance_create_destroy_mutex;
44- return instance_create_destroy_mutex;
35+ // Global loader lock to:
36+ // 1. Ensure ActiveLoaderInstance get and set operations are done atomically.
37+ // 2. Ensure RuntimeInterface isn't used to unload the runtime while the runtime is in use.
38+ std::mutex &GetGlobalLoaderMutex () {
39+ static std::mutex loader_mutex;
40+ return loader_mutex;
4541}
4642
4743// Prototypes for the debug utils calls used internally.
@@ -90,7 +86,7 @@ static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrEnumerateApiLayerProperties(uint32
9086 LoaderLogger::LogVerboseMessage (" xrEnumerateApiLayerProperties" , " Entering loader trampoline" );
9187
9288 // Make sure only one thread is attempting to read the JSON files at a time.
93- std::unique_lock<std::mutex> json_lock ( GetLoaderJsonMutex ());
89+ std::unique_lock<std::mutex> loader_lock ( GetGlobalLoaderMutex ());
9490
9591 XrResult result = ApiLayerInterface::GetApiLayerProperties (" xrEnumerateApiLayerProperties" , propertyCapacityInput,
9692 propertyCountOutput, properties);
@@ -123,8 +119,8 @@ LoaderXrEnumerateInstanceExtensionProperties(const char *layerName, uint32_t pro
123119 XrResult result;
124120
125121 {
126- // Make sure only one thread is attempting to read the JSON files at a time .
127- std::unique_lock<std::mutex> json_lock ( GetLoaderJsonMutex ());
122+ // Make sure the runtime isn't unloaded while this call is in progress .
123+ std::unique_lock<std::mutex> loader_lock ( GetGlobalLoaderMutex ());
128124
129125 // Get the layer extension properties
130126 result = ApiLayerInterface::GetInstanceExtensionProperties (" xrEnumerateInstanceExtensionProperties" , layerName,
@@ -238,7 +234,8 @@ static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrCreateInstance(const XrInstanceCre
238234 return XR_ERROR_VALIDATION_FAILURE;
239235 }
240236
241- std::unique_lock<std::mutex> instance_lock (GetInstanceCreateDestroyMutex ());
237+ // Make sure the ActiveLoaderInstance::IsAvailable check is done atomically with RuntimeInterface::LoadRuntime.
238+ std::unique_lock<std::mutex> instance_lock (GetGlobalLoaderMutex ());
242239
243240 // Check if there is already an XrInstance that is alive. If so, another instance cannot be created.
244241 // The loader does not support multiple simultaneous instances because the loader is intended to be
@@ -255,7 +252,6 @@ static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrCreateInstance(const XrInstanceCre
255252
256253 // Make sure only one thread is attempting to read the JSON files and use the instance.
257254 {
258- std::unique_lock<std::mutex> json_lock (GetLoaderJsonMutex ());
259255 // Load the available runtime
260256 result = RuntimeInterface::LoadRuntime (" xrCreateInstance" );
261257 if (XR_FAILED (result)) {
@@ -326,7 +322,8 @@ static XRAPI_ATTR XrResult XRAPI_CALL LoaderXrDestroyInstance(XrInstance instanc
326322 return XR_ERROR_HANDLE_INVALID;
327323 }
328324
329- std::unique_lock<std::mutex> loader_instance_lock (GetInstanceCreateDestroyMutex ());
325+ // Make sure the runtime isn't unloaded while it is being used by xrEnumerateInstanceExtensionProperties.
326+ std::unique_lock<std::mutex> loader_lock (GetGlobalLoaderMutex ());
330327
331328 LoaderInstance *loader_instance;
332329 XrResult result = ActiveLoaderInstance::Get (&loader_instance, " xrDestroyInstance" );
0 commit comments