1 #ifndef SHARED_MUTEX_LOCKING_THREAD_HPP 2 #define SHARED_MUTEX_LOCKING_THREAD_HPP 3 4 // (C) Copyright 2008 Anthony Williams 5 // 6 // Distributed under the Boost Software License, Version 1.0. (See 7 // accompanying file LICENSE_1_0.txt or copy at 8 // http://www.boost.org/LICENSE_1_0.txt) 9 10 #include <boost/config.hpp> 11 #include <boost/thread/mutex.hpp> 12 #include <boost/thread/condition_variable.hpp> 13 #include <boost/thread/shared_mutex.hpp> 14 15 template<typename lock_type> 16 class locking_thread 17 { 18 boost::shared_mutex& rw_mutex; 19 unsigned& unblocked_count; 20 boost::condition_variable& unblocked_condition; 21 unsigned& simultaneous_running_count; 22 unsigned& max_simultaneous_running; 23 boost::mutex& unblocked_count_mutex; 24 boost::mutex& finish_mutex; 25 public: locking_thread(boost::shared_mutex & rw_mutex_,unsigned & unblocked_count_,boost::mutex & unblocked_count_mutex_,boost::condition_variable & unblocked_condition_,boost::mutex & finish_mutex_,unsigned & simultaneous_running_count_,unsigned & max_simultaneous_running_)26 locking_thread(boost::shared_mutex& rw_mutex_, 27 unsigned& unblocked_count_, 28 boost::mutex& unblocked_count_mutex_, 29 boost::condition_variable& unblocked_condition_, 30 boost::mutex& finish_mutex_, 31 unsigned& simultaneous_running_count_, 32 unsigned& max_simultaneous_running_): 33 rw_mutex(rw_mutex_), 34 unblocked_count(unblocked_count_), 35 unblocked_condition(unblocked_condition_), 36 simultaneous_running_count(simultaneous_running_count_), 37 max_simultaneous_running(max_simultaneous_running_), 38 unblocked_count_mutex(unblocked_count_mutex_), 39 finish_mutex(finish_mutex_) 40 {} 41 42 #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) 43 locking_thread(locking_thread const&) = default; 44 #endif 45 operator ()()46 void operator()() 47 { 48 // acquire lock 49 lock_type lock(rw_mutex); 50 51 // increment count to show we're unblocked 52 { 53 boost::unique_lock<boost::mutex> ublock(unblocked_count_mutex); 54 ++unblocked_count; 55 unblocked_condition.notify_one(); 56 ++simultaneous_running_count; 57 if(simultaneous_running_count>max_simultaneous_running) 58 { 59 max_simultaneous_running=simultaneous_running_count; 60 } 61 } 62 63 // wait to finish 64 boost::unique_lock<boost::mutex> finish_lock(finish_mutex); 65 { 66 boost::unique_lock<boost::mutex> ublock(unblocked_count_mutex); 67 --simultaneous_running_count; 68 } 69 } 70 private: 71 void operator=(locking_thread&); 72 }; 73 74 class simple_writing_thread 75 { 76 boost::shared_mutex& rwm; 77 boost::mutex& finish_mutex; 78 boost::mutex& unblocked_mutex; 79 unsigned& unblocked_count; 80 81 void operator=(simple_writing_thread&); 82 83 public: simple_writing_thread(boost::shared_mutex & rwm_,boost::mutex & finish_mutex_,boost::mutex & unblocked_mutex_,unsigned & unblocked_count_)84 simple_writing_thread(boost::shared_mutex& rwm_, 85 boost::mutex& finish_mutex_, 86 boost::mutex& unblocked_mutex_, 87 unsigned& unblocked_count_): 88 rwm(rwm_),finish_mutex(finish_mutex_), 89 unblocked_mutex(unblocked_mutex_),unblocked_count(unblocked_count_) 90 {} 91 92 #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) 93 simple_writing_thread(simple_writing_thread const&) = default; 94 #endif 95 operator ()()96 void operator()() 97 { 98 boost::unique_lock<boost::shared_mutex> lk(rwm); 99 100 { 101 boost::unique_lock<boost::mutex> ulk(unblocked_mutex); 102 ++unblocked_count; 103 } 104 105 boost::unique_lock<boost::mutex> flk(finish_mutex); 106 } 107 }; 108 109 class simple_reading_thread 110 { 111 boost::shared_mutex& rwm; 112 boost::mutex& finish_mutex; 113 boost::mutex& unblocked_mutex; 114 unsigned& unblocked_count; 115 116 void operator=(simple_reading_thread&); 117 118 public: simple_reading_thread(boost::shared_mutex & rwm_,boost::mutex & finish_mutex_,boost::mutex & unblocked_mutex_,unsigned & unblocked_count_)119 simple_reading_thread(boost::shared_mutex& rwm_, 120 boost::mutex& finish_mutex_, 121 boost::mutex& unblocked_mutex_, 122 unsigned& unblocked_count_): 123 rwm(rwm_),finish_mutex(finish_mutex_), 124 unblocked_mutex(unblocked_mutex_),unblocked_count(unblocked_count_) 125 {} 126 127 #if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) 128 simple_reading_thread(simple_reading_thread const&) = default; 129 #endif 130 operator ()()131 void operator()() 132 { 133 boost::shared_lock<boost::shared_mutex> lk(rwm); 134 135 { 136 boost::unique_lock<boost::mutex> ulk(unblocked_mutex); 137 ++unblocked_count; 138 } 139 140 boost::unique_lock<boost::mutex> flk(finish_mutex); 141 } 142 }; 143 144 145 #endif 146