Use custom std::unique_ptr deleter to more safely handle owning pointer

This commit is contained in:
Chris Thrasher 2024-10-14 18:52:31 -06:00
parent efa989aa19
commit 533992b6f3
No known key found for this signature in database
GPG Key ID: 56FB686C9DFC8E2C

View File

@ -43,41 +43,32 @@ namespace
{ {
struct VulkanLibraryWrapper struct VulkanLibraryWrapper
{ {
~VulkanLibraryWrapper()
{
if (library)
dlclose(library);
}
// Try to load the library and all the required entry points // Try to load the library and all the required entry points
bool loadLibrary() bool loadLibrary()
{ {
if (library) if (library)
return true; return true;
library = dlopen("libvulkan.so.1", RTLD_LAZY); library.reset(dlopen("libvulkan.so.1", RTLD_LAZY));
if (!library) if (!library)
return false; return false;
if (!loadEntryPoint(vkGetInstanceProcAddr, "vkGetInstanceProcAddr")) if (!loadEntryPoint(vkGetInstanceProcAddr, "vkGetInstanceProcAddr"))
{ {
dlclose(library); library.reset();
library = nullptr;
return false; return false;
} }
if (!loadEntryPoint(vkEnumerateInstanceLayerProperties, "vkEnumerateInstanceLayerProperties")) if (!loadEntryPoint(vkEnumerateInstanceLayerProperties, "vkEnumerateInstanceLayerProperties"))
{ {
dlclose(library); library.reset();
library = nullptr;
return false; return false;
} }
if (!loadEntryPoint(vkEnumerateInstanceExtensionProperties, "vkEnumerateInstanceExtensionProperties")) if (!loadEntryPoint(vkEnumerateInstanceExtensionProperties, "vkEnumerateInstanceExtensionProperties"))
{ {
dlclose(library); library.reset();
library = nullptr;
return false; return false;
} }
@ -87,12 +78,19 @@ struct VulkanLibraryWrapper
template <typename T> template <typename T>
bool loadEntryPoint(T& entryPoint, const char* name) bool loadEntryPoint(T& entryPoint, const char* name)
{ {
entryPoint = reinterpret_cast<T>(dlsym(library, name)); entryPoint = reinterpret_cast<T>(dlsym(library.get(), name));
return entryPoint != nullptr; return entryPoint != nullptr;
} }
void* library{}; struct SharedLibraryDeleter
{
void operator()(void* ptr) const
{
dlclose(ptr);
}
};
std::unique_ptr<void, SharedLibraryDeleter> library;
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr{}; PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr{};
PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties{}; PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties{};
@ -169,7 +167,7 @@ VulkanFunctionPointer VulkanImpl::getFunction(const char* name)
if (!isAvailable(false)) if (!isAvailable(false))
return nullptr; return nullptr;
return reinterpret_cast<VulkanFunctionPointer>(dlsym(wrapper.library, name)); return reinterpret_cast<VulkanFunctionPointer>(dlsym(wrapper.library.get(), name));
} }