diff --git a/src/plugin.rs b/src/plugin.rs index bb73d1a3..2aab1ab8 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -10,7 +10,10 @@ use crate::params::Params; use crate::wrapper::clap::features::ClapFeature; use crate::wrapper::state::PluginState; -pub type TaskExecutor

= Box::BackgroundTask) + Send + Sync>; +/// A function that can execute a plugin's [`BackgroundTask`][Plugin::BackgroundTask]s. A plugin can +/// dispatch these tasks from the `initialize()` function, the `process()` function, or the GUI, so +/// they can be deferred for later to avoid blocking realtime contexts. +pub type TaskExecutor

= Box::BackgroundTask) + Send>; /// Basic functionality that needs to be implemented by a plugin. The wrappers will use this to /// expose the plugin in a particular plugin format. diff --git a/src/wrapper/clap/context.rs b/src/wrapper/clap/context.rs index bd53258b..f3ad795e 100644 --- a/src/wrapper/clap/context.rs +++ b/src/wrapper/clap/context.rs @@ -115,7 +115,7 @@ impl GuiContext for WrapperGuiContext

{ impl InitContext

for WrapperInitContext<'_, P> { fn execute(&self, task: P::BackgroundTask) { - (self.wrapper.task_executor)(task); + (self.wrapper.task_executor.lock())(task); } fn plugin_api(&self) -> PluginApi { diff --git a/src/wrapper/clap/wrapper.rs b/src/wrapper/clap/wrapper.rs index 5c4f24a1..1fff8391 100644 --- a/src/wrapper/clap/wrapper.rs +++ b/src/wrapper/clap/wrapper.rs @@ -107,7 +107,7 @@ pub struct Wrapper { /// The wrapped plugin instance. plugin: Mutex

, /// The plugin's background task executor closure. - pub task_executor: TaskExecutor

, + pub task_executor: Mutex>, /// The plugin's parameters. These are fetched once during initialization. That way the /// `ParamPtr`s are guaranteed to live at least as long as this object and we can interact with /// the `Params` object without having to acquire a lock on `plugin`. @@ -353,7 +353,7 @@ impl MainThreadExecutor> for Wrapper

{ unsafe fn execute(&self, task: Task

) { // This function is always called from the main thread, from [Self::on_main_thread]. match task { - Task::PluginTask(task) => (self.task_executor)(task), + Task::PluginTask(task) => (self.task_executor.lock())(task), Task::LatencyChanged => match &*self.host_latency.borrow() { Some(host_latency) => { // XXX: The CLAP docs mention that you should request a restart if this happens @@ -387,7 +387,7 @@ impl MainThreadExecutor> for Wrapper

{ impl Wrapper

{ pub fn new(host_callback: *const clap_host) -> Arc { let plugin = P::default(); - let task_executor = plugin.task_executor(); + let task_executor = Mutex::new(plugin.task_executor()); let editor = plugin.editor().map(Mutex::new); // This is used to allow the plugin to restore preset data from its editor, see the comment diff --git a/src/wrapper/standalone/context.rs b/src/wrapper/standalone/context.rs index c97979a2..7e7ec4c1 100644 --- a/src/wrapper/standalone/context.rs +++ b/src/wrapper/standalone/context.rs @@ -80,7 +80,7 @@ impl GuiContext for WrapperGuiContext { impl InitContext

for WrapperInitContext<'_, P, B> { fn execute(&self, task: P::BackgroundTask) { - (self.wrapper.task_executor_wrapper.task_executor)(task); + (self.wrapper.task_executor_wrapper.task_executor.lock())(task); } fn plugin_api(&self) -> PluginApi { diff --git a/src/wrapper/standalone/wrapper.rs b/src/wrapper/standalone/wrapper.rs index a430eb8c..c3952d4f 100644 --- a/src/wrapper/standalone/wrapper.rs +++ b/src/wrapper/standalone/wrapper.rs @@ -141,12 +141,12 @@ impl WindowHandler for WrapperWindowHandler { /// Adapter to make `TaskExecutor

` work as a `MainThreadExecutor`. pub struct TaskExecutorWrapper { - pub task_executor: TaskExecutor

, + pub task_executor: Mutex>, } impl MainThreadExecutor for TaskExecutorWrapper

{ unsafe fn execute(&self, task: P::BackgroundTask) { - (self.task_executor)(task) + (self.task_executor.lock())(task) } } @@ -156,7 +156,7 @@ impl Wrapper { pub fn new(backend: B, config: WrapperConfig) -> Result, WrapperError> { let plugin = P::default(); let task_executor_wrapper = Arc::new(TaskExecutorWrapper { - task_executor: plugin.task_executor(), + task_executor: Mutex::new(plugin.task_executor()), }); let params = plugin.params(); let editor = plugin.editor().map(|editor| Arc::new(Mutex::new(editor))); diff --git a/src/wrapper/vst3/context.rs b/src/wrapper/vst3/context.rs index dba0bfa8..b431d403 100644 --- a/src/wrapper/vst3/context.rs +++ b/src/wrapper/vst3/context.rs @@ -117,7 +117,7 @@ impl GuiContext for WrapperGuiContext

{ impl InitContext

for WrapperInitContext<'_, P> { fn execute(&self, task: P::BackgroundTask) { - (self.inner.task_executor)(task); + (self.inner.task_executor.lock())(task); } fn plugin_api(&self) -> PluginApi { diff --git a/src/wrapper/vst3/inner.rs b/src/wrapper/vst3/inner.rs index d0216e6c..8c8b70eb 100644 --- a/src/wrapper/vst3/inner.rs +++ b/src/wrapper/vst3/inner.rs @@ -34,7 +34,7 @@ pub(crate) struct WrapperInner { /// The wrapped plugin instance. pub plugin: Mutex

, /// The plugin's background task executor closure. - pub task_executor: TaskExecutor

, + pub task_executor: Mutex>, /// The plugin's parameters. These are fetched once during initialization. That way the /// `ParamPtr`s are guaranteed to live at least as long as this object and we can interact with /// the `Params` object without having to acquire a lock on `plugin`. @@ -197,7 +197,7 @@ impl WrapperInner

{ #[allow(unused_unsafe)] pub fn new() -> Arc { let plugin = P::default(); - let task_executor = plugin.task_executor(); + let task_executor = Mutex::new(plugin.task_executor()); let editor = plugin.editor().map(|editor| Arc::new(Mutex::new(editor))); // This is used to allow the plugin to restore preset data from its editor, see the comment @@ -527,7 +527,7 @@ impl MainThreadExecutor> for WrapperInner

{ // function for checking if a to be scheduled task can be handled right there and // then). match task { - Task::PluginTask(task) => (self.task_executor)(task), + Task::PluginTask(task) => (self.task_executor.lock())(task), Task::TriggerRestart(flags) => match &*self.component_handler.borrow() { Some(handler) => { handler.restart_component(flags);