Skip to content

Instantly share code, notes, and snippets.

@raphlinus
Created March 3, 2019 10:51
Show Gist options
  • Save raphlinus/e21caf808f62fbe222bd05f5feedbe80 to your computer and use it in GitHub Desktop.
Save raphlinus/e21caf808f62fbe222bd05f5feedbe80 to your computer and use it in GitHub Desktop.
Sketch of thread-safety idea for VST
struct Key(Arc<()>);
impl Key {
pub fn new() {
Key(Arc::new(()))
}
}
// Note: Key is not Clone, there can be only one.
struct Exclusive<T> {
key: Arc<()>,
inner: UnsafeCell<T>,
}
impl<T> Exclusive<T> {
pub fn new(key: &Key, inner: T) -> Exclusive<T> {
Exclusive {
key: key.0.clone(),
inner: UnsafeCell::new(T),
}
}
pub fn unlock(&self, key: &mut Key) -> &mut T {
// the key must point to the same block of memory.
assert!(key.deref() as *const _ == self.key.deref() as *const _);
self.inner.get() as &mut T
}
}
pub trait Plugin {
fn new(host: HostCallback, key: &Key) -> Self;
fn most_methods(&self);
fn process(&self, key: &mut Key, buffer: &mut AudioBuffer<f32>);
fn process_events(&self, key: &mut Key, events: &api::Events);
}
struct MyPlugin {
immutable_stuff: ... ,
atomic_stuff: AtomicFoo,
exclusive_stuff: Exclusive<...>,
}
impl Plugin for MyPlugin {
fn new(host: HostCallback, key: &Key) -> Self {
MyPlugin {
immutable_stuff: ...,
atomic_stuff: AtomicFoo::new(),
exclusive_stuff: Exclusive::new(key, ...),
}
}
fn process(&self, key: &mut Key, buffer: &mut AudioBuffer<f32>) {
let mut state = exclusive_stuff.unlock(key);
... mutate state ...
}
}
deep inside VST implementation {
key: UnsafeCell<Key>,
...
unsafe {
plugin.process(self.key.get() as &mut Key, buffer);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment