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 #elif defined(PEGASUS_PLATFORM_HPUX_ACC)
60 # define PEGASUS_USE_POSIX_RWLOCK
61 #elif defined(PEGASUS_PLATFORM_OS400_ISERIES_IBM)
62 # define PEGASUS_USE_POSIX_RWLOCK
63 #elif defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC)
64 mike 1.2 # 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 //
83 //==============================================================================
84
85 mike 1.2 #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;
|
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.2 ReadLock(ReadWriteSem& rwsem) : _rwsem(rwsem)
228 {
229 _rwsem.wait_read(Threads::self());
230 }
231
232 ~ReadLock()
233 {
234 _rwsem.unlock_read(Threads::self());
235 }
236
237 private:
238 ReadWriteSem & _rwsem;
239 };
240
241 //==============================================================================
242 //
243 // WriteLock
244 //
245 //==============================================================================
246
247 class WriteLock
248 mike 1.2 {
249 public:
250
251 WriteLock(ReadWriteSem& rwsem) : _rwsem(rwsem)
252 {
253 _rwsem.wait_write(Threads::self());
254 }
255
256 ~WriteLock()
257 {
258 _rwsem.unlock_write(Threads::self());
259 }
260
261 private:
262 ReadWriteSem & _rwsem;
263 };
264
265 PEGASUS_NAMESPACE_END
266
267 #endif /* Pegasus_ReadWriteSem_h */
|