Richard Stelling
Richard Stelling

Reputation: 25665

Call to CFReadStreamRead stops execution in thread

NB: The entire code base for this project is so large that posting any meaningful amount wold render this question too localised, I have tried to distil any code down to the bare-essentials. I'm not expecting anyone to solve my problems directly but I will up vote those answers I find helpful or intriguing.

This project uses a modified version of AudioStreamer to playback audio files that are saved to locally to the device (iPhone).

The stream is set up and scheduled on the current loop using this code (unaltered from the standard AudioStreamer project as far as I know):

CFStreamClientContext context = {0, self, NULL, NULL, NULL};
CFReadStreamSetClient(
                          stream,
                          kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered,
                          ASReadStreamCallBack,
                          &context);
CFReadStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);

The ASReadStreamCallBack calls:

- (void)handleReadFromStream:(CFReadStreamRef)aStream
               eventType:(CFStreamEventType)eventType

On the AudioStreamer object, this all works fine until the stream is read using this code:

BOOL hasBytes = NO;  //Added for debugging
hasBytes = CFReadStreamHasBytesAvailable(stream);
        
length = CFReadStreamRead(stream, bytes, kAQDefaultBufSize);

hasBytes is YES but when CFReadStreamRead is called execution stops, the App does not crash it just stops exciting, any break points below the CFReadStreamRead call are not hit and ASReadStreamCallBack is not called again.

I am at a loss to what might cause this, my best guess is the thread is being terminated? But the hows and whys is why I'm asking SO.

Has anyone seen this behaviour before? How can I track it down and ideas on how I might solve it will be very much welcome!

Additional Info Requested via Comments

  1. This is 100% repeatable
  2. CFReadStreamHasBytesAvailable was added by me for debugging but removing it has no effect

Upvotes: 1

Views: 1180

Answers (2)

tumtumtum
tumtumtum

Reputation: 1162

It is possible that the stream pointer is just corrupt in some way. CFReadStreamRead should certainly not block if bytes are available (it certainly would never block for more than a few milliseconds for local files). Can you provide the code you use to create the stream?

Alternatively, CFReadStreams send messages asynchronously but it is possible (but not likely) that it's blocking because the runloop isn't being processed.

If you prefer, I've uploaded my AudioPlayer inspired by Matt's AudioStreamer hosted at https://code.google.com/p/audjustable/. It supports local files (as well as HTTP). I think it does what you wanted (stream files from more than just HTTP).

Upvotes: 0

Rob Napier
Rob Napier

Reputation: 299345

First, I assume that CFReadStreamScheduleWithRunLoop() is running on the same thread as CFReadStreamRead()?

Is this thread processing its runloop? Failure to do this is my main suspicion. Do you have a call like CFRunLoopRun() or equivalent on this thread?

Typically there is no reason to spawn a separate thread for reading streams asynchronously, so I'm a little confused about your threading design. Is there really a background thread involved here? Also, typically CFReadStreamRead() would be in your client callback (when you receive the kCFStreamEventHasBytesAvailable event (which it appears to be in the linked code), but you're suggesting ASReadStreamCallBack is never called. How have you modified AudioStreamer?

Upvotes: 2

Related Questions