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
19void 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
35void 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
51void 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
67void 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
83void 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
99namespace
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
115void 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
140BOOST_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

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