From 548dc74d8acfbe0ee01cf52edd3260ce80fb0411 Mon Sep 17 00:00:00 2001 From: Benjamin Klum Date: Thu, 23 Jan 2025 13:40:35 +0100 Subject: [PATCH] Replace Once with OnceLock --- main/low/src/macros.rs | 2 +- main/low/src/static_context.rs | 57 +++++++++++++++------------------- 2 files changed, 26 insertions(+), 33 deletions(-) diff --git a/main/low/src/macros.rs b/main/low/src/macros.rs index f9a290fd..a2c6cb46 100644 --- a/main/low/src/macros.rs +++ b/main/low/src/macros.rs @@ -48,7 +48,7 @@ macro_rules! dll_main { _: *const u8, ) -> u32 { if reason == reaper_low::raw::DLL_PROCESS_ATTACH { - reaper_low::register_hinstance(hinstance); + let _ = reaper_low::register_hinstance(hinstance); } else if reason == reaper_low::raw::DLL_PROCESS_DETACH { reaper_low::execute_plugin_destroy_hooks(); } diff --git a/main/low/src/static_context.rs b/main/low/src/static_context.rs index d0be2b15..fffc0062 100644 --- a/main/low/src/static_context.rs +++ b/main/low/src/static_context.rs @@ -1,14 +1,17 @@ -use crate::{ - raw, register_plugin_destroy_hook, GetSwellFunc, PluginDestroyHook, StaticPluginContext, -}; +use crate::{raw, GetSwellFunc, StaticPluginContext}; +use fragile::Fragile; +use std::ptr::null_mut; /// Exposes the (hopefully) obtained static plug-in context. /// /// This is typically called by one of the plugin macros. pub fn static_plugin_context() -> StaticPluginContext { StaticPluginContext { - h_instance: unsafe { hinstance::HINSTANCE }, - get_swell_func: unsafe { swell::GET_SWELL_FUNC }, + h_instance: hinstance::HINSTANCE + .get() + .map(|i| *i.get()) + .unwrap_or(null_mut()), + get_swell_func: swell::GET_SWELL_FUNC.get().copied(), } } @@ -18,21 +21,18 @@ pub fn static_plugin_context() -> StaticPluginContext { /// This is typically called by some SWELL entry point in one of the plugin macros. /// /// [`static_extension_plugin_context()`]: fn.static_extension_plugin_context.html -pub fn register_swell_function_provider(get_func: Option) { +pub fn register_swell_function_provider(get_func: GetSwellFunc) -> Result<(), &'static str> { // Save provider in static variable. - swell::INIT_GET_SWELL_FUNC.call_once(|| unsafe { - swell::GET_SWELL_FUNC = get_func; - register_plugin_destroy_hook(PluginDestroyHook { - name: "reaper_low::swell::GET_SWELL_FUNC", - callback: || swell::GET_SWELL_FUNC = None, - }); - }); + swell::GET_SWELL_FUNC + .set(get_func) + .map_err(|_| "SWELL function provider registered already")?; // On Linux Rust will get informed first about the SWELL function provider, so we need to pass // it on to the C++ side. #[cfg(target_os = "linux")] unsafe { swell::register_swell_function_provider_called_from_rust(get_func); } + Ok(()) } /// Registers the module handle globally. @@ -41,26 +41,17 @@ pub fn register_swell_function_provider(get_func: Option) { /// This is typically called on Windows only by some entry point in one of the plugin macros. /// /// [`static_plugin_context()`]: fn.static_plugin_context.html -pub fn register_hinstance(hinstance: raw::HINSTANCE) { - // Save handle in static variable. - hinstance::INIT_HINSTANCE.call_once(|| unsafe { - hinstance::HINSTANCE = hinstance; - register_plugin_destroy_hook(PluginDestroyHook { - name: "reaper_low::hinstance::HINSTANCE", - callback: || hinstance::HINSTANCE = std::ptr::null_mut(), - }); - }); +pub fn register_hinstance(hinstance: raw::HINSTANCE) -> Result<(), &'static str> { + hinstance::HINSTANCE + .set(Fragile::new(hinstance)) + .map_err(|_| "HINSTANCE registered already") } mod swell { - use std::os::raw::{c_char, c_void}; - use std::sync::Once; + use std::sync::OnceLock; /// On Linux/macOS this will contain the SWELL function provider after REAPER start. - pub static mut GET_SWELL_FUNC: Option< - unsafe extern "C" fn(name: *const c_char) -> *mut c_void, - > = None; - pub static INIT_GET_SWELL_FUNC: Once = Once::new(); + pub static GET_SWELL_FUNC: OnceLock = OnceLock::new(); #[cfg(target_os = "linux")] extern "C" { @@ -82,15 +73,17 @@ mod swell { #[cfg(target_os = "macos")] #[no_mangle] unsafe extern "C" fn register_swell_called_from_cpp(get_func: Option) { - crate::register_swell_function_provider(get_func); + if let Some(get_func) = get_func { + let _ = crate::register_swell_function_provider(get_func); + } } } mod hinstance { use crate::raw; - use std::sync::Once; + use fragile::Fragile; + use std::sync::OnceLock; /// On Windows, this will contain the module handle after the plug-in has been loaded. - pub static mut HINSTANCE: raw::HINSTANCE = std::ptr::null_mut(); - pub static INIT_HINSTANCE: Once = Once::new(); + pub static HINSTANCE: OnceLock> = OnceLock::new(); }