views:

110

answers:

1

What I Want

I've got an NSOperationQueue in my application and it's critical that all operations get processed before the application quits. I've got the following code on quit to make sure the NSOperationQueue is empty before quitting:

if ([NSThread isMainThread]) {
    while ([[operationQueue operations] count] > 0) {
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.05]];
    }
} else {
    [operationQueue waitUntilAllOperationsAreFinished];
}

I've encountered a problem with my code before where an NSOperation "froze" before finishing and it blocked the whole queue. Obviously, in situations like this, my code should throw an exception, which it now does.

But I still want to guard against anything weird happening where operations stop and block the queue, resulting in the application never quitting and the fault not being caught.

My Rubbish Solution

I'm considering putting a timeout on the queue finishing its operations. Then when it does timeout, I could throw an exception then the problem could be caught.

However, this doesn't feel right. Ideally, I don't want to be reliant upon timers to make sure work is done.

My Question

Is there a better, fail safe, way of making sure my operations haven't frozen?

+2  A: 

If I understand...

  • you want to know that your operations haven't frozen ... becomes ...
  • you want to know that all of your operations will finish executing ... becomes ...
  • you want to solve the halting problem

Good luck with that.

Realistically though, what you're doing with the waitUntilAllOperationsAreFinished is about as good as you're going to get. You could add another class that watches each operation and makes sure it doesn't run for too long (say 10x longer than you're expecting it to run), at which point it would -cancel the NSOperation (More or less your timer approach). However, even that's not foolproof, because the operation could be blocked on something where you can't check for -isCancelled (inside a system call, for example).

Dave DeLong
Thanks for the great answer, Dave. It's nice to be reassured that I'm not too far off base with my timeout approach. I'm content to crash on an operation queue timeout, then at least I know there's some kind of problem here.
John Gallagher