|
reSIProcate/rutil
9694
|
00001 /* ==================================================================== 00002 * The Vovida Software License, Version 1.0 00003 * 00004 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 00010 * 1. Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * 00013 * 2. Redistributions in binary form must reproduce the above copyright 00014 * notice, this list of conditions and the following disclaimer in 00015 * the documentation and/or other materials provided with the 00016 * distribution. 00017 * 00018 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00019 * and "Vovida Open Communication Application Library (VOCAL)" must 00020 * not be used to endorse or promote products derived from this 00021 * software without prior written permission. For written 00022 * permission, please contact vocal@vovida.org. 00023 * 00024 * 4. Products derived from this software may not be called "VOCAL", nor 00025 * may "VOCAL" appear in their name, without prior written 00026 * permission of Vovida Networks, Inc. 00027 * 00028 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00029 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00030 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00031 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00032 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00033 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00034 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00035 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00036 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00037 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00038 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00039 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00040 * DAMAGE. 00041 * 00042 * ==================================================================== 00043 * 00044 * This software consists of voluntary contributions made by Vovida 00045 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00046 * Inc. For more information on Vovida Networks, Inc., please see 00047 * <http://www.vovida.org/>. 00048 * 00049 */ 00050 00051 #include "RWMutex.hxx" 00052 #include "Lock.hxx" 00053 #include <cassert> 00054 00055 using resip::RWMutex; 00056 using resip::Lock; 00057 00058 RWMutex::RWMutex() 00059 : Lockable(), 00060 mReaderCount(0), 00061 mWriterHasLock(false), 00062 mPendingWriterCount(0) 00063 { 00064 } 00065 00066 00067 RWMutex::~RWMutex() 00068 { 00069 } 00070 00071 00072 void 00073 RWMutex::readlock() 00074 { 00075 Lock lock(mMutex); 00076 00077 while ( mWriterHasLock || mPendingWriterCount > 0 ) 00078 { 00079 mReadCondition.wait(mMutex); 00080 } 00081 00082 mReaderCount++; 00083 } 00084 00085 00086 void 00087 RWMutex::writelock() 00088 { 00089 Lock lock(mMutex); 00090 00091 mPendingWriterCount++; 00092 00093 while ( mWriterHasLock || mReaderCount > 0 ) 00094 { 00095 mPendingWriteCondition.wait(mMutex); 00096 } 00097 00098 mPendingWriterCount--; 00099 00100 mWriterHasLock = true; 00101 } 00102 00103 00104 void 00105 RWMutex::lock() 00106 { 00107 writelock(); 00108 } 00109 00110 00111 void 00112 RWMutex::unlock() 00113 { 00114 Lock lock(mMutex); 00115 00116 // Unlocking a write lock. 00117 // 00118 if ( mWriterHasLock ) 00119 { 00120 assert( mReaderCount == 0 ); 00121 00122 mWriterHasLock = false; 00123 00124 // Pending writers have priority. Could potentially starve readers. 00125 // 00126 if ( mPendingWriterCount > 0 ) 00127 { 00128 mPendingWriteCondition.signal(); 00129 } 00130 00131 // No writer, no pending writers, so all the readers can go. 00132 // 00133 else 00134 { 00135 mReadCondition.broadcast(); 00136 } 00137 00138 } 00139 00140 // Unlocking a read lock. 00141 // 00142 else 00143 { 00144 assert( mReaderCount > 0 ); 00145 00146 mReaderCount--; 00147 00148 if ( mReaderCount == 0 && mPendingWriterCount > 0 ) 00149 { 00150 mPendingWriteCondition.signal(); 00151 } 00152 } 00153 } 00154 00155 unsigned int 00156 RWMutex::readerCount() const 00157 { 00158 return ( mReaderCount ); 00159 } 00160 00161 unsigned int 00162 RWMutex::pendingWriterCount() const 00163 { 00164 return ( mPendingWriterCount ); 00165 }
1.7.5.1