mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 16:50:58 +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
|
- (BOOL) waitUntilDate: (NSDate*)limit
|
||||||
{
|
{
|
||||||
NSTimeInterval t = [limit timeIntervalSinceReferenceDate];
|
NSTimeInterval t = [limit timeIntervalSince1970];
|
||||||
double secs, subsecs;
|
double secs, subsecs;
|
||||||
struct timespec timeout;
|
struct timespec timeout;
|
||||||
|
int retVal = 0;
|
||||||
|
|
||||||
// Split the float into seconds and fractions of a second
|
// Split the float into seconds and fractions of a second
|
||||||
subsecs = modf(t, &secs);
|
subsecs = modf(t, &secs);
|
||||||
timeout.tv_sec = secs;
|
timeout.tv_sec = secs;
|
||||||
// Convert fractions of a second to nanoseconds
|
// Convert fractions of a second to nanoseconds
|
||||||
timeout.tv_nsec = subsecs * 1e9;
|
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;
|
return YES;
|
||||||
}
|
}
|
||||||
else
|
else if (retVal == EINVAL)
|
||||||
{
|
{
|
||||||
return NO;
|
NSLog(@"Invalid arguments to pthread_cond_timedwait");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -379,24 +385,19 @@ MUNLOCK
|
||||||
- (BOOL) lockWhenCondition: (NSInteger)condition_to_meet
|
- (BOOL) lockWhenCondition: (NSInteger)condition_to_meet
|
||||||
beforeDate: (NSDate*)limitDate
|
beforeDate: (NSDate*)limitDate
|
||||||
{
|
{
|
||||||
BOOL ret;
|
|
||||||
|
|
||||||
[_condition lock];
|
[_condition lock];
|
||||||
if (condition_to_meet == _condition_value)
|
if (condition_to_meet == _condition_value)
|
||||||
{
|
{
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
if ([_condition waitUntilDate: limitDate]
|
while ([_condition waitUntilDate: limitDate]) {
|
||||||
&& (condition_to_meet == _condition_value))
|
if (condition_to_meet == _condition_value) {
|
||||||
{
|
return YES; // KEEP THE LOCK
|
||||||
ret = YES;
|
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
|
||||||
ret = NO;
|
// we timed out and no longer have the lock
|
||||||
}
|
return NO;
|
||||||
[_condition unlock];
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MNAME
|
MNAME
|
||||||
|
@ -406,10 +407,18 @@ MNAME
|
||||||
return [_condition tryLock];
|
return [_condition tryLock];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) tryLockWhenCondition: (NSInteger)value
|
- (BOOL) tryLockWhenCondition: (NSInteger)condition_to_meet
|
||||||
{
|
{
|
||||||
return [self lockWhenCondition: value
|
if ([_condition tryLock]) {
|
||||||
beforeDate: [NSDate date]];
|
if (condition_to_meet == _condition_value) {
|
||||||
|
return YES; // KEEP THE LOCK
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[_condition unlock];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) unlock
|
- (void) unlock
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue