adium/adium

Fix two issues in the log viewer:
adium-1.5.2
2012-06-20, Thijs Alkemade
82f8f5b935a4
Fix two issues in the log viewer:

- Fix a race condition between the flushing and releasing of the index when the window is closed and the flushing by the indexer, by making sure -_cleanDirtyLogs retains its index and enters the closing group. This caused a crash.
- Fix an issue where _remainingLogs gets out of sync with the number of logs still in localLogSet when the log fails to parse. This caused an infinite loop and stopped the indexing from ever finishing.


Fixes #15984
--- a/Source/AILoggerPlugin.m Wed Jun 20 22:55:37 2012 +0200
+++ b/Source/AILoggerPlugin.m Wed Jun 20 23:24:21 2012 +0200
@@ -1440,10 +1440,13 @@
return;
}
+ CFRetain(searchIndex);
+
// logsIndexed = 0;
OSAtomicCompareAndSwap64Barrier(logsIndexed, 0, (int64_t*)&logsIndexed);
if (self.indexingAllowed) {
+
self.isIndexing = YES;
__block UInt32 lastUpdate = TickCount();
__block SInt32 unsavedChanges = 0;
@@ -1451,7 +1454,9 @@
AILogWithSignature(@"Cleaning %i dirty logs", [localLogSet count]);
[localLogSet retain];
dispatch_group_async(loggerPluginGroup, searchIndexQueue, blockWithAutoreleasePool(^{
+
dispatch_group_enter(logIndexingGroup);
+
while (_remainingLogs > 0 && bself.indexingAllowed) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
__block NSString *__logPath = nil;
@@ -1535,6 +1540,9 @@
CFRelease(documentText);
dispatch_semaphore_signal(jobSemaphore);
} else {
+ OSAtomicIncrement64Barrier((int64_t *)&(bself->logsIndexed));
+ OSAtomicDecrement64Barrier((int64_t *)&_remainingLogs);
+
dispatch_semaphore_signal(jobSemaphore);
}
@@ -1550,6 +1558,7 @@
AILogWithSignature(@"Could not create document for %@ [%@]",logPath,[NSURL fileURLWithPath:logPath]);
if (document) CFRelease(document);
OSAtomicIncrement64Barrier((int64_t *)&(bself->logsIndexed));
+ OSAtomicDecrement64Barrier((int64_t *)&_remainingLogs);
OSAtomicIncrement32Barrier((int32_t *)&unsavedChanges);
dispatch_semaphore_signal(jobSemaphore);
dispatch_semaphore_signal(logLoadingPrefetchSemaphore);
@@ -1563,6 +1572,7 @@
if (unsavedChanges) {
[bself _saveDirtyLogSet];
}
+ dispatch_group_enter(closingIndexGroup);
dispatch_group_leave(logIndexingGroup);
dispatch_group_notify(logIndexingGroup, searchIndexQueue, ^{
dispatch_async(dispatch_get_main_queue(), ^{
@@ -1572,10 +1582,14 @@
AILogWithSignature(@"After cleaning dirty logs, the search index has a max ID of %i and a count of %i",
SKIndexGetMaximumDocumentID(searchIndex),
SKIndexGetDocumentCount(searchIndex));
+ CFRelease(searchIndex);
[bself _didCleanDirtyLogs];
[localLogSet release];
});
+ dispatch_group_leave(closingIndexGroup);
}));
+ } else {
+ CFRelease(searchIndex);
}
}
@@ -1649,7 +1663,7 @@
[bself _flushIndex:bself->logIndex];
if (bself.canCloseIndex) {
SKIndexClose(bself->logIndex);
- AILogWithSignature(@"**** Finished closing index %p", bself->logIndex);
+ AILogWithSignature(@"**** %@ Released its index %p", bself, bself->logIndex);
bself->logIndex = nil;
}
}
@@ -1666,7 +1680,7 @@
SKIndexFlush(inIndex);
SKIndexCompact(inIndex);
CFRelease(inIndex);
- AILogWithSignature(@"**** Finished flushing index %p, and released it",inIndex);
+ AILogWithSignature(@"**** Finished flushing index %p",inIndex);
self.indexIsFlushing = NO;
}