From 53b843ccec590da87408a4170174fa1ab71474ea Mon Sep 17 00:00:00 2001 From: Frederik Seiffert Date: Thu, 13 Apr 2017 12:17:11 +0200 Subject: [PATCH] Implemented -[NSConditionLock lockWhenCondition:beforeDate:] Fixes #845. --- Frameworks/Foundation/NSConditionLock.mm | 45 ++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/Frameworks/Foundation/NSConditionLock.mm b/Frameworks/Foundation/NSConditionLock.mm index 7181e2f89c..bfe683ca9a 100644 --- a/Frameworks/Foundation/NSConditionLock.mm +++ b/Frameworks/Foundation/NSConditionLock.mm @@ -148,11 +148,50 @@ - (void)lockWhenCondition:(NSInteger)condition { } /** -@Status Stub + @Status Interoperable */ - (BOOL)lockWhenCondition:(NSInteger)condition beforeDate:(NSDate*)date { - UNIMPLEMENTED(); - return NO; + int rc; + struct timespec t = { 0 }; + struct EbrTimeval tv; + NSTimeInterval d = [date timeIntervalSinceNow]; + + EbrGetTimeOfDay(&tv); + + t.tv_sec = tv.tv_sec; + t.tv_nsec = tv.tv_usec * 1000; + + t.tv_sec += (unsigned int)d; + t.tv_nsec = (long)((double)t.tv_nsec + fmod(d, 1.0) * 1000000000.0); + + t.tv_sec += t.tv_nsec / 1000000000; + t.tv_nsec %= 1000000000; + + if ((rc = pthread_mutex_lock(&_mutex)) != 0) { + [NSException raise:NSInvalidArgumentException format:@"failed to lock %@ (errno: %d)", self, rc]; + } + + while (_value != condition) { + switch ((rc = pthread_cond_timedwait(&_cond, &_mutex, &t))) { + case 0: + break; + + case ETIMEDOUT: + if ((rc = pthread_mutex_unlock(&_mutex)) != 0) { + [NSException raise:NSInvalidArgumentException format:@"failed to unlock %@ before date %@ (errno: %d)", self, date, rc]; + } + return NO; + + default: + if ((rc = pthread_mutex_unlock(&_mutex)) != 0) { + [NSException raise:NSInvalidArgumentException format:@"failed to unlock %@ before date %@ (errno: %d)", self, date, rc]; + } + [NSException raise:NSInvalidArgumentException format:@"failed to lock %@ before date %@ (errno: %d)", self, date, rc]; + return NO; + } + } + + return YES; } /**