log4cplus  1.1.0
syncprims-pmsm.h
Go to the documentation of this file.
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 }