root/unix/posix_locking_impl.hpp

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

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. attr
  2. attr
  3. attr
  4. attr
  5. lock
  6. lock
  7. unlock
  8. decay
  9. set
  10. unlock
  11. reset
  12. try_lock
  13. lock
  14. clear
  15. count
  16. lock
  17. lock
  18. unlock
  19. decay

   1 /******************************************************************************
   2 ** $Header: svn+ssh://jmmcg@svn.code.sf.net/p/libjmmcg/code/trunk/libjmmcg/unix/posix_locking_impl.hpp 2272 2018-03-17 22:21:39Z jmmcg $
   3 **
   4 ** Copyright (c) 2004 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 pthreads {
  22 
  23         class condition_var::attr : protected non_copyable {
  24         public:
  25                 explicit __stdcall attr(const int shared) noexcept(true) FORCE_INLINE {
  26                         [[maybe_unused]] const int ret1=pthread_condattr_init(&attr_);
  27                         assert(ret1==0);
  28                         [[maybe_unused]] const int ret2=pthread_condattr_setpshared(&attr_, shared);
  29                         assert(ret2==0);
  30                 }
  31                 __stdcall ~attr() noexcept(true) FORCE_INLINE {
  32                         [[maybe_unused]] const int ret=pthread_condattr_destroy(&attr_);
  33                         assert(ret==0);
  34                 }
  35 
  36                 operator pthread_condattr_t const *() const noexcept(true) FORCE_INLINE {
  37                         return &attr_;
  38                 }
  39                 operator pthread_condattr_t *() noexcept(true) FORCE_INLINE {
  40                         return &attr_;
  41                 }
  42 
  43                 friend inline tostream &__fastcall FORCE_INLINE
  44                 operator<<(tostream &os, attr const &a) {
  45                         os<<static_cast<pthread_condattr_t const *>(a);
  46                         return os;
  47                 }
  48 
  49         private:
  50                 pthread_condattr_t attr_;
  51         };
  52 
  53         inline
  54         condition_var::condition_var(const int shared) noexcept(false) {
  55                 attr attrs(shared);
  56                 const atomic_state_type pth_err=static_cast<atomic_state_type>(pthread_cond_init(&cond_var, static_cast<const pthread_condattr_t *>(attrs)));
  57                 if (pth_err!=lock_traits::atom_set) {
  58                         info::function fun(__LINE__, __PRETTY_FUNCTION__, typeid(*this), info::function::argument(_T("const int shared"), tostring(shared)));
  59                         fun.add_arg(info::function::argument(_T("attr"), tostring(attrs)));
  60                         fun.add_arg(info::function::argument(_T("Return code"), tostring(pth_err)));
  61                         throw exception_type(_T("Could not initialise condition variable."), fun, JMMCG_REVISION_HDR(_T("$Header: svn+ssh://jmmcg@svn.code.sf.net/p/libjmmcg/code/trunk/libjmmcg/unix/posix_locking_impl.hpp 2272 2018-03-17 22:21:39Z jmmcg $")));
  62                 }
  63         }
  64 
  65         inline
  66         condition_var::~condition_var() noexcept(true) {
  67                 [[maybe_unused]] const atomic_state_type pth_err=static_cast<atomic_state_type>(pthread_cond_destroy(&cond_var));
  68                 assert(pth_err==lock_traits::atom_set);
  69         }
  70 
  71         class anon_mutex::attr : protected non_copyable {
  72         public:
  73                 __stdcall attr(const int shared, const int err_chk) noexcept(true) FORCE_INLINE {
  74                         [[maybe_unused]] const int ret1=pthread_mutexattr_init(&attr_);
  75                         assert(ret1==0);
  76                         [[maybe_unused]] const int ret2=pthread_mutexattr_setpshared(&attr_,shared);
  77                         assert(ret2==0);
  78                         [[maybe_unused]] const int ret3=pthread_mutexattr_settype(&attr_,err_chk);
  79                         assert(ret3==0);
  80                 }
  81                 __stdcall ~attr() noexcept(true) FORCE_INLINE {
  82                         [[maybe_unused]] const int ret=pthread_mutexattr_destroy(&attr_);
  83                         assert(ret==0);
  84                 }
  85 
  86                 operator pthread_mutexattr_t const *() const noexcept(true) FORCE_INLINE {
  87                         return &attr_;
  88                 }
  89                 operator pthread_mutexattr_t *() noexcept(true) FORCE_INLINE {
  90                         return &attr_;
  91                 }
  92 
  93                 friend inline tostream &__fastcall FORCE_INLINE
  94                 operator<<(tostream &os, attr const &a) noexcept(false) {
  95                         os<<static_cast<pthread_mutexattr_t const *>(a);
  96                         return os;
  97                 }
  98 
  99         private:
 100                 pthread_mutexattr_t attr_;
 101         };
 102 
 103         inline
 104         anon_mutex::anon_mutex() noexcept(false) {
 105                 attr attrs(PTHREAD_PROCESS_PRIVATE, PTHREAD_MUTEX_ERRORCHECK);
 106                 const atomic_state_type pth_err=static_cast<atomic_state_type>(pthread_mutex_init(&mutex, static_cast<pthread_mutexattr_t *>(attrs)));
 107                 if (pth_err!=lock_traits::atom_set) {
 108                         info::function fun(__LINE__, __PRETTY_FUNCTION__, typeid(*this), info::function::argument(_T("attr"), tostring(attrs)));
 109                         fun.add_arg(info::function::argument(_T("Return code"), tostring(pth_err)));
 110                         throw exception_type(_T("Could not initialise the mutex."), fun, JMMCG_REVISION_HDR(_T("$Header: svn+ssh://jmmcg@svn.code.sf.net/p/libjmmcg/code/trunk/libjmmcg/unix/posix_locking_impl.hpp 2272 2018-03-17 22:21:39Z jmmcg $")));
 111                 }
 112         }
 113 
 114         inline
 115         anon_mutex::~anon_mutex() noexcept(true) {
 116                 [[maybe_unused]] const atomic_state_type pth_err=static_cast<atomic_state_type>(pthread_mutex_destroy(&mutex));
 117                 assert(pth_err==lock_traits::atom_set);
 118         }
 119 
 120         inline
 121         anon_mutex::operator api_mutex_type *() noexcept(true) {
 122                 return &mutex;
 123         }
 124 
 125         inline anon_mutex::atomic_state_type
 126         anon_mutex::lock() noexcept(true) {
 127                 return static_cast<atomic_state_type>(pthread_mutex_lock(&mutex));
 128         }
 129 
 130         inline anon_mutex::atomic_state_type
 131         anon_mutex::lock(const timeout_type timeout) noexcept(true) {
 132                 if (timeout==infinite_timeout()) {
 133                         return lock();
 134                 } else {
 135                         return static_cast<atomic_state_type>(pthread_mutex_trylock(&mutex));
 136                 }
 137         }
 138 
 139         inline anon_mutex::atomic_state_type
 140         anon_mutex::unlock() noexcept(true) {
 141                 const atomic_state_type ret=static_cast<atomic_state_type>(pthread_mutex_unlock(&mutex));
 142                 return ret ? static_cast<atomic_state_type>(ret) : lock_traits::atom_unset;
 143         }
 144 
 145         inline void
 146         anon_mutex::decay() noexcept(true) {
 147         }
 148 
 149         inline
 150         anon_mutex::anon_mutex(const int shared, const int err_chk) noexcept(false) {
 151                 attr attrs(shared, err_chk);
 152                 const atomic_state_type pth_err=static_cast<atomic_state_type>(pthread_mutex_init(&mutex, static_cast<pthread_mutexattr_t *>(attrs)));
 153                 if (pth_err!=lock_traits::atom_set) {
 154                         info::function fun(__LINE__, __PRETTY_FUNCTION__, typeid(*this), info::function::argument(_T("const int shared"), tostring(shared)));
 155                         fun.add_arg(info::function::argument(_T("const int err_chk"), tostring(err_chk)));
 156                         fun.add_arg(info::function::argument(_T("attr"), tostring(attrs)));
 157                         fun.add_arg(info::function::argument(_T("Return code"), tostring(pth_err)));
 158                         throw exception_type(_T("Could not initialise mutex."), fun, JMMCG_REVISION_HDR(_T("$Header: svn+ssh://jmmcg@svn.code.sf.net/p/libjmmcg/code/trunk/libjmmcg/unix/posix_locking_impl.hpp 2272 2018-03-17 22:21:39Z jmmcg $")));
 159                 }
 160         }
 161 
 162         inline
 163         anon_semaphore::anon_semaphore(const atomic_state_type state) noexcept(false) {
 164                 const atomic_state_type err=static_cast<atomic_state_type>(sem_init(&sem, 0, state==atom_set));
 165                 if (err!=lock_traits::atom_set) {
 166                         info::function fun(__LINE__, __PRETTY_FUNCTION__, typeid(*this), info::function::argument(_T("const atomic_state_type state"), tostring(state)));
 167                         fun.add_arg(info::function::argument(_T("Return code"), tostring(err)));
 168                         throw exception_type(_T("Could not initialise anonymous semaphore."), fun, JMMCG_REVISION_HDR(_T("$Header: svn+ssh://jmmcg@svn.code.sf.net/p/libjmmcg/code/trunk/libjmmcg/unix/posix_locking_impl.hpp 2272 2018-03-17 22:21:39Z jmmcg $")));
 169                 }
 170         }
 171 
 172         inline
 173         anon_semaphore::anon_semaphore(const atomic_state_type state, int shared) noexcept(false) {
 174                 const atomic_state_type err=static_cast<atomic_state_type>(sem_init(&sem, shared, state==atom_set));
 175                 if (err!=lock_traits::atom_set) {
 176                         info::function fun(__LINE__, __PRETTY_FUNCTION__, typeid(*this), info::function::argument(_T("const atomic_state_type state"), tostring(state)));
 177                         fun.add_arg(info::function::argument(_T("atomic_state_type state"), tostring(state)));
 178                         fun.add_arg(info::function::argument(_T("int shared"), tostring(shared)));
 179                         fun.add_arg(info::function::argument(_T("Return code"), tostring(err)));
 180                         throw exception_type(_T("Could not initialise anonymous semaphore."), fun, JMMCG_REVISION_HDR(_T("$Header: svn+ssh://jmmcg@svn.code.sf.net/p/libjmmcg/code/trunk/libjmmcg/unix/posix_locking_impl.hpp 2272 2018-03-17 22:21:39Z jmmcg $")));
 181                 }
 182         }
 183 
 184         inline
 185         anon_semaphore::~anon_semaphore() noexcept(true) {
 186                 [[maybe_unused]] const atomic_state_type err=static_cast<atomic_state_type>(sem_destroy(&sem));
 187                 assert(err==lock_traits::atom_set);
 188         }
 189 
 190         inline
 191         anon_semaphore::operator api_event_type *() noexcept(true) {
 192                 return static_cast<api_event_type *>(&sem);
 193         }
 194 
 195         inline anon_semaphore::atomic_state_type
 196         anon_semaphore::set() noexcept(true) {
 197                 return static_cast<atomic_state_type>(sem_post(&sem));
 198         }
 199 
 200         inline anon_semaphore::lock_result_type
 201         anon_semaphore::unlock() noexcept(true) {
 202                 return static_cast<atomic_state_type>(sem_trywait(&sem));
 203         }
 204 
 205         inline anon_semaphore::atomic_state_type
 206         anon_semaphore::reset() noexcept(true) {
 207                 return unlock();
 208         }
 209 
 210         inline anon_semaphore::lock_result_type
 211         anon_semaphore::try_lock() noexcept(true) {
 212                 if (!sem_trywait(&sem)) {
 213                         return lock_traits::atom_set;
 214                 } else {
 215                         return lock_traits::atom_unset;
 216                 }
 217         }
 218 
 219         inline anon_semaphore::lock_result_type
 220         anon_semaphore::lock() noexcept(false) {
 221                 if (!sem_wait(&sem)) {
 222                         return lock_traits::atom_set;
 223                 } else {
 224                         return lock_traits::atom_abandoned;
 225                 }
 226         }
 227 
 228         inline void
 229         anon_semaphore::clear() noexcept(true) {
 230                 while (try_lock()==lock_traits::atom_set);
 231         }
 232 
 233         inline anon_semaphore::count_type
 234         anon_semaphore::count() const noexcept(false) {
 235                 count_type val=0;
 236                 const atomic_state_type err=static_cast<atomic_state_type>(sem_getvalue(&sem, &val));
 237                 if (err!=lock_traits::atom_set) {
 238                         info::function fun(__LINE__, __PRETTY_FUNCTION__, typeid(&anon_semaphore::count), info::function::argument(_T("count_type val"), tostring(val)));
 239                         fun.add_arg(info::function::argument(_T("Return code"), tostring(err)));
 240                         throw exception_type(_T("Could not get the count from the semaphore object."), fun, JMMCG_REVISION_HDR(_T("$Header: svn+ssh://jmmcg@svn.code.sf.net/p/libjmmcg/code/trunk/libjmmcg/unix/posix_locking_impl.hpp 2272 2018-03-17 22:21:39Z jmmcg $")));
 241                 }
 242                 return val;
 243         }
 244 
 245         inline
 246         nonrecursive_anon_mutex::nonrecursive_anon_mutex() noexcept(noexcept(anon_semaphore())) {
 247                 assert(event_.count()==1);
 248         }
 249 
 250         inline
 251         nonrecursive_anon_mutex::~nonrecursive_anon_mutex() noexcept(true) {
 252                 event_.clear();
 253         }
 254 
 255         inline nonrecursive_anon_mutex::atomic_state_type
 256         nonrecursive_anon_mutex::lock(const timeout_type timeout) noexcept(noexcept(event_.lock(timeout))) {
 257                 const atomic_state_type ret=event_.lock(timeout);
 258                 assert(event_.count()>=0);
 259                 return ret;
 260         }
 261 
 262         inline nonrecursive_anon_mutex::atomic_state_type
 263         nonrecursive_anon_mutex::lock() noexcept(noexcept(event_.lock())) {
 264                 const atomic_state_type ret=event_.lock();
 265                 assert(event_.count()>=0);
 266                 return ret;
 267         }
 268 
 269         inline nonrecursive_anon_mutex::atomic_state_type
 270         nonrecursive_anon_mutex::unlock() noexcept(noexcept(event_.set())) {
 271                 assert(event_.count()>=0);
 272                 const atomic_state_type ret=event_.set();
 273                 assert(event_.count()>=0);
 274                 return ret;
 275         }
 276 
 277         inline void
 278         nonrecursive_anon_mutex::decay() noexcept(true) {
 279         }
 280 
 281 } } }

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