log4cplus
1.1.0
|
00001 // -*- C++ -*- 00002 // Copyright (C) 2010, Vaclav Haisman. All rights reserved. 00003 // 00004 // Redistribution and use in source and binary forms, with or without modifica- 00005 // tion, are permitted provided that the following conditions are met: 00006 // 00007 // 1. Redistributions of source code must retain the above copyright notice, 00008 // this list of conditions and the following disclaimer. 00009 // 00010 // 2. Redistributions in binary form must reproduce the above copyright notice, 00011 // this list of conditions and the following disclaimer in the documentation 00012 // and/or other materials provided with the distribution. 00013 // 00014 // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 00015 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 00016 // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00017 // APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 00018 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- 00019 // DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 00020 // OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 00021 // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00022 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 00023 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00024 00030 00031 00032 #if ! defined (INSIDE_LOG4CPLUS) 00033 # error "This header must not be be used outside log4cplus' implementation files." 00034 #endif 00035 00036 00037 // This implements algorithm described in "Concurrent Control with "Readers" 00038 // and "Writers"; P.J. Courtois, F. Heymans, and D.L. Parnas; 00039 // MBLE Research Laboratory; Brussels, Belgium" 00040 00041 00042 inline 00043 SharedMutex::SharedMutex () 00044 : m1 (log4cplus::thread::Mutex::DEFAULT) 00045 , m2 (log4cplus::thread::Mutex::DEFAULT) 00046 , m3 (log4cplus::thread::Mutex::DEFAULT) 00047 , w (1, 1) 00048 , writer_count (0) 00049 , r (1, 1) 00050 , reader_count (0) 00051 { } 00052 00053 00054 inline 00055 SharedMutex::~SharedMutex () 00056 { } 00057 00058 00059 inline 00060 void 00061 SharedMutex::rdlock () const 00062 { 00063 MutexGuard m3_guard (m3); 00064 SemaphoreGuard r_guard (r); 00065 MutexGuard m1_guard (m1); 00066 if (reader_count + 1 == 1) 00067 w.lock (); 00068 00069 reader_count += 1; 00070 } 00071 00072 00073 inline 00074 void 00075 SharedMutex::rdunlock () const 00076 { 00077 MutexGuard m1_guard (m1); 00078 if (reader_count - 1 == 0) 00079 w.unlock (); 00080 00081 reader_count -= 1; 00082 } 00083 00084 00085 inline 00086 void 00087 SharedMutex::wrlock () const 00088 { 00089 { 00090 MutexGuard m2_guard (m2); 00091 if (writer_count + 1 == 1) 00092 r.lock (); 00093 00094 writer_count += 1; 00095 } 00096 try 00097 { 00098 w.lock (); 00099 } 00100 catch (...) 00101 { 00102 MutexGuard m2_guard (m2); 00103 writer_count -= 1; 00104 throw; 00105 } 00106 } 00107 00108 00109 inline 00110 void 00111 SharedMutex::wrunlock () const 00112 { 00113 w.unlock (); 00114 MutexGuard m2_guard (m2); 00115 if (writer_count - 1 == 0) 00116 r.unlock (); 00117 00118 writer_count -= 1; 00119 }