From b65158283ae6b4981a76f47e204684d6e41c5db0 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Mon, 31 Jan 2022 17:16:27 +0100 Subject: [PATCH] Support parking_lot mutexes and rwlocks --- Cargo.toml | 1 + plugins/gain/Cargo.toml | 2 ++ plugins/gain/src/lib.rs | 2 +- src/params.rs | 48 +++++++++++++++++++++++++++++++++++++---- 4 files changed, 48 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 26400503..0364caaa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ members = ["nih_plug_derive", "plugins/gain", "xtask"] [dependencies] nih_plug_derive = { path = "nih_plug_derive" } lazy_static = "1.4" +parking_lot = "0.12" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" vst3-sys = { git = "https://github.com/robbert-vdh/vst3-sys.git", branch = "feature/pointer-rewrite" } diff --git a/plugins/gain/Cargo.toml b/plugins/gain/Cargo.toml index 2f1c3f0f..a2910a73 100644 --- a/plugins/gain/Cargo.toml +++ b/plugins/gain/Cargo.toml @@ -8,3 +8,5 @@ crate-type = ["cdylib"] [dependencies] nih_plug = { path = "../../" } + +parking_lot = "0.12" diff --git a/plugins/gain/src/lib.rs b/plugins/gain/src/lib.rs index 8b544274..835891ed 100644 --- a/plugins/gain/src/lib.rs +++ b/plugins/gain/src/lib.rs @@ -23,8 +23,8 @@ use nih_plug::{ plugin::{BufferConfig, BusConfig, Plugin, ProcessStatus, Vst3Plugin}, util, }; +use parking_lot::RwLock; use std::pin::Pin; -use std::sync::RwLock; struct Gain { params: Pin>, diff --git a/src/params.rs b/src/params.rs index 374f5568..0057f802 100644 --- a/src/params.rs +++ b/src/params.rs @@ -19,7 +19,6 @@ use std::collections::HashMap; use std::fmt::Display; use std::pin::Pin; -use std::sync::{Mutex, RwLock}; pub type FloatParam = PlainParam; pub type IntParam = PlainParam; @@ -32,7 +31,6 @@ pub use serde_json::to_string as serialize_field; /// The functinoality needed for persisting a field to the plugin's state, and for restoring values /// when loading old state. /// -/// TODO: Replace uses of standard library synchronization primitives with parking_lot's /// TODO: Modifying these fields (or any parameter for that matter) should mark the plugin's state /// as dirty. pub trait PersistentField<'a, T>: Send + Sync @@ -45,7 +43,7 @@ where F: Fn(&T) -> R; } -impl<'a, T> PersistentField<'a, T> for RwLock +impl<'a, T> PersistentField<'a, T> for std::sync::RwLock where T: serde::Serialize + serde::Deserialize<'a> + Send + Sync, { @@ -60,7 +58,22 @@ where } } -impl<'a, T> PersistentField<'a, T> for Mutex +impl<'a, T> PersistentField<'a, T> for parking_lot::RwLock +where + T: serde::Serialize + serde::Deserialize<'a> + Send + Sync, +{ + fn set(&self, new_value: T) { + *self.write() = new_value; + } + fn map(&self, f: F) -> R + where + F: Fn(&T) -> R, + { + f(&self.read()) + } +} + +impl<'a, T> PersistentField<'a, T> for std::sync::Mutex where T: serde::Serialize + serde::Deserialize<'a> + Send + Sync, { @@ -75,6 +88,28 @@ where } } +macro_rules! impl_persistent_field_parking_lot_mutex { + ($ty:ty) => { + impl<'a, T> PersistentField<'a, T> for $ty + where + T: serde::Serialize + serde::Deserialize<'a> + Send + Sync, + { + fn set(&self, new_value: T) { + *self.lock() = new_value; + } + fn map(&self, f: F) -> R + where + F: Fn(&T) -> R, + { + f(&self.lock()) + } + } + }; +} + +impl_persistent_field_parking_lot_mutex!(parking_lot::Mutex); +impl_persistent_field_parking_lot_mutex!(parking_lot::FairMutex); + /// A distribution for a parameter's range. Probably need to add some forms of skewed ranges and /// maybe a callback based implementation at some point. #[derive(Debug)] @@ -374,6 +409,11 @@ pub enum ParamPtr { BoolParam(*mut BoolParam), } +// These pointers only point to fields on pinned structs, and the caller always needs to make sure +// that dereferencing them is safe +unsafe impl Send for ParamPtr {} +unsafe impl Sync for ParamPtr {} + impl ParamPtr { /// Get the human readable name for this parameter. ///