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: |
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 | |
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: |
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 | |
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: |
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 | |
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 | |