@@ -91,8 +91,8 @@ use super::FileLock;
91
91
use crate :: CargoResult ;
92
92
use crate :: GlobalContext ;
93
93
use anyhow:: Context as _;
94
- use std:: cell:: RefCell ;
95
94
use std:: io;
95
+ use std:: sync:: Mutex ;
96
96
97
97
/// The style of lock to acquire.
98
98
#[ derive( Copy , Clone , Debug , PartialEq ) ]
@@ -435,7 +435,11 @@ pub struct CacheLock<'lock> {
435
435
impl Drop for CacheLock < ' _ > {
436
436
fn drop ( & mut self ) {
437
437
use CacheLockMode :: * ;
438
- let mut state = self . locker . state . borrow_mut ( ) ;
438
+ let mut state = match self . locker . state . lock ( ) {
439
+ Ok ( result) => result,
440
+ // we should release the cache even if a thread panicked while holding a lock
441
+ Err ( poison) => poison. into_inner ( ) ,
442
+ } ;
439
443
match self . mode {
440
444
Shared => {
441
445
state. mutate_lock . decrement ( ) ;
@@ -472,24 +476,25 @@ pub struct CacheLocker {
472
476
///
473
477
/// [`CacheLocker`] uses interior mutability because it is stuffed inside
474
478
/// [`GlobalContext`], which does not allow mutation.
475
- state : RefCell < CacheState > ,
479
+ state : Mutex < CacheState > ,
476
480
}
477
481
478
482
impl CacheLocker {
479
483
/// Creates a new `CacheLocker`.
480
484
pub fn new ( ) -> CacheLocker {
481
485
CacheLocker {
482
- state : RefCell :: new ( CacheState {
486
+ state : CacheState {
483
487
cache_lock : RecursiveLock :: new ( CACHE_LOCK_NAME ) ,
484
488
mutate_lock : RecursiveLock :: new ( MUTATE_NAME ) ,
485
- } ) ,
489
+ }
490
+ . into ( ) ,
486
491
}
487
492
}
488
493
489
494
/// Acquires a lock with the given mode, possibly blocking if another
490
495
/// cargo is holding the lock.
491
496
pub fn lock ( & self , gctx : & GlobalContext , mode : CacheLockMode ) -> CargoResult < CacheLock < ' _ > > {
492
- let mut state = self . state . borrow_mut ( ) ;
497
+ let mut state = self . state . lock ( ) . unwrap ( ) ;
493
498
let _ = state. lock ( gctx, mode, Blocking ) ?;
494
499
Ok ( CacheLock { mode, locker : self } )
495
500
}
@@ -501,7 +506,7 @@ impl CacheLocker {
501
506
gctx : & GlobalContext ,
502
507
mode : CacheLockMode ,
503
508
) -> CargoResult < Option < CacheLock < ' _ > > > {
504
- let mut state = self . state . borrow_mut ( ) ;
509
+ let mut state = self . state . lock ( ) . unwrap ( ) ;
505
510
if state. lock ( gctx, mode, NonBlocking ) ? == LockAcquired {
506
511
Ok ( Some ( CacheLock { mode, locker : self } ) )
507
512
} else {
@@ -519,7 +524,7 @@ impl CacheLocker {
519
524
/// `DownloadExclusive` will return true if a `MutateExclusive` lock is
520
525
/// held since they overlap.
521
526
pub fn is_locked ( & self , mode : CacheLockMode ) -> bool {
522
- let state = self . state . borrow ( ) ;
527
+ let state = self . state . lock ( ) . unwrap ( ) ;
523
528
match (
524
529
mode,
525
530
state. cache_lock . count ,
0 commit comments