From 3a1fbed4c30a06dc1003df9a14ae8334a65d2a50 Mon Sep 17 00:00:00 2001
From: Robbert van der Helm <mail@robbertvanderhelm.nl>
Date: Tue, 1 Feb 2022 17:01:05 +0100
Subject: [PATCH] Mark MainThreadExecutor::execute as unsafe

This should only be called from the main thread. Otherwise the API's
threading guarantees will not be upheld.
---
 src/context.rs       | 4 ++--
 src/context/linux.rs | 4 ++--
 src/wrapper/vst3.rs  | 7 ++++---
 3 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/src/context.rs b/src/context.rs
index 93cec608..8cb9c8c8 100644
--- a/src/context.rs
+++ b/src/context.rs
@@ -83,6 +83,6 @@ where
 
 /// Something that can execute tasks of type `T`.
 pub(crate) trait MainThreadExecutor<T>: Send + Sync {
-    /// Execute a task on the current thread.
-    fn execute(&self, task: T);
+    /// Execute a task on the current thread. This shoudl only be called from the main thread.
+    unsafe fn execute(&self, task: T);
 }
diff --git a/src/context/linux.rs b/src/context/linux.rs
index cefafb9c..78411a5b 100644
--- a/src/context/linux.rs
+++ b/src/context/linux.rs
@@ -85,7 +85,7 @@ where
         if self.is_main_thread() {
             match self.executor.upgrade() {
                 Some(e) => {
-                    e.execute(task);
+                    unsafe { e.execute(task) };
                     true
                 }
                 None => {
@@ -125,7 +125,7 @@ where
     loop {
         match receiver.recv() {
             Ok(Message::Task(task)) => match executor.upgrade() {
-                Some(e) => e.execute(task),
+                Some(e) => unsafe { e.execute(task) },
                 None => {
                     nih_log!("Received a new task but the executor is no longer alive, shutting down worker");
                     return;
diff --git a/src/wrapper/vst3.rs b/src/wrapper/vst3.rs
index d3668073..323b274b 100644
--- a/src/wrapper/vst3.rs
+++ b/src/wrapper/vst3.rs
@@ -274,7 +274,8 @@ impl<P: Plugin> Wrapper<'_, P> {
 }
 
 impl<P: Plugin> MainThreadExecutor<Task> for WrapperInner<'_, P> {
-    fn execute(&self, task: Task) {
+    unsafe fn execute(&self, task: Task) {
+        // This function is always called from the main thread
         // TODO: When we add GUI resizing and context menus, this should propagate those events to
         //       `IRunLoop` on Linux to keep REAPER happy. That does mean a double spool, but we can
         //       come up with a nicer solution to handle that later (can always add a separate
@@ -282,9 +283,9 @@ impl<P: Plugin> MainThreadExecutor<Task> for WrapperInner<'_, P> {
         //       then).
         match task {
             Task::TriggerRestart(flags) => match &*self.component_handler.read() {
-                Some(handler) => unsafe {
+                Some(handler) => {
                     handler.restart_component(flags);
-                },
+                }
                 None => nih_debug_assert_failure!("Component handler not yet set"),
             },
         }