1// Copyright (C) 2007 Anthony Williams
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6#define BOOST_THREAD_VERSION 2
7#define BOOST_TEST_MODULE Boost.Threads: condition_variable notify_all test suite
8#include <boost/thread/detail/config.hpp>
9
10#include <boost/thread/thread_only.hpp>
11
12#include <boost/test/unit_test.hpp>
13
14#include "./util.inl"
15#include "./condition_test_common.hpp"
16
17unsigned const number_of_test_threads=5;
18
19void do_test_condition_notify_all_wakes_from_wait()
20{
21 wait_for_flag data;
22
23 boost::thread_group group;
24
25 try
26 {
27 for(unsigned i=0;i<number_of_test_threads;++i)
28 {
29 group.create_thread(threadfunc: bind(func: &wait_for_flag::wait_without_predicate, param&: data));
30 }
31
32 {
33 boost::unique_lock<boost::mutex> lock(data.mutex);
34 data.flag=true;
35 data.cond_var.notify_all();
36 }
37
38 group.join_all();
39 BOOST_CHECK_EQUAL(data.woken,number_of_test_threads);
40 }
41 catch(...)
42 {
43 group.join_all();
44 throw;
45 }
46}
47
48void do_test_condition_notify_all_wakes_from_wait_with_predicate()
49{
50 wait_for_flag data;
51
52 boost::thread_group group;
53
54 try
55 {
56 for(unsigned i=0;i<number_of_test_threads;++i)
57 {
58 group.create_thread(threadfunc: bind(func: &wait_for_flag::wait_with_predicate, param&: data));
59 }
60
61 {
62 boost::unique_lock<boost::mutex> lock(data.mutex);
63 data.flag=true;
64 data.cond_var.notify_all();
65 }
66
67 group.join_all();
68 BOOST_CHECK_EQUAL(data.woken,number_of_test_threads);
69 }
70 catch(...)
71 {
72 group.join_all();
73 throw;
74 }
75}
76
77void do_test_condition_notify_all_wakes_from_timed_wait()
78{
79 wait_for_flag data;
80
81 boost::thread_group group;
82
83 try
84 {
85 for(unsigned i=0;i<number_of_test_threads;++i)
86 {
87 group.create_thread(threadfunc: bind(func: &wait_for_flag::timed_wait_without_predicate, param&: data));
88 }
89
90 {
91 boost::unique_lock<boost::mutex> lock(data.mutex);
92 data.flag=true;
93 data.cond_var.notify_all();
94 }
95
96 group.join_all();
97 BOOST_CHECK_EQUAL(data.woken,number_of_test_threads);
98 }
99 catch(...)
100 {
101 group.join_all();
102 throw;
103 }
104}
105
106void do_test_condition_notify_all_wakes_from_timed_wait_with_predicate()
107{
108 wait_for_flag data;
109
110 boost::thread_group group;
111
112 try
113 {
114 for(unsigned i=0;i<number_of_test_threads;++i)
115 {
116 group.create_thread(threadfunc: bind(func: &wait_for_flag::timed_wait_with_predicate, param&: data));
117 }
118
119 {
120 boost::unique_lock<boost::mutex> lock(data.mutex);
121 data.flag=true;
122 data.cond_var.notify_all();
123 }
124
125 group.join_all();
126 BOOST_CHECK_EQUAL(data.woken,number_of_test_threads);
127 }
128 catch(...)
129 {
130 group.join_all();
131 throw;
132 }
133}
134
135void do_test_condition_notify_all_wakes_from_relative_timed_wait_with_predicate()
136{
137 wait_for_flag data;
138
139 boost::thread_group group;
140
141 try
142 {
143 for(unsigned i=0;i<number_of_test_threads;++i)
144 {
145 group.create_thread(threadfunc: bind(func: &wait_for_flag::relative_timed_wait_with_predicate, param&: data));
146 }
147
148 {
149 boost::unique_lock<boost::mutex> lock(data.mutex);
150 data.flag=true;
151 data.cond_var.notify_all();
152 }
153
154 group.join_all();
155 BOOST_CHECK_EQUAL(data.woken,number_of_test_threads);
156 }
157 catch(...)
158 {
159 group.join_all();
160 throw;
161 }
162}
163
164namespace
165{
166 boost::mutex multiple_wake_mutex;
167 boost::condition_variable multiple_wake_cond;
168 unsigned multiple_wake_count=0;
169
170 void wait_for_condvar_and_increase_count()
171 {
172 boost::unique_lock<boost::mutex> lk(multiple_wake_mutex);
173 multiple_wake_cond.wait(m&: lk);
174 ++multiple_wake_count;
175 }
176
177}
178
179
180void do_test_notify_all_following_notify_one_wakes_all_threads()
181{
182 boost::thread thread1(&wait_for_condvar_and_increase_count);
183 boost::thread thread2(&wait_for_condvar_and_increase_count);
184
185 boost::this_thread::sleep(rel_time: boost::posix_time::milliseconds(200));
186 multiple_wake_cond.notify_one();
187
188 boost::thread thread3(&wait_for_condvar_and_increase_count);
189
190 boost::this_thread::sleep(rel_time: boost::posix_time::milliseconds(200));
191 multiple_wake_cond.notify_one();
192 multiple_wake_cond.notify_all();
193 boost::this_thread::sleep(rel_time: boost::posix_time::milliseconds(200));
194
195 {
196 boost::unique_lock<boost::mutex> lk(multiple_wake_mutex);
197 BOOST_CHECK(multiple_wake_count==3);
198 }
199
200 thread1.join();
201 thread2.join();
202 thread3.join();
203}
204
205BOOST_AUTO_TEST_CASE(test_condition_notify_all)
206{
207 timed_test(func: &do_test_condition_notify_all_wakes_from_wait, secs: timeout_seconds);
208 timed_test(func: &do_test_condition_notify_all_wakes_from_wait_with_predicate, secs: timeout_seconds);
209 timed_test(func: &do_test_condition_notify_all_wakes_from_timed_wait, secs: timeout_seconds);
210 timed_test(func: &do_test_condition_notify_all_wakes_from_timed_wait_with_predicate, secs: timeout_seconds);
211 timed_test(func: &do_test_condition_notify_all_wakes_from_relative_timed_wait_with_predicate, secs: timeout_seconds);
212 timed_test(func: &do_test_notify_all_following_notify_one_wakes_all_threads, secs: timeout_seconds);
213}
214
215
216
217

source code of boost/libs/thread/test/test_condition_notify_all.cpp