Better locking behavior for playlist storage
This should fix up potential locking issues with maintaining a copy of the results set while certain other background actions may happen, such as the player updating play counts while playing. Signed-off-by: Christopher Snowhill <kode54@gmail.com>xcode15
parent
bc7331cf8c
commit
ce723fd44e
|
@ -232,6 +232,9 @@ static AppController *kAppController = nil;
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
[playlistController.persistentContainerLock lock];
|
[playlistController.persistentContainerLock lock];
|
||||||
NSArray *results = [playlistController.persistentContainer.viewContext executeFetchRequest:request error:&error];
|
NSArray *results = [playlistController.persistentContainer.viewContext executeFetchRequest:request error:&error];
|
||||||
|
if(results) {
|
||||||
|
results = [results copy];
|
||||||
|
}
|
||||||
[playlistController.persistentContainerLock unlock];
|
[playlistController.persistentContainerLock unlock];
|
||||||
|
|
||||||
if(results && [results count] == 1) {
|
if(results && [results count] == 1) {
|
||||||
|
|
|
@ -267,18 +267,20 @@ static void *playlistControllerContext = &playlistControllerContext;
|
||||||
PlayCount *pc = pe.playCountItem;
|
PlayCount *pc = pe.playCountItem;
|
||||||
|
|
||||||
if(pc) {
|
if(pc) {
|
||||||
|
[self.persistentContainerLock lock];
|
||||||
pc.count += 1;
|
pc.count += 1;
|
||||||
pc.lastPlayed = [NSDate date];
|
pc.lastPlayed = [NSDate date];
|
||||||
|
[self.persistentContainerLock unlock];
|
||||||
} else {
|
} else {
|
||||||
[self.persistentContainerLock lock];
|
[self.persistentContainerLock lock];
|
||||||
pc = [NSEntityDescription insertNewObjectForEntityForName:@"PlayCount" inManagedObjectContext:self.persistentContainer.viewContext];
|
pc = [NSEntityDescription insertNewObjectForEntityForName:@"PlayCount" inManagedObjectContext:self.persistentContainer.viewContext];
|
||||||
[self.persistentContainerLock unlock];
|
|
||||||
pc.count = 1;
|
pc.count = 1;
|
||||||
pc.firstSeen = pc.lastPlayed = [NSDate date];
|
pc.firstSeen = pc.lastPlayed = [NSDate date];
|
||||||
pc.album = pe.album;
|
pc.album = pe.album;
|
||||||
pc.artist = pe.artist;
|
pc.artist = pe.artist;
|
||||||
pc.title = pe.title;
|
pc.title = pe.title;
|
||||||
pc.filename = pe.filenameFragment;
|
pc.filename = pe.filenameFragment;
|
||||||
|
[self.persistentContainerLock unlock];
|
||||||
}
|
}
|
||||||
|
|
||||||
[self commitPersistentStore];
|
[self commitPersistentStore];
|
||||||
|
@ -290,13 +292,13 @@ static void *playlistControllerContext = &playlistControllerContext;
|
||||||
if(!pc) {
|
if(!pc) {
|
||||||
[self.persistentContainerLock lock];
|
[self.persistentContainerLock lock];
|
||||||
pc = [NSEntityDescription insertNewObjectForEntityForName:@"PlayCount" inManagedObjectContext:self.persistentContainer.viewContext];
|
pc = [NSEntityDescription insertNewObjectForEntityForName:@"PlayCount" inManagedObjectContext:self.persistentContainer.viewContext];
|
||||||
[self.persistentContainerLock unlock];
|
|
||||||
pc.count = 0;
|
pc.count = 0;
|
||||||
pc.firstSeen = [NSDate date];
|
pc.firstSeen = [NSDate date];
|
||||||
pc.album = pe.album;
|
pc.album = pe.album;
|
||||||
pc.artist = pe.artist;
|
pc.artist = pe.artist;
|
||||||
pc.title = pe.title;
|
pc.title = pe.title;
|
||||||
pc.filename = pe.filenameFragment;
|
pc.filename = pe.filenameFragment;
|
||||||
|
[self.persistentContainerLock unlock];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,16 +309,18 @@ static void *playlistControllerContext = &playlistControllerContext;
|
||||||
if(!pc) {
|
if(!pc) {
|
||||||
[self.persistentContainerLock lock];
|
[self.persistentContainerLock lock];
|
||||||
pc = [NSEntityDescription insertNewObjectForEntityForName:@"PlayCount" inManagedObjectContext:self.persistentContainer.viewContext];
|
pc = [NSEntityDescription insertNewObjectForEntityForName:@"PlayCount" inManagedObjectContext:self.persistentContainer.viewContext];
|
||||||
[self.persistentContainerLock unlock];
|
|
||||||
pc.count = 0;
|
pc.count = 0;
|
||||||
pc.firstSeen = [NSDate date];
|
pc.firstSeen = [NSDate date];
|
||||||
pc.album = pe.album;
|
pc.album = pe.album;
|
||||||
pc.artist = pe.artist;
|
pc.artist = pe.artist;
|
||||||
pc.title = pe.title;
|
pc.title = pe.title;
|
||||||
pc.filename = pe.filenameFragment;
|
pc.filename = pe.filenameFragment;
|
||||||
|
[self.persistentContainerLock unlock];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[self.persistentContainerLock lock];
|
||||||
pc.rating = rating;
|
pc.rating = rating;
|
||||||
|
[self.persistentContainerLock unlock];
|
||||||
|
|
||||||
[self commitPersistentStore];
|
[self commitPersistentStore];
|
||||||
}
|
}
|
||||||
|
@ -1380,6 +1384,9 @@ static void *playlistControllerContext = &playlistControllerContext;
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
[self.persistentContainerLock lock];
|
[self.persistentContainerLock lock];
|
||||||
NSArray *results = [self.persistentContainer.viewContext executeFetchRequest:request error:&error];
|
NSArray *results = [self.persistentContainer.viewContext executeFetchRequest:request error:&error];
|
||||||
|
if(results) {
|
||||||
|
results = [results copy];
|
||||||
|
}
|
||||||
[self.persistentContainerLock unlock];
|
[self.persistentContainerLock unlock];
|
||||||
|
|
||||||
if(results && [results count] > 0) {
|
if(results && [results count] > 0) {
|
||||||
|
@ -1401,6 +1408,9 @@ static void *playlistControllerContext = &playlistControllerContext;
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
[self.persistentContainerLock lock];
|
[self.persistentContainerLock lock];
|
||||||
NSArray *results = [self.persistentContainer.viewContext executeFetchRequest:request error:&error];
|
NSArray *results = [self.persistentContainer.viewContext executeFetchRequest:request error:&error];
|
||||||
|
if(results) {
|
||||||
|
results = [results copy];
|
||||||
|
}
|
||||||
[self.persistentContainerLock unlock];
|
[self.persistentContainerLock unlock];
|
||||||
|
|
||||||
if(results && [results count] > 0) {
|
if(results && [results count] > 0) {
|
||||||
|
@ -1937,15 +1947,18 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)pathSuggesterEmpty {
|
- (BOOL)pathSuggesterEmpty {
|
||||||
|
BOOL rval;
|
||||||
|
|
||||||
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"SandboxToken"];
|
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"SandboxToken"];
|
||||||
|
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
[self.persistentContainerLock lock];
|
[self.persistentContainerLock lock];
|
||||||
NSArray *results = [self.persistentContainer.viewContext executeFetchRequest:request error:&error];
|
NSArray *results = [self.persistentContainer.viewContext executeFetchRequest:request error:&error];
|
||||||
|
if(!results || [results count] < 1) rval = YES;
|
||||||
|
else rval = NO;
|
||||||
[self.persistentContainerLock unlock];
|
[self.persistentContainerLock unlock];
|
||||||
|
|
||||||
if(!results || [results count] < 1) return YES;
|
return rval;
|
||||||
else return NO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -366,9 +366,9 @@ extern NSMutableDictionary<NSString *, AlbumArtwork *> *kArtworkDictionary;
|
||||||
if(![kArtworkDictionary objectForKey:imageCacheTag]) {
|
if(![kArtworkDictionary objectForKey:imageCacheTag]) {
|
||||||
[kPersistentContainerLock lock];
|
[kPersistentContainerLock lock];
|
||||||
AlbumArtwork *art = [NSEntityDescription insertNewObjectForEntityForName:@"AlbumArtwork" inManagedObjectContext:kPersistentContainer.viewContext];
|
AlbumArtwork *art = [NSEntityDescription insertNewObjectForEntityForName:@"AlbumArtwork" inManagedObjectContext:kPersistentContainer.viewContext];
|
||||||
[kPersistentContainerLock unlock];
|
|
||||||
art.artHash = imageCacheTag;
|
art.artHash = imageCacheTag;
|
||||||
art.artData = albumArtInternal;
|
art.artData = albumArtInternal;
|
||||||
|
[kPersistentContainerLock unlock];
|
||||||
|
|
||||||
[kArtworkDictionary setObject:art forKey:imageCacheTag];
|
[kArtworkDictionary setObject:art forKey:imageCacheTag];
|
||||||
}
|
}
|
||||||
|
@ -591,7 +591,6 @@ NSURL *_Nullable urlForPath(NSString *_Nullable path) {
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
[kPersistentContainerLock lock];
|
[kPersistentContainerLock lock];
|
||||||
NSArray *results = [kPersistentContainer.viewContext executeFetchRequest:request error:&error];
|
NSArray *results = [kPersistentContainer.viewContext executeFetchRequest:request error:&error];
|
||||||
[kPersistentContainerLock unlock];
|
|
||||||
|
|
||||||
if(!results || [results count] < 1) {
|
if(!results || [results count] < 1) {
|
||||||
NSPredicate *filenamePredicate = [NSPredicate predicateWithFormat:@"filename == %@", self.filenameFragment];
|
NSPredicate *filenamePredicate = [NSPredicate predicateWithFormat:@"filename == %@", self.filenameFragment];
|
||||||
|
@ -599,11 +598,14 @@ NSURL *_Nullable urlForPath(NSString *_Nullable path) {
|
||||||
request = [NSFetchRequest fetchRequestWithEntityName:@"PlayCount"];
|
request = [NSFetchRequest fetchRequestWithEntityName:@"PlayCount"];
|
||||||
request.predicate = filenamePredicate;
|
request.predicate = filenamePredicate;
|
||||||
|
|
||||||
[kPersistentContainerLock lock];
|
|
||||||
results = [kPersistentContainer.viewContext executeFetchRequest:request error:&error];
|
results = [kPersistentContainer.viewContext executeFetchRequest:request error:&error];
|
||||||
[kPersistentContainerLock unlock];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(results) {
|
||||||
|
results = [results copy];
|
||||||
|
}
|
||||||
|
[kPersistentContainerLock unlock];
|
||||||
|
|
||||||
if(!results || [results count] < 1) return nil;
|
if(!results || [results count] < 1) return nil;
|
||||||
|
|
||||||
return results[0];
|
return results[0];
|
||||||
|
|
|
@ -569,11 +569,11 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
||||||
dispatch_sync_reentrant(dispatch_get_main_queue(), ^{
|
dispatch_sync_reentrant(dispatch_get_main_queue(), ^{
|
||||||
[self->playlistController.persistentContainerLock lock];
|
[self->playlistController.persistentContainerLock lock];
|
||||||
pe = [NSEntityDescription insertNewObjectForEntityForName:@"PlaylistEntry" inManagedObjectContext:self->playlistController.persistentContainer.viewContext];
|
pe = [NSEntityDescription insertNewObjectForEntityForName:@"PlaylistEntry" inManagedObjectContext:self->playlistController.persistentContainer.viewContext];
|
||||||
[self->playlistController.persistentContainerLock unlock];
|
|
||||||
pe.url = url;
|
pe.url = url;
|
||||||
pe.index = index + i;
|
pe.index = index + i;
|
||||||
pe.rawTitle = [[url path] lastPathComponent];
|
pe.rawTitle = [[url path] lastPathComponent];
|
||||||
pe.queuePosition = -1;
|
pe.queuePosition = -1;
|
||||||
|
[self->playlistController.persistentContainerLock unlock];
|
||||||
});
|
});
|
||||||
|
|
||||||
[entries addObject:pe];
|
[entries addObject:pe];
|
||||||
|
@ -593,10 +593,10 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
||||||
dispatch_sync_reentrant(dispatch_get_main_queue(), ^{
|
dispatch_sync_reentrant(dispatch_get_main_queue(), ^{
|
||||||
[self->playlistController.persistentContainerLock lock];
|
[self->playlistController.persistentContainerLock lock];
|
||||||
pe = [NSEntityDescription insertNewObjectForEntityForName:@"PlaylistEntry" inManagedObjectContext:self->playlistController.persistentContainer.viewContext];
|
pe = [NSEntityDescription insertNewObjectForEntityForName:@"PlaylistEntry" inManagedObjectContext:self->playlistController.persistentContainer.viewContext];
|
||||||
[self->playlistController.persistentContainerLock unlock];
|
|
||||||
[pe setValuesForKeysWithDictionary:entry];
|
[pe setValuesForKeysWithDictionary:entry];
|
||||||
pe.index = index + i;
|
pe.index = index + i;
|
||||||
pe.queuePosition = -1;
|
pe.queuePosition = -1;
|
||||||
|
[self->playlistController.persistentContainerLock unlock];
|
||||||
});
|
});
|
||||||
|
|
||||||
[entries addObject:pe];
|
[entries addObject:pe];
|
||||||
|
@ -797,6 +797,9 @@ NSURL *_Nullable urlForPath(NSString *_Nullable path);
|
||||||
NSError *error;
|
NSError *error;
|
||||||
[playlistController.persistentContainerLock lock];
|
[playlistController.persistentContainerLock lock];
|
||||||
NSArray *results = [moc executeFetchRequest:request error:&error];
|
NSArray *results = [moc executeFetchRequest:request error:&error];
|
||||||
|
if(results) {
|
||||||
|
results = [results copy];
|
||||||
|
}
|
||||||
[playlistController.persistentContainerLock unlock];
|
[playlistController.persistentContainerLock unlock];
|
||||||
|
|
||||||
if(results && [results count] > 0) {
|
if(results && [results count] > 0) {
|
||||||
|
@ -926,8 +929,8 @@ NSURL *_Nullable urlForPath(NSString *_Nullable path);
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
[playlistController.persistentContainerLock lock];
|
[playlistController.persistentContainerLock lock];
|
||||||
NSArray *results = [moc executeFetchRequest:request error:&error];
|
NSArray *results = [moc executeFetchRequest:request error:&error];
|
||||||
[playlistController.persistentContainerLock unlock];
|
|
||||||
if(!results) {
|
if(!results) {
|
||||||
|
[playlistController.persistentContainerLock unlock];
|
||||||
ALog(@"Error fetching AlbumArtwork objects: %@\n%@", [error localizedDescription], [error userInfo]);
|
ALog(@"Error fetching AlbumArtwork objects: %@\n%@", [error localizedDescription], [error userInfo]);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
@ -935,6 +938,7 @@ NSURL *_Nullable urlForPath(NSString *_Nullable path);
|
||||||
for(AlbumArtwork *art in results) {
|
for(AlbumArtwork *art in results) {
|
||||||
[kArtworkDictionary setObject:art forKey:art.artHash];
|
[kArtworkDictionary setObject:art forKey:art.artHash];
|
||||||
}
|
}
|
||||||
|
[playlistController.persistentContainerLock unlock];
|
||||||
|
|
||||||
request = [NSFetchRequest fetchRequestWithEntityName:@"PlaylistEntry"];
|
request = [NSFetchRequest fetchRequestWithEntityName:@"PlaylistEntry"];
|
||||||
|
|
||||||
|
@ -944,15 +948,20 @@ NSURL *_Nullable urlForPath(NSString *_Nullable path);
|
||||||
|
|
||||||
[playlistController.persistentContainerLock lock];
|
[playlistController.persistentContainerLock lock];
|
||||||
results = [moc executeFetchRequest:request error:&error];
|
results = [moc executeFetchRequest:request error:&error];
|
||||||
[playlistController.persistentContainerLock unlock];
|
|
||||||
if(!results) {
|
if(!results) {
|
||||||
|
[playlistController.persistentContainerLock unlock];
|
||||||
ALog(@"Error fetching PlaylistEntry objects: %@\n%@", [error localizedDescription], [error userInfo]);
|
ALog(@"Error fetching PlaylistEntry objects: %@\n%@", [error localizedDescription], [error userInfo]);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
if([results count] == 0) return NO;
|
if([results count] == 0) {
|
||||||
|
[playlistController.persistentContainerLock unlock];
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
NSMutableArray *resultsCopy = [results mutableCopy];
|
NSMutableArray *resultsCopy = [results mutableCopy];
|
||||||
|
[playlistController.persistentContainerLock unlock];
|
||||||
|
|
||||||
NSMutableIndexSet *pruneSet = [[NSMutableIndexSet alloc] init];
|
NSMutableIndexSet *pruneSet = [[NSMutableIndexSet alloc] init];
|
||||||
NSUInteger index = 0;
|
NSUInteger index = 0;
|
||||||
for(PlaylistEntry *pe in resultsCopy) {
|
for(PlaylistEntry *pe in resultsCopy) {
|
||||||
|
|
|
@ -69,6 +69,9 @@
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
[lock lock];
|
[lock lock];
|
||||||
NSArray *results = [pc.viewContext executeFetchRequest:request error:&error];
|
NSArray *results = [pc.viewContext executeFetchRequest:request error:&error];
|
||||||
|
if(results) {
|
||||||
|
results = [results copy];
|
||||||
|
}
|
||||||
[lock unlock];
|
[lock unlock];
|
||||||
|
|
||||||
if(!results || [results count] < 1) return;
|
if(!results || [results count] < 1) return;
|
||||||
|
|
|
@ -44,6 +44,9 @@
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
[lock lock];
|
[lock lock];
|
||||||
NSArray *results = [pc.viewContext executeFetchRequest:request error:&error];
|
NSArray *results = [pc.viewContext executeFetchRequest:request error:&error];
|
||||||
|
if(results) {
|
||||||
|
results = [results copy];
|
||||||
|
}
|
||||||
[lock unlock];
|
[lock unlock];
|
||||||
|
|
||||||
if(results && [results count] > 0) {
|
if(results && [results count] > 0) {
|
||||||
|
@ -69,12 +72,10 @@
|
||||||
|
|
||||||
[lock lock];
|
[lock lock];
|
||||||
SandboxToken *token = [NSEntityDescription insertNewObjectForEntityForName:@"SandboxToken" inManagedObjectContext:pc.viewContext];
|
SandboxToken *token = [NSEntityDescription insertNewObjectForEntityForName:@"SandboxToken" inManagedObjectContext:pc.viewContext];
|
||||||
[lock unlock];
|
|
||||||
|
|
||||||
if(token) {
|
if(token) {
|
||||||
token.path = [url path];
|
token.path = [url path];
|
||||||
token.bookmark = bookmark;
|
token.bookmark = bookmark;
|
||||||
[lock lock];
|
|
||||||
[pc.viewContext save:&err];
|
[pc.viewContext save:&err];
|
||||||
[lock unlock];
|
[lock unlock];
|
||||||
if(err) {
|
if(err) {
|
||||||
|
@ -84,6 +85,8 @@
|
||||||
[NSClassFromString(@"SandboxBroker") cleanupFolderAccess];
|
[NSClassFromString(@"SandboxBroker") cleanupFolderAccess];
|
||||||
[self refresh];
|
[self refresh];
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
[lock unlock];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,6 @@ extern NSPersistentContainer *kPersistentContainer;
|
||||||
+ (PlaylistEntry *)playlistEntryWithMetadataItem:(NSMetadataItem *)metadataItem {
|
+ (PlaylistEntry *)playlistEntryWithMetadataItem:(NSMetadataItem *)metadataItem {
|
||||||
[kPersistentContainerLock lock];
|
[kPersistentContainerLock lock];
|
||||||
PlaylistEntry *entry = [NSEntityDescription insertNewObjectForEntityForName:@"PlaylistEntry" inManagedObjectContext:kPersistentContainer.viewContext];
|
PlaylistEntry *entry = [NSEntityDescription insertNewObjectForEntityForName:@"PlaylistEntry" inManagedObjectContext:kPersistentContainer.viewContext];
|
||||||
[kPersistentContainerLock unlock];
|
|
||||||
|
|
||||||
entry.deLeted = YES;
|
entry.deLeted = YES;
|
||||||
|
|
||||||
|
@ -85,6 +84,7 @@ extern NSPersistentContainer *kPersistentContainer;
|
||||||
entry.url = url;
|
entry.url = url;
|
||||||
|
|
||||||
[entry setMetadata:dict];
|
[entry setMetadata:dict];
|
||||||
|
[kPersistentContainerLock unlock];
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1446,12 +1446,12 @@ static SQLiteStore *g_sharedStore = nil;
|
||||||
- (PlaylistEntry *_Nonnull)getTrack:(int64_t)trackId {
|
- (PlaylistEntry *_Nonnull)getTrack:(int64_t)trackId {
|
||||||
[kPersistentContainerLock lock];
|
[kPersistentContainerLock lock];
|
||||||
PlaylistEntry *entry = [NSEntityDescription insertNewObjectForEntityForName:@"PlaylistEntry" inManagedObjectContext:kPersistentContainer.viewContext];
|
PlaylistEntry *entry = [NSEntityDescription insertNewObjectForEntityForName:@"PlaylistEntry" inManagedObjectContext:kPersistentContainer.viewContext];
|
||||||
[kPersistentContainerLock unlock];
|
|
||||||
|
|
||||||
if(trackId < 0) {
|
if(trackId < 0) {
|
||||||
entry.error = YES;
|
entry.error = YES;
|
||||||
entry.errorMessage = NSLocalizedString(@"ErrorInvalidTrackId", @"");
|
entry.errorMessage = NSLocalizedString(@"ErrorInvalidTrackId", @"");
|
||||||
entry.deLeted = YES;
|
entry.deLeted = YES;
|
||||||
|
[kPersistentContainerLock unlock];
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1462,6 +1462,7 @@ static SQLiteStore *g_sharedStore = nil;
|
||||||
entry.error = YES;
|
entry.error = YES;
|
||||||
entry.errorMessage = NSLocalizedString(@"ErrorSqliteProblem", @"");
|
entry.errorMessage = NSLocalizedString(@"ErrorSqliteProblem", @"");
|
||||||
entry.deLeted = YES;
|
entry.deLeted = YES;
|
||||||
|
[kPersistentContainerLock unlock];
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1472,6 +1473,7 @@ static SQLiteStore *g_sharedStore = nil;
|
||||||
entry.error = YES;
|
entry.error = YES;
|
||||||
entry.errorMessage = NSLocalizedString(@"ErrorSqliteProblem", @"");
|
entry.errorMessage = NSLocalizedString(@"ErrorSqliteProblem", @"");
|
||||||
entry.deLeted = YES;
|
entry.deLeted = YES;
|
||||||
|
[kPersistentContainerLock unlock];
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1547,6 +1549,7 @@ static SQLiteStore *g_sharedStore = nil;
|
||||||
entry.errorMessage = NSLocalizedString(@"ErrorTrackMissing", @"");
|
entry.errorMessage = NSLocalizedString(@"ErrorTrackMissing", @"");
|
||||||
entry.deLeted = YES;
|
entry.deLeted = YES;
|
||||||
}
|
}
|
||||||
|
[kPersistentContainerLock unlock];
|
||||||
|
|
||||||
sqlite3_reset(st);
|
sqlite3_reset(st);
|
||||||
|
|
||||||
|
@ -1863,8 +1866,10 @@ static SQLiteStore *g_sharedStore = nil;
|
||||||
int64_t entryId = sqlite3_column_int64(st, select_playlist_out_entry_id);
|
int64_t entryId = sqlite3_column_int64(st, select_playlist_out_entry_id);
|
||||||
entry = [self getTrack:trackId];
|
entry = [self getTrack:trackId];
|
||||||
if(!entry.deLeted && !entry.error) {
|
if(!entry.deLeted && !entry.error) {
|
||||||
|
[kPersistentContainerLock lock];
|
||||||
entry.index = index;
|
entry.index = index;
|
||||||
entry.entryId = entryId;
|
entry.entryId = entryId;
|
||||||
|
[kPersistentContainerLock unlock];
|
||||||
} else {
|
} else {
|
||||||
[kPersistentContainerLock lock];
|
[kPersistentContainerLock lock];
|
||||||
[kPersistentContainer.viewContext deleteObject:entry];
|
[kPersistentContainer.viewContext deleteObject:entry];
|
||||||
|
|
|
@ -166,6 +166,9 @@ static SandboxBroker *kSharedSandboxBroker = nil;
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
[lock lock];
|
[lock lock];
|
||||||
NSArray *results = [pc.viewContext executeFetchRequest:request error:&error];
|
NSArray *results = [pc.viewContext executeFetchRequest:request error:&error];
|
||||||
|
if(results) {
|
||||||
|
results = [results copy];
|
||||||
|
}
|
||||||
[lock unlock];
|
[lock unlock];
|
||||||
if(results && [results count] > 0) {
|
if(results && [results count] > 0) {
|
||||||
ret = [[SandboxEntry alloc] initWithToken:results[0]];
|
ret = [[SandboxEntry alloc] initWithToken:results[0]];
|
||||||
|
@ -183,6 +186,9 @@ static SandboxBroker *kSharedSandboxBroker = nil;
|
||||||
error = nil;
|
error = nil;
|
||||||
[lock lock];
|
[lock lock];
|
||||||
results = [pc.viewContext executeFetchRequest:request error:&error];
|
results = [pc.viewContext executeFetchRequest:request error:&error];
|
||||||
|
if(results) {
|
||||||
|
results = [results copy];
|
||||||
|
}
|
||||||
[lock unlock];
|
[lock unlock];
|
||||||
|
|
||||||
if(results && [results count] > 0) {
|
if(results && [results count] > 0) {
|
||||||
|
@ -253,12 +259,14 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
||||||
|
|
||||||
[lock lock];
|
[lock lock];
|
||||||
SandboxToken *token = [NSEntityDescription insertNewObjectForEntityForName:@"SandboxToken" inManagedObjectContext:pc.viewContext];
|
SandboxToken *token = [NSEntityDescription insertNewObjectForEntityForName:@"SandboxToken" inManagedObjectContext:pc.viewContext];
|
||||||
[lock unlock];
|
|
||||||
|
|
||||||
if(token) {
|
if(token) {
|
||||||
token.path = [folderUrl path];
|
token.path = [folderUrl path];
|
||||||
token.bookmark = bookmark;
|
token.bookmark = bookmark;
|
||||||
|
[lock unlock];
|
||||||
[SandboxBroker cleanupFolderAccess];
|
[SandboxBroker cleanupFolderAccess];
|
||||||
|
} else {
|
||||||
|
[lock unlock];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -301,13 +309,13 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
||||||
dispatch_sync_reentrant(dispatch_get_main_queue(), ^{
|
dispatch_sync_reentrant(dispatch_get_main_queue(), ^{
|
||||||
[lock lock];
|
[lock lock];
|
||||||
SandboxToken *token = [NSEntityDescription insertNewObjectForEntityForName:@"SandboxToken" inManagedObjectContext:pc.viewContext];
|
SandboxToken *token = [NSEntityDescription insertNewObjectForEntityForName:@"SandboxToken" inManagedObjectContext:pc.viewContext];
|
||||||
[lock unlock];
|
|
||||||
|
|
||||||
if(token) {
|
if(token) {
|
||||||
token.path = [url path];
|
token.path = [url path];
|
||||||
token.bookmark = bookmark;
|
token.bookmark = bookmark;
|
||||||
token.folder = NO;
|
token.folder = NO;
|
||||||
}
|
}
|
||||||
|
[lock unlock];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -369,12 +377,14 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
||||||
|
|
||||||
[lock lock];
|
[lock lock];
|
||||||
SandboxToken *token = [NSEntityDescription insertNewObjectForEntityForName:@"SandboxToken" inManagedObjectContext:pc.viewContext];
|
SandboxToken *token = [NSEntityDescription insertNewObjectForEntityForName:@"SandboxToken" inManagedObjectContext:pc.viewContext];
|
||||||
[lock unlock];
|
|
||||||
|
|
||||||
if(token) {
|
if(token) {
|
||||||
token.path = [folderUrl path];
|
token.path = [folderUrl path];
|
||||||
token.bookmark = bookmark;
|
token.bookmark = bookmark;
|
||||||
|
[lock unlock];
|
||||||
[SandboxBroker cleanupFolderAccess];
|
[SandboxBroker cleanupFolderAccess];
|
||||||
|
} else {
|
||||||
|
[lock unlock];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -391,14 +401,17 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
||||||
request.sortDescriptors = @[sortDescriptor];
|
request.sortDescriptors = @[sortDescriptor];
|
||||||
|
|
||||||
NSError *error = nil;
|
NSError *error = nil;
|
||||||
|
NSMutableArray *resultsCopy = nil;
|
||||||
[lock lock];
|
[lock lock];
|
||||||
NSArray *results = [pc.viewContext executeFetchRequest:request error:&error];
|
NSArray *results = [pc.viewContext executeFetchRequest:request error:&error];
|
||||||
|
if(results) {
|
||||||
|
resultsCopy = [results mutableCopy];
|
||||||
|
}
|
||||||
[lock unlock];
|
[lock unlock];
|
||||||
|
|
||||||
BOOL isUpdated = NO;
|
BOOL isUpdated = NO;
|
||||||
|
|
||||||
if(results && [results count]) {
|
if(resultsCopy && [resultsCopy count]) {
|
||||||
NSMutableArray *resultsCopy = [results mutableCopy];
|
|
||||||
for(NSUInteger i = 0; i < [resultsCopy count] - 1; ++i) {
|
for(NSUInteger i = 0; i < [resultsCopy count] - 1; ++i) {
|
||||||
SandboxToken *token = resultsCopy[i];
|
SandboxToken *token = resultsCopy[i];
|
||||||
NSURL *url = [NSURL fileURLWithPath:token.path];
|
NSURL *url = [NSURL fileURLWithPath:token.path];
|
||||||
|
|
Loading…
Reference in New Issue