@@ -240,6 +240,11 @@ where
240
240
// function, to avoid multiple reentrant calls.
241
241
let mut _attempt = self . locking_attempt . lock ( ) . await ;
242
242
243
+ // The lock is already dirtied? Let's stop here.
244
+ if self . is_dirty ( ) {
245
+ return Err ( CrossProcessLockError :: LockDirtied ) ;
246
+ }
247
+
243
248
// If another thread obtained the lock, make sure to only superficially increase
244
249
// the number of holders, and carry on.
245
250
if self . num_holders . load ( Ordering :: SeqCst ) > 0 {
@@ -274,6 +279,8 @@ where
274
279
"The lock has been acquired, but it's been dirtied!"
275
280
) ;
276
281
self . is_dirty . store ( true , Ordering :: SeqCst ) ;
282
+
283
+ return Err ( CrossProcessLockError :: LockDirtied ) ;
277
284
}
278
285
279
286
// This was the same generation, no problem.
@@ -340,6 +347,11 @@ where
340
347
}
341
348
}
342
349
350
+ // The lock has been dirtied. Exit the loop.
351
+ if this. is_dirty ( ) {
352
+ break ;
353
+ }
354
+
343
355
sleep ( Duration :: from_millis ( EXTEND_LEASE_EVERY_MS ) ) . await ;
344
356
345
357
match this
@@ -459,6 +471,11 @@ pub enum CrossProcessLockError {
459
471
#[ error( "a lock timed out" ) ]
460
472
LockTimeout ,
461
473
474
+ /// The lock has been dirtied, i.e. it means another process took the lock
475
+ /// while this process was holding it.
476
+ #[ error( "a lock has been dirtied" ) ]
477
+ LockDirtied ,
478
+
462
479
#[ error( transparent) ]
463
480
#[ cfg( not( target_family = "wasm" ) ) ]
464
481
TryLockError ( #[ from] Box < dyn Error + Send + Sync > ) ,
0 commit comments