@@ -2,6 +2,7 @@ use rustc_hash::FxHashMap;
22use std:: collections:: hash_map:: OccupiedEntry ;
33
44use crate :: key:: DatabaseKeyIndex ;
5+ use crate :: plumbing:: ZalsaLocal ;
56use crate :: runtime:: {
67 BlockOnTransferredOwner , BlockResult , BlockTransferredResult , Running , WaitResult ,
78} ;
@@ -21,6 +22,8 @@ pub(crate) struct SyncTable {
2122}
2223
2324pub ( crate ) enum ClaimResult < ' a , Guard = ClaimGuard < ' a > > {
25+ /// Successfully claimed the query.
26+ Claimed ( Guard ) ,
2427 /// Can't claim the query because it is running on an other thread.
2528 Running ( Running < ' a > ) ,
2629 /// Claiming the query results in a cycle.
@@ -30,8 +33,6 @@ pub(crate) enum ClaimResult<'a, Guard = ClaimGuard<'a>> {
3033 /// [`SyncTable::try_claim`] with [`Reentrant::Allow`].
3134 inner : bool ,
3235 } ,
33- /// Successfully claimed the query.
34- Claimed ( Guard ) ,
3536}
3637
3738pub ( crate ) struct SyncState {
@@ -68,6 +69,7 @@ impl SyncTable {
6869 pub ( crate ) fn try_claim < ' me > (
6970 & ' me self ,
7071 zalsa : & ' me Zalsa ,
72+ zalsa_local : & ' me ZalsaLocal ,
7173 key_index : Id ,
7274 reentrant : Reentrancy ,
7375 ) -> ClaimResult < ' me > {
@@ -77,7 +79,12 @@ impl SyncTable {
7779 let id = match occupied_entry. get ( ) . id {
7880 SyncOwner :: Thread ( id) => id,
7981 SyncOwner :: Transferred => {
80- return match self . try_claim_transferred ( zalsa, occupied_entry, reentrant) {
82+ return match self . try_claim_transferred (
83+ zalsa,
84+ zalsa_local,
85+ occupied_entry,
86+ reentrant,
87+ ) {
8188 Ok ( claimed) => claimed,
8289 Err ( other_thread) => match other_thread. block ( write) {
8390 BlockResult :: Cycle => ClaimResult :: Cycle { inner : false } ,
@@ -115,6 +122,7 @@ impl SyncTable {
115122 ClaimResult :: Claimed ( ClaimGuard {
116123 key_index,
117124 zalsa,
125+ zalsa_local,
118126 sync_table : self ,
119127 mode : ReleaseMode :: Default ,
120128 } )
@@ -172,6 +180,7 @@ impl SyncTable {
172180 fn try_claim_transferred < ' me > (
173181 & ' me self ,
174182 zalsa : & ' me Zalsa ,
183+ zalsa_local : & ' me ZalsaLocal ,
175184 mut entry : OccupiedEntry < Id , SyncState > ,
176185 reentrant : Reentrancy ,
177186 ) -> Result < ClaimResult < ' me > , Box < BlockOnTransferredOwner < ' me > > > {
@@ -195,6 +204,7 @@ impl SyncTable {
195204 Ok ( ClaimResult :: Claimed ( ClaimGuard {
196205 key_index,
197206 zalsa,
207+ zalsa_local,
198208 sync_table : self ,
199209 mode : ReleaseMode :: SelfOnly ,
200210 } ) )
@@ -214,6 +224,7 @@ impl SyncTable {
214224 Ok ( ClaimResult :: Claimed ( ClaimGuard {
215225 key_index,
216226 zalsa,
227+ zalsa_local,
217228 sync_table : self ,
218229 mode : ReleaseMode :: Default ,
219230 } ) )
@@ -295,6 +306,7 @@ pub(crate) struct ClaimGuard<'me> {
295306 zalsa : & ' me Zalsa ,
296307 sync_table : & ' me SyncTable ,
297308 mode : ReleaseMode ,
309+ zalsa_local : & ' me ZalsaLocal ,
298310}
299311
300312impl < ' me > ClaimGuard < ' me > {
@@ -319,10 +331,21 @@ impl<'me> ClaimGuard<'me> {
319331 "Release claim on {:?} due to panic" ,
320332 self . database_key_index( )
321333 ) ;
322-
323334 self . release ( state, WaitResult :: Panicked ) ;
324335 }
325336
337+ #[ cold]
338+ #[ inline( never) ]
339+ fn release_cancelled ( & self ) {
340+ let mut syncs = self . sync_table . syncs . lock ( ) ;
341+ let state = syncs. remove ( & self . key_index ) . expect ( "key claimed twice?" ) ;
342+ tracing:: debug!(
343+ "Release claim on {:?} due to cancellation" ,
344+ self . database_key_index( )
345+ ) ;
346+ self . release ( state, WaitResult :: Cancelled ) ;
347+ }
348+
326349 #[ inline( always) ]
327350 fn release ( & self , state : SyncState , wait_result : WaitResult ) {
328351 let SyncState {
@@ -446,7 +469,11 @@ impl<'me> ClaimGuard<'me> {
446469impl Drop for ClaimGuard < ' _ > {
447470 fn drop ( & mut self ) {
448471 if thread:: panicking ( ) {
449- self . release_panicking ( ) ;
472+ if self . zalsa_local . is_cancelled ( ) {
473+ self . release_cancelled ( ) ;
474+ } else {
475+ self . release_panicking ( ) ;
476+ }
450477 return ;
451478 }
452479
0 commit comments