Re: NSOperationQueue broken?
Re: NSOperationQueue broken?
- Subject: Re: NSOperationQueue broken?
- From: Jamie Johnson <email@hidden>
- Date: Thu, 30 Oct 2008 19:26:50 -0700
By overriding -start of NSInvocationOperation and wrapping the call to
super in an try/catch block:
[Switching to process 8541 local thread 0x2d03]
Running…
2008-10-30 16:13:08.446 NSOp-Test[8541:1703]
NSInvalidArgumentException - *** -[MyOp start]: receiver has already
started or finished, 0x113040
2008-10-30 16:13:08.913 NSOp-Test[8541:1603]
NSInvalidArgumentException - *** -[MyOp start]: receiver has already
started or finished, 0x115e00
2008-10-30 16:13:12.683 NSOp-Test[8541:3403]
NSInvalidArgumentException - *** -[MyOp start]: receiver has already
started or finished, 0x116d70
2008-10-30 16:13:16.183 NSOp-Test[8541:2e03]
NSInvalidArgumentException - *** -[MyOp start]: receiver has already
started or finished, 0x110fe0
objc[8541]: FREED(id): message start sent to freed object=0x115ca0
[Switching to process 8541 thread 0x1403]
Program received signal: “EXC_BAD_INSTRUCTION”.
[Switching to process 8541 thread 0x1403]
kill
quit
There's no guarantee the diagnostic code I've added isn't introducing
other problems, multiprocessing is a pita that way, but the above
information leads me to conclude an operation can be freed in an
unexpected manor. You're probably correct about a race condition. Also
in this method I have tests to check isExecuting, isFinished, !
isReady, and isCancelled and log accordingly; note you see none of
that here but on occasion I have seen runs where these came back as
true unexpectedly. Breaking on those cases it looked like memory was
hosed.
Unfortunately (or fortunately in this case) my project requires 10.4.
But to support easy migration later I implement a compatible
interfaces to NSOperation etal (only implemented what the project
requires). Looks like you'll be doing similar or restructuring your
solution.
Please share what you find out.
Jamie
On Oct 30, 2008, at 5:30 PM, Michael Ash wrote:
On Thu, Oct 30, 2008 at 6:04 PM, Jamie Johnson <email@hidden>
wrote:
Looks like you're hosing memory because the subsequent invocation
operations
are being released prior to their completion as seen in this call
stack:
#0 0x00001a0c in -[MyOp dealloc] at NSOp-Test.m:27
#1 0x94fba20f in NSPopAutoreleasePool
#2 0x9504f3a8 in -[NSOperation start]
#3 0x00001ad6 in -[MyOp start] at NSOp-Test.m:39
As a guess the NSOperationQueue places the operation in an
autoreleasepool,
not really retaining it itself. The nearest pool happens to be
constructed
in NSOperation -start. Upon exit boom!
It's a good theory. Alas, I don't think it's the case.
To prove this, take my original test case and replace the -test method
with this group of methods:
- (void)test
{
[NSThread detachNewThreadSelector:@selector(_enqueueThread)
toTarget:self withObject:nil];
}
- (void)_enqueueThread
{
while(1)
{
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSInvocationOperation *op = [[NSInvocationOperation alloc]
initWithTarget:self selector:@selector(_operationTarget) object:nil];
[_queue addOperation:op];
[op release];
[pool release];
}
}
- (void)_operationTarget
{
}
This avoids the pitfall you mention but still (on my computer) throws
the same exception as before.
Based on the state of the program when it crashes, it appears that the
problem is caused by a race condition which occasionally causes two of
the worker threads that NSOperationQueue spawns to dequeue and execute
the same NSOperation. Since an NSOperation is only supposed to run
once, things fall down go boom. This is just a theory, mind, and I'm
not sure of it yet.
Mike
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please 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
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please 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