Sandbox: Rework several blocking actions

Several actions have been reworked to be non-blocking, as their
operation should still occur in the main thread, but should not block
the thread they are called from, as they are not required to continue
processing there.

End of secure access has also been made non-blocking, as it is usually
only called when an input is done accessing a given file or folder, so
it should be important to return quickly, as the input is likely about
to terminate, and other things are waiting for it to return.

Also remove a nested block call for the storage access, as it is within
an existing serializing block, so it shouldn't need to be nested.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
xcode15
Christopher Snowhill 2022-12-09 21:12:33 -08:00
parent 4b37ffebee
commit 1de501a64a
No known key found for this signature in database
1 changed files with 46 additions and 40 deletions

View File

@ -218,10 +218,18 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
}
}
static inline void dispatch_async_reentrant(dispatch_queue_t queue, dispatch_block_t block) {
if(dispatch_queue_get_label(queue) == dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)) {
block();
} else {
dispatch_async(queue, block);
}
}
- (void)addFolderIfMissing:(NSURL *)folderUrl {
if(![folderUrl isFileURL]) return;
dispatch_sync_reentrant(dispatch_get_main_queue(), ^{
dispatch_async_reentrant(dispatch_get_main_queue(), ^{
SandboxEntry *_entry = nil;
for(SandboxEntry *entry in self->storage) {
@ -263,7 +271,7 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
NSURL *url = [SandboxBroker urlWithoutFragment:fileUrl];
dispatch_sync_reentrant(dispatch_get_main_queue(), ^{
dispatch_async_reentrant(dispatch_get_main_queue(), ^{
SandboxEntry *_entry = nil;
for(SandboxEntry *entry in self->storage) {
@ -322,49 +330,47 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
}
if(!_entry) {
dispatch_sync_reentrant(dispatch_get_main_queue(), ^{
static BOOL warnedYet = NO;
static BOOL warnedYet = NO;
if(!warnedYet) {
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:NSLocalizedString(@"GrantPathTitle", @"Title of file dialog for granting folder access")];
[alert setInformativeText:NSLocalizedString(@"GrantPathMessage", @"Message to new users regarding file permissions")];
[alert addButtonWithTitle:NSLocalizedString(@"GrantPathOK", @"OK button text")];
[alert addButtonWithTitle:NSLocalizedString(@"GrantPathStopWarning", @"Button to stop warnings for session")];
if(!warnedYet) {
NSAlert *alert = [[NSAlert alloc] init];
[alert setMessageText:NSLocalizedString(@"GrantPathTitle", @"Title of file dialog for granting folder access")];
[alert setInformativeText:NSLocalizedString(@"GrantPathMessage", @"Message to new users regarding file permissions")];
[alert addButtonWithTitle:NSLocalizedString(@"GrantPathOK", @"OK button text")];
[alert addButtonWithTitle:NSLocalizedString(@"GrantPathStopWarning", @"Button to stop warnings for session")];
if([alert runModal] == NSAlertSecondButtonReturn) {
warnedYet = YES;
}
if([alert runModal] == NSAlertSecondButtonReturn) {
warnedYet = YES;
}
}
NSOpenPanel *panel = [NSOpenPanel openPanel];
[panel setAllowsMultipleSelection:NO];
[panel setCanChooseDirectories:YES];
[panel setCanChooseFiles:NO];
[panel setFloatingPanel:YES];
[panel setDirectoryURL:folderUrl];
[panel setTitle:NSLocalizedString(@"GrantPathTitle", @"Title of file dialog for granting folder access")];
NSInteger result = [panel runModal];
if(result == NSModalResponseOK) {
NSURL *folderUrl = [panel URL];
NSError *err = nil;
NSData *bookmark = [folderUrl bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope includingResourceValuesForKeys:nil relativeToURL:nil error:&err];
if(!bookmark && err) {
ALog(@"Failed to add bookmark for URL: %@, with error: %@", folderUrl, [err localizedDescription]);
return;
}
NSOpenPanel *panel = [NSOpenPanel openPanel];
[panel setAllowsMultipleSelection:NO];
[panel setCanChooseDirectories:YES];
[panel setCanChooseFiles:NO];
[panel setFloatingPanel:YES];
[panel setDirectoryURL:folderUrl];
[panel setTitle:NSLocalizedString(@"GrantPathTitle", @"Title of file dialog for granting folder access")];
NSInteger result = [panel runModal];
if(result == NSModalResponseOK) {
NSURL *folderUrl = [panel URL];
NSError *err = nil;
NSData *bookmark = [folderUrl bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope includingResourceValuesForKeys:nil relativeToURL:nil error:&err];
if(!bookmark && err) {
ALog(@"Failed to add bookmark for URL: %@, with error: %@", folderUrl, [err localizedDescription]);
return;
}
NSPersistentContainer *pc = [SandboxBroker sharedPersistentContainer];
NSPersistentContainer *pc = [SandboxBroker sharedPersistentContainer];
SandboxToken *token = [NSEntityDescription insertNewObjectForEntityForName:@"SandboxToken" inManagedObjectContext:pc.viewContext];
SandboxToken *token = [NSEntityDescription insertNewObjectForEntityForName:@"SandboxToken" inManagedObjectContext:pc.viewContext];
if(token) {
token.path = [folderUrl path];
token.bookmark = bookmark;
[SandboxBroker cleanupFolderAccess];
}
if(token) {
token.path = [folderUrl path];
token.bookmark = bookmark;
[SandboxBroker cleanupFolderAccess];
}
});
}
}
});
}
@ -376,7 +382,7 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"SandboxToken"];
request.sortDescriptors = @[sortDescriptor];
[pc.viewContext performBlockAndWait:^{
[pc.viewContext performBlock:^{
NSError *error = nil;
NSArray *results = [pc.viewContext executeFetchRequest:request error:&error];
NSMutableArray *resultsCopy = nil;
@ -455,7 +461,7 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
SandboxEntry *entry = CFBridgingRelease(handle);
if(!entry) return;
dispatch_sync_reentrant(dispatch_get_main_queue(), ^{
dispatch_async_reentrant(dispatch_get_main_queue(), ^{
if(entry.refCount > 1) {
entry.refCount -= 1;
} else {