Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/span/src/map.rs')
| -rw-r--r-- | crates/span/src/map.rs | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/crates/span/src/map.rs b/crates/span/src/map.rs index bb09933536..d14c497474 100644 --- a/crates/span/src/map.rs +++ b/crates/span/src/map.rs @@ -156,6 +156,44 @@ where } } +#[cfg(not(no_salsa_async_drops))] +impl<S> Drop for SpanMap<S> { + fn drop(&mut self) { + struct SendPtr(*mut [()]); + unsafe impl Send for SendPtr {} + static SPAN_MAP_DROP_THREAD: std::sync::OnceLock< + std::sync::mpsc::Sender<(SendPtr, fn(SendPtr))>, + > = std::sync::OnceLock::new(); + SPAN_MAP_DROP_THREAD + .get_or_init(|| { + let (sender, receiver) = std::sync::mpsc::channel::<(SendPtr, fn(SendPtr))>(); + std::thread::Builder::new() + .name("SpanMapDropper".to_owned()) + .spawn(move || receiver.iter().for_each(|(b, drop)| drop(b))) + .unwrap(); + sender + }) + .send(( + unsafe { + SendPtr(std::mem::transmute::<*mut [(TextSize, SpanData<S>)], *mut [()]>( + Box::<[(TextSize, SpanData<S>)]>::into_raw( + std::mem::take(&mut self.spans).into_boxed_slice(), + ), + )) + }, + |b: SendPtr| { + _ = unsafe { + Box::from_raw(std::mem::transmute::< + *mut [()], + *mut [(TextSize, SpanData<S>)], + >(b.0)) + } + }, + )) + .unwrap(); + } +} + #[derive(PartialEq, Eq, Hash, Debug)] pub struct RealSpanMap { file_id: EditionedFileId, |