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

  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           #include "ReadWriteSem.h"
 35           #include "Time.h"
 36           #include "PegasusAssert.h"
 37           #include "Threads.h"
 38 kumpf 1.13 #include "Exception.h"
 39            #include "System.h"
 40 mike  1.2  
 41            PEGASUS_NAMESPACE_BEGIN
 42            
 43            //==============================================================================
 44            //
 45            // PEGASUS_USE_POSIX_RWLOCK
 46            //
 47            //==============================================================================
 48            
 49            #ifdef PEGASUS_USE_POSIX_RWLOCK
 50            
 51 kumpf 1.12 ReadWriteSem::ReadWriteSem()
 52 mike  1.2  {
 53                pthread_rwlock_init(&_rwlock.rwlock, NULL);
 54            }
 55            
 56            ReadWriteSem::~ReadWriteSem()
 57            {
 58 kumpf 1.5      int r = 0;
 59 mike  1.6      while ((r = pthread_rwlock_destroy(&_rwlock.rwlock)) == EBUSY ||
 60 kumpf 1.5             (r == -1 && errno == EBUSY))
 61 mike  1.2      {
 62                    Threads::yield();
 63                }
 64            }
 65            
 66 kumpf 1.12 void ReadWriteSem::waitRead()
 67 mike  1.2  {
 68 kumpf 1.13     int r = pthread_rwlock_rdlock(&_rwlock.rwlock);
 69            
 70                if (r != 0)
 71 mike  1.2      {
 72 kumpf 1.13         if (r != -1)
 73                    {
 74                        // Special behavior for Single UNIX Specification, Version 3
 75                        errno = r;
 76                    }
 77            
 78                    throw Exception(MessageLoaderParms(
 79                        "Common.InternalException.READ_LOCK_FAILED",
 80                        "Failed to acquire read lock: $0",
 81                        PEGASUS_SYSTEM_ERRORMSG_NLS));
 82 mike  1.2      }
 83            }
 84            
 85 kumpf 1.12 void ReadWriteSem::waitWrite()
 86 mike  1.2  {
 87 kumpf 1.13     int r = pthread_rwlock_wrlock(&_rwlock.rwlock);
 88            
 89                if (r != 0)
 90 mike  1.2      {
 91 kumpf 1.13         if (r != -1)
 92                    {
 93                        // Special behavior for Single UNIX Specification, Version 3
 94                        errno = r;
 95                    }
 96            
 97                    throw Exception(MessageLoaderParms(
 98                        "Common.InternalException.WRITE_LOCK_FAILED",
 99                        "Failed to acquire write lock: $0",
100                        PEGASUS_SYSTEM_ERRORMSG_NLS));
101 mike  1.2      }
102 kumpf 1.12 }
103 kumpf 1.10 
104 kumpf 1.12 void ReadWriteSem::unlockRead()
105            {
106 kumpf 1.10     int rc = pthread_rwlock_unlock(&_rwlock.rwlock);
107                // All documented error codes represent coding errors.
108                PEGASUS_ASSERT(rc == 0);
109 mike  1.2  }
110            
111 kumpf 1.12 void ReadWriteSem::unlockWrite()
112 mike  1.2  {
113 kumpf 1.12     int rc = pthread_rwlock_unlock(&_rwlock.rwlock);
114                // All documented error codes represent coding errors.
115                PEGASUS_ASSERT(rc == 0);
116 mike  1.2  }
117            
118            #endif /* PEGASUS_USE_POSIX_RWLOCK */
119            
120            //==============================================================================
121            //
122            // PEGASUS_USE_SEMAPHORE_RWLOCK
123            //
124            //==============================================================================
125            
126            #if defined(PEGASUS_USE_SEMAPHORE_RWLOCK)
127            
128            // // If i get cancelled, I MUST ensure:
129            // 1) I do not hold the internal mutex
130            // 2) I do not hold the write lock
131            // 3) I am not using a reader slot
132            
133 kumpf 1.12 ReadWriteSem::ReadWriteSem() : _rwlock()
134 mike  1.2  {
135            }
136            
137            ReadWriteSem::~ReadWriteSem()
138            {
139                // lock everyone out of this object
140                try
141                {
142                    _rwlock._internal_lock.lock();
143                }
144 kumpf 1.13     catch (...)
145 mike  1.2      {
146                    PEGASUS_ASSERT(0);
147                }
148 kumpf 1.12     while (_rwlock._readers.get() > 0 || _rwlock._writers.get() > 0)
149 mike  1.2      {
150                    Threads::yield();
151                }
152                _rwlock._internal_lock.unlock();
153            }
154            
155 kumpf 1.12 void ReadWriteSem::waitRead()
156 mike  1.2  {
157 kumpf 1.12     // Lock the internal mutex to ensure only one waiter is processed at a time.
158                AutoMutex lock(_rwlock._internal_lock);
159            
160                // Wait for the existing writer (if any) to clear.
161                while (_rwlock._writers.get() > 0)
162                {
163                    Threads::yield();
164 mike  1.2      }
165 kumpf 1.12 
166                // Wait for a reader slot to open up.
167                _rwlock._rlock.wait();
168            
169                // Increment the number of readers.
170                _rwlock._readers++;
171            }
172            
173            void ReadWriteSem::waitWrite()
174            {
175                // Lock the internal mutex to ensure only one waiter is processed at a time.
176                AutoMutex lock(_rwlock._internal_lock);
177            
178                // Allow all the readers to exit.
179                while (_rwlock._readers.get() > 0)
180                {
181                    Threads::yield();
182                }
183            
184                // Obtain the write mutex.
185                _rwlock._wlock.lock();
186 kumpf 1.12 
187                // Set the writer count to one.
188                _rwlock._writers = 1;
189 mike  1.2  }
190            
191 kumpf 1.12 void ReadWriteSem::unlockRead()
192 mike  1.2  {
193 kumpf 1.12     PEGASUS_ASSERT(_rwlock._readers.get() > 0);
194                _rwlock._readers--;
195                _rwlock._rlock.signal();
196 mike  1.2  }
197            
198 kumpf 1.12 void ReadWriteSem::unlockWrite()
199 mike  1.2  {
200 kumpf 1.12     PEGASUS_ASSERT(_rwlock._writers.get() == 1);
201                _rwlock._writers = 0;
202                _rwlock._wlock.unlock();
203 mike  1.2  }
204            
205            #endif /* !PEGASUS_USE_SEMAPHORE_RWLOCK */
206            
207            PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2