How to use state variables which don't implement Sync trait?
Hi, I'm trying to implement a variable clock delay plugin in the NIH-plug framework. Here's the WIP: https://github.com/teowoz/nih-plug/tree/varispeed-delay
The problem is, it looks like all members of plugin state struct must implement Sync trait, but the library I want to use (rubato) doesn't implement it:
$ cargo xtask bundle varispeed_delay --release
Finished release [optimized] target(s) in 0.10s
Running `target/release/xtask bundle varispeed_delay --release`
Compiling varispeed_delay v0.1.0 (/home/teo/Projects/nih-plug/plugins/varispeed_delay)
error[E0277]: `(dyn rubato::asynchro::SincInterpolator<f64> + 'static)` cannot be shared between threads safely
--> plugins/varispeed_delay/src/lib.rs:84:6
|
84 | impl Plugin for VariSpeedDelay {
| ^^^^^^ `(dyn rubato::asynchro::SincInterpolator<f64> + 'static)` cannot be shared between threads safely
|
= help: the trait `Sync` is not implemented for `(dyn rubato::asynchro::SincInterpolator<f64> + 'static)`
= note: required because of the requirements on the impl of `Sync` for `Unique<(dyn rubato::asynchro::SincInterpolator<f64> + 'static)>`
= note: required because it appears within the type `Box<(dyn rubato::asynchro::SincInterpolator<f64> + 'static)>`
= note: required because it appears within the type `SincFixedIn<f64>`
note: required because it appears within the type `VariSpeedDelay`
--> plugins/varispeed_delay/src/lib.rs:25:8
|
25 | struct VariSpeedDelay {
| ^^^^^^^^^^^^^^
note: required by a bound in `nih_plug::prelude::Plugin`
--> /home/teo/Projects/nih-plug/src/plugin.rs:26:36
|
26 | pub trait Plugin: Default + Send + Sync + 'static {
| ^^^^ required by this bound in `nih_plug::prelude::Plugin`
error[E0277]: `(dyn rubato::asynchro::SincInterpolator<f64> + 'static)` cannot be shared between threads safely
--> plugins/varispeed_delay/src/lib.rs:189:6
|
189 | impl Vst3Plugin for VariSpeedDelay {
| ^^^^^^^^^^ `(dyn rubato::asynchro::SincInterpolator<f64> + 'static)` cannot be shared between threads safely
|
= help: the trait `Sync` is not implemented for `(dyn rubato::asynchro::SincInterpolator<f64> + 'static)`
= note: required because of the requirements on the impl of `Sync` for `Unique<(dyn rubato::asynchro::SincInterpolator<f64> + 'static)>`
= note: required because it appears within the type `Box<(dyn rubato::asynchro::SincInterpolator<f64> + 'static)>`
= note: required because it appears within the type `SincFixedIn<f64>`
note: required because it appears within the type `VariSpeedDelay`
--> plugins/varispeed_delay/src/lib.rs:25:8
|
25 | struct VariSpeedDelay {
| ^^^^^^^^^^^^^^
note: required by a bound in `nih_plug::prelude::Vst3Plugin`
--> /home/teo/Projects/nih-plug/src/plugin.rs:201:23
|
201 | pub trait Vst3Plugin: Plugin {
| ^^^^^^ required by this bound in `nih_plug::prelude::Vst3Plugin`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `varispeed_delay` due to 2 previous errors
Error: Could not build varispeed_delay
The compiler says that resampler struct cannot be shared between threads safely, but it won't be used in multiple threads at once anyway, so why is the Sync trait required? Is there way around it? Sorry if it's a stupid question, I'm just starting to learn Rust.
Everything you store in your plugin struct needs to be Sync. The issue you're running into is that the type you're using contains a boxed trait object which does not have the Send + Sync trait bounds, thus making it non-Sync. Since you'll have exclusive mutable access in the initialize, reset, and process functions you should be able to do whatever you want with your struct's fields, but you still need to be able to store them in a way that's Send+Sync. There's a proposed and currently nightly-only API for this through the Exclusive` struct, but outside of reimplementing that yourself or using a crate I don't know if there's another alternative here.
Plugin and most other traits now long require Send as of a couple weeks ago (https://github.com/robbert-vdh/nih-plug/commit/f9bdaffc625cbb5cbf56c14b995c4c9d356dff09 for Plugin). Sync is no longer needed.