New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Small catalog fixes #1232
Small catalog fixes #1232
Conversation
NSTableViewDataSource methods are never called since QSCatalogPrefPane is an NSOutlineViewDataSource
… in the prefs Also: * Use GCD and get rid of the scanForcedInThread: method This may conflict with quicksilver#1143 slightly
It would have taken me much, much longer and wouldn't have been nearly as clever. :-) Looks good. I'll run it for a while. |
It looks like |
Now here's a crash report for you. I saw this when testing this branch, but that could be coincidence.
Looking at the code, I don't see how this is possible. Wouldn't the array itself have to contain |
I think the problem is multi-threading maybe?! :) I've added an @synchronized() around the block in question, so that might fix it. Also, it seems like |
There are now also a couple of commits that add most of what @tiennou changed in #1143. The changes are:
Thoughts? |
I thought QSLibrarian was nothing more than the aggregated result of all the various catalog scanners, so it doesn't seem out of the question that it should manage/co-ordinate catalog entry scans. But that doesn't mean it needs to. You understand it better than I do, so I'll trust your conclusion. I've been running with this for a while and had no problems. I'll test it out a bit more, but most likely merge it tomorrow. |
My point about not using QSLibrarian to control scanning was that each QSCatalogEntry is independent, and say the catalog entry for iTunes songs can quite happily be scanning at the same time as say… your Safari bookmarks catalog entry. If we blocked things in QSLibrarian it would make scanning a completely serial process, and a bit slow. The only time QSLibrarian needs to 'block' anything is when it's writing the catalog… although having said that, I actually don't think it needs to at all. It'd still be good if @tiennou had a few seconds to chime in on my previous comments before Rob's merge finger gets fired up ;-) |
OK, I guess I misunderstood how it works. I thought by adding to a queue, you're just piling up things that need to be done, and GCD automatically decides how to do them (possibly concurrently). |
When creating a queue, you decide how you want it to behave (serial or concurrent). 10.6 only supports serial queues (Etienne used 10.7+ methods, hence why one of my changes from Etienne's code (above) is "don't use 10.7+ only methods") |
Well, then I think your approach is correct. I'll leave this open for a while to see if Etienne has anything to say. |
Tadaaa ! ;-).
The only thing I don't get is that we were trying to kill mutated-while-being-enumerated exceptions right ? Thrown by QSLibrarian when one of the catalog scanners changed its contents while it was writing that data ? So now I don't get how you can fix those without making scanning completely serial (or at most concurrent with a write barrier which is sadly 10.7+) or putting back Also, I'm wondering about Other than that, I don't see anything wrong in the diff, it's just that this scanning process looks messier to me than it should be (which is why I'd tried to bring it back all under QSLibrarian so that it would be easier on the brain). |
Thanks for chiming in Etienne. I'll have more of a think about the mutated-while-being-enumerated exceptions, but does
I don't really know what Here's some fuel for thought, and the strangeness of blocks… Try running this app: Or, to save you the time, you'll notice that the FIRST enumeration block runs fine, eventhough the array is mutated whilst being enumerated. //
// main.m
// EnumerateMutate
//
// Created by Patrick on 05/12/2012.
// Copyright (c) 2012 Patrick Robertson. All rights reserved.
//
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
@autoreleasepool {
__block NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"a", @"b", @"c", @"d", @"e", @"f", @"g", @"h", @"i", @"j", @"k", @"l", @"m", @"n", @"o", @"p", @"q", @"r", @"s", @"t", @"u", @"v", @"w", @"x", @"y", @"z", nil];
NSIndexSet *ind = [arr indexesOfObjectsWithOptions:NSEnumerationConcurrent passingTest:^BOOL(NSString *s, NSUInteger idx, BOOL *stop) {
if ([s isEqualToString:@"d"]) {
[arr removeAllObjects];
}
return [s isEqualToString:@"o"];
}];
NSLog(@"passed test 1");
arr = [NSMutableArray arrayWithObjects:@"a", @"b", @"c", @"d", @"e", @"f", @"g", @"h", @"i", @"j", @"k", @"l", @"m", @"n", @"o", @"p", @"q", @"r", @"s", @"t", @"u", @"v", @"w", @"x", @"y", @"z", nil];
NSIndexSet *ind2 = [arr indexesOfObjectsPassingTest:^BOOL(NSString *s, NSUInteger idx, BOOL *stop) {
if ([s isEqualToString:@"d"]) {
[arr removeAllObjects];
}
return [s isEqualToString:@"o"];
}];
NSLog(@"passed test 2");
arr = [NSMutableArray arrayWithObjects:@"a", @"b", @"c", @"d", @"e", @"f", @"g", @"h", @"i", @"j", @"k", @"l", @"m", @"n", @"o", @"p", @"q", @"r", @"s", @"t", @"u", @"v", @"w", @"x", @"y", @"z", nil];
NSUInteger newCount = [arr count];
for (NSString *s in arr) {
if ([s isEqualToString:@"d"]) {
[arr removeAllObjects];
}
if ([s isEqualToString:@"o"]) {
NSLog(@"%@",s);
}
}
NSLog(@"passed test 3");
// insert code here...
}
return 0;
} |
OK, to answer @tiennou's discussion of I'm working on adding serial dispatch queues to each catalog entry as we speak, a commit will be up in a few mins |
This is a general rework of the changes already mentioned in quicksilver#1232. Serial dispatch queues have now been introduced to each Catalog entry. In essence, this means that each catalog entry is responsible for scanning in a serial (single thread) manner, as opposed to trying to get QSLibrarian to do it.
OK, another few commits pushed. See the commits for info. One other change not mentioned in the commit is that I've made |
…e iVar within a block, the __block is unrequired
Rob slyly got me to do this… :P
Disabling/enabling an item in the catalog prefs then restarting QS wouldn't make the change stick.
This pull fixes that, along with a few other cleanups and GCD