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

  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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2