Fix a plugin crash on closing UI

This commit is contained in:
Jean Pierre Cimalando 2020-09-04 10:30:03 +02:00
parent 026875ae98
commit 174194ebd2
3 changed files with 63 additions and 58 deletions

View file

@ -74,6 +74,12 @@ typedef std::unique_ptr<CFrame, FrameHolderDeleter> FrameHolder;
///
struct sfizz_ui_t : EditorController, VSTGUIEditorInterface {
#if LINUX
SoHandleInitializer soHandleInitializer;
#endif
#if MAC
BundleRefInitializer bundleRefInitializer;
#endif
LV2UI_Write_Function write = nullptr;
LV2UI_Controller con = nullptr;
LV2_URID_Map *map = nullptr;
@ -369,13 +375,6 @@ LV2_SYMBOL_EXPORT
const LV2UI_Descriptor *
lv2ui_descriptor(uint32_t index)
{
#if LINUX
VSTGUI::initializeSoHandle();
#endif
#if MAC
VSTGUI::initializeBundleRef();
#endif
switch (index)
{
case 0:

View file

@ -11,6 +11,7 @@
#include <algorithm>
#include <memory>
#include <mutex>
#include <stdexcept>
#if LINUX
#include <dlfcn.h>
#include <poll.h>
@ -143,36 +144,31 @@ namespace VSTGUI
{
void* soHandle = nullptr;
static volatile bool soHandleInitialized = false;
static volatile size_t soHandleCount = 0;
static std::mutex soHandleMutex;
struct Dl_handle_deleter
SoHandleInitializer::SoHandleInitializer()
{
void operator()(void* x) const noexcept
{
dlclose(x);
}
};
static std::unique_ptr<void, Dl_handle_deleter> soHandlePointer;
} // namespace VSTGUI
void VSTGUI::initializeSoHandle()
{
if (VSTGUI::soHandleInitialized)
return;
std::lock_guard<std::mutex> lock(VSTGUI::soHandleMutex);
if (VSTGUI::soHandleInitialized)
return;
Dl_info info;
if (dladdr((void*)&lv2ui_descriptor, &info))
{
VSTGUI::soHandle = dlopen(info.dli_fname, RTLD_LAZY);
VSTGUI::soHandlePointer.reset(VSTGUI::soHandle);
}
VSTGUI::soHandleInitialized = true;
std::lock_guard<std::mutex> lock(soHandleMutex);
if (soHandleCount++ == 0) {
Dl_info info;
if (dladdr((void*)&lv2ui_descriptor, &info))
soHandle = dlopen(info.dli_fname, RTLD_LAZY);
if (!soHandle)
throw std::runtime_error("SoHandleInitializer");
}
}
SoHandleInitializer::~SoHandleInitializer()
{
std::lock_guard<std::mutex> lock(soHandleMutex);
if (--soHandleCount == 0) {
dlclose(soHandle);
soHandle = nullptr;
}
}
} // namespace VSTGUI
#endif
///
@ -194,31 +190,27 @@ namespace VSTGUI
{
void* gBundleRef = nullptr;
static volatile bool gBundleRefInitialized = false;
static volatile size_t gBundleRefCount = 0;
static std::mutex gBundleRefMutex;
struct CFBundle_deleter {
void operator()(CFBundleRef x) const noexcept
{
CFRelease(x);
}
};
static std::unique_ptr<__CFBundle, CFBundle_deleter> gBundleRefPointer;
} // namespace VSTGUI
void VSTGUI::initializeBundleRef()
BundleRefInitializer::BundleRefInitializer()
{
if (VSTGUI::gBundleRefInitialized)
return;
std::lock_guard<std::mutex> lock(VSTGUI::gBundleRefMutex);
if (VSTGUI::gBundleRefInitialized)
return;
CFBundleRef bundleRef = GetPluginBundle();
VSTGUI::gBundleRef = bundleRef;
VSTGUI::gBundleRefPointer.reset(bundleRef);
VSTGUI::gBundleRefInitialized = true;
std::lock_guard<std::mutex> lock(gBundleRefMutex);
if (bundleRefCount++ == 0) {
gBundleRef = GetPluginBundle();
if (!gBundleRef)
throw std::runtime_error("BundleRefInitializer");
}
}
BundleRefInitializer::~BundleRefInitializer()
{
std::lock_guard<std::mutex> lock(gBundleRefMutex);
if (--bundleRefCount == 0) {
CFRelease((CFBundleRef)gBundleRef);
gBundleRef = nullptr;
}
}
} // namespace VSTGUI
#endif

View file

@ -63,13 +63,27 @@ private:
#if LINUX
namespace VSTGUI
{
void initializeSoHandle();
class SoHandleInitializer {
public:
SoHandleInitializer();
~SoHandleInitializer();
private:
SoHandleInitializer(const SoHandleInitializer&) = delete;
SoHandleInitializer& operator=(const SoHandleInitializer&) = delete;
};
}
#endif
#if MAC
namespace VSTGUI
{
void initializeBundleRef();
class BundleRefInitializer {
public:
BundleRefInitializer();
~BundleRefInitializer();
private:
BundleRefInitializer(const BundleRefInitializer&) = delete;
BundleRefInitializer& operator=(const BundleRefInitializer&) = delete;
};
}
#endif