1 // Copyright (C) 2001-2003
4 // Copyright Frank Mori Hess 2009
6 // Use, modification and
7 // distribution is subject to the Boost Software License, Version
8 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
11 // This is a simplified/modified version of libs/thread/test/test_mutex.cpp
12 // added to test boost::signals2::mutex.
13 // For more information, see http://www.boost.org
15 // Note boost/test/minimal.hpp can cause windows.h to get included, which
16 // can screw up our checks of _WIN32_WINNT if it is included
17 // after boost/signals2/mutex.hpp. Frank Hess 2009-03-07.
18 // We now use boost/test/included/unit_test.hpp, not sure if above still
19 // applies, but might as well leave the include where it is.
20 #define BOOST_TEST_MODULE mutex_test
21 #include <boost/test/included/unit_test.hpp>
23 #include <boost/bind/bind.hpp>
24 #include <boost/signals2/dummy_mutex.hpp>
25 #include <boost/signals2/mutex.hpp>
26 #include <boost/thread/locks.hpp>
27 #include <boost/thread/mutex.hpp>
28 #include <boost/thread/thread.hpp>
29 #include <boost/thread/thread_time.hpp>
30 #include <boost/thread/condition.hpp>
32 using namespace boost::placeholders
;
34 class execution_monitor
37 execution_monitor(int secs
)
38 : done(false), m_secs(secs
) { }
41 boost::mutex::scoped_lock
lock(mutex
);
46 boost::mutex::scoped_lock
lock(mutex
);
52 boost::posix_time::time_duration timeout
= boost::posix_time::seconds(m_secs
);
53 boost::mutex::scoped_lock
lock(mutex
);
55 if (!cond
.timed_wait(lock
, timeout
))
63 boost::condition cond
;
69 class indirect_adapter
72 indirect_adapter(F func
, execution_monitor
& monitor
)
73 : m_func(func
), m_monitor(monitor
) { }
74 void operator()() const
78 boost::thread
thrd(m_func
);
91 execution_monitor
& m_monitor
;
92 void operator=(indirect_adapter
&);
96 void timed_test(F func
, int secs
)
98 execution_monitor
monitor(secs
);
99 indirect_adapter
<F
> ifunc(func
, monitor
);
101 boost::thread
thrd(ifunc
);
102 BOOST_REQUIRE(monitor
.wait()); // Timed test didn't complete in time, possible deadlock
105 template <typename M
>
108 typedef M mutex_type
;
109 typedef typename
boost::unique_lock
<M
> lock_type
;
114 boost::condition condition
;
116 // Test the lock's constructors.
118 lock_type
lock(mutex
, boost::defer_lock
);
121 lock_type
lock(mutex
);
122 BOOST_CHECK(lock
? true : false);
124 // Construct a fast time out.
125 boost::posix_time::time_duration timeout
= boost::posix_time::milliseconds(100);
127 // Test the lock and the mutex with condition variables.
128 // No one is going to notify this condition variable. We expect to
130 BOOST_CHECK(!condition
.timed_wait(lock
, timeout
));
131 BOOST_CHECK(lock
? true : false);
133 // Test the lock and unlock methods.
137 BOOST_CHECK(lock
? true : false);
141 template <typename M
>
144 typedef M mutex_type
;
145 typedef typename
boost::unique_lock
<M
> lock_type
;
150 boost::condition condition
;
152 // Test the lock's constructors.
154 lock_type
lock(mutex
, boost::try_to_lock
);
155 BOOST_CHECK(lock
? true : false);
158 lock_type
lock(mutex
, boost::defer_lock
);
161 lock_type
lock(mutex
, boost::try_to_lock
);
162 BOOST_CHECK(lock
? true : false);
164 // Construct a fast time out.
165 boost::posix_time::time_duration timeout
= boost::posix_time::milliseconds(100);
167 // Test the lock and the mutex with condition variables.
168 // No one is going to notify this condition variable. We expect to
170 BOOST_CHECK(!condition
.timed_wait(lock
, timeout
));
171 BOOST_CHECK(lock
? true : false);
173 // Test the lock, unlock and trylock methods.
177 BOOST_CHECK(lock
? true : false);
180 BOOST_CHECK(lock
.try_lock());
181 BOOST_CHECK(lock
? true : false);
185 template<typename Mutex
>
186 struct test_lock_exclusion
188 typedef boost::unique_lock
<Mutex
> Lock
;
191 boost::mutex done_mutex
;
194 boost::condition_variable done_cond
;
196 test_lock_exclusion():
197 done(false),locked(false)
200 void locking_thread()
204 boost::lock_guard
<boost::mutex
> lk(done_mutex
);
205 locked
=lock
.owns_lock();
207 done_cond
.notify_one();
215 typedef test_lock_exclusion
<Mutex
> this_type
;
217 void do_test(void (this_type::*test_func
)())
222 boost::lock_guard
<boost::mutex
> lk(done_mutex
);
228 boost::thread
t(test_func
,this);
233 boost::mutex::scoped_lock
lk(done_mutex
);
234 BOOST_CHECK(!done_cond
.timed_wait(lk
, boost::posix_time::seconds(1),
235 boost::bind(&this_type::is_done
,this)));
239 boost::mutex::scoped_lock
lk(done_mutex
);
240 BOOST_CHECK(done_cond
.timed_wait(lk
, boost::posix_time::seconds(1),
241 boost::bind(&this_type::is_done
,this)));
257 do_test(&this_type::locking_thread
);
264 test_lock
<boost::signals2::mutex
>()();
265 // try_lock not supported on old versions of windows
266 #if !defined(BOOST_HAS_WINTHREADS) || (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0400))
267 test_trylock
<boost::signals2::mutex
>()();
269 test_lock_exclusion
<boost::signals2::mutex
>()();
274 timed_test(&do_test_mutex
, 3);
277 void do_test_dummy_mutex()
279 test_lock
<boost::signals2::dummy_mutex
>()();
280 test_trylock
<boost::signals2::dummy_mutex
>()();
283 void test_dummy_mutex()
285 timed_test(&do_test_dummy_mutex
, 2);
288 BOOST_AUTO_TEST_CASE(test_main
)