@@ -136,19 +136,6 @@ pub enum CacheLockMode {
136
136
MutateExclusive ,
137
137
}
138
138
139
- /// A locker that can be used to acquire locks.
140
- ///
141
- /// See the [`crate::util::cache_lock`] module documentation for an overview
142
- /// of how cache locking works.
143
- #[ derive( Debug ) ]
144
- pub struct CacheLocker {
145
- /// The state of the locker.
146
- ///
147
- /// [`CacheLocker`] uses interior mutability because it is stuffed inside
148
- /// the global `Config`, which does not allow mutation.
149
- state : RefCell < CacheState > ,
150
- }
151
-
152
139
/// Whether or not a lock attempt should block.
153
140
#[ derive( Copy , Clone ) ]
154
141
enum BlockingMode {
@@ -371,6 +358,69 @@ struct CacheState {
371
358
mutate_lock : RecursiveLock ,
372
359
}
373
360
361
+ impl CacheState {
362
+ fn lock (
363
+ & mut self ,
364
+ config : & Config ,
365
+ mode : CacheLockMode ,
366
+ blocking : BlockingMode ,
367
+ ) -> CargoResult < LockingResult > {
368
+ use CacheLockMode :: * ;
369
+ if mode == Shared && self . cache_lock . count > 0 && self . mutate_lock . count == 0 {
370
+ // Shared lock, when a DownloadExclusive is held.
371
+ //
372
+ // This isn't supported because it could cause a deadlock. If
373
+ // one cargo is attempting to acquire a MutateExclusive lock,
374
+ // and acquires the mutate lock, but is blocked on the
375
+ // download lock, and the cargo that holds the download lock
376
+ // attempts to get a shared lock, they would end up blocking
377
+ // each other.
378
+ panic ! ( "shared lock while holding download lock is not allowed" ) ;
379
+ }
380
+ match mode {
381
+ Shared => {
382
+ if self . mutate_lock . lock_shared ( config, SHARED_DESCR , blocking) == WouldBlock {
383
+ return Ok ( WouldBlock ) ;
384
+ }
385
+ }
386
+ DownloadExclusive => {
387
+ if self
388
+ . cache_lock
389
+ . lock_exclusive ( config, DOWNLOAD_EXCLUSIVE_DESCR , blocking) ?
390
+ == WouldBlock
391
+ {
392
+ return Ok ( WouldBlock ) ;
393
+ }
394
+ }
395
+ MutateExclusive => {
396
+ if self
397
+ . mutate_lock
398
+ . lock_exclusive ( config, MUTATE_EXCLUSIVE_DESCR , blocking) ?
399
+ == WouldBlock
400
+ {
401
+ return Ok ( WouldBlock ) ;
402
+ }
403
+
404
+ // Part of the contract of MutateExclusive is that it doesn't
405
+ // allow any processes to have a lock on the package cache, so
406
+ // this acquires both locks.
407
+ match self
408
+ . cache_lock
409
+ . lock_exclusive ( config, DOWNLOAD_EXCLUSIVE_DESCR , blocking)
410
+ {
411
+ Ok ( LockAcquired ) => { }
412
+ Ok ( WouldBlock ) => return Ok ( WouldBlock ) ,
413
+ Err ( e) => {
414
+ self . mutate_lock . decrement ( ) ;
415
+ return Err ( e) ;
416
+ }
417
+ }
418
+ }
419
+ }
420
+ Ok ( LockAcquired )
421
+ }
422
+ }
423
+
374
424
/// A held lock guard.
375
425
///
376
426
/// When this is dropped, the lock will be released.
@@ -380,6 +430,25 @@ pub struct CacheLock<'lock> {
380
430
locker : & ' lock CacheLocker ,
381
431
}
382
432
433
+ impl Drop for CacheLock < ' _ > {
434
+ fn drop ( & mut self ) {
435
+ use CacheLockMode :: * ;
436
+ let mut state = self . locker . state . borrow_mut ( ) ;
437
+ match self . mode {
438
+ Shared => {
439
+ state. mutate_lock . decrement ( ) ;
440
+ }
441
+ DownloadExclusive => {
442
+ state. cache_lock . decrement ( ) ;
443
+ }
444
+ MutateExclusive => {
445
+ state. cache_lock . decrement ( ) ;
446
+ state. mutate_lock . decrement ( ) ;
447
+ }
448
+ }
449
+ }
450
+ }
451
+
383
452
/// The filename for the [`CacheLockMode::DownloadExclusive`] lock.
384
453
const CACHE_LOCK_NAME : & str = ".package-cache" ;
385
454
/// The filename for the [`CacheLockMode::MutateExclusive`] and
@@ -391,6 +460,19 @@ const SHARED_DESCR: &str = "shared package cache";
391
460
const DOWNLOAD_EXCLUSIVE_DESCR : & str = "package cache" ;
392
461
const MUTATE_EXCLUSIVE_DESCR : & str = "package cache mutation" ;
393
462
463
+ /// A locker that can be used to acquire locks.
464
+ ///
465
+ /// See the [`crate::util::cache_lock`] module documentation for an overview
466
+ /// of how cache locking works.
467
+ #[ derive( Debug ) ]
468
+ pub struct CacheLocker {
469
+ /// The state of the locker.
470
+ ///
471
+ /// [`CacheLocker`] uses interior mutability because it is stuffed inside
472
+ /// the global `Config`, which does not allow mutation.
473
+ state : RefCell < CacheState > ,
474
+ }
475
+
394
476
impl CacheLocker {
395
477
/// Creates a new `CacheLocker`.
396
478
pub fn new ( ) -> CacheLocker {
@@ -450,69 +532,6 @@ impl CacheLocker {
450
532
}
451
533
}
452
534
453
- impl CacheState {
454
- fn lock (
455
- & mut self ,
456
- config : & Config ,
457
- mode : CacheLockMode ,
458
- blocking : BlockingMode ,
459
- ) -> CargoResult < LockingResult > {
460
- use CacheLockMode :: * ;
461
- if mode == Shared && self . cache_lock . count > 0 && self . mutate_lock . count == 0 {
462
- // Shared lock, when a DownloadExclusive is held.
463
- //
464
- // This isn't supported because it could cause a deadlock. If
465
- // one cargo is attempting to acquire a MutateExclusive lock,
466
- // and acquires the mutate lock, but is blocked on the
467
- // download lock, and the cargo that holds the download lock
468
- // attempts to get a shared lock, they would end up blocking
469
- // each other.
470
- panic ! ( "shared lock while holding download lock is not allowed" ) ;
471
- }
472
- match mode {
473
- Shared => {
474
- if self . mutate_lock . lock_shared ( config, SHARED_DESCR , blocking) == WouldBlock {
475
- return Ok ( WouldBlock ) ;
476
- }
477
- }
478
- DownloadExclusive => {
479
- if self
480
- . cache_lock
481
- . lock_exclusive ( config, DOWNLOAD_EXCLUSIVE_DESCR , blocking) ?
482
- == WouldBlock
483
- {
484
- return Ok ( WouldBlock ) ;
485
- }
486
- }
487
- MutateExclusive => {
488
- if self
489
- . mutate_lock
490
- . lock_exclusive ( config, MUTATE_EXCLUSIVE_DESCR , blocking) ?
491
- == WouldBlock
492
- {
493
- return Ok ( WouldBlock ) ;
494
- }
495
-
496
- // Part of the contract of MutateExclusive is that it doesn't
497
- // allow any processes to have a lock on the package cache, so
498
- // this acquires both locks.
499
- match self
500
- . cache_lock
501
- . lock_exclusive ( config, DOWNLOAD_EXCLUSIVE_DESCR , blocking)
502
- {
503
- Ok ( LockAcquired ) => { }
504
- Ok ( WouldBlock ) => return Ok ( WouldBlock ) ,
505
- Err ( e) => {
506
- self . mutate_lock . decrement ( ) ;
507
- return Err ( e) ;
508
- }
509
- }
510
- }
511
- }
512
- Ok ( LockAcquired )
513
- }
514
- }
515
-
516
535
/// Returns whether or not the error appears to be from a read-only filesystem.
517
536
fn maybe_readonly ( err : & anyhow:: Error ) -> bool {
518
537
err. chain ( ) . any ( |err| {
@@ -528,22 +547,3 @@ fn maybe_readonly(err: &anyhow::Error) -> bool {
528
547
false
529
548
} )
530
549
}
531
-
532
- impl Drop for CacheLock < ' _ > {
533
- fn drop ( & mut self ) {
534
- use CacheLockMode :: * ;
535
- let mut state = self . locker . state . borrow_mut ( ) ;
536
- match self . mode {
537
- Shared => {
538
- state. mutate_lock . decrement ( ) ;
539
- }
540
- DownloadExclusive => {
541
- state. cache_lock . decrement ( ) ;
542
- }
543
- MutateExclusive => {
544
- state. cache_lock . decrement ( ) ;
545
- state. mutate_lock . decrement ( ) ;
546
- }
547
- }
548
- }
549
- }
0 commit comments