(file) Return to IPCWindows_inline.h CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

  1 karl  1.20 //%2005////////////////////////////////////////////////////////////////////////
  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 mike  1.2  //
 12            // Permission is hereby granted, free of charge, to any person obtaining a copy
 13 kumpf 1.7  // of this software and associated documentation files (the "Software"), to
 14            // deal in the Software without restriction, including without limitation the
 15            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 16 mike  1.2  // sell copies of the Software, and to permit persons to whom the Software is
 17            // furnished to do so, subject to the following conditions:
 18 karl  1.20 // 
 19 kumpf 1.7  // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 20 mike  1.2  // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 21            // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 22 kumpf 1.7  // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 23            // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 24            // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 25 mike  1.2  // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 26            // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 27            //
 28            //==============================================================================
 29            //
 30            // Author: Mike Day (mdday@us.ibm.com)
 31            //
 32 david.dillard 1.19 // Modified By: David Dillard, VERITAS Software Corp.
 33                    //              (david.dillard@veritas.com)
 34 mike          1.2  //
 35                    //%/////////////////////////////////////////////////////////////////////////////
 36                    
 37                    
 38 david.dillard 1.19 //%// ---- inline implmentations of Windows IPC routines ----
 39 mike          1.2  
 40                    #ifndef IPCWindows_inline_h
 41                    #define IPCWindows_inline_h
 42                    
 43                    //-----------------------------------------------------------------
 44                    /// Native Windows inline implementation of Mutex class
 45                    //-----------------------------------------------------------------
 46                    
 47 david.dillard 1.19 // block until gaining the lock - throw a deadlock
 48                    // exception if process already holds the lock
 49 mike          1.2  inline void Mutex::lock(PEGASUS_THREAD_TYPE caller) throw(Deadlock, WaitFailed)
 50                    {
 51 david.dillard 1.19     if(_mutex.owner == caller)
 52                            throw( Deadlock( _mutex.owner ) );
 53 mike          1.2  
 54 david.dillard 1.19     DWORD errorcode = WaitForSingleObject(_mutex.mut, INFINITE);
 55                        if(errorcode == WAIT_FAILED)
 56                            throw( WaitFailed( _mutex.owner) );
 57                        _mutex.owner = caller;
 58 mike          1.2  }
 59 david.dillard 1.19 
 60                    // try to gain the lock - lock succeeds immediately if the
 61 mike          1.2  // mutex is not already locked. throws an exception and returns
 62 david.dillard 1.19 // immediately if the mutex is currently locked.
 63 mike          1.2  inline void Mutex::try_lock(PEGASUS_THREAD_TYPE caller) throw(Deadlock, AlreadyLocked, WaitFailed)
 64                    {
 65 david.dillard 1.19     if(_mutex.owner == caller)
 66                            throw( Deadlock( _mutex.owner ) );
 67 mike          1.2  
 68 david.dillard 1.19     DWORD errorcode = WaitForSingleObject(_mutex.mut, 0);
 69                        if (errorcode == WAIT_TIMEOUT)
 70                            throw(AlreadyLocked(_mutex.owner));
 71                        if(errorcode == WAIT_FAILED)
 72                            throw(WaitFailed(_mutex.owner));
 73                        _mutex.owner = caller;
 74 mike          1.2  }
 75                    
 76                    // wait for milliseconds and throw an exception then return if the wait
 77                    // expires without gaining the lock. Otherwise return without throwing an
 78                    // exception.
 79                    
 80 david.dillard 1.19 inline void Mutex::timed_lock( Uint32 milliseconds , PEGASUS_THREAD_TYPE caller)
 81                        throw(Deadlock, TimeOut, WaitFailed)
 82 mike          1.2  {
 83 david.dillard 1.19     if(_mutex.owner == caller)
 84                            throw( Deadlock( _mutex.owner ) );
 85 mike          1.2  
 86 david.dillard 1.19     DWORD errorcode = WaitForSingleObject(_mutex.mut, milliseconds);
 87                        if (errorcode == WAIT_TIMEOUT)
 88                            throw(TimeOut(_mutex.owner));
 89                        if(errorcode == WAIT_FAILED)
 90                            throw(WaitFailed(_mutex.owner));
 91                        _mutex.owner = caller;
 92 mike          1.2  }
 93                    
 94                    // unlock the mutex
 95                    inline void Mutex::unlock() throw(Permission)
 96                    {
 97 david.dillard 1.19     PEGASUS_THREAD_TYPE m_owner = _mutex.owner;
 98                        _mutex.owner = 0;
 99                        ReleaseMutex(_mutex.mut);
100 mike          1.2  }
101                    
102                    
103                    //-----------------------------------------------------------------
104                    /// Native Windows inline implementation of Semaphore class
105                    //-----------------------------------------------------------------
106                    
107                    // block until this semaphore is in a signalled state
108 brian.campbell 1.18 // note that windows does not support interrupt
109 david.dillard  1.19 inline void Semaphore::wait(Boolean ignoreInterrupt) throw(WaitFailed, WaitInterrupted)
110 mike           1.2  {
111 david.dillard  1.19     DWORD errorcode = WaitForSingleObject(_semaphore.sem, INFINITE);
112                         if(errorcode != WAIT_FAILED)
113                             _count--;
114                         else
115                             throw(WaitFailed((PEGASUS_THREAD_TYPE)GetCurrentThreadId()));
116 mike           1.2  }
117                     
118 david.dillard  1.19 // wait succeeds immediately if semaphore has a non-zero count,
119                     // return immediately and throw and exception if the
120                     // count is zero.
121 mike           1.2  inline void Semaphore::try_wait(void) throw(WaitFailed)
122                     {
123 david.dillard  1.19     DWORD errorcode = WaitForSingleObject(_semaphore.sem, 0);
124                         if(errorcode == WAIT_TIMEOUT || errorcode == WAIT_FAILED)
125                             throw(WaitFailed((PEGASUS_THREAD_TYPE)GetCurrentThreadId()));
126                         _count--;
127 mike           1.2  }
128                     
129                     
130                     // wait for milliseconds and throw an exception
131                     // if wait times out without gaining the semaphore
132                     inline void Semaphore::time_wait( Uint32 milliseconds ) throw(TimeOut)
133                     {
134 david.dillard  1.19     DWORD errorcode = WaitForSingleObject(_semaphore.sem, milliseconds);
135                         if (errorcode == WAIT_TIMEOUT || errorcode == WAIT_FAILED)
136                             throw(TimeOut((PEGASUS_THREAD_TYPE)GetCurrentThreadId()));
137                         _count--;
138 mike           1.2  }
139                     
140 david.dillard  1.19 // increment the count of the semaphore
141 mike           1.2  inline void Semaphore::signal()
142                     {
143 david.dillard  1.19     _count++;
144                         ReleaseSemaphore(_semaphore.sem, 1, NULL);
145 mike           1.2  }
146                     
147                     // return the count of the semaphore
148 david.dillard  1.19 inline int Semaphore::count()
149 mike           1.2  {
150 david.dillard  1.19     return(_count);
151 mike           1.2  }
152                     
153                     
154                     //-----------------------------------------------------------------
155                     /// Native Windows inline implementation of AtomicInt class
156                     //-----------------------------------------------------------------
157                     #if defined(PEGASUS_ATOMIC_INT_NATIVE)
158                     
159 david.dillard  1.19 inline AtomicInt& AtomicInt::operator=(const AtomicInt& original)
160 mike           1.2  {
161 david.dillard  1.19     InterlockedExchange(&_rep, original._rep);
162                         return *this;
163 mike           1.2  }
164                     
165                     inline AtomicInt& AtomicInt::operator=(Uint32 val)
166                     {
167 david.dillard  1.19     InterlockedExchange(&_rep, val);
168                         return *this;
169 mike           1.2  }
170                     
171 kumpf          1.8  inline Uint32 AtomicInt::value(void) const
172 mike           1.2  {
173 david.dillard  1.19     return ((Uint32)_rep);
174 mike           1.2  }
175                     
176                     inline void AtomicInt::operator++(void) { InterlockedIncrement(&_rep); }
177                     inline void AtomicInt::operator--(void) { InterlockedDecrement(&_rep); }
178                     inline void AtomicInt::operator++(int) { InterlockedIncrement(&_rep); }
179                     inline void AtomicInt::operator--(int) { InterlockedDecrement(&_rep); }
180                     
181 david.dillard  1.19 inline Uint32 AtomicInt::operator+(const AtomicInt& val)
182                     {
183                         //InterlockedExchangeAdd(&_rep, val._rep);
184                         return (_rep + val._rep);
185                     }
186                     
187                     inline Uint32 AtomicInt::operator+(Uint32 val)
188                     {
189                         //InterlockedExchangeAdd(&_rep, val);
190                         return (_rep + val);
191                     }
192                     
193                     inline Uint32 AtomicInt::operator-(const AtomicInt& val)
194                     {
195                         //LONG temp_operand, temp_result;
196                         //temp_operand = InterlockedExchangeAdd((long *)&(val._rep), 0);
197                         //temp_result = InterlockedExchangeAdd(&_rep, 0);
198                         //return(temp_result - temp_operand);
199                         return (_rep - val._rep);
200                     }
201                     
202 david.dillard  1.19 inline Uint32 AtomicInt::operator-(Uint32 val)
203                     {
204                         //LONG temp_operand, temp_result;
205                         //temp_operand = InterlockedExchangeAdd( (long *)&val, 0);
206                         //temp_result = InterlockedExchangeAdd(&_rep, 0);
207                         //return(temp_result - temp_operand);
208                         return (_rep - val);
209                     }
210                     
211                     inline AtomicInt& AtomicInt::operator+=(const AtomicInt& val)
212                     {
213                         InterlockedExchangeAdd(&_rep, val._rep);
214                         return *this;
215                     }
216                     
217                     inline AtomicInt& AtomicInt::operator+=(Uint32 val)
218                     {
219                         InterlockedExchangeAdd(&_rep, val);
220                         return *this;
221                     }
222                     
223 david.dillard  1.19 inline AtomicInt& AtomicInt::operator-=(const AtomicInt& val)
224 mike           1.2  {
225 david.dillard  1.19     LONG temp ;
226                         InterlockedExchange(&temp, val._rep);
227                         enter_crit(&_crit);
228                         _rep -= temp;
229                         exit_crit(&_crit);
230                     
231                         return *this;
232 mike           1.2  }
233                     
234 david.dillard  1.19 inline AtomicInt& AtomicInt::operator-=(Uint32 val)
235                     {
236                         LONG temp ;
237                         InterlockedExchange(&temp, val);
238                         enter_crit(&_crit);
239                         _rep -= temp;
240                         exit_crit(&_crit);
241                     
242                         return *this;
243 mike           1.2  }
244                     
245 kumpf          1.10 inline Boolean AtomicInt::DecAndTestIfZero()
246 kumpf          1.9  {
247 david.dillard  1.19     return(InterlockedDecrement(&_rep) == 0);
248 kumpf          1.9  }
249                     
250 mike           1.2  
251                     #endif // inline atomic int
252                     
253                     //_________________________________________________________________
254                     //
255                     /// Native Windows implementation of the conditional semaphore
256                     //_________________________________________________________________
257                     
258 david.dillard  1.19 #ifdef PEGASUS_CONDITIONAL_NATIVE
259 mike           1.2  
260                     inline void Condition::signal(PEGASUS_THREAD_TYPE caller)
261                        throw(IPCException)
262                     {
263 david.dillard  1.19     _cond_mutex->lock(caller);
264                         try
265                         {
266                             unlocked_signal(caller);
267                         }
268                         catch(...)
269                         {
270                             unlock_object();
271                             throw;
272                         }
273                         _cond_mutex->unlock();
274 mike           1.2  }
275                     
276                     inline void Condition::unlocked_signal(PEGASUS_THREAD_TYPE caller)
277 david.dillard  1.19     throw(IPCException)
278 mike           1.2  {
279 david.dillard  1.19     if(_cond_mutex->_mutex.owner != caller)
280                             throw Permission((PEGASUS_THREAD_TYPE)caller);
281 tony           1.13 
282 david.dillard  1.19     // Change from PulseEvent to SetEvent, this is part of
283 tony           1.13     //    fix to avoid deadlock in CIMClient Constructor.
284                         //PulseEvent(_condition);
285                         SetEvent(_condition);
286 mike           1.2  }
287                     
288                     inline void Condition::lock_object(PEGASUS_THREAD_TYPE caller)
289 david.dillard  1.19     throw(IPCException)
290 mike           1.2  {
291 david.dillard  1.19     if(_disallow.value() > 0 )
292                             throw ListClosed();
293                         _cond_mutex->lock(caller);
294 mike           1.2  }
295                     
296                     inline void Condition::try_lock_object(PEGASUS_THREAD_TYPE caller)
297 david.dillard  1.19     throw(IPCException)
298 mike           1.2  {
299 david.dillard  1.19     if(_disallow.value() > 0 )
300                             throw ListClosed();
301                         _cond_mutex->try_lock(caller);
302 mike           1.2  }
303                     
304                     inline void Condition::wait_lock_object(PEGASUS_THREAD_TYPE caller, int milliseconds)
305 david.dillard  1.19     throw(IPCException)
306 mike           1.2  {
307 david.dillard  1.19     if(_disallow.value() > 0)
308                             throw ListClosed();
309                         _cond_mutex->timed_lock(milliseconds, caller);
310                         if( _disallow.value() > 0 )
311                         {
312                             _cond_mutex->unlock();
313                             throw ListClosed();
314                         }
315 mike           1.2  }
316                     
317                     inline void Condition::unlock_object(void)
318                     {
319 david.dillard  1.19     _cond_mutex->unlock();
320 mike           1.2  }
321                     
322                     inline void Condition::unlocked_wait(PEGASUS_THREAD_TYPE caller)
323                     {
324 david.dillard  1.19     unlocked_timed_wait(-1, caller);
325 mike           1.2  }
326                     
327                     inline void Condition::unlocked_timed_wait(int milliseconds, PEGASUS_THREAD_TYPE caller)
328                     {
329 david.dillard  1.19     if(_disallow.value() > 0)
330                         {
331                             _cond_mutex->unlock();
332                             throw ListClosed();
333                         }
334                     
335                         if(_cond_mutex->_mutex.owner != caller)
336                             throw Permission((PEGASUS_THREAD_TYPE)caller);
337                         if(milliseconds == -1)
338                             milliseconds = INFINITE;
339 tony           1.13 
340 david.dillard  1.19     // Change from PulseEvent to SetEvent, this is part of
341                         //    fix to avoid deadlock in CIMClient Constructor
342 tony           1.13     // Change added next line since SignalObjectAndWait
343                         //       releases the mutex
344                         _cond_mutex->_mutex.owner = 0;
345                     
346 david.dillard  1.19     DWORD retcode = SignalObjectAndWait(_cond_mutex->_mutex.mut, _condition,
347                                                                 milliseconds, false);
348                         if(retcode == WAIT_TIMEOUT)
349                             throw TimeOut(pegasus_thread_self());
350                         _cond_mutex->lock(caller);
351 mike           1.2  }
352                     
353                     
354 david.dillard  1.19 #endif // inline native conditional
355 mike           1.2  
356                     #endif // IPCWindows_inline_h

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2