Hi!
I have a problem with NSURLConnection* class in multithread environment. Minimalized test program source code and its output inserted below. A documentation here:
http://www.gnustep.org/resources/documentation/Developer/Base/Reference/NSURLConnection.html
says nothing about multithread restriction. I need NSURLConnection to work asynchronous in the thread, and many threads parallel at a time.
There is a program "main.m", 100 lines of text inserted below. Its a minimal program. There is only one class (http_obj), which able to process an asynchronous http
request, and the protocol delegates in the class too. The main() function allocates that class one or more times, and start thread(s) too. An unsigned integer (i2) ensures the number of threads. (Application exit synchronization is a bit ugly, but that is not the point now.) With i2=1 only one thread got allocated, and it works fine. Program output also inserted at bottom of code. With i2=2 it freezes on [NSURLConnection connectionWithRequest:delegate:]. Am i missing something?
/* -------------------------------------------------------------*/
/* ------------------------- main.m ----------------------------*/
#import <Foundation/Foundation.h>
//----
@interface http_obj:NSObject {
NSMutableData* download_buff;
boolean download_end; }
-(void) proc_it:(id)obj;
@end
//----
@implementation http_obj
-(void) proc_it:(id)obj {
NSAutoreleasePool* pool= [[NSAutoreleasePool alloc] init];
download_end= NO;
NSLog(@"function entry checkpoint");
NSString* http_str= [@"http://127.0.0.1/index.html"
stringByAddingPercentEscapesUsingEncoding:
NSUTF8StringEncoding];
download_buff= [NSMutableData dataWithCapacity:1024];
NSURL* base_url= [NSURL URLWithString:http_str];
NSMutableURLRequest* url_request= [NSMutableURLRequest
requestWithURL:base_url
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:60];
NSLog(@"nsurlconnection checkpoint");
NSURLConnection* url_connection= [NSURLConnection
connectionWithRequest:url_request
delegate:self];
NSLog(@"runloop checkpoint");
while(!download_end) [[NSRunLoop currentRunLoop]
runMode:NSDefaultRunLoopMode
beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.3]];
NSLog(@"download done checkpoint");
[pool drain];
return;}
//--
-(void)connection:(NSURLConnection*)connection
didFailWithError:(NSError*)error {
NSLog(@"didFailWithError");
download_end= YES;}
-(NSCachedURLResponse*)connection:(NSURLConnection*)connection
willCacheResponse:(NSCachedURLResponse*)cachedResponse {
NSLog(@"willCacheResponse");
return nil;}
-(void)connection:(NSURLConnection*)connection
didReceiveResponse:(NSURLResponse*)response {
NSLog(@"didReceiveResponse");
[download_buff setLength:0];}
-(void)connection:(NSURLConnection*)connection
didReceiveData:(NSData*)data {
NSLog(@"didReceiveData");
[download_buff appendData:data]; }
-(NSURLRequest*)connection:(NSURLConnection*)connection
willSendRequest:(NSURLRequest*)request
redirectResponse:(NSURLResponse*)redirectResponse {
NSLog(@"willSendRequest");
return request;}
-(void)connectionDidFinishLoading:(NSURLConnection*)connection {
NSLog(@"connectionDidFinishLoading");
download_end= YES;}
@end
//----
int main (int argc, const char * argv[]) {
NSAutoreleasePool* pool= [[NSAutoreleasePool alloc] init];
//--
unsigned i1;
unsigned i2= 2;
for(i1=0; i1< i2; i1++) {
http_obj* o1= [[[http_obj alloc] init] autorelease];
[NSThread detachNewThreadSelector:@selector(proc_it:)
toTarget:o1 withObject:o1]; }
[NSThread sleepForTimeInterval:10.0];
NSLog(@"app exit checkpoint");
[pool drain];
return 0;}
//-----------------------------------------------------
// App output if i2==1
//
// 2012-11-21 09:47:03.450 main[1652] function entry
checkpoint
// 2012-11-21 09:47:03.465 main[1652] nsurlconnection checkpoint
// 2012-11-21 09:47:04.370 main[1652] runloop checkpoint
// 2012-11-21 09:47:04.386 main[1652] didReceiveResponse
// 2012-11-21 09:47:04.386 main[1652] didReceiveData
// 2012-11-21 09:47:04.386 main[1652] connectionDidFinishLoading
// 2012-11-21 09:47:04.386 main[1652] download done checkpoint
// 2012-11-21 09:47:13.371 main[1652] app exit checkpoint
//-----------------------------------------------------
// App output if i2==2 (1st output line is broken to let it short)
//
// 2012-11-21 09:49:04.288 main[304] WARNING - unable to create
// shared user defaults!
// 2012-11-21 09:49:04.350 main[304] function entry checkpoint
// 2012-11-21 09:49:04.350 main[304] function entry checkpoint
// 2012-11-21 09:49:04.366 main[304] nsurlconnection checkpoint
// 2012-11-21 09:49:04.366 main[304] nsurlconnection checkpoint
// 2012-11-21
09:49:14.256 main[304] app exit checkpoint
//-----------------------------------------------------
/* --------------------------- end -----------------------------*/
/* -------------------------------------------------------------*/