From cf20ecae9f9572d598c3655f1c5dae35a9f4c548 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 9 Jan 2019 22:51:05 +0300 Subject: unwind on cancel --- crates/ra_db/src/lib.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'crates/ra_db/src') diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index fb8ea2496..abe6430fb 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs @@ -5,6 +5,8 @@ mod input; mod loc2id; pub mod mock; +use std::panic; + use ra_syntax::{TextUnit, TextRange, SourceFile, TreePtr}; pub use crate::{ @@ -18,13 +20,21 @@ pub use crate::{ loc2id::LocationIntener, }; -pub trait BaseDatabase: salsa::Database { +pub trait BaseDatabase: salsa::Database + panic::RefUnwindSafe { fn check_canceled(&self) -> Cancelable<()> { - if self.salsa_runtime().is_current_revision_canceled() { - Err(Canceled::new()) - } else { - Ok(()) - } + self.salsa_runtime() + .unwind_if_current_revision_is_canceled(); + Ok(()) + } + + fn catch_canceled T + panic::UnwindSafe, T>( + &self, + f: F, + ) -> Result { + panic::catch_unwind(|| f(self)).map_err(|err| match err.downcast::() { + Ok(_) => Canceled::new(), + Err(payload) => panic::resume_unwind(payload), + }) } } -- cgit v1.2.3 From 64455ad701c8bce6e35793042f5e2ec177e12f7e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 10 Jan 2019 12:20:32 +0300 Subject: use unwinding for cancelation --- crates/ra_db/src/cancellation.rs | 4 ++++ crates/ra_db/src/lib.rs | 9 +++++---- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'crates/ra_db/src') diff --git a/crates/ra_db/src/cancellation.rs b/crates/ra_db/src/cancellation.rs index 8d38eebfb..f7077b992 100644 --- a/crates/ra_db/src/cancellation.rs +++ b/crates/ra_db/src/cancellation.rs @@ -27,6 +27,10 @@ impl Canceled { pub(crate) fn new() -> Canceled { Canceled { _private: () } } + + pub fn throw() -> ! { + std::panic::resume_unwind(Box::new(Canceled::new())) + } } impl std::fmt::Display for Canceled { diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index abe6430fb..00d2d5ae9 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs @@ -20,10 +20,10 @@ pub use crate::{ loc2id::LocationIntener, }; -pub trait BaseDatabase: salsa::Database + panic::RefUnwindSafe { +pub trait BaseDatabase: salsa::Database { fn check_canceled(&self) -> Cancelable<()> { self.salsa_runtime() - .unwind_if_current_revision_is_canceled(); + .if_current_revision_is_canceled(Canceled::throw); Ok(()) } @@ -31,8 +31,9 @@ pub trait BaseDatabase: salsa::Database + panic::RefUnwindSafe { &self, f: F, ) -> Result { - panic::catch_unwind(|| f(self)).map_err(|err| match err.downcast::() { - Ok(_) => Canceled::new(), + let me = panic::AssertUnwindSafe(self); + panic::catch_unwind(|| f(me.0)).map_err(|err| match err.downcast::() { + Ok(canceled) => *canceled, Err(payload) => panic::resume_unwind(payload), }) } -- cgit v1.2.3 From f72c031eb9a15f25834a7980008db764ff2867a0 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 10 Jan 2019 13:04:04 +0300 Subject: implement RefUnwindSafe --- crates/ra_db/src/lib.rs | 5 ++--- crates/ra_db/src/loc2id.rs | 11 ++++++++++- 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'crates/ra_db/src') diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index 00d2d5ae9..20e712afe 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs @@ -20,7 +20,7 @@ pub use crate::{ loc2id::LocationIntener, }; -pub trait BaseDatabase: salsa::Database { +pub trait BaseDatabase: salsa::Database + panic::RefUnwindSafe { fn check_canceled(&self) -> Cancelable<()> { self.salsa_runtime() .if_current_revision_is_canceled(Canceled::throw); @@ -31,8 +31,7 @@ pub trait BaseDatabase: salsa::Database { &self, f: F, ) -> Result { - let me = panic::AssertUnwindSafe(self); - panic::catch_unwind(|| f(me.0)).map_err(|err| match err.downcast::() { + panic::catch_unwind(|| f(self)).map_err(|err| match err.downcast::() { Ok(canceled) => *canceled, Err(payload) => panic::resume_unwind(payload), }) diff --git a/crates/ra_db/src/loc2id.rs b/crates/ra_db/src/loc2id.rs index 254c52629..359cd893d 100644 --- a/crates/ra_db/src/loc2id.rs +++ b/crates/ra_db/src/loc2id.rs @@ -1,4 +1,4 @@ -use std::hash::Hash; +use std::{panic, hash::Hash}; use parking_lot::Mutex; use rustc_hash::FxHashMap; @@ -70,6 +70,15 @@ where map: Mutex>, } +impl panic::RefUnwindSafe for LocationIntener +where + ID: ArenaId + Clone, + LOC: Clone + Eq + Hash, + ID: panic::RefUnwindSafe, + LOC: panic::RefUnwindSafe, +{ +} + impl Default for LocationIntener where ID: ArenaId + Clone, -- cgit v1.2.3 From 86bc898a2fa5818eac4b87714b59970023acc60f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 10 Jan 2019 13:06:42 +0300 Subject: explain why we use resume_unwind --- crates/ra_db/src/cancellation.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'crates/ra_db/src') diff --git a/crates/ra_db/src/cancellation.rs b/crates/ra_db/src/cancellation.rs index f7077b992..32a268553 100644 --- a/crates/ra_db/src/cancellation.rs +++ b/crates/ra_db/src/cancellation.rs @@ -29,6 +29,8 @@ impl Canceled { } pub fn throw() -> ! { + // We use resume and not panic here to avoid running the panic + // hook (that is, to avoid collecting and printing backtrace). std::panic::resume_unwind(Box::new(Canceled::new())) } } -- cgit v1.2.3