It seems to me that any NSInputStream object should pop out of its read: method if the stream is closed by another thread regardless of the other end of the socket connection. But in some cases this does not appear to be true. It seems that unless the other side first sends something at least once before on the connection, the read: method will not respond to the stream closing.
Code to open the connection:
// Open the socket...
CFStreamCreatePairWithSocketToHost(NULL, Host, Port, &readStream, &writeStream);
// Create NSStream objects for our use...
inputStream = (NSInputStream *)readStream;
outputStream = (NSOutputStream *)writeStream;
// take ownership of the NSStream objects...
[inputStream retain];
[outputStream retain];
// open the streams....
[inputStream open];
[outputStream open];
Code to close the connection:
// Close the streams...
[inputStream close];
[outputStream close];
// Release ownership...
[outputStream release];
[inputStream release];
// clear reference values...
outputStream = nil;
inputStream = nil;
In the receive thread:
-(uint8_t) GetByte
{
uint8_t c;
int N = [inputStream read:&c maxLength:1];
if ( N < 1 )
@throw [[TcpClientException alloc] init];
return c;
}
When I go to close the stream from the main thread, the receive thread remains in the read method. Eventually it times out and crashes. Even the crash does not result in any kind of object being thrown (I tried to surround the code to catch anything (id) and got nothing).
How does one reliably force read to pop out every time the streams are to be closed?
Additionally:
I am using XCODE 4.4.1 on ML with 5.1 iPad simulator.
If I only close the inputStream and do not release or set to nil, then the problem occurs as well.