• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
CFReadStreamHasBytesAvailable locks up my threads on 10.3.9
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

CFReadStreamHasBytesAvailable locks up my threads on 10.3.9


  • Subject: CFReadStreamHasBytesAvailable locks up my threads on 10.3.9
  • From: Justin Greenfield <email@hidden>
  • Date: Tue, 19 Apr 2005 14:02:36 -0500

Hi guys..

In my app, I have 2 threads that run in the background, performing downloads via HTTP. In each thread, a URL object is created and downloaded. My code just polls the stream to see if it has bytes available and accumulate the incoming data in one of our own objects to be returned.

This code has worked flawlessly since 10.2 and although though it's probably not the most elegant implementation, it's fine for us (downloads that are a few bytes to a few hundred kilobytes in size).

Since 10.3.9 was released, however, things have gone south... In our app, the call to CFReadStreamHasBytesAvailable will start blocking at some point (after a couple of my URL objects are downloaded), so my Get() method never returns and the thread which is waiting on it so it can process the next query is rendered useless, and my application stops getting new data.

This only seems to happen with HTTPStreams to a CGI that returns a small amount of data, usually less than 200 bytes.

The Get() method looks like this:

CxData CxUrl::Get ()
{
	CFReadStreamRef stream = CreateStream();
	CxData data(0);
	CFStreamError err;
	bool done = false;

	if (::CFReadStreamOpen(stream))
	{
		while (!done)
		{
			uint8 buf[1024];
			CFIndex bytesRead = 0;

			if (::CFReadStreamHasBytesAvailable(stream))
				bytesRead = ::CFReadStreamRead(stream, buf, 1024);

			if (bytesRead < 0)
			{
				err = ::CFReadStreamGetError(stream);
				done = true;
			}
			else if (bytesRead == 0)
			{
				if (::CFReadStreamGetStatus(stream) == kCFStreamStatusAtEnd)
					done = true;
			}
			else
			{
				CxData temp((void*)buf, bytesRead);
				data += temp;
			}
		}

		::CFReadStreamClose(stream);
	}
	else
		err = ::CFReadStreamGetError(stream);

	ProcessResponseHeader(stream);
	::CFRelease(stream);

	return data;
}


Once I figured out that it was CFReadStreamHasBytesAvailable that was causing my lockup, I slightly changed the Get method to look like this:


CxData CxUrl::Get ()
{
	CFReadStreamRef stream = CreateStream();
	CxData data(0);
	CFStreamError err;
	bool done = false;

	if (::CFReadStreamOpen(stream))
	{
		while (!done)
		{
			uint8 buf[1024];
			CFIndex bytesRead = 0;
			CFStreamStatus streamStatus = ::CFReadStreamGetStatus(stream);

			//if (::CFReadStreamHasBytesAvailable(stream))
			if (streamStatus == kCFStreamStatusOpen)
			{
				bytesRead = ::CFReadStreamRead(stream, buf, 1024);
				streamStatus = ::CFReadStreamGetStatus(stream);
			}

			if (bytesRead < 0)
			{
				err = ::CFReadStreamGetError(stream);
				done = true;
			}
			else if (bytesRead == 0)
			{
				if (::CFReadStreamGetStatus(stream) == kCFStreamStatusAtEnd)
					done = true;
			}
			else
			{
				CxData temp((void*)buf, bytesRead);
				data += temp;

				if (streamStatus == kCFStreamStatusAtEnd)
					done = true;
			}
		}

		::CFReadStreamClose(stream);
	}
	else
		err = ::CFReadStreamGetError(stream);

	ProcessResponseHeader(stream);
	::CFRelease(stream);

	return data;
}

This seems to help in some cases, but now it will occasionally crash in CFReadStreamRead....

Thread 6 Crashed:
0 libobjc.A.dylib 0x90831204 objc_msgSend + 0x24
1 com.apple.CFNetwork 0x927fb70c _CFNetConnectionResponseIsComplete + 0x28
2 com.apple.CFNetwork 0x927fb6cc readFromConnection + 0x174
3 com.apple.CFNetwork 0x927f23a4 httpRequestRead + 0x124
4 com.apple.CoreFoundation 0x901f38ac CFReadStreamRead + 0x180
5 edu.ou.ocs.weatherscope 0x00039880 CxUrl::Get() + 0x78
6 edu.ou.ocs.weatherscope 0x00078ec8 DxGraphManager::MessageUpdateConfig(bool) + 0x1f8
7 edu.ou.ocs.weatherscope 0x000781f0 DxGraphManager::OnMessage(long) + 0x84
8 edu.ou.ocs.weatherscope 0x00041dc8 CxThread::RunLoop() + 0x54
9 edu.ou.ocs.weatherscope 0x00041d5c CxThread::TaskProc(void*) + 0x1c
10 ...ple.CoreServices.CarbonCore 0x902f6b90 PrivateMPEntryPoint + 0x4c
11 libSystem.B.dylib 0x90024910 _pthread_body + 0x28


As this has seriously broken our application, I need some help to figure out how to work around this.... Any ideas??

Thanks,
Justin

--
Justin Greenfield
email@hidden
Oklahoma Climatological Survey - Software Development Group

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Macnetworkprog mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • Re: CFReadStreamHasBytesAvailable locks up my threads on 10.3.9
      • From: Becky Willrich <email@hidden>
  • Prev by Date: Solved: Using non-ASCII chars to access servers
  • Next by Date: Re: CFReadStreamHasBytesAvailable locks up my threads on 10.3.9
  • Previous by thread: Solved: Using non-ASCII chars to access servers
  • Next by thread: Re: CFReadStreamHasBytesAvailable locks up my threads on 10.3.9
  • Index(es):
    • Date
    • Thread