• 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
Re: Blocking a method's return until an "async' forked thread has finished it's work.
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Blocking a method's return until an "async' forked thread has finished it's work.


  • Subject: Re: Blocking a method's return until an "async' forked thread has finished it's work.
  • From: Robert Nicholson <email@hidden>
  • Date: Mon, 4 Jun 2007 10:04:45 +0700

Despite the setting that I receive my posts to the list they aren't being sent so I'm replying to what I sent earlier.

Here's a transcript from gdb

(gdb) continue
Current language: auto; currently objective-c
2007-06-04 09:56:19.408 Automator[1522] Number of workers 5
2007-06-04 09:56:19.408 Automator[1522] Interval timeout (null)
2007-06-04 09:56:19.408 Automator[1522] Number of elements 14
2007-06-04 09:56:19.408 Automator[1522] Total number of batches 3
(gdb) continue
(gdb) continue
[Switching to process 1522 thread 0x8207]
[Switching to process 1522 thread 0x8207]
(gdb) continue
2007-06-04 09:56:22.806 Automator[1522] 0x18128e10/0 Pulling from the queue
[Switching to process 1522 thread 0x8403]
[Switching to process 1522 thread 0x8403]
(gdb) continue
2007-06-04 09:56:41.423 Automator[1522] 0x18123120/3 Pulling from the queue
[Switching to process 1522 thread 0x7b17]
[Switching to process 1522 thread 0x7b17]
(gdb) continue
2007-06-04 09:56:45.463 Automator[1522] 0x17d2e9b0/2 Pulling from the queue
2007-06-04 09:56:45.467 Automator[1522] worker 2 given batch 2
[Switching to process 1522 thread 0x8307]
[Switching to process 1522 thread 0x8307]
(gdb) continue
2007-06-04 09:56:50.007 Automator[1522] 0x17d8f900/1 Pulling from the queue
2007-06-04 09:56:50.016 Automator[1522] worker 0 given batch 0
2007-06-04 09:56:50.016 Automator[1522] worker 3 given batch 1
[Switching to process 1522 thread 0x8207]
[Switching to process 1522 thread 0x8403]
(gdb) continue
2007-06-04 09:56:54.686 Automator[1522] Thread 0x18123120 runJob begin
2007-06-04 09:56:54.687 Automator[1522] Thread 0x18123120 runJob end
[Switching to process 1522 thread 0x8d03]
[Switching to process 1522 thread 0x8d03]
(gdb) continue
2007-06-04 09:56:56.654 Automator[1522] Thread 0x17de4f80 doDownload
[Switching to process 1522 thread 0x8903]
[Switching to process 1522 thread 0x8903]
(gdb) continue
2007-06-04 09:56:57.341 Automator[1522] Thread 0x17fb8920 doDownload
[Switching to process 1522 thread 0x8a03]
[Switching to process 1522 thread 0x8a03]
(gdb) continue
2007-06-04 09:56:57.918 Automator[1522] Thread 0x17d7ba70 doDownload
[Switching to process 1522 thread 0x8d03]
[Switching to process 1522 thread 0x8d03]
(gdb) continue
2007-06-04 09:56:58.519 Automator[1522] 0x17de4f80 releasing pool doDownload
2007-06-04 09:56:58.519 Automator[1522] 0x17de4f80 released pool doDownload
[Switching to process 1522 thread 0x8207]
[Switching to process 1522 thread 0x8207]
(gdb) continue
(gdb) continue
2007-06-04 09:57:00.127 Automator[1522] Thread 0x18128e10 runJob begin
2007-06-04 09:57:00.127 Automator[1522] Thread 0x18128e10 runJob end


The Debugger has exited due to signal 11 (SIGSEGV).The Debugger has exited due to signal 11 (SIGSEGV).

On Jun 4, 2007, at 12:05 AM, Robert Nicholson wrote:

Please read below.

Begin forwarded message:

From: Robert Nicholson <email@hidden>
Date: June 3, 2007 11:50:03 PM GMT+07:00
To: Cocoa Developers Developers <email@hidden>
Subject: Blocking a method's return until an "async' forked thread has finished it's work.


In general this is allowed right?

ie. if I have some methods that will update the condition lock I can initialize with the total number of workers and as each worker finishes or errors I can deduct by 1 the value of the condition count until it's reaches 0 and then the method will unblock and return right?

In this case the runJobs: method forks again and the same approach is used to block until an async "process" is complete.

The machport is used to return the result of the work for each item back to the parent thread.

- (void)runJobsInMultipleThreads:(unsigned int)count
{
  int i;

  //initialize the threadLock with the number of thread

  [threadLock lock];
  [threadLock unlockWithCondition:count];

  NSPort *mainPort = [NSMachPort port];
  if (!mainPort)
  {
	return;
  }

  [mainPort setDelegate:self];

[[NSRunLoop currentRunLoop] addPort:mainPort forMode:NSDefaultRunLoopMode];

  NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
  [parameters setObject:mainPort forKey:@"port"];

// start the secondary threads
// loop starts at 1 because the main thread is also used (see below)


  for (i=0;i<count;i++) {
    [NSThread detachNewThreadSelector:@selector(runJobs:)
		toTarget:self
		withObject:parameters];
  }

//wait until done, ie until the count of threads in threadLock is down to 0

  [threadLock lockWhenCondition:0];
  [threadLock unlock];
}

so at the runJobs: level it looks like this

- (void)runJobs:(NSMutableDictionary *)parameters;
{
  NSAutoreleasePool *pool;
  BCKJob *aJob;

  //run jobs from the queue until none left
  pool=[[NSAutoreleasePool alloc] init];

  NSMachPort *port = [parameters objectForKey:@"port"];

  aJob = [queue tryDequeue];
  do {
	if (aJob) {
	    [aJob setPort:port];
		[aJob runJob];
	}
  } while (aJob = [queue tryDequeue]);

  //the thread is done with the jobs
  //decrease the count of threads in threadLock
  [threadLock lock];
  [threadLock unlockWithCondition: ([threadLock condition] - 1) ];

  [pool release];
  pool = nil;
 }

and a call to runJob forks again for each item in a workers batch of work.

- (void)runJob
{
	int i = 0;

	[batchLock lock];
	[batchLock unlockWithCondition:[batch count]];

	for (i=0;i<[batch count];i++) {
		NSURL *url = [batch objectAtIndex:i];

		NSMutableDictionary *parameters = [NSMutableDictionary dictionary];
			[parameters setObject:port forKey:@"port"];
			[parameters setObject:url forKey:@"url"];

		[NSThread detachNewThreadSelector:@selector(doDownload:)
                 toTarget:self
                 withObject:parameters];
	}

	[batchLock lockWhenCondition:0];
	[batchLock unlock];

}

and doDownload looks like this

- (void)doDownload:(NSMutableDictionary *)parameters
{
NSAutoreleasePool *pool;

pool = [[NSAutoreleasePool alloc] init];

NSURL *url = [parameters objectForKey:@"url"];

NSURLRequest *r = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:timeout];

NSURLDownload *d = [[NSURLDownload alloc] initWithRequest:r delegate:self];

double resolution = 1.0;
BOOL isRunning;
do {
NSDate *next = [NSDate dateWithTimeIntervalSinceNow:resolution];
isRunning = [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:next];
} while (isRunning && ((completedCount + errorCount) == [batch count]));

[pool release];
pool = nil;
}


If anything I'm currently retaining more than I should but until I solve the memory related SIGTRAP I'm not too worried about that.

so the idea is that nothing will be autorelease until all work is complete.

completeCount and errorCount and updated in

- (void)download:(NSURLDownload *)download didFailWithError: (NSError *)error

- (void)downloadDidFinish:(NSURLDownload *)download

as well as the batchLock which should ensure that runJob does not return until
it's finished it's batch of work.


One particuarly annoying aspect of NSURLDownload is that you get notified that a file is created
regardless of whether the download is successful or not. So you have to build a map the download request against
the path in order to be able to return the path later on. I'd much prefer that when it either error'd or finished that it also gave you the path it's used.


I wouldn't mind seeing the source of NSSynchronousURLConnectionDelegate just to see how it blocks the calling thread until all the work is complete.









_______________________________________________

Cocoa-dev mailing list (email@hidden)

Do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • Re: Blocking a method's return until an "async' forked thread has finished it's work.
      • From: Robert Nicholson <email@hidden>
References: 
 >Blocking a method's return until an "async' forked thread has finished it's work. (From: Robert Nicholson <email@hidden>)

  • Prev by Date: Re: NSSegmentedCell in table column
  • Next by Date: Re: Blocking a method's return until an "async' forked thread has finished it's work.
  • Previous by thread: Blocking a method's return until an "async' forked thread has finished it's work.
  • Next by thread: Re: Blocking a method's return until an "async' forked thread has finished it's work.
  • Index(es):
    • Date
    • Thread