Skip navigation.
 
mlEXC_BAD_INSTRUCTION + CURLHandle + threads
FROM : Nick Kocharhook
DATE : Sun Nov 24 23:22:01 2002

I'm using CURLHandle to download a bunch of images embedded in an HTML
document. I first grab the HTML file with a CURLHandle (which works just
fine), parse it, and then loop through all the images, creating a
CURLHandle for each and telling it to loadInBackground.

This creates as many threads are there are images, which shouldn't
particularly be a problem, I don't think. The idea is to have each
CURLHandle fetch one image and then call the
URLHandleResourceDidFinishLoading: function, which will add the
newly-fetched data to the array in my class that is to hold all the
images.

I want to do this in the background so that the UI can be updated
dynamically as new images arrive, and the app isn't blocking for all the
images. (Death to the spinning cursor!)

I've set up an if statement in the aforementioned function that branches
based on the data's content-type (parse a text/html document vs. add an
image/* to the array). I'm not sure if I'm going to need a lock here or
if NSMutableArray is threadsafe, but I haven't even gotten to that
problem yet.

The problem I'm encountering is that as soon as the first thread times
out, the program crashes. The debugger says it received an
EXC_BAD_INSTRUCTION.

Question 1: Why are the threads timing out when the first one (to get
the HTML page in the first place) didn't?

Question 2: What the heck does that EXC_ error mean??

Code follows. Any help is appreciated; I'm a thread newbie, so it could
very well be something obvious.

- (void)URLHandleResourceDidFinishLoading:(NSURLHandle *)sender
{
    NSData *data = [sender resourceData]; // blocks until loaded
    NSString *contentType = [sender propertyForKeyIfAvailable:@"content-type"];
   
    [sender removeClient:self];  // disconnect this from the URL handle

    // Process Body
    if (nil != data)
    {
        if ([contentType hasPrefix:@"text/html"]) {
            [imageArray removeAllObjects];
            [imageArray addObjectsFromArray:[self imageLinksFromHTML:data]];
            [self resolveImages];
        } else if ([contentType hasPrefix:@"image/"]) {
            NSLog(@"%@", contentType);  // This line is never executed. :-(
        }
    }
}

- (void)resolveImages
{
    // imageArray is an array of dictionaries
    NSEnumerator *imgEnum = [imageArray objectEnumerator];
    id obj;
   
    while (obj = [imgEnum nextObject]) {
        CURLHandle *imgCurlHandle;
        NSImage *img = [obj objectForKey:IMAGE];
        if (img == nil) {
            // Get this image -- syntax stolen from CURLHandleTester
            imgCurlHandle = (CURLHandle *)[[[obj objectForKey:IMAGE_LINK] absoluteURL] URLHandleUsingCache:NO];
            [imgCurlHandle setConnectionTimeout:4]; // a.k.a. setSecondsUntilCrash:
            [imgCurlHandle setFollowsRedirects:NO];
            [imgCurlHandle loadInBackground];

            // don't release our curlHandle
            [obj setObject:imgCurlHandle forKey:@"CurlHandle"];
        }
    }
}

TIA,

--
Nick Kocharhook  --  <<email_removed>> -- Rot-13

Related mailsAuthorDate
mlEXC_BAD_INSTRUCTION + CURLHandle + threads Nick Kocharhook Nov 24, 23:22
mlRe: EXC_BAD_INSTRUCTION + CURLHandle + threads Jake Repp Nov 25, 11:06
mlRe: EXC_BAD_INSTRUCTION + CURLHandle + threads Dan Wood Nov 25, 14:47