Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
When performRedirect is called we should destroy the old readStream b…
…efore rebuilding the request with the new stream in case the existing stream had not finished, which could be the case if the full data for the old stream was found in the cache after its first bits had returned but before it had finished. Here is a detailed example of a way this situation can occur: * Consider you have two reusable requests R1 and R2 that both request the same URL * Start these request one right after the other (in chronological order of how events play out) R1: * Starts with an initial readStream R1S1. The request is not in the download cache so it goes and starts pulling the stream R2: * Starts with an initial readStream R2S1 (same url as R1S1). The request is not in the download cache so it goes and starts pulling the stream R1: * The R1S1 stream finishes downloading its data (so no more data will be coming in on R1S1) * It calls handleStreamComplete and the data for the url gets stored in the cache * handleStreamComplete sees it is a redirect request * [self main] reuses R1 and sets up a new readStream which we'll call R1S2 with the redirected url * Redirected url is not in the download cache so it goes and starts pulling the stream R2: * First bits of data return on R2S1 stream * handleBytesAvailable calls readResponseHeaders * readResponseHeaders check if request was previously cached and it WAS (since R1 cached it after R1S1 finished). * readResponseHeaders calls useDataFromCache which calls performRedirect which calls [self main] * [self main] reuses R2 and sets up a new readstream R2S2 with the redirected url * When the new readStream R2S2 is set it overwrites the old R2S1 stream but R2S1 WAS NOT FINISHED pulling data *** This is because so far it has only returned its first bytes of data and when it was found in the cache we moved on * The redirected url for R2S2 is not in the download cache so it goes and starts pulling the stream * R1 and R2 finish their R1S2 and R2S2 streams which each pull the contents of the redirected url and both requests are closed * The R2S1 stream returns with the rest of the content of its request but R2 has already been finished and dealloced * Crash occurs in ReadStreamClientCallBack(CFReadStreamRef readStream, CFStreamEventType type, void *clientCallBackInfo) because clientCallBackInfo is deallocated.
- Loading branch information
744a8fe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to have fixed a crash that I was having. My app relies on caching and redirects in download queues that can sometimes be created and canceled rapidly.