1 karl 1.23 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.2 //
|
3 karl 1.17 // 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 karl 1.15 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.17 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.20 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.23 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mike 1.2 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
15 kumpf 1.7 // 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 mike 1.2 // 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 karl 1.20 //
|
21 kumpf 1.7 // 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 kumpf 1.7 // 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 mike 1.2 // 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 // Author: Mike Day (mdday@us.ibm.com)
33 //
|
34 david.dillard 1.19 // Modified By: David Dillard, VERITAS Software Corp.
35 // (david.dillard@veritas.com)
|
36 mike 1.2 //
37 //%/////////////////////////////////////////////////////////////////////////////
38
39
|
40 david.dillard 1.19 //%// ---- inline implmentations of Windows IPC routines ----
|
41 mike 1.2
42 #ifndef IPCWindows_inline_h
43 #define IPCWindows_inline_h
44
45 //-----------------------------------------------------------------
46 /// Native Windows inline implementation of Mutex class
47 //-----------------------------------------------------------------
48
|
49 david.dillard 1.19 // block until gaining the lock - throw a deadlock
50 // exception if process already holds the lock
|
51 david.dillard 1.21 inline void Mutex::lock(PEGASUS_THREAD_TYPE caller)
|
52 mike 1.2 {
|
53 david.dillard 1.19 if(_mutex.owner == caller)
54 throw( Deadlock( _mutex.owner ) );
|
55 mike 1.2
|
56 david.dillard 1.19 DWORD errorcode = WaitForSingleObject(_mutex.mut, INFINITE);
57 if(errorcode == WAIT_FAILED)
58 throw( WaitFailed( _mutex.owner) );
59 _mutex.owner = caller;
|
60 mike 1.2 }
|
61 david.dillard 1.19
62 // try to gain the lock - lock succeeds immediately if the
|
63 mike 1.2 // mutex is not already locked. throws an exception and returns
|
64 david.dillard 1.19 // immediately if the mutex is currently locked.
|
65 david.dillard 1.21 inline void Mutex::try_lock(PEGASUS_THREAD_TYPE caller)
|
66 mike 1.2 {
|
67 david.dillard 1.19 if(_mutex.owner == caller)
68 throw( Deadlock( _mutex.owner ) );
|
69 mike 1.2
|
70 david.dillard 1.19 DWORD errorcode = WaitForSingleObject(_mutex.mut, 0);
71 if (errorcode == WAIT_TIMEOUT)
72 throw(AlreadyLocked(_mutex.owner));
73 if(errorcode == WAIT_FAILED)
74 throw(WaitFailed(_mutex.owner));
75 _mutex.owner = caller;
|
76 mike 1.2 }
77
78 // wait for milliseconds and throw an exception then return if the wait
79 // expires without gaining the lock. Otherwise return without throwing an
80 // exception.
81
|
82 david.dillard 1.19 inline void Mutex::timed_lock( Uint32 milliseconds , PEGASUS_THREAD_TYPE caller)
|
83 mike 1.2 {
|
84 david.dillard 1.19 if(_mutex.owner == caller)
85 throw( Deadlock( _mutex.owner ) );
|
86 mike 1.2
|
87 david.dillard 1.19 DWORD errorcode = WaitForSingleObject(_mutex.mut, milliseconds);
88 if (errorcode == WAIT_TIMEOUT)
89 throw(TimeOut(_mutex.owner));
90 if(errorcode == WAIT_FAILED)
91 throw(WaitFailed(_mutex.owner));
92 _mutex.owner = caller;
|
93 mike 1.2 }
94
95 // unlock the mutex
|
96 david.dillard 1.21 inline void Mutex::unlock()
|
97 mike 1.2 {
|
98 david.dillard 1.19 PEGASUS_THREAD_TYPE m_owner = _mutex.owner;
99 _mutex.owner = 0;
100 ReleaseMutex(_mutex.mut);
|
101 mike 1.2 }
102
103
104 //-----------------------------------------------------------------
105 /// Native Windows inline implementation of Semaphore class
106 //-----------------------------------------------------------------
107
108 // block until this semaphore is in a signalled state
|
109 brian.campbell 1.18 // note that windows does not support interrupt
|
110 david.dillard 1.21 inline void Semaphore::wait(Boolean ignoreInterrupt)
|
111 mike 1.2 {
|
112 david.dillard 1.19 DWORD errorcode = WaitForSingleObject(_semaphore.sem, INFINITE);
113 if(errorcode != WAIT_FAILED)
114 _count--;
115 else
116 throw(WaitFailed((PEGASUS_THREAD_TYPE)GetCurrentThreadId()));
|
117 mike 1.2 }
118
|
119 david.dillard 1.19 // wait succeeds immediately if semaphore has a non-zero count,
120 // return immediately and throw and exception if the
121 // count is zero.
|
122 david.dillard 1.21 inline void Semaphore::try_wait()
|
123 mike 1.2 {
|
124 david.dillard 1.19 DWORD errorcode = WaitForSingleObject(_semaphore.sem, 0);
125 if(errorcode == WAIT_TIMEOUT || errorcode == WAIT_FAILED)
126 throw(WaitFailed((PEGASUS_THREAD_TYPE)GetCurrentThreadId()));
127 _count--;
|
128 mike 1.2 }
129
130
131 // wait for milliseconds and throw an exception
132 // if wait times out without gaining the semaphore
|
133 david.dillard 1.21 inline void Semaphore::time_wait(Uint32 milliseconds)
|
134 mike 1.2 {
|
135 david.dillard 1.19 DWORD errorcode = WaitForSingleObject(_semaphore.sem, milliseconds);
136 if (errorcode == WAIT_TIMEOUT || errorcode == WAIT_FAILED)
137 throw(TimeOut((PEGASUS_THREAD_TYPE)GetCurrentThreadId()));
138 _count--;
|
139 mike 1.2 }
140
|
141 david.dillard 1.19 // increment the count of the semaphore
|
142 mike 1.2 inline void Semaphore::signal()
143 {
|
144 david.dillard 1.19 _count++;
145 ReleaseSemaphore(_semaphore.sem, 1, NULL);
|
146 mike 1.2 }
147
148 // return the count of the semaphore
|
149 david.dillard 1.21 inline int Semaphore::count() const
|
150 mike 1.2 {
|
151 david.dillard 1.19 return(_count);
|
152 mike 1.2 }
153
154
155 //_________________________________________________________________
156 //
157 /// Native Windows implementation of the conditional semaphore
158 //_________________________________________________________________
159
|
160 david.dillard 1.19 #ifdef PEGASUS_CONDITIONAL_NATIVE
|
161 mike 1.2
162 inline void Condition::signal(PEGASUS_THREAD_TYPE caller)
163 {
|
164 david.dillard 1.19 _cond_mutex->lock(caller);
165 try
166 {
167 unlocked_signal(caller);
168 }
169 catch(...)
170 {
171 unlock_object();
172 throw;
173 }
174 _cond_mutex->unlock();
|
175 mike 1.2 }
176
177 inline void Condition::unlocked_signal(PEGASUS_THREAD_TYPE caller)
178 {
|
179 david.dillard 1.19 if(_cond_mutex->_mutex.owner != caller)
180 throw Permission((PEGASUS_THREAD_TYPE)caller);
|
181 tony 1.13
|
182 david.dillard 1.19 // Change from PulseEvent to SetEvent, this is part of
|
183 tony 1.13 // fix to avoid deadlock in CIMClient Constructor.
184 //PulseEvent(_condition);
185 SetEvent(_condition);
|
186 mike 1.2 }
187
188 inline void Condition::lock_object(PEGASUS_THREAD_TYPE caller)
189 {
|
190 mike 1.22 if(_disallow.get() > 0 )
|
191 david.dillard 1.19 throw ListClosed();
192 _cond_mutex->lock(caller);
|
193 mike 1.2 }
194
195 inline void Condition::try_lock_object(PEGASUS_THREAD_TYPE caller)
196 {
|
197 mike 1.22 if(_disallow.get() > 0 )
|
198 david.dillard 1.19 throw ListClosed();
199 _cond_mutex->try_lock(caller);
|
200 mike 1.2 }
201
202 inline void Condition::wait_lock_object(PEGASUS_THREAD_TYPE caller, int milliseconds)
203 {
|
204 mike 1.22 if(_disallow.get() > 0)
|
205 david.dillard 1.19 throw ListClosed();
206 _cond_mutex->timed_lock(milliseconds, caller);
|
207 mike 1.22 if( _disallow.get() > 0 )
|
208 david.dillard 1.19 {
209 _cond_mutex->unlock();
210 throw ListClosed();
211 }
|
212 mike 1.2 }
213
214 inline void Condition::unlock_object(void)
215 {
|
216 david.dillard 1.19 _cond_mutex->unlock();
|
217 mike 1.2 }
218
219 inline void Condition::unlocked_wait(PEGASUS_THREAD_TYPE caller)
220 {
|
221 david.dillard 1.19 unlocked_timed_wait(-1, caller);
|
222 mike 1.2 }
223
224 inline void Condition::unlocked_timed_wait(int milliseconds, PEGASUS_THREAD_TYPE caller)
225 {
|
226 mike 1.22 if(_disallow.get() > 0)
|
227 david.dillard 1.19 {
228 _cond_mutex->unlock();
229 throw ListClosed();
230 }
231
232 if(_cond_mutex->_mutex.owner != caller)
233 throw Permission((PEGASUS_THREAD_TYPE)caller);
234 if(milliseconds == -1)
235 milliseconds = INFINITE;
|
236 tony 1.13
|
237 david.dillard 1.19 // Change from PulseEvent to SetEvent, this is part of
238 // fix to avoid deadlock in CIMClient Constructor
|
239 tony 1.13 // Change added next line since SignalObjectAndWait
240 // releases the mutex
241 _cond_mutex->_mutex.owner = 0;
242
|
243 david.dillard 1.19 DWORD retcode = SignalObjectAndWait(_cond_mutex->_mutex.mut, _condition,
244 milliseconds, false);
245 if(retcode == WAIT_TIMEOUT)
246 throw TimeOut(pegasus_thread_self());
247 _cond_mutex->lock(caller);
|
248 mike 1.2 }
249
250
|
251 david.dillard 1.19 #endif // inline native conditional
|
252 mike 1.2
253 #endif // IPCWindows_inline_h
|