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 | |
8 | #define BOOST_TEST_MODULE Boost.Threads: condition_variable notify_one test suite |
9 | |
10 | #include <boost/thread/detail/config.hpp> |
11 | |
12 | #include <boost/thread/thread_only.hpp> |
13 | |
14 | #include <boost/test/unit_test.hpp> |
15 | |
16 | #include "./util.inl" |
17 | #include "./condition_test_common.hpp" |
18 | |
19 | void do_test_condition_notify_one_wakes_from_wait() |
20 | { |
21 | wait_for_flag data; |
22 | |
23 | boost::thread thread(bind(func: &wait_for_flag::wait_without_predicate, param&: data)); |
24 | |
25 | { |
26 | boost::unique_lock<boost::mutex> lock(data.mutex); |
27 | data.flag=true; |
28 | data.cond_var.notify_one(); |
29 | } |
30 | |
31 | thread.join(); |
32 | BOOST_CHECK(data.woken); |
33 | } |
34 | |
35 | void do_test_condition_notify_one_wakes_from_wait_with_predicate() |
36 | { |
37 | wait_for_flag data; |
38 | |
39 | boost::thread thread(bind(func: &wait_for_flag::wait_with_predicate, param&: data)); |
40 | |
41 | { |
42 | boost::unique_lock<boost::mutex> lock(data.mutex); |
43 | data.flag=true; |
44 | data.cond_var.notify_one(); |
45 | } |
46 | |
47 | thread.join(); |
48 | BOOST_CHECK(data.woken); |
49 | } |
50 | |
51 | void do_test_condition_notify_one_wakes_from_timed_wait() |
52 | { |
53 | wait_for_flag data; |
54 | |
55 | boost::thread thread(bind(func: &wait_for_flag::timed_wait_without_predicate, param&: data)); |
56 | |
57 | { |
58 | boost::unique_lock<boost::mutex> lock(data.mutex); |
59 | data.flag=true; |
60 | data.cond_var.notify_one(); |
61 | } |
62 | |
63 | thread.join(); |
64 | BOOST_CHECK(data.woken); |
65 | } |
66 | |
67 | void do_test_condition_notify_one_wakes_from_timed_wait_with_predicate() |
68 | { |
69 | wait_for_flag data; |
70 | |
71 | boost::thread thread(bind(func: &wait_for_flag::timed_wait_with_predicate, param&: data)); |
72 | |
73 | { |
74 | boost::unique_lock<boost::mutex> lock(data.mutex); |
75 | data.flag=true; |
76 | data.cond_var.notify_one(); |
77 | } |
78 | |
79 | thread.join(); |
80 | BOOST_CHECK(data.woken); |
81 | } |
82 | |
83 | void do_test_condition_notify_one_wakes_from_relative_timed_wait_with_predicate() |
84 | { |
85 | wait_for_flag data; |
86 | |
87 | boost::thread thread(bind(func: &wait_for_flag::relative_timed_wait_with_predicate, param&: data)); |
88 | |
89 | { |
90 | boost::unique_lock<boost::mutex> lock(data.mutex); |
91 | data.flag=true; |
92 | data.cond_var.notify_one(); |
93 | } |
94 | |
95 | thread.join(); |
96 | BOOST_CHECK(data.woken); |
97 | } |
98 | |
99 | namespace |
100 | { |
101 | boost::mutex multiple_wake_mutex; |
102 | boost::condition_variable multiple_wake_cond; |
103 | unsigned multiple_wake_count=0; |
104 | |
105 | void wait_for_condvar_and_increase_count() |
106 | { |
107 | boost::unique_lock<boost::mutex> lk(multiple_wake_mutex); |
108 | multiple_wake_cond.wait(m&: lk); |
109 | ++multiple_wake_count; |
110 | } |
111 | |
112 | } |
113 | |
114 | |
115 | void do_test_multiple_notify_one_calls_wakes_multiple_threads() |
116 | { |
117 | boost::thread thread1(&wait_for_condvar_and_increase_count); |
118 | boost::thread thread2(&wait_for_condvar_and_increase_count); |
119 | |
120 | boost::this_thread::sleep(rel_time: boost::posix_time::milliseconds(200)); |
121 | multiple_wake_cond.notify_one(); |
122 | |
123 | boost::thread thread3(&wait_for_condvar_and_increase_count); |
124 | |
125 | boost::this_thread::sleep(rel_time: boost::posix_time::milliseconds(200)); |
126 | multiple_wake_cond.notify_one(); |
127 | multiple_wake_cond.notify_one(); |
128 | boost::this_thread::sleep(rel_time: boost::posix_time::milliseconds(200)); |
129 | |
130 | { |
131 | boost::unique_lock<boost::mutex> lk(multiple_wake_mutex); |
132 | BOOST_CHECK(multiple_wake_count==3); |
133 | } |
134 | |
135 | thread1.join(); |
136 | thread2.join(); |
137 | thread3.join(); |
138 | } |
139 | |
140 | BOOST_AUTO_TEST_CASE(test_condition_notify_one) |
141 | { |
142 | timed_test(func: &do_test_condition_notify_one_wakes_from_wait, secs: timeout_seconds, type: execution_monitor::use_mutex); |
143 | timed_test(func: &do_test_condition_notify_one_wakes_from_wait_with_predicate, secs: timeout_seconds, type: execution_monitor::use_mutex); |
144 | timed_test(func: &do_test_condition_notify_one_wakes_from_timed_wait, secs: timeout_seconds, type: execution_monitor::use_mutex); |
145 | timed_test(func: &do_test_condition_notify_one_wakes_from_timed_wait_with_predicate, secs: timeout_seconds, type: execution_monitor::use_mutex); |
146 | timed_test(func: &do_test_condition_notify_one_wakes_from_relative_timed_wait_with_predicate, secs: timeout_seconds, type: execution_monitor::use_mutex); |
147 | timed_test(func: &do_test_multiple_notify_one_calls_wakes_multiple_threads, secs: timeout_seconds, type: execution_monitor::use_mutex); |
148 | } |
149 | |