[Audio Player] Eliminate an avenue of lockups
Prevent the player from locking up in certain circumstances, by not locking chainQueue the entire time this function is processing. Signed-off-by: Christopher Snowhill <kode54@gmail.com>lastfm
parent
42b2142ab7
commit
22cd16bb46
|
@ -357,71 +357,77 @@
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BufferChain *lastChain;
|
||||||
|
|
||||||
@synchronized(chainQueue) {
|
@synchronized(chainQueue) {
|
||||||
newChain = [[BufferChain alloc] initWithController:self];
|
newChain = [[BufferChain alloc] initWithController:self];
|
||||||
|
|
||||||
endOfInputReached = YES;
|
endOfInputReached = YES;
|
||||||
|
|
||||||
BufferChain *lastChain = [chainQueue lastObject];
|
lastChain = [chainQueue lastObject];
|
||||||
if(lastChain == nil) {
|
if(lastChain == nil) {
|
||||||
lastChain = bufferChain;
|
lastChain = bufferChain;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BOOL pathsEqual = NO;
|
BOOL pathsEqual = NO;
|
||||||
|
|
||||||
if([nextStream isFileURL] && [[lastChain streamURL] isFileURL]) {
|
if([nextStream isFileURL] && [[lastChain streamURL] isFileURL]) {
|
||||||
NSString *unixPathNext = [nextStream path];
|
NSString *unixPathNext = [nextStream path];
|
||||||
NSString *unixPathPrev = [[lastChain streamURL] path];
|
NSString *unixPathPrev = [[lastChain streamURL] path];
|
||||||
|
|
||||||
if([unixPathNext isEqualToString:unixPathPrev])
|
if([unixPathNext isEqualToString:unixPathPrev])
|
||||||
pathsEqual = YES;
|
pathsEqual = YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pathsEqual || ([[nextStream scheme] isEqualToString:[[lastChain streamURL] scheme]] && (([nextStream host] == nil && [[lastChain streamURL] host] == nil) || [[nextStream host] isEqualToString:[[lastChain streamURL] host]]) && [[nextStream path] isEqualToString:[[lastChain streamURL] path]])) {
|
if(pathsEqual || ([[nextStream scheme] isEqualToString:[[lastChain streamURL] scheme]] && (([nextStream host] == nil && [[lastChain streamURL] host] == nil) || [[nextStream host] isEqualToString:[[lastChain streamURL] host]]) && [[nextStream path] isEqualToString:[[lastChain streamURL] path]])) {
|
||||||
if([lastChain setTrack:nextStream] && [newChain openWithInput:[lastChain inputNode] withUserInfo:nextStreamUserInfo withRGInfo:nextStreamRGInfo]) {
|
if([lastChain setTrack:nextStream] && [newChain openWithInput:[lastChain inputNode] withUserInfo:nextStreamUserInfo withRGInfo:nextStreamRGInfo]) {
|
||||||
[newChain setStreamURL:nextStream];
|
[newChain setStreamURL:nextStream];
|
||||||
|
|
||||||
|
@synchronized(chainQueue) {
|
||||||
[self addChainToQueue:newChain];
|
[self addChainToQueue:newChain];
|
||||||
DLog(@"TRACK SET!!! %@", newChain);
|
|
||||||
// Keep on-playin
|
|
||||||
newChain = nil;
|
|
||||||
|
|
||||||
atomic_fetch_sub(&refCount, 1);
|
|
||||||
return NO;
|
|
||||||
}
|
}
|
||||||
}
|
DLog(@"TRACK SET!!! %@", newChain);
|
||||||
|
// Keep on-playin
|
||||||
lastChain = nil;
|
|
||||||
|
|
||||||
while(shouldContinue && ![newChain open:nextStream withUserInfo:nextStreamUserInfo withRGInfo:nextStreamRGInfo]) {
|
|
||||||
if(nextStream == nil) {
|
|
||||||
newChain = nil;
|
|
||||||
atomic_fetch_sub(&refCount, 1);
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
newChain = nil;
|
newChain = nil;
|
||||||
[self requestNextStream:nextStreamUserInfo];
|
|
||||||
|
|
||||||
newChain = [[BufferChain alloc] initWithController:self];
|
atomic_fetch_sub(&refCount, 1);
|
||||||
|
return NO;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[self addChainToQueue:newChain];
|
lastChain = nil;
|
||||||
|
|
||||||
|
while(shouldContinue && ![newChain open:nextStream withUserInfo:nextStreamUserInfo withRGInfo:nextStreamRGInfo]) {
|
||||||
|
if(nextStream == nil) {
|
||||||
|
newChain = nil;
|
||||||
|
atomic_fetch_sub(&refCount, 1);
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
newChain = nil;
|
newChain = nil;
|
||||||
|
[self requestNextStream:nextStreamUserInfo];
|
||||||
|
|
||||||
// I'm stupid and can't hold too much stuff in my head all at once, so writing it here.
|
newChain = [[BufferChain alloc] initWithController:self];
|
||||||
//
|
|
||||||
// Once we get here:
|
|
||||||
// - buffer chain for previous stream finished reading
|
|
||||||
// - there are (probably) some bytes of the previous stream in the output buffer which haven't been played
|
|
||||||
// (by output node) yet
|
|
||||||
// - self.bufferChain == previous playlist entry's buffer chain
|
|
||||||
// - self.nextStream == next playlist entry's URL
|
|
||||||
// - self.nextStreamUserInfo == next playlist entry
|
|
||||||
// - head of chainQueue is the buffer chain for the next entry (which has launched its threads already)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@synchronized(chainQueue) {
|
||||||
|
[self addChainToQueue:newChain];
|
||||||
|
}
|
||||||
|
|
||||||
|
newChain = nil;
|
||||||
|
|
||||||
|
// I'm stupid and can't hold too much stuff in my head all at once, so writing it here.
|
||||||
|
//
|
||||||
|
// Once we get here:
|
||||||
|
// - buffer chain for previous stream finished reading
|
||||||
|
// - there are (probably) some bytes of the previous stream in the output buffer which haven't been played
|
||||||
|
// (by output node) yet
|
||||||
|
// - self.bufferChain == previous playlist entry's buffer chain
|
||||||
|
// - self.nextStream == next playlist entry's URL
|
||||||
|
// - self.nextStreamUserInfo == next playlist entry
|
||||||
|
// - head of chainQueue is the buffer chain for the next entry (which has launched its threads already)
|
||||||
|
|
||||||
atomic_fetch_sub(&refCount, 1);
|
atomic_fetch_sub(&refCount, 1);
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue