I am writing an Objective-C class that I want to be thread safe. To do this I am using pthreads and a pthread_rwlock (using @synchronized is overkill and I want to learn a bit more about pthreads). The lock is inited in the objects designated init method and destroyed in dealloc. I have three methods for manipulating the lock; readLock, writeLock, unlock. These three methods simply invoke the related pthread functions and currently nothing else.
Here are two of the objects methods, both of which require a writeLock:
-(void)addValue:(const void *)buffer
{
[self writeLock];
NSUInteger lastIndex = self.lastIndex;
[self setValue:buffer atIndex:(lastIndex == NSNotFound) ? 0 : lastIndex+1];
[self unlock];
}
-(void)setValue:(const void *)buffer atIndex:(NSUInteger)index
{
[self writeLock];
//do work here
[self unlock];
}
Invoking setAddValue: will first obtain a write lock and then invoke setValue:atIndex: which will also attempt to obtain a write lock. The documentation states that the behaviour is undefined when this occurs. Therefore, how do I check if a thread has a lock before attempting to obtain a lock?
(I could ensure that critical section make no invocation that trigger another lock request, but that would mean code repetition and I want to keep my code DRY).
Not entirely clear what kind of lock you’re using. You indicate you’re using pthreads, and read/write lock, so I’m concluding that you’re using a pthread_rwlock.
If that’s true, then you should be able to use
pthread_rwlock_trywrlockon the lock. From the man page,And, one of the errors is:
Therefore, I believe you should be able to call
pthread_rwlock_trywrlock()and you will either be successful, it will returnEBUSYif another thread has the lock, or you will getEDEADLKif the current thread has the lock.