1 /* Copyright 2006-2013 Joaquin M Lopez Munoz. 2 * Distributed under the Boost Software License, Version 1.0. 3 * (See accompanying file LICENSE_1_0.txt or copy at 4 * http://www.boost.org/LICENSE_1_0.txt) 5 * 6 * See http://www.boost.org/libs/flyweight for library home page. 7 */ 8 9 #ifndef BOOST_FLYWEIGHT_DETAIL_RECURSIVE_LW_MUTEX_HPP 10 #define BOOST_FLYWEIGHT_DETAIL_RECURSIVE_LW_MUTEX_HPP 11 12 #if defined(_MSC_VER) 13 #pragma once 14 #endif 15 16 /* Recursive lightweight mutex. Relies entirely on 17 * boost::detail::lightweight_mutex, except in Pthreads, where we 18 * explicitly use the PTHREAD_MUTEX_RECURSIVE attribute 19 * (lightweight_mutex uses the default mutex type instead). 20 */ 21 22 #include <boost/config.hpp> 23 24 #if !defined(BOOST_HAS_PTHREADS) 25 #include <boost/detail/lightweight_mutex.hpp> 26 namespace boost{ 27 28 namespace flyweights{ 29 30 namespace detail{ 31 32 typedef boost::detail::lightweight_mutex recursive_lightweight_mutex; 33 34 } /* namespace flyweights::detail */ 35 36 } /* namespace flyweights */ 37 38 } /* namespace boost */ 39 #else 40 /* code shamelessly ripped from <boost/detail/lwm_pthreads.hpp> */ 41 42 #include <boost/assert.hpp> 43 #include <boost/noncopyable.hpp> 44 #include <pthread.h> 45 46 namespace boost{ 47 48 namespace flyweights{ 49 50 namespace detail{ 51 52 struct recursive_lightweight_mutex:noncopyable 53 { recursive_lightweight_mutexboost::flyweights::detail::recursive_lightweight_mutex54 recursive_lightweight_mutex() 55 { 56 pthread_mutexattr_t attr; 57 BOOST_VERIFY(pthread_mutexattr_init(&attr)==0); 58 BOOST_VERIFY(pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE)==0); 59 BOOST_VERIFY(pthread_mutex_init(&m_,&attr)==0); 60 BOOST_VERIFY(pthread_mutexattr_destroy(&attr)==0); 61 } 62 ~recursive_lightweight_mutexboost::flyweights::detail::recursive_lightweight_mutex63 ~recursive_lightweight_mutex(){pthread_mutex_destroy(&m_);} 64 65 struct scoped_lock; 66 friend struct scoped_lock; 67 struct scoped_lock:noncopyable 68 { 69 public: scoped_lockboost::flyweights::detail::recursive_lightweight_mutex::scoped_lock70 scoped_lock(recursive_lightweight_mutex& m):m_(m.m_) 71 { 72 BOOST_VERIFY(pthread_mutex_lock(&m_)==0); 73 } 74 ~scoped_lockboost::flyweights::detail::recursive_lightweight_mutex::scoped_lock75 ~scoped_lock(){BOOST_VERIFY(pthread_mutex_unlock(&m_)==0);} 76 77 private: 78 pthread_mutex_t& m_; 79 }; 80 81 private: 82 pthread_mutex_t m_; 83 }; 84 85 } /* namespace flyweights::detail */ 86 87 } /* namespace flyweights */ 88 89 } /* namespace boost */ 90 #endif 91 92 #endif 93