~ubuntu-branches/ubuntu/edgy/sope/edgy

« back to all changes in this revision

Viewing changes to libFoundation/Foundation/NSLock.m

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Ley
  • Date: 2005-08-19 16:53:31 UTC
  • Revision ID: james.westby@ubuntu.com-20050819165331-hs683wz1osm708pw
Tags: upstream-4.4rc.2
ImportĀ upstreamĀ versionĀ 4.4rc.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
   NSLock.m
 
3
 
 
4
   Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea.
 
5
   All rights reserved.
 
6
 
 
7
   Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
 
8
 
 
9
   This file is part of libFoundation.
 
10
 
 
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
 
15
   documentation.
 
16
 
 
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.
 
23
*/
 
24
 
 
25
#include <Foundation/common.h>
 
26
#include <Foundation/NSLock.h>
 
27
 
 
28
#include <Foundation/NSException.h>
 
29
#include <Foundation/exceptions/GeneralExceptions.h>
 
30
#include <extensions/objc-runtime.h>
 
31
#include <config.h>
 
32
 
 
33
NSRecursiveLock* libFoundationLock = nil;
 
34
 
 
35
/*
 
36
 * NSLock - lock of depth limited to 1
 
37
 */
 
38
 
 
39
@implementation NSLock
 
40
 
 
41
- init
 
42
{
 
43
    mutex = objc_mutex_allocate();
 
44
    if (!mutex) {
 
45
        RELEASE(self);
 
46
        return nil;
 
47
    }
 
48
    return self;
 
49
}
 
50
 
 
51
- (void)dealloc
 
52
{
 
53
    if (mutex)
 
54
        objc_mutex_deallocate(mutex);
 
55
    [super dealloc];
 
56
}
 
57
 
 
58
- (void)lock
 
59
{
 
60
    if (objc_mutex_lock(mutex) > 1) {
 
61
        [[[InvalidUseOfMethodException alloc] initWithFormat:
 
62
            @"attempt to lock a simple lock (NSLock) multiple times"] raise];
 
63
    }
 
64
}
 
65
 
 
66
- (BOOL)tryLock
 
67
{
 
68
    int depth = objc_mutex_trylock(mutex);
 
69
    
 
70
    if (depth > 1) {
 
71
        [[[InvalidUseOfMethodException alloc] initWithFormat:
 
72
            @"attempt to lock a simple lock (NSLock) multiple times"] raise];
 
73
    }
 
74
    
 
75
    return depth == 1 ? YES : NO;
 
76
}
 
77
 
 
78
- (BOOL)lockBeforeDate:(NSDate *)limit
 
79
{
 
80
    // TODO: Temporary implementation
 
81
    [self lock];
 
82
    return YES;
 
83
}
 
84
 
 
85
- (void)unlock
 
86
{
 
87
    if (objc_mutex_unlock(mutex) < 0) {
 
88
        [[[InvalidUseOfMethodException alloc] initWithFormat:
 
89
            @"attempt to unlock a lock not owned by the current thread"] raise];
 
90
    }
 
91
}
 
92
 
 
93
@end /* NSLock */
 
94
 
 
95
/*
 
96
 * NSLock - lock of unlimited (MAX_INT) depth
 
97
 */
 
98
 
 
99
@implementation NSRecursiveLock
 
100
 
 
101
- init
 
102
{
 
103
    mutex = objc_mutex_allocate();
 
104
    if (!mutex) {
 
105
        RELEASE(self);
 
106
        return nil;
 
107
    }
 
108
    return self;
 
109
}
 
110
 
 
111
- (void)dealloc
 
112
{
 
113
    if (mutex)
 
114
        objc_mutex_deallocate(mutex);
 
115
    [super dealloc];
 
116
}
 
117
 
 
118
- (void)lock
 
119
{
 
120
    if (objc_mutex_lock(mutex) < 0)
 
121
        [[[InvalidUseOfMethodException alloc] initWithFormat:
 
122
            @"attempt to lock an invalid lock"] raise];
 
123
}
 
124
 
 
125
- (BOOL)tryLock
 
126
{
 
127
    return objc_mutex_trylock(mutex) > 0 ? YES : NO;
 
128
}
 
129
 
 
130
- (BOOL)lockBeforeDate:(NSDate *)limit
 
131
{
 
132
    // TODO: Temporary implementation
 
133
    [self lock];
 
134
    return YES;
 
135
}
 
136
 
 
137
- (void)unlock
 
138
{
 
139
    if (objc_mutex_unlock(mutex) < 0)
 
140
        [[[InvalidUseOfMethodException alloc] initWithFormat:
 
141
            @"attempt to unlock a lock not owned by the current thread"] raise];
 
142
}
 
143
 
 
144
@end /* NSRecursiveLock:NSObject */
 
145
 
 
146
/*
 
147
 * Condition lock
 
148
 */
 
149
 
 
150
@implementation NSConditionLock
 
151
 
 
152
- init
 
153
{
 
154
    return [self initWithCondition:0];
 
155
}
 
156
 
 
157
- initWithCondition:(int)aCondition
 
158
{
 
159
    mutex = objc_mutex_allocate();
 
160
    if (!mutex) {
 
161
        RELEASE(self);
 
162
        return nil;
 
163
    }
 
164
    condition = objc_condition_allocate();
 
165
    if (!condition) {
 
166
        RELEASE(self);
 
167
        return nil;
 
168
    }
 
169
    value = aCondition;
 
170
    return self;
 
171
}
 
172
 
 
173
- (void)dealloc
 
174
{
 
175
    if (condition)
 
176
        objc_condition_deallocate(condition);
 
177
    if (mutex)
 
178
        objc_mutex_deallocate(mutex);
 
179
    [super dealloc];
 
180
}
 
181
 
 
182
- (int)condition
 
183
{
 
184
    return value;
 
185
}
 
186
 
 
187
- (void)lock
 
188
{
 
189
    if (objc_mutex_lock(mutex) < 0)
 
190
        [[[InvalidUseOfMethodException alloc] initWithFormat:
 
191
            @"attempt to lock an invalid lock"] raise];
 
192
}
 
193
 
 
194
- (void)lockWhenCondition:(int)aCondition
 
195
{
 
196
    int depth;
 
197
    
 
198
    // Try to lock the mutex
 
199
    depth = objc_mutex_lock(mutex);
 
200
 
 
201
    // Return on error
 
202
    if (depth == -1)
 
203
        [[[InvalidUseOfMethodException alloc] initWithFormat:
 
204
            @"attempt to lock an invalid lock"] raise];
 
205
            
 
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];
 
211
 
 
212
    // Wait condition
 
213
    while (value != aCondition)
 
214
            objc_condition_wait(condition, mutex);
 
215
}
 
216
 
 
217
- (BOOL)lockBeforeDate:(NSDate *)limit
 
218
{
 
219
    // TODO: Temporary implementation
 
220
    [self lock];
 
221
    return YES;
 
222
}
 
223
 
 
224
- (BOOL)lockWhenCondition:(int)aCondition beforeDate:(NSDate *)limit
 
225
{
 
226
    // TODO: Temporary implementation
 
227
    [self lockWhenCondition:aCondition];
 
228
    return YES;
 
229
}
 
230
 
 
231
- (BOOL)tryLock
 
232
{
 
233
    return objc_mutex_trylock(mutex) > 0 ? YES : NO;
 
234
}
 
235
 
 
236
- (BOOL)tryLockWhenCondition:(int)aCondition
 
237
{
 
238
    if (![self tryLock])
 
239
        return NO;
 
240
    
 
241
    if (value != aCondition) {
 
242
        objc_mutex_unlock(mutex);
 
243
        return NO;
 
244
    }
 
245
    
 
246
    return YES;
 
247
}
 
248
 
 
249
- (void)unlock
 
250
{
 
251
    if (objc_mutex_unlock(mutex) < 0)
 
252
        [[[InvalidUseOfMethodException alloc] initWithFormat:
 
253
            @"attempt to unlock a lock not owned by the current thread"] raise];
 
254
}
 
255
 
 
256
- (void)unlockWithCondition:(int)aCondition
 
257
{
 
258
    int depth;
 
259
    
 
260
    // Try to lock the mutex again
 
261
    depth = objc_mutex_trylock(mutex);
 
262
    
 
263
    // Another thread has the lock so abort
 
264
    if (depth == -1)
 
265
        [[[InvalidUseOfMethodException alloc] initWithFormat:
 
266
            @"attempt to lock an invalid lock"] raise];
 
267
    
 
268
    // If the depth is only 1 then we just acquired
 
269
    // the lock above, bogus unlock so abort
 
270
    if (depth == 1)
 
271
        [[[InvalidUseOfMethodException alloc] initWithFormat:
 
272
            @"attempt to unlock with condition a lock "
 
273
            @"not owned by the current thread"] raise];
 
274
    
 
275
    value = aCondition;
 
276
    
 
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);
 
282
}
 
283
 
 
284
@end /* NSConditionLock:NSObject */
 
285
 
 
286
/*
 
287
  Local Variables:
 
288
  c-basic-offset: 4
 
289
  tab-width: 8
 
290
  End:
 
291
*/