Use a custom .spawn_unchecked without nightly req
Courtesy of Yandros on the Rust Discord.
This commit is contained in:
parent
9c93414d9c
commit
98076ff792
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
25
src/util.rs
25
src/util.rs
|
@ -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::*;
|
||||
|
|
Loading…
Reference in a new issue