Browse Source

Import Linux-VST3 crash fix from upstream

Signed-off-by: falkTX <falktx@falktx.com>
tags/v2.4.0
falkTX 3 years ago
parent
commit
6f70ba9134
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
1 changed files with 123 additions and 94 deletions
  1. +123
    -94
      source/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp

+ 123
- 94
source/modules/juce_audio_processors/format_types/juce_VST3PluginFormat.cpp View File

@@ -1042,6 +1042,123 @@ private:
JUCE_IMPLEMENT_SINGLETON (DLLHandleCache)
//==============================================================================
#if JUCE_LINUX || JUCE_BSD
class RunLoop final : public Steinberg::Linux::IRunLoop
{
public:
RunLoop() = default;
~RunLoop()
{
for (const auto& h : eventHandlerMap)
LinuxEventLoop::unregisterFdCallback (h.first);
}
//==============================================================================
tresult PLUGIN_API registerEventHandler (Linux::IEventHandler* handler,
Linux::FileDescriptor fd) override
{
if (handler == nullptr)
return kInvalidArgument;
auto& handlers = eventHandlerMap[fd];
if (handlers.empty())
{
LinuxEventLoop::registerFdCallback (fd, [this] (int descriptor)
{
for (auto* h : eventHandlerMap[descriptor])
h->onFDIsSet (descriptor);
return true;
});
}
handlers.push_back (handler);
return kResultTrue;
}
tresult PLUGIN_API unregisterEventHandler (Linux::IEventHandler* handler) override
{
if (handler == nullptr)
return kInvalidArgument;
for (auto iter = eventHandlerMap.begin(), end = eventHandlerMap.end(); iter != end;)
{
auto& handlers = iter->second;
auto handlersIter = std::find (std::begin (handlers), std::end (handlers), handler);
if (handlersIter != std::end (handlers))
{
handlers.erase (handlersIter);
if (handlers.empty())
{
LinuxEventLoop::unregisterFdCallback (iter->first);
iter = eventHandlerMap.erase (iter);
continue;
}
}
++iter;
}
return kResultTrue;
}
//==============================================================================
tresult PLUGIN_API registerTimer (Linux::ITimerHandler* handler, Linux::TimerInterval milliseconds) override
{
if (handler == nullptr || milliseconds <= 0)
return kInvalidArgument;
timerCallers.emplace_back (handler, (int) milliseconds);
return kResultTrue;
}
tresult PLUGIN_API unregisterTimer (Linux::ITimerHandler* handler) override
{
auto iter = std::find (timerCallers.begin(), timerCallers.end(), handler);
if (iter == timerCallers.end())
return kInvalidArgument;
timerCallers.erase (iter);
return kResultTrue;
}
//==============================================================================
uint32 PLUGIN_API addRef() override { return 1000; }
uint32 PLUGIN_API release() override { return 1000; }
tresult PLUGIN_API queryInterface (const TUID, void**) override { return kNoInterface; }
private:
//==============================================================================
struct TimerCaller : private Timer
{
TimerCaller (Linux::ITimerHandler* h, int interval) : handler (h) { startTimer (interval); }
~TimerCaller() override { stopTimer(); }
void timerCallback() override { handler->onTimer(); }
bool operator== (Linux::ITimerHandler* other) const noexcept { return handler == other; }
Linux::ITimerHandler* handler = nullptr;
};
std::unordered_map<Linux::FileDescriptor, std::vector<Linux::IEventHandler*>> eventHandlerMap;
std::list<TimerCaller> timerCallers;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RunLoop)
};
#endif
//==============================================================================
struct VST3ModuleHandle : public ReferenceCountedObject
{
@@ -1189,104 +1306,11 @@ struct VST3PluginWindow : public AudioProcessorEditor,
}
#if JUCE_LINUX
struct RunLoop final : public Steinberg::Linux::IRunLoop
{
~RunLoop()
{
for (const auto& h : eventHandlers)
LinuxEventLoop::unregisterFdCallback (h.first);
}
tresult PLUGIN_API registerEventHandler (Linux::IEventHandler* handler,
Linux::FileDescriptor fd) override
{
if (handler == nullptr || eventHandlers.find (fd) != eventHandlers.end())
return kInvalidArgument;
LinuxEventLoop::registerFdCallback (fd, [handler] (int descriptor)
{
handler->onFDIsSet (descriptor);
return true;
});
eventHandlers.emplace (fd, handler);
return kResultTrue;
}
tresult PLUGIN_API unregisterEventHandler (Linux::IEventHandler* handler) override
{
if (handler == nullptr)
return kInvalidArgument;
for (auto it = eventHandlers.begin(), end = eventHandlers.end(); it != end; ++it)
{
if (it->second == handler)
{
LinuxEventLoop::unregisterFdCallback (it->first);
eventHandlers.erase (it);
return kResultTrue;
}
}
return kResultFalse;
}
tresult PLUGIN_API registerTimer (Linux::ITimerHandler* handler, Linux::TimerInterval milliseconds) override
{
if (handler == nullptr || milliseconds == 0)
return kInvalidArgument;
timerHandlers.push_back (std::make_unique<TimerCaller> (handler, (int) milliseconds));
return kResultTrue;
}
tresult PLUGIN_API unregisterTimer (Linux::ITimerHandler* handler) override
{
if (handler == nullptr)
return kInvalidArgument;
for (auto it = timerHandlers.begin(), end = timerHandlers.end(); it != end; ++it)
{
if (it->get()->handler == handler)
{
timerHandlers.erase (it);
return kResultTrue;
}
}
return kNotImplemented;
}
uint32 PLUGIN_API addRef() override { return 1000; }
uint32 PLUGIN_API release() override { return 1000; }
tresult PLUGIN_API queryInterface (const TUID, void**) override { return kNoInterface; }
std::unordered_map<Linux::FileDescriptor, Linux::IEventHandler*> eventHandlers;
struct TimerCaller : public Timer
{
TimerCaller (Linux::ITimerHandler* h, int interval) : handler (h)
{
startTimer (interval);
}
void timerCallback() override
{
handler->onTimer();
}
Linux::ITimerHandler* handler;
};
std::vector<std::unique_ptr<TimerCaller>> timerHandlers;
};
RunLoop runLoop;
Steinberg::tresult PLUGIN_API queryInterface (const Steinberg::TUID iid, void** obj) override
{
if (doUIDsMatch (iid, Steinberg::Linux::IRunLoop::iid))
{
*obj = &runLoop;
*obj = &runLoop.get();
return kResultTrue;
}
@@ -1530,6 +1554,7 @@ private:
AutoResizingNSViewComponentWithParent embeddedComponent;
using HandleFormat = NSView*;
#elif JUCE_LINUX
SharedResourcePointer<RunLoop> runLoop;
XEmbedComponent embeddedComponent { true, false };
using HandleFormat = Window;
#else
@@ -2665,6 +2690,10 @@ public:
private:
//==============================================================================
#if JUCE_LINUX || JUCE_BSD
SharedResourcePointer<RunLoop> runLoop;
#endif
std::unique_ptr<VST3ComponentHolder> holder;
friend VST3HostContext;


Loading…
Cancel
Save