NSConditionLock question
NSConditionLock question
- Subject: NSConditionLock question
- From: Sarwat Khan <email@hidden>
- Date: Fri, 17 Aug 2001 18:22:59 -0400
I've run into a bit of deadlock with this bit of code,
[_queueLock lock];
if ([_queue count] == 0 && _isClosed == FALSE)
{
[_queueLock unlock]; //bad!
[_queueLock lockWhenCondition:kCondition_hasData];
}
What I want is to be able to relock on another condition. The problem
here is that isClosed is set to true just after the unlock. I've been
able to implement this using pthread's mutex stuff, which has
pthread_cond_wait(condition, mutex), which will unlock the mutex and
wait for the condition (and re-lock the mutex when it returns).
I'm sure that I'm going about this the wrong way. Any tips?
It's a queue that has 'sendObject' and 'receiveObject'. It blocks the
sender thread if the queue is full, and it blocks the receiver thread if
the queue is empty. I think, once upon a time, back in the RDR2 days,
there was a threading demo of a producer-consumer problem that had
similar constraints. I can't find it on the developer FTP site, and I
doubt I can read the demo straight off of the Rhapsody CDs (Assuming I
find them :)
Here's a larger code snippet, without using pthread_mutex_t.
- (void) sendObject:(in id)object;
{
[_queueLock lock];
if (_isClosed) //don't add anymore objects if closed.
{
[_queueLock unlock];
return;
}
if (_maxSize != 0 && [_queue count] >= _maxSize)
{
[_queueLock unlock]; //+++ bad!!!
[_queueLock lockWhenCondition:kCondition_canAddData];
if (_isClosed) {[_queueLock unlock]; return;}
}
//do actual insert
[_queue insertObject:object atIndex:0];
[_queueLock unlockWithCondition:kCondition_hasData];
}
- (id) receiveObject;
{
id result = nil;
[_queueLock lock];
//sleep if we don't have data. If not sleeping, then return nil.
if ([_queue count] == 0 && _isClosed == NO)
{
[_queueLock unlock]; //+++ bad!!!
[_queueLock lockWhenCondition:kCondition_hasData];
}
//remove the object and return it.
if (result = [_queue lastObject])
{
[[result retain] autorelease];
[_queue removeLastObject];
}
[_queueLock unlockWithCondition:kCondition_canAddData];
return result;
}
- (void) close;
{
[_queueLock lock];
_isClosed = YES;
[_queueLock unlock];
/* the pthread_mutex version adds this here:
pthread_cond_signal(&_cond_canAddData, &_mutex);
pthread_cond_signal(&_cond_hasData, &_mutex);
*/
}