@@ -59,7 +59,9 @@ @interface PINDiskCache () {
59
59
@property (strong , nonatomic ) NSURL *cacheURL;
60
60
@property (strong , nonatomic ) PINOperationQueue *operationQueue;
61
61
@property (strong , nonatomic ) NSMutableDictionary <NSString *, PINDiskCacheMetadata *> *metadata;
62
+ @property (assign , nonatomic ) pthread_cond_t diskWritableCondition;
62
63
@property (assign , nonatomic ) BOOL diskWritable;
64
+ @property (assign , nonatomic ) pthread_cond_t diskStateKnownCondition;
63
65
@property (assign , nonatomic ) BOOL diskStateKnown;
64
66
@end
65
67
@@ -203,6 +205,9 @@ - (instancetype)initWithName:(NSString *)name
203
205
} else {
204
206
_keyDecoder = self.defaultKeyDecoder ;
205
207
}
208
+
209
+ pthread_cond_init (&_diskWritableCondition, NULL );
210
+ pthread_cond_init (&_diskStateKnownCondition, NULL );
206
211
207
212
// we don't want to do anything without setting up the disk cache, but we also don't want to block init, it can take a while to initialize. This must *not* be done on _operationQueue because other operations added may hold the lock and fill up the queue.
208
213
dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
@@ -422,22 +427,24 @@ + (void)emptyTrash
422
427
423
428
- (BOOL )_locked_createCacheDirectory
424
429
{
425
- if ([[NSFileManager defaultManager ] fileExistsAtPath: [_cacheURL path ]]) {
426
- _diskWritable = YES ;
427
- return NO ;
430
+ BOOL created = NO ;
431
+ if ([[NSFileManager defaultManager ] fileExistsAtPath: [_cacheURL path ]] == NO ) {
432
+ NSError *error = nil ;
433
+ BOOL success = [[NSFileManager defaultManager ] createDirectoryAtURL: _cacheURL
434
+ withIntermediateDirectories: YES
435
+ attributes: nil
436
+ error: &error];
437
+ PINDiskCacheError (error);
438
+ created = success;
428
439
}
429
440
430
- NSError *error = nil ;
431
- BOOL success = [[NSFileManager defaultManager ] createDirectoryAtURL: _cacheURL
432
- withIntermediateDirectories: YES
433
- attributes: nil
434
- error: &error];
435
- PINDiskCacheError (error);
441
+
436
442
437
443
// while this may not be true if success is false, it's better than deadlocking later.
438
444
_diskWritable = YES ;
445
+ pthread_cond_broadcast (&_diskWritableCondition);
439
446
440
- return success ;
447
+ return created ;
441
448
}
442
449
443
450
- (void )initializeDiskProperties
@@ -490,6 +497,7 @@ - (void)initializeDiskProperties
490
497
[self trimToSizeByDateAsync: self ->_byteLimit completion: nil ];
491
498
492
499
_diskStateKnown = YES ;
500
+ pthread_cond_broadcast (&_diskStateKnownCondition);
493
501
[self unlock ];
494
502
}
495
503
@@ -1436,31 +1444,21 @@ - (void)setWritingProtectionOption:(NSDataWritingOptions)writingProtectionOption
1436
1444
1437
1445
- (void )lockUntilWritable
1438
1446
{
1439
- __unused int result = pthread_mutex_lock (&_mutex);
1440
- NSAssert (result == 0 , @" Failed to lock PINDiskCache %@ . Code: %d " , self, result);
1447
+ [self lock ];
1441
1448
1442
1449
// spinlock if the disk isn't writable
1443
- while (_diskWritable == NO ) {
1444
- [self unlock ];
1445
- usleep (100 );
1446
-
1447
- __unused int result = pthread_mutex_lock (&_mutex);
1448
- NSAssert (result == 0 , @" Failed to lock PINDiskCache %@ . Code: %d " , self, result);
1450
+ if (_diskWritable == NO ) {
1451
+ pthread_cond_wait (&_diskWritableCondition, &_mutex);
1449
1452
}
1450
1453
}
1451
1454
1452
1455
- (void )lockUntilDiskStateKnown
1453
1456
{
1454
- __unused int result = pthread_mutex_lock (&_mutex);
1455
- NSAssert (result == 0 , @" Failed to lock PINDiskCache %@ . Code: %d " , self, result);
1457
+ [self lock ];
1456
1458
1457
1459
// spinlock if the disk state isn't known
1458
- while (_diskStateKnown == NO ) {
1459
- [self unlock ];
1460
- usleep (100 );
1461
-
1462
- __unused int result = pthread_mutex_lock (&_mutex);
1463
- NSAssert (result == 0 , @" Failed to lock PINDiskCache %@ . Code: %d " , self, result);
1460
+ if (_diskStateKnown == NO ) {
1461
+ pthread_cond_wait (&_diskStateKnownCondition, &_mutex);
1464
1462
}
1465
1463
}
1466
1464
0 commit comments