VST2: Consolidate support methods (close, unload)
Properly unload linux VST2 plugins and fix Mac VST2 bundle unloading - do not use dlclose(): CFBundleRef is reference counted, so we need to retain a reference. Previously it went out of scope at the end of mac_vst_load().
This commit is contained in:
parent
ef06f01c7b
commit
fcd04cd27a
|
@ -25,6 +25,23 @@
|
|||
#include "ardour/libardour_visibility.h"
|
||||
#include "ardour/vestige/vestige.h"
|
||||
|
||||
#ifdef MACVST_SUPPORT
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
/* fix up stupid apple macros */
|
||||
#undef check
|
||||
#undef require
|
||||
#undef verify
|
||||
|
||||
#ifdef YES
|
||||
#undef YES
|
||||
#endif
|
||||
#ifdef NO
|
||||
#undef NO
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
struct LIBARDOUR_API _VSTKey
|
||||
{
|
||||
/** virtual-key code, or 0 if this _VSTFXKey is a `character' key */
|
||||
|
@ -62,16 +79,17 @@ typedef AEffect * (* main_entry_t) (audioMasterCallback);
|
|||
|
||||
struct LIBARDOUR_API _VSTHandle
|
||||
{
|
||||
void* dll;
|
||||
#ifdef MACVST_SUPPORT
|
||||
CFBundleRef bundleRef;
|
||||
CFBundleRefNum res_file_id;
|
||||
#else
|
||||
void* dll;
|
||||
#endif
|
||||
|
||||
char* name;
|
||||
char* path;
|
||||
|
||||
main_entry_t main_entry;
|
||||
|
||||
int plugincnt;
|
||||
#ifdef MACVST_SUPPORT
|
||||
int32_t res_file_id;
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct _VSTHandle VSTHandle;
|
||||
|
|
|
@ -267,6 +267,7 @@ vstfx_unload (VSTHandle* fhandle)
|
|||
if (fhandle->name)
|
||||
{
|
||||
free (fhandle->name);
|
||||
fhandle->name = 0;
|
||||
}
|
||||
|
||||
/*Don't need the plugin handle any more*/
|
||||
|
@ -339,30 +340,19 @@ void vstfx_close (VSTState* vstfx)
|
|||
vstfx->plugin->dispatcher (vstfx->plugin, effClose, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
if (vstfx->handle->plugincnt)
|
||||
if (vstfx->handle->plugincnt) {
|
||||
vstfx->handle->plugincnt--;
|
||||
|
||||
/*vstfx_unload will unload the dll if the instance count allows -
|
||||
we need to do this because some plugins keep their own instance count
|
||||
and (JUCE) manages the plugin UI in its own thread. When the plugins
|
||||
internal instance count reaches zero, JUCE stops the UI thread and won't
|
||||
restart it until the next time the library is loaded. If we don't unload
|
||||
the lib JUCE will never restart*/
|
||||
|
||||
|
||||
if (vstfx->handle->plugincnt)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*Valid plugin loaded - so we can unload it and 0 the pointer
|
||||
to it. We can't free the handle here because we don't know what else
|
||||
might need it. It should be / is freed when the plugin is deleted*/
|
||||
/* vstfx_unload will unload the dll if the instance count allows -
|
||||
* we need to do this because some plugins keep their own instance count
|
||||
* and (JUCE) manages the plugin UI in its own thread. When the plugins
|
||||
* internal instance count reaches zero, JUCE stops the UI thread and won't
|
||||
* restart it until the next time the library is loaded. If we don't unload
|
||||
* the lib JUCE will never restart
|
||||
*/
|
||||
|
||||
vstfx_unload (vstfx->handle);
|
||||
|
||||
if (vstfx->handle->dll)
|
||||
{
|
||||
dlclose(vstfx->handle->dll); //dlclose keeps its own reference count
|
||||
vstfx->handle->dll = 0;
|
||||
}
|
||||
free(vstfx);
|
||||
}
|
||||
|
|
|
@ -39,8 +39,6 @@
|
|||
|
||||
#include "pbd/i18n.h"
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
/*Simple error handler stuff for VSTFX*/
|
||||
|
||||
void mac_vst_error (const char *fmt, ...)
|
||||
|
@ -96,34 +94,34 @@ mac_vst_load (const char *path)
|
|||
|
||||
fhandle = mac_vst_handle_new ();
|
||||
|
||||
fhandle->dll = NULL;
|
||||
fhandle->bundleRef = 0;
|
||||
|
||||
CFURLRef url;
|
||||
if (!(url = CFURLCreateFromFileSystemRepresentation (0, (const UInt8*)path, (CFIndex) strlen (path), true))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
CFBundleRef bundleRef = CFBundleCreate (kCFAllocatorDefault, url);
|
||||
fhandle->bundleRef = CFBundleCreate (kCFAllocatorDefault, url);
|
||||
CFRelease (url);
|
||||
|
||||
if (bundleRef == 0) {
|
||||
if (fhandle->bundleRef == 0) {
|
||||
free (fhandle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!CFBundleLoadExecutable (bundleRef)) {
|
||||
CFRelease (bundleRef);
|
||||
if (!CFBundleLoadExecutable (fhandle->bundleRef)) {
|
||||
free (fhandle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fhandle->name = strdup (path);
|
||||
fhandle->dll = (void*) &bundleRef;
|
||||
|
||||
fhandle->main_entry = (main_entry_t)
|
||||
CFBundleGetFunctionPointerForName (bundleRef, CFSTR("main_macho"));
|
||||
CFBundleGetFunctionPointerForName (fhandle->bundleRef, CFSTR("main_macho"));
|
||||
|
||||
if (!fhandle->main_entry) {
|
||||
fhandle->main_entry = (main_entry_t)
|
||||
CFBundleGetFunctionPointerForName (bundleRef, CFSTR("VSTPluginMain"));
|
||||
CFBundleGetFunctionPointerForName (fhandle->bundleRef, CFSTR("VSTPluginMain"));
|
||||
}
|
||||
|
||||
if (fhandle->main_entry == 0) {
|
||||
|
@ -131,7 +129,7 @@ mac_vst_load (const char *path)
|
|||
return 0;
|
||||
}
|
||||
|
||||
fhandle->res_file_id = CFBundleOpenBundleResourceMap (bundleRef);
|
||||
fhandle->res_file_id = CFBundleOpenBundleResourceMap (fhandle->bundleRef);
|
||||
|
||||
/*return the handle of the plugin*/
|
||||
return fhandle;
|
||||
|
@ -144,25 +142,22 @@ mac_vst_unload (VSTHandle* fhandle)
|
|||
{
|
||||
if (fhandle->plugincnt)
|
||||
{
|
||||
/*Still have plugin instances - can't unload the library
|
||||
- actually dlclose keeps an instance count anyway*/
|
||||
|
||||
/*Still have plugin instances - can't unload the library */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*Valid plugin loaded?*/
|
||||
|
||||
if (fhandle->dll)
|
||||
if (fhandle->bundleRef)
|
||||
{
|
||||
CFBundleRef* bundleRefPtr = (CFBundleRef*) fhandle->dll;
|
||||
CFBundleCloseBundleResourceMap (*bundleRefPtr, (CFBundleRefNum)fhandle->res_file_id);
|
||||
CFRelease (*bundleRefPtr);
|
||||
fhandle->dll = 0;
|
||||
CFBundleCloseBundleResourceMap (fhandle->bundleRef, fhandle->res_file_id);
|
||||
fhandle->bundleRef = 0;
|
||||
}
|
||||
|
||||
if (fhandle->name)
|
||||
{
|
||||
free (fhandle->name);
|
||||
fhandle->name = 0;
|
||||
}
|
||||
|
||||
/*Don't need the plugin handle any more*/
|
||||
|
@ -238,31 +233,20 @@ void mac_vst_close (VSTState* mac_vst)
|
|||
mac_vst->plugin->dispatcher (mac_vst->plugin, effClose, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
if (mac_vst->handle->plugincnt)
|
||||
if (mac_vst->handle->plugincnt) {
|
||||
mac_vst->handle->plugincnt--;
|
||||
|
||||
/*mac_vst_unload will unload the dll if the instance count allows -
|
||||
we need to do this because some plugins keep their own instance count
|
||||
and (JUCE) manages the plugin UI in its own thread. When the plugins
|
||||
internal instance count reaches zero, JUCE stops the UI thread and won't
|
||||
restart it until the next time the library is loaded. If we don't unload
|
||||
the lib JUCE will never restart*/
|
||||
|
||||
|
||||
if (mac_vst->handle->plugincnt)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/*Valid plugin loaded - so we can unload it and 0 the pointer
|
||||
to it. We can't free the handle here because we don't know what else
|
||||
might need it. It should be / is freed when the plugin is deleted*/
|
||||
/* mac_vst_unload will unload the dll if the instance count allows -
|
||||
* we need to do this because some plugins keep their own instance count
|
||||
* and (JUCE) manages the plugin UI in its own thread. When the plugins
|
||||
* internal instance count reaches zero, JUCE stops the UI thread and won't
|
||||
* restart it until the next time the library is loaded. If we don't unload
|
||||
* the lib JUCE will never restart
|
||||
*/
|
||||
|
||||
mac_vst_unload (mac_vst->handle);
|
||||
|
||||
if (mac_vst->handle->dll)
|
||||
{
|
||||
dlclose (mac_vst->handle->dll); //dlclose keeps its own reference count
|
||||
mac_vst->handle->dll = 0;
|
||||
}
|
||||
free (mac_vst);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue