root/core/rw_locking_impl.hpp

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. lock
  2. unlock
  3. decayed
  4. unlock
  5. readers_free
  6. unlock
  7. rw_lk

   1 /******************************************************************************

   2 ** $Header: svn+ssh://jmmcg@svn.code.sf.net/p/libjmmcg/code/trunk/libjmmcg/core/rw_locking_impl.hpp 2353 2018-10-21 20:22:18Z jmmcg $

   3 **

   4 ** Copyright © 2011 by J.M.McGuiness, coder@hussar.me.uk

   5 **

   6 ** This library is free software; you can redistribute it and/or

   7 ** modify it under the terms of the GNU Lesser General Public

   8 ** License as published by the Free Software Foundation; either

   9 ** version 2.1 of the License, or (at your option) any later version.

  10 **

  11 ** This library is distributed in the hope that it will be useful,

  12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of

  13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU

  14 ** Lesser General Public License for more details.

  15 **

  16 ** You should have received a copy of the GNU Lesser General Public

  17 ** License along with this library; if not, write to the Free Software

  18 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

  19 */
  20 
  21 namespace jmmcg { namespace ppd { namespace lock { namespace rw {
  22 
  23         template<class L> inline constexpr
  24         decaying_write_impl<L>::decaying_write_impl(atomic_t &l) noexcept(true)
  25         : rw_lk(l) {
  26         }
  27 
  28         template<class L>
  29         inline typename decaying_write_impl<L>::atomic_state_type
  30         decaying_write_impl<L>::lock(const timeout_type) noexcept(false) {
  31                 return lock();
  32         }
  33 
  34         template<class L>
  35         inline typename decaying_write_impl<L>::atomic_state_type
  36         decaying_write_impl<L>::unlock() noexcept(true) {
  37                 return rw_lk.unlock();
  38         }
  39 
  40         template<class L>
  41         inline void
  42         decaying_write_impl<L>::decay() noexcept(true) {
  43                 rw_lk.decay();
  44         }
  45 
  46         template<class T> inline constexpr
  47         decaying_write_impl<locker<T> >::decaying_write_impl(atomic_t &l) noexcept(true)
  48         : rw_lk(l), exclusive_w_lk(rw_lk.writer_lk), decayed(false) {
  49         }
  50 
  51         template<class T>
  52         inline typename decaying_write_impl<locker<T> >::atomic_state_type
  53         decaying_write_impl<locker<T> >::lock() noexcept(false) {
  54                 exclusive_w_lk.lock();
  55                 const typename atomic_t::atomic_state_type ret=rw_lk.readers_free.lock();
  56                 assert(ret==atomic_t::atom_set);
  57                 assert(rw_lk.readers==0);
  58                 return ret;
  59         }
  60 
  61         template<class T>
  62         inline typename decaying_write_impl<locker<T> >::atomic_state_type
  63         decaying_write_impl<locker<T> >::lock(const timeout_type) noexcept(false) {
  64                 return lock();
  65         }
  66 
  67         template<class T>
  68         inline typename decaying_write_impl<locker<T> >::atomic_state_type
  69         decaying_write_impl<locker<T> >::unlock() noexcept(true) {
  70                 exclusive_w_lk.unlock();
  71                 if (!decayed) {
  72                         const typename atomic_t::atomic_state_type ret=rw_lk.readers_free.set();
  73                         assert(ret==atomic_t::atom_set);
  74                         return ret;
  75                 } else {
  76                         if ((--rw_lk.readers)==0) {
  77                                 rw_lk.readers=typename atomic_t::atomic_counter_type(0);
  78                                 assert(rw_lk.readers==0);
  79                                 const typename atomic_t::atomic_state_type ret=rw_lk.readers_free.set();
  80                                 assert(ret==atomic_t::atom_set);
  81                                 return ret;
  82                         }
  83                         assert(rw_lk.readers>=0);
  84                 }
  85                 return atomic_t::atom_unset;
  86         }
  87 
  88         template<class T>
  89         inline void
  90         decaying_write_impl<locker<T> >::decay() noexcept(true) {
  91                 if (!decayed) {
  92                         assert(rw_lk.readers==0);
  93                         ++rw_lk.readers;
  94                         decayed=true;
  95                         [[maybe_unused]] const typename atomic_t::atomic_state_type ret=exclusive_w_lk.unlock();
  96                         assert(ret==atomic_t::atom_unset);
  97                 }
  98         }
  99 
 100         template<class T> inline
 101         locker<T>::locker() noexcept(false)
 102         : readers(), readers_free(lock_traits::atom_set) {
 103         }
 104 
 105         template<class T> inline typename locker<T>::atomic_state_type
 106         locker<T>::lock() noexcept(false) {
 107                 if ((readers++)==0) {
 108                         [[maybe_unused]] const typename locker::atomic_state_type ret=readers_free.lock();
 109                         assert(ret==locker::atom_set);
 110                 }
 111                 return lock_traits::atom_set;
 112         }
 113 
 114         template<class T> inline typename locker<T>::atomic_state_type
 115         locker<T>::unlock() noexcept(true) {
 116                 if ((--readers)==0) {
 117                         readers=atomic_counter_type(0);
 118                         assert(readers==0);
 119                         return readers_free.set();
 120                 }
 121                 if (readers<0) {
 122                         readers=atomic_counter_type(0);
 123                 }
 124                 assert(readers>=0);
 125                 return lock_traits::atom_unset;
 126         }
 127 
 128         template<class T> inline
 129         locker<T>::read_lock_type::read_lock_type(atomic_t &l, const timeout_type) noexcept(false)
 130         : lk(l) {
 131                 [[maybe_unused]] const typename atomic_t::atomic_state_type ret=lk.lock();
 132                 assert(ret==atomic_t::atom_set);
 133         }
 134 
 135         template<class T> inline
 136         locker<T>::read_lock_type::~read_lock_type() noexcept(true) {
 137                 assert(dynamic_cast<atomic_t *>(&lk));
 138                 lk.unlock();
 139         }
 140 
 141         template<class T> inline
 142         locker<T>::write_lock_type::write_lock_type(atomic_t &l, const timeout_type) noexcept(false)
 143         : exclusive_w_lk(l.writer_lk, lock_traits::infinite_timeout()), rw_lk(l) {
 144                 [[maybe_unused]] const typename atomic_t::atomic_state_type ret=rw_lk.readers_free.lock();
 145                 assert(ret==atomic_t::atom_set);
 146                 assert(rw_lk.readers==0);
 147         }
 148 
 149         template<class T> inline
 150         locker<T>::write_lock_type::~write_lock_type() noexcept(true) {
 151                 assert(dynamic_cast<atomic_t *>(&rw_lk));
 152                 [[maybe_unused]] const typename atomic_t::atomic_state_type ret=rw_lk.readers_free.set();
 153                 assert(ret==atomic_t::atom_set);
 154         }
 155 
 156         template<class T> inline
 157         locker<T>::decaying_write_lock_type::decaying_write_lock_type(atomic_t &l, const timeout_type) noexcept(false)
 158         : base_t(l) {
 159                 base_t::lock();
 160         }
 161 
 162         template<class T> inline
 163         locker<T>::decaying_write_lock_type::~decaying_write_lock_type() noexcept(true) {
 164                 base_t::unlock();
 165         }
 166 
 167         template<class T> inline void
 168         locker<T>::decaying_write_lock_type::decay() noexcept(true) {
 169                 base_t::decay();
 170         }
 171 
 172 } } } }

/* [<][>][^][v][top][bottom][index][help] */