-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathSSYSystemSemaphore.h
101 lines (86 loc) · 3.37 KB
/
SSYSystemSemaphore.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#import <Cocoa/Cocoa.h>
#import <semaphore.h>
/*!
@brief Cocoa wrapper around the Darwin system semaphore
facility which is declared in semaphore.h.
@details Buggy. If a process crashes after locking but before
relinquishing a semaphore, that semaphore will be hung
forever. We need a forceRelinquish method which
would call sem_unlink(name) unconditionally. See:
http://lists.apple.com/archives/darwin-kernel/2009/Mar/msg00067.html
*/
@interface SSYSystemSemaphore : NSObject {
NSString* name ;
sem_t* descriptor ;
BOOL gotSemaphore ;
NSTimeInterval initialBackoff ;
CGFloat backoffFactor ;
NSTimeInterval maxBackoff ;
NSTimeInterval timeout ;
}
@property (copy) NSString* name ;
@property sem_t* descriptor ;
@property BOOL gotSemaphore ;
@property NSTimeInterval initialBackoff ;
@property CGFloat backoffFactor ;
@property NSTimeInterval maxBackoff ;
@property NSTimeInterval timeout ;
/*!
@brief Returns a process-wide shared system semaphore
@details Since I've been engineering for 30 years and just
had a use for one of these, I figured one would be enough
in many cases. Useful, for example, if an entire process
needs to acquire an exclusive semaphore before doing its work.
*/
+ (SSYSystemSemaphore*)sharedSemaphore ;
/*!
@brief Configures a system semaphore
@details Send this message to configure a system semaphore
before sending any other messages to it.
@param name_ A name for the system semaphore
@param backoff_ The time interval for which -lockError_p
will sleep before retrying if it is not able to acquire the
its named system semaphore. Normally, you set this
to the expected time that it might take another user to
relinquish the system semaphore.
@param timeout_ The time interval after which lockError_p
will give up and return NO if it cannot acquire its receiver's
system semaphore
*/
- (void)setName:(NSString*)name_
initialBackoff:(NSTimeInterval)initialBackoff_
backoffFactor:(CGFloat)backoffFactor_
maxBackoff:(NSTimeInterval)maxBackoff_
timeout:(NSTimeInterval)timeout_ ;
/*!
@brief Attempts to exclusively the receiver's system semaphore,
blocking and retrying up to its timeout.
@details Send this message before beginning a task which
needs exclusive access to system resources guarded by the
semaphore.
Begins by setting the receiver's current backoff, a private
attribute, to its initial backoff. Then begins attempts...
If the receiver's system semaphore cannot be obtained
because it already exists exclusively on the system, sleeps for
the receiver's current backoff, multiplies the backoff by the
backoff factor, limits the backoff to the max backoff, and
repeats this until either the semaphore is obtained or the
receiver's timeout is exceeded.
@param error_p Upon return, if an error occurs, points to a
relevant NSError*. If a timeout occurred, the error
code will be ETIME. Pass NULL if you don't want the error.
@result YES if the semaphore was obtained.
NO if the timeout was exceeded, or some other unrecoverable
eror occurred.
*/
- (BOOL)lockError_p:(NSError**)error_p ;
/*!
@brief
@details Send this message to relinquish the semaphore
after a task requiring exclusive access to system resources
guarded by the semaphore has completed.
@param error_p
@result
*/
- (BOOL)relinquishError_p:(NSError**)error_p ;
@end