1
0
Fork 0

Use a custom .spawn_unchecked without nightly req

Courtesy of Yandros on the Rust Discord.
This commit is contained in:
Robbert van der Helm 2022-02-01 15:04:36 +01:00
parent 9c93414d9c
commit 98076ff792
3 changed files with 33 additions and 8 deletions

View file

@ -22,9 +22,9 @@ use crossbeam::channel;
use std::sync::Arc;
use std::thread::{self, JoinHandle, ThreadId};
use crate::nih_log;
use super::{EventLoop, MainThreadExecutor};
use crate::nih_log;
use crate::util::ThreadSpawnUnchecked;
/// See [super::EventLoop].
pub(crate) struct LinuxEventLoop<T, E> {
@ -69,9 +69,12 @@ where
worker_thread: Some(unsafe {
thread::Builder::new()
.name(String::from("worker"))
// FIXME: Find another way to bind a thread lifetime to this struct without a
// nightly-only fature
.spawn_unchecked(move || worker_thread(receiver, executor))
// The worker thread gets joined when this struct gets dropped, and if this
// struct never gets dropped it just sits there idly. Panics cannot be unwound,
// but in plugin-land we have bigger worries than that.
// This is the same as the `.spawn_unchecked()` function, but without requiring
// a nightly compiler.
.spawn_unchecked_2(move || worker_thread(receiver, executor))
.expect("Could not spawn worker thread")
}),
worker_thread_channel: sender,

View file

@ -16,9 +16,6 @@
// TODO: Once everything is more fleshed out, document the basic usage of this library
// FIXME: Find an alternative for this
#![feature(thread_spawn_unchecked)]
pub mod context;
#[macro_use]
pub mod debug;

View file

@ -35,6 +35,31 @@ pub fn gain_to_db(gain: f32) -> f32 {
}
}
/// A version of [std::thread::Builder::spawn_unchecked] that works on the stable compiler.
/// Implementation courtesy of Yandros on the Rust Discord.
pub(crate) trait ThreadSpawnUnchecked {
unsafe fn spawn_unchecked_2<F, R>(self, f: F) -> std::io::Result<std::thread::JoinHandle<R>>
where
F: FnOnce() -> R + Send,
R: 'static + Send;
}
impl ThreadSpawnUnchecked for std::thread::Builder {
unsafe fn spawn_unchecked_2<F, R>(self, f: F) -> std::io::Result<std::thread::JoinHandle<R>>
where
F: FnOnce() -> R + Send,
R: 'static + Send,
{
let f: Box<dyn Send + FnOnce() -> R> = Box::new(f);
// ^ No need for `'_` inside function bodies
// v but this is more readable
let _: &Box<dyn '_ + Send + FnOnce() -> R> = &f;
// Safety: same-layout since only a lifetime difference
let f: Box<dyn 'static + Send + FnOnce() -> R> = std::mem::transmute(f);
self.spawn(f)
}
}
#[cfg(test)]
mod tests {
use super::*;