4
Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea.
7
Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
9
This file is part of libFoundation.
11
Permission to use, copy, modify, and distribute this software and its
12
documentation for any purpose and without fee is hereby granted, provided
13
that the above copyright notice appear in all copies and that both that
14
copyright notice and this permission notice appear in supporting
17
We disclaim all warranties with regard to this software, including all
18
implied warranties of merchantability and fitness, in no event shall
19
we be liable for any special, indirect or consequential damages or any
20
damages whatsoever resulting from loss of use, data or profits, whether in
21
an action of contract, negligence or other tortious action, arising out of
22
or in connection with the use or performance of this software.
25
#include <Foundation/common.h>
26
#include <Foundation/NSLock.h>
28
#include <Foundation/NSException.h>
29
#include <Foundation/exceptions/GeneralExceptions.h>
30
#include <extensions/objc-runtime.h>
33
NSRecursiveLock* libFoundationLock = nil;
36
* NSLock - lock of depth limited to 1
39
@implementation NSLock
43
mutex = objc_mutex_allocate();
54
objc_mutex_deallocate(mutex);
60
if (objc_mutex_lock(mutex) > 1) {
61
[[[InvalidUseOfMethodException alloc] initWithFormat:
62
@"attempt to lock a simple lock (NSLock) multiple times"] raise];
68
int depth = objc_mutex_trylock(mutex);
71
[[[InvalidUseOfMethodException alloc] initWithFormat:
72
@"attempt to lock a simple lock (NSLock) multiple times"] raise];
75
return depth == 1 ? YES : NO;
78
- (BOOL)lockBeforeDate:(NSDate *)limit
80
// TODO: Temporary implementation
87
if (objc_mutex_unlock(mutex) < 0) {
88
[[[InvalidUseOfMethodException alloc] initWithFormat:
89
@"attempt to unlock a lock not owned by the current thread"] raise];
96
* NSLock - lock of unlimited (MAX_INT) depth
99
@implementation NSRecursiveLock
103
mutex = objc_mutex_allocate();
114
objc_mutex_deallocate(mutex);
120
if (objc_mutex_lock(mutex) < 0)
121
[[[InvalidUseOfMethodException alloc] initWithFormat:
122
@"attempt to lock an invalid lock"] raise];
127
return objc_mutex_trylock(mutex) > 0 ? YES : NO;
130
- (BOOL)lockBeforeDate:(NSDate *)limit
132
// TODO: Temporary implementation
139
if (objc_mutex_unlock(mutex) < 0)
140
[[[InvalidUseOfMethodException alloc] initWithFormat:
141
@"attempt to unlock a lock not owned by the current thread"] raise];
144
@end /* NSRecursiveLock:NSObject */
150
@implementation NSConditionLock
154
return [self initWithCondition:0];
157
- initWithCondition:(int)aCondition
159
mutex = objc_mutex_allocate();
164
condition = objc_condition_allocate();
176
objc_condition_deallocate(condition);
178
objc_mutex_deallocate(mutex);
189
if (objc_mutex_lock(mutex) < 0)
190
[[[InvalidUseOfMethodException alloc] initWithFormat:
191
@"attempt to lock an invalid lock"] raise];
194
- (void)lockWhenCondition:(int)aCondition
198
// Try to lock the mutex
199
depth = objc_mutex_lock(mutex);
203
[[[InvalidUseOfMethodException alloc] initWithFormat:
204
@"attempt to lock an invalid lock"] raise];
206
// Error if recursive lock and condition is false
207
if ((depth > 1) && (value != aCondition))
208
[[[InvalidUseOfMethodException alloc] initWithFormat:
209
@"attempt to lock a condition lock multiple times"
210
@"with a different condition value"] raise];
213
while (value != aCondition)
214
objc_condition_wait(condition, mutex);
217
- (BOOL)lockBeforeDate:(NSDate *)limit
219
// TODO: Temporary implementation
224
- (BOOL)lockWhenCondition:(int)aCondition beforeDate:(NSDate *)limit
226
// TODO: Temporary implementation
227
[self lockWhenCondition:aCondition];
233
return objc_mutex_trylock(mutex) > 0 ? YES : NO;
236
- (BOOL)tryLockWhenCondition:(int)aCondition
241
if (value != aCondition) {
242
objc_mutex_unlock(mutex);
251
if (objc_mutex_unlock(mutex) < 0)
252
[[[InvalidUseOfMethodException alloc] initWithFormat:
253
@"attempt to unlock a lock not owned by the current thread"] raise];
256
- (void)unlockWithCondition:(int)aCondition
260
// Try to lock the mutex again
261
depth = objc_mutex_trylock(mutex);
263
// Another thread has the lock so abort
265
[[[InvalidUseOfMethodException alloc] initWithFormat:
266
@"attempt to lock an invalid lock"] raise];
268
// If the depth is only 1 then we just acquired
269
// the lock above, bogus unlock so abort
271
[[[InvalidUseOfMethodException alloc] initWithFormat:
272
@"attempt to unlock with condition a lock "
273
@"not owned by the current thread"] raise];
277
// Wake up threads waiting a condition to happen
278
objc_condition_broadcast(condition);
279
// This is a valid unlock so set the condition and unlock twice
280
objc_mutex_unlock(mutex);
281
objc_mutex_unlock(mutex);
284
@end /* NSConditionLock:NSObject */