@@ -3,6 +3,8 @@ use std::fmt;
33use std:: fmt:: Formatter ;
44use std:: panic:: UnwindSafe ;
55use std:: ptr:: { self , NonNull } ;
6+ use std:: sync:: atomic:: Ordering ;
7+ use std:: sync:: Arc ;
68
79use rustc_hash:: FxHashMap ;
810use thin_vec:: ThinVec ;
@@ -39,13 +41,32 @@ pub struct ZalsaLocal {
3941 /// Stores the most recent page for a given ingredient.
4042 /// This is thread-local to avoid contention.
4143 most_recent_pages : UnsafeCell < FxHashMap < IngredientIndex , PageIndex > > ,
44+
45+ cancelled : CancellationToken ,
46+ }
47+
48+ /// A cancellation token that can be used to cancel a query computation for a specific local `Database`.
49+ #[ derive( Default , Clone , Debug ) ]
50+ pub struct CancellationToken ( Arc < AtomicBool > ) ;
51+
52+ impl CancellationToken {
53+ /// Inform the database to cancel the current query computation.
54+ pub fn cancel ( & self ) {
55+ self . 0 . store ( true , Ordering :: Relaxed ) ;
56+ }
57+
58+ /// Check if the query computation has been requested to be cancelled.
59+ pub fn is_cancelled ( & self ) -> bool {
60+ self . 0 . load ( Ordering :: Relaxed )
61+ }
4262}
4363
4464impl ZalsaLocal {
4565 pub ( crate ) fn new ( ) -> Self {
4666 ZalsaLocal {
4767 query_stack : RefCell :: new ( QueryStack :: default ( ) ) ,
4868 most_recent_pages : UnsafeCell :: new ( FxHashMap :: default ( ) ) ,
69+ cancelled : CancellationToken :: default ( ) ,
4970 }
5071 }
5172
@@ -401,12 +422,24 @@ impl ZalsaLocal {
401422 }
402423 }
403424
425+ pub ( crate ) fn cancellation_token ( & self ) -> CancellationToken {
426+ self . cancelled . clone ( )
427+ }
428+
429+ #[ inline]
430+ pub fn take_cancellation ( & self ) -> bool {
431+ self . cancelled . 0 . swap ( false , Ordering :: Relaxed )
432+ }
433+
404434 #[ cold]
405- pub ( crate ) fn unwind_cancelled ( & self , current_revision : Revision ) {
406- // Why is this reporting an untracked read? We do not store the query revisions on unwind do we?
407- self . report_untracked_read ( current_revision) ;
435+ pub ( crate ) fn unwind_pending_write ( & self ) {
408436 Cancelled :: PendingWrite . throw ( ) ;
409437 }
438+
439+ #[ cold]
440+ pub ( crate ) fn unwind_cancelled ( & self ) {
441+ Cancelled :: Cancelled . throw ( ) ;
442+ }
410443}
411444
412445// Okay to implement as `ZalsaLocal`` is !Sync
0 commit comments