mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 08:21:25 +00:00
Fix several problems with lockWhenCondition:beforeDate:
First -- it needs to use timeIntervalSince1970 to be using the same reference date required for pthread_cond_timedwait Second -- lockWhenCondition needs to loop because pthread_cond_timedwait can return prior to delay expiring (but with the wrong condition). Third -- Internally the lock was incorrectly being unlocked on a delayed acquire (and YES return). And was incorrectly being unlocked a second time when the timeout expired. Also, fixed a problem with tryLockWhenCondition: By calling lockWhenCondition: it would incorrectly report a deadlock (rather than just return no) when we already have the lock. All these changes are in line with expected and documented behavior for NSLock. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@29472 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
367d552a3b
commit
d85c001251
1 changed files with 29 additions and 20 deletions
|
@ -297,23 +297,29 @@ MUNLOCK
|
|||
|
||||
- (BOOL) waitUntilDate: (NSDate*)limit
|
||||
{
|
||||
NSTimeInterval t = [limit timeIntervalSinceReferenceDate];
|
||||
NSTimeInterval t = [limit timeIntervalSince1970];
|
||||
double secs, subsecs;
|
||||
struct timespec timeout;
|
||||
int retVal = 0;
|
||||
|
||||
// Split the float into seconds and fractions of a second
|
||||
subsecs = modf(t, &secs);
|
||||
timeout.tv_sec = secs;
|
||||
// Convert fractions of a second to nanoseconds
|
||||
timeout.tv_nsec = subsecs * 1e9;
|
||||
if (0 == pthread_cond_timedwait(&_condition, &_mutex, &timeout))
|
||||
|
||||
retVal = pthread_cond_timedwait(&_condition, &_mutex, &timeout);
|
||||
|
||||
if (retVal == 0)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
else
|
||||
else if (retVal == EINVAL)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
NSLog(@"Invalid arguments to pthread_cond_timedwait");
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -379,24 +385,19 @@ MUNLOCK
|
|||
- (BOOL) lockWhenCondition: (NSInteger)condition_to_meet
|
||||
beforeDate: (NSDate*)limitDate
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
[_condition lock];
|
||||
if (condition_to_meet == _condition_value)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
if ([_condition waitUntilDate: limitDate]
|
||||
&& (condition_to_meet == _condition_value))
|
||||
{
|
||||
ret = YES;
|
||||
while ([_condition waitUntilDate: limitDate]) {
|
||||
if (condition_to_meet == _condition_value) {
|
||||
return YES; // KEEP THE LOCK
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = NO;
|
||||
}
|
||||
[_condition unlock];
|
||||
return ret;
|
||||
}
|
||||
|
||||
// we timed out and no longer have the lock
|
||||
return NO;
|
||||
}
|
||||
|
||||
MNAME
|
||||
|
@ -406,10 +407,18 @@ MNAME
|
|||
return [_condition tryLock];
|
||||
}
|
||||
|
||||
- (BOOL) tryLockWhenCondition: (NSInteger)value
|
||||
- (BOOL) tryLockWhenCondition: (NSInteger)condition_to_meet
|
||||
{
|
||||
return [self lockWhenCondition: value
|
||||
beforeDate: [NSDate date]];
|
||||
if ([_condition tryLock]) {
|
||||
if (condition_to_meet == _condition_value) {
|
||||
return YES; // KEEP THE LOCK
|
||||
}
|
||||
else {
|
||||
[_condition unlock];
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void) unlock
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue