1 mike 1.2 //%2006////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
6 // IBM Corp.; EMC Corporation, The Open Group.
7 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
9 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
11 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
20 //
21 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 mike 1.2 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 //%/////////////////////////////////////////////////////////////////////////////
33
34 #ifndef Pegasus_ReadWriteSem_h
35 #define Pegasus_ReadWriteSem_h
36
37 #include <Pegasus/Common/Config.h>
38 #include <Pegasus/Common/Linkage.h>
39 #include <Pegasus/Common/Semaphore.h>
40 #include <Pegasus/Common/Mutex.h>
41 #include <Pegasus/Common/AtomicInt.h>
42
43 mike 1.2 #define PEG_SEM_READ 1
44 #define PEG_SEM_WRITE 2
45
46 PEGASUS_NAMESPACE_BEGIN
47
48 //==============================================================================
49 //
50 // Select the read-write-lock implementation for your platform:
51 //
52 // PEGASUS_USE_POSIX_RWLOCK
53 // PEGASUS_USE_SEMAPHORE_RWLOCK
54 //
55 //==============================================================================
56
57 #if defined(PEGASUS_PLATFORM_AIX_RS_IBMCXX)
58 # define PEGASUS_USE_POSIX_RWLOCK
|
59 ouyang.jian 1.5 #elif defined(PEGASUS_PLATFORM_PASE_ISERIES_IBMCXX)
60 # define PEGASUS_USE_POSIX_RWLOCK
|
61 mike 1.2 #elif defined(PEGASUS_PLATFORM_HPUX_ACC)
62 # define PEGASUS_USE_POSIX_RWLOCK
63 #elif defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC)
64 # define PEGASUS_USE_POSIX_RWLOCK
65 #elif defined(PEGASUS_PLATFORM_TRU64_ALPHA_DECCXX)
66 # define PEGASUS_USE_POSIX_RWLOCK
67 #elif defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
68 # define PEGASUS_USE_POSIX_RWLOCK
69 #elif defined(PEGASUS_PLATFORM_VMS_IA64_DECCXX)
70 # define PEGASUS_USE_POSIX_RWLOCK
71 #elif defined(PEGASUS_PLATFORM_VMS_ALPHA_DECCXX)
72 # define PEGASUS_USE_POSIX_RWLOCK
73 #elif defined(PEGASUS_PLATFORM_LINUX_X86_64_GNU)
74 # define PEGASUS_USE_POSIX_RWLOCK
75 #else
76 # define PEGASUS_USE_SEMAPHORE_RWLOCK
77 #endif
78
79 //==============================================================================
80 //
81 // ReadWriteSemRep
82 mike 1.2 //
83 //==============================================================================
84
85 #ifdef PEGASUS_USE_POSIX_RWLOCK
86 struct ReadWriteSemRep
87 {
88 pthread_rwlock_t rwlock;
89 ThreadType owner;
90 };
91 #endif /* PEGASUS_USE_POSIX_RWLOCK */
92
93 #ifdef PEGASUS_USE_SEMAPHORE_RWLOCK
94 struct ReadWriteSemRep
95 {
96 Semaphore _rlock;
97 Mutex _wlock;
98 Mutex _internal_lock;
99 ThreadType _owner;
|
100 kumpf 1.3 ReadWriteSemRep() :
|
101 mike 1.2 _rlock(10), _wlock(), _internal_lock(), _owner(Threads::self())
102 {
103 }
104 };
105 #endif /* PEGASUS_USE_POSIX_RWLOCK */
106
107 //==============================================================================
108 //
109 // ReadWriteSem
110 //
111 //==============================================================================
112
113 class PEGASUS_COMMON_LINKAGE ReadWriteSem
114 {
115 public:
116
117 ReadWriteSem();
118
119 ~ReadWriteSem();
120
121 // @exception Deadlock
122 mike 1.2 // @exception Permission
123 // @exception WaitFailed
124 inline void wait_read(ThreadType caller)
125 {
126 wait(PEG_SEM_READ, caller );
127 }
128
129 // @exception Deadlock
130 // @exception Permission
131 // @exception WaitFailed
132 inline void wait_write(ThreadType caller)
133 {
134 wait(PEG_SEM_WRITE, caller);
135 }
136
137 // @exception Deadlock
138 // @exception Permission
139 // @exception AlreadyLocked
140 // @exception WaitFailed
141 inline void try_wait_read(ThreadType caller)
142 {
143 mike 1.2 try_wait(PEG_SEM_READ, caller);
144 }
145
146 // @exception Deadlock
147 // @exception Permission
148 // @exception AlreadyLocked
149 // @exception WaitFailed
150 inline void try_wait_write(ThreadType caller)
151 {
152 try_wait(PEG_SEM_WRITE, caller);
153 }
154
155 // @exception Deadlock
156 // @exception Permission
157 // @exception TimeOut
158 // @exception WaitFailed
159 inline void timed_wait_read(ThreadType caller, int milliseconds)
160 {
161 timed_wait(PEG_SEM_READ, caller, milliseconds);
162 }
163
164 mike 1.2 // @exception Deadlock
165 // @exception Permission
166 // @exception TimeOut
167 // @exception WaitFailed
168 inline void timed_wait_write(ThreadType caller, int milliseconds)
169 {
170 timed_wait(PEG_SEM_WRITE, caller, milliseconds);
171 }
172
173 // @exception Permission
174 inline void unlock_read(ThreadType caller)
175 {
176 unlock(PEG_SEM_READ, caller);
177 }
178
179 // @exception Permission
180 inline void unlock_write(ThreadType caller)
181 {
182 unlock(PEG_SEM_WRITE, caller);
183 }
184
185 mike 1.2 int read_count() const;
186 int write_count() const;
187
188 // @exception Deadlock
189 // @exception Permission
190 // @exception WaitFailed
191 // @exception TooManyReaders
192 void wait(Uint32 mode, ThreadType caller);
193
194 // @exception Deadlock
195 // @exception Permission
196 // @exception WaitFailed
197 // @exception TooManyReaders
198 void try_wait(Uint32 mode, ThreadType caller);
199
200 // @exception Timeout
201 // @exception Deadlock
202 // @exception Permission
203 // @exception WaitFailed
204 // @exception TooManyReaders
205 void timed_wait(Uint32 mode, ThreadType caller, int milliseconds);
206 mike 1.2
207 // @exception Permission
208 void unlock(Uint32 mode, ThreadType caller);
209
210 private:
211 AtomicInt _readers;
212 AtomicInt _writers;
213 ReadWriteSemRep _rwlock;
214 friend void extricate_read_write(void *);
215 };
216
217 //==============================================================================
218 //
219 // ReadLock
220 //
221 //==============================================================================
222
223 class ReadLock
224 {
225 public:
226
|
227 mike 1.5.2.2 ReadLock(ReadWriteSem& rwsem, bool performLock = true)
228 : _rwsem(rwsem), _performLock(performLock)
|
229 mike 1.2 {
|
230 mike 1.5.2.2 if (_performLock)
231 _rwsem.wait_read(Threads::self());
|
232 mike 1.2 }
233
234 ~ReadLock()
235 {
|
236 mike 1.5.2.2 if (_performLock)
237 _rwsem.unlock_read(Threads::self());
|
238 mike 1.2 }
239
240 private:
241 ReadWriteSem & _rwsem;
|
242 mike 1.5.2.2 bool _performLock;
|
243 mike 1.2 };
244
245 //==============================================================================
246 //
247 // WriteLock
248 //
249 //==============================================================================
250
251 class WriteLock
252 {
253 public:
254
|
255 mike 1.5.2.2 WriteLock(ReadWriteSem& rwsem, bool performLock = true)
256 : _rwsem(rwsem), _performLock(performLock)
|
257 mike 1.2 {
|
258 mike 1.5.2.2 if (_performLock)
259 _rwsem.wait_write(Threads::self());
|
260 mike 1.2 }
261
262 ~WriteLock()
263 {
|
264 mike 1.5.2.2 if (_performLock)
265 _rwsem.unlock_write(Threads::self());
|
266 mike 1.2 }
267
268 private:
269 ReadWriteSem & _rwsem;
|
270 mike 1.5.2.2 bool _performLock;
|
271 mike 1.5.2.1 };
272
|
273 mike 1.2 PEGASUS_NAMESPACE_END
274
275 #endif /* Pegasus_ReadWriteSem_h */
|