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.rs38
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,