Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should NSLocking usage always be wrapped in @try/@finally?

Given a Cocoa NSLocking object (like an NSLock) and some non-trivial code to be executed while the lock is held:

To ensure a lock is always released, should the following idiom always be used?

NSLock *mutex = // get lock from somewhere
@try {
    [mutex lock];
    // do non-trivial stuff
} 
@finally {
    [mutex unlock];
}

This seems prudent (and common in Java), but I haven't seen any Cocoa code do this.

Should this idiom be used? Why or why not?

like image 503
Todd Ditchendorf Avatar asked Oct 12 '11 06:10

Todd Ditchendorf


2 Answers

To ensure a lock is always released, should the following idiom always be used?

Yes, where program correctness after that scope ('non-trivial stuff') is required, and assuming your program can properly recover from the exceptions it encounters.

Should this idiom be used? Why or why not?

If you can recover, then yes, unlocking is necessary to continue execution normally. Otherwise, your program will be executing in an invalid state.

  • Example 1: When the lock is destroyed (during dealloc), the attempt to destroy it will fail because it is still locked. Whether the implementation continues to destroy the lock or ignores the error is not defined (I would guess it would persist, meaning it would never exit from dealloc).

  • Example 2: When it is locked from another thread (or the same thread, if not reentrant) then you will never acquire the lock and another error, deadlock, or exception may be produced as a result. An implementation could also (eventually) proceed with no lock acquired. All that is guaranteed is logging when/if an error is detected.

pthread_mutexes and the implementations that depend on them may not behave very gracefully if you have such a lock imbalance; this always falls back to a programmer error.

Correct and defensive locking in pure objc and c is not very pretty. The Java idiom is correct, and equally applicable to Foundation APIs. The reason you don't see it as much may be because exceptions are a less popular/used error handling mechanism within Cocoa APIs and programs that depend on them (compared to Java). see also Bavarious' note in the comments

like image 59
justin Avatar answered Sep 24 '22 06:09

justin


No.

Exceptions are only used for programming errors in Cocoa. They are not used for situations where the program is expected to recover.

like image 43
Nikolai Ruhe Avatar answered Sep 26 '22 06:09

Nikolai Ruhe