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// Terminal functions needed by xrCreateInstance.
@@ -84,7 +80,7 @@ XRAPI_ATTR XrResult XRAPI_CALL LoaderXrEnumerateApiLayerProperties(uint32_t prop
8480 LoaderLogger::LogVerboseMessage (" xrEnumerateApiLayerProperties" , " Entering loader trampoline" );
8581
8682 // Make sure only one thread is attempting to read the JSON files at a time.
87- std::unique_lock<std::mutex> json_lock ( GetLoaderJsonMutex ());
83+ std::unique_lock<std::mutex> loader_lock ( GetGlobalLoaderMutex ());
8884
8985 XrResult result = ApiLayerInterface::GetApiLayerProperties (" xrEnumerateApiLayerProperties" , propertyCapacityInput,
9086 propertyCountOutput, properties);
@@ -117,8 +113,8 @@ XRAPI_ATTR XrResult XRAPI_CALL LoaderXrEnumerateInstanceExtensionProperties(cons
117113 XrResult result;
118114
119115 {
120- // Make sure only one thread is attempting to read the JSON files at a time .
121- std::unique_lock<std::mutex> json_lock ( GetLoaderJsonMutex ());
116+ // Make sure the runtime isn't unloaded while this call is in progress .
117+ std::unique_lock<std::mutex> loader_lock ( GetGlobalLoaderMutex ());
122118
123119 // Get the layer extension properties
124120 result = ApiLayerInterface::GetInstanceExtensionProperties (" xrEnumerateInstanceExtensionProperties" , layerName,
@@ -231,7 +227,8 @@ XRAPI_ATTR XrResult XRAPI_CALL LoaderXrCreateInstance(const XrInstanceCreateInfo
231227 return XR_ERROR_VALIDATION_FAILURE;
232228 }
233229
234- std::unique_lock<std::mutex> instance_lock (GetInstanceCreateDestroyMutex ());
230+ // Make sure the ActiveLoaderInstance::IsAvailable check is done atomically with RuntimeInterface::LoadRuntime.
231+ std::unique_lock<std::mutex> instance_lock (GetGlobalLoaderMutex ());
235232
236233 // Check if there is already an XrInstance that is alive. If so, another instance cannot be created.
237234 // The loader does not support multiple simultaneous instances because the loader is intended to be
@@ -248,7 +245,6 @@ XRAPI_ATTR XrResult XRAPI_CALL LoaderXrCreateInstance(const XrInstanceCreateInfo
248245
249246 // Make sure only one thread is attempting to read the JSON files and use the instance.
250247 {
251- std::unique_lock<std::mutex> json_lock (GetLoaderJsonMutex ());
252248 // Load the available runtime
253249 result = RuntimeInterface::LoadRuntime (" xrCreateInstance" );
254250 if (XR_FAILED (result)) {
@@ -318,7 +314,8 @@ XRAPI_ATTR XrResult XRAPI_CALL LoaderXrDestroyInstance(XrInstance instance) XRLO
318314 return XR_ERROR_HANDLE_INVALID;
319315 }
320316
321- std::unique_lock<std::mutex> loader_instance_lock (GetInstanceCreateDestroyMutex ());
317+ // Make sure the runtime isn't unloaded while it is being used by xrEnumerateInstanceExtensionProperties.
318+ std::unique_lock<std::mutex> loader_lock (GetGlobalLoaderMutex ());
322319
323320 LoaderInstance *loader_instance;
324321 XrResult result = ActiveLoaderInstance::Get (&loader_instance, " xrDestroyInstance" );
0 commit comments