Replace spawn_unchecked with static lifetimes
These things don't need to hold references, so this gets rid of some nasty c ode.
This commit is contained in:
parent
1e77a92285
commit
1f2029ecbe
|
@ -90,14 +90,15 @@ pub trait GuiContext {
|
|||
/// thread.
|
||||
///
|
||||
/// This is never used generically, but having this as a trait will cause any missing functions on
|
||||
/// an implementation to show up as compiler errors even when using a different platform.
|
||||
/// an implementation to show up as compiler errors even when using a different platform. And since
|
||||
/// the tasks and executor will be sent to a thread, they need to have static lifetimes.
|
||||
///
|
||||
/// TODO: At some point rethink the design to make it possible to have a singleton message queue for
|
||||
/// all instances of a plugin.
|
||||
pub(crate) trait EventLoop<T, E>
|
||||
where
|
||||
T: Send,
|
||||
E: MainThreadExecutor<T>,
|
||||
T: Send + 'static,
|
||||
E: MainThreadExecutor<T> + 'static,
|
||||
{
|
||||
/// Create and start a new event loop. The thread this is called on will be designated as the
|
||||
/// main thread, so this should be called when constructing the wrapper.
|
||||
|
|
|
@ -24,7 +24,6 @@ use std::thread::{self, JoinHandle, ThreadId};
|
|||
|
||||
use super::{EventLoop, MainThreadExecutor};
|
||||
use crate::nih_log;
|
||||
use crate::util::ThreadSpawnUnchecked;
|
||||
|
||||
/// See [super::EventLoop].
|
||||
pub(crate) struct LinuxEventLoop<T, E> {
|
||||
|
@ -56,8 +55,8 @@ enum Message<T> {
|
|||
|
||||
impl<T, E> EventLoop<T, E> for LinuxEventLoop<T, E>
|
||||
where
|
||||
T: Send,
|
||||
E: MainThreadExecutor<T>,
|
||||
T: Send + 'static,
|
||||
E: MainThreadExecutor<T> + 'static,
|
||||
{
|
||||
fn new_and_spawn(executor: Weak<E>) -> Self {
|
||||
let (sender, receiver) = channel::bounded(super::TASK_QUEUE_CAPACITY);
|
||||
|
@ -66,17 +65,12 @@ where
|
|||
executor: executor.clone(),
|
||||
main_thread_id: thread::current().id(),
|
||||
// With our drop implementation we guarentee that this thread never outlives this struct
|
||||
worker_thread: Some(unsafe {
|
||||
worker_thread: Some(
|
||||
thread::Builder::new()
|
||||
.name(String::from("worker"))
|
||||
// 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")
|
||||
}),
|
||||
.spawn(move || worker_thread(receiver, executor))
|
||||
.expect("Could not spawn worker thread"),
|
||||
),
|
||||
worker_thread_channel: sender,
|
||||
}
|
||||
}
|
||||
|
|
22
src/util.rs
22
src/util.rs
|
@ -41,28 +41,6 @@ pub fn midi_note_to_freq(pitch: u8) -> f32 {
|
|||
2.0f32.powf((pitch as f32 - 69.0) / 12.0) * 440.0
|
||||
}
|
||||
|
||||
/// 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 '_ + FnOnce() -> R + Send> = Box::new(f);
|
||||
// SAFETY: same-layout since only a lifetime difference
|
||||
let f: Box<dyn 'static + FnOnce() -> R + Send> = std::mem::transmute(f);
|
||||
self.spawn(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
Loading…
Reference in a new issue