diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
commit | 19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch) | |
tree | 42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/boost/libs/thread/test/sync | |
parent | Initial commit. (diff) | |
download | ceph-upstream.tar.xz ceph-upstream.zip |
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/thread/test/sync')
295 files changed, 27469 insertions, 0 deletions
diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable/assign_fail.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable/assign_fail.cpp new file mode 100644 index 000000000..703616ff1 --- /dev/null +++ b/src/boost/libs/thread/test/sync/conditions/condition_variable/assign_fail.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/condition_variable> + +// class condition_variable; + +// condition_variable& operator=(const condition_variable&) = delete; + +#include <boost/thread/condition_variable.hpp> + +void fail() +{ + boost::condition_variable cv0; + boost::condition_variable cv1; + cv1 = cv0; + +} + +#include "../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable/copy_fail.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable/copy_fail.cpp new file mode 100644 index 000000000..374ce3165 --- /dev/null +++ b/src/boost/libs/thread/test/sync/conditions/condition_variable/copy_fail.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/condition_variable> + +// class condition_variable; + +// condition_variable(const condition_variable&) = delete; + +#include <boost/thread/condition_variable.hpp> +#include <boost/detail/lightweight_test.hpp> + +void fail() +{ + boost::condition_variable cv0; + boost::condition_variable cv1(cv0); +} + +#include "../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable/default_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable/default_pass.cpp new file mode 100644 index 000000000..465a12de8 --- /dev/null +++ b/src/boost/libs/thread/test/sync/conditions/condition_variable/default_pass.cpp @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/condition_variable> + +// class condition_variable; + +// condition_variable(const condition_variable&) = delete; + +#include <boost/thread/condition_variable.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::condition_variable cv0; + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable/dtor_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable/dtor_pass.cpp new file mode 100644 index 000000000..533898ed4 --- /dev/null +++ b/src/boost/libs/thread/test/sync/conditions/condition_variable/dtor_pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/condition_variable> + +// class condition_variable; + +// condition_variable(const condition_variable&) = delete; + +#include <boost/thread/condition_variable.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/thread/locks.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::condition_variable* cv; +boost::mutex m; +typedef boost::unique_lock<boost::mutex> Lock; + +bool f_ready = false; +bool g_ready = false; + +void f() +{ + Lock lk(m); + f_ready = true; + cv->notify_one(); + cv->wait(lk); + delete cv; +} + +void g() +{ + Lock lk(m); + g_ready = true; + cv->notify_one(); + while (!f_ready) + { + cv->wait(lk); + } + cv->notify_one(); +} + +int main() +{ + cv = new boost::condition_variable; + boost::thread th2(g); + Lock lk(m); + while (!g_ready) + { + cv->wait(lk); + } + lk.unlock(); + boost::thread th1(f); + th1.join(); + th2.join(); + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable/lost_notif_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable/lost_notif_pass.cpp new file mode 100644 index 000000000..79dbcd295 --- /dev/null +++ b/src/boost/libs/thread/test/sync/conditions/condition_variable/lost_notif_pass.cpp @@ -0,0 +1,241 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2017 Austin J. Beer +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/condition_variable> + +// class condition_variable; + +// condition_variable(const condition_variable&) = delete; + +#include <iostream> +#include <boost/thread/condition_variable.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <cassert> + +// Summary of each test: +// 1. Start the test thread and wait for it to start up. +// The test thread waits for the flag to be set using a large timeout. +// 2. The main thread takes the lock and then sleeps for a long time while holding +// the lock before setting the flag and calling notify_one(). If the wait +// function being tested is polling pthread_cond_timedwait() internally, any +// notifications sent after pthread_cond_timedwait() times out but before it can +// reacquire the lock may be "lost". pthread_cond_timedwait() will report that +// it timed out and the wait function may incorrectly assume that no +// notification was received. This test ensures that that doesn't happen. +// 3. Measure how it takes the test thread to return. If it received the +// notification, it will return fairly quickly. If it missed the notification, +// the test thread won't return until the wait function being tested times out. + +//------------------------------------------------------------------------------ + +boost::condition_variable cv; +boost::mutex mut; + +bool flag; +bool waiting; + +bool flagIsSet() +{ + return flag; +} + +bool threadIsWaiting() +{ + return waiting; +} + +//------------------------------------------------------------------------------ + +#ifdef BOOST_THREAD_USES_DATETIME + +boost::posix_time::milliseconds posix_wait_time(1000); + +template <typename F> +void test_posix_wait_function(F f) +{ + flag = false; + waiting = false; + boost::thread t(f); + while (!threadIsWaiting()) + { + boost::this_thread::sleep(boost::posix_time::milliseconds(1)); + } + + boost::unique_lock<boost::mutex> lk(mut); + boost::this_thread::sleep(boost::posix_time::milliseconds(500)); + boost::posix_time::ptime t0 = boost::posix_time::microsec_clock::universal_time(); + flag = true; + cv.notify_one(); + lk.unlock(); + t.join(); + boost::posix_time::ptime t1 = boost::posix_time::microsec_clock::universal_time(); + + BOOST_TEST(t1 - t0 < boost::posix_time::milliseconds(250)); +} + +//------------------------------------------------------------------------------ + +void timed_wait_absolute_without_pred() +{ + boost::unique_lock<boost::mutex> lk(mut); + waiting = true; + while (!flagIsSet()) + { + cv.timed_wait(lk, boost::posix_time::microsec_clock::universal_time() + posix_wait_time); + } +} + +void timed_wait_absolute_with_pred() +{ + boost::unique_lock<boost::mutex> lk(mut); + waiting = true; + cv.timed_wait(lk, boost::posix_time::microsec_clock::universal_time() + posix_wait_time, flagIsSet); +} + +//------------------------------------------------------------------------------ + +void timed_wait_relative_without_pred() +{ + boost::unique_lock<boost::mutex> lk(mut); + waiting = true; + while (!flagIsSet()) + { + cv.timed_wait(lk, posix_wait_time); + } +} + +void timed_wait_relative_with_pred() +{ + boost::unique_lock<boost::mutex> lk(mut); + waiting = true; + cv.timed_wait(lk, posix_wait_time, flagIsSet); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_DATETIME not defined for this platform as not supported" +#endif + +//------------------------------------------------------------------------------ + +#ifdef BOOST_THREAD_USES_CHRONO + +boost::chrono::milliseconds chrono_wait_time(1000); + +template <typename F> +void test_chrono_wait_function(F f) +{ + flag = false; + waiting = false; + boost::thread t(f); + while (!threadIsWaiting()) + { + boost::this_thread::sleep_for(boost::chrono::milliseconds(1)); + } + + boost::unique_lock<boost::mutex> lk(mut); + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + boost::chrono::steady_clock::time_point t0 = boost::chrono::steady_clock::now(); + flag = true; + cv.notify_one(); + lk.unlock(); + t.join(); + boost::chrono::steady_clock::time_point t1 = boost::chrono::steady_clock::now(); + + BOOST_TEST(t1 - t0 < boost::chrono::milliseconds(250)); +} + +//------------------------------------------------------------------------------ + +void wait_until_system_without_pred() +{ + boost::unique_lock<boost::mutex> lk(mut); + waiting = true; + while (!flagIsSet()) + { + cv.wait_until(lk, boost::chrono::system_clock::now() + chrono_wait_time); + } +} + +void wait_until_system_with_pred() +{ + boost::unique_lock<boost::mutex> lk(mut); + waiting = true; + cv.wait_until(lk, boost::chrono::system_clock::now() + chrono_wait_time, flagIsSet); +} + +//------------------------------------------------------------------------------ + +void wait_until_steady_without_pred() +{ + boost::unique_lock<boost::mutex> lk(mut); + waiting = true; + while (!flagIsSet()) + { + cv.wait_until(lk, boost::chrono::steady_clock::now() + chrono_wait_time); + } +} + +void wait_until_steady_with_pred() +{ + boost::unique_lock<boost::mutex> lk(mut); + waiting = true; + cv.wait_until(lk, boost::chrono::steady_clock::now() + chrono_wait_time, flagIsSet); +} + +//------------------------------------------------------------------------------ + +void wait_for_without_pred() +{ + boost::unique_lock<boost::mutex> lk(mut); + waiting = true; + while (!flagIsSet()) + { + cv.wait_for(lk, chrono_wait_time); + } +} + +void wait_for_with_pred() +{ + boost::unique_lock<boost::mutex> lk(mut); + waiting = true; + cv.wait_for(lk, chrono_wait_time, flagIsSet); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif + +//------------------------------------------------------------------------------ + +int main() +{ +#ifdef BOOST_THREAD_USES_DATETIME + test_posix_wait_function(timed_wait_absolute_without_pred); + test_posix_wait_function(timed_wait_absolute_with_pred); + test_posix_wait_function(timed_wait_relative_without_pred); + test_posix_wait_function(timed_wait_relative_with_pred); +#endif + +#ifdef BOOST_THREAD_USES_CHRONO + test_chrono_wait_function(wait_until_system_without_pred); + test_chrono_wait_function(wait_until_system_with_pred); + test_chrono_wait_function(wait_until_steady_without_pred); + test_chrono_wait_function(wait_until_steady_with_pred); + test_chrono_wait_function(wait_for_without_pred); + test_chrono_wait_function(wait_for_with_pred); +#endif + + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable/native_handle_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable/native_handle_pass.cpp new file mode 100644 index 000000000..9835f5920 --- /dev/null +++ b/src/boost/libs/thread/test/sync/conditions/condition_variable/native_handle_pass.cpp @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/condition_variable> + +// class condition_variable; + +// condition_variable(const condition_variable&) = delete; + +#include <boost/thread/condition_variable.hpp> + +#include <boost/static_assert.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ +#if defined BOOST_THREAD_DEFINES_CONDITION_VARIABLE_NATIVE_HANDLE + //BOOST_STATIC_ASSERT((boost::is_same<boost::condition_variable::native_handle_type, pthread_cond_t*>::value)); + boost::condition_variable cv; + boost::condition_variable::native_handle_type h = cv.native_handle(); + BOOST_TEST(h != 0); +#else +#error "Test not applicable: BOOST_THREAD_DEFINES_CONDITION_VARIABLE_NATIVE_HANDLE not defined for this platform as not supported" +#endif + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_for_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_for_pass.cpp new file mode 100644 index 000000000..4c6a0af3e --- /dev/null +++ b/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_for_pass.cpp @@ -0,0 +1,116 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/condition_variable> + +// class condition_variable; + +// condition_variable(const condition_variable&) = delete; + +#include <iostream> +#include <boost/thread/condition_variable.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <cassert> +#include "../../../timming.hpp" + +#if defined BOOST_THREAD_USES_CHRONO + +boost::condition_variable cv; +boost::mutex mut; + +int test1 = 0; +int test2 = 0; + +int runs = 0; + +typedef boost::chrono::steady_clock Clock; +typedef boost::chrono::milliseconds milliseconds; +typedef boost::chrono::nanoseconds nanoseconds; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ + try { + boost::unique_lock<boost::mutex> lk(mut); + assert(test2 == 0); + test1 = 1; + cv.notify_one(); + Clock::time_point t0 = Clock::now(); + Clock::time_point t = t0 + milliseconds(250); + while (test2 == 0 && cv.wait_for(lk, t - Clock::now()) == boost::cv_status::no_timeout) {} + Clock::time_point t1 = Clock::now(); + if (runs == 0) + { + assert(t1 - t0 < max_diff); + assert(test2 != 0); + } + else + { + nanoseconds d = t1 - t0 - milliseconds(250); + std::cout << "diff= " << d.count() << std::endl; + std::cout << "max_diff= " << max_diff.count() << std::endl; + assert( d < max_diff); + assert(test2 == 0); + } + ++runs; + } catch(...) { + std::cout << "ERROR exception" << __LINE__ << std::endl; + assert(false); + } +} + +int main() +{ + try + { + boost::unique_lock<boost::mutex> lk(mut); + boost::thread t(f); + BOOST_TEST(test1 == 0); + while (test1 == 0) + cv.wait(lk); + BOOST_TEST(test1 != 0); + test2 = 1; + lk.unlock(); + cv.notify_one(); + t.join(); + } catch(...) { + std::cout << "ERROR exception" << __LINE__ << std::endl; + BOOST_TEST(false); + } + test1 = 0; + test2 = 0; + try + { + boost::unique_lock<boost::mutex> lk(mut); + boost::thread t(f); + BOOST_TEST(test1 == 0); + while (test1 == 0) + cv.wait(lk); + BOOST_TEST(test1 != 0); + lk.unlock(); + t.join(); + } catch(...) { + BOOST_TEST(false); + std::cout << "ERROR exception" << __LINE__ << std::endl; + } + return boost::report_errors(); +} +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif + diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_for_pred_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_for_pred_pass.cpp new file mode 100644 index 000000000..92ba82f1e --- /dev/null +++ b/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_for_pred_pass.cpp @@ -0,0 +1,127 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/condition_variable> + +// class condition_variable; + +// condition_variable(const condition_variable&) = delete; + +#include <boost/thread/condition_variable.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <cassert> +#include <iostream> +#include "../../../timming.hpp" + +#if defined BOOST_THREAD_USES_CHRONO + +class Pred +{ + int& i_; +public: + explicit Pred(int& i) : + i_(i) + { + } + + bool operator()() + { + return i_ != 0; + } +}; + +boost::condition_variable cv; +boost::mutex mut; + +int test1 = 0; +int test2 = 0; + +int runs = 0; + +typedef boost::chrono::system_clock Clock; +typedef boost::chrono::milliseconds milliseconds; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ + try { + boost::unique_lock < boost::mutex > lk(mut); + assert(test2 == 0); + test1 = 1; + cv.notify_one(); + Clock::time_point t0 = Clock::now(); + cv.wait_for(lk, milliseconds(250), Pred(test2)); + Clock::time_point t1 = Clock::now(); + if (runs == 0) + { + assert(t1 - t0 < max_diff); + assert(test2 != 0); + } + else + { + assert(t1 - t0 - milliseconds(250) < max_diff); + assert(test2 == 0); + } + ++runs; + } catch(...) { + std::cout << "ERROR exception" << __LINE__ << std::endl; + assert(false); + } +} + +int main() +{ + try + { + boost::unique_lock < boost::mutex > lk(mut); + boost::thread t(f); + BOOST_TEST(test1 == 0); + while (test1 == 0) + cv.wait(lk); + BOOST_TEST(test1 != 0); + test2 = 1; + lk.unlock(); + cv.notify_one(); + t.join(); + } catch(...) { + BOOST_TEST(false); + std::cout << "ERROR exception" << __LINE__ << std::endl; + } + test1 = 0; + test2 = 0; + try + { + boost::unique_lock < boost::mutex > lk(mut); + boost::thread t(f); + BOOST_TEST(test1 == 0); + while (test1 == 0) + cv.wait(lk); + BOOST_TEST(test1 != 0); + lk.unlock(); + t.join(); + } catch(...) { + BOOST_TEST(false); + std::cout << "ERROR exception" << __LINE__ << std::endl; + } + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_pass.cpp new file mode 100644 index 000000000..612724b85 --- /dev/null +++ b/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_pass.cpp @@ -0,0 +1,79 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/condition_variable> + +// class condition_variable; + +// void wait(unique_lock<mutex>& lock); + + +#include <boost/thread/condition_variable.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <cassert> +#include <iostream> + +#if defined BOOST_THREAD_USES_CHRONO + +boost::condition_variable cv; +boost::mutex mut; + +int test1 = 0; +int test2 = 0; + +int runs = 0; + +void f() +{ + try { + boost::unique_lock<boost::mutex> lk(mut); + assert(test2 == 0); + test1 = 1; + cv.notify_one(); + while (test2 == 0) { + cv.wait(lk); + } + assert(test2 != 0); + } catch(...) { + std::cout << "ERROR exception" << __LINE__ << std::endl; + assert(false); + } +} + +int main() +{ + try { + boost::unique_lock<boost::mutex>lk(mut); + boost::thread t(f); + BOOST_TEST(test1 == 0); + while (test1 == 0) + { + cv.wait(lk); + } + BOOST_TEST(test1 != 0); + test2 = 1; + lk.unlock(); + cv.notify_one(); + t.join(); + } catch(...) { + BOOST_TEST(false); + std::cout << "ERROR exception" << __LINE__ << std::endl; + } + return boost::report_errors(); +} +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif + diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_until_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_until_pass.cpp new file mode 100644 index 000000000..34ef32268 --- /dev/null +++ b/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_until_pass.cpp @@ -0,0 +1,128 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/condition_variable> + +// class condition_variable; + +// condition_variable(const condition_variable&) = delete; + +#include <boost/thread/condition_variable.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <iostream> +#include <cassert> +#include "../../../timming.hpp" + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +struct Clock +{ + typedef boost::chrono::milliseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef boost::chrono::time_point<Clock> time_point; + static const bool is_steady = true; + + static time_point now() + { + using namespace boost::chrono; + return time_point(duration_cast<duration> (steady_clock::now().time_since_epoch())); + } +}; + +boost::condition_variable cv; +boost::mutex mut; + + +int test1 = 0; +int test2 = 0; + +int runs = 0; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ + try { + boost::unique_lock < boost::mutex > lk(mut); + assert(test2 == 0); + test1 = 1; + cv.notify_one(); + Clock::time_point t0 = Clock::now(); + Clock::time_point t = t0 + Clock::duration(250); + while (test2 == 0 && cv.wait_until(lk, t) == boost::cv_status::no_timeout) {} + Clock::time_point t1 = Clock::now(); + if (runs == 0) + { + ns d = t1 - t0; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + assert(test2 != 0); + } + else + { + ns d = t1 - t0 - Clock::duration(250); + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + assert(test2 == 0); + } + ++runs; + } catch(...) { + assert(false); + std::cout << "ERROR exception" << __LINE__ << std::endl; + } +} + +int main() +{ + try + { + boost::unique_lock < boost::mutex > lk(mut); + boost::thread t(f); + BOOST_TEST(test1 == 0); + while (test1 == 0) + cv.wait(lk); + BOOST_TEST(test1 != 0); + test2 = 1; + lk.unlock(); + cv.notify_one(); + t.join(); + } catch(...) { + BOOST_TEST(false); + std::cout << "ERROR exception" << __LINE__ << std::endl; + } + + test1 = 0; + test2 = 0; + try + { + boost::unique_lock < boost::mutex > lk(mut); + boost::thread t(f); + BOOST_TEST(test1 == 0); + while (test1 == 0) + cv.wait(lk); + BOOST_TEST(test1 != 0); + lk.unlock(); + t.join(); + } catch(...) { + BOOST_TEST(false); + std::cout << "ERROR exception" << __LINE__ << std::endl; + } + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_until_pred_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_until_pred_pass.cpp new file mode 100644 index 000000000..120e49853 --- /dev/null +++ b/src/boost/libs/thread/test/sync/conditions/condition_variable/wait_until_pred_pass.cpp @@ -0,0 +1,146 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/condition_variable> + +// class condition_variable; + +// condition_variable(const condition_variable&) = delete; + +#include <boost/thread/condition_variable.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <cassert> +#include <iostream> +#include "../../../timming.hpp" + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::milliseconds milliseconds; +typedef boost::chrono::nanoseconds nanoseconds; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +struct Clock +{ + typedef boost::chrono::milliseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef boost::chrono::time_point<Clock> time_point; + static const bool is_steady = true; + + static time_point now() + { + using namespace boost::chrono; + return time_point(duration_cast<duration> (steady_clock::now().time_since_epoch())); + } +}; + +class Pred +{ + int& i_; +public: + explicit Pred(int& i) : + i_(i) + { + } + + bool operator()() + { + return i_ != 0; + } +}; + +boost::condition_variable cv; +boost::mutex mut; + +int test1 = 0; +int test2 = 0; + +int runs = 0; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ + try { + boost::unique_lock<boost::mutex> lk(mut); + assert(test2 == 0); + test1 = 1; + cv.notify_one(); + Clock::time_point t0 = Clock::now(); + Clock::time_point t = t0 + Clock::duration(250); + bool r = cv.wait_until(lk, t, Pred(test2)); + Clock::time_point t1 = Clock::now(); + if (runs == 0) + { + assert(t1 - t0 < max_diff); + assert(test2 != 0); + assert(r); + } + else + { + const nanoseconds d = t1 - t0 - milliseconds(250); + std::cout << "diff= " << d.count() << std::endl; + std::cout << "max_diff= " << max_diff.count() << std::endl; + assert(d < max_diff); + assert(test2 == 0); + assert(!r); + } + ++runs; + } catch(...) { + std::cout << "ERROR exception" << __LINE__ << std::endl; + assert(false); + } +} + +int main() +{ + try + { + boost::unique_lock<boost::mutex> lk(mut); + boost::thread t(f); + BOOST_TEST(test1 == 0); + while (test1 == 0) + cv.wait(lk); + BOOST_TEST(test1 != 0); + test2 = 1; + lk.unlock(); + cv.notify_one(); + t.join(); + } catch(...) { + BOOST_TEST(false); + std::cout << "ERROR exception" << __LINE__ << std::endl; + } + test1 = 0; + test2 = 0; + try + { + boost::unique_lock<boost::mutex> lk(mut); + boost::thread t(f); + BOOST_TEST(test1 == 0); + while (test1 == 0) + cv.wait(lk); + BOOST_TEST(test1 != 0); + lk.unlock(); + t.join(); + } catch(...) { + BOOST_TEST(false); + std::cout << "ERROR exception" << __LINE__ << std::endl; + } + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable_any/assign_fail.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/assign_fail.cpp new file mode 100644 index 000000000..6dba459cb --- /dev/null +++ b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/assign_fail.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/condition_variable_any> + +// class condition_variable_any; + +// condition_variable_any& operator=(const condition_variable_any&) = delete; + +#include <boost/thread/condition_variable.hpp> + +void fail() +{ + boost::condition_variable_any cv0; + boost::condition_variable_any cv1; + cv1 = cv0; +} + +#include "../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable_any/copy_fail.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/copy_fail.cpp new file mode 100644 index 000000000..71d3a3f06 --- /dev/null +++ b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/copy_fail.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/condition_variable_any> + +// class condition_variable_any; + +// condition_variable_any(const condition_variable_any&) = delete; + +#include <boost/thread/condition_variable.hpp> +#include <boost/detail/lightweight_test.hpp> + +void fail() +{ + boost::condition_variable_any cv0; + boost::condition_variable_any cv1(cv0); +} + +#include "../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable_any/default_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/default_pass.cpp new file mode 100644 index 000000000..21116ebc4 --- /dev/null +++ b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/default_pass.cpp @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/condition_variable_any> + +// class condition_variable_any; + +// condition_variable_any(const condition_variable_any&) = delete; + +#include <boost/thread/condition_variable.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::condition_variable_any cv0; + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable_any/dtor_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/dtor_pass.cpp new file mode 100644 index 000000000..7734d93b7 --- /dev/null +++ b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/dtor_pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/condition_variable_any> + +// class condition_variable_any; + +// condition_variable_any(const condition_variable_any&) = delete; + +#include <boost/thread/condition_variable.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/thread/locks.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::condition_variable_any* cv; +boost::timed_mutex m; +typedef boost::unique_lock<boost::timed_mutex> Lock; + +bool f_ready = false; +bool g_ready = false; + +void f() +{ + Lock lk(m); + f_ready = true; + cv->notify_one(); + cv->wait(lk); + delete cv; +} + +void g() +{ + Lock lk(m); + g_ready = true; + cv->notify_one(); + while (!f_ready) + { + cv->wait(lk); + } + cv->notify_one(); +} + +int main() +{ + cv = new boost::condition_variable_any; + boost::thread th2(g); + Lock lk(m); + while (!g_ready) + { + cv->wait(lk); + } + lk.unlock(); + boost::thread th1(f); + th1.join(); + th2.join(); + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable_any/lost_notif_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/lost_notif_pass.cpp new file mode 100644 index 000000000..c696da3c2 --- /dev/null +++ b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/lost_notif_pass.cpp @@ -0,0 +1,241 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2017 Austin J. Beer +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/condition_variable> + +// class condition_variable; + +// condition_variable(const condition_variable&) = delete; + +#include <iostream> +#include <boost/thread/condition_variable.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <cassert> + +// Summary of each test: +// 1. Start the test thread and wait for it to start up. +// The test thread waits for the flag to be set using a large timeout. +// 2. The main thread takes the lock and then sleeps for a long time while holding +// the lock before setting the flag and calling notify_one(). If the wait +// function being tested is polling pthread_cond_timedwait() internally, any +// notifications sent after pthread_cond_timedwait() times out but before it can +// reacquire the lock may be "lost". pthread_cond_timedwait() will report that +// it timed out and the wait function may incorrectly assume that no +// notification was received. This test ensures that that doesn't happen. +// 3. Measure how it takes the test thread to return. If it received the +// notification, it will return fairly quickly. If it missed the notification, +// the test thread won't return until the wait function being tested times out. + +//------------------------------------------------------------------------------ + +boost::condition_variable_any cv; +boost::mutex mut; + +bool flag; +bool waiting; + +bool flagIsSet() +{ + return flag; +} + +bool threadIsWaiting() +{ + return waiting; +} + +//------------------------------------------------------------------------------ + +#ifdef BOOST_THREAD_USES_DATETIME + +boost::posix_time::milliseconds posix_wait_time(1000); + +template <typename F> +void test_posix_wait_function(F f) +{ + flag = false; + waiting = false; + boost::thread t(f); + while (!threadIsWaiting()) + { + boost::this_thread::sleep(boost::posix_time::milliseconds(1)); + } + + boost::unique_lock<boost::mutex> lk(mut); + boost::this_thread::sleep(boost::posix_time::milliseconds(500)); + boost::posix_time::ptime t0 = boost::posix_time::microsec_clock::universal_time(); + flag = true; + cv.notify_one(); + lk.unlock(); + t.join(); + boost::posix_time::ptime t1 = boost::posix_time::microsec_clock::universal_time(); + + BOOST_TEST(t1 - t0 < boost::posix_time::milliseconds(250)); +} + +//------------------------------------------------------------------------------ + +void timed_wait_absolute_without_pred() +{ + boost::unique_lock<boost::mutex> lk(mut); + waiting = true; + while (!flagIsSet()) + { + cv.timed_wait(lk, boost::posix_time::microsec_clock::universal_time() + posix_wait_time); + } +} + +void timed_wait_absolute_with_pred() +{ + boost::unique_lock<boost::mutex> lk(mut); + waiting = true; + cv.timed_wait(lk, boost::posix_time::microsec_clock::universal_time() + posix_wait_time, flagIsSet); +} + +//------------------------------------------------------------------------------ + +void timed_wait_relative_without_pred() +{ + boost::unique_lock<boost::mutex> lk(mut); + waiting = true; + while (!flagIsSet()) + { + cv.timed_wait(lk, posix_wait_time); + } +} + +void timed_wait_relative_with_pred() +{ + boost::unique_lock<boost::mutex> lk(mut); + waiting = true; + cv.timed_wait(lk, posix_wait_time, flagIsSet); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_DATETIME not defined for this platform as not supported" +#endif + +//------------------------------------------------------------------------------ + +#ifdef BOOST_THREAD_USES_CHRONO + +boost::chrono::milliseconds chrono_wait_time(1000); + +template <typename F> +void test_chrono_wait_function(F f) +{ + flag = false; + waiting = false; + boost::thread t(f); + while (!threadIsWaiting()) + { + boost::this_thread::sleep_for(boost::chrono::milliseconds(1)); + } + + boost::unique_lock<boost::mutex> lk(mut); + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + boost::chrono::steady_clock::time_point t0 = boost::chrono::steady_clock::now(); + flag = true; + cv.notify_one(); + lk.unlock(); + t.join(); + boost::chrono::steady_clock::time_point t1 = boost::chrono::steady_clock::now(); + + BOOST_TEST(t1 - t0 < boost::chrono::milliseconds(250)); +} + +//------------------------------------------------------------------------------ + +void wait_until_system_without_pred() +{ + boost::unique_lock<boost::mutex> lk(mut); + waiting = true; + while (!flagIsSet()) + { + cv.wait_until(lk, boost::chrono::system_clock::now() + chrono_wait_time); + } +} + +void wait_until_system_with_pred() +{ + boost::unique_lock<boost::mutex> lk(mut); + waiting = true; + cv.wait_until(lk, boost::chrono::system_clock::now() + chrono_wait_time, flagIsSet); +} + +//------------------------------------------------------------------------------ + +void wait_until_steady_without_pred() +{ + boost::unique_lock<boost::mutex> lk(mut); + waiting = true; + while (!flagIsSet()) + { + cv.wait_until(lk, boost::chrono::steady_clock::now() + chrono_wait_time); + } +} + +void wait_until_steady_with_pred() +{ + boost::unique_lock<boost::mutex> lk(mut); + waiting = true; + cv.wait_until(lk, boost::chrono::steady_clock::now() + chrono_wait_time, flagIsSet); +} + +//------------------------------------------------------------------------------ + +void wait_for_without_pred() +{ + boost::unique_lock<boost::mutex> lk(mut); + waiting = true; + while (!flagIsSet()) + { + cv.wait_for(lk, chrono_wait_time); + } +} + +void wait_for_with_pred() +{ + boost::unique_lock<boost::mutex> lk(mut); + waiting = true; + cv.wait_for(lk, chrono_wait_time, flagIsSet); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif + +//------------------------------------------------------------------------------ + +int main() +{ +#ifdef BOOST_THREAD_USES_DATETIME + test_posix_wait_function(timed_wait_absolute_without_pred); + test_posix_wait_function(timed_wait_absolute_with_pred); + test_posix_wait_function(timed_wait_relative_without_pred); + test_posix_wait_function(timed_wait_relative_with_pred); +#endif + +#ifdef BOOST_THREAD_USES_CHRONO + test_chrono_wait_function(wait_until_system_without_pred); + test_chrono_wait_function(wait_until_system_with_pred); + test_chrono_wait_function(wait_until_steady_without_pred); + test_chrono_wait_function(wait_until_steady_with_pred); + test_chrono_wait_function(wait_for_without_pred); + test_chrono_wait_function(wait_for_with_pred); +#endif + + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_for_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_for_pass.cpp new file mode 100644 index 000000000..b1fca89f6 --- /dev/null +++ b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_for_pass.cpp @@ -0,0 +1,104 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/condition_variable_any> + +// class condition_variable_any; + +// condition_variable_any(const condition_variable_any&) = delete; + +#include <boost/thread/condition_variable.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + +#if defined BOOST_THREAD_USES_CHRONO + +boost::condition_variable_any cv; + +typedef boost::timed_mutex L0; +typedef boost::unique_lock<L0> L1; + +L0 m0; + +int test1 = 0; +int test2 = 0; + +int runs = 0; + +typedef boost::chrono::system_clock Clock; +typedef boost::chrono::milliseconds milliseconds; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ + L1 lk(m0); + BOOST_TEST(test2 == 0); + test1 = 1; + cv.notify_one(); + Clock::time_point t0 = Clock::now(); + Clock::time_point t = t0 + milliseconds(250); + while (test2 == 0 && cv.wait_for(lk, t - Clock::now()) == boost::cv_status::no_timeout) {} + Clock::time_point t1 = Clock::now(); + if (runs == 0) + { + ns d = t1 - t0; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + BOOST_TEST(test2 != 0); + } + else + { + ns d = t1 - t0 - ms(250); + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + BOOST_TEST(test2 == 0); + } + ++runs; +} + +int main() +{ + { + L1 lk(m0); + boost::thread t(f); + BOOST_TEST(test1 == 0); + while (test1 == 0) + cv.wait(lk); + BOOST_TEST(test1 != 0); + test2 = 1; + lk.unlock(); + cv.notify_one(); + t.join(); + } + test1 = 0; + test2 = 0; + { + L1 lk(m0); + boost::thread t(f); + BOOST_TEST(test1 == 0); + while (test1 == 0) + cv.wait(lk); + BOOST_TEST(test1 != 0); + lk.unlock(); + t.join(); + } + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_for_pred_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_for_pred_pass.cpp new file mode 100644 index 000000000..3885b23c1 --- /dev/null +++ b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_for_pred_pass.cpp @@ -0,0 +1,118 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/condition_variable_any> + +// class condition_variable_any; + +// condition_variable_any(const condition_variable_any&) = delete; + +#include <boost/thread/condition_variable.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + +#if defined BOOST_THREAD_USES_CHRONO + +class Pred +{ + int& i_; +public: + explicit Pred(int& i) : + i_(i) + { + } + + bool operator()() + { + return i_ != 0; + } +}; + +boost::condition_variable_any cv; + +typedef boost::timed_mutex L0; +typedef boost::unique_lock<L0> L1; + +L0 m0; + +int test1 = 0; +int test2 = 0; + +int runs = 0; + +typedef boost::chrono::system_clock Clock; +typedef boost::chrono::milliseconds milliseconds; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ + L1 lk(m0); + BOOST_TEST(test2 == 0); + test1 = 1; + cv.notify_one(); + Clock::time_point t0 = Clock::now(); + cv.wait_for(lk, milliseconds(250), Pred(test2)); + Clock::time_point t1 = Clock::now(); + if (runs == 0) + { + ns d = t1 - t0 ; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + BOOST_TEST(test2 != 0); + } + else + { + ns d = t1 - t0 - ms(250); + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + BOOST_TEST(test2 == 0); + } + ++runs; +} + +int main() +{ + { + L1 lk(m0); + boost::thread t(f); + BOOST_TEST(test1 == 0); + while (test1 == 0) + cv.wait(lk); + BOOST_TEST(test1 != 0); + test2 = 1; + lk.unlock(); + cv.notify_one(); + t.join(); + } + test1 = 0; + test2 = 0; + { + L1 lk(m0); + boost::thread t(f); + BOOST_TEST(test1 == 0); + while (test1 == 0) + cv.wait(lk); + BOOST_TEST(test1 != 0); + lk.unlock(); + t.join(); + } + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_until_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_until_pass.cpp new file mode 100644 index 000000000..acf5fb1c4 --- /dev/null +++ b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_until_pass.cpp @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/condition_variable_any> + +// class condition_variable_any; + +// condition_variable_any(const condition_variable_any&) = delete; + +#include <boost/thread/condition_variable.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +struct Clock +{ + typedef boost::chrono::milliseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef boost::chrono::time_point<Clock> time_point; + static const bool is_steady = true; + + static time_point now() + { + using namespace boost::chrono; + return time_point(duration_cast<duration> (steady_clock::now().time_since_epoch())); + } +}; + +boost::condition_variable_any cv; + +typedef boost::timed_mutex L0; +typedef boost::unique_lock<L0> L1; + +L0 m0; + +int test1 = 0; +int test2 = 0; + +int runs = 0; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ + L1 lk(m0); + BOOST_TEST(test2 == 0); + test1 = 1; + cv.notify_one(); + Clock::time_point t0 = Clock::now(); + Clock::time_point t = t0 + Clock::duration(250); + while (test2 == 0 && cv.wait_until(lk, t) == boost::cv_status::no_timeout) {} + Clock::time_point t1 = Clock::now(); + if (runs == 0) + { + ns d = t1 - t0; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + BOOST_TEST(test2 != 0); + } + else + { + ns d = t1 - t0 - ms(250); + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + BOOST_TEST(test2 == 0); + } + ++runs; +} + +int main() +{ + { + L1 lk(m0); + boost::thread t(f); + BOOST_TEST(test1 == 0); + while (test1 == 0) + cv.wait(lk); + BOOST_TEST(test1 != 0); + test2 = 1; + lk.unlock(); + cv.notify_one(); + t.join(); + } + test1 = 0; + test2 = 0; + { + L1 lk(m0); + boost::thread t(f); + BOOST_TEST(test1 == 0); + while (test1 == 0) + cv.wait(lk); + BOOST_TEST(test1 != 0); + lk.unlock(); + t.join(); + } + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif diff --git a/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_until_pred_pass.cpp b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_until_pred_pass.cpp new file mode 100644 index 000000000..f6e9b7ee2 --- /dev/null +++ b/src/boost/libs/thread/test/sync/conditions/condition_variable_any/wait_until_pred_pass.cpp @@ -0,0 +1,134 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/condition_variable_any> + +// class condition_variable_any; + +// condition_variable_any(const condition_variable_any&) = delete; + +#include <boost/thread/condition_variable.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + +#if defined BOOST_THREAD_USES_CHRONO + +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; + +struct Clock +{ + typedef boost::chrono::milliseconds duration; + typedef duration::rep rep; + typedef duration::period period; + typedef boost::chrono::time_point<Clock> time_point; + static const bool is_steady = true; + + static time_point now() + { + using namespace boost::chrono; + return time_point(duration_cast<duration> (steady_clock::now().time_since_epoch())); + } +}; + +class Pred +{ + int& i_; +public: + explicit Pred(int& i) : + i_(i) + { + } + + bool operator()() + { + return i_ != 0; + } +}; + +boost::condition_variable_any cv; + +typedef boost::timed_mutex L0; +typedef boost::unique_lock<L0> L1; + +L0 m0; + +int test1 = 0; +int test2 = 0; + +int runs = 0; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ + L1 lk(m0); + BOOST_TEST(test2 == 0); + test1 = 1; + cv.notify_one(); + Clock::time_point t0 = Clock::now(); + Clock::time_point t = t0 + Clock::duration(250); + bool r = cv.wait_until(lk, t, Pred(test2)); + Clock::time_point t1 = Clock::now(); + if (runs == 0) + { + ns d = t1 - t0; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + BOOST_TEST(test2 != 0); + BOOST_TEST(r); + } + else + { + ns d = t1 - t0 - ms(250); + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + BOOST_TEST(test2 == 0); + BOOST_TEST(!r); + } + ++runs; +} + +int main() +{ + { + L1 lk(m0); + boost::thread t(f); + BOOST_TEST(test1 == 0); + while (test1 == 0) + cv.wait(lk); + BOOST_TEST(test1 != 0); + test2 = 1; + lk.unlock(); + cv.notify_one(); + t.join(); + } + test1 = 0; + test2 = 0; + { + L1 lk(m0); + boost::thread t(f); + BOOST_TEST(test1 == 0); + while (test1 == 0) + cv.wait(lk); + BOOST_TEST(test1 != 0); + lk.unlock(); + t.join(); + } + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif diff --git a/src/boost/libs/thread/test/sync/conditions/cv_status/cv_status_pass.cpp b/src/boost/libs/thread/test/sync/conditions/cv_status/cv_status_pass.cpp new file mode 100644 index 000000000..becac4da5 --- /dev/null +++ b/src/boost/libs/thread/test/sync/conditions/cv_status/cv_status_pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/thread.hpp> + +// class thread + +// static unsigned hardware_concurrency(); + +#include <boost/thread/condition_variable.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + { + BOOST_TEST(boost::cv_status::no_timeout != boost::cv_status::timeout); + } + { + boost::cv_status st = boost::cv_status::no_timeout; + BOOST_TEST(st == boost::cv_status::no_timeout); + BOOST_TEST(boost::cv_status::no_timeout==st); + BOOST_TEST(st != boost::cv_status::timeout); + BOOST_TEST(boost::cv_status::timeout!=st); + } + { + boost::cv_status st = boost::cv_status::timeout; + BOOST_TEST(st == boost::cv_status::timeout); + BOOST_TEST(boost::cv_status::timeout==st); + BOOST_TEST(st != boost::cv_status::no_timeout); + BOOST_TEST(boost::cv_status::no_timeout!=st); + } + { + boost::cv_status st; + st = boost::cv_status::no_timeout; + BOOST_TEST(st == boost::cv_status::no_timeout); + BOOST_TEST(boost::cv_status::no_timeout==st); + BOOST_TEST(st != boost::cv_status::timeout); + BOOST_TEST(boost::cv_status::timeout!=st); + } + { + boost::cv_status st; + st = boost::cv_status::timeout; + BOOST_TEST(st == boost::cv_status::timeout); + BOOST_TEST(boost::cv_status::timeout==st); + BOOST_TEST(st != boost::cv_status::no_timeout); + BOOST_TEST(boost::cv_status::no_timeout!=st); + } + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/conditions/notify_all_at_thread_exit_pass.cpp b/src/boost/libs/thread/test/sync/conditions/notify_all_at_thread_exit_pass.cpp new file mode 100644 index 000000000..d6eecbd95 --- /dev/null +++ b/src/boost/libs/thread/test/sync/conditions/notify_all_at_thread_exit_pass.cpp @@ -0,0 +1,51 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/condition_variable.hpp> + +// void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk); + +#define BOOST_THREAD_USES_MOVE +#define BOOST_THREAD_VESRION 3 + +#include <boost/thread/condition_variable.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/locks.hpp> +#include <boost/thread/thread.hpp> +#include <boost/chrono/chrono.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::condition_variable cv; +boost::mutex mut; + +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::high_resolution_clock Clock; + +void func() +{ + boost::unique_lock < boost::mutex > lk(mut); + boost::notify_all_at_thread_exit(cv, boost::move(lk)); + boost::this_thread::sleep_for(ms(300)); +} + +int main() +{ + boost::unique_lock < boost::mutex > lk(mut); + boost::thread(func).detach(); + Clock::time_point t0 = Clock::now(); + cv.wait(lk); + Clock::time_point t1 = Clock::now(); + BOOST_TEST(t1 - t0 > ms(250)); + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/async/async_executor_pass.cpp b/src/boost/libs/thread/test/sync/futures/async/async_executor_pass.cpp new file mode 100644 index 000000000..d5a0f4423 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/async/async_executor_pass.cpp @@ -0,0 +1,250 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// template <class Executor, class F, class... Args> +// future<typename result_of<F(Args...)>::type> +// async(Executor& ex, F&& f, Args&&... args); + +#define BOOST_THREAD_VERSION 5 +#include <boost/config.hpp> +#if ! defined BOOST_NO_CXX11_DECLTYPE +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif +#include <iostream> +#include <boost/thread/future.hpp> +#include <boost/thread/thread.hpp> +#include <boost/thread/detail/memory.hpp> +#include <boost/thread/csbl/memory/unique_ptr.hpp> +#include <memory> +#include <boost/detail/lightweight_test.hpp> +#include <boost/thread/executors/basic_thread_pool.hpp> +#include <boost/thread/executor.hpp> + +typedef boost::chrono::high_resolution_clock Clock; +typedef boost::chrono::milliseconds ms; + +class A +{ + long data_; + +public: + typedef long result_type; + + explicit A(long i) : + data_(i) + { + } + + long doit() const + { + boost::this_thread::sleep_for(ms(200)); + return data_; + } + long operator()() const + { + boost::this_thread::sleep_for(ms(200)); + return data_; + } +}; + +class MoveOnly +{ +public: + typedef int result_type; + + int value; + +BOOST_THREAD_MOVABLE_ONLY(MoveOnly) + MoveOnly() + { + value = 0; + } + MoveOnly( BOOST_THREAD_RV_REF(MoveOnly)) + { + value = 1; + } + MoveOnly& operator=(BOOST_THREAD_RV_REF(MoveOnly)) + { + value = 2; + return *this; + } + + int operator()() + { + boost::this_thread::sleep_for(ms(200)); + return 3; + } + template <typename OS> + friend OS& operator<<(OS& os, MoveOnly const& v) + { + os << v.value; + return os; + } + }; + + namespace boost + { +BOOST_THREAD_DCL_MOVABLE (MoveOnly) + } + +int f0() +{ + boost::this_thread::sleep_for(ms(200)); + return 3; +} + +int i = 0; + +int& f1() +{ + boost::this_thread::sleep_for(ms(200)); + return i; +} + +void f2() +{ + boost::this_thread::sleep_for(ms(200)); +} + +boost::csbl::unique_ptr<int> f3_0() +{ + boost::this_thread::sleep_for(ms(200)); + boost::csbl::unique_ptr<int> r( (new int(3))); + return boost::move(r); +} +MoveOnly f3_1() +{ + boost::this_thread::sleep_for(ms(200)); + MoveOnly r; + return boost::move(r); +} + +boost::csbl::unique_ptr<int> f3(int i) +{ + boost::this_thread::sleep_for(ms(200)); + return boost::csbl::unique_ptr<int>(new int(i)); +} + +boost::csbl::unique_ptr<int> f4( + BOOST_THREAD_RV_REF_BEG boost::csbl::unique_ptr<int> BOOST_THREAD_RV_REF_END p +) +{ + boost::this_thread::sleep_for(ms(200)); + return boost::move(p); +} + +struct check_timer { + boost::chrono::nanoseconds delay; + Clock::time_point start; + check_timer(boost::chrono::nanoseconds delay) + : delay(delay) + , start(Clock::now()) + { + } + ~check_timer() { + Clock::time_point now = Clock::now(); + BOOST_TEST(now - start < delay); + std::cout << __FILE__ << "[" << __LINE__ << "] " << (now - start).count() << std::endl; + } + +}; + +int main() +{ + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; +#if defined BOOST_THREAD_PROVIDES_EXECUTORS + { + try + { + boost::executor_adaptor<boost::basic_thread_pool> ex(1); + boost::future<int> f = boost::async(ex, &f0); + boost::this_thread::sleep_for(ms(300)); + int res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST(res == 3); + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } +#endif +#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) && defined BOOST_THREAD_PROVIDES_EXECUTORS + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try + { + boost::executor_adaptor<boost::basic_thread_pool> ex(1); + boost::future<long> f = boost::async(ex, A(3)); + boost::this_thread::sleep_for(ms(300)); + int res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST(res == 3); + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + + } +#endif +#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) && defined BOOST_THREAD_PROVIDES_EXECUTORS + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try + { + boost::executor_adaptor<boost::basic_thread_pool> ex(1); + MoveOnly mo; + boost::future<int> f = boost::async(ex, boost::move(mo)); + //boost::future<int> f = boost::async(ex, MoveOnly()); + boost::this_thread::sleep_for(ms(300)); + int res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST(res == 3); + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } +#endif + + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/futures/async/async_pass.cpp b/src/boost/libs/thread/test/sync/futures/async/async_pass.cpp new file mode 100644 index 000000000..86fdfdbec --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/async/async_pass.cpp @@ -0,0 +1,903 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// template <class F, class... Args> +// future<typename result_of<F(Args...)>::type> +// async(F&& f, Args&&... args); + +// template <class F, class... Args> +// future<typename result_of<F(Args...)>::type> +// async(launch policy, F&& f, Args&&... args); + +//#define BOOST_THREAD_VERSION 3 +#define BOOST_THREAD_VERSION 4 +#include <boost/config.hpp> +#if ! defined BOOST_NO_CXX11_DECLTYPE +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif +#include <iostream> +#include <boost/thread/future.hpp> +#include <boost/thread/thread.hpp> +#include <boost/thread/detail/memory.hpp> +#include <boost/thread/csbl/memory/unique_ptr.hpp> +#include <memory> +#include <boost/detail/lightweight_test.hpp> + +typedef boost::chrono::high_resolution_clock Clock; +typedef boost::chrono::milliseconds ms; + +class A +{ + long data_; + +public: + typedef long result_type; + + explicit A(long i) : + data_(i) + { + } + + long doit() const + { + boost::this_thread::sleep_for(ms(200)); + return data_; + } + long operator()() const + { + boost::this_thread::sleep_for(ms(200)); + return data_; + } +}; + +class MoveOnly +{ +public: + typedef int result_type; + + int value; + + BOOST_THREAD_MOVABLE_ONLY(MoveOnly) + MoveOnly() + { + value = 0; + } + MoveOnly( BOOST_THREAD_RV_REF(MoveOnly)) + { + value = 1; + } + MoveOnly& operator=(BOOST_THREAD_RV_REF(MoveOnly)) + { + value = 2; + return *this; + } + + int operator()() const + { + boost::this_thread::sleep_for(ms(200)); + return 3; + } + template <typename OS> + friend OS& operator<<(OS& os, MoveOnly const& v) + { + os << v.value; + return os; + } +}; + +namespace boost +{ + BOOST_THREAD_DCL_MOVABLE (MoveOnly) +} + +int f0() +{ + boost::this_thread::sleep_for(ms(200)); + return 3; +} + +int i = 0; + +int& f1() +{ + boost::this_thread::sleep_for(ms(200)); + return i; +} + +void f2() +{ + boost::this_thread::sleep_for(ms(200)); +} + +boost::csbl::unique_ptr<int> f3_0() +{ + boost::this_thread::sleep_for(ms(200)); + boost::csbl::unique_ptr<int> r( (new int(3))); + return boost::move(r); +} +MoveOnly f3_1() +{ + boost::this_thread::sleep_for(ms(200)); + MoveOnly r; + return boost::move(r); +} + +boost::csbl::unique_ptr<int> f3(int i) +{ + boost::this_thread::sleep_for(ms(200)); + return boost::csbl::unique_ptr<int>(new int(i)); +} + +boost::csbl::unique_ptr<int> f4( + BOOST_THREAD_RV_REF_BEG boost::csbl::unique_ptr<int> BOOST_THREAD_RV_REF_END p +) +{ + boost::this_thread::sleep_for(ms(200)); + return boost::move(p); +} + +struct check_timer { + boost::chrono::nanoseconds delay; + Clock::time_point start; + check_timer(boost::chrono::nanoseconds delay) + : delay(delay) + , start(Clock::now()) + { + } + ~check_timer() { + Clock::time_point now = Clock::now(); + BOOST_TEST(now - start < delay); + std::cout << __FILE__ << "[" << __LINE__ << "] " << (now - start).count() << std::endl; + } + +}; + +int main() +{ + { + try { + boost::async(f0); + } catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } + { + try { + boost::async(boost::launch::async, f0); + } catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } +#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try { + boost::async(boost::launch::deferred, f0); + } catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } +#endif + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try + { + boost::future<int> f = boost::async(f0); + boost::this_thread::sleep_for(ms(300)); + int res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST(res == 3); + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + + } + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try + { + boost::shared_future<int> f = boost::async(f0).share(); + boost::this_thread::sleep_for(ms(300)); + int res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST(res == 3); + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + + } + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try + { + boost::future<int> f = boost::async(boost::launch::async, f0); + boost::this_thread::sleep_for(ms(300)); + int res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST(res == 3); + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + + } + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try + { + boost::future<long> f = boost::async(boost::launch::async, A(3)); + boost::this_thread::sleep_for(ms(300)); + int res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST(res == 3); + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + + } +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try + { + boost::future<long> f = boost::async(boost::launch::deferred, A(3)); + //boost::this_thread::sleep_for(ms(300)); + int res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST(res == 3); + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + + } +#endif +#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try + { + A a(3); + boost::future<long> f = boost::async(boost::launch::async, &A::doit, &a); + boost::this_thread::sleep_for(ms(300)); + int res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST(res == 3); + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + + } + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try + { + A a(3); + boost::future<long> f = boost::async(boost::launch::deferred, &A::doit, &a); + boost::this_thread::sleep_for(ms(300)); + int res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST(res == 3); + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + + } +#endif + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try + { + boost::future<int> f = boost::async(boost::launch::async, BOOST_THREAD_MAKE_RV_REF(MoveOnly())); + boost::this_thread::sleep_for(ms(300)); + int res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST(res == 3); + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try + { + boost::future<int> f = boost::async(boost::launch::deferred, BOOST_THREAD_MAKE_RV_REF(MoveOnly())); + boost::this_thread::sleep_for(ms(300)); + int res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST(res == 3); + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } +#endif + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try + { + boost::future<int> f = boost::async(boost::launch::any, f0); + boost::this_thread::sleep_for(ms(300)); + int res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST(res == 3); + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl; + { + try + { + boost::future<int> f = boost::async(boost::launch::deferred, f0); + //boost::this_thread::sleep_for(ms(300)); + int res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST(res == 3); + } + catch (std::exception& ex) + { + std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } +#endif + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try + { + boost::future<int&> f = boost::async(f1); + boost::this_thread::sleep_for(ms(300)); + int* res; + { + check_timer timer(ms(500)); + res = &f.get(); + } + BOOST_TEST(res == &i); + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try + { + boost::future<int&> f = boost::async(boost::launch::async, f1); + boost::this_thread::sleep_for(ms(300)); + int* res; + { + check_timer timer(ms(500)); + res = &f.get(); + } + BOOST_TEST(res == &i); + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try + { + boost::future<int&> f = boost::async(boost::launch::any, f1); + boost::this_thread::sleep_for(ms(300)); + int* res; + { + check_timer timer(ms(500)); + res = &f.get(); + } + BOOST_TEST(res == &i); + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl; + { + try + { + boost::future<int&> f = boost::async(boost::launch::deferred, f1); + //boost::this_thread::sleep_for(ms(300)); + int* res; + { + check_timer timer(ms(500)); + res = &f.get(); + } + BOOST_TEST(res == &i); + } + catch (std::exception& ex) + { + std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } +#endif + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try + { + boost::future<void> f = boost::async(f2); + boost::this_thread::sleep_for(ms(300)); + { + check_timer timer(ms(500)); + f.get(); + } + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try + { + boost::future<void> f = boost::async(boost::launch::async, f2); + boost::this_thread::sleep_for(ms(300)); + { + check_timer timer(ms(500)); + f.get(); + } + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try + { + boost::future<void> f = boost::async(boost::launch::any, f2); + boost::this_thread::sleep_for(ms(300)); + { + check_timer timer(ms(500)); + f.get(); + } + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl; + { + try + { + boost::future<void> f = boost::async(boost::launch::deferred, f2); + //boost::this_thread::sleep_for(ms(300)); + { + check_timer timer(ms(500)); + f.get(); + } + } + catch (std::exception& ex) + { + std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } +#endif + + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try + { + boost::future<MoveOnly> f = boost::async(&f3_1); + boost::this_thread::sleep_for(ms(300)); + MoveOnly res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST_EQ(res.value, 2); + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try + { + boost::future<MoveOnly> f = boost::async(boost::launch::deferred, &f3_1); + //boost::this_thread::sleep_for(ms(300)); + MoveOnly res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST_EQ(res.value, 2); + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } +#endif + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try + { + boost::future<MoveOnly> f; + f = boost::async(&f3_1); + boost::this_thread::sleep_for(ms(300)); + MoveOnly res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST(res.value == 2); + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } + std::cout << __FILE__ << "[" << __LINE__ << "]" << std::endl; + { + try + { + boost::future<boost::csbl::unique_ptr<int> > f = boost::async(&f3_0); + boost::this_thread::sleep_for(ms(300)); + boost::csbl::unique_ptr<int> res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST(*res == 3); + } + catch (std::exception& ex) + { + std::cout << __FILE__ << "[" << __LINE__ << "]" << ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } + +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl; + { + try + { + boost::future<boost::csbl::unique_ptr<int> > f = boost::async(boost::launch::async, &f3, 3); + boost::this_thread::sleep_for(ms(300)); + boost::csbl::unique_ptr<int> res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST(*res == 3); + } + catch (std::exception& ex) + { + std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } + std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl; + { + try + { + boost::future<boost::csbl::unique_ptr<int> > f = boost::async(boost::launch::deferred, &f3, 3); + //boost::this_thread::sleep_for(ms(300)); + boost::csbl::unique_ptr<int> res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST(*res == 3); + } + catch (std::exception& ex) + { + std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } + std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl; + { + try + { + boost::future<boost::csbl::unique_ptr<int> > f = boost::async(&f3, 3); + boost::this_thread::sleep_for(ms(300)); + boost::csbl::unique_ptr<int> res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST(*res == 3); + } + catch (std::exception& ex) + { + std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } +#endif + +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl; + { + try + { + boost::future<boost::csbl::unique_ptr<int> > f = boost::async(boost::launch::async, &f4, boost::csbl::unique_ptr<int>(new int(3))); + boost::this_thread::sleep_for(ms(300)); + boost::csbl::unique_ptr<int> res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST(*res == 3); + } + catch (std::exception& ex) + { + std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } + std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl; + { + try + { + boost::future<boost::csbl::unique_ptr<int> > f = boost::async(boost::launch::deferred, &f4, boost::csbl::unique_ptr<int>(new int(3))); + //boost::this_thread::sleep_for(ms(300)); + boost::csbl::unique_ptr<int> res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST(*res == 3); + } + catch (std::exception& ex) + { + std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } + std::cout << __FILE__ <<"["<<__LINE__<<"]"<<std::endl; + { + try + { + boost::future<boost::csbl::unique_ptr<int> > f = boost::async(&f4, boost::csbl::unique_ptr<int>(new int(3))); + boost::this_thread::sleep_for(ms(300)); + boost::csbl::unique_ptr<int> res; + { + check_timer timer(ms(500)); + res = f.get(); + } + BOOST_TEST(*res == 3); + } + catch (std::exception& ex) + { + std::cout << __FILE__ <<"["<<__LINE__<<"]"<<ex.what() << std::endl; + BOOST_TEST(false && "exception thrown"); + } + catch (...) + { + BOOST_TEST(false && "exception thrown"); + } + } +#endif + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/futures/future/async_deferred_then_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/async_deferred_then_pass.cpp new file mode 100644 index 000000000..b400074cd --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/future/async_deferred_then_pass.cpp @@ -0,0 +1,153 @@ +// Copyright (C) 2012-2013 Vicente Botet +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class future<R> + +// template<typename F> +// auto then(F&& func) -> future<decltype(func(*this))>; + +#define BOOST_THREAD_VERSION 4 +//#define BOOST_THREAD_USES_LOG +#define BOOST_THREAD_USES_LOG_THREAD_ID +#include <boost/thread/detail/log.hpp> + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + + +int p1() +{ + BOOST_THREAD_LOG << "p1 < " << BOOST_THREAD_END_LOG; + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + BOOST_THREAD_LOG << "p1 >" << BOOST_THREAD_END_LOG; + return 1; +} + +int p2(boost::future<int> f) +{ + BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG; + BOOST_TEST(f.valid()); + int i = f.get(); + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG; + return 2 * i; +} + +void p3(boost::future<int> f) +{ + BOOST_THREAD_LOG << "p3 <" << &f << BOOST_THREAD_END_LOG; + BOOST_TEST(f.valid()); + int i = f.get(); + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + BOOST_THREAD_LOG << "p3 <" << &f << " " <<i << BOOST_THREAD_END_LOG; + return; +} + +int main() +{ + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + try + { + boost::future<int> f1 = boost::async(boost::launch::deferred, &p1); + BOOST_TEST(f1.valid()); + { + boost::future<int> f2 = f1.then(&p2); + BOOST_TEST(f2.valid()); + } + BOOST_TEST(! f1.valid()); + } + catch (std::exception& ex) + { + BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + catch (...) + { + BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::future<int> f1 = boost::async(boost::launch::deferred, &p1); + BOOST_TEST(f1.valid()); + boost::future<int> f2 = f1.then(&p2); + BOOST_TEST(f2.valid()); + BOOST_TEST(! f1.valid()); + try + { + BOOST_TEST(f2.get()==2); + } + catch (std::exception& ex) + { + BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + catch (...) + { + BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::future<int> f1 = boost::async(boost::launch::deferred, &p1); + BOOST_TEST(f1.valid()); + boost::future<void> f2 = f1.then(&p3); + BOOST_TEST(f2.valid()); + try + { + f2.wait(); + } + catch (std::exception& ex) + { + BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + catch (...) + { + BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::future<int> f2 = boost::async(boost::launch::deferred, p1).then(&p2); + BOOST_TEST(f2.get()==2); + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::future<int> f1 = boost::async(boost::launch::deferred, p1); + boost::future<int> f21 = f1.then(&p2); + boost::future<int> f2= f21.then(&p2); + BOOST_TEST(f2.get()==4); + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::future<int> f1 = boost::async(boost::launch::deferred, p1); + boost::future<int> f2= f1.then(&p2).then(&p2); + BOOST_TEST(f2.get()==4); + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::future<int> f2 = boost::async(boost::launch::deferred, p1).then(&p2).then(&p2); + BOOST_TEST(f2.get()==4); + } + + return boost::report_errors(); +} + +#else + +int main() +{ + return 0; +} +#endif diff --git a/src/boost/libs/thread/test/sync/futures/future/copy_assign_fail.cpp b/src/boost/libs/thread/test/sync/futures/future/copy_assign_fail.cpp new file mode 100644 index 000000000..170f3a057 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/future/copy_assign_fail.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class future<R> + +// future& operator=(const future&) = delete; + + +#define BOOST_THREAD_VERSION 3 +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + { + typedef int T; + boost::promise<T> p; + boost::future<T> f0 = p.get_future(); + boost::future<T> f; + f = f0; + } + + return boost::report_errors(); +} + +#include "../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/futures/future/copy_ctor_fail.cpp b/src/boost/libs/thread/test/sync/futures/future/copy_ctor_fail.cpp new file mode 100644 index 000000000..3a16afd50 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/future/copy_ctor_fail.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> +// class future<R> + +// future(const future&) = delete; + + +#define BOOST_THREAD_VERSION 3 +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + { + typedef int T; + boost::promise<T> p; + boost::future<T> f0 = p.get_future(); + boost::future<T> f = f0; + } + + return boost::report_errors(); +} + +#include "../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/futures/future/default_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/default_pass.cpp new file mode 100644 index 000000000..1b4cf392f --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/future/default_pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class future<R> + +// future(); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + + { + boost::future<int> f; + BOOST_TEST(!f.valid()); + } + { + boost::future<int&> f; + BOOST_TEST(!f.valid()); + } + { + boost::future<void> f; + BOOST_TEST(!f.valid()); + } + + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/future/dtor_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/dtor_pass.cpp new file mode 100644 index 000000000..abfca7d8c --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/future/dtor_pass.cpp @@ -0,0 +1,109 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class future<R> + +// ~future(); + +#define BOOST_THREAD_VERSION 3 +#include <boost/exception/exception.hpp> + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +#include "../test_allocator.hpp" +#endif + +int main() +{ +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS + BOOST_TEST(test_alloc_base::count == 0); + { + typedef int T; + boost::future<T> f; + { + boost::promise<T> p(boost::allocator_arg, test_allocator<T>()); + BOOST_TEST(test_alloc_base::count == 1); + f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(test_alloc_base::count == 1); + BOOST_TEST(f.valid()); + } + BOOST_TEST(test_alloc_base::count == 1); + BOOST_TEST(f.valid()); + } + BOOST_TEST(test_alloc_base::count == 0); + { + typedef int& T; + boost::future<T> f; + { + boost::promise<T> p(boost::allocator_arg, test_allocator<int>()); + BOOST_TEST(test_alloc_base::count == 1); + f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(test_alloc_base::count == 1); + BOOST_TEST(f.valid()); + } + BOOST_TEST(test_alloc_base::count == 1); + BOOST_TEST(f.valid()); + } + BOOST_TEST(test_alloc_base::count == 0); + { + typedef void T; + boost::future<T> f; + { + boost::promise<T> p(boost::allocator_arg, test_allocator<T>()); + BOOST_TEST(test_alloc_base::count == 1); + f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(test_alloc_base::count == 1); + BOOST_TEST(f.valid()); + } + BOOST_TEST(test_alloc_base::count == 1); + BOOST_TEST(f.valid()); + } + BOOST_TEST(test_alloc_base::count == 0); +#endif + { + typedef int T; + boost::future<T> f; + { + boost::promise<T> p; + f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(f.valid()); + } + BOOST_TEST(f.valid()); + } + { + typedef int& T; + boost::future<T> f; + { + boost::promise<T> p; + f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(f.valid()); + } + BOOST_TEST(f.valid()); + } + { + typedef void T; + boost::future<T> f; + { + boost::promise<T> p; + f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(f.valid()); + } + BOOST_TEST(f.valid()); + } + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/future/get_or_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/get_or_pass.cpp new file mode 100644 index 000000000..7db938d37 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/future/get_or_pass.cpp @@ -0,0 +1,187 @@ +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class future<R> + +// R future::get_or(R&&); +// R& future<R&>::get_or(R&); + +#define BOOST_THREAD_VERSION 4 +//#define BOOST_THREAD_USES_LOG +#define BOOST_THREAD_USES_LOG_THREAD_ID +#include <boost/thread/detail/log.hpp> + +#include <boost/thread/future.hpp> +#include <boost/thread/thread.hpp> +#include <boost/core/ref.hpp> +#include <boost/detail/lightweight_test.hpp> + +#if defined BOOST_THREAD_USES_CHRONO + +#ifdef BOOST_MSVC +#pragma warning(disable: 4127) // conditional expression is constant +#endif + +namespace boost +{ +template <typename T> +struct wrap +{ + wrap(T const& v) : value(v){} + T value; + +}; + +template <typename T> +exception_ptr make_exception_ptr(T v) { + return copy_exception(wrap<T>(v)); +} +} + +void func1(boost::promise<int> p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + p.set_value(3); +} + +void func2(boost::promise<int> p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + p.set_exception(boost::make_exception_ptr(3)); +} + +int j = 0; + +void func3(boost::promise<int&> p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + j = 5; + p.set_value(j); +} + +void func4(boost::promise<int&> p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + p.set_exception(boost::make_exception_ptr(3.5)); +} + +void func5(boost::promise<void> p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + p.set_value(); +} + +void func6(boost::promise<void> p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + p.set_exception(boost::make_exception_ptr(4)); +} + + +int main() +{ + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + typedef int T; + { + boost::promise<T> p; + boost::future<T> f = p.get_future(); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func1, boost::move(p)).detach(); +#else + p.set_value(3); +#endif + BOOST_TEST(f.valid()); + BOOST_TEST(f.get_or(4) == 3); +#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET + BOOST_TEST(!f.valid()); +#endif + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::promise<T> p; + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + boost::future<T> f = p.get_future(); + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func2, boost::move(p)).detach(); +#else + p.set_exception(boost::make_exception_ptr(3)); +#endif + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + try + { + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + BOOST_TEST(f.valid()); + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + BOOST_TEST(f.get_or(4) == 4); + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + } + catch (...) + { + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } +#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + BOOST_TEST(!f.valid()); +#endif + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + typedef int& T; + { + boost::promise<T> p; + boost::future<T> f = p.get_future(); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func3, boost::move(p)).detach(); +#else + int j=5; + p.set_value(j); +#endif + BOOST_TEST(f.valid()); + int k=4; + BOOST_TEST(f.get_or(boost::ref(k)) == 5); +#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET + BOOST_TEST(!f.valid()); +#endif + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::promise<T> p; + boost::future<T> f = p.get_future(); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func4, boost::move(p)).detach(); +#else + p.set_exception(boost::make_exception_ptr(3.5)); +#endif + try + { + BOOST_TEST(f.valid()); + int j=4; + BOOST_TEST(f.get_or(boost::ref(j)) == 4); + } + catch (...) + { + BOOST_TEST(false); + } +#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET + BOOST_TEST(!f.valid()); +#endif + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif diff --git a/src/boost/libs/thread/test/sync/futures/future/get_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/get_pass.cpp new file mode 100644 index 000000000..ec2ccf8b0 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/future/get_pass.cpp @@ -0,0 +1,268 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class future<R> + +// const R& future::get(); +// R& future<R&>::get(); +// void future<void>::get(); + +//#define BOOST_THREAD_VERSION 3 +#define BOOST_THREAD_VERSION 4 +//#define BOOST_THREAD_USES_LOG +#define BOOST_THREAD_USES_LOG_THREAD_ID +#include <boost/thread/detail/log.hpp> + +#include <boost/thread/future.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> + +#if defined BOOST_THREAD_USES_CHRONO + +#ifdef BOOST_MSVC +#pragma warning(disable: 4127) // conditional expression is constant +#endif + +namespace boost +{ +template <typename T> +struct wrap +{ + wrap(T const& v) : value(v){} + T value; + +}; + +template <typename T> +exception_ptr make_exception_ptr(T v) { + return copy_exception(wrap<T>(v)); +} +} + +void func1(boost::promise<int> p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + p.set_value(3); +} + +void func2(boost::promise<int> p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + p.set_exception(boost::make_exception_ptr(3)); +} + +int j = 0; + +void func3(boost::promise<int&> p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + j = 5; + p.set_value(j); +} + +void func4(boost::promise<int&> p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + p.set_exception(boost::make_exception_ptr(3.5)); +} + +void func5(boost::promise<void> p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + p.set_value(); +} + +void func6(boost::promise<void> p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + p.set_exception(boost::make_exception_ptr(4)); +} + + +int main() +{ + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + typedef int T; + { + boost::promise<T> p; + boost::future<T> f = p.get_future(); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func1, boost::move(p)).detach(); +#else + p.set_value(3); +#endif + BOOST_TEST(f.valid()); + BOOST_TEST(f.get() == 3); +#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET + BOOST_TEST(!f.valid()); +#endif + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::promise<T> p; + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + boost::future<T> f = p.get_future(); + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func2, boost::move(p)).detach(); +#else + p.set_exception(boost::make_exception_ptr(3)); +#endif + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + try + { + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + BOOST_TEST(f.valid()); + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + BOOST_TEST(f.get() == 3); + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + } + catch (boost::wrap<int> const& i) + { + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + BOOST_TEST(i.value == 3); + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + } + catch (...) + { + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + } +#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + BOOST_TEST(!f.valid()); +#endif + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + typedef int& T; + { + boost::promise<T> p; + boost::future<T> f = p.get_future(); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func3, boost::move(p)).detach(); +#else + int j=5; + p.set_value(j); +#endif + BOOST_TEST(f.valid()); + BOOST_TEST(f.get() == 5); +#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET + BOOST_TEST(!f.valid()); +#endif + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::promise<T> p; + boost::future<T> f = p.get_future(); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func4, boost::move(p)).detach(); +#else + p.set_exception(boost::make_exception_ptr(3.5)); +#endif + try + { + BOOST_TEST(f.valid()); + BOOST_TEST(f.get() == 3); + BOOST_TEST(false); + } + catch (boost::wrap<double> const& i) + { + BOOST_TEST(i.value == 3.5); + } +#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET + BOOST_TEST(!f.valid()); +#endif + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::promise<T> p; + boost::future<T> f = p.get_future(); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func4, boost::move(p)).detach(); +#else + p.set_exception(boost::make_exception_ptr(3.5)); +#endif + try + { + BOOST_TEST(f.valid()); + boost::exception_ptr ptr = f.get_exception_ptr(); + } + catch (...) + { + BOOST_TEST(false); + } + BOOST_TEST(f.valid()); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + + typedef void T; + { + boost::promise<T> p; + boost::future<T> f = p.get_future(); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func5, boost::move(p)).detach(); +#else + p.set_value(); +#endif + BOOST_TEST(f.valid()); + f.get(); +#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET + BOOST_TEST(!f.valid()); +#endif + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::promise<T> p; + boost::future<T> f = p.get_future(); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func6, boost::move(p)).detach(); +#else + p.set_exception(boost::make_exception_ptr(4)); +#endif + try + { + BOOST_TEST(f.valid()); + f.get(); + BOOST_TEST(false); + } + catch (boost::wrap<int> const& i) + { + BOOST_TEST(i.value == 4); + } + catch (...) + { + BOOST_TEST(false); + } +#ifdef BOOST_THREAD_PROVIDES_FUTURE_INVALID_AFTER_GET + BOOST_TEST(!f.valid()); +#endif + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif diff --git a/src/boost/libs/thread/test/sync/futures/future/move_assign_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/move_assign_pass.cpp new file mode 100644 index 000000000..ebb13e5e0 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/future/move_assign_pass.cpp @@ -0,0 +1,87 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <future> + +// class future<R> + +// future& operator=(future&& rhs); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::mutex m0; +boost::mutex m1; + +int main() +{ + { + typedef int T; + boost::promise<T> p; + boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + boost::future<T> f; + f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(f.valid()); + } + { + typedef int T; + boost::future<T> f0; + boost::future<T> f; + f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(!f.valid()); + } + { + typedef int& T; + boost::promise<T> p; + boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + boost::future<T> f; + f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(f.valid()); + } + { + typedef int& T; + boost::future<T> f0; + boost::future<T> f; + f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(!f.valid()); + } + { + typedef void T; + boost::promise<T> p; + boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + boost::future<T> f; + f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(f.valid()); + } + { + typedef void T; + boost::future<T> f0; + boost::future<T> f; + f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(!f.valid()); + } + + + return boost::report_errors(); + +} + diff --git a/src/boost/libs/thread/test/sync/futures/future/move_ctor_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/move_ctor_pass.cpp new file mode 100644 index 000000000..8da893a3c --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/future/move_ctor_pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <future> + +// class future<R> + +// future(future&& rhs); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::mutex m; + +int main() +{ + { + typedef int T; + boost::promise<T> p; + boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + boost::future<T> f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(f.valid()); + } + { + typedef int T; + boost::future<T> f0; + boost::future<T> f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(!f.valid()); + } + { + typedef int& T; + boost::promise<T> p; + boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + boost::future<T> f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(f.valid()); + } + { + typedef int& T; + boost::future<T> f0; + boost::future<T> f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(!f.valid()); + } + { + typedef void T; + boost::promise<T> p; + boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + boost::future<T> f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(f.valid()); + } + { + typedef void T; + boost::future<T> f0; + boost::future<T> f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(!f.valid()); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/future/share_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/share_pass.cpp new file mode 100644 index 000000000..91c07f5cd --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/future/share_pass.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class future<R> + +// shared_future<R> share() &&; + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + + { + typedef int T; + boost::promise<T> p; + boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + boost::shared_future<T> sf = f0.share(); + boost::shared_future<T> f = sf; + BOOST_TEST(!f0.valid()); + BOOST_TEST(f.valid()); + } + { + typedef int T; + boost::future<T> f0; + boost::shared_future<T> sf = f0.share(); + boost::shared_future<T> f = sf; + BOOST_TEST(!f0.valid()); + BOOST_TEST(!f.valid()); + } + { + typedef int& T; + boost::promise<T> p; + boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + boost::shared_future<T> sf = f0.share(); + boost::shared_future<T> f = sf; + BOOST_TEST(!f0.valid()); + BOOST_TEST(f.valid()); + } + { + typedef int& T; + boost::future<T> f0; + boost::shared_future<T> sf = f0.share(); + boost::shared_future<T> f = sf; + BOOST_TEST(!f0.valid()); + BOOST_TEST(!f.valid()); + } + { + typedef void T; + boost::promise<T> p; + boost::future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + boost::shared_future<T> sf = f0.share(); + boost::shared_future<T> f = sf; + BOOST_TEST(!f0.valid()); + BOOST_TEST(f.valid()); + } + { + typedef void T; + boost::future<T> f0; + boost::shared_future<T> sf = f0.share(); + boost::shared_future<T> f = sf; + BOOST_TEST(!f0.valid()); + BOOST_TEST(!f.valid()); + } + + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/future/then_deferred_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/then_deferred_pass.cpp new file mode 100644 index 000000000..0ea37bd7f --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/future/then_deferred_pass.cpp @@ -0,0 +1,137 @@ +// Copyright (C) 2012-2013 Vicente Botet +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class future<R> + +// template<typename F> +// auto then(F&& func) -> future<decltype(func(*this))>; + +#define BOOST_THREAD_VERSION 4 +//#define BOOST_THREAD_USES_LOG +#define BOOST_THREAD_USES_LOG_THREAD_ID +#include <boost/thread/detail/log.hpp> + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <cassert> + +#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION + +#ifdef BOOST_MSVC +#pragma warning(disable: 4127) // conditional expression is constant +#endif + +int p1() +{ + BOOST_THREAD_LOG << "p1 < " << BOOST_THREAD_END_LOG; + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + BOOST_THREAD_LOG << "p1 >" << BOOST_THREAD_END_LOG; + return 1; +} + +int p2(boost::future<int> f) +{ + assert(f.is_ready()); + + BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG; + BOOST_TEST(f.valid()); + int i = f.get(); + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG; + return 2 * i; +} + +void p3(boost::future<int> f) +{ + assert(f.is_ready()); + BOOST_THREAD_LOG << "p3 <" << &f << BOOST_THREAD_END_LOG; + BOOST_TEST(f.valid()); + int i = f.get(); + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + BOOST_THREAD_LOG << "p3 <" << &f << " " <<i << BOOST_THREAD_END_LOG; + return; +} + +int main() +{ + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::future<int> f1 = boost::async(boost::launch::async, &p1); + BOOST_TEST(f1.valid()); + boost::future<int> f2 = f1.then(boost::launch::deferred, &p2); + BOOST_TEST(f2.valid()); + BOOST_TEST(! f1.valid()); + try + { + BOOST_TEST(f2.get()==2); + } + catch (std::exception& ex) + { + BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + catch (...) + { + BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::future<int> f1 = boost::async(boost::launch::async, &p1); + BOOST_TEST(f1.valid()); + boost::future<void> f2 = f1.then(boost::launch::deferred, &p3); + BOOST_TEST(f2.valid()); + try + { + f2.wait(); + } + catch (std::exception& ex) + { + BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + catch (...) + { + BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::future<int> f2 = boost::async(p1).then(boost::launch::deferred, &p2); + BOOST_TEST(f2.get()==2); + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::future<int> f1 = boost::async(p1); + boost::future<int> f21 = f1.then(boost::launch::deferred, &p2); + boost::future<int> f2= f21.then(boost::launch::deferred, &p2); + BOOST_TEST(f2.get()==4); + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::future<int> f1 = boost::async(p1); + boost::future<int> f2= f1.then(boost::launch::deferred, &p2).then(boost::launch::deferred, &p2); + BOOST_TEST(f2.get()==4); + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::future<int> f2 = boost::async(p1).then(boost::launch::deferred, &p2).then(boost::launch::deferred, &p2); + BOOST_TEST(f2.get()==4); + } + + return boost::report_errors(); +} + +#else + +int main() +{ + return 0; +} +#endif diff --git a/src/boost/libs/thread/test/sync/futures/future/then_executor_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/then_executor_pass.cpp new file mode 100644 index 000000000..fcb062a0e --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/future/then_executor_pass.cpp @@ -0,0 +1,152 @@ +// Copyright (C) 2014 Vicente Botet +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class future<R> + +// template<typename F> +// auto then(F&& func) -> future<decltype(func(*this))>; + +#define BOOST_THREAD_VERSION 5 +//#define BOOST_THREAD_USES_LOG +#define BOOST_THREAD_USES_LOG_THREAD_ID +#include <boost/thread/detail/log.hpp> + +#include <boost/thread/future.hpp> +#include <boost/thread/executors/basic_thread_pool.hpp> +#include <boost/thread/executor.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <cassert> + +#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION + +#ifdef BOOST_MSVC +#pragma warning(disable: 4127) // conditional expression is constant +#endif + +int p1() +{ + BOOST_THREAD_LOG << "p1 < " << BOOST_THREAD_END_LOG; + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + BOOST_THREAD_LOG << "p1 >" << BOOST_THREAD_END_LOG; + return 1; +} + +int p2(boost::future<int> f) +{ + assert(f.is_ready()); + BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG; + BOOST_TEST(f.valid()); + int i = f.get(); + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG; + return 2 * i; +} + +void p3(boost::future<int> f) +{ + assert(f.is_ready()); + BOOST_THREAD_LOG << "p3 <" << &f << BOOST_THREAD_END_LOG; + BOOST_TEST(f.valid()); + int i = f.get(); + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + BOOST_THREAD_LOG << "p3 <" << &f << " " <<i << BOOST_THREAD_END_LOG; + return; +} + +int main() +{ + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::basic_thread_pool ex(1); + boost::future<int> f1 = boost::async(boost::launch::async, &p1); + BOOST_TEST(f1.valid()); + boost::future<int> f2 = f1.then(ex, &p2); + BOOST_TEST(f2.valid()); + BOOST_TEST(! f1.valid()); + try + { + BOOST_TEST(f2.get()==2); + } + catch (std::exception& ex) + { + BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + catch (...) + { + BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::basic_thread_pool ex(1); + boost::future<int> f1 = boost::async(boost::launch::async, &p1); + BOOST_TEST(f1.valid()); + boost::future<void> f2 = f1.then(ex, &p3); + BOOST_TEST(f2.valid()); + try + { + f2.wait(); + } + catch (std::exception& ex) + { + BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + catch (...) + { + BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::basic_thread_pool ex(1); + boost::future<int> f2 = boost::async(p1).then(ex, &p2); + BOOST_TEST(f2.get()==2); + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::basic_thread_pool ex(1); + boost::future<int> f1 = boost::async(p1); + boost::future<int> f21 = f1.then(ex, &p2); + boost::future<int> f2= f21.then(ex, &p2); + BOOST_TEST(f2.get()==4); + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::basic_thread_pool ex(1); + boost::future<int> f1 = boost::async(p1); + boost::future<int> f21 = f1.then(ex, &p2); + boost::future<int> f2= f21.then(&p2); + BOOST_TEST(f2.get()==4); + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::basic_thread_pool ex(1); + boost::future<int> f1 = boost::async(p1); + boost::future<int> f2= f1.then(&p2).then(ex, &p2); + BOOST_TEST(f2.get()==4); + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::basic_thread_pool ex(1); + boost::future<int> f2 = boost::async(p1).then(ex, &p2).then(ex, &p2); + BOOST_TEST(f2.get()==4); + } + + return boost::report_errors(); +} + +#else + +int main() +{ + return 0; +} +#endif diff --git a/src/boost/libs/thread/test/sync/futures/future/then_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/then_pass.cpp new file mode 100644 index 000000000..12270679b --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/future/then_pass.cpp @@ -0,0 +1,133 @@ +// Copyright (C) 2012-2013 Vicente Botet +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class future<R> + +// template<typename F> +// auto then(F&& func) -> future<decltype(func(*this))>; + +#define BOOST_THREAD_VERSION 4 +//#define BOOST_THREAD_USES_LOG +#define BOOST_THREAD_USES_LOG_THREAD_ID +#include <boost/thread/detail/log.hpp> + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION + +#ifdef BOOST_MSVC +#pragma warning(disable: 4127) // conditional expression is constant +#endif + +int p1() +{ + BOOST_THREAD_LOG << "p1 < " << BOOST_THREAD_END_LOG; + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + BOOST_THREAD_LOG << "p1 >" << BOOST_THREAD_END_LOG; + return 1; +} + +int p2(boost::future<int> f) +{ + BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG; + BOOST_TEST(f.valid()); + int i = f.get(); + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG; + return 2 * i; +} + +void p3(boost::future<int> f) +{ + BOOST_THREAD_LOG << "p3 <" << &f << BOOST_THREAD_END_LOG; + BOOST_TEST(f.valid()); + int i = f.get(); + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + BOOST_THREAD_LOG << "p3 <" << &f << " " <<i << BOOST_THREAD_END_LOG; + return; +} + +int main() +{ + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::future<int> f1 = boost::async(boost::launch::async, &p1); + BOOST_TEST(f1.valid()); + boost::future<int> f2 = f1.then(&p2); + BOOST_TEST(f2.valid()); + BOOST_TEST(! f1.valid()); + try + { + BOOST_TEST(f2.get()==2); + } + catch (std::exception& ex) + { + BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + catch (...) + { + BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::future<int> f1 = boost::async(boost::launch::async, &p1); + BOOST_TEST(f1.valid()); + boost::future<void> f2 = f1.then(&p3); + BOOST_TEST(f2.valid()); + try + { + f2.wait(); + } + catch (std::exception& ex) + { + BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + catch (...) + { + BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::future<int> f2 = boost::async(p1).then(&p2); + BOOST_TEST(f2.get()==2); + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::future<int> f1 = boost::async(p1); + boost::future<int> f21 = f1.then(&p2); + boost::future<int> f2= f21.then(&p2); + BOOST_TEST(f2.get()==4); + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::future<int> f1 = boost::async(p1); + boost::future<int> f2= f1.then(&p2).then(&p2); + BOOST_TEST(f2.get()==4); + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::future<int> f2 = boost::async(p1).then(&p2).then(&p2); + BOOST_TEST(f2.get()==4); + } + + return boost::report_errors(); +} + +#else + +int main() +{ + return 0; +} +#endif diff --git a/src/boost/libs/thread/test/sync/futures/future/wait_for_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/wait_for_pass.cpp new file mode 100644 index 000000000..71bca7abe --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/future/wait_for_pass.cpp @@ -0,0 +1,174 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class future<R> + +// template <class Rep, class Period> +// future_status +// wait_for(const chrono::duration<Rep, Period>& rel_time) const; + +#define BOOST_THREAD_VERSION 4 +//#define BOOST_THREAD_USES_LOG +#define BOOST_THREAD_USES_LOG_THREAD_ID +#include <boost/thread/detail/log.hpp> +#include "../../../timming.hpp" + +#include <boost/thread/future.hpp> +#include <boost/thread/thread.hpp> +#include <boost/chrono/chrono_io.hpp> +#include <boost/detail/lightweight_test.hpp> + +#if defined BOOST_THREAD_USES_CHRONO + +#ifdef BOOST_MSVC +#pragma warning(disable: 4127) // conditional expression is constant +#endif + +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; + +namespace boost +{ + template <typename OStream> + OStream& operator<<(OStream& os , boost::future_status st ) + { + os << underlying_cast<int>(st) << " "; + return os; + } + template <typename T> + struct wrap + { + wrap(T const& v) : + value(v) + { + } + T value; + + }; + + template <typename T> + exception_ptr make_exception_ptr(T v) + { + return copy_exception(wrap<T> (v)); + } +} + +void func1(boost::promise<int> p) +{ + boost::this_thread::sleep_for(ms(500)); + p.set_value(3); +} + +int j = 0; + +void func3(boost::promise<int&> p) +{ + boost::this_thread::sleep_for(ms(500)); + j = 5; + p.set_value(j); +} + +void func5(boost::promise<void> p) +{ + boost::this_thread::sleep_for(ms(500)); + p.set_value(); +} + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +int main() +{ + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + typedef boost::chrono::high_resolution_clock Clock; + { + typedef int T; + boost::promise<T> p; + boost::future<T> f = p.get_future(); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func1, boost::move(p)).detach(); +#endif + BOOST_TEST(f.valid()); + BOOST_TEST_EQ(f.wait_for(ms(250)) , boost::future_status::timeout); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +#else + func1(boost::move(p)); +#endif + BOOST_TEST(f.valid()); + BOOST_TEST_EQ(f.wait_for(ms(750)) , boost::future_status::ready); + BOOST_TEST(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + BOOST_TEST(f.valid()); + ns d = t1 - t0; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + } + { + typedef int& T; + boost::promise<T> p; + boost::future<T> f = p.get_future(); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func3, boost::move(p)).detach(); +#endif + BOOST_TEST(f.valid()); + BOOST_TEST_EQ(f.wait_for(ms(250)) , boost::future_status::timeout); + BOOST_TEST(f.valid()); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +#else + func3(boost::move(p)); +#endif + BOOST_TEST_EQ(f.wait_for(ms(750)) , boost::future_status::ready); + BOOST_TEST(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + BOOST_TEST(f.valid()); + ns d = t1 - t0; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + } + { + typedef void T; + boost::promise<T> p; + boost::future<T> f = p.get_future(); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func5, boost::move(p)).detach(); +#endif + BOOST_TEST(f.valid()); + BOOST_TEST_EQ(f.wait_for(ms(250)) , boost::future_status::timeout); + BOOST_TEST(f.valid()); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +#else + func5(boost::move(p)); +#endif + BOOST_TEST_EQ(f.wait_for(ms(750)) , boost::future_status::ready); + BOOST_TEST(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + BOOST_TEST(f.valid()); + ns d = t1 - t0; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif diff --git a/src/boost/libs/thread/test/sync/futures/future/wait_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/wait_pass.cpp new file mode 100644 index 000000000..daa9b376f --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/future/wait_pass.cpp @@ -0,0 +1,155 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class future<R> + +// template <class Rep, class Period> +// void wait() const; + +//#define BOOST_THREAD_VERSION 3 +#define BOOST_THREAD_VERSION 4 +//#define BOOST_THREAD_USES_LOG +#define BOOST_THREAD_USES_LOG_THREAD_ID +#include <boost/thread/detail/log.hpp> + +#include <boost/thread/future.hpp> +#include <boost/thread/thread.hpp> +#include <boost/chrono/chrono_io.hpp> +#include <boost/detail/lightweight_test.hpp> + +#if defined BOOST_THREAD_USES_CHRONO + +#ifdef BOOST_MSVC +#pragma warning(disable: 4127) // conditional expression is constant +#endif + +typedef boost::chrono::milliseconds ms; + +namespace boost +{ + template <typename OStream> + OStream& operator<<(OStream& os , boost::future_status st ) + { + os << underlying_cast<int>(st) << " "; + return os; + } + template <typename T> + struct wrap + { + wrap(T const& v) : + value(v) + { + } + T value; + + }; + + template <typename T> + exception_ptr make_exception_ptr(T v) + { + return copy_exception(wrap<T> (v)); + } +} + +void func1(boost::promise<int> p) +{ + boost::this_thread::sleep_for(ms(500)); + p.set_value(3); +} + +int j = 0; + +void func3(boost::promise<int&> p) +{ + boost::this_thread::sleep_for(ms(500)); + j = 5; + p.set_value(j); +} + +void func5(boost::promise<void> p) +{ + boost::this_thread::sleep_for(ms(500)); + p.set_value(); +} + +int main() +{ + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + typedef boost::chrono::high_resolution_clock Clock; + { + typedef int T; + boost::promise<T> p; + boost::future<T> f = p.get_future(); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func1, boost::move(p)).detach(); +#else + func1(boost::move(p)); +#endif + BOOST_TEST(f.valid()); + f.wait(); + BOOST_TEST(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + BOOST_TEST(f.valid()); + BOOST_TEST(t1 - t0 < ms(50)); + } + { + typedef int& T; + boost::promise<T> p; + boost::future<T> f = p.get_future(); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func3, boost::move(p)).detach(); +#else + func3(boost::move(p)); +#endif + BOOST_TEST(f.valid()); + f.wait(); + BOOST_TEST(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + BOOST_TEST(f.valid()); + BOOST_TEST(t1 - t0 < ms(50)); + } + { + typedef void T; + boost::promise<T> p; + boost::future<T> f = p.get_future(); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func5, boost::move(p)).detach(); +#else + func5(boost::move(p)); +#endif + BOOST_TEST(f.valid()); + f.wait(); + BOOST_TEST(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + BOOST_TEST(f.valid()); + BOOST_TEST(t1 - t0 < ms(50)); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif diff --git a/src/boost/libs/thread/test/sync/futures/future/wait_until_pass.cpp b/src/boost/libs/thread/test/sync/futures/future/wait_until_pass.cpp new file mode 100644 index 000000000..e9351671d --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/future/wait_until_pass.cpp @@ -0,0 +1,175 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class future<R> + +// template <class Rep, class Period> +// future_status +// wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; + +//#define BOOST_THREAD_VERSION 3 +#define BOOST_THREAD_VERSION 4 +//#define BOOST_THREAD_USES_LOG +#define BOOST_THREAD_USES_LOG_THREAD_ID +#include <boost/thread/detail/log.hpp> + +#include <boost/thread/future.hpp> +#include <boost/thread/thread.hpp> +#include <boost/chrono/chrono_io.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + +#if defined BOOST_THREAD_USES_CHRONO + +#ifdef BOOST_MSVC +#pragma warning(disable: 4127) // conditional expression is constant +#endif + +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; + +namespace boost +{ + template <typename OStream> + OStream& operator<<(OStream& os , boost::future_status st ) + { + os << underlying_cast<int>(st) << " "; + return os; + } + template <typename T> + struct wrap + { + wrap(T const& v) : + value(v) + { + } + T value; + + }; + + template <typename T> + exception_ptr make_exception_ptr(T v) + { + return copy_exception(wrap<T> (v)); + } +} + +void func1(boost::promise<int> p) +{ + boost::this_thread::sleep_for(ms(500)); + p.set_value(3); +} + +int j = 0; + +void func3(boost::promise<int&> p) +{ + boost::this_thread::sleep_for(ms(500)); + j = 5; + p.set_value(j); +} + +void func5(boost::promise<void> p) +{ + boost::this_thread::sleep_for(ms(500)); + p.set_value(); +} + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +int main() +{ + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + typedef boost::chrono::high_resolution_clock Clock; + { + typedef int T; + boost::promise<T> p; + boost::future<T> f = p.get_future(); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func1, boost::move(p)).detach(); +#endif + BOOST_TEST(f.valid()); + BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(250)) , boost::future_status::timeout); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +#else + func1(boost::move(p)); +#endif + BOOST_TEST(f.valid()); + BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(750)) , boost::future_status::ready); + BOOST_TEST(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + BOOST_TEST(f.valid()); + ns d = t1 - t0; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + } + { + typedef int& T; + boost::promise<T> p; + boost::future<T> f = p.get_future(); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func3, boost::move(p)).detach(); +#endif + BOOST_TEST(f.valid()); + BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(250)) , boost::future_status::timeout); + BOOST_TEST(f.valid()); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +#else + func3(boost::move(p)); +#endif + BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(750)) , boost::future_status::ready); + BOOST_TEST(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + BOOST_TEST(f.valid()); + ns d = t1 - t0; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + } + { + typedef void T; + boost::promise<T> p; + boost::future<T> f = p.get_future(); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func5, boost::move(p)).detach(); +#endif + BOOST_TEST(f.valid()); + BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(250)) , boost::future_status::timeout); + BOOST_TEST(f.valid()); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +#else + func5(boost::move(p)); +#endif + BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(750)) , boost::future_status::ready); + BOOST_TEST(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + BOOST_TEST(f.valid()); + ns d = t1 - t0; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif diff --git a/src/boost/libs/thread/test/sync/futures/make_ready_future_pass.cpp b/src/boost/libs/thread/test/sync/futures/make_ready_future_pass.cpp new file mode 100644 index 000000000..dfce3cde7 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/make_ready_future_pass.cpp @@ -0,0 +1,157 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011,2014 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class promise<R> + +// future<void> make_ready_future(); +// template <class T> +// future<decay_t<T>> make_ready_future(T&&); +// template <class T> +// future<T> make_ready_future(remove_reference_t<T>&); +// template <class T> +// future<T> make_ready_future(remove_reference_t<T>&&); +// template <class T, class ...Args> +// future<T> make_ready_future(Args&& ... args); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/static_assert.hpp> + +struct A +{ + A() : + value(0) + { + } + A(int i) : + value(i) + { + } + A(int i, int j) : + value(i+j) + { + } + int value; +}; + +A make(int i) { + return A(i); +} +A make(int i, int j) { + return A(i, j); +} + +struct movable2 +{ + int value_; + BOOST_THREAD_MOVABLE_ONLY(movable2) + movable2() : value_(1){} + movable2(int i) : value_(i){} + movable2(int i, int j) : value_(i+j){} + + //Move constructor and assignment + movable2(BOOST_RV_REF(movable2) m) + { value_ = m.value_; m.value_ = 0; } + + movable2 & operator=(BOOST_THREAD_RV_REF(movable2) m) + { value_ = m.value_; m.value_ = 0; return *this; } + + bool moved() const //Observer + { return !value_; } + + int value() const //Observer + { return value_; } +}; + + +movable2 move_return_function2(int i) { + return movable2(i); +} + +int main() +{ +#if defined BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT((boost::is_copy_constructible<movable2>::value == false)); + BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<movable2>::value == true)); + BOOST_STATIC_ASSERT((boost::is_copy_constructible<A>::value == true)); + BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<A>::value == false)); +#endif + + { + boost::future<void> f = boost::make_ready_future(); + f.wait(); + } + { + typedef A T; + T i; + boost::future<T> f = boost::make_ready_future(i); + BOOST_TEST(f.get().value==0); + } +#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + { + typedef A T; + boost::future<T> f = boost::make_ready_future<T>(); + BOOST_TEST(f.get().value==0); + } + { + typedef A T; + boost::future<T> f = boost::make_ready_future<T>(1); + BOOST_TEST(f.get().value==1); + } + { + typedef A T; + boost::future<T> f = boost::make_ready_future<T>(1,2); + BOOST_TEST(f.get().value==3); + } + { + typedef A T; + T i; + boost::future<T&> f = boost::make_ready_future<T&>(i); + BOOST_TEST(f.get().value==0); + } +#endif +#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +// sync/futures/make_ready_future_pass.cpp:125:65: erreur: conversion from Ôboost::future<boost::rv<movable2> >Õ to non-scalar type Ôboost::future<movable2>Õ requested + { + typedef movable2 T; + T i; + boost::future<T> f = boost::make_ready_future(boost::move(i)); + BOOST_TEST_EQ(f.get().value(),1); + } +#endif +#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + { + typedef movable2 T; + boost::future<T> f = boost::make_ready_future<T>(); + BOOST_TEST(f.get().value()==1); + } + { + typedef movable2 T; + boost::future<T> f = boost::make_ready_future<T>(1); + BOOST_TEST(f.get().value()==1); + } + { + typedef movable2 T; + boost::future<T> f = boost::make_ready_future<T>(1,2); + BOOST_TEST(f.get().value()==3); + } +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/alloc_ctor_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/alloc_ctor_pass.cpp new file mode 100644 index 000000000..e83c06446 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/packaged_task/alloc_ctor_pass.cpp @@ -0,0 +1,181 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class packaged_task<R> + +// template <class F, class Allocator> +// explicit packaged_task(allocator_arg_t, const Allocator& a, F&& f); + + +#define BOOST_THREAD_VERSION 4 +#if BOOST_THREAD_VERSION == 4 +#define BOOST_THREAD_DETAIL_SIGNATURE double() +#else +#define BOOST_THREAD_DETAIL_SIGNATURE double +#endif + +#include <boost/thread/detail/config.hpp> +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + + +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +#include "../test_allocator.hpp" + +double fct() +{ + return 5.0; +} +long lfct() +{ + return 5; +} + +class A +{ + long data_; + +public: + BOOST_THREAD_COPYABLE_AND_MOVABLE(A) + static int n_moves; + static int n_copies; + static int n_instances; + static int n_destroy; + + explicit A(long i) : data_(i) + { + ++n_instances; + } + A(BOOST_THREAD_RV_REF(A) a) : data_(BOOST_THREAD_RV(a).data_) + { + ++n_instances; + ++n_moves; BOOST_THREAD_RV(a).data_ = -1; + } + A& operator=(BOOST_THREAD_RV_REF(A) a) + { + data_ = BOOST_THREAD_RV(a).data_; + BOOST_THREAD_RV(a).data_ = -1; + ++n_moves; + return *this; + } + A(const A& a) : data_(a.data_) + { + ++n_instances; + ++n_copies; + } + A& operator=(BOOST_THREAD_COPY_ASSIGN_REF(A) a) + { + data_ = a.data_; + ++n_copies; + return *this; + } + ~A() + { + --n_instances; + ++n_destroy; + } + + long operator()() const + { return data_;} + long operator()(long i, long j) const + { return data_ + i + j;} +}; + +int A::n_moves = 0; +int A::n_copies = 0; +int A::n_instances = 0; +int A::n_destroy = 0; + +int main() +{ + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(boost::allocator_arg, + test_allocator<A>(), BOOST_THREAD_MAKE_RV_REF(A(5))); + BOOST_TEST(test_alloc_base::count > 0); + BOOST_TEST(p.valid()); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + //p(3, 'a'); + p(); + BOOST_TEST(f.get() == 5.0); + } + BOOST_TEST(A::n_copies == 0); + BOOST_TEST(A::n_moves > 0); + BOOST_TEST(A::n_instances == 0); + BOOST_TEST(A::n_destroy > 0); + BOOST_TEST(test_alloc_base::count == 0); + A::n_copies = 0; + A::n_moves = 0; + { + A a(5); + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(boost::allocator_arg, + test_allocator<A>(), a); + BOOST_TEST(test_alloc_base::count > 0); + BOOST_TEST(p.valid()); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + //p(3, 'a'); + p(); + BOOST_TEST(f.get() == 5.0); + } + //BOOST_TEST(A::n_copies > 0); + //BOOST_TEST(A::n_moves > 0); + BOOST_TEST(test_alloc_base::count == 0); + A::n_copies = 0; + A::n_moves = 0; + { + const A a(5); + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(boost::allocator_arg, + test_allocator<A>(), a); + BOOST_TEST(test_alloc_base::count > 0); + BOOST_TEST(p.valid()); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + //p(3, 'a'); + p(); + BOOST_TEST(f.get() == 5.0); + } + //BOOST_TEST(A::n_copies > 0); + //BOOST_TEST(A::n_moves > 0); + BOOST_TEST(test_alloc_base::count == 0); + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(boost::allocator_arg, + test_allocator<A>(), fct); + BOOST_TEST(test_alloc_base::count > 0); + BOOST_TEST(p.valid()); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + //p(3, 'a'); + p(); + BOOST_TEST(f.get() == 5.0); + } + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(boost::allocator_arg, + test_allocator<A>(), &lfct); + BOOST_TEST(test_alloc_base::count > 0); + BOOST_TEST(p.valid()); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + //p(3, 'a'); + p(); + BOOST_TEST(f.get() == 5.0); + } + + return boost::report_errors(); +} + +#else +int main() +{ + return boost::report_errors(); +} +#endif + diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/copy_assign_fail.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/copy_assign_fail.cpp new file mode 100644 index 000000000..7f068eced --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/packaged_task/copy_assign_fail.cpp @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> +// class packaged_task<R> + +// packaged_task& operator=(packaged_task&) = delete; + + +#define BOOST_THREAD_VERSION 4 +#if BOOST_THREAD_VERSION == 4 +#define BOOST_THREAD_DETAIL_SIGNATURE double() +#else +#define BOOST_THREAD_DETAIL_SIGNATURE double +#endif + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()() const {return data_;} + long operator()(long i, long j) const {return data_ + i + j;} +}; + + +int main() +{ + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0(A(5)); + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p; + p = p0; + } + + return boost::report_errors(); +} + +#include "../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/copy_ctor_fail.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/copy_ctor_fail.cpp new file mode 100644 index 000000000..22a174961 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/packaged_task/copy_ctor_fail.cpp @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> +// class packaged_task<R> + +// packaged_task(packaged_task&) = delete; + + +#define BOOST_THREAD_VERSION 4 +#if BOOST_THREAD_VERSION == 4 +#define BOOST_THREAD_DETAIL_SIGNATURE double() +#else +#define BOOST_THREAD_DETAIL_SIGNATURE double +#endif + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()() const {return data_;} + long operator()(long i, long j) const {return data_ + i + j;} +}; + + +int main() +{ + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0(A(5)); + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(p0); + + } + + return boost::report_errors(); +} + +#include "../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/default_ctor_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/default_ctor_pass.cpp new file mode 100644 index 000000000..7ab9f1e7c --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/packaged_task/default_ctor_pass.cpp @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> +// class packaged_task<R> + +// packaged_task(); + + +#define BOOST_THREAD_VERSION 4 +#if BOOST_THREAD_VERSION == 4 +#define BOOST_THREAD_DETAIL_SIGNATURE int() +#else +#define BOOST_THREAD_DETAIL_SIGNATURE int +#endif + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <string> + +int main() +{ + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p; + BOOST_TEST(!p.valid()); + + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/dtor_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/dtor_pass.cpp new file mode 100644 index 000000000..89620ad05 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/packaged_task/dtor_pass.cpp @@ -0,0 +1,108 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class packaged_task<R> + +// ~packaged_task(); + +//#define BOOST_THREAD_VERSION 3 +#define BOOST_THREAD_VERSION 4 + + +#include <boost/thread/future.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> + +#if BOOST_THREAD_VERSION == 4 +#define BOOST_THREAD_DETAIL_SIGNATURE double() +#else +#define BOOST_THREAD_DETAIL_SIGNATURE double +#endif + +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK +#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +#define BOOST_THREAD_DETAIL_SIGNATURE_2 double(int, char) +#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5 + 3 +'a' +#else +#define BOOST_THREAD_DETAIL_SIGNATURE_2 double() +#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5 +#endif +#else +#define BOOST_THREAD_DETAIL_SIGNATURE_2 double +#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5 +#endif + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()() const {return data_;} + long operator()(long i, long j) const {return data_ + i + j;} +}; + +void func(boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> ) +{ +} + +void func2(boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p) +{ +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + p(3, 'a'); +#else + p(); +#endif +} + +int main() +{ + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(A(5)); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func, boost::move(p)).detach(); +#else + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE>* p2=new boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE>(boost::move(p)); + delete p2; +#endif + try + { + f.get(); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::broken_promise)); + } + } + { + std::cout << __LINE__ << std::endl; + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(A(5)); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func2, boost::move(p)).detach(); +#else + p(); +#endif + std::cout << __LINE__ << std::endl; + BOOST_TEST(f.get() == BOOST_THREAD_DETAIL_SIGNATURE_2_RES); + std::cout << __LINE__ << std::endl; + } + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp new file mode 100644 index 000000000..a4bd3105f --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp @@ -0,0 +1,378 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> +// class packaged_task<R> + +// template <class F> +// explicit packaged_task(F&& f); + + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +#if BOOST_THREAD_VERSION == 4 +#define BOOST_THREAD_DETAIL_SIGNATURE double() +#define BOOST_THREAD_DETAIL_VOID_SIGNATURE void() +#else +#define BOOST_THREAD_DETAIL_SIGNATURE double +#define BOOST_THREAD_DETAIL_VOID_SIGNATURE void +#endif + +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK +#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +#define BOOST_THREAD_DETAIL_SIGNATURE_2 double(int, char) +#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5 + 3 +'a' +#define BOOST_THREAD_DETAIL_VOID_SIGNATURE_2 void(int) +#else +#define BOOST_THREAD_DETAIL_SIGNATURE_2 double() +#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5 +#define BOOST_THREAD_DETAIL_VOID_SIGNATURE_2 void() +#endif +#else +#define BOOST_THREAD_DETAIL_SIGNATURE_2 double +#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5 +#define BOOST_THREAD_DETAIL_VOID_SIGNATURE_2 void +#endif + +void void_fct() +{ + return; +} +double fct() +{ + return 5.0; +} +long lfct() +{ + return 5; +} + +class A +{ +public: + long data_; + + static int n_moves; + static int n_copies; + BOOST_THREAD_COPYABLE_AND_MOVABLE(A) + static void reset() + { + n_moves=0; + n_copies=0; + } + + explicit A(long i) : data_(i) + { + } + A(BOOST_THREAD_RV_REF(A) a) : data_(BOOST_THREAD_RV(a).data_) + { + BOOST_THREAD_RV(a).data_ = -1; + ++n_moves; + } + A& operator=(BOOST_THREAD_RV_REF(A) a) + { + data_ = BOOST_THREAD_RV(a).data_; + BOOST_THREAD_RV(a).data_ = -1; + ++n_moves; + return *this; + } + A(const A& a) : data_(a.data_) + { + ++n_copies; + } + A& operator=(BOOST_THREAD_COPY_ASSIGN_REF(A) a) + { + data_ = a.data_; + ++n_copies; + return *this; + } + ~A() + { + } + + void operator()(int) const + { } + long operator()() const + { return data_;} + long operator()(long i, long j) const + { return data_ + i + j;} +}; + +int A::n_moves = 0; +int A::n_copies = 0; + +class M +{ + +public: + long data_; + static int n_moves; + + BOOST_THREAD_MOVABLE_ONLY(M) + static void reset() { + n_moves=0; + } + explicit M(long i) : data_(i) + { + } + M(BOOST_THREAD_RV_REF(M) a) : data_(BOOST_THREAD_RV(a).data_) + { + BOOST_THREAD_RV(a).data_ = -1; + ++n_moves; + } + M& operator=(BOOST_THREAD_RV_REF(M) a) + { + data_ = BOOST_THREAD_RV(a).data_; + BOOST_THREAD_RV(a).data_ = -1; + ++n_moves; + return *this; + } + ~M() + { + } + + void operator()(int) const + { } + long operator()() const + { return data_;} + long operator()(long i, long j) const + { return data_ + i + j;} +}; + +int M::n_moves = 0; + +class C +{ +public: + long data_; + + static int n_copies; + static void reset() + { + n_copies=0; + } + + explicit C(long i) : data_(i) + { + } + C(const C& a) : data_(a.data_) + { + ++n_copies; + } + C& operator=(C const& a) + { + data_ = a.data_; + ++n_copies; + return *this; + } + ~C() + { + } + + void operator()(int) const + { } + long operator()() const + { return data_;} + long operator()(long i, long j) const + { return data_ + i + j;} +}; +int C::n_copies = 0; + +int main() +{ + { + A::reset(); + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(BOOST_THREAD_MAKE_RV_REF(A(5))); + BOOST_TEST(p.valid()); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + p(3, 'a'); +#else + p(); +#endif + BOOST_TEST(f.get() == BOOST_THREAD_DETAIL_SIGNATURE_2_RES); + BOOST_TEST(A::n_copies == 0); + BOOST_TEST_EQ(A::n_moves, 1); + } + { + A::reset(); + A a(5); + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(a); + BOOST_TEST(p.valid()); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + //p(3, 'a'); + p(); + BOOST_TEST(f.get() == 5.0); + BOOST_TEST_EQ(A::n_copies, 1); + BOOST_TEST_EQ(A::n_moves, 0); + } + { + A::reset(); + const A a(5); + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(a); + BOOST_TEST(p.valid()); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + //p(3, 'a'); + p(); + BOOST_TEST(f.get() == 5.0); + BOOST_TEST_EQ(A::n_copies, 1); + BOOST_TEST_EQ(A::n_moves, 0); + } +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + { + A::reset(); + boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(BOOST_THREAD_MAKE_RV_REF(A(5))); + BOOST_TEST(p.valid()); + boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + p(1); + BOOST_TEST(A::n_copies == 0); + BOOST_TEST_EQ(A::n_moves, 1); + } + { + A::reset(); + A a(5); + boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(a); + BOOST_TEST(p.valid()); + boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + p(1); + BOOST_TEST_EQ(A::n_copies, 1); + BOOST_TEST_EQ(A::n_moves, 0); + } + { + A::reset(); + const A a(5); + boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(a); + BOOST_TEST(p.valid()); + boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + p(1); + BOOST_TEST_EQ(A::n_copies, 1); + BOOST_TEST_EQ(A::n_moves, 0); + } +#endif + { + M::reset(); + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(BOOST_THREAD_MAKE_RV_REF(M(5))); + BOOST_TEST(p.valid()); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + p(3, 'a'); +#else + p(); +#endif + BOOST_TEST(f.get() == BOOST_THREAD_DETAIL_SIGNATURE_2_RES); + BOOST_TEST_EQ(M::n_moves, 1); + } + { + M::reset(); + M a(5); + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(boost::move(a)); + BOOST_TEST(p.valid()); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + //p(3, 'a'); + p(); + BOOST_TEST(f.get() == 5.0); + BOOST_TEST_EQ(M::n_moves, 1); + } +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + { + M::reset(); + boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(BOOST_THREAD_MAKE_RV_REF(M(5))); + BOOST_TEST(p.valid()); + boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + p(1); + BOOST_TEST_EQ(M::n_moves, 1); + } + { + M::reset(); + M a(5); + boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(boost::move(a)); + BOOST_TEST(p.valid()); + boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + p(1); + BOOST_TEST_EQ(M::n_moves, 1); + } +#endif + { + C::reset(); + C a(5); + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(a); + BOOST_TEST(p.valid()); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + //p(3, 'a'); + p(); + BOOST_TEST(f.get() == 5.0); + BOOST_TEST_EQ(C::n_copies, 1); + } + + { + C::reset(); + const C a(5); + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(a); + BOOST_TEST(p.valid()); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + //p(3, 'a'); + p(); + BOOST_TEST(f.get() == 5.0); + BOOST_TEST_EQ(C::n_copies, 1); + } +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + { + C::reset(); + C a(5); + boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(a); + BOOST_TEST(p.valid()); + boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + p(1); + BOOST_TEST_EQ(C::n_copies, 1); + } + + { + C::reset(); + const C a(5); + boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE_2> p(a); + BOOST_TEST(p.valid()); + boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + p(1); + BOOST_TEST_EQ(C::n_copies, 1); + } +#endif + { + boost::packaged_task<BOOST_THREAD_DETAIL_VOID_SIGNATURE> p(void_fct); + BOOST_TEST(p.valid()); + boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + p(); + } + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(fct); + BOOST_TEST(p.valid()); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + //p(3, 'a'); + p(); + BOOST_TEST(f.get() == 5.0); + } + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(&lfct); + BOOST_TEST(p.valid()); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + //p(3, 'a'); + p(); + BOOST_TEST(f.get() == 5.0); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/get_future_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/get_future_pass.cpp new file mode 100644 index 000000000..7b2985794 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/packaged_task/get_future_pass.cpp @@ -0,0 +1,80 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class packaged_task<R> + +// future<R> get_future(); + + +#define BOOST_THREAD_VERSION 4 +#if BOOST_THREAD_VERSION == 4 +#define BOOST_THREAD_DETAIL_SIGNATURE double() +#else +#define BOOST_THREAD_DETAIL_SIGNATURE double +#endif + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()() const {return data_;} + long operator()(long i, long j) const {return data_ + i + j;} +}; + +int main() +{ + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(A(5)); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + //p(3, 'a'); + p(); + BOOST_TEST(f.get() == 5.0); + } + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(A(5)); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + try + { + f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::future_already_retrieved)); + } + } + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p; + try + { + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state)); + } + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/make_ready_at_thread_exit_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/make_ready_at_thread_exit_pass.cpp new file mode 100644 index 000000000..08db7bbf2 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/packaged_task/make_ready_at_thread_exit_pass.cpp @@ -0,0 +1,189 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class packaged_task<R> + +// packaged_task(packaged_task&& other); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +#if defined BOOST_THREAD_USES_CHRONO && \ + defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && \ + defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + +class E : public std::exception +{ +public: + long data; + explicit E(long i) : + data(i) + { + } + + const char* what() const throw() { return ""; } + + ~E() throw() {} +}; +class A +{ + long data_; + +public: + explicit A(long i) : + data_(i) + { + } + + long operator()(long i, long j) const + { + if (j == 'z') BOOST_THROW_EXCEPTION( E(6) ); + return data_ + i + j; + } +}; + +void func0_mv(BOOST_THREAD_RV_REF(boost::packaged_task<double(int, char)>) p) +//void func0(boost::packaged_task<double(int, char)> p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + p.make_ready_at_thread_exit(3, 'a'); +} +void func0(boost::packaged_task<double(int, char)> *p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + p->make_ready_at_thread_exit(3, 'a'); +} +void func1(boost::packaged_task<double(int, char)> *p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + p->make_ready_at_thread_exit(3, 'z'); +} + +void func2(boost::packaged_task<double(int, char)> *p) +{ + p->make_ready_at_thread_exit(3, 'a'); + try + { + p->make_ready_at_thread_exit(3, 'c'); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); + } +} + +void func3(boost::packaged_task<double(int, char)> *p) +{ + try + { + p->make_ready_at_thread_exit(3, 'a'); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state)); + } +} + +int main() +{ + { + boost::packaged_task<double(int, char)> p(A(5)); + boost::future<double> f = p.get_future(); +#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD + boost::thread(func0_mv, boost::move(p)).detach(); +#else + boost::thread(func0, &p).detach(); +#endif + BOOST_TEST(f.get() == 105.0); + } + { + boost::packaged_task<double(int, char)> p2(A(5)); + boost::future<double> f = p2.get_future(); + boost::packaged_task<double(int, char)> p = boost::move(p2); + boost::thread(func0, &p).detach(); + BOOST_TEST(f.get() == 105.0); + } + { + boost::packaged_task<double(int, char)> p(A(5)); + boost::future<double> f = p.get_future(); + //boost::thread(func1, boost::move(p)).detach(); + boost::thread(func1, &p).detach(); + try + { + f.get(); + BOOST_TEST(false); + } + catch (const E& e) + { + BOOST_TEST(e.data == 6); + } + } + { + boost::packaged_task<double(int, char)> p2(A(5)); + boost::future<double> f = p2.get_future(); + boost::packaged_task<double(int, char)> p = boost::move(p2); + boost::thread(func1, &p).detach(); + try + { + f.get(); + BOOST_TEST(false); + } + catch (const E& e) + { + BOOST_TEST(e.data == 6); + } + } + { + boost::packaged_task<double(int, char)> p(A(5)); + boost::future<double> f = p.get_future(); + //boost::thread(func2, boost::move(p)).detach(); + boost::thread(func2, &p).detach(); + BOOST_TEST(f.get() == 105.0); + } + { + boost::packaged_task<double(int, char)> p2(A(5)); + boost::future<double> f = p2.get_future(); + boost::packaged_task<double(int, char)> p = boost::move(p2); + boost::thread(func2, &p).detach(); + BOOST_TEST(f.get() == 105.0); + } + { + boost::packaged_task<double(int, char)> p(A(5)); + //boost::thread t(func3, boost::move(p)); + boost::thread t(func3, &p); + t.join(); + } + { + boost::packaged_task<double(int, char)> p2(A(5)); + boost::packaged_task<double(int, char)> p = boost::move(p2); + boost::thread t(func3, &p); + t.join(); + } + + return boost::report_errors(); +} + +#else +int main() +{ + return boost::report_errors(); +} +//#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif + + diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/member_swap_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/member_swap_pass.cpp new file mode 100644 index 000000000..fe3c062f8 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/packaged_task/member_swap_pass.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class packaged_task<R> + +// void swap(packaged_task& other); + +#define BOOST_THREAD_VERSION 4 +#if BOOST_THREAD_VERSION == 4 +#define BOOST_THREAD_DETAIL_SIGNATURE double() +#else +#define BOOST_THREAD_DETAIL_SIGNATURE double +#endif + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +class A +{ + long data_; + +public: + explicit A(long i) : + data_(i) + { + } + + long operator()() const + { + return data_; + } + long operator()(long i, long j) const + { + return data_ + i + j; + } +}; + +int main() +{ + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0(A(5)); + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p; + p.swap(p0); + BOOST_TEST(!p0.valid()); + BOOST_TEST(p.valid()); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + //p(3, 'a'); + p(); + BOOST_TEST(f.get() == 5.0); + } + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0; + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p; + p.swap(p0); + BOOST_TEST(!p0.valid()); + BOOST_TEST(!p.valid()); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/move_assign_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/move_assign_pass.cpp new file mode 100644 index 000000000..fe696c8fb --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/packaged_task/move_assign_pass.cpp @@ -0,0 +1,68 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <future> + +// class promise<R> + +// promise& operator=(promise&& rhs); + +#define BOOST_THREAD_VERSION 4 +#if BOOST_THREAD_VERSION == 4 +#define BOOST_THREAD_DETAIL_SIGNATURE double() +#else +#define BOOST_THREAD_DETAIL_SIGNATURE double +#endif + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()() const {return data_;} + long operator()(long i, long j) const {return data_ + i + j;} +}; + + +int main() +{ + + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0(A(5)); + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p; + p = boost::move(p0); + BOOST_TEST(!p0.valid()); + BOOST_TEST(p.valid()); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + // p(3, 'a'); + p(); + BOOST_TEST(f.get() == 5.0); + } + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0; + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p; + p = boost::move(p0); + BOOST_TEST(!p0.valid()); + BOOST_TEST(!p.valid()); + } + + return boost::report_errors(); + +} + diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/move_ctor_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/move_ctor_pass.cpp new file mode 100644 index 000000000..a5085b311 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/packaged_task/move_ctor_pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class packaged_task<R> + +// packaged_task(packaged_task&& other); + +#define BOOST_THREAD_VERSION 4 +#if BOOST_THREAD_VERSION == 4 +#define BOOST_THREAD_DETAIL_SIGNATURE double() +#else +#define BOOST_THREAD_DETAIL_SIGNATURE double +#endif + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()() const {return data_;} + long operator()(long i, long j) const {return data_ + i + j;} +}; + + +int main() +{ + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0(A(5)); + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p = boost::move(p0); + BOOST_TEST(!p0.valid()); + BOOST_TEST(p.valid()); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + //p(3, 'a'); + p(); + BOOST_TEST(f.get() == 5.0); + } + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0; + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p = boost::move(p0); + BOOST_TEST(!p0.valid()); + BOOST_TEST(!p.valid()); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/non_member_swap_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/non_member_swap_pass.cpp new file mode 100644 index 000000000..fb579094d --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/packaged_task/non_member_swap_pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// template <class R> +// void +// swap(packaged_task<R>& x, packaged_task<R>& y); + +#define BOOST_THREAD_VERSION 4 +#if BOOST_THREAD_VERSION == 4 +#define BOOST_THREAD_DETAIL_SIGNATURE double() +#else +#define BOOST_THREAD_DETAIL_SIGNATURE double +#endif + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +class A +{ + long data_; + +public: + explicit A(long i) : data_(i) {} + + long operator()() const {return data_;} + long operator()(long i, long j) const {return data_ + i + j;} +}; + +int main() +{ + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0(A(5)); + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p; + p.swap(p0); + BOOST_TEST(!p0.valid()); + BOOST_TEST(p.valid()); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + //p(3, 'a'); + p(); + BOOST_TEST(f.get() == 5.0); + } + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p0; + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p; + p.swap(p0); + BOOST_TEST(!p0.valid()); + BOOST_TEST(!p.valid()); + } + return boost::report_errors(); + +} + diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/operator_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/operator_pass.cpp new file mode 100644 index 000000000..db932f72b --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/packaged_task/operator_pass.cpp @@ -0,0 +1,218 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> +// class packaged_task<R> + +// void operator()(); + + +//#define BOOST_THREAD_VERSION 3 +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +#if defined BOOST_THREAD_USES_CHRONO + +#if BOOST_THREAD_VERSION == 4 +#define BOOST_THREAD_DETAIL_SIGNATURE double() +#else +#define BOOST_THREAD_DETAIL_SIGNATURE double +#endif + +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK +#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +#define BOOST_THREAD_DETAIL_SIGNATURE_2 double(int, char) +#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5 + 3 +'a' +#else +#define BOOST_THREAD_DETAIL_SIGNATURE_2 double() +#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5 +#endif +#else +#define BOOST_THREAD_DETAIL_SIGNATURE_2 double +#define BOOST_THREAD_DETAIL_SIGNATURE_2_RES 5 +#endif +class E : public std::exception +{ +public: + long data; + explicit E(long i) : + data(i) + { + } + + const char* what() const throw() { return ""; } + + ~E() throw() {} +}; + +class A +{ + long data_; + +public: + explicit A(long i) : + data_(i) + { + } + + long operator()() const + { + if (data_ == 0) BOOST_THROW_EXCEPTION(E(6)); + return data_; + } + long operator()(long i, long j) const + { + if (j == 'z') BOOST_THROW_EXCEPTION(E(6)); + return data_ + i + j; + } + ~A() {} +}; + +void func0(boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + p(3, 'a'); +#else + p(); +#endif +} + +void func1(boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + p(3, 'z'); +#else + p(); +#endif +} + +void func2(boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p) +{ +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + p(3, 'a'); +#else + p(); +#endif + try + { +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + p(3, 'c'); +#else + p(); +#endif + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); + } +} + +void func3(boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p) +{ + try + { +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + p(3, 'a'); +#else + p(); +#endif + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state)); + } +} + +int main() +{ + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(A(5)); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func0, boost::move(p)).detach(); +#else + //p(); +#endif + //BOOST_TEST(f.get() == 5.0); + } + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(A(0)); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func1, boost::move(p)).detach(); +#endif + try + { +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +#else + p(); +#endif + f.get(); + BOOST_TEST(false); + } + catch (const E& e) + { + BOOST_TEST(e.data == 6); + } + catch (...) + { + BOOST_TEST(false); + } + } + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(A(5)); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread t(func2, boost::move(p)); +#else + p(); +#endif +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + BOOST_TEST(f.get() == 105); + t.join(); +#else + BOOST_TEST(f.get() == 5.0); +#endif + } + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p; +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread t(func3, boost::move(p)); + t.join(); +#else + try + { + #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + p(3, 'a'); + #else + p(); + #endif + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state)); + } +#endif + } + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/reset_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/reset_pass.cpp new file mode 100644 index 000000000..711e7a57f --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/packaged_task/reset_pass.cpp @@ -0,0 +1,81 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> +// class packaged_task<R> + +// void operator()(); + + +#define BOOST_THREAD_VERSION 4 +#if BOOST_THREAD_VERSION == 4 +#define BOOST_THREAD_DETAIL_SIGNATURE double() +#else +#define BOOST_THREAD_DETAIL_SIGNATURE double +#endif + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +class A +{ + long data_; + +public: + explicit A(long i) : + data_(i) + { + } + + long operator()() const + { + return data_; + } + long operator()(long i, long j) const + { + if (j == 'z') throw A(6); + return data_ + i + j; + } +}; + +int main() +{ + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(A(5)); + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + //p(3, 'a'); + p(); + BOOST_TEST(f.get() == 5.0); + p.reset(); + //p(4, 'a'); + p(); + f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(f.get() == 5.0); + } + { + boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p; + try + { + p.reset(); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state)); + } + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/types_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/types_pass.cpp new file mode 100644 index 000000000..a52fb0439 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/packaged_task/types_pass.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// template<class R, class... ArgTypes> +// class packaged_task<R(ArgTypes...)> +// { +// public: +// typedef R result_type; + + +#include <boost/thread/future.hpp> +#include <boost/static_assert.hpp> +#include <boost/detail/lightweight_test.hpp> + +struct A {}; + +int main() +{ + //BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::packaged_task<A>::result_type, A>::value), ""); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/packaged_task/use_allocator_pass.cpp b/src/boost/libs/thread/test/sync/futures/packaged_task/use_allocator_pass.cpp new file mode 100644 index 000000000..ef75b7caa --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/packaged_task/use_allocator_pass.cpp @@ -0,0 +1,53 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class packaged_task<R(ArgTypes...)> + +// template <class Callable, class Alloc> +// struct uses_allocator<packaged_task<Callable>, Alloc> +// : true_type { }; + + +#define BOOST_THREAD_VERSION 4 +#if BOOST_THREAD_VERSION == 4 +#define BOOST_THREAD_DETAIL_SIGNATURE double() +#else +#define BOOST_THREAD_DETAIL_SIGNATURE double +#endif + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/static_assert.hpp> + +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +#include "../test_allocator.hpp" + +int main() +{ + + BOOST_STATIC_ASSERT_MSG((boost::csbl::uses_allocator<boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE>, test_allocator<double> >::value), ""); + + return boost::report_errors(); +} + +#else +int main() +{ + return boost::report_errors(); +} +#endif + + diff --git a/src/boost/libs/thread/test/sync/futures/promise/alloc_ctor_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/alloc_ctor_pass.cpp new file mode 100644 index 000000000..0d0c3c0b9 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/promise/alloc_ctor_pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class promise<R> + +// promise(allocator_arg_t, const Allocator& a); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +#include "../test_allocator.hpp" + +int main() +{ + BOOST_TEST(test_alloc_base::count == 0); + { + boost::promise<int> p(boost::allocator_arg, test_allocator<int>()); + BOOST_TEST(test_alloc_base::count == 1); + boost::future<int> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(test_alloc_base::count == 1); + BOOST_TEST(f.valid()); + } + BOOST_TEST(test_alloc_base::count == 0); + { + boost::promise<int&> p(boost::allocator_arg, test_allocator<int>()); + BOOST_TEST(test_alloc_base::count == 1); + boost::future<int&> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(test_alloc_base::count == 1); + BOOST_TEST(f.valid()); + } + BOOST_TEST(test_alloc_base::count == 0); + { + boost::promise<void> p(boost::allocator_arg, test_allocator<void>()); + BOOST_TEST(test_alloc_base::count == 1); + boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(test_alloc_base::count == 1); + BOOST_TEST(f.valid()); + } + BOOST_TEST(test_alloc_base::count == 0); + + + return boost::report_errors(); +} + +#else +int main() +{ + return boost::report_errors(); +} +#endif + + diff --git a/src/boost/libs/thread/test/sync/futures/promise/copy_assign_fail.cpp b/src/boost/libs/thread/test/sync/futures/promise/copy_assign_fail.cpp new file mode 100644 index 000000000..07895578f --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/promise/copy_assign_fail.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> +// class promise<R> +// promise& operator=(const promise& rhs) = delete; + +#define BOOST_THREAD_VERSION 3 +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + { + boost::promise<int> p0; + boost::promise<int> p; + p = p0; + } + + return boost::report_errors(); +} + +#include "../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/futures/promise/copy_ctor_fail.cpp b/src/boost/libs/thread/test/sync/futures/promise/copy_ctor_fail.cpp new file mode 100644 index 000000000..cfd67a6d7 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/promise/copy_ctor_fail.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> +// class promise<R> +// promise& operator=(const promise& rhs) = delete; + +#define BOOST_THREAD_VERSION 3 +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + { + boost::promise<int> p0; + boost::promise<int> p(p0); + } + + return boost::report_errors(); +} + +#include "../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/futures/promise/default_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/default_pass.cpp new file mode 100644 index 000000000..00198a168 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/promise/default_pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class promise<R> + +// promise(); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + + { + boost::promise<int> p; + boost::future<int> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(f.valid()); + } + { + boost::promise<int&> p; + boost::future<int&> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(f.valid()); + } + { + boost::promise<void> p; + boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(f.valid()); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/promise/dtor_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/dtor_pass.cpp new file mode 100644 index 000000000..e449c0378 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/promise/dtor_pass.cpp @@ -0,0 +1,116 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class promise<R> + +// ~promise(); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + { + typedef int T; + boost::future<T> f; + { + boost::promise<T> p; + f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + p.set_value(3); + } + BOOST_TEST(f.get() == 3); + } + { + typedef int T; + boost::future<T> f; + { + boost::promise<T> p; + f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + } + try + { + //T i = + (void)f.get(); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::broken_promise)); + } + } + { + typedef int& T; + int i = 4; + boost::future<T> f; + { + boost::promise<T> p; + f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + p.set_value(i); + } + BOOST_TEST(&f.get() == &i); + } + { + typedef int& T; + boost::future<T> f; + { + boost::promise<T> p; + f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + } + try + { + //T i = + (void)f.get(); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::broken_promise)); + } + } + { + typedef void T; + boost::future<T> f; + { + boost::promise<T> p; + f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + p.set_value(); + } + f.get(); + BOOST_TEST(true); + } + { + typedef void T; + boost::future<T> f; + { + boost::promise<T> p; + f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + } + try + { + f.get(); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::broken_promise)); + } + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/promise/emplace_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/emplace_pass.cpp new file mode 100644 index 000000000..6a1a35292 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/promise/emplace_pass.cpp @@ -0,0 +1,207 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011,2014 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class promise<R> + +// template <class ...Args> +// void promise::emplace(Args&& ... args); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/static_assert.hpp> + +struct A +{ + A() : + value(0) + { + } + A(int i) : + value(i) + { + } + A(int i, int j) : + value(i+j) + { + } + BOOST_THREAD_MOVABLE_ONLY(A) + + A(BOOST_THREAD_RV_REF(A) rhs) + { + if(rhs.value==0) + throw 9; + else + { + value=rhs.value; + rhs.value=0; + } + } + A& operator=(BOOST_THREAD_RV_REF(A) rhs) + { + if(rhs.value==0) + throw 9; + else + { + value=rhs.value; + rhs.value=0; + } + return *this; + } + int value; +}; + +A make(int i) { + return A(i); +} +A make(int i, int j) { + return A(i, j); +} + +struct movable2 +{ + int value_; + BOOST_THREAD_MOVABLE_ONLY(movable2) + movable2() : value_(1){} + movable2(int i) : value_(i){} + movable2(int i, int j) : value_(i+j){} + + //Move constructor and assignment + movable2(BOOST_RV_REF(movable2) m) + { value_ = m.value_; m.value_ = 0; } + + movable2 & operator=(BOOST_THREAD_RV_REF(movable2) m) + { value_ = m.value_; m.value_ = 0; return *this; } + + bool moved() const //Observer + { return !value_; } + + int value() const //Observer + { return value_; } +}; + + +movable2 move_return_function2(int i) { + return movable2(i); +} + +int main() +{ +#if defined BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT((boost::is_copy_constructible<movable2>::value == false)); + BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<movable2>::value == true)); + BOOST_STATIC_ASSERT((boost::is_copy_constructible<A>::value == false)); + BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<A>::value == true)); +#endif +#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + { + typedef A T; + T i; + boost::promise<T> p; + boost::future<T> f = p.get_future(); + p.emplace(); + try + { + T a = f.get(); (void)a; + BOOST_TEST(false); + } + catch (int j) + { + BOOST_TEST(j == 9); + } + catch (...) + { + BOOST_TEST(false); + } + } + { + typedef A T; + boost::promise<T> p; + boost::future<T> f = p.get_future(); + p.emplace(3); + BOOST_TEST(f.get().value == 3); + try + { + T j(3); + p.set_value(boost::move(j)); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); + } + catch (...) + { + BOOST_TEST(false); + } + + } + { + boost::promise<movable2> p; + boost::future<movable2> f = p.get_future(); + p.emplace(3); + BOOST_TEST(f.get().value_ == 3); + try + { + p.emplace(3); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); + } + catch (...) + { + BOOST_TEST(false); + } + + } + { + boost::promise<A> p; + boost::future<A> f = p.get_future(); + p.emplace(1,2); + BOOST_TEST(f.get().value == 3); + try + { + p.emplace(1,2); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); + } + catch (...) + { + BOOST_TEST(false); + } + + } + { + typedef A T; + boost::promise<T> p; + boost::future<T> f = p.get_future(); + p.emplace(3); + boost::promise<T> p2(boost::move(p)); + BOOST_TEST(f.get().value == 3); + + } +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/promise/get_future_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/get_future_pass.cpp new file mode 100644 index 000000000..13a63b13d --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/promise/get_future_pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class promise<R> + +// future<R> get_future(); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + { + boost::promise<double> p; + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + p.set_value(105.5); + BOOST_TEST(f.get() == 105.5); + } + { + boost::promise<double> p; + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + try + { + f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::future_already_retrieved)); + } + } + { + boost::promise<double> p; + boost::promise<double> p0 = boost::move(p); + try + { + boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state)); + } + } + + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/promise/move_assign_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/move_assign_pass.cpp new file mode 100644 index 000000000..0190527c0 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/promise/move_assign_pass.cpp @@ -0,0 +1,155 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <future> + +// class promise<R> + +// promise& operator=(promise&& rhs); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +#include "../test_allocator.hpp" +#endif + +boost::mutex m0; +boost::mutex m1; + +int main() +{ +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS + BOOST_TEST(test_alloc_base::count == 0); + { + boost::promise<int> p0(boost::allocator_arg, test_allocator<int>()); + boost::promise<int> p(boost::allocator_arg, test_allocator<int>()); + BOOST_TEST(test_alloc_base::count == 2); + p = boost::move(p0); + BOOST_TEST(test_alloc_base::count == 1); + boost::future<int> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(test_alloc_base::count == 1); + BOOST_TEST(f.valid()); + try + { + f = BOOST_THREAD_MAKE_RV_REF(p0.get_future()); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state)); + } + BOOST_TEST(test_alloc_base::count == 1); + } + BOOST_TEST(test_alloc_base::count == 0); + + { + boost::promise<int&> p0(boost::allocator_arg, test_allocator<int>()); + boost::promise<int&> p(boost::allocator_arg, test_allocator<int>()); + BOOST_TEST(test_alloc_base::count == 2); + p = boost::move(p0); + BOOST_TEST(test_alloc_base::count == 1); + boost::future<int&> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(test_alloc_base::count == 1); + BOOST_TEST(f.valid()); + try + { + f = BOOST_THREAD_MAKE_RV_REF(p0.get_future()); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state)); + } + BOOST_TEST(test_alloc_base::count == 1); + } + BOOST_TEST(test_alloc_base::count == 0); + { + boost::promise<void> p0(boost::allocator_arg, test_allocator<void>()); + boost::promise<void> p(boost::allocator_arg, test_allocator<void>()); + BOOST_TEST(test_alloc_base::count == 2); + p = boost::move(p0); + BOOST_TEST(test_alloc_base::count == 1); + boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(test_alloc_base::count == 1); + BOOST_TEST(f.valid()); + try + { + f = BOOST_THREAD_MAKE_RV_REF(p0.get_future()); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state)); + } + BOOST_TEST(test_alloc_base::count == 1); + } + BOOST_TEST(test_alloc_base::count == 0); + +#endif + { + boost::promise<int> p0; + boost::promise<int> p; + p = boost::move(p0); + boost::future<int> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(f.valid()); + try + { + f = BOOST_THREAD_MAKE_RV_REF(p0.get_future()); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state)); + } + } + + { + boost::promise<int&> p0; + boost::promise<int&> p; + p = boost::move(p0); + boost::future<int&> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(f.valid()); + try + { + f = BOOST_THREAD_MAKE_RV_REF(p0.get_future()); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state)); + } + } + { + boost::promise<void> p0; + boost::promise<void> p; + p = boost::move(p0); + boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(f.valid()); + try + { + f = BOOST_THREAD_MAKE_RV_REF(p0.get_future()); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state)); + } + } + + return boost::report_errors(); + +} + diff --git a/src/boost/libs/thread/test/sync/futures/promise/move_ctor_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/move_ctor_pass.cpp new file mode 100644 index 000000000..a72eb1829 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/promise/move_ctor_pass.cpp @@ -0,0 +1,151 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <future> + +// class promise<R> + +// promise(promise&& rhs); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +#include "../test_allocator.hpp" +#endif + +boost::mutex m; + +int main() +{ +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS + BOOST_TEST(test_alloc_base::count == 0); + { + boost::promise<int> p0(boost::allocator_arg, test_allocator<int>()); + boost::promise<int> p(boost::move(p0)); + BOOST_TEST(test_alloc_base::count == 1); + std::cout << __LINE__ << std::endl; + boost::future<int> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + std::cout << __LINE__ << std::endl; + BOOST_TEST(test_alloc_base::count == 1); + BOOST_TEST(f.valid()); + std::cout << __LINE__ << std::endl; + try + { + f = BOOST_THREAD_MAKE_RV_REF(p0.get_future()); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state)); + } + std::cout << __LINE__ << std::endl; + BOOST_TEST(test_alloc_base::count == 1); + } + std::cout << __LINE__ << std::endl; + BOOST_TEST(test_alloc_base::count == 0); + { + boost::promise<int&> p0(boost::allocator_arg, test_allocator<int>()); + boost::promise<int&> p(boost::move(p0)); + BOOST_TEST(test_alloc_base::count == 1); + boost::future<int&> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(test_alloc_base::count == 1); + BOOST_TEST(f.valid()); + try + { + f = BOOST_THREAD_MAKE_RV_REF(p0.get_future()); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state)); + } + BOOST_TEST(test_alloc_base::count == 1); + } + BOOST_TEST(test_alloc_base::count == 0); + { + boost::promise<void> p0(boost::allocator_arg, test_allocator<void>()); + boost::promise<void> p(boost::move(p0)); + BOOST_TEST(test_alloc_base::count == 1); + boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(test_alloc_base::count == 1); + BOOST_TEST(f.valid()); + try + { + f = BOOST_THREAD_MAKE_RV_REF(p0.get_future()); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state)); + } + BOOST_TEST(test_alloc_base::count == 1); + } + BOOST_TEST(test_alloc_base::count == 0); +#endif + { + boost::promise<int> p0; + boost::promise<int> p(boost::move(p0)); + std::cout << __LINE__ << std::endl; + boost::future<int> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + std::cout << __LINE__ << std::endl; + BOOST_TEST(f.valid()); + std::cout << __LINE__ << std::endl; + try + { + f = BOOST_THREAD_MAKE_RV_REF(p0.get_future()); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state)); + } + std::cout << __LINE__ << std::endl; + } + std::cout << __LINE__ << std::endl; + { + boost::promise<int&> p0; + boost::promise<int&> p(boost::move(p0)); + boost::future<int&> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(f.valid()); + try + { + f = BOOST_THREAD_MAKE_RV_REF(p0.get_future()); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state)); + } + } + { + boost::promise<void> p0; + boost::promise<void> p(boost::move(p0)); + boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(f.valid()); + try + { + f = BOOST_THREAD_MAKE_RV_REF(p0.get_future()); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::no_state)); + } + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/promise/set_exception_at_thread_exit_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/set_exception_at_thread_exit_pass.cpp new file mode 100644 index 000000000..d23d0befb --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/promise/set_exception_at_thread_exit_pass.cpp @@ -0,0 +1,110 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class promise<R> + +// void promise::set_exception_at_thread_exit(exception_ptr p); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/static_assert.hpp> + +namespace boost +{ + template <typename T> + struct wrap + { + wrap(T const& v) : + value(v) + { + } + T value; + + }; + + template <typename T> + exception_ptr make_exception_ptr(T v) + { + return copy_exception(wrap<T> (v)); + } +} + +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +void func(boost::promise<int> p) +#else +boost::promise<int> p; +void func() +#endif +{ + //p.set_exception(boost::make_exception_ptr(3)); + p.set_exception_at_thread_exit(boost::make_exception_ptr(3)); +} + +int main() +{ + { + typedef int T; +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::promise<T> p; + boost::future<T> f = p.get_future(); + boost::thread(func, boost::move(p)).detach(); +#else + boost::future<T> f = p.get_future(); + boost::thread(func).detach(); +#endif + try + { + f.get(); + BOOST_TEST(false); + } + catch (boost::wrap<int> i) + { + BOOST_TEST(i.value == 3); + } + catch (...) + { + BOOST_TEST(false); + } + } + { + typedef int T; + boost::promise<T> p2; + boost::future<T> f = p2.get_future(); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func, boost::move(p2)).detach(); +#else + p = boost::move(p2); + boost::thread(func).detach(); +#endif + try + { + f.get(); + BOOST_TEST(false); + } + catch (boost::wrap<int> i) + { + BOOST_TEST(i.value == 3); + } + catch (...) + { + BOOST_TEST(false); + } + } + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/promise/set_exception_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/set_exception_pass.cpp new file mode 100644 index 000000000..c27aec293 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/promise/set_exception_pass.cpp @@ -0,0 +1,110 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class promise<R> + +// void set_exception(exception_ptr p); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/static_assert.hpp> + +namespace boost +{ + template <typename T> + struct wrap + { + wrap(T const& v) : + value(v) + { + } + T value; + + }; + + template <typename T> + exception_ptr make_exception_ptr(T v) + { + return copy_exception(wrap<T> (v)); + } +} + +int main() +{ + + { + typedef int T; + boost::promise<T> p; + boost::future<T> f = p.get_future(); + p.set_exception(boost::make_exception_ptr(3)); + try + { + f.get(); + BOOST_TEST(false); + } + catch (boost::wrap<int> i) + { + BOOST_TEST(i.value == 3); + } + try + { + p.set_exception(boost::make_exception_ptr(3)); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); + } + catch (...) + { + BOOST_TEST(false); + } + } + { + typedef int T; + boost::promise<T> p; + boost::future<T> f = p.get_future(); + p.set_exception_deferred(boost::make_exception_ptr(3)); + BOOST_TEST(!f.is_ready()); + p.notify_deferred(); + try + { + f.get(); + BOOST_TEST(false); + } + catch (boost::wrap<int> i) + { + BOOST_TEST(i.value == 3); + } + try + { + p.set_exception(boost::make_exception_ptr(3)); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); + } + catch (...) + { + BOOST_TEST(false); + } + } + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/promise/set_lvalue_at_thread_exit_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/set_lvalue_at_thread_exit_pass.cpp new file mode 100644 index 000000000..a143dc636 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/promise/set_lvalue_at_thread_exit_pass.cpp @@ -0,0 +1,49 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class promise<R> + +// void promise<R&>::set_value_at_thread_exit(R& r); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <memory> + +int i = 0; + +//void func(boost::promise<int&> p) +boost::promise<int&> p; +void func() +{ + p.set_value_at_thread_exit(i); + i = 4; +} + +int main() +{ + { + //boost::promise<int&> p; + boost::future<int&> f = p.get_future(); + //boost::thread(func, boost::move(p)).detach(); + boost::thread(func).detach(); + int r = f.get(); + BOOST_TEST(r == 4); + } + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/promise/set_lvalue_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/set_lvalue_pass.cpp new file mode 100644 index 000000000..6acfb62d1 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/promise/set_lvalue_pass.cpp @@ -0,0 +1,132 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class promise<R> + +// void promise<R&>::set_value(R& r); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/static_assert.hpp> + +int main() +{ + + { + typedef int& T; + int i = 3; + boost::promise<T> p; + boost::future<T> f = p.get_future(); + p.set_value(i); + int& j = f.get(); + BOOST_TEST(j == 3); + ++i; + BOOST_TEST(j == 4); + try + { + p.set_value(i); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); + } + catch (...) + { + BOOST_TEST(false); + } + } + { + typedef int& T; + int i = 3; + boost::promise<T> p; + boost::future<T> f = p.get_future(); + p.set_value(i); + int& j = f.get(); + BOOST_TEST(j == 3); + ++i; + BOOST_TEST(j == 4); + try + { + p.set_value_deferred(i); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); + } + catch (...) + { + BOOST_TEST(false); + } + } + { + typedef int& T; + int i = 3; + boost::promise<T> p; + boost::future<T> f = p.get_future(); + p.set_value_deferred(i); + BOOST_TEST(!f.is_ready()); + p.notify_deferred(); + int& j = f.get(); + BOOST_TEST(j == 3); + ++i; + BOOST_TEST(j == 4); + try + { + p.set_value_deferred(i); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); + } + catch (...) + { + BOOST_TEST(false); + } + } + { + typedef int& T; + int i = 3; + boost::promise<T> p; + boost::future<T> f = p.get_future(); + p.set_value_deferred(i); + BOOST_TEST(!f.is_ready()); + p.notify_deferred(); + int& j = f.get(); + BOOST_TEST(j == 3); + ++i; + BOOST_TEST(j == 4); + try + { + p.set_value(i); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); + } + catch (...) + { + BOOST_TEST(false); + } + } + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/promise/set_rvalue_at_thread_exit_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/set_rvalue_at_thread_exit_pass.cpp new file mode 100644 index 000000000..0b23b4834 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/promise/set_rvalue_at_thread_exit_pass.cpp @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011,2014 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class promise<R> + +// void promise::set_value_at_thread_exit(R&& p); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/thread/detail/memory.hpp> +#include <boost/thread/csbl/memory/unique_ptr.hpp> + +boost::promise<boost::csbl::unique_ptr<int> > p; +boost::promise<boost::csbl::unique_ptr<int> > p2; +void func() +{ + boost::csbl::unique_ptr<int> uptr(new int(5)); + p.set_value_at_thread_exit(boost::move(uptr)); +} +void func2() +{ + p2.set_value_at_thread_exit(boost::csbl::make_unique<int>(5)); +} + +int main() +{ + { + boost::future<boost::csbl::unique_ptr<int> > f = p.get_future(); + boost::thread(func).detach(); + BOOST_TEST(*f.get() == 5); + } + { + boost::future<boost::csbl::unique_ptr<int> > f = p2.get_future(); + boost::thread(func2).detach(); + BOOST_TEST(*f.get() == 5); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/promise/set_rvalue_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/set_rvalue_pass.cpp new file mode 100644 index 000000000..63260d726 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/promise/set_rvalue_pass.cpp @@ -0,0 +1,297 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011,2014 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class promise<R> + +// void promise::set_value(R&& r); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/static_assert.hpp> + +struct A +{ + A() : + value(0) + { + } + A(int i) : + value(i) + { + } + BOOST_THREAD_MOVABLE_ONLY(A) + + A(BOOST_THREAD_RV_REF(A) rhs) + { + if(rhs.value==0) + throw 9; + else + { + value=rhs.value; + rhs.value=0; + } + } + A& operator=(BOOST_THREAD_RV_REF(A) rhs) + { + if(rhs.value==0) + throw 9; + else + { + value=rhs.value; + rhs.value=0; + } + return *this; + } + int value; +}; + +A make(int i) { + return A(i); +} + +struct movable2 +{ + int value_; + BOOST_THREAD_MOVABLE_ONLY(movable2) + movable2() : value_(1){} + movable2(int i) : value_(i){} + + //Move constructor and assignment + movable2(BOOST_RV_REF(movable2) m) + { value_ = m.value_; m.value_ = 0; } + + movable2 & operator=(BOOST_THREAD_RV_REF(movable2) m) + { value_ = m.value_; m.value_ = 0; return *this; } + + bool moved() const //Observer + { return !value_; } + + int value() const //Observer + { return value_; } +}; + + +movable2 move_return_function2(int i) { + return movable2(i); +} + +int main() +{ +#if defined BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_STATIC_ASSERT((boost::is_copy_constructible<movable2>::value == false)); + BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<movable2>::value == true)); + BOOST_STATIC_ASSERT((boost::is_copy_constructible<A>::value == false)); + BOOST_STATIC_ASSERT((boost::has_move_emulation_enabled<A>::value == true)); +#endif + + { + typedef A T; + T i; + boost::promise<T> p; + boost::future<T> f = p.get_future(); + try + { + p.set_value(boost::move(i)); + BOOST_TEST(false); + } + catch (int j) + { + BOOST_TEST(j == 9); + } + catch (...) + { + BOOST_TEST(false); + } + } + { + typedef A T; + T i; + boost::promise<T> p; + boost::future<T> f = p.get_future(); + try + { + p.set_value_deferred(boost::move(i)); + BOOST_TEST(!f.is_ready()); + p.notify_deferred(); + + BOOST_TEST(false); + } + catch (int j) + { + BOOST_TEST(j == 9); + } + catch (...) + { + BOOST_TEST(false); + } + } + { + typedef A T; + T i; + boost::promise<T> p; + boost::future<T> f = p.get_future(); + try + { + p.set_value((T())); + BOOST_TEST(false); + } + catch (int j) + { + BOOST_TEST(j == 9); + } + catch (...) + { + BOOST_TEST(false); + } + } + { + typedef A T; + T i; + boost::promise<T> p; + boost::future<T> f = p.get_future(); + try + { + p.set_value_deferred((T())); + BOOST_TEST(false); + } + catch (int j) + { + BOOST_TEST(j == 9); + } + catch (...) + { + BOOST_TEST(false); + } + } + { + typedef A T; + T i(3); + boost::promise<T> p; + boost::future<T> f = p.get_future(); + p.set_value(boost::move(i)); + BOOST_TEST(f.get().value == 3); + try + { + T j(3); + p.set_value(boost::move(j)); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); + } + catch (...) + { + BOOST_TEST(false); + } + + } + { + movable2 i(3); + boost::promise<movable2> p; + boost::future<movable2> f = p.get_future(); + p.set_value(move_return_function2(3)); + BOOST_TEST(f.get().value_ == 3); + try + { + movable2 j(3); + p.set_value(boost::move(j)); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); + } + catch (...) + { + BOOST_TEST(false); + } + + } + { + boost::promise<A> p; + boost::future<A> f = p.get_future(); + p.set_value(make(3)); + BOOST_TEST(f.get().value == 3); + try + { + A j(3); + p.set_value(boost::move(j)); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); + } + catch (...) + { + BOOST_TEST(false); + } + + } + { + typedef A T; + T i(3); + boost::promise<T> p; + boost::future<T> f = p.get_future(); + p.set_value(boost::move(i)); + BOOST_TEST(i.value == 0); + boost::promise<T> p2(boost::move(p)); + BOOST_TEST(f.get().value == 3); + + } + { + typedef A T; + T i(3); + boost::promise<T> p; + boost::future<T> f = p.get_future(); + p.set_value(boost::move(i)); + BOOST_TEST(i.value == 0); + boost::promise<T> p2(boost::move(p)); + boost::future<T> f2(boost::move(f)); + BOOST_TEST(f2.get().value == 3); + + } + { + typedef A T; + T i(3); + boost::promise<T> p; + p.set_value(boost::move(i)); + BOOST_TEST(i.value == 0); + boost::promise<T> p2(boost::move(p)); + boost::future<T> f = p2.get_future(); + BOOST_TEST(f.get().value == 3); + + } + + { + typedef boost::future<int> T; + boost::promise<int> pi; + T fi=pi.get_future(); + pi.set_value(3); + + boost::promise<T> p; + boost::future<T> f = p.get_future(); + p.set_value(boost::move(fi)); + boost::future<T> f2(boost::move(f)); + BOOST_TEST(f2.get().get() == 3); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_const_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_const_pass.cpp new file mode 100644 index 000000000..4972cb7d8 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_const_pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class promise<R> + +// void promise::set_value_at_thread_exit(const R& r); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +void func(boost::promise<int> p) +#else +boost::promise<int> p; +void func() +#endif +{ + const int i = 5; + p.set_value_at_thread_exit(i); +} + +int main() +{ + { +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::promise<int> p; + boost::future<int> f = p.get_future(); + boost::thread(func, boost::move(p)).detach(); +#else + boost::future<int> f = p.get_future(); + boost::thread(func).detach(); +#endif + try + { + BOOST_TEST(f.get() == 5); + } + catch (...) + { + BOOST_TEST(false); + } + } + { +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +#else + boost::promise<int> p2; + boost::future<int> f = p2.get_future(); + p = boost::move(p2); + boost::thread(func).detach(); + BOOST_TEST(f.get() == 5); +#endif + } + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp new file mode 100644 index 000000000..c79f2a23e --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp @@ -0,0 +1,110 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class promise<R> + +// void promise<void>::set_value_at_thread_exit(); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +int i = 0; + +boost::promise<void> p; +void func() +{ + p.set_value_at_thread_exit(); + i = 1; +} + +//void func2_mv(BOOST_THREAD_RV_REF(boost::promise<void>) p2) +void func2_mv(boost::promise<void> p2) +{ + p2.set_value_at_thread_exit(); + i = 2; +} + +void func2(boost::promise<void> *p2) +{ + p2->set_value_at_thread_exit(); + i = 2; +} +int main() +{ + try + { + boost::future<void> f = p.get_future(); + boost::thread(func).detach(); + f.get(); + BOOST_TEST(i == 1); + + } + catch(std::exception& ) + { + BOOST_TEST(false); + } + catch(...) + { + BOOST_TEST(false); + } + + try + { + boost::promise<void> p2; + boost::future<void> f = p2.get_future(); + p = boost::move(p2); + boost::thread(func).detach(); + f.get(); + BOOST_TEST(i == 1); + + } + catch(std::exception& ex) + { + std::cout << __FILE__ << ":" << __LINE__ << " " << ex.what() << std::endl; + BOOST_TEST(false); + } + catch(...) + { + BOOST_TEST(false); + } + + try + { + boost::promise<void> p2; + boost::future<void> f = p2.get_future(); +#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD + boost::thread(func2_mv, boost::move(p2)).detach(); +#else + boost::thread(func2, &p2).detach(); +#endif + f.wait(); + f.get(); + BOOST_TEST(i == 2); + } + catch(std::exception& ex) + { + std::cout << __FILE__ << ":" << __LINE__ << " " << ex.what() << std::endl; + BOOST_TEST(false); + } + catch(...) + { + BOOST_TEST(false); + } + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/promise/set_value_const_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/set_value_const_pass.cpp new file mode 100644 index 000000000..84f2fb273 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/promise/set_value_const_pass.cpp @@ -0,0 +1,118 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class promise<R> + +// void promise::set_value(const R& r); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/static_assert.hpp> +#include <boost/config.hpp> + +#ifdef BOOST_MSVC +# pragma warning(disable: 4702) // unreachable code +#endif + +struct A +{ + A() + { + } + A(const A&) + { + throw 10; + } +#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) + A& operator= (const A&) = default; +#endif +}; + +int main() +{ + + { + typedef int T; + T i = 3; + boost::promise<T> p; + boost::future<T> f = p.get_future(); + p.set_value(i); + ++i; + BOOST_TEST(f.get() == 3); + --i; + try + { + p.set_value(i); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); + } + catch (...) + { + BOOST_TEST(false); + } + } + { + typedef int T; + T i = 3; + boost::promise<T> p; + boost::future<T> f = p.get_future(); + p.set_value_deferred(i); + p.notify_deferred(); + ++i; + BOOST_TEST(f.get() == 3); + --i; + try + { + p.set_value(i); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); + } + catch (...) + { + BOOST_TEST(false); + } + } + { + typedef A T; + T i; + boost::promise<T> p; + boost::future<T> f = p.get_future(); + try + { + p.set_value(i); + BOOST_TEST(false); + } + catch (int j) + { + BOOST_TEST(j == 10); + } + catch (...) + { + BOOST_TEST(false); + } + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/promise/set_value_void_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/set_value_void_pass.cpp new file mode 100644 index 000000000..7c11d5b66 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/promise/set_value_void_pass.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class promise<R> + +// void promise<void>::set_value(); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/static_assert.hpp> + +struct A +{ + A() + { + } + A(const A&) + { + throw 10; + } +}; + +int main() +{ + + { + typedef void T; + boost::promise<T> p; + boost::future<T> f = p.get_future(); + p.set_value(); + f.get(); + try + { + p.set_value(); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); + } + catch (...) + { + BOOST_TEST(false); + } + } + { + typedef void T; + boost::promise<T> p; + boost::future<T> f = p.get_future(); + p.set_value_deferred(); + p.notify_deferred(); + f.get(); + try + { + p.set_value(); + BOOST_TEST(false); + } + catch (const boost::future_error& e) + { + BOOST_TEST(e.code() == boost::system::make_error_code(boost::future_errc::promise_already_satisfied)); + } + catch (...) + { + BOOST_TEST(false); + } + } + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/promise/use_allocator_pass.cpp b/src/boost/libs/thread/test/sync/futures/promise/use_allocator_pass.cpp new file mode 100644 index 000000000..3b1e96c7e --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/promise/use_allocator_pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class promise<R> + +// promise(allocator_arg_t, const Allocator& a); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/static_assert.hpp> + +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +#include "../test_allocator.hpp" + +int main() +{ + + BOOST_STATIC_ASSERT_MSG((boost::csbl::uses_allocator<boost::promise<int>, test_allocator<int> >::value), ""); + BOOST_STATIC_ASSERT_MSG((boost::csbl::uses_allocator<boost::promise<int&>, test_allocator<int&> >::value), ""); + BOOST_STATIC_ASSERT_MSG((boost::csbl::uses_allocator<boost::promise<void>, test_allocator<void> >::value), ""); + + return boost::report_errors(); +} + +#else +int main() +{ + return boost::report_errors(); +} +#endif + + diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/copy_assign_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/copy_assign_pass.cpp new file mode 100644 index 000000000..1b23b2d16 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/shared_future/copy_assign_pass.cpp @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class shared_future<R> + +// shared_future& operator=(const shared_future&); + + +#define BOOST_THREAD_VERSION 3 +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + { + typedef int T; + boost::promise<T> p; + boost::shared_future<T> f0((p.get_future())); + boost::shared_future<T> f; + f = f0; + BOOST_TEST(f0.valid()); + BOOST_TEST(f.valid()); + + } + { + typedef int T; + boost::shared_future<T> f0; + boost::shared_future<T> f; + f = f0; + BOOST_TEST(!f0.valid()); + BOOST_TEST(!f.valid()); + } + { + typedef int& T; + boost::promise<T> p; + boost::shared_future<T> f0((p.get_future())); + boost::shared_future<T> f; + f = f0; + BOOST_TEST(f0.valid()); + BOOST_TEST(f.valid()); + } + { + typedef int& T; + boost::shared_future<T> f0; + boost::shared_future<T> f; + f = f0; + BOOST_TEST(!f0.valid()); + BOOST_TEST(!f.valid()); + } + { + typedef void T; + boost::promise<T> p; + boost::shared_future<T> f0((p.get_future())); + boost::shared_future<T> f; + f = f0; + BOOST_TEST(f0.valid()); + BOOST_TEST(f.valid()); + } + { + typedef void T; + boost::shared_future<T> f0; + boost::shared_future<T> f; + f = f0; + BOOST_TEST(!f0.valid()); + BOOST_TEST(!f.valid()); + } + + return boost::report_errors(); +} + +//#include "../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/copy_ctor_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/copy_ctor_pass.cpp new file mode 100644 index 000000000..fd29c0fe3 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/shared_future/copy_ctor_pass.cpp @@ -0,0 +1,77 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> +// class shared_future<R> + +// shared_future(const future&); + + +#define BOOST_THREAD_VERSION 3 +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + { + typedef int T; + boost::promise<T> p; + boost::shared_future<T> f0((p.get_future())); + boost::shared_future<T> f = f0; + BOOST_TEST(f0.valid()); + BOOST_TEST(f.valid()); + } + { + typedef int T; + boost::shared_future < T > f0; + boost::shared_future<T> f = f0; + BOOST_TEST(!f0.valid()); + BOOST_TEST(!f.valid()); + } + { + typedef int& T; + boost::promise<T> p; + boost::shared_future<T> f0((p.get_future())); + boost::shared_future<T> f = f0; + BOOST_TEST(f0.valid()); + BOOST_TEST(f.valid()); + } + { + typedef int& T; + boost::shared_future < T > f0; + boost::shared_future<T> f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(!f.valid()); + } + { + typedef void T; + boost::promise<T> p; + boost::shared_future<T> f0((p.get_future())); + boost::shared_future<T> f = f0; + BOOST_TEST(f0.valid()); + BOOST_TEST(f.valid()); + } + { + typedef void T; + boost::shared_future < T > f0; + boost::shared_future<T> f = f0; + BOOST_TEST(!f0.valid()); + BOOST_TEST(!f.valid()); + } + + return boost::report_errors(); +} + +//#include "../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/default_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/default_pass.cpp new file mode 100644 index 000000000..59ecea3a3 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/shared_future/default_pass.cpp @@ -0,0 +1,45 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class shared_future<R> + +// shared_future(); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + + { + boost::shared_future<int> f; + BOOST_TEST(!f.valid()); + } + { + boost::shared_future<int&> f; + BOOST_TEST(!f.valid()); + } + { + boost::shared_future<void> f; + BOOST_TEST(!f.valid()); + } + + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/dtor_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/dtor_pass.cpp new file mode 100644 index 000000000..01fb591c0 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/shared_future/dtor_pass.cpp @@ -0,0 +1,109 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class shared_future<R> + +// ~shared_future(); + +#define BOOST_THREAD_VERSION 3 +#include <boost/exception/exception.hpp> + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +#include "../test_allocator.hpp" +#endif + +int main() +{ +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS + BOOST_TEST(test_alloc_base::count == 0); + { + typedef int T; + boost::shared_future<T> f; + { + boost::promise<T> p(boost::allocator_arg, test_allocator<T>()); + BOOST_TEST(test_alloc_base::count == 1); + f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(test_alloc_base::count == 1); + BOOST_TEST(f.valid()); + } + BOOST_TEST(test_alloc_base::count == 1); + BOOST_TEST(f.valid()); + } + BOOST_TEST(test_alloc_base::count == 0); + { + typedef int& T; + boost::shared_future<T> f; + { + boost::promise<T> p(boost::allocator_arg, test_allocator<int>()); + BOOST_TEST(test_alloc_base::count == 1); + f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(test_alloc_base::count == 1); + BOOST_TEST(f.valid()); + } + BOOST_TEST(test_alloc_base::count == 1); + BOOST_TEST(f.valid()); + } + BOOST_TEST(test_alloc_base::count == 0); + { + typedef void T; + boost::shared_future<T> f; + { + boost::promise<T> p(boost::allocator_arg, test_allocator<T>()); + BOOST_TEST(test_alloc_base::count == 1); + f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(test_alloc_base::count == 1); + BOOST_TEST(f.valid()); + } + BOOST_TEST(test_alloc_base::count == 1); + BOOST_TEST(f.valid()); + } + BOOST_TEST(test_alloc_base::count == 0); +#endif + { + typedef int T; + boost::shared_future<T> f; + { + boost::promise<T> p; + f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(f.valid()); + } + BOOST_TEST(f.valid()); + } + { + typedef int& T; + boost::shared_future<T> f; + { + boost::promise<T> p; + f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(f.valid()); + } + BOOST_TEST(f.valid()); + } + { + typedef void T; + boost::shared_future<T> f; + { + boost::promise<T> p; + f = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + BOOST_TEST(f.valid()); + } + BOOST_TEST(f.valid()); + } + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/get_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/get_pass.cpp new file mode 100644 index 000000000..558fb024f --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/shared_future/get_pass.cpp @@ -0,0 +1,208 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/shared_future.hpp> + +// class shared_future<R> + +// const R& shared_future::get(); +// R& shared_future<R&>::get(); +// void shared_future<void>::get(); +//#define BOOST_THREAD_VERSION 3 +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/future.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> + +#if defined BOOST_THREAD_USES_CHRONO + +namespace boost +{ +template <typename T> +struct wrap +{ + wrap(T const& v) : value(v){} + T value; + +}; + +template <typename T> +exception_ptr make_exception_ptr(T v) { + return copy_exception(wrap<T>(v)); +} +} + +void func1(boost::promise<int> p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + p.set_value(3); +} + +void func2(boost::promise<int> p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + p.set_exception(boost::make_exception_ptr(3)); +} + +int j = 0; + +void func3(boost::promise<int&> p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + j = 5; + p.set_value(j); +} + +void func4(boost::promise<int&> p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + p.set_exception(boost::make_exception_ptr(3.5)); +} + +void func5(boost::promise<void> p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + p.set_value(); +} + +void func6(boost::promise<void> p) +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + p.set_exception(boost::make_exception_ptr(4)); +} + + +int main() +{ + { + typedef int T; + { + boost::promise<T> p; + boost::shared_future<T> f((p.get_future())); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func1, boost::move(p)).detach(); +#else + p.set_value(3); +#endif + BOOST_TEST(f.valid()); + BOOST_TEST(f.get() == 3); + BOOST_TEST(f.valid()); + } + { + boost::promise<T> p; + boost::shared_future<T> f((p.get_future())); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func2, boost::move(p)).detach(); +#else + p.set_exception(boost::make_exception_ptr(3)); +#endif + try + { + BOOST_TEST(f.valid()); + BOOST_TEST(f.get() == 3); + BOOST_TEST(false); + } + catch (boost::wrap<int> const& i) + { + BOOST_TEST(i.value == 3); + } + catch (...) + { + BOOST_TEST(false); + } + BOOST_TEST(f.valid()); + } + } + { + typedef int& T; + { + boost::promise<T> p; + boost::shared_future<T> f((p.get_future())); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func3, boost::move(p)).detach(); +#else + int j=5; + p.set_value(j); +#endif + BOOST_TEST(f.valid()); + BOOST_TEST(f.get() == 5); + BOOST_TEST(f.valid()); + } + { + boost::promise<T> p; + boost::shared_future<T> f((p.get_future())); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func4, boost::move(p)).detach(); +#else + p.set_exception(boost::make_exception_ptr(3.5)); +#endif + try + { + BOOST_TEST(f.valid()); + BOOST_TEST(f.get() == 3); + BOOST_TEST(false); + } + catch (boost::wrap<double> const& i) + { + BOOST_TEST(i.value == 3.5); + } + BOOST_TEST(f.valid()); + } + } + + typedef void T; + { + boost::promise<T> p; + boost::shared_future<T> f((p.get_future())); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func5, boost::move(p)).detach(); +#else + p.set_value(); +#endif + BOOST_TEST(f.valid()); + f.get(); + BOOST_TEST(f.valid()); + } + { + boost::promise<T> p; + boost::shared_future<T> f((p.get_future())); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func6, boost::move(p)).detach(); +#else + p.set_exception(boost::make_exception_ptr(4)); +#endif + try + { + BOOST_TEST(f.valid()); + f.get(); + BOOST_TEST(false); + } + catch (boost::wrap<int> const& i) + { + BOOST_TEST(i.value == 4); + } + catch (...) + { + BOOST_TEST(false); + } + BOOST_TEST(f.valid()); + } + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/move_assign_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/move_assign_pass.cpp new file mode 100644 index 000000000..40ff4992c --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/shared_future/move_assign_pass.cpp @@ -0,0 +1,87 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <future> + +// class shared_future<R> + +// shared_future& shared_future=(shared_future&& rhs); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::mutex m0; +boost::mutex m1; + +int main() +{ + { + typedef int T; + boost::promise<T> p; + boost::shared_future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + boost::shared_future<T> f; + f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(f.valid()); + } + { + typedef int T; + boost::shared_future<T> f0; + boost::shared_future<T> f; + f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(!f.valid()); + } + { + typedef int& T; + boost::promise<T> p; + boost::shared_future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + boost::shared_future<T> f; + f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(f.valid()); + } + { + typedef int& T; + boost::shared_future<T> f0; + boost::shared_future<T> f; + f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(!f.valid()); + } + { + typedef void T; + boost::promise<T> p; + boost::shared_future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + boost::shared_future<T> f; + f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(f.valid()); + } + { + typedef void T; + boost::shared_future<T> f0; + boost::shared_future<T> f; + f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(!f.valid()); + } + + + return boost::report_errors(); + +} + diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/move_ctor_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/move_ctor_pass.cpp new file mode 100644 index 000000000..533f5ec90 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/shared_future/move_ctor_pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <future> + +// class shared_future<R> + +// shared_future(shared_future&& rhs); + +#define BOOST_THREAD_VERSION 3 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::mutex m; + +int main() +{ + { + typedef int T; + boost::promise<T> p; + boost::shared_future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + boost::shared_future<T> f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(f.valid()); + } + { + typedef int T; + boost::shared_future<T> f0; + boost::shared_future<T> f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(!f.valid()); + } + { + typedef int& T; + boost::promise<T> p; + boost::shared_future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + boost::shared_future<T> f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(f.valid()); + } + { + typedef int& T; + boost::shared_future<T> f0; + boost::shared_future<T> f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(!f.valid()); + } + { + typedef void T; + boost::promise<T> p; + boost::shared_future<T> f0 = BOOST_THREAD_MAKE_RV_REF(p.get_future()); + boost::shared_future<T> f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(f.valid()); + } + { + typedef void T; + boost::shared_future<T> f0; + boost::shared_future<T> f = boost::move(f0); + BOOST_TEST(!f0.valid()); + BOOST_TEST(!f.valid()); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/then_executor_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/then_executor_pass.cpp new file mode 100644 index 000000000..73b42fc8a --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/shared_future/then_executor_pass.cpp @@ -0,0 +1,149 @@ +// Copyright (C) 2014 Vicente Botet +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class future<R> + +// template<typename F> +// auto then(F&& func) -> future<decltype(func(*this))>; + +#define BOOST_THREAD_VERSION 4 +#define BOOST_THREAD_PROVIDES_EXECUTORS +//#define BOOST_THREAD_USES_LOG +#define BOOST_THREAD_USES_LOG_THREAD_ID +#include <boost/thread/detail/log.hpp> + +#include <boost/thread/future.hpp> +#include <boost/thread/executors/basic_thread_pool.hpp> +#include <boost/thread/executor.hpp> +#include <boost/detail/lightweight_test.hpp> + +#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION + +#ifdef BOOST_MSVC +#pragma warning(disable: 4127) // conditional expression is constant +#endif + +int p1() +{ + BOOST_THREAD_LOG << "p1 < " << BOOST_THREAD_END_LOG; + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + BOOST_THREAD_LOG << "p1 >" << BOOST_THREAD_END_LOG; + return 1; +} + +int p2(boost::shared_future<int> f) +{ + BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG; + BOOST_TEST(f.valid()); + int i = f.get(); + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG; + return 2 * i; +} + +void p3(boost::shared_future<int> f) +{ + BOOST_THREAD_LOG << "p3 <" << &f << BOOST_THREAD_END_LOG; + BOOST_TEST(f.valid()); + int i = f.get(); + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + BOOST_THREAD_LOG << "p3 <" << &f << " " << i << BOOST_THREAD_END_LOG; + return ; +} + +int main() +{ + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::basic_thread_pool ex(1); + boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share(); + BOOST_TEST(f1.valid()); + boost::future<int> f2 = f1.then(ex, &p2); + BOOST_TEST(f2.valid()); + try + { + BOOST_TEST(f2.get()==2); + } + catch (std::exception& ex) + { + BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + catch (...) + { + BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::basic_thread_pool ex(1); + boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share(); + BOOST_TEST(f1.valid()); + boost::future<void> f2 = f1.then(ex, &p3); + BOOST_TEST(f2.valid()); + try + { + f2.wait(); + } + catch (std::exception& ex) + { + BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + catch (...) + { + BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::basic_thread_pool ex(1); + boost::future<int> f2 = boost::async(p1).share().then(ex, &p2); + BOOST_TEST(f2.get()==2); + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::basic_thread_pool ex(1); + boost::shared_future<int> f1 = boost::async(p1).share(); + boost::shared_future<int> f21 = f1.then(ex, &p2).share(); + boost::future<int> f2= f21.then(ex, &p2); + BOOST_TEST(f2.get()==4); + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::basic_thread_pool ex(1); + boost::shared_future<int> f1 = boost::async(p1).share(); + boost::shared_future<int> f21 = f1.then(ex, &p2).share(); + boost::future<int> f2= f21.then(&p2); + BOOST_TEST(f2.get()==4); + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::basic_thread_pool ex(1); + boost::shared_future<int> f1 = boost::async(p1).share(); + boost::future<int> f2= f1.then(ex, &p2).share().then(ex, &p2); + BOOST_TEST(f2.get()==4); + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::basic_thread_pool ex(1); + boost::future<int> f2 = boost::async(p1).share().then(ex, &p2).share().then(ex, &p2); + BOOST_TEST(f2.get()==4); + } + + return boost::report_errors(); +} + +#else + +int main() +{ + return 0; +} +#endif diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/then_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/then_pass.cpp new file mode 100644 index 000000000..e7cca062e --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/shared_future/then_pass.cpp @@ -0,0 +1,156 @@ +// Copyright (C) 2012-2013 Vicente Botet +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class future<R> + +// template<typename F> +// auto then(F&& func) -> future<decltype(func(*this))>; + +#define BOOST_THREAD_VERSION 4 +//#define BOOST_THREAD_USES_LOG +#define BOOST_THREAD_USES_LOG_THREAD_ID +#include <boost/thread/detail/log.hpp> + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +#if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION + +#ifdef BOOST_MSVC +#pragma warning(disable: 4127) // conditional expression is constant +#endif + +int p1() +{ + BOOST_THREAD_LOG << "p1 < " << BOOST_THREAD_END_LOG; + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + BOOST_THREAD_LOG << "p1 >" << BOOST_THREAD_END_LOG; + return 1; +} + +int p2(boost::shared_future<int> f) +{ + BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG; + BOOST_TEST(f.valid()); + int i = f.get(); + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + BOOST_THREAD_LOG << "p2 <" << &f << BOOST_THREAD_END_LOG; + return 2 * i; +} + +void p3(boost::shared_future<int> f) +{ + BOOST_THREAD_LOG << "p3 <" << &f << BOOST_THREAD_END_LOG; + BOOST_TEST(f.valid()); + int i = f.get(); + boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); + BOOST_THREAD_LOG << "p3 <" << &f << " " << i << BOOST_THREAD_END_LOG; + return ; +} + +int main() +{ + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share(); + BOOST_TEST(f1.valid()); + boost::future<int> f2 = f1.then(&p2); + BOOST_TEST(f2.valid()); + try + { + BOOST_TEST(f2.get()==2); + } + catch (std::exception& ex) + { + BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + catch (...) + { + BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share(); + BOOST_TEST(f1.valid()); + boost::future<int> f2 = f1.then(&p2); + boost::future<int> f3 = f1.then(&p2); + BOOST_TEST(f2.valid()); + BOOST_TEST(f3.valid()); + try + { + BOOST_TEST(f2.get()==2); + BOOST_TEST(f3.get()==2); + } + catch (std::exception& ex) + { + BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + catch (...) + { + BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share(); + BOOST_TEST(f1.valid()); + boost::future<void> f2 = f1.then(&p3); + BOOST_TEST(f2.valid()); + try + { + f2.wait(); + } + catch (std::exception& ex) + { + BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + catch (...) + { + BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG; + BOOST_TEST(false); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::future<int> f2 = boost::async(p1).share().then(&p2); + BOOST_TEST(f2.get()==2); + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::shared_future<int> f1 = boost::async(p1).share(); + boost::shared_future<int> f21 = f1.then(&p2).share(); + boost::future<int> f2= f21.then(&p2); + BOOST_TEST(f2.get()==4); + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::shared_future<int> f1 = boost::async(p1).share(); + boost::future<int> f2= f1.then(&p2).share().then(&p2); + BOOST_TEST(f2.get()==4); + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + boost::future<int> f2 = boost::async(p1).share().then(&p2).share().then(&p2); + BOOST_TEST(f2.get()==4); + } + + return boost::report_errors(); +} + +#else + +int main() +{ + return 0; +} +#endif diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/wait_for_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/wait_for_pass.cpp new file mode 100644 index 000000000..e9d8ac684 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/shared_future/wait_for_pass.cpp @@ -0,0 +1,174 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class shared_future<R> + +// template <class Rep, class Period> +// future_status +// wait_for(const chrono::duration<Rep, Period>& rel_time) const; + +#define BOOST_THREAD_VERSION 4 +//#define BOOST_THREAD_USES_LOG +#define BOOST_THREAD_USES_LOG_THREAD_ID +#include <boost/thread/detail/log.hpp> + +#include <boost/thread/future.hpp> +#include <boost/thread/thread.hpp> +#include <boost/chrono/chrono_io.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + +#if defined BOOST_THREAD_USES_CHRONO + +#ifdef BOOST_MSVC +#pragma warning(disable: 4127) // conditional expression is constant +#endif + +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; + +namespace boost +{ + template <typename OStream> + OStream& operator<<(OStream& os , boost::future_status st ) + { + os << underlying_cast<int>(st) << " "; + return os; + } + template <typename T> + struct wrap + { + wrap(T const& v) : + value(v) + { + } + T value; + + }; + + template <typename T> + exception_ptr make_exception_ptr(T v) + { + return copy_exception(wrap<T> (v)); + } +} + +void func1(boost::promise<int> p) +{ + boost::this_thread::sleep_for(ms(500)); + p.set_value(3); +} + +int j = 0; + +void func3(boost::promise<int&> p) +{ + boost::this_thread::sleep_for(ms(500)); + j = 5; + p.set_value(j); +} + +void func5(boost::promise<void> p) +{ + boost::this_thread::sleep_for(ms(500)); + p.set_value(); +} + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +int main() +{ + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + typedef boost::chrono::high_resolution_clock Clock; + { + typedef int T; + boost::promise<T> p; + boost::shared_future<T> f((p.get_future())); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func1, boost::move(p)).detach(); +#endif + BOOST_TEST(f.valid()); + BOOST_TEST_EQ(f.wait_for(ms(250)) , boost::future_status::timeout); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +#else + func1(boost::move(p)); +#endif + BOOST_TEST(f.valid()); + BOOST_TEST_EQ(f.wait_for(ms(750)) , boost::future_status::ready); + BOOST_TEST(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + BOOST_TEST(f.valid()); + ns d = t1 - t0; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + } + { + typedef int& T; + boost::promise<T> p; + boost::shared_future<T> f((p.get_future())); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func3, boost::move(p)).detach(); +#endif + BOOST_TEST(f.valid()); + BOOST_TEST_EQ(f.wait_for(ms(250)) , boost::future_status::timeout); + BOOST_TEST(f.valid()); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +#else + func3(boost::move(p)); +#endif + BOOST_TEST_EQ(f.wait_for(ms(750)) , boost::future_status::ready); + BOOST_TEST(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + BOOST_TEST(f.valid()); + ns d = t1 - t0; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + } + { + typedef void T; + boost::promise<T> p; + boost::shared_future<T> f((p.get_future())); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func5, boost::move(p)).detach(); +#endif + BOOST_TEST(f.valid()); + BOOST_TEST_EQ(f.wait_for(ms(250)) , boost::future_status::timeout); + BOOST_TEST(f.valid()); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +#else + func5(boost::move(p)); +#endif + BOOST_TEST_EQ(f.wait_for(ms(750)) , boost::future_status::ready); + BOOST_TEST(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + BOOST_TEST(f.valid()); + ns d = t1 - t0; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/wait_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/wait_pass.cpp new file mode 100644 index 000000000..d2d1b31f6 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/shared_future/wait_pass.cpp @@ -0,0 +1,155 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class shared_future<R> + +// template <class Rep, class Period> +// void wait() const; + +//#define BOOST_THREAD_VERSION 3 +#define BOOST_THREAD_VERSION 4 +//#define BOOST_THREAD_USES_LOG +#define BOOST_THREAD_USES_LOG_THREAD_ID +#include <boost/thread/detail/log.hpp> + +#include <boost/thread/future.hpp> +#include <boost/thread/thread.hpp> +#include <boost/chrono/chrono_io.hpp> +#include <boost/detail/lightweight_test.hpp> + +#if defined BOOST_THREAD_USES_CHRONO + +#ifdef BOOST_MSVC +#pragma warning(disable: 4127) // conditional expression is constant +#endif + +typedef boost::chrono::milliseconds ms; + +namespace boost +{ + template <typename OStream> + OStream& operator<<(OStream& os , boost::future_status st ) + { + os << underlying_cast<int>(st) << " "; + return os; + } + template <typename T> + struct wrap + { + wrap(T const& v) : + value(v) + { + } + T value; + + }; + + template <typename T> + exception_ptr make_exception_ptr(T v) + { + return copy_exception(wrap<T> (v)); + } +} + +void func1(boost::promise<int> p) +{ + boost::this_thread::sleep_for(ms(500)); + p.set_value(3); +} + +int j = 0; + +void func3(boost::promise<int&> p) +{ + boost::this_thread::sleep_for(ms(500)); + j = 5; + p.set_value(j); +} + +void func5(boost::promise<void> p) +{ + boost::this_thread::sleep_for(ms(500)); + p.set_value(); +} + +int main() +{ + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + typedef boost::chrono::high_resolution_clock Clock; + { + typedef int T; + boost::promise<T> p; + boost::shared_future<T> f((p.get_future())); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func1, boost::move(p)).detach(); +#else + func1(boost::move(p)); +#endif + BOOST_TEST(f.valid()); + f.wait(); + BOOST_TEST(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + BOOST_TEST(f.valid()); + BOOST_TEST(t1 - t0 < ms(50)); + } + { + typedef int& T; + boost::promise<T> p; + boost::shared_future<T> f((p.get_future())); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func3, boost::move(p)).detach(); +#else + func3(boost::move(p)); +#endif + BOOST_TEST(f.valid()); + f.wait(); + BOOST_TEST(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + BOOST_TEST(f.valid()); + BOOST_TEST(t1 - t0 < ms(50)); + } + { + typedef void T; + boost::promise<T> p; + boost::shared_future<T> f((p.get_future())); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func5, boost::move(p)).detach(); +#else + func5(boost::move(p)); +#endif + BOOST_TEST(f.valid()); + f.wait(); + BOOST_TEST(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + BOOST_TEST(f.valid()); + BOOST_TEST(t1 - t0 < ms(50)); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif diff --git a/src/boost/libs/thread/test/sync/futures/shared_future/wait_until_pass.cpp b/src/boost/libs/thread/test/sync/futures/shared_future/wait_until_pass.cpp new file mode 100644 index 000000000..8b05725e7 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/shared_future/wait_until_pass.cpp @@ -0,0 +1,175 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// class shared_future<R> + +// template <class Rep, class Period> +// future_status +// wait_until(const chrono::time_point<Clock, Duration>& abs_time) const; + +//#define BOOST_THREAD_VERSION 3 +#define BOOST_THREAD_VERSION 4 +//#define BOOST_THREAD_USES_LOG +#define BOOST_THREAD_USES_LOG_THREAD_ID +#include <boost/thread/detail/log.hpp> + +#include <boost/thread/future.hpp> +#include <boost/thread/thread.hpp> +#include <boost/chrono/chrono_io.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + +#if defined BOOST_THREAD_USES_CHRONO + +#ifdef BOOST_MSVC +#pragma warning(disable: 4127) // conditional expression is constant +#endif + +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; + +namespace boost +{ + template <typename OStream> + OStream& operator<<(OStream& os , boost::future_status st ) + { + os << underlying_cast<int>(st) << " "; + return os; + } + template <typename T> + struct wrap + { + wrap(T const& v) : + value(v) + { + } + T value; + + }; + + template <typename T> + exception_ptr make_exception_ptr(T v) + { + return copy_exception(wrap<T> (v)); + } +} + +void func1(boost::promise<int> p) +{ + boost::this_thread::sleep_for(ms(500)); + p.set_value(3); +} + +int j = 0; + +void func3(boost::promise<int&> p) +{ + boost::this_thread::sleep_for(ms(500)); + j = 5; + p.set_value(j); +} + +void func5(boost::promise<void> p) +{ + boost::this_thread::sleep_for(ms(500)); + p.set_value(); +} + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +int main() +{ + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + { + typedef boost::chrono::high_resolution_clock Clock; + { + typedef int T; + boost::promise<T> p; + boost::shared_future<T> f((p.get_future())); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func1, boost::move(p)).detach(); +#endif + BOOST_TEST(f.valid()); + BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(250)) , boost::future_status::timeout); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +#else + func1(boost::move(p)); +#endif + BOOST_TEST(f.valid()); + BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(750)) , boost::future_status::ready); + BOOST_TEST(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + BOOST_TEST(f.valid()); + ns d = t1 - t0; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + } + { + typedef int& T; + boost::promise<T> p; + boost::shared_future<T> f((p.get_future())); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func3, boost::move(p)).detach(); +#endif + BOOST_TEST(f.valid()); + BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(250)) , boost::future_status::timeout); + BOOST_TEST(f.valid()); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +#else + func3(boost::move(p)); +#endif + BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(750)) , boost::future_status::ready); + BOOST_TEST(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + BOOST_TEST(f.valid()); + ns d = t1 - t0; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + } + { + typedef void T; + boost::promise<T> p; + boost::shared_future<T> f((p.get_future())); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + boost::thread(func5, boost::move(p)).detach(); +#endif + BOOST_TEST(f.valid()); + BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(250)) , boost::future_status::timeout); + BOOST_TEST(f.valid()); +#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +#else + func5(boost::move(p)); +#endif + BOOST_TEST_EQ(f.wait_until(Clock::now() + ms(750)) , boost::future_status::ready); + BOOST_TEST(f.valid()); + Clock::time_point t0 = Clock::now(); + f.wait(); + Clock::time_point t1 = Clock::now(); + BOOST_TEST(f.valid()); + ns d = t1 - t0; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + } + } + BOOST_THREAD_LOG << BOOST_THREAD_END_LOG; + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif diff --git a/src/boost/libs/thread/test/sync/futures/test_allocator.hpp b/src/boost/libs/thread/test/sync/futures/test_allocator.hpp new file mode 100644 index 000000000..a73d7d8e3 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/test_allocator.hpp @@ -0,0 +1,158 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_THREAD_TEST_ALLOCATOR_HPP +#define BOOST_THREAD_TEST_ALLOCATOR_HPP + +#include <cstddef> +#include <boost/type_traits.hpp> +#include <boost/thread/detail/move.hpp> +#include <cstdlib> +#include <new> +#include <climits> + +class test_alloc_base +{ +public: + static int count; +public: + static int throw_after; +}; + +int test_alloc_base::count = 0; +int test_alloc_base::throw_after = INT_MAX; + +template <class T> +class test_allocator + : public test_alloc_base +{ + int data_; + + template <class U> friend class test_allocator; +public: + + typedef unsigned size_type; + typedef int difference_type; + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef typename boost::add_lvalue_reference<value_type>::type reference; + typedef typename boost::add_lvalue_reference<const value_type>::type const_reference; + + template <class U> struct rebind {typedef test_allocator<U> other;}; + + test_allocator() throw() : data_(-1) {} + explicit test_allocator(int i) throw() : data_(i) {} + test_allocator(const test_allocator& a) throw() + : data_(a.data_) {} + template <class U> test_allocator(const test_allocator<U>& a) throw() + : data_(a.data_) {} + ~test_allocator() throw() {data_ = 0;} + pointer address(reference x) const {return &x;} + const_pointer address(const_reference x) const {return &x;} + pointer allocate(size_type n, const void* = 0) + { + if (count >= throw_after) + throw std::bad_alloc(); + ++count; + return (pointer)std::malloc(n * sizeof(T)); + } + void deallocate(pointer p, size_type) + {--count; std::free(p);} + size_type max_size() const throw() + {return UINT_MAX / sizeof(T);} + void construct(pointer p, const T& val) + {::new(p) T(val);} + + void construct(pointer p, BOOST_THREAD_RV_REF(T) val) + {::new(p) T(boost::move(val));} + + void destroy(pointer p) {p->~T();} + + friend bool operator==(const test_allocator& x, const test_allocator& y) + {return x.data_ == y.data_;} + friend bool operator!=(const test_allocator& x, const test_allocator& y) + {return !(x == y);} +}; + +template <> +class test_allocator<void> + : public test_alloc_base +{ + int data_; + + template <class U> friend class test_allocator; +public: + + typedef unsigned size_type; + typedef int difference_type; + typedef void value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + + template <class U> struct rebind {typedef test_allocator<U> other;}; + + test_allocator() throw() : data_(-1) {} + explicit test_allocator(int i) throw() : data_(i) {} + test_allocator(const test_allocator& a) throw() + : data_(a.data_) {} + template <class U> test_allocator(const test_allocator<U>& a) throw() + : data_(a.data_) {} + ~test_allocator() throw() {data_ = 0;} + + friend bool operator==(const test_allocator& x, const test_allocator& y) + {return x.data_ == y.data_;} + friend bool operator!=(const test_allocator& x, const test_allocator& y) + {return !(x == y);} +}; + +template <class T> +class other_allocator +{ + int data_; + + template <class U> friend class other_allocator; + +public: + typedef T value_type; + + other_allocator() : data_(-1) {} + explicit other_allocator(int i) : data_(i) {} + template <class U> other_allocator(const other_allocator<U>& a) + : data_(a.data_) {} + T* allocate(std::size_t n) + {return (T*)std::malloc(n * sizeof(T));} + void deallocate(T* p, std::size_t) + {std::free(p);} + + other_allocator select_on_container_copy_construction() const + {return other_allocator(-2);} + + friend bool operator==(const other_allocator& x, const other_allocator& y) + {return x.data_ == y.data_;} + friend bool operator!=(const other_allocator& x, const other_allocator& y) + {return !(x == y);} + + typedef boost::true_type propagate_on_container_copy_assignment; + typedef boost::true_type propagate_on_container_move_assignment; + typedef boost::true_type propagate_on_container_swap; + +#ifdef BOOST_NO_SFINAE_EXPR + std::size_t max_size() const + {return UINT_MAX / sizeof(T);} +#endif // BOOST_NO_SFINAE_EXPR + +}; + +#endif // BOOST_THREAD_TEST_ALLOCATOR_HPP diff --git a/src/boost/libs/thread/test/sync/futures/when_all/iterators_pass.cpp b/src/boost/libs/thread/test/sync/futures/when_all/iterators_pass.cpp new file mode 100644 index 000000000..2646074f0 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/when_all/iterators_pass.cpp @@ -0,0 +1,362 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2014 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// template< typename InputIterator> +// future<vector<typename InputIterator::value_type> > +// when_all(InputIterator first, InputIterator last) + +#include <boost/config.hpp> + +#if ! defined BOOST_NO_CXX11_DECLTYPE +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif + + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <stdexcept> + +#ifdef BOOST_MSVC +#pragma warning(disable: 4127) // conditional expression is constant +#endif + +int p1() +{ + return 123; +} + +int thr() +{ + throw std::logic_error("123"); +} +int p2() +{ + return 321; +} + +int main() +{ +#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY + if (0) // todo not yet implemented + { // invalid future copy-constructible + boost::csbl::vector<boost::future<int> > v; + boost::future<int> f1; + v.push_back(boost::move(f1)); + v.push_back(boost::make_ready_future(321)); + BOOST_TEST(! v[0].valid()); + BOOST_TEST(v[1].valid()); + + boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(v.begin(), v.end()); + BOOST_TEST(! v[0].valid()); + BOOST_TEST(! v[1].valid()); + BOOST_TEST(all.valid()); + boost::csbl::vector<boost::future<int> > res = all.get(); + BOOST_TEST(res.size() == 2); + BOOST_TEST(res[1].valid()); + BOOST_TEST(res[1].is_ready()); + // has exception + //BOOST_TEST(res[0].get() == 123); + BOOST_TEST(res[1].valid()); + BOOST_TEST(res[1].is_ready()); + BOOST_TEST(res[1].get() == 321); + } + { // is_ready future copy-constructible + boost::future<int> f1 = boost::make_ready_future(123); + boost::future<int> f2 = boost::make_ready_future(321); + boost::csbl::vector<boost::future<int> > v; + v.push_back(boost::move(f1)); + v.push_back(boost::move(f2)); + BOOST_TEST(v[0].valid()); + BOOST_TEST(v[0].is_ready()); + BOOST_TEST(v[1].valid()); + BOOST_TEST(v[1].is_ready()); + boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(v.begin(), v.end()); + BOOST_TEST(! v[0].valid()); + BOOST_TEST(! v[1].valid()); + BOOST_TEST(all.valid()); + if (0) // todo FAILS not yet implemented + BOOST_TEST(all.is_ready()); + boost::csbl::vector<boost::future<int> > res = all.get(); + BOOST_TEST(res[0].valid()); + BOOST_TEST(res[0].is_ready()); + BOOST_TEST(res[0].get() == 123); + BOOST_TEST(res[1].valid()); + BOOST_TEST(res[1].is_ready()); + BOOST_TEST(res[1].get() == 321); + } + { // is_ready shared_future copy-constructible + boost::shared_future<int> f1 = boost::make_ready_future(123).share(); + boost::shared_future<int> f2 = boost::make_ready_future(321).share(); + boost::csbl::vector<boost::shared_future<int> > v; + v.push_back(f1); + v.push_back(f2); + BOOST_TEST(v[0].valid()); + BOOST_TEST(v[0].is_ready()); + BOOST_TEST(v[1].valid()); + BOOST_TEST(v[1].is_ready()); + boost::future<boost::csbl::vector<boost::shared_future<int> > > all = boost::when_all(v.begin(), v.end()); + if (0) // fixme + BOOST_TEST(v[0].valid()); + if (0) // fixme + BOOST_TEST(v[1].valid()); + BOOST_TEST(all.valid()); + if (0) // todo FAILS not yet implemented + BOOST_TEST(all.is_ready()); + boost::csbl::vector<boost::shared_future<int> > res = all.get(); + BOOST_TEST(res[0].valid()); + BOOST_TEST(res[0].is_ready()); + BOOST_TEST(res[0].get() == 123); + BOOST_TEST(res[1].valid()); + BOOST_TEST(res[1].is_ready()); + BOOST_TEST(res[1].get() == 321); + } + { // packaged_task future copy-constructible + boost::packaged_task<int()> pt1(&p1); + boost::future<int> f1 = pt1.get_future(); + BOOST_TEST(f1.valid()); + boost::packaged_task<int()> pt2(&p2); + boost::future<int> f2 = pt2.get_future(); + BOOST_TEST(f2.valid()); + boost::csbl::vector<boost::future<int> > v; + v.push_back(boost::move(f1)); + v.push_back(boost::move(f2)); + BOOST_TEST(v[0].valid()); + BOOST_TEST(v[1].valid()); + boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(v.begin(), v.end()); + BOOST_TEST(! v[0].valid()); + BOOST_TEST(! v[1].valid()); + BOOST_TEST(all.valid()); + pt1(); + pt2(); + boost::csbl::vector<boost::future<int> > res = all.get(); + BOOST_TEST(res[0].valid()); + BOOST_TEST(res[0].is_ready()); + BOOST_TEST(res[0].get() == 123); + BOOST_TEST(res[1].valid()); + BOOST_TEST(res[1].is_ready()); + BOOST_TEST(res[1].get() == 321); + } + { // packaged_task future copy-constructible + boost::packaged_task<int()> pt1(&thr); + boost::future<int> f1 = pt1.get_future(); + BOOST_TEST(f1.valid()); + boost::packaged_task<int()> pt2(&p2); + boost::future<int> f2 = pt2.get_future(); + BOOST_TEST(f2.valid()); + boost::csbl::vector<boost::future<int> > v; + v.push_back(boost::move(f1)); + v.push_back(boost::move(f2)); + BOOST_TEST(v[0].valid()); + BOOST_TEST(v[1].valid()); + boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(v.begin(), v.end()); + BOOST_TEST(! v[0].valid()); + BOOST_TEST(! v[1].valid()); + BOOST_TEST(all.valid()); + pt1(); + pt2(); + boost::csbl::vector<boost::future<int> > res = all.get(); + BOOST_TEST(res[0].valid()); + BOOST_TEST(res[0].is_ready()); + try { + res[0].get(); + BOOST_TEST(false); + } catch (std::logic_error& ex) { + BOOST_TEST(ex.what() == std::string("123")); + } catch (...) { + BOOST_TEST(false); + } + BOOST_TEST(res[1].valid()); + BOOST_TEST(res[1].is_ready()); + BOOST_TEST(res[1].get() == 321); + } + { // packaged_task shared_future copy-constructible + boost::packaged_task<int()> pt1(&p1); + boost::shared_future<int> f1 = pt1.get_future().share(); + BOOST_TEST(f1.valid()); + boost::packaged_task<int()> pt2(&p2); + boost::shared_future<int> f2 = pt2.get_future().share(); + BOOST_TEST(f2.valid()); + boost::csbl::vector<boost::shared_future<int> > v; + v.push_back(f1); + v.push_back(f2); + BOOST_TEST(v[0].valid()); + BOOST_TEST(v[1].valid()); + boost::future<boost::csbl::vector<boost::shared_future<int> > > all = boost::when_all(v.begin(), v.end()); + if (0) // fixme + BOOST_TEST(v[0].valid()); + if (0) // fixme + BOOST_TEST(v[1].valid()); + BOOST_TEST(all.valid()); + BOOST_TEST(! all.is_ready()); + pt1(); + BOOST_TEST(! all.is_ready()); + pt2(); + boost::this_thread::sleep_for(boost::chrono::milliseconds(300)); + BOOST_TEST(all.is_ready()); + boost::csbl::vector<boost::shared_future<int> > res = all.get(); + BOOST_TEST(res[0].valid()); + BOOST_TEST(res[0].is_ready()); + BOOST_TEST(res[0].get() == 123); + BOOST_TEST(res[1].valid()); + BOOST_TEST(res[1].is_ready()); + BOOST_TEST(res[1].get() == 321); + } + { // async future copy-constructible + boost::future<int> f1 = boost::async(boost::launch::async, &p1); + BOOST_TEST(f1.valid()); + boost::future<int> f2 = boost::async(boost::launch::async, &p2); + BOOST_TEST(f2.valid()); + boost::csbl::vector<boost::future<int> > v; + v.push_back(boost::move(f1)); + v.push_back(boost::move(f2)); + BOOST_TEST(v[0].valid()); + BOOST_TEST(v[1].valid()); + boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(v.begin(), v.end()); + BOOST_TEST(! v[0].valid()); + BOOST_TEST(! v[1].valid()); + BOOST_TEST(all.valid()); + boost::csbl::vector<boost::future<int> > res = all.get(); + BOOST_TEST(res[0].valid()); + BOOST_TEST(res[0].is_ready()); + BOOST_TEST(res[0].get() == 123); + BOOST_TEST(res[1].valid()); + BOOST_TEST(res[1].is_ready()); + BOOST_TEST(res[1].get() == 321); + } + { // async shared_future copy-constructible + boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share(); + BOOST_TEST(f1.valid()); + boost::shared_future<int> f2 = boost::async(boost::launch::async, &p2).share(); + BOOST_TEST(f2.valid()); + boost::csbl::vector<boost::shared_future<int> > v; + v.push_back(f1); + v.push_back(f2); + BOOST_TEST(v[0].valid()); + BOOST_TEST(v[1].valid()); + boost::future<boost::csbl::vector<boost::shared_future<int> > > all = boost::when_all(v.begin(), v.end()); + if (0) // fixme + BOOST_TEST(v[0].valid()); + if (0) // fixme + BOOST_TEST(v[1].valid()); + BOOST_TEST(all.valid()); + boost::csbl::vector<boost::shared_future<int> > res = all.get(); + BOOST_TEST(res[0].valid()); + BOOST_TEST(res[0].is_ready()); + BOOST_TEST(res[0].get() == 123); + BOOST_TEST(res[1].valid()); + BOOST_TEST(res[1].is_ready()); + BOOST_TEST(res[1].get() == 321); + } + { // async future copy-constructible + boost::future<int> f1 = boost::async(boost::launch::async, &p1); + BOOST_TEST(f1.valid()); + boost::future<int> f2 = boost::make_ready_future(321); + BOOST_TEST(f2.valid()); + BOOST_TEST(f2.is_ready()); + boost::csbl::vector<boost::future<int> > v; + v.push_back(boost::move(f1)); + v.push_back(boost::move(f2)); + BOOST_TEST(v[0].valid()); + BOOST_TEST(v[1].valid()); + boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(v.begin(), v.end()); + BOOST_TEST(! v[0].valid()); + BOOST_TEST(! v[1].valid()); + BOOST_TEST(all.valid()); + boost::csbl::vector<boost::future<int> > res = all.get(); + BOOST_TEST(res[0].valid()); + BOOST_TEST(res[0].is_ready()); + BOOST_TEST(res[0].get() == 123); + BOOST_TEST(res[1].valid()); + BOOST_TEST(res[1].is_ready()); + BOOST_TEST(res[1].get() == 321); + } +#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD + // fixme darwin-4.8.0_11 terminate called without an active exception + { // deferred future copy-constructible + boost::future<int> f1 = boost::async(boost::launch::deferred, &p1); + boost::future<int> f2 = boost::async(boost::launch::deferred, &p2); + boost::csbl::vector<boost::future<int> > v; + v.push_back(boost::move(f1)); + v.push_back(boost::move(f2)); + BOOST_TEST(v[0].valid()); + BOOST_TEST(v[1].valid()); + boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(v.begin(), v.end()); + BOOST_TEST(! v[0].valid()); + BOOST_TEST(! v[1].valid()); + BOOST_TEST(all.valid()); + boost::csbl::vector<boost::future<int> > res = all.get(); + BOOST_TEST(res[0].valid()); + BOOST_TEST(res[0].is_ready()); + BOOST_TEST(res[0].get() == 123); + BOOST_TEST(res[1].valid()); + BOOST_TEST(res[1].is_ready()); + BOOST_TEST(res[1].get() == 321); + } + // fixme darwin-4.8.0_11 terminate called without an active exception + { // deferred shared_future copy-constructible + boost::shared_future<int> f1 = boost::async(boost::launch::deferred, &p1).share(); + boost::shared_future<int> f2 = boost::async(boost::launch::deferred, &p2).share(); + boost::csbl::vector<boost::shared_future<int> > v; + v.push_back(f1); + v.push_back(f2); + BOOST_TEST(v[0].valid()); + BOOST_TEST(v[1].valid()); + boost::future<boost::csbl::vector<boost::shared_future<int> > > all = boost::when_all(v.begin(), v.end()); + if (0) // fixme + BOOST_TEST(v[0].valid()); + if (0) // fixme + BOOST_TEST(v[1].valid()); + BOOST_TEST(all.valid()); + boost::csbl::vector<boost::shared_future<int> > res = all.get(); + BOOST_TEST(res[0].valid()); + BOOST_TEST(res[0].is_ready()); + BOOST_TEST(res[0].get() == 123); + BOOST_TEST(res[1].valid()); + BOOST_TEST(res[1].is_ready()); + BOOST_TEST(res[1].get() == 321); + } +#endif +#if ! defined BOOST_NO_CXX11_LAMBDAS + { // async futures copy-constructible then() + boost::future<int> f1 = boost::async(boost::launch::async, &p1); + BOOST_TEST(f1.valid()); + boost::future<int> f2 = boost::async(boost::launch::async, &p2); + BOOST_TEST(f2.valid()); + boost::csbl::vector<boost::future<int> > v; + v.push_back(boost::move(f1)); + v.push_back(boost::move(f2)); + BOOST_TEST(v[0].valid()); + BOOST_TEST(v[1].valid()); + boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_all(v.begin(), v.end()); + BOOST_TEST(! v[0].valid()); + BOOST_TEST(! v[1].valid()); + BOOST_TEST(all.valid()); + boost::future<int> sum = all.then([](boost::future<boost::csbl::vector<boost::future<int> > > f) + { + boost::csbl::vector<boost::future<int> > v = f.get(); + return v[0].get() + v[1].get(); + }); + BOOST_TEST(sum.valid()); + BOOST_TEST(sum.get() == 444); + } +#endif +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/when_all/none_pass.cpp b/src/boost/libs/thread/test/sync/futures/when_all/none_pass.cpp new file mode 100644 index 000000000..613e2368d --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/when_all/none_pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2014 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// future<tuple<>> when_all(); + +#include <boost/config.hpp> + +#if ! defined BOOST_NO_CXX11_DECLTYPE +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif + + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ +#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY + + { + boost::future<boost::csbl::tuple<> > all = boost::when_all(); + BOOST_TEST(all.valid()); + BOOST_TEST(all.is_ready()); + } +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/when_all/one_pass.cpp b/src/boost/libs/thread/test/sync/futures/when_all/one_pass.cpp new file mode 100644 index 000000000..026abcf53 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/when_all/one_pass.cpp @@ -0,0 +1,186 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2014 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// template <class T, class Ts> +// future<tuple<T>> when_all(T&&); + +#include <boost/config.hpp> + +#if ! defined BOOST_NO_CXX11_DECLTYPE +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif + + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <stdexcept> + +#ifdef BOOST_MSVC +#pragma warning(disable: 4127) // conditional expression is constant +#endif + +int p1() +{ + return 123; +} + +int thr() +{ + throw std::logic_error("123"); +} + +int main() +{ +#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY + if (0) // todo not yet implemented + { // invalid future copy-constructible + boost::future<int> f1; + BOOST_TEST(! f1.valid()); + boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + // has exception + //BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + } + { // is_ready future copy-constructible + boost::future<int> f1 = boost::make_ready_future(123); + BOOST_TEST(f1.valid()); + BOOST_TEST(f1.is_ready()); + boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(all.valid()); + if (0) // todo FAILS not yet implemented + BOOST_TEST(all.is_ready()); + boost::csbl::tuple<boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + } + { // is_ready shared_future copy-constructible + boost::shared_future<int> f1 = boost::make_ready_future(123).share(); + BOOST_TEST(f1.valid()); + BOOST_TEST(f1.is_ready()); + boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_all(f1); + BOOST_TEST(f1.valid()); + BOOST_TEST(all.valid()); + if (0) // todo FAILS not yet implemented + BOOST_TEST(all.is_ready()); + boost::csbl::tuple<boost::shared_future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + } + { // packaged_task future copy-constructible + boost::packaged_task<int()> pt1(&p1); + boost::future<int> f1 = pt1.get_future(); + BOOST_TEST(f1.valid()); + boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(all.valid()); + pt1(); + boost::csbl::tuple<boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + } + { // packaged_task shared_future copy-constructible + boost::packaged_task<int()> pt1(&p1); + boost::shared_future<int> f1 = pt1.get_future().share(); + BOOST_TEST(f1.valid()); + boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_all(f1); + BOOST_TEST(f1.valid()); + BOOST_TEST(all.valid()); + pt1(); + boost::csbl::tuple<boost::shared_future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + } + { // packaged_task future copy-constructible + boost::packaged_task<int()> pt1(&thr); + boost::future<int> f1 = pt1.get_future(); + BOOST_TEST(f1.valid()); + boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(all.valid()); + pt1(); + boost::csbl::tuple<boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + try { + boost::csbl::get<0>(res).get(); + BOOST_TEST(false); + } catch (std::logic_error& ex) { + BOOST_TEST(ex.what() == std::string("123")); + } catch (...) { + BOOST_TEST(false); + } + } + { // async future copy-constructible + boost::future<int> f1 = boost::async(boost::launch::async, &p1); + BOOST_TEST(f1.valid()); + boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + } + { // async shared_future copy-constructible + boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share(); + BOOST_TEST(f1.valid()); + boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_all(f1); + BOOST_TEST(f1.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::shared_future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + } +#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD + // fixme darwin-4.8.0_11 terminate called without an active exception + { // deferred future copy-constructible + boost::future<int> f1 = boost::async(boost::launch::deferred, &p1); + boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_all(boost::move(f1)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + } + // fixme darwin-4.8.0_11 terminate called without an active exception + { // deferred shared_future copy-constructible + boost::shared_future<int> f1 = boost::async(boost::launch::deferred, &p1).share(); + boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_all(f1); + BOOST_TEST(f1.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::shared_future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + } +#endif +#endif + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/when_all/variadic_pass.cpp b/src/boost/libs/thread/test/sync/futures/when_all/variadic_pass.cpp new file mode 100644 index 000000000..f3b93b8be --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/when_all/variadic_pass.cpp @@ -0,0 +1,300 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2014 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// template <class T, class Ts> +// future<tuple<T, Ts...>> when_all(T&&, Ts&& ...); + +#include <boost/config.hpp> + +#if ! defined BOOST_NO_CXX11_DECLTYPE +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif + + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <stdexcept> + +#ifdef BOOST_MSVC +#pragma warning(disable: 4127) // conditional expression is constant +#endif + +int p1() +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(100)); + return 123; +} + +int thr() +{ + throw std::logic_error("123"); +} +int p2() +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(200)); + return 321; +} + +int main() +{ +#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY + if (0) // todo not yet implemented + { // invalid future copy-constructible + boost::future<int> f1; + boost::future<int> f2 = boost::make_ready_future(321); + BOOST_TEST(! f1.valid()); + BOOST_TEST(f2.valid()); + boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(! f2.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + // has exception + //BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + BOOST_TEST(boost::csbl::get<1>(res).valid()); + BOOST_TEST(boost::csbl::get<1>(res).is_ready()); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } + { // is_ready future copy-constructible + boost::future<int> f1 = boost::make_ready_future(123); + boost::future<int> f2 = boost::make_ready_future(321); + BOOST_TEST(f1.valid()); + BOOST_TEST(f1.is_ready()); + BOOST_TEST(f2.valid()); + BOOST_TEST(f2.is_ready()); + boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(! f2.valid()); + BOOST_TEST(all.valid()); + if (0) // todo FAILS not yet implemented + BOOST_TEST(all.is_ready()); + boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + BOOST_TEST(boost::csbl::get<1>(res).valid()); + BOOST_TEST(boost::csbl::get<1>(res).is_ready()); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } + { // is_ready shared_future copy-constructible + boost::shared_future<int> f1 = boost::make_ready_future(123).share(); + boost::shared_future<int> f2 = boost::make_ready_future(321).share(); + BOOST_TEST(f1.valid()); + BOOST_TEST(f1.is_ready()); + BOOST_TEST(f2.valid()); + BOOST_TEST(f2.is_ready()); + boost::future<boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > > all = boost::when_all(f1, f2); + BOOST_TEST(f1.valid()); + BOOST_TEST(f2.valid()); + BOOST_TEST(all.valid()); + if (0) // todo FAILS not yet implemented + BOOST_TEST(all.is_ready()); + boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + BOOST_TEST(boost::csbl::get<1>(res).valid()); + BOOST_TEST(boost::csbl::get<1>(res).is_ready()); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } + { // packaged_task future copy-constructible + boost::packaged_task<int()> pt1(&p1); + boost::future<int> f1 = pt1.get_future(); + BOOST_TEST(f1.valid()); + boost::packaged_task<int()> pt2(&p2); + boost::future<int> f2 = pt2.get_future(); + BOOST_TEST(f2.valid()); + boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(! f2.valid()); + BOOST_TEST(all.valid()); + pt1(); + pt2(); + boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + BOOST_TEST(boost::csbl::get<1>(res).valid()); + BOOST_TEST(boost::csbl::get<1>(res).is_ready()); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } + { // packaged_task future copy-constructible + boost::packaged_task<int()> pt1(&thr); + boost::future<int> f1 = pt1.get_future(); + BOOST_TEST(f1.valid()); + boost::packaged_task<int()> pt2(&p2); + boost::future<int> f2 = pt2.get_future(); + BOOST_TEST(f2.valid()); + boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(! f2.valid()); + BOOST_TEST(all.valid()); + pt1(); + pt2(); + boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + try { + boost::csbl::get<0>(res).get(); + BOOST_TEST(false); + } catch (std::logic_error& ex) { + BOOST_TEST(ex.what() == std::string("123")); + } catch (...) { + BOOST_TEST(false); + } + BOOST_TEST(boost::csbl::get<1>(res).valid()); + BOOST_TEST(boost::csbl::get<1>(res).is_ready()); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } + { // packaged_task shared_future copy-constructible + boost::packaged_task<int()> pt1(&p1); + boost::shared_future<int> f1 = pt1.get_future().share(); + BOOST_TEST(f1.valid()); + boost::packaged_task<int()> pt2(&p2); + boost::shared_future<int> f2 = pt2.get_future().share(); + BOOST_TEST(f2.valid()); + boost::future<boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > > all = boost::when_all(f1, f2); + BOOST_TEST(f1.valid()); + BOOST_TEST(f2.valid()); + BOOST_TEST(all.valid()); + BOOST_TEST(! all.is_ready()); + pt1(); + BOOST_TEST(! all.is_ready()); + pt2(); + boost::this_thread::sleep_for(boost::chrono::milliseconds(300)); + BOOST_TEST(all.is_ready()); + boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + BOOST_TEST(boost::csbl::get<1>(res).valid()); + BOOST_TEST(boost::csbl::get<1>(res).is_ready()); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } + { // async future copy-constructible + boost::future<int> f1 = boost::async(boost::launch::async, &p1); + BOOST_TEST(f1.valid()); + boost::future<int> f2 = boost::async(boost::launch::async, &p2); + BOOST_TEST(f2.valid()); + boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(! f2.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + BOOST_TEST(boost::csbl::get<1>(res).valid()); + BOOST_TEST(boost::csbl::get<1>(res).is_ready()); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } + { // async shared_future copy-constructible + boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share(); + BOOST_TEST(f1.valid()); + boost::shared_future<int> f2 = boost::async(boost::launch::async, &p2).share(); + BOOST_TEST(f2.valid()); + boost::future<boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > > all = boost::when_all(f1, f2); + BOOST_TEST(f1.valid()); + BOOST_TEST(f2.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + BOOST_TEST(boost::csbl::get<1>(res).valid()); + BOOST_TEST(boost::csbl::get<1>(res).is_ready()); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } + { // async future copy-constructible + boost::future<int> f1 = boost::async(boost::launch::async, &p1); + BOOST_TEST(f1.valid()); + boost::future<int> f2 = boost::make_ready_future(321); + BOOST_TEST(f2.valid()); + BOOST_TEST(f2.is_ready()); + boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(! f2.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + BOOST_TEST(boost::csbl::get<1>(res).valid()); + BOOST_TEST(boost::csbl::get<1>(res).is_ready()); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } +#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD + // fixme darwin-4.8.0_11 terminate called without an active exception + { // deferred future copy-constructible + boost::future<int> f1 = boost::async(boost::launch::deferred, &p1); + boost::future<int> f2 = boost::async(boost::launch::deferred, &p2); + boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(! f2.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<1>(res).valid()); + BOOST_TEST(boost::csbl::get<1>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } + // fixme darwin-4.8.0_11 terminate called without an active exception + { // deferred shared_future copy-constructible + boost::shared_future<int> f1 = boost::async(boost::launch::deferred, &p1).share(); + boost::shared_future<int> f2 = boost::async(boost::launch::deferred, &p2).share(); + boost::future<boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > > all = boost::when_all(f1, f2); + BOOST_TEST(f1.valid()); + BOOST_TEST(f2.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<1>(res).valid()); + BOOST_TEST(boost::csbl::get<1>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } +#endif +#if ! defined BOOST_NO_CXX11_LAMBDAS + { // async futures copy-constructible then() + boost::future<int> f1 = boost::async(boost::launch::async, &p1); + BOOST_TEST(f1.valid()); + boost::future<int> f2 = boost::async(boost::launch::async, &p2); + BOOST_TEST(f2.valid()); + boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_all(boost::move(f1), boost::move(f2)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(! f2.valid()); + BOOST_TEST(all.valid()); + boost::future<int> sum = all.then([](boost::future<boost::csbl::tuple<boost::future<int>, boost::future<int> > > f) + { + boost::csbl::tuple<boost::future<int>,boost::future<int> > v = f.get(); + return boost::csbl::get<0>(v).get()+boost::csbl::get<1>(v).get(); + }); + BOOST_TEST(sum.valid()); + BOOST_TEST(sum.get() == 444); + } +#endif +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/when_any/iterators_pass.cpp b/src/boost/libs/thread/test/sync/futures/when_any/iterators_pass.cpp new file mode 100644 index 000000000..03336d022 --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/when_any/iterators_pass.cpp @@ -0,0 +1,363 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2014 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// template< typename InputIterator> +// future<vector<typename InputIterator::value_type> > +// when_any(InputIterator first, InputIterator last) + +#include <boost/config.hpp> + +#if ! defined BOOST_NO_CXX11_DECLTYPE +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif + + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <stdexcept> + +#ifdef BOOST_MSVC +#pragma warning(disable: 4127) // conditional expression is constant +#endif + +int p1() +{ + return 123; +} + +int thr() +{ + throw std::logic_error("123"); +} +int p2() +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(200)); + return 321; +} + +int main() +{ +#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY + if (0) // todo not yet implemented + { // invalid future copy-constructible + boost::csbl::vector<boost::future<int> > v; + boost::future<int> f1; + v.push_back(boost::move(f1)); + v.push_back(boost::make_ready_future(321)); + BOOST_TEST(! v[0].valid()); + BOOST_TEST(v[1].valid()); + + boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_any(v.begin(), v.end()); + BOOST_TEST(! v[0].valid()); + BOOST_TEST(! v[1].valid()); + BOOST_TEST(all.valid()); + boost::csbl::vector<boost::future<int> > res = all.get(); + BOOST_TEST(res.size() == 2); + BOOST_TEST(res[1].valid()); + BOOST_TEST(res[1].is_ready()); + // has exception + //BOOST_TEST(res[0].get() == 123); + BOOST_TEST(res[1].valid()); + BOOST_TEST(res[1].is_ready()); + BOOST_TEST(res[1].get() == 321); + } + { // is_ready future copy-constructible + boost::future<int> f1 = boost::make_ready_future(123); + boost::future<int> f2 = boost::make_ready_future(321); + boost::csbl::vector<boost::future<int> > v; + v.push_back(boost::move(f1)); + v.push_back(boost::move(f2)); + BOOST_TEST(v[0].valid()); + BOOST_TEST(v[0].is_ready()); + BOOST_TEST(v[1].valid()); + BOOST_TEST(v[1].is_ready()); + boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_any(v.begin(), v.end()); + BOOST_TEST(! v[0].valid()); + BOOST_TEST(! v[1].valid()); + BOOST_TEST(all.valid()); + if (0) // todo FAILS not yet implemented + BOOST_TEST(all.is_ready()); + boost::csbl::vector<boost::future<int> > res = all.get(); + BOOST_TEST(res[0].valid()); + BOOST_TEST(res[0].is_ready()); + BOOST_TEST(res[0].get() == 123); + BOOST_TEST(res[1].valid()); + BOOST_TEST(res[1].is_ready()); + BOOST_TEST(res[1].get() == 321); + } + { // is_ready shared_future copy-constructible + boost::shared_future<int> f1 = boost::make_ready_future(123).share(); + boost::shared_future<int> f2 = boost::make_ready_future(321).share(); + boost::csbl::vector<boost::shared_future<int> > v; + v.push_back(f1); + v.push_back(f2); + BOOST_TEST(v[0].valid()); + BOOST_TEST(v[0].is_ready()); + BOOST_TEST(v[1].valid()); + BOOST_TEST(v[1].is_ready()); + boost::future<boost::csbl::vector<boost::shared_future<int> > > all = boost::when_any(v.begin(), v.end()); + if (0) // fixme + BOOST_TEST(v[0].valid()); + if (0) // fixme + BOOST_TEST(v[1].valid()); + BOOST_TEST(all.valid()); + if (0) // todo FAILS not yet implemented + BOOST_TEST(all.is_ready()); + boost::csbl::vector<boost::shared_future<int> > res = all.get(); + BOOST_TEST(res[0].valid()); + BOOST_TEST(res[0].is_ready()); + BOOST_TEST(res[0].get() == 123); + BOOST_TEST(res[1].valid()); + BOOST_TEST(res[1].is_ready()); + BOOST_TEST(res[1].get() == 321); + } + { // packaged_task future copy-constructible + boost::packaged_task<int()> pt1(&p1); + boost::future<int> f1 = pt1.get_future(); + BOOST_TEST(f1.valid()); + boost::packaged_task<int()> pt2(&p2); + boost::future<int> f2 = pt2.get_future(); + BOOST_TEST(f2.valid()); + boost::csbl::vector<boost::future<int> > v; + v.push_back(boost::move(f1)); + v.push_back(boost::move(f2)); + BOOST_TEST(v[0].valid()); + BOOST_TEST(v[1].valid()); + boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_any(v.begin(), v.end()); + BOOST_TEST(! v[0].valid()); + BOOST_TEST(! v[1].valid()); + BOOST_TEST(all.valid()); + pt1(); + pt2(); + boost::csbl::vector<boost::future<int> > res = all.get(); + BOOST_TEST(res[0].valid()); + BOOST_TEST(res[0].is_ready()); + BOOST_TEST(res[0].get() == 123); + BOOST_TEST(res[1].valid()); + BOOST_TEST(res[1].is_ready()); + BOOST_TEST(res[1].get() == 321); + } + { // packaged_task future copy-constructible + boost::packaged_task<int()> pt1(&thr); + boost::future<int> f1 = pt1.get_future(); + BOOST_TEST(f1.valid()); + boost::packaged_task<int()> pt2(&p2); + boost::future<int> f2 = pt2.get_future(); + BOOST_TEST(f2.valid()); + boost::csbl::vector<boost::future<int> > v; + v.push_back(boost::move(f1)); + v.push_back(boost::move(f2)); + BOOST_TEST(v[0].valid()); + BOOST_TEST(v[1].valid()); + boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_any(v.begin(), v.end()); + BOOST_TEST(! v[0].valid()); + BOOST_TEST(! v[1].valid()); + BOOST_TEST(all.valid()); + pt1(); + pt2(); + boost::csbl::vector<boost::future<int> > res = all.get(); + BOOST_TEST(res[0].valid()); + BOOST_TEST(res[0].is_ready()); + try { + res[0].get(); + BOOST_TEST(false); + } catch (std::logic_error& ex) { + BOOST_TEST(ex.what() == std::string("123")); + } catch (...) { + BOOST_TEST(false); + } + BOOST_TEST(res[1].valid()); + BOOST_TEST(res[1].is_ready()); + BOOST_TEST(res[1].get() == 321); + } + { // packaged_task shared_future copy-constructible + boost::packaged_task<int()> pt1(&p1); + boost::shared_future<int> f1 = pt1.get_future().share(); + BOOST_TEST(f1.valid()); + boost::packaged_task<int()> pt2(&p2); + boost::shared_future<int> f2 = pt2.get_future().share(); + BOOST_TEST(f2.valid()); + boost::csbl::vector<boost::shared_future<int> > v; + v.push_back(f1); + v.push_back(f2); + BOOST_TEST(v[0].valid()); + BOOST_TEST(v[1].valid()); + boost::future<boost::csbl::vector<boost::shared_future<int> > > all = boost::when_any(v.begin(), v.end()); + if (0) // fixme + BOOST_TEST(v[0].valid()); + if (0) // fixme + BOOST_TEST(v[1].valid()); + BOOST_TEST(all.valid()); + BOOST_TEST(! all.is_ready()); + pt1(); + pt2(); + boost::this_thread::sleep_for(boost::chrono::milliseconds(300)); + BOOST_TEST(all.is_ready()); + boost::csbl::vector<boost::shared_future<int> > res = all.get(); + BOOST_TEST(res[0].valid()); + BOOST_TEST(res[0].is_ready()); + BOOST_TEST(res[0].get() == 123); + BOOST_TEST(res[1].valid()); + BOOST_TEST(res[1].is_ready()); + BOOST_TEST(res[1].get() == 321); + } + { // async future copy-constructible + boost::future<int> f1 = boost::async(boost::launch::async, &p1); + BOOST_TEST(f1.valid()); + boost::future<int> f2 = boost::async(boost::launch::async, &p2); + BOOST_TEST(f2.valid()); + boost::csbl::vector<boost::future<int> > v; + v.push_back(boost::move(f1)); + v.push_back(boost::move(f2)); + BOOST_TEST(v[0].valid()); + BOOST_TEST(v[1].valid()); + boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_any(v.begin(), v.end()); + BOOST_TEST(! v[0].valid()); + BOOST_TEST(! v[1].valid()); + BOOST_TEST(all.valid()); + boost::csbl::vector<boost::future<int> > res = all.get(); + BOOST_TEST(res[0].valid()); + BOOST_TEST(res[0].is_ready()); + BOOST_TEST(res[0].get() == 123); + BOOST_TEST(res[1].valid()); + BOOST_TEST(! res[1].is_ready()); + BOOST_TEST(res[1].get() == 321); + } + { // async shared_future copy-constructible + boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share(); + BOOST_TEST(f1.valid()); + boost::shared_future<int> f2 = boost::async(boost::launch::async, &p2).share(); + BOOST_TEST(f2.valid()); + boost::csbl::vector<boost::shared_future<int> > v; + v.push_back(f1); + v.push_back(f2); + BOOST_TEST(v[0].valid()); + BOOST_TEST(v[1].valid()); + boost::future<boost::csbl::vector<boost::shared_future<int> > > all = boost::when_any(v.begin(), v.end()); + if (0) // fixme + BOOST_TEST(v[0].valid()); + if (0) // fixme + BOOST_TEST(v[1].valid()); + BOOST_TEST(all.valid()); + boost::csbl::vector<boost::shared_future<int> > res = all.get(); + BOOST_TEST(res[0].valid()); + BOOST_TEST(res[0].is_ready()); + BOOST_TEST(res[0].get() == 123); + BOOST_TEST(res[1].valid()); + BOOST_TEST(! res[1].is_ready()); + BOOST_TEST(res[1].get() == 321); + } + { // async future copy-constructible + boost::future<int> f1 = boost::async(boost::launch::async, &p1); + BOOST_TEST(f1.valid()); + boost::future<int> f2 = boost::make_ready_future(321); + BOOST_TEST(f2.valid()); + BOOST_TEST(f2.is_ready()); + boost::csbl::vector<boost::future<int> > v; + v.push_back(boost::move(f1)); + v.push_back(boost::move(f2)); + BOOST_TEST(v[0].valid()); + BOOST_TEST(v[1].valid()); + boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_any(v.begin(), v.end()); + BOOST_TEST(! v[0].valid()); + BOOST_TEST(! v[1].valid()); + BOOST_TEST(all.valid()); + boost::csbl::vector<boost::future<int> > res = all.get(); + BOOST_TEST(res[0].valid()); + if (0) // fixme + BOOST_TEST(! res[0].is_ready()); + BOOST_TEST(res[0].get() == 123); + BOOST_TEST(res[1].valid()); + BOOST_TEST(res[1].is_ready()); + BOOST_TEST(res[1].get() == 321); + } +#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD + // fixme darwin-4.8.0_11 terminate called without an active exception + { // deferred future copy-constructible + boost::future<int> f1 = boost::async(boost::launch::deferred, &p1); + boost::future<int> f2 = boost::async(boost::launch::deferred, &p2); + boost::csbl::vector<boost::future<int> > v; + v.push_back(boost::move(f1)); + v.push_back(boost::move(f2)); + BOOST_TEST(v[0].valid()); + BOOST_TEST(v[1].valid()); + boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_any(v.begin(), v.end()); + BOOST_TEST(! v[0].valid()); + BOOST_TEST(! v[1].valid()); + BOOST_TEST(all.valid()); + boost::csbl::vector<boost::future<int> > res = all.get(); + BOOST_TEST(res[0].valid()); + BOOST_TEST(res[0].is_ready()); + BOOST_TEST(res[0].get() == 123); + BOOST_TEST(res[1].valid()); + BOOST_TEST(! res[1].is_ready()); + BOOST_TEST(res[1].get() == 321); + } + // fixme darwin-4.8.0_11 terminate called without an active exception + { // deferred shared_future copy-constructible + boost::shared_future<int> f1 = boost::async(boost::launch::deferred, &p1).share(); + boost::shared_future<int> f2 = boost::async(boost::launch::deferred, &p2).share(); + boost::csbl::vector<boost::shared_future<int> > v; + v.push_back(f1); + v.push_back(f2); + BOOST_TEST(v[0].valid()); + BOOST_TEST(v[1].valid()); + boost::future<boost::csbl::vector<boost::shared_future<int> > > all = boost::when_any(v.begin(), v.end()); + if (0) // fixme + BOOST_TEST(v[0].valid()); + if (0) // fixme + BOOST_TEST(v[1].valid()); + BOOST_TEST(all.valid()); + boost::csbl::vector<boost::shared_future<int> > res = all.get(); + BOOST_TEST(res[0].valid()); + BOOST_TEST(res[0].is_ready()); + BOOST_TEST(res[0].get() == 123); + BOOST_TEST(res[1].valid()); + BOOST_TEST(! res[1].is_ready()); + BOOST_TEST(res[1].get() == 321); + } +#endif +#if ! defined BOOST_NO_CXX11_LAMBDAS + { // async futures copy-constructible then() + boost::future<int> f1 = boost::async(boost::launch::async, &p1); + BOOST_TEST(f1.valid()); + boost::future<int> f2 = boost::async(boost::launch::async, &p2); + BOOST_TEST(f2.valid()); + boost::csbl::vector<boost::future<int> > v; + v.push_back(boost::move(f1)); + v.push_back(boost::move(f2)); + BOOST_TEST(v[0].valid()); + BOOST_TEST(v[1].valid()); + boost::future<boost::csbl::vector<boost::future<int> > > all = boost::when_any(v.begin(), v.end()); + BOOST_TEST(! v[0].valid()); + BOOST_TEST(! v[1].valid()); + BOOST_TEST(all.valid()); + boost::future<int> sum = all.then([](boost::future<boost::csbl::vector<boost::future<int> > > f) + { + boost::csbl::vector<boost::future<int> > v = f.get(); + return v[0].get() + v[1].get(); + }); + BOOST_TEST(sum.valid()); + BOOST_TEST(sum.get() == 444); + } +#endif +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/when_any/none_pass.cpp b/src/boost/libs/thread/test/sync/futures/when_any/none_pass.cpp new file mode 100644 index 000000000..2edd0bc6d --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/when_any/none_pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2014 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// future<tuple<>> when_any(); + +#include <boost/config.hpp> + +#if ! defined BOOST_NO_CXX11_DECLTYPE +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif + + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ +#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY + + { + boost::future<boost::csbl::tuple<> > all = boost::when_any(); + BOOST_TEST(all.valid()); + BOOST_TEST(all.is_ready()); + } +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/when_any/one_pass.cpp b/src/boost/libs/thread/test/sync/futures/when_any/one_pass.cpp new file mode 100644 index 000000000..61882ef6d --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/when_any/one_pass.cpp @@ -0,0 +1,159 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2014 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// future<tuple<T>> when_any(T&&); + +#include <boost/config.hpp> + +#if ! defined BOOST_NO_CXX11_DECLTYPE +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif + + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> + +#ifdef BOOST_MSVC +#pragma warning(disable: 4127) // conditional expression is constant +#endif + +int p1() +{ + return 123; +} + +int main() +{ +#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY + if (0) // todo not yet implemented + { // invalid future copy-constructible + boost::future<int> f1; + BOOST_TEST(! f1.valid()); + boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_any(boost::move(f1)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + // has exception + //BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + } + { // is_ready future copy-constructible + boost::future<int> f1 = boost::make_ready_future(123); + BOOST_TEST(f1.valid()); + BOOST_TEST(f1.is_ready()); + boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_any(boost::move(f1)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(all.valid()); + if (0) // todo FAILS not yet implemented + BOOST_TEST(all.is_ready()); + boost::csbl::tuple<boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + } + { // is_ready shared_future copy-constructible + boost::shared_future<int> f1 = boost::make_ready_future(123).share(); + BOOST_TEST(f1.valid()); + BOOST_TEST(f1.is_ready()); + boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_any(f1); + BOOST_TEST(f1.valid()); + BOOST_TEST(all.valid()); + if (0) // todo FAILS not yet implemented + BOOST_TEST(all.is_ready()); + boost::csbl::tuple<boost::shared_future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + } + { // packaged_task future copy-constructible + boost::packaged_task<int()> pt1(&p1); + boost::future<int> f1 = pt1.get_future(); + BOOST_TEST(f1.valid()); + boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_any(boost::move(f1)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(all.valid()); + pt1(); + boost::csbl::tuple<boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + } + { // packaged_task shared_future copy-constructible + boost::packaged_task<int()> pt1(&p1); + boost::shared_future<int> f1 = pt1.get_future().share(); + BOOST_TEST(f1.valid()); + boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_any(f1); + BOOST_TEST(f1.valid()); + BOOST_TEST(all.valid()); + pt1(); + boost::csbl::tuple<boost::shared_future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + } + { // async future copy-constructible + boost::future<int> f1 = boost::async(boost::launch::async, &p1); + BOOST_TEST(f1.valid()); + boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_any(boost::move(f1)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + } + { // async shared_future copy-constructible + boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share(); + BOOST_TEST(f1.valid()); + boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_any(f1); + BOOST_TEST(f1.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::shared_future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + } +#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD + // fixme darwin-4.8.0_11 terminate called without an active exception + { // deferred future copy-constructible + boost::future<int> f1 = boost::async(boost::launch::deferred, &p1); + boost::future<boost::csbl::tuple<boost::future<int> > > all = boost::when_any(boost::move(f1)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + } + // fixme darwin-4.8.0_11 terminate called without an active exception + { // deferred shared_future copy-constructible + boost::shared_future<int> f1 = boost::async(boost::launch::deferred, &p1).share(); + boost::future<boost::csbl::tuple<boost::shared_future<int> > > all = boost::when_any(f1); + BOOST_TEST(f1.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::shared_future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + } +#endif +#endif + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/futures/when_any/variadic_pass.cpp b/src/boost/libs/thread/test/sync/futures/when_any/variadic_pass.cpp new file mode 100644 index 000000000..09b3951fc --- /dev/null +++ b/src/boost/libs/thread/test/sync/futures/when_any/variadic_pass.cpp @@ -0,0 +1,323 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2014 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/future.hpp> + +// template <class T, class Ts> +// future<tuple<T, Ts...>> when_any(T&&, Ts&& ...); + +#include <boost/config.hpp> + +#if ! defined BOOST_NO_CXX11_DECLTYPE +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/future.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <stdexcept> + +#ifdef BOOST_MSVC +#pragma warning(disable: 4127) // conditional expression is constant +#endif + +int p1() +{ + return 123; +} + +int thr() +{ + throw std::logic_error("123"); +} +int p2() +{ + boost::this_thread::sleep_for(boost::chrono::milliseconds(200)); + return 321; +} + +int main() +{ +#if defined BOOST_THREAD_PROVIDES_FUTURE_WHEN_ALL_WHEN_ANY + if (0) // todo not yet implemented + { // invalid future copy-constructible + boost::future<int> f1; + boost::future<int> f2 = boost::make_ready_future(321); + BOOST_TEST(! f1.valid()); + BOOST_TEST(f2.valid()); + boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(! f2.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<1>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready() || boost::csbl::get<1>(res).is_ready()); + // has exception + //BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } + { // is_ready future copy-constructible + boost::future<int> f1 = boost::make_ready_future(123); + boost::future<int> f2 = boost::make_ready_future(321); + BOOST_TEST(f1.valid()); + BOOST_TEST(f1.is_ready()); + BOOST_TEST(f2.valid()); + BOOST_TEST(f2.is_ready()); + boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(! f2.valid()); + BOOST_TEST(all.valid()); + if (0) // todo FAILS not yet implemented + BOOST_TEST(all.is_ready()); + boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<1>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready() || boost::csbl::get<1>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } + { // is_ready shared_future copy-constructible + boost::shared_future<int> f1 = boost::make_ready_future(123).share(); + boost::shared_future<int> f2 = boost::make_ready_future(321).share(); + BOOST_TEST(f1.valid()); + BOOST_TEST(f1.is_ready()); + BOOST_TEST(f2.valid()); + BOOST_TEST(f2.is_ready()); + boost::future<boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > > all = boost::when_any(f1, f2); + BOOST_TEST(f1.valid()); + BOOST_TEST(f2.valid()); + BOOST_TEST(all.valid()); + if (0) // todo FAILS not yet implemented + BOOST_TEST(all.is_ready()); + boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<1>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready() || boost::csbl::get<1>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } + { // packaged_task future copy-constructible + boost::packaged_task<int()> pt1(&p1); + boost::future<int> f1 = pt1.get_future(); + BOOST_TEST(f1.valid()); + boost::packaged_task<int()> pt2(&p2); + boost::future<int> f2 = pt2.get_future(); + BOOST_TEST(f2.valid()); + boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(! f2.valid()); + BOOST_TEST(all.valid()); + pt1(); + pt2(); + boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<1>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready() || boost::csbl::get<1>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } + { // packaged_task future copy-constructible + boost::packaged_task<int()> pt1(&thr); + boost::future<int> f1 = pt1.get_future(); + BOOST_TEST(f1.valid()); + boost::packaged_task<int()> pt2(&p2); + boost::future<int> f2 = pt2.get_future(); + BOOST_TEST(f2.valid()); + boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(! f2.valid()); + BOOST_TEST(all.valid()); + pt1(); + pt2(); + boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<1>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready() || boost::csbl::get<1>(res).is_ready()); + try { + boost::csbl::get<0>(res).get(); + BOOST_TEST(false); + } catch (std::logic_error& ex) { + BOOST_TEST(ex.what() == std::string("123")); + } catch (...) { + BOOST_TEST(false); + } + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } + { // packaged_task shared_future copy-constructible + boost::packaged_task<int()> pt1(&p1); + boost::shared_future<int> f1 = pt1.get_future().share(); + BOOST_TEST(f1.valid()); + boost::packaged_task<int()> pt2(&p2); + boost::shared_future<int> f2 = pt2.get_future().share(); + BOOST_TEST(f2.valid()); + boost::future<boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > > all = boost::when_any(f1, f2); + BOOST_TEST(f1.valid()); + BOOST_TEST(f2.valid()); + BOOST_TEST(all.valid()); + BOOST_TEST(! all.is_ready()); + pt1(); + pt2(); + boost::this_thread::sleep_for(boost::chrono::milliseconds(300)); + BOOST_TEST(all.is_ready()); + boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<1>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready() || boost::csbl::get<1>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } + { // async future copy-constructible + boost::future<int> f1 = boost::async(boost::launch::async, &p1); + BOOST_TEST(f1.valid()); + boost::future<int> f2 = boost::async(boost::launch::async, &p2); + BOOST_TEST(f2.valid()); + boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(! f2.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready() || boost::csbl::get<1>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } + { // async shared_future copy-constructible + boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share(); + BOOST_TEST(f1.valid()); + boost::shared_future<int> f2 = boost::async(boost::launch::async, &p2).share(); + BOOST_TEST(f2.valid()); + boost::future<boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > > all = boost::when_any(f1, f2); + BOOST_TEST(f1.valid()); + BOOST_TEST(f2.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<1>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready() || boost::csbl::get<1>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } + { // async future copy-constructible + boost::future<int> f1 = boost::async(boost::launch::async, &p1); + BOOST_TEST(f1.valid()); + boost::future<int> f2 = boost::make_ready_future(321); + BOOST_TEST(f2.valid()); + BOOST_TEST(f2.is_ready()); + boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(! f2.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + //BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<1>(res).valid()); + BOOST_TEST(boost::csbl::get<1>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } +#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD + // fixme darwin-4.8.0_11 terminate called without an active exception + { // deferred future copy-constructible + boost::future<int> f1 = boost::async(boost::launch::deferred, &p1); + boost::future<int> f2 = boost::async(boost::launch::deferred, &p2); + std::cout << __FILE__ << " " << __LINE__ << std::endl; + + boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2)); + std::cout << __FILE__ << " " << __LINE__ << std::endl; + BOOST_TEST(! f1.valid()); + BOOST_TEST(! f2.valid()); + BOOST_TEST(all.valid()); + std::cout << __FILE__ << " " << __LINE__ << std::endl; + boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get(); + std::cout << __FILE__ << " " << __LINE__ << std::endl; + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<1>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready() || boost::csbl::get<1>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } + // fixme darwin-4.8.0_11 terminate called without an active exception + { // deferred future copy-constructible + boost::future<int> f1 = boost::async(boost::launch::deferred, &p1); + boost::future<int> f2 = boost::async(boost::launch::async, &p2); + boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(! f2.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + BOOST_TEST(boost::csbl::get<1>(res).valid()); + //BOOST_TEST(! boost::csbl::get<1>(res).is_ready()); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } + // fixme darwin-4.8.0_11 terminate called without an active exception + { // deferred future copy-constructible + boost::future<int> f1 = boost::async(boost::launch::async, &p1); + boost::future<int> f2 = boost::async(boost::launch::deferred, &p2); + boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(! f2.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::future<int>,boost::future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + //BOOST_TEST(boost::csbl::get<0>(res).is_ready()); + BOOST_TEST(boost::csbl::get<1>(res).valid()); + BOOST_TEST(boost::csbl::get<1>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } + // fixme darwin-4.8.0_11 terminate called without an active exception + { // deferred shared_future copy-constructible + boost::shared_future<int> f1 = boost::async(boost::launch::deferred, &p1).share(); + boost::shared_future<int> f2 = boost::async(boost::launch::deferred, &p2).share(); + boost::future<boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > > all = boost::when_any(f1, f2); + BOOST_TEST(f1.valid()); + BOOST_TEST(f2.valid()); + BOOST_TEST(all.valid()); + boost::csbl::tuple<boost::shared_future<int>,boost::shared_future<int> > res = all.get(); + BOOST_TEST(boost::csbl::get<0>(res).valid()); + BOOST_TEST(boost::csbl::get<1>(res).valid()); + BOOST_TEST(boost::csbl::get<0>(res).is_ready() || boost::csbl::get<1>(res).is_ready()); + BOOST_TEST(boost::csbl::get<0>(res).get() == 123); + BOOST_TEST(boost::csbl::get<1>(res).get() == 321); + } +#endif +#if ! defined BOOST_NO_CXX11_LAMBDAS + { // async futures copy-constructible then() + boost::future<int> f1 = boost::async(boost::launch::async, &p1); + BOOST_TEST(f1.valid()); + boost::future<int> f2 = boost::async(boost::launch::async, &p2); + BOOST_TEST(f2.valid()); + boost::future<boost::csbl::tuple<boost::future<int>,boost::future<int> > > all = boost::when_any(boost::move(f1), boost::move(f2)); + BOOST_TEST(! f1.valid()); + BOOST_TEST(! f2.valid()); + BOOST_TEST(all.valid()); + boost::future<int> sum = all.then([](boost::future<boost::csbl::tuple<boost::future<int>, boost::future<int> > > f) + { + boost::csbl::tuple<boost::future<int>,boost::future<int> > v = f.get(); + return boost::csbl::get<0>(v).get()+boost::csbl::get<1>(v).get(); + }); + BOOST_TEST(sum.valid()); + BOOST_TEST(sum.get() == 444); + } +#endif +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/deque_views/single_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/deque_views/single_thread_pass.cpp new file mode 100644 index 000000000..bd9ff152f --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/deque_views/single_thread_pass.cpp @@ -0,0 +1,468 @@ +// Copyright (C) 2014 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/sync_deque.hpp> + +// class sync_deque<T> + +// sync_deque(); + +#define BOOST_THREAD_VERSION 4 +//#define BOOST_THREAD_QUEUE_DEPRECATE_OLD + +#include <boost/thread/concurrent_queues/sync_deque.hpp> +#include <boost/thread/concurrent_queues/deque_adaptor.hpp> +#include <boost/thread/concurrent_queues/deque_views.hpp> + +#include <boost/detail/lightweight_test.hpp> +#include <boost/static_assert.hpp> + +class non_copyable +{ + int val; +public: + BOOST_THREAD_MOVABLE_ONLY(non_copyable) + non_copyable(int v) : val(v){} + non_copyable(BOOST_RV_REF(non_copyable) x): val(x.val) {} + non_copyable& operator=(BOOST_RV_REF(non_copyable) x) { val=x.val; return *this; } + bool operator==(non_copyable const& x) const {return val==x.val;} + template <typename OSTREAM> + friend OSTREAM& operator <<(OSTREAM& os, non_copyable const&x ) + { + os << x.val; + return os; + } + +}; + +#if defined BOOST_NO_CXX11_RVALUE_REFERENCES +BOOST_STATIC_ASSERT( ! boost::is_copy_constructible<non_copyable>::value ); +BOOST_STATIC_ASSERT( boost::has_move_emulation_enabled<non_copyable>::value ); +#endif + +int main() +{ + + { + // default queue invariants + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_back<int> q(sq); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // default queue invariants + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_front<int> q(sq); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + + + { + // empty queue try_pull fails + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_front<int> q(sq); + int i; + BOOST_TEST( boost::queue_op_status::empty == q.try_pull(i)); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // empty queue push rvalue/copyable succeeds + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_back<int> q(sq); + q.push(1); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue push lvalue/copyable succeeds + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_back<int> q(sq); + int i; + q.push(i); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + + +#if 0 + { + // empty queue push rvalue/non_copyable succeeds + boost::deque_adaptor<boost::sync_deque<non_copyable> > sq; + boost::deque_back<non_copyable> q(sq); + q.push(non_copyable(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900) + { + // empty queue push rvalue/non_copyable succeeds + boost::deque_adaptor<boost::sync_deque<non_copyable> > q; + //boost::sync_deque<non_copyable> q; + //boost::deque_back<non_copyable> q(sq); + non_copyable nc(1); + q.push_back(boost::move(nc)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif + { + // empty queue push rvalue succeeds + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_back<int> q(sq); + q.push(1); + q.push(2); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 2u); + BOOST_TEST(! q.closed()); + } + { + // empty queue push lvalue succeeds + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_back<int> q(sq); + int i; + q.push(i); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue/copyable succeeds + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_back<int> q(sq); + BOOST_TEST(boost::queue_op_status::success == q.try_push(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue/copyable succeeds + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_back<int> q(sq); + BOOST_TEST(boost::queue_op_status::success == q.try_push(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + +#if 0 + { + // empty queue try_push rvalue/non-copyable succeeds + boost::deque_adaptor<boost::sync_deque<non_copyable> > sq; + boost::deque_back<non_copyable> q(sq); + non_copyable nc(1); + BOOST_TEST(boost::queue_op_status::success == q.try_push(boost::move(nc))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif + + { + // empty queue try_push lvalue succeeds + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_back<int> q(sq); + int i=0; + BOOST_TEST(boost::queue_op_status::success == q.try_push(i)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue succeeds + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_back<int> q(sq); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + + +#if 0 + { + // empty queue nonblocking_push_back rvalue/non-copyable succeeds + boost::deque_adaptor<boost::sync_deque<non_copyable> > sq; + boost::deque_back<non_copyable> q(sq); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(non_copyable(1))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900) + { + // empty queue nonblocking_push_back rvalue/non-copyable succeeds + boost::deque_adaptor<boost::sync_deque<non_copyable> > sq; + boost::deque_back<non_copyable> q(sq); + non_copyable nc(1); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(boost::move(nc))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif + { + // 1-element queue pull_front succeed + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_front<int> q(sq); + sq.push_back(1); + int i; + q.pull(i); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900) + { + // 1-element queue pull_front succeed + boost::deque_adaptor<boost::sync_deque<non_copyable> > sq; + boost::deque_front<non_copyable> q(sq); + non_copyable nc1(1); + sq.push_back(boost::move(nc1)); + non_copyable nc2(2); + q.pull(nc2); + BOOST_TEST_EQ(nc1, nc2); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#endif + { + // 1-element queue pull_front succeed + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_front<int> q(sq); + sq.push_back(1); + int i = q.pull(); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900) + { + // 1-element queue pull_front succeed + boost::deque_adaptor<boost::sync_deque<non_copyable> > sq; + boost::deque_front<non_copyable> q(sq); + non_copyable nc1(1); + sq.push_back(boost::move(nc1)); + non_copyable nc = q.pull(); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#endif + { + // 1-element queue try_pull_front succeed + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_front<int> q(sq); + sq.push_back(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.try_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900) + { + // 1-element queue try_pull_front succeed + boost::deque_adaptor<boost::sync_deque<non_copyable> > sq; + boost::deque_front<non_copyable> q(sq); + non_copyable nc1(1); + sq.push_back(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.try_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#endif + + { + // 1-element queue nonblocking_pull_front succeed + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_front<int> q(sq); + sq.push_back(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900) + { + // 1-element queue nonblocking_pull_front succeed + boost::deque_adaptor<boost::sync_deque<non_copyable> > sq; + boost::deque_front<non_copyable> q(sq); + non_copyable nc1(1); + sq.push_back(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue wait_pull_front succeed + boost::deque_adaptor<boost::sync_deque<non_copyable> > sq; + boost::deque_front<non_copyable> q(sq); + non_copyable nc1(1); + sq.push_back(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#endif + { + // 1-element queue wait_pull_front succeed + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_front<int> q(sq); + sq.push_back(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900) + { + // 1-element queue wait_pull_front succeed + boost::deque_adaptor<boost::sync_deque<non_copyable> > sq; + boost::deque_front<non_copyable> q(sq); + non_copyable nc1(1); + sq.push_back(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#endif + { + // closed invariants + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_back<int> q(sq); + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed invariants + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_front<int> q(sq); + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed queue push fails + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_back<int> q(sq); + q.close(); + try { + q.push(1); + BOOST_TEST(false); + } catch (...) { + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + } + { + // 1-element closed queue pull succeed + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_front<int> q(sq); + sq.push_back(1); + q.close(); + int i; + q.pull(i); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // 1-element closed queue wait_pull_front succeed + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_front<int> q(sq); + sq.push_back(1); + q.close(); + int i; + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed empty queue wait_pull_front fails + boost::deque_adaptor<boost::sync_deque<int> > sq; + boost::deque_front<int> q(sq); + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(q.closed()); + int i; + BOOST_TEST(boost::queue_op_status::closed == q.wait_pull(i)); + BOOST_TEST(q.empty()); + BOOST_TEST(q.closed()); + } + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/adopt_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/adopt_lock_pass.cpp new file mode 100644 index 000000000..b6039c556 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/adopt_lock_pass.cpp @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class lock_guard; + +// lock_guard(mutex_type& m, adopt_lock_t); + +#include <boost/thread/lock_guard.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../../timming.hpp" + +#ifdef BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#endif +boost::mutex m; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#ifdef BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + { + m.lock(); + boost::lock_guard<boost::mutex> lg(m, boost::adopt_lock); + t1 = Clock::now(); + } +#else + //time_point t0 = Clock::now(); + //time_point t1; + { + m.lock(); + boost::lock_guard<boost::mutex> lg(m, boost::adopt_lock); + //t1 = Clock::now(); + } + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#ifdef BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/copy_assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/copy_assign_fail.cpp new file mode 100644 index 000000000..a3957c750 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/copy_assign_fail.cpp @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class lock_guard; + +// lock_guard& operator=(lock_guard const&) = delete; + +#include <boost/thread/lock_guard.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::mutex m0; +boost::mutex m1; + +int main() +{ + boost::lock_guard<boost::mutex> lk0(m0); + boost::lock_guard<boost::mutex> lk1(m1); + lk1 = lk0; + +} + +#include "../../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/copy_ctor_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/copy_ctor_fail.cpp new file mode 100644 index 000000000..5c1b3a1c2 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/copy_ctor_fail.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class lock_guard; + +// lock_guard(lock_guard const&) = delete; + + +#include <boost/thread/lock_guard.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::mutex m0; +boost::mutex m1; + +int main() +{ + boost::lock_guard<boost::mutex> lk0(m0); + boost::lock_guard<boost::mutex> lk1 = lk0; +} + +#include "../../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/default_pass.cpp new file mode 100644 index 000000000..4fcc26a9b --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/default_pass.cpp @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class lock_guard; + +// lock_guard(Mutex &); + +#include <boost/thread/lock_guard.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../../timming.hpp" + +#ifdef BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#endif + +boost::mutex m; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#ifdef BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + { + boost::lock_guard<boost::mutex> lg(m); + t1 = Clock::now(); + } +#else + //time_point t0 = Clock::now(); + //time_point t1; + { + boost::lock_guard<boost::mutex> lg(m); + //t1 = Clock::now(); + } + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#ifdef BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_adopt_lock_compile_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_adopt_lock_compile_fail.cpp new file mode 100644 index 000000000..9aab78ddd --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_adopt_lock_compile_fail.cpp @@ -0,0 +1,21 @@ +// Copyright (C) 2018 Tom Hughes +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/lock_guard.hpp> + +// template <class Mutex> class lock_guard; + +// lock_guard(Mutex& m_, adopt_lock_t) + +#include <boost/thread/lock_guard.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::mutex m; + +void fail() +{ + boost::lock_guard<boost::mutex> lk(m, boost::adopt_lock); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_adopt_lock_compile_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_adopt_lock_compile_pass.cpp new file mode 100644 index 000000000..a158677ad --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_adopt_lock_compile_pass.cpp @@ -0,0 +1,22 @@ +// Copyright (C) 2018 Tom Hughes +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/lock_guard.hpp> + +// template <class Mutex> class lock_guard; + +// lock_guard(Mutex& m_, adopt_lock_t) + +#include <boost/thread/lock_guard.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::mutex m; + +void pass() +{ + m.lock(); + boost::lock_guard<boost::mutex> lk(m, boost::adopt_lock); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_compile_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_compile_fail.cpp new file mode 100644 index 000000000..eead4501c --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_compile_fail.cpp @@ -0,0 +1,22 @@ +// Copyright (C) 2018 Tom Hughes +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/lock_guard.hpp> + +// template <class Mutex> class lock_guard; + +// lock_guard(Mutex& m_) + +#include <boost/thread/lock_guard.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::mutex m; + +void fail() +{ + boost::lock_guard<boost::mutex> lk0(m); + boost::lock_guard<boost::mutex> lk1(m); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_compile_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_compile_pass.cpp new file mode 100644 index 000000000..aee2e40e4 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/lock_guard_compile_pass.cpp @@ -0,0 +1,24 @@ +// Copyright (C) 2018 Tom Hughes +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/lock_guard.hpp> + +// template <class Mutex> class lock_guard; + +// lock_guard(Mutex& m_) + +#include <boost/thread/lock_guard.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::mutex m; + +void pass() +{ + { + boost::lock_guard<boost::mutex> lk0(m); + } + boost::lock_guard<boost::mutex> lk1(m); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/make_lock_guard_adopt_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/make_lock_guard_adopt_lock_pass.cpp new file mode 100644 index 000000000..cecdc84ce --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/make_lock_guard_adopt_lock_pass.cpp @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/lock_guard.hpp> + +// template <class Lockable> +// lock_guard<Lockable> make_lock_guard(Lockable &, adopt_lock_t); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/lock_guard.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../../timming.hpp" + + +#ifdef BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#endif +boost::mutex m; + +#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_THREAD_NO_MAKE_LOCK_GUARD + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#ifdef BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + { + m.lock(); + auto&& lg = boost::make_lock_guard(m, boost::adopt_lock); (void)lg; + + t1 = Clock::now(); + } +#else + //time_point t0 = Clock::now(); + //time_point t1; + { + m.lock(); + auto&& lg = boost::make_lock_guard(m, boost::adopt_lock); (void)lg; + //t1 = Clock::now(); + } + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} +#endif + +int main() +{ +#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_THREAD_NO_MAKE_LOCK_GUARD + m.lock(); + boost::thread t(f); +#ifdef BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + +#endif + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/make_lock_guard_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/make_lock_guard_pass.cpp new file mode 100644 index 000000000..853fae743 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/make_lock_guard_pass.cpp @@ -0,0 +1,77 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/lock_guard.hpp> + +// template <class Lockable> +// lock_guard<Lockable> make_lock_guard(Lockable &); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/lock_guard.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> + +#include <boost/detail/lightweight_test.hpp> +#include "../../../../timming.hpp" + +#ifdef BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#endif + +boost::mutex m; + +#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_THREAD_NO_MAKE_LOCK_GUARD && defined BOOST_THREAD_USES_CHRONO + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ + t0 = Clock::now(); + { + const auto&& lg = boost::make_lock_guard(m); (void)lg; + t1 = Clock::now(); + } +} +#endif + +int main() +{ + +#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_THREAD_NO_MAKE_LOCK_GUARD && defined BOOST_THREAD_USES_CHRONO + { + m.lock(); + boost::thread t(f); + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); + m.unlock(); + t.join(); + + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); + } +#endif + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/types_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/types_pass.cpp new file mode 100644 index 000000000..7c2d39375 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/lock_guard/types_pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/mutex.hpp> + +// <mutex> + +// template <class Mutex> +// class lock_guard +// { +// public: +// typedef Mutex mutex_type; +// ... +// }; + + +#include <boost/thread/lock_guard.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::lock_guard<boost::mutex>::mutex_type, + boost::mutex>::value), ""); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/copy_assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/copy_assign_fail.cpp new file mode 100644 index 000000000..c5d9a39b5 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/copy_assign_fail.cpp @@ -0,0 +1,31 @@ +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class nested_strict_lock; + +// nested_strict_lock& operator=(nested_strict_lock const&) = delete; + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/strict_lock.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::mutex m0; +boost::mutex m1; + +int main() +{ + boost::unique_lock<boost::mutex> lk0(m0); + boost::unique_lock<boost::mutex> lk1(m1); + boost::nested_strict_lock<boost::unique_lock<boost::mutex> > nlk0(lk0); + boost::nested_strict_lock<boost::unique_lock<boost::mutex> > nlk1(lk1); + lk1 = lk0; + +} + +#include "../../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/copy_ctor_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/copy_ctor_fail.cpp new file mode 100644 index 000000000..1c0abf94a --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/copy_ctor_fail.cpp @@ -0,0 +1,28 @@ +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class nested_strict_lock; + +// nested_strict_lock(nested_strict_lock const&) = delete; + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/strict_lock.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::mutex m0; +boost::mutex m1; + +int main() +{ + boost::nested_strict_lock<boost::unique_lock<boost::mutex> > lk0(m0); + boost::nested_strict_lock<boost::unique_lock<boost::mutex> > lk1 = lk0; +} + +#include "../../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/default_pass.cpp new file mode 100644 index 000000000..0182bdd95 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/default_pass.cpp @@ -0,0 +1,79 @@ +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class nested_strict_lock; + +// nested_strict_lock(Mutex &); + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/strict_lock.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../../timming.hpp" + +#ifdef BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#endif + +boost::mutex m; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#ifdef BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + boost::unique_lock<boost::mutex> lg(m); + { + boost::nested_strict_lock<boost::unique_lock<boost::mutex> > nlg(lg); + t1 = Clock::now(); + } +#else + //time_point t0 = Clock::now(); + //time_point t1; + boost::unique_lock<boost::mutex> lg(m); + { + boost::nested_strict_lock<boost::unique_lock<boost::mutex> > nlg(lg); + //t1 = Clock::now(); + } + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + { + m.lock(); + boost::thread t(f); +#ifdef BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/make_nested_strict_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/make_nested_strict_lock_pass.cpp new file mode 100644 index 000000000..5a10728cb --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/make_nested_strict_lock_pass.cpp @@ -0,0 +1,70 @@ +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/strict_lock.hpp> + +// template <class Lockable> +// strict_lock<Lockable> make_strict_lock(Lockable &); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/strict_lock.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> + +#include <boost/detail/lightweight_test.hpp> +#include "../../../../timming.hpp" + +#ifdef BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#endif + +boost::mutex m; + +#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_THREAD_NO_MAKE_NESTED_STRICT_LOCK && defined BOOST_THREAD_USES_CHRONO + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ + t0 = Clock::now(); + boost::unique_lock<boost::mutex> lg(m); + { + const auto&& nlg = boost::make_nested_strict_lock(lg); (void)nlg; + t1 = Clock::now(); + } +} +#endif + +int main() +{ + +#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_THREAD_NO_MAKE_NESTED_STRICT_LOCK && defined BOOST_THREAD_USES_CHRONO + { + m.lock(); + boost::thread t(f); + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); + m.unlock(); + t.join(); + + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); + } +#endif + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/owns_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/owns_lock_pass.cpp new file mode 100644 index 000000000..be06b6a06 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/owns_lock_pass.cpp @@ -0,0 +1,60 @@ +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class nested_strict_lock; + +// bool owns_lock(Mutex *) const; + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/strict_lock.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::mutex m; + boost::mutex m2; + { + boost::unique_lock<boost::mutex> lk(m); + { + boost::nested_strict_lock<boost::unique_lock<boost::mutex> > nlk(lk); + BOOST_TEST(nlk.owns_lock(&m) == true); + BOOST_TEST(!nlk.owns_lock(&m2) == true); + } + BOOST_TEST(lk.owns_lock() == true && lk.mutex()==&m); + } + { + m.lock(); + boost::unique_lock<boost::mutex> lk(m, boost::adopt_lock); + { + boost::nested_strict_lock<boost::unique_lock<boost::mutex> > nlk(lk); + BOOST_TEST(nlk.owns_lock(&m) == true); + BOOST_TEST(!nlk.owns_lock(&m2) == true); + } + BOOST_TEST(lk.owns_lock() == true && lk.mutex()==&m); + } + { + boost::unique_lock<boost::mutex> lk(m, boost::defer_lock); + { + boost::nested_strict_lock<boost::unique_lock<boost::mutex> > nlk(lk); + BOOST_TEST(nlk.owns_lock(&m) == true); + BOOST_TEST(!nlk.owns_lock(&m2) == true); + } + BOOST_TEST(lk.owns_lock() == true && lk.mutex()==&m); + } + { + boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock); + { + boost::nested_strict_lock<boost::unique_lock<boost::mutex> > nlk(lk); + BOOST_TEST(nlk.owns_lock(&m) == true); + BOOST_TEST(!nlk.owns_lock(&m2) == true); + } + BOOST_TEST(lk.owns_lock() == true && lk.mutex()==&m); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/types_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/types_pass.cpp new file mode 100644 index 000000000..5a7c690e4 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/nested_strict_lock/types_pass.cpp @@ -0,0 +1,35 @@ +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/mutex.hpp> + +// <mutex> + +// template <class Lock> +// class nested_strict_lock +// { +// public: +// typedef typename Lock::mutex_type mutex_type; +// ... +// }; + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/strict_lock.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::nested_strict_lock<boost::unique_lock<boost::mutex> >::mutex_type, + boost::mutex>::value), ""); + + BOOST_STATIC_ASSERT_MSG((boost::is_strict_lock<boost::nested_strict_lock<boost::unique_lock<boost::mutex> > >::value), ""); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_assign_fail.cpp new file mode 100644 index 000000000..408e0f267 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_assign_fail.cpp @@ -0,0 +1,33 @@ +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class reverse_lock; + +// reverse_lock& operator=(reverse_lock const&) = delete; + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/reverse_lock.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/lock_types.hpp> + + +int main() +{ + boost::mutex m0; + boost::mutex m1; + boost::unique_lock<boost::mutex> lk0(m0); + boost::unique_lock<boost::mutex> lk1(m1); + { + boost::reverse_lock<boost::unique_lock<boost::mutex> > lg0(lk0); + boost::reverse_lock<boost::unique_lock<boost::mutex> > lg1(lk1); + lg1 = lg0; + } + +} + +#include "../../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_ctor_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_ctor_fail.cpp new file mode 100644 index 000000000..c936c11b8 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/copy_ctor_fail.cpp @@ -0,0 +1,32 @@ +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class reverse_lock; + +// reverse_lock(reverse_lock const&) = delete; + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/reverse_lock.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/lock_types.hpp> + +boost::mutex m0; +boost::mutex m1; + +int main() +{ + boost::mutex m0; + boost::unique_lock<boost::mutex> lk0(m0); + { + boost::reverse_lock<boost::unique_lock<boost::mutex> > lg0(lk0); + boost::reverse_lock<boost::unique_lock<boost::mutex> > lg1(lg0); + } +} + +#include "../../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/types_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/types_pass.cpp new file mode 100644 index 000000000..13a17fd3a --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/types_pass.cpp @@ -0,0 +1,34 @@ +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/mutex.hpp> + +// <mutex> + +// template <class Mutex> +// class unlock_guard +// { +// public: +// typedef Mutex mutex_type; +// ... +// }; + + +#include <boost/thread/mutex.hpp> +#include <boost/thread/reverse_lock.hpp> +#include <boost/thread/lock_types.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::reverse_lock<boost::unique_lock<boost::mutex> >::mutex_type, + boost::mutex>::value), ""); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/unique_lock_ctor_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/unique_lock_ctor_pass.cpp new file mode 100644 index 000000000..57a1f1e01 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/reverse_lock/unique_lock_ctor_pass.cpp @@ -0,0 +1,52 @@ +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unlock_guard; + +// unlock_guard(unlock_guard const&) = delete; + +#include <boost/thread/reverse_lock.hpp> +#include <boost/thread/lock_types.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> + + +int main() +{ + { + boost::mutex m; + boost::unique_lock<boost::mutex> lk(m); + BOOST_TEST(lk.owns_lock()); + BOOST_TEST(lk.mutex()==&m); + + { + boost::reverse_lock<boost::unique_lock<boost::mutex> > lg(lk); + BOOST_TEST(!lk.owns_lock()); + BOOST_TEST(lk.mutex()==0); + } + BOOST_TEST(lk.owns_lock()); + BOOST_TEST(lk.mutex()==&m); + } + + { + boost::mutex m; + boost::unique_lock<boost::mutex> lk(m, boost::defer_lock); + BOOST_TEST(! lk.owns_lock()); + BOOST_TEST(lk.mutex()==&m); + { + boost::reverse_lock<boost::unique_lock<boost::mutex> > lg(lk); + BOOST_TEST(!lk.owns_lock()); + BOOST_TEST(lk.mutex()==0); + } + BOOST_TEST(lk.owns_lock()); + BOOST_TEST(lk.mutex()==&m); + } + + + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/adopt_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/adopt_lock_pass.cpp new file mode 100644 index 000000000..f9089e7a8 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/adopt_lock_pass.cpp @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class shared_lock; + +// shared_lock(mutex_type& m, adopt_lock_t); + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + + +int main() +{ + boost::shared_mutex m; + m.lock_shared(); + boost::shared_lock<boost::shared_mutex> lk(m, boost::adopt_lock); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/copy_assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/copy_assign_fail.cpp new file mode 100644 index 000000000..2bc99f34b --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/copy_assign_fail.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class shared_lock; + +// shared_lock& operator=(shared_lock const&) = delete; + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m0; +boost::shared_mutex m1; + +int main() +{ + boost::shared_lock<boost::shared_mutex> lk0(m0); + boost::shared_lock<boost::shared_mutex> lk1(m1); + lk1 = lk0; + BOOST_TEST(lk1.mutex() == &m0); + BOOST_TEST(lk1.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + +} + +#include "../../../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/copy_ctor_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/copy_ctor_fail.cpp new file mode 100644 index 000000000..43fddebe8 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/copy_ctor_fail.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class shared_lock; + +// shared_lock(shared_lock const&) = delete; + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m0; +boost::shared_mutex m1; + +int main() +{ + boost::shared_lock<boost::shared_mutex> lk0(m0); + boost::shared_lock<boost::shared_mutex> lk1 = lk0; + BOOST_TEST(lk1.mutex() == &m1); + BOOST_TEST(lk1.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); +} + +#include "../../../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/default_pass.cpp new file mode 100644 index 000000000..9ccae93b7 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/default_pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class shared_lock; + +// shared_lock(shared_lock const&) = delete; + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::shared_lock<boost::shared_mutex> ul; + BOOST_TEST(!ul.owns_lock()); + BOOST_TEST(ul.mutex() == 0); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/defer_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/defer_lock_pass.cpp new file mode 100644 index 000000000..84388aca4 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/defer_lock_pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class shared_lock; + +// shared_lock(mutex_type& m, adopt_lock_t); + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::shared_mutex m; + m.lock(); + boost::shared_lock<boost::shared_mutex> lk(m, boost::defer_lock); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == false); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/duration_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/duration_pass.cpp new file mode 100644 index 000000000..45037c224 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/duration_pass.cpp @@ -0,0 +1,87 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class shared_lock; + +// template <class Rep, class Period> +// shared_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time); + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/chrono/chrono_io.hpp> +#include "../../../../../timming.hpp" + +boost::shared_mutex m; + +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f1() +{ + t0 = Clock::now(); + boost::shared_lock<boost::shared_mutex> lk(m, ms(750)); + BOOST_TEST(lk.owns_lock() == true); + t1 = Clock::now(); +} + +void f2() +{ + t0 = Clock::now(); + boost::shared_lock<boost::shared_mutex> lk(m, ms(250)); + BOOST_TEST(lk.owns_lock() == false); + t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + BOOST_THREAD_TEST_IT(d, ns(max_diff)); +} + +int main() +{ + { + m.lock(); + boost::thread t(f1); + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); + m.unlock(); + t.join(); + + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); + } + { + m.lock(); + boost::thread t(f2); + boost::this_thread::sleep_for(ms(750)); + m.unlock(); + t.join(); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_assign_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_assign_pass.cpp new file mode 100644 index 000000000..ef54e229f --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_assign_pass.cpp @@ -0,0 +1,82 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/shared_mutex.hpp> + +// template <class Mutex> class shared_lock; + +// shared_lock(shared_lock const&) = delete; + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m0; +boost::shared_mutex m1; + +int main() +{ + { + boost::shared_lock<boost::shared_mutex> lk0(m0); + boost::shared_lock<boost::shared_mutex> lk1(m1); + lk1 = boost::move(lk0); + BOOST_TEST(lk1.mutex() == &m0); + BOOST_TEST(lk1.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + + boost::shared_lock<boost::shared_mutex> lk1; + lk1 = BOOST_THREAD_MAKE_RV_REF(boost::shared_lock<boost::shared_mutex>(m0)); + BOOST_TEST(lk1.mutex() == &m0); + BOOST_TEST(lk1.owns_lock() == true); + } + { + boost::unique_lock<boost::shared_mutex> lk0(m0); + boost::shared_lock<boost::shared_mutex> lk1(m1); + lk1 = BOOST_THREAD_MAKE_RV_REF(boost::shared_lock<boost::shared_mutex>(boost::move(lk0))); + BOOST_TEST(lk1.mutex() == &m0); + BOOST_TEST(lk1.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + + boost::shared_lock<boost::shared_mutex> lk1; + lk1 = BOOST_THREAD_MAKE_RV_REF(boost::shared_lock<boost::shared_mutex>(boost::unique_lock<boost::shared_mutex>(m0))); + BOOST_TEST(lk1.mutex() == &m0); + BOOST_TEST(lk1.owns_lock() == true); + } + { + boost::upgrade_lock<boost::shared_mutex> lk0(m0); + boost::shared_lock<boost::shared_mutex> lk1(m1); + lk1 = BOOST_THREAD_MAKE_RV_REF(boost::shared_lock<boost::shared_mutex>(boost::move(lk0))); + BOOST_TEST(lk1.mutex() == &m0); + BOOST_TEST(lk1.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + + boost::shared_lock<boost::shared_mutex> lk1; + lk1 = BOOST_THREAD_MAKE_RV_REF(boost::shared_lock<boost::shared_mutex>(boost::upgrade_lock<boost::shared_mutex>(m0))); + BOOST_TEST(lk1.mutex() == &m0); + BOOST_TEST(lk1.owns_lock() == true); + } + return boost::report_errors(); + +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_pass.cpp new file mode 100644 index 000000000..307c76142 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class shared_lock; + +// shared_lock& operator=(shared_lock&& u); + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m; + +int main() +{ + { + boost::shared_lock<boost::shared_mutex> lk0(m); + boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0))); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::shared_lock<boost::shared_mutex> lk( (BOOST_THREAD_MAKE_RV_REF(boost::shared_lock<boost::shared_mutex>(m)))); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + } + + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_unique_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_unique_lock_pass.cpp new file mode 100644 index 000000000..38f6e7d7d --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_unique_lock_pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class shared_lock; + +// shared_lock& operator=(shared_lock&& u); + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m; + +int main() +{ + + { + boost::unique_lock<boost::shared_mutex> lk0(m); + boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0))); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::shared_lock<boost::shared_mutex> lk( (boost::unique_lock<boost::shared_mutex>(m))); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + } + { + boost::unique_lock<boost::shared_mutex> lk0(m, boost::defer_lock); + boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0))); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::unique_lock<boost::shared_mutex> lk0(m, boost::defer_lock); + lk0.release(); + boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0))); + BOOST_TEST(lk.mutex() == 0); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_upgrade_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_upgrade_lock_pass.cpp new file mode 100644 index 000000000..36ecb6a5a --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/move_ctor_upgrade_lock_pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class shared_lock; + +// shared_lock& operator=(shared_lock&& u); + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m; + +int main() +{ + + { + boost::upgrade_lock<boost::shared_mutex> lk0(m); + boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0))); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::shared_lock<boost::shared_mutex> lk( (boost::upgrade_lock<boost::shared_mutex>(m))); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + } + { + boost::upgrade_lock<boost::shared_mutex> lk0(m, boost::defer_lock); + boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0))); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::upgrade_lock<boost::shared_mutex> lk0(m, boost::defer_lock); + lk0.release(); + boost::shared_lock<boost::shared_mutex> lk( (boost::move(lk0))); + BOOST_TEST(lk.mutex() == 0); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/mutex_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/mutex_pass.cpp new file mode 100644 index 000000000..f50aa6199 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/mutex_pass.cpp @@ -0,0 +1,86 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class shared_lock; + +// explicit shared_lock(Mutex& m); + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../../../timming.hpp" + +boost::shared_mutex m; + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + { + boost::shared_lock<boost::shared_mutex> ul(m); + t1 = Clock::now(); + } +#else + //time_point t0 = Clock::now(); + //time_point t1; + { + boost::shared_lock<boost::shared_mutex> ul(m); + //t1 = Clock::now(); + } + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#else +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/time_point_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/time_point_pass.cpp new file mode 100644 index 000000000..41d9cd8f9 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/time_point_pass.cpp @@ -0,0 +1,86 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class shared_lock; + +// template <class Clock, class Duration> +// shared_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time); + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../../../timming.hpp" + +boost::shared_mutex m; + +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f1() +{ + t0 = Clock::now(); + boost::shared_lock<boost::shared_mutex> lk(m, Clock::now() + ms(750)); + BOOST_TEST(lk.owns_lock() == true); + t1 = Clock::now(); +} + +void f2() +{ + t0 = Clock::now(); + boost::shared_lock<boost::shared_mutex> lk(m, Clock::now() + ms(250)); + BOOST_TEST(lk.owns_lock() == false); + t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + BOOST_THREAD_TEST_IT(d, ns(max_diff)); +} + +int main() +{ + { + m.lock(); + boost::thread t(f1); + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); + m.unlock(); + t.join(); + + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); + } + { + m.lock(); + boost::thread t(f2); + boost::this_thread::sleep_for(ms(750)); + m.unlock(); + t.join(); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/try_to_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/try_to_lock_pass.cpp new file mode 100644 index 000000000..5f3036c0c --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/cons/try_to_lock_pass.cpp @@ -0,0 +1,115 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class shared_lock; + +// shared_lock(mutex_type& m, try_to_lock_t); + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../../../timming.hpp" + +boost::shared_mutex m; + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + { + boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock); + BOOST_TEST(lk.owns_lock() == false); + } + { + boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock); + BOOST_TEST(lk.owns_lock() == false); + } + { + boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock); + BOOST_TEST(lk.owns_lock() == false); + } + for (;;) + { + boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock); + if (lk.owns_lock()) { + t1 = Clock::now(); + break; + } + } +#else +// time_point t0 = Clock::now(); +// { +// boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock); +// BOOST_TEST(lk.owns_lock() == false); +// } +// { +// boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock); +// BOOST_TEST(lk.owns_lock() == false); +// } +// { +// boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock); +// BOOST_TEST(lk.owns_lock() == false); +// } + for (;;) + { + boost::shared_lock<boost::shared_mutex> lk(m, boost::try_to_lock); + if (lk.owns_lock()) break; + } + //time_point t1 = Clock::now(); + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#else +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/lock_pass.cpp new file mode 100644 index 000000000..456c26dfd --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/lock_pass.cpp @@ -0,0 +1,126 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class shared_lock; + +// void lock(); + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <iostream> +#include "../../../../../timming.hpp" + +boost::shared_mutex m; + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + boost::shared_lock < boost::shared_mutex > lk(m, boost::defer_lock); + t0 = Clock::now(); + lk.lock(); + t1 = Clock::now(); + BOOST_TEST(lk.owns_lock() == true); + try + { + lk.lock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur); + } + lk.unlock(); + lk.release(); + try + { + lk.lock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted); + } +#else + boost::shared_lock < boost::shared_mutex > lk(m, boost::defer_lock); + //time_point t0 = Clock::now(); + lk.lock(); + //time_point t1 = Clock::now(); + BOOST_TEST(lk.owns_lock() == true); + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); + try + { + lk.lock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur); + } + lk.unlock(); + lk.release(); + try + { + lk.lock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted); + } +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#else +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_for_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_for_pass.cpp new file mode 100644 index 000000000..07d32df39 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_for_pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class shared_lock; + +// template <class Rep, class Period> +// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); + +#include <boost/thread/lock_types.hpp> +//#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +bool try_lock_for_called = false; + +typedef boost::chrono::milliseconds ms; + +struct shared_mutex +{ + template <class Rep, class Period> + bool try_lock_shared_for(const boost::chrono::duration<Rep, Period>& rel_time) + { + BOOST_TEST(rel_time == ms(5)); + try_lock_for_called = !try_lock_for_called; + return try_lock_for_called; + } + void unlock_shared() + { + } +}; + +shared_mutex m; + +int main() +{ + boost::shared_lock<shared_mutex> lk(m, boost::defer_lock); + BOOST_TEST(lk.try_lock_for(ms(5)) == true); + BOOST_TEST(try_lock_for_called == true); + BOOST_TEST(lk.owns_lock() == true); + try + { + lk.try_lock_for(ms(5)); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur); + } + lk.unlock(); + BOOST_TEST(lk.try_lock_for(ms(5)) == false); + BOOST_TEST(try_lock_for_called == false); + BOOST_TEST(lk.owns_lock() == false); + lk.release(); + try + { + lk.try_lock_for(ms(5)); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_pass.cpp new file mode 100644 index 000000000..6a1997238 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_pass.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class shared_lock; + +// template <class Rep, class Period> +// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); + +#include <boost/thread/lock_types.hpp> +//#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +bool try_lock_called = false; + +struct shared_mutex +{ + bool try_lock_shared() + { + try_lock_called = !try_lock_called; + return try_lock_called; + } + void unlock_shared() + { + } +}; + +shared_mutex m; + +int main() +{ + boost::shared_lock<shared_mutex> lk(m, boost::defer_lock); + BOOST_TEST(lk.try_lock() == true); + BOOST_TEST(try_lock_called == true); + BOOST_TEST(lk.owns_lock() == true); + try + { + lk.try_lock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur); + } + lk.unlock(); + BOOST_TEST(lk.try_lock() == false); + BOOST_TEST(try_lock_called == false); + BOOST_TEST(lk.owns_lock() == false); + lk.release(); + try + { + lk.try_lock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_until_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_until_pass.cpp new file mode 100644 index 000000000..cdfd0e161 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/try_lock_until_pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class shared_lock; + +// template <class Clock, class Duration> +// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +bool try_lock_until_called = false; + +struct shared_mutex +{ + template <class Clock, class Duration> + bool try_lock_shared_until(const boost::chrono::time_point<Clock, Duration>& abs_time) + { + typedef boost::chrono::milliseconds ms; + BOOST_TEST(Clock::now() - abs_time < ms(5)); + try_lock_until_called = !try_lock_until_called; + return try_lock_until_called; + } + void unlock_shared() + { + } +}; + +shared_mutex m; + +int main() +{ + typedef boost::chrono::steady_clock Clock; + boost::shared_lock<shared_mutex> lk(m, boost::defer_lock); + BOOST_TEST(lk.try_lock_until(Clock::now()) == true); + BOOST_TEST(try_lock_until_called == true); + BOOST_TEST(lk.owns_lock() == true); + try + { + lk.try_lock_until(Clock::now()); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur); + } + lk.unlock(); + BOOST_TEST(lk.try_lock_until(Clock::now()) == false); + BOOST_TEST(try_lock_until_called == false); + BOOST_TEST(lk.owns_lock() == false); + lk.release(); + try + { + lk.try_lock_until(Clock::now()); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted); + } + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/unlock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/unlock_pass.cpp new file mode 100644 index 000000000..e8ed7c74c --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/locking/unlock_pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class shared_lock; + +// template <class Rep, class Period> +// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); + +#include <boost/thread/lock_types.hpp> +//#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +bool unlock_called = false; + +struct shared_mutex +{ + void lock_shared() + { + } + void unlock_shared() + { + unlock_called = true; + } +}; + +shared_mutex m; + +int main() +{ + boost::shared_lock<shared_mutex> lk(m); + lk.unlock(); + BOOST_TEST(unlock_called == true); + BOOST_TEST(lk.owns_lock() == false); + try + { + lk.unlock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted); + } + lk.release(); + try + { + lk.unlock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/member_swap_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/member_swap_pass.cpp new file mode 100644 index 000000000..11f366bd6 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/member_swap_pass.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class shared_lock; + +// void swap(shared_lock& u); + +#include <boost/thread/lock_types.hpp> +#include <boost/detail/lightweight_test.hpp> + +struct shared_mutex +{ + void lock_shared() + { + } + void unlock_shared() + { + } +}; + +shared_mutex m; + +int main() +{ + boost::shared_lock<shared_mutex> lk1(m); + boost::shared_lock<shared_mutex> lk2; + lk1.swap(lk2); + BOOST_TEST(lk1.mutex() == 0); + BOOST_TEST(lk1.owns_lock() == false); + BOOST_TEST(lk2.mutex() == &m); + BOOST_TEST(lk2.owns_lock() == true); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/non_member_swap_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/non_member_swap_pass.cpp new file mode 100644 index 000000000..c0ccb8b9d --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/non_member_swap_pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> +// void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y); + +#include <boost/thread/lock_types.hpp> +#include <boost/detail/lightweight_test.hpp> + +struct shared_mutex +{ + void lock_shared() + { + } + void unlock_shared() + { + } +}; + +shared_mutex m; + +int main() +{ + boost::shared_lock<shared_mutex> lk1(m); + boost::shared_lock<shared_mutex> lk2; + swap(lk1, lk2); + BOOST_TEST(lk1.mutex() == 0); + BOOST_TEST(lk1.owns_lock() == false); + BOOST_TEST(lk2.mutex() == &m); + BOOST_TEST(lk2.owns_lock() == true); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/release_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/release_pass.cpp new file mode 100644 index 000000000..c39ca50aa --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/mod/release_pass.cpp @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class shared_lock; + +// void Mutex* release(); + +#include <boost/thread/lock_types.hpp> +#include <boost/detail/lightweight_test.hpp> + +struct shared_mutex +{ + static int lock_count; + static int unlock_count; + void lock_shared() + { + ++lock_count; + } + void unlock_shared() + { + ++unlock_count; + } +}; + +int shared_mutex::lock_count = 0; +int shared_mutex::unlock_count = 0; + +shared_mutex m; + +int main() +{ + boost::shared_lock<shared_mutex> lk(m); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + BOOST_TEST(shared_mutex::lock_count == 1); + BOOST_TEST(shared_mutex::unlock_count == 0); + BOOST_TEST(lk.release() == &m); + BOOST_TEST(lk.mutex() == 0); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(shared_mutex::lock_count == 1); + BOOST_TEST(shared_mutex::unlock_count == 0); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/mutex_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/mutex_pass.cpp new file mode 100644 index 000000000..2012186ae --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/mutex_pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class shared_lock; + +// Mutex *mutex() const; + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m; + +int main() +{ + boost::shared_lock<boost::shared_mutex> lk0; + BOOST_TEST(lk0.mutex() == 0); + boost::shared_lock<boost::shared_mutex> lk1(m); + BOOST_TEST(lk1.mutex() == &m); + lk1.unlock(); + BOOST_TEST(lk1.mutex() == &m); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/op_bool_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/op_bool_pass.cpp new file mode 100644 index 000000000..407bfcc6f --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/op_bool_pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class shared_lock; + +// explicit operator bool() const; + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m; + +int main() +{ + boost::shared_lock < boost::shared_mutex > lk0; + BOOST_TEST(bool(lk0) == false); + boost::shared_lock < boost::shared_mutex > lk1(m); + BOOST_TEST(bool(lk1) == true); + lk1.unlock(); + BOOST_TEST(bool(lk1) == false); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/owns_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/owns_lock_pass.cpp new file mode 100644 index 000000000..dce14d3e9 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/obs/owns_lock_pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class shared_lock; + +// bool owns_lock() const; + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m; + +int main() +{ + boost::shared_lock<boost::shared_mutex> lk0; + BOOST_TEST(lk0.owns_lock() == false); + boost::shared_lock<boost::shared_mutex> lk1(m); + BOOST_TEST(lk1.owns_lock() == true); + lk1.unlock(); + BOOST_TEST(lk1.owns_lock() == false); + + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/types_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/types_pass.cpp new file mode 100644 index 000000000..2f83ef98f --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock/types_pass.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/mutex.hpp> + +// <mutex> + +// template <class Mutex> +// class shared_lock +// { +// public: +// typedef Mutex mutex_type; +// ... +// }; + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/static_assert.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::shared_lock<boost::shared_mutex>::mutex_type, + boost::shared_mutex>::value), ""); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/adopt_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/adopt_lock_pass.cpp new file mode 100644 index 000000000..fe125e8a0 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/adopt_lock_pass.cpp @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/shared_lock_guard.hpp> + +// template <class Mutex> class shared_lock_guard; + +// shared_lock_guard(mutex_type& m, adopt_lock_t); + +#include <boost/thread/shared_lock_guard.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../../timming.hpp" + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +boost::shared_mutex m; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + { + m.lock_shared(); + boost::shared_lock_guard<boost::shared_mutex> lg(m, boost::adopt_lock); + t1 = Clock::now(); + } +#else + //time_point t0 = Clock::now(); + //time_point t1; + { + m.lock_shared(); + boost::shared_lock_guard<boost::shared_mutex> lg(m, boost::adopt_lock); + //t1 = Clock::now(); + } + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#else +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/copy_assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/copy_assign_fail.cpp new file mode 100644 index 000000000..43607ac26 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/copy_assign_fail.cpp @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/shared_lock_guard.hpp> + +// template <class Mutex> class shared_lock_guard; + +// shared_lock_guard& operator=(shared_lock_guard const&) = delete; + +#include <boost/thread/shared_lock_guard.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m0; +boost::shared_mutex m1; + +int main() +{ + boost::shared_lock_guard<boost::shared_mutex> lk0(m0); + boost::shared_lock_guard<boost::shared_mutex> lk1(m1); + lk1 = lk0; + +} + +#include "../../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/copy_ctor_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/copy_ctor_fail.cpp new file mode 100644 index 000000000..a7d4f006d --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/copy_ctor_fail.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/shared_lock_guard.hpp> + +// template <class Mutex> class shared_lock_guard; + +// shared_lock_guard(shared_lock_guard const&) = delete; + + +#include <boost/thread/shared_lock_guard.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m0; +boost::shared_mutex m1; + +int main() +{ + boost::shared_lock_guard<boost::shared_mutex> lk0(m0); + boost::shared_lock_guard<boost::shared_mutex> lk1 = lk0; +} + +#include "../../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/default_pass.cpp new file mode 100644 index 000000000..694ba4a14 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/default_pass.cpp @@ -0,0 +1,86 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/shared_lock_guard.hpp> + +// template <class Mutex> class shared_lock_guard; + +// shared_lock_guard(shared_lock_guard const&) = delete; + +#include <boost/thread/shared_lock_guard.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <iostream> +#include "../../../../timming.hpp" + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +boost::shared_mutex m; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + { + boost::shared_lock_guard<boost::shared_mutex> lg(m); + t1 = Clock::now(); + } +#else + //time_point t0 = Clock::now(); + //time_point t1; + { + boost::shared_lock_guard<boost::shared_mutex> lg(m); + //t1 = Clock::now(); + } + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#else +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/types_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/types_pass.cpp new file mode 100644 index 000000000..57a2116d1 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/shared_lock_guard/types_pass.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/shared_lock_guard.hpp> + +// <mutex> + +// template <class Mutex> +// class shared_lock_guard +// { +// public: +// typedef Mutex mutex_type; +// ... +// }; + + +#include <boost/thread/shared_mutex.hpp> +#include <boost/thread/shared_lock_guard.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::shared_lock_guard<boost::shared_mutex>::mutex_type, + boost::shared_mutex>::value), ""); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/copy_assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/copy_assign_fail.cpp new file mode 100644 index 000000000..1852224bb --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/copy_assign_fail.cpp @@ -0,0 +1,28 @@ +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class strict_lock; + +// strict_lock& operator=(strict_lock const&) = delete; + +#include <boost/thread/strict_lock.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::mutex m0; +boost::mutex m1; + +int main() +{ + boost::strict_lock<boost::mutex> lk0(m0); + boost::strict_lock<boost::mutex> lk1(m1); + lk1 = lk0; + +} + +#include "../../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/copy_ctor_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/copy_ctor_fail.cpp new file mode 100644 index 000000000..331610cb1 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/copy_ctor_fail.cpp @@ -0,0 +1,27 @@ +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class strict_lock; + +// strict_lock(strict_lock const&) = delete; + + +#include <boost/thread/strict_lock.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::mutex m0; +boost::mutex m1; + +int main() +{ + boost::strict_lock<boost::mutex> lk0(m0); + boost::strict_lock<boost::mutex> lk1 = lk0; +} + +#include "../../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/default_pass.cpp new file mode 100644 index 000000000..aa2fb0071 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/default_pass.cpp @@ -0,0 +1,74 @@ +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class strict_lock; + +// strict_lock(Mutex &); + +#include <boost/thread/strict_lock.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../../timming.hpp" + +#ifdef BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#endif + +boost::mutex m; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#ifdef BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + { + boost::strict_lock<boost::mutex> lg(m); + t1 = Clock::now(); + } +#else + //time_point t0 = Clock::now(); + //time_point t1; + { + boost::strict_lock<boost::mutex> lg(m); + //t1 = Clock::now(); + } + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#ifdef BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/make_strict_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/make_strict_lock_pass.cpp new file mode 100644 index 000000000..c5a3069f0 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/make_strict_lock_pass.cpp @@ -0,0 +1,70 @@ +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/strict_lock.hpp> + +// template <class Lockable> +// strict_lock<Lockable> make_strict_lock(Lockable &); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/strict_lock.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> + +#include <boost/detail/lightweight_test.hpp> +#include "../../../../timming.hpp" + +#ifdef BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#endif + +boost::mutex m; + +#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_THREAD_NO_MAKE_STRICT_LOCK && defined BOOST_THREAD_USES_CHRONO + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ + t0 = Clock::now(); + { + const auto&& lg = boost::make_strict_lock(m); (void)lg; + t1 = Clock::now(); + } + ns d = t1 - t0 - ms(250); + BOOST_THREAD_TEST_IT(d, ns(max_diff)); +} +#endif + +int main() +{ + +#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_THREAD_NO_MAKE_STRICT_LOCK && defined BOOST_THREAD_USES_CHRONO + { + m.lock(); + boost::thread t(f); + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); + m.unlock(); + t.join(); + + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); + } +#endif + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/owns_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/owns_lock_pass.cpp new file mode 100644 index 000000000..c0c2ec861 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/owns_lock_pass.cpp @@ -0,0 +1,34 @@ +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class strict_lock; + +// bool owns_lock(Mutex *) const; + +#include <boost/thread/strict_lock.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> + +#ifdef BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +#endif + +int main() +{ + boost::mutex m; + boost::mutex m2; + + boost::strict_lock<boost::mutex> lk(m); + BOOST_TEST(lk.owns_lock(&m) == true); + BOOST_TEST(!lk.owns_lock(&m2) == true); + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/types_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/types_pass.cpp new file mode 100644 index 000000000..f813e5ca8 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/strict_lock/types_pass.cpp @@ -0,0 +1,34 @@ +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/mutex.hpp> + +// <mutex> + +// template <class Mutex> +// class strict_lock +// { +// public: +// typedef Mutex mutex_type; +// ... +// }; + + +#include <boost/thread/strict_lock.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/static_assert.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::strict_lock<boost::mutex>::mutex_type, + boost::mutex>::value), ""); + + BOOST_STATIC_ASSERT_MSG((boost::is_strict_lock<boost::strict_lock<boost::mutex> >::value), ""); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/adopt_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/adopt_lock_pass.cpp new file mode 100644 index 000000000..42d33378e --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/adopt_lock_pass.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// unique_lock(mutex_type& m, adopt_lock_t); + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + + +int main() +{ + boost::mutex m; + m.lock(); + boost::unique_lock<boost::mutex> lk(m, boost::adopt_lock); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/copy_assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/copy_assign_fail.cpp new file mode 100644 index 000000000..d69a1eec7 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/copy_assign_fail.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// unique_lock& operator=(unique_lock const&) = delete; + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::mutex m0; +boost::mutex m1; + +int main() +{ + boost::unique_lock<boost::mutex> lk0(m0); + boost::unique_lock<boost::mutex> lk1(m1); + lk1 = lk0; + BOOST_TEST(lk1.mutex() == &m0); + BOOST_TEST(lk1.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + +} + +#include "../../../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/copy_ctor_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/copy_ctor_fail.cpp new file mode 100644 index 000000000..08fc3c344 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/copy_ctor_fail.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// unique_lock(unique_lock const&) = delete; + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::mutex m0; +boost::mutex m1; + +int main() +{ + boost::unique_lock<boost::mutex> lk0(m0); + boost::unique_lock<boost::mutex> lk1 = lk0; + BOOST_TEST(lk1.mutex() == &m1); + BOOST_TEST(lk1.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); +} + +#include "../../../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/default_pass.cpp new file mode 100644 index 000000000..7989b8173 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/default_pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// unique_lock(unique_lock const&) = delete; + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::unique_lock<boost::mutex> ul; + BOOST_TEST(!ul.owns_lock()); + BOOST_TEST(ul.mutex() == 0); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/defer_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/defer_lock_pass.cpp new file mode 100644 index 000000000..5045af26e --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/defer_lock_pass.cpp @@ -0,0 +1,34 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// unique_lock(mutex_type& m, adopt_lock_t); + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::mutex m; + boost::unique_lock<boost::mutex> lk(m, boost::defer_lock); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == false); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/duration_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/duration_pass.cpp new file mode 100644 index 000000000..19aa0575f --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/duration_pass.cpp @@ -0,0 +1,94 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// template <class Rep, class Period> +// unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time); + +#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/chrono/chrono_io.hpp> +#include "../../../../../timming.hpp" + +#if defined BOOST_THREAD_USES_CHRONO + +boost::timed_mutex m; + +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f1() +{ + t0 = Clock::now(); + boost::unique_lock<boost::timed_mutex> lk(m, ms(750)); + BOOST_TEST(lk.owns_lock() == true); + t1 = Clock::now(); +} + +void f2() +{ + t0 = Clock::now(); + boost::unique_lock<boost::timed_mutex> lk(m, ms(250)); + BOOST_TEST(lk.owns_lock() == false); + t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + BOOST_THREAD_TEST_IT(d, ns(max_diff)); +} + +int main() +{ + { + m.lock(); + boost::thread t(f1); + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); + m.unlock(); + t.join(); + + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); + } + { + m.lock(); + boost::thread t(f2); + boost::this_thread::sleep_for(ms(750)); + m.unlock(); + t.join(); + } + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_adopt_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_adopt_lock_pass.cpp new file mode 100644 index 000000000..2f385ec87 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_adopt_lock_pass.cpp @@ -0,0 +1,31 @@ +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/lock_factories.hpp> + +// template <class Mutex> class unique_lock; +// unique_lock<Mutex> make_unique_lock(Mutex&, adopt_lock_t); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/lock_factories.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::mutex m; + m.lock(); +#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) + auto +#else + boost::unique_lock<boost::mutex> +#endif + lk = boost::make_unique_lock(m, boost::adopt_lock); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_defer_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_defer_lock_pass.cpp new file mode 100644 index 000000000..e32fad168 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_defer_lock_pass.cpp @@ -0,0 +1,32 @@ +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/lock_factories.hpp> + +// template <class Mutex> class unique_lock; +// unique_lock<Mutex> make_unique_lock(Mutex&, defer_lock_t); + +// unique_lock(mutex_type& m, adopt_lock_t); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/lock_factories.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::mutex m; +#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) + auto +#else + boost::unique_lock<boost::mutex> +#endif + lk = boost::make_unique_lock(m, boost::defer_lock); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == false); + + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_mutex_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_mutex_pass.cpp new file mode 100644 index 000000000..97b625564 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_mutex_pass.cpp @@ -0,0 +1,100 @@ +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/lock_factories.hpp> + +// template <class Mutex> +// unique_lock<Mutex> make_unique_lock(Mutex&); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/detail/config.hpp> +#include <boost/thread/lock_factories.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../../../timming.hpp" + +//#if ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + +boost::mutex m; + +#if defined BOOST_THREAD_USES_CHRONO + +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + { +#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) + auto +#else + boost::unique_lock<boost::mutex> +#endif + //&& + _ = boost::make_unique_lock(m); (void)_; + t1 = Clock::now(); + } +#else + //time_point t0 = Clock::now(); + //time_point t1; + { +#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) + auto +#else + boost::unique_lock<boost::mutex> +#endif + //&& + _ = boost::make_unique_lock(m); (void)_; + //t1 = Clock::now(); + } + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#else +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} +//#else +//int main() +//{ +// return boost::report_errors(); +//} +//#endif + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_try_to_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_try_to_lock_pass.cpp new file mode 100644 index 000000000..d0149d906 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_lock_try_to_lock_pass.cpp @@ -0,0 +1,146 @@ +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; +// unique_lock<Mutex> make_unique_lock(Mutex&, try_to_lock_t); + +#define BOOST_THREAD_VERSION 4 + + +#include <boost/thread/lock_factories.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../../../timming.hpp" + +boost::mutex m; + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + { + t0 = Clock::now(); +#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) + auto +#else + boost::unique_lock<boost::mutex> +#endif + lk = boost::make_unique_lock(m, boost::try_to_lock); + BOOST_TEST(lk.owns_lock() == false); + t1 = Clock::now(); + ns d = t1 - t0; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + } + { + t0 = Clock::now(); +#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) + auto +#else + boost::unique_lock<boost::mutex> +#endif + lk = boost::make_unique_lock(m, boost::try_to_lock); + BOOST_TEST(lk.owns_lock() == false); + t1 = Clock::now(); + ns d = t1 - t0; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + } + { + t0 = Clock::now(); +#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) + auto +#else + boost::unique_lock<boost::mutex> +#endif + lk = boost::make_unique_lock(m, boost::try_to_lock); + BOOST_TEST(lk.owns_lock() == false); + t1 = Clock::now(); + ns d = t1 - t0; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + } + { + t0 = Clock::now(); + for (;;) + { +#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) + auto +#else + boost::unique_lock<boost::mutex> +#endif + lk = boost::make_unique_lock(m, boost::try_to_lock); + if (lk.owns_lock()) { + t1 = Clock::now(); + break; + } + } + } +#else +// time_point t0 = Clock::now(); +// { +// boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock); +// BOOST_TEST(lk.owns_lock() == false); +// } +// { +// boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock); +// BOOST_TEST(lk.owns_lock() == false); +// } +// { +// boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock); +// BOOST_TEST(lk.owns_lock() == false); +// } + for (;;) + { +#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) + auto +#else + boost::unique_lock<boost::mutex> +#endif + lk = boost::make_unique_lock(m, boost::try_to_lock); + if (lk.owns_lock()) break; + } + //time_point t1 = Clock::now(); + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#else +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_locks_mutex_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_locks_mutex_pass.cpp new file mode 100644 index 000000000..72c574b20 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/make_unique_locks_mutex_pass.cpp @@ -0,0 +1,94 @@ +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/lock_factories.hpp> + +// template <class Mutex> +// unique_lock<Mutex> make_unique_lock(Mutex&); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/lock_factories.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../../../timming.hpp" + +#if ! defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && ! defined BOOST_THREAD_NO_MAKE_UNIQUE_LOCKS && ! defined BOOST_NO_CXX11_RVALUE_REFERENCES + +boost::mutex m1; +boost::mutex m2; +boost::mutex m3; + + +#if defined BOOST_THREAD_USES_CHRONO + +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + { + auto&& _ = boost::make_unique_locks(m1,m2,m3); (void)_; + t1 = Clock::now(); + } +#else + //time_point t0 = Clock::now(); + //time_point t1; + { + auto&& _ = boost::make_unique_locks(m1,m2,m3); (void)_; + //t1 = Clock::now(); + } + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m1.lock(); + m2.lock(); + m3.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#else +#endif + m1.unlock(); + m2.unlock(); + m3.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} +#else +int main() +{ + return boost::report_errors(); +} +#endif + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_assign_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_assign_pass.cpp new file mode 100644 index 000000000..7c84d1520 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_assign_pass.cpp @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/mutex.hpp> + +// template <class Mutex> class unique_lock; + +// unique_lock(unique_lock const&) = delete; + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::mutex m0; +boost::mutex m1; + +int main() +{ + { + boost::unique_lock<boost::mutex> lk0(m0); + boost::unique_lock<boost::mutex> lk1(m1); + lk1 = boost::move(lk0); + BOOST_TEST(lk1.mutex() == &m0); + BOOST_TEST(lk1.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + + + { + + boost::unique_lock<boost::mutex> lk1; + lk1 = BOOST_THREAD_MAKE_RV_REF(boost::unique_lock<boost::mutex>(m0)); + BOOST_TEST(lk1.mutex() == &m0); + BOOST_TEST(lk1.owns_lock() == true); + } + return boost::report_errors(); + +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_pass.cpp new file mode 100644 index 000000000..cf682fbd4 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// unique_lock(unique_lock&& u); + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::mutex m; + +int main() +{ + { + boost::unique_lock<boost::mutex> lk0(m); + boost::unique_lock<boost::mutex> lk( (boost::move(lk0))); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::unique_lock<boost::mutex> lk( (BOOST_THREAD_MAKE_RV_REF(boost::unique_lock<boost::mutex>(m)))); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + } + { + boost::unique_lock<boost::mutex> lk0(m, boost::defer_lock); + boost::unique_lock<boost::mutex> lk( (boost::move(lk0))); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::unique_lock<boost::mutex> lk0(m, boost::defer_lock); + lk0.release(); + boost::unique_lock<boost::mutex> lk( (boost::move(lk0))); + BOOST_TEST(lk.mutex() == 0); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_for_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_for_pass.cpp new file mode 100644 index 000000000..0e61cb1a7 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_for_pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// template <class Rep, class Period> +// unique_lock(shared_lock<mutex_type>&&, +// const chrono::duration<Rep, Period>&); + +#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS +#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION +#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m; + +int main() +{ + { + boost::shared_lock<boost::shared_mutex> lk0(m); + boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::unique_lock<boost::shared_mutex> + lk(boost::shared_lock<boost::shared_mutex>(m), boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + } + { + boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock); + boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock); + lk0.release(); + boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == 0); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_pass.cpp new file mode 100644 index 000000000..3068866f0 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_try_pass.cpp @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// unique_lock(shared_lock&& u, try_to_lock); + +#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS +#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION +#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m; + +int main() +{ + { + boost::shared_lock<boost::shared_mutex> lk0(m); + boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock ); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::unique_lock<boost::shared_mutex> lk(boost::shared_lock<boost::shared_mutex>(m), boost::try_to_lock); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + } + { + boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock); + boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock); + lk0.release(); + boost::unique_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock); + BOOST_TEST(lk.mutex() == 0); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_until_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_until_pass.cpp new file mode 100644 index 000000000..f1e54cf45 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_shared_lock_until_pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// template <class Clock, class Duration> +// unique_lock(shared_lock<mutex_type>&&, +// const chrono::time_point<Clock, Duration>&); + +#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS +#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION +#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m; + +int main() +{ + { + boost::shared_lock<boost::shared_mutex> lk0(m); + boost::unique_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::unique_lock<boost::shared_mutex> + lk( boost::shared_lock<boost::shared_mutex>(m), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + } + { + boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock); + boost::unique_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock); + lk0.release(); + boost::unique_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == 0); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_for_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_for_pass.cpp new file mode 100644 index 000000000..7437ee0e7 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_for_pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// template <class Clock, class Duration> +// unique_lock(shared_lock<mutex_type>&&, +// const chrono::duration<Rep, Period>&); + +#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::upgrade_mutex m; + +int main() +{ + { + boost::upgrade_lock<boost::upgrade_mutex> lk0(m); + boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::unique_lock<boost::upgrade_mutex> + lk(boost::upgrade_lock<boost::upgrade_mutex>(m), boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + } + { + boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock); + boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock); + lk0.release(); + boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == 0); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_pass.cpp new file mode 100644 index 000000000..c72067ae9 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_pass.cpp @@ -0,0 +1,63 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// unique_lock(upgrade_lock&& u); + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::upgrade_mutex m; + +int main() +{ + { + boost::upgrade_lock<boost::upgrade_mutex> lk0(m); + boost::unique_lock<boost::upgrade_mutex> lk( (boost::move(lk0))); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::unique_lock<boost::upgrade_mutex> lk( (BOOST_THREAD_MAKE_RV_REF(boost::upgrade_lock<boost::upgrade_mutex>(m)))); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + } + { + boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock); + boost::unique_lock<boost::upgrade_mutex> lk( (boost::move(lk0))); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock); + lk0.release(); + boost::unique_lock<boost::upgrade_mutex> lk( (boost::move(lk0))); + BOOST_TEST(lk.mutex() == 0); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_try_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_try_pass.cpp new file mode 100644 index 000000000..fdbdf2165 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_try_pass.cpp @@ -0,0 +1,64 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// unique_lock(upgrade_lock&& u, try_to_lock); + +#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::upgrade_mutex m; + +int main() +{ + { + boost::upgrade_lock<boost::upgrade_mutex> lk0(m); + boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::try_to_lock ); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::unique_lock<boost::upgrade_mutex> lk(boost::upgrade_lock<boost::upgrade_mutex>(m), boost::try_to_lock); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + } + { + boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock); + boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::try_to_lock); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock); + lk0.release(); + boost::unique_lock<boost::upgrade_mutex> lk(boost::move(lk0), boost::try_to_lock); + BOOST_TEST(lk.mutex() == 0); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_until_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_until_pass.cpp new file mode 100644 index 000000000..cd33f709c --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/move_ctor_upgrade_lock_until_pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// template <class Clock, class Duration> +// unique_lock(shared_lock<mutex_type>&&, +// const chrono::time_point<Clock, Duration>&); + +#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::upgrade_mutex m; + +int main() +{ + { + boost::upgrade_lock<boost::upgrade_mutex> lk0(m); + boost::unique_lock<boost::upgrade_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::unique_lock<boost::upgrade_mutex> + lk( boost::upgrade_lock<boost::upgrade_mutex>(m), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + } + { + boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock); + boost::unique_lock<boost::upgrade_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::upgrade_lock<boost::upgrade_mutex> lk0(m, boost::defer_lock); + lk0.release(); + boost::unique_lock<boost::upgrade_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == 0); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/mutex_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/mutex_pass.cpp new file mode 100644 index 000000000..d5b7ca295 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/mutex_pass.cpp @@ -0,0 +1,90 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// explicit unique_lock(Mutex& m); + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <iostream> +#include "../../../../../timming.hpp" + + +boost::mutex m; + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + { + boost::unique_lock<boost::mutex> ul(m); + t1 = Clock::now(); + } +#else + //time_point t0 = Clock::now(); + //time_point t1; + { + boost::unique_lock<boost::mutex> ul(m); + //t1 = Clock::now(); + } + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#else +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} + + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/time_point_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/time_point_pass.cpp new file mode 100644 index 000000000..53358de6e --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/time_point_pass.cpp @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// template <class Clock, class Duration> +// unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time); + +#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../../../timming.hpp" + +#if defined BOOST_THREAD_USES_CHRONO + +boost::timed_mutex m; + +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f1() +{ + t0 = Clock::now(); + boost::unique_lock<boost::timed_mutex> lk(m, Clock::now() + ms(750)); + BOOST_TEST(lk.owns_lock() == true); + t1 = Clock::now(); +} + +void f2() +{ + t0 = Clock::now(); + boost::unique_lock<boost::timed_mutex> lk(m, Clock::now() + ms(250)); + BOOST_TEST(lk.owns_lock() == false); + t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + BOOST_TEST(d < max_diff); +} + +int main() +{ + { + m.lock(); + boost::thread t(f1); + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); + m.unlock(); + t.join(); + + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); + } + { + m.lock(); + boost::thread t(f2); + boost::this_thread::sleep_for(ms(750)); + m.unlock(); + t.join(); + } + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/try_to_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/try_to_lock_pass.cpp new file mode 100644 index 000000000..0f0c8ded4 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/cons/try_to_lock_pass.cpp @@ -0,0 +1,120 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// unique_lock(mutex_type& m, try_to_lock_t); + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../../../timming.hpp" + + +boost::mutex m; + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + { + boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock); + BOOST_TEST(lk.owns_lock() == false); + } + { + boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock); + BOOST_TEST(lk.owns_lock() == false); + } + { + boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock); + BOOST_TEST(lk.owns_lock() == false); + } + for (;;) + { + boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock); + if (lk.owns_lock()) { + t1 = Clock::now(); + break; + } + } + //m.unlock(); +#else +// time_point t0 = Clock::now(); +// { +// boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock); +// BOOST_TEST(lk.owns_lock() == false); +// } +// { +// boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock); +// BOOST_TEST(lk.owns_lock() == false); +// } +// { +// boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock); +// BOOST_TEST(lk.owns_lock() == false); +// } + for (;;) + { + boost::unique_lock<boost::mutex> lk(m, boost::try_to_lock); + if (lk.owns_lock()) break; + } + //time_point t1 = Clock::now(); + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#else +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + std::cout << "d_ns: " << d_ns.count() << std::endl; + std::cout << "d_ms: " << d_ms.count() << std::endl; + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/lock_pass.cpp new file mode 100644 index 000000000..94edb4342 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/lock_pass.cpp @@ -0,0 +1,127 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// void lock(); + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <iostream> +#include "../../../../../timming.hpp" + +boost::mutex m; + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + boost::unique_lock < boost::mutex > lk(m, boost::defer_lock); + t0 = Clock::now(); + lk.lock(); + t1 = Clock::now(); + BOOST_TEST(lk.owns_lock() == true); + try + { + lk.lock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur); + } + lk.unlock(); + lk.release(); + try + { + lk.lock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted); + } +#else + boost::unique_lock < boost::mutex > lk(m, boost::defer_lock); + //time_point t0 = Clock::now(); + lk.lock(); + //time_point t1 = Clock::now(); + BOOST_TEST(lk.owns_lock() == true); + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); + try + { + lk.lock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur); + } + lk.unlock(); + lk.release(); + try + { + lk.lock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted); + } +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#else +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} + + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_for_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_for_pass.cpp new file mode 100644 index 000000000..2be8416eb --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_for_pass.cpp @@ -0,0 +1,85 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// template <class Rep, class Period> +// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); + +#include <boost/thread/lock_types.hpp> +//#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +#if defined BOOST_THREAD_USES_CHRONO + + +bool try_lock_for_called = false; + +typedef boost::chrono::milliseconds ms; + +struct mutex +{ + template <class Rep, class Period> + bool try_lock_for(const boost::chrono::duration<Rep, Period>& rel_time) + { + BOOST_TEST(rel_time == ms(5)); + try_lock_for_called = !try_lock_for_called; + return try_lock_for_called; + } + void unlock() + { + } +}; + +mutex m; + +int main() +{ + boost::unique_lock<mutex> lk(m, boost::defer_lock); + BOOST_TEST(lk.try_lock_for(ms(5)) == true); + BOOST_TEST(try_lock_for_called == true); + BOOST_TEST(lk.owns_lock() == true); + try + { + lk.try_lock_for(ms(5)); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur); + } + lk.unlock(); + BOOST_TEST(lk.try_lock_for(ms(5)) == false); + BOOST_TEST(try_lock_for_called == false); + BOOST_TEST(lk.owns_lock() == false); + lk.release(); + try + { + lk.try_lock_for(ms(5)); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted); + } + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_pass.cpp new file mode 100644 index 000000000..8553c1c0b --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_pass.cpp @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// template <class Rep, class Period> +// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); + +#include <boost/thread/lock_types.hpp> +//#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +bool try_lock_called = false; + +struct mutex +{ + bool try_lock() + { + try_lock_called = !try_lock_called; + return try_lock_called; + } + void unlock() + { + } +}; + +mutex m; + +int main() +{ + boost::unique_lock<mutex> lk(m, boost::defer_lock); + BOOST_TEST(lk.try_lock() == true); + BOOST_TEST(try_lock_called == true); + BOOST_TEST(lk.owns_lock() == true); + try + { + lk.try_lock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur); + } + lk.unlock(); + BOOST_TEST(lk.try_lock() == false); + BOOST_TEST(try_lock_called == false); + BOOST_TEST(lk.owns_lock() == false); + lk.release(); + try + { + lk.try_lock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted); + } + + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_until_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_until_pass.cpp new file mode 100644 index 000000000..df6e7369e --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/try_lock_until_pass.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// template <class Clock, class Duration> +// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +#if defined BOOST_THREAD_USES_CHRONO + + +bool try_lock_until_called = false; + +struct mutex +{ + template <class Clock, class Duration> + bool try_lock_until(const boost::chrono::time_point<Clock, Duration>& abs_time) + { + typedef boost::chrono::milliseconds ms; + BOOST_TEST(Clock::now() - abs_time < ms(5)); + try_lock_until_called = !try_lock_until_called; + return try_lock_until_called; + } + void unlock() + { + } +}; + +mutex m; + +int main() +{ + typedef boost::chrono::steady_clock Clock; + boost::unique_lock<mutex> lk(m, boost::defer_lock); + BOOST_TEST(lk.try_lock_until(Clock::now()) == true); + BOOST_TEST(try_lock_until_called == true); + BOOST_TEST(lk.owns_lock() == true); + try + { + lk.try_lock_until(Clock::now()); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur); + } + lk.unlock(); + BOOST_TEST(lk.try_lock_until(Clock::now()) == false); + BOOST_TEST(try_lock_until_called == false); + BOOST_TEST(lk.owns_lock() == false); + lk.release(); + try + { + lk.try_lock_until(Clock::now()); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted); + } + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/unlock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/unlock_pass.cpp new file mode 100644 index 000000000..4ad954f24 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/locking/unlock_pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// bool unlock(); + +#include <boost/thread/lock_types.hpp> +//#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + + +bool unlock_called = false; + +struct mutex +{ + void lock() + { + } + void unlock() + { + unlock_called = true; + } +}; + +mutex m; + +int main() +{ + boost::unique_lock<mutex> lk(m); + lk.unlock(); + BOOST_TEST(unlock_called == true); + BOOST_TEST(lk.owns_lock() == false); + try + { + lk.unlock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted); + } + lk.release(); + try + { + lk.unlock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/member_swap_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/member_swap_pass.cpp new file mode 100644 index 000000000..617682fe3 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/member_swap_pass.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// void swap(unique_lock& u); + +#include <boost/thread/lock_types.hpp> +#include <boost/detail/lightweight_test.hpp> + +struct mutex +{ + void lock() + { + } + void unlock() + { + } +}; + +mutex m; + +int main() +{ + boost::unique_lock<mutex> lk1(m); + boost::unique_lock<mutex> lk2; + lk1.swap(lk2); + BOOST_TEST(lk1.mutex() == 0); + BOOST_TEST(lk1.owns_lock() == false); + BOOST_TEST(lk2.mutex() == &m); + BOOST_TEST(lk2.owns_lock() == true); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/non_member_swap_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/non_member_swap_pass.cpp new file mode 100644 index 000000000..74ba5ff3f --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/non_member_swap_pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> +// void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y); + +#include <boost/thread/lock_types.hpp> +#include <boost/detail/lightweight_test.hpp> + +struct mutex +{ + void lock() + { + } + void unlock() + { + } +}; + +mutex m; + +int main() +{ + boost::unique_lock<mutex> lk1(m); + boost::unique_lock<mutex> lk2; + swap(lk1, lk2); + BOOST_TEST(lk1.mutex() == 0); + BOOST_TEST(lk1.owns_lock() == false); + BOOST_TEST(lk2.mutex() == &m); + BOOST_TEST(lk2.owns_lock() == true); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/release_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/release_pass.cpp new file mode 100644 index 000000000..63c3831e5 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/mod/release_pass.cpp @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// void Mutex* release(); + +#include <boost/thread/lock_types.hpp> +#include <boost/detail/lightweight_test.hpp> + +struct mutex +{ + static int lock_count; + static int unlock_count; + void lock() + { + ++lock_count; + } + void unlock() + { + ++unlock_count; + } +}; + +int mutex::lock_count = 0; +int mutex::unlock_count = 0; + +mutex m; + +int main() +{ + boost::unique_lock<mutex> lk(m); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + BOOST_TEST(mutex::lock_count == 1); + BOOST_TEST(mutex::unlock_count == 0); + BOOST_TEST(lk.release() == &m); + BOOST_TEST(lk.mutex() == 0); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(mutex::lock_count == 1); + BOOST_TEST(mutex::unlock_count == 0); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/mutex_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/mutex_pass.cpp new file mode 100644 index 000000000..68f1bbb6d --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/mutex_pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// Mutex *mutex() const; + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::mutex m; + +int main() +{ + boost::unique_lock<boost::mutex> lk0; + BOOST_TEST(lk0.mutex() == 0); + boost::unique_lock<boost::mutex> lk1(m); + BOOST_TEST(lk1.mutex() == &m); + lk1.unlock(); + BOOST_TEST(lk1.mutex() == &m); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/op_bool_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/op_bool_pass.cpp new file mode 100644 index 000000000..3fa18225a --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/op_bool_pass.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// explicit operator bool() const; + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::mutex m; + +int main() +{ + { + boost::unique_lock<boost::mutex> lk0; + BOOST_TEST(bool(lk0) == false); + boost::unique_lock<boost::mutex> lk1(m); + BOOST_TEST(bool(lk1) == true); + lk1.unlock(); + BOOST_TEST(bool(lk1) == false); + } + + { + boost::unique_lock<boost::mutex> lk0; + if (lk0) BOOST_TEST(false); + boost::unique_lock<boost::mutex> lk1(m); + if (!lk1) BOOST_TEST(false); + lk1.unlock(); + if (lk1) BOOST_TEST(false); + } + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/op_int_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/op_int_fail.cpp new file mode 100644 index 000000000..92fe0ffcb --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/op_int_fail.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// explicit operator bool() const; + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::mutex m; + +int main() +{ + { + boost::unique_lock<boost::mutex> lk0; + int i = int(lk0); + BOOST_TEST(i == 0); + } + + return boost::report_errors(); +} + +#include "../../../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/owns_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/owns_lock_pass.cpp new file mode 100644 index 000000000..6a9f019aa --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/obs/owns_lock_pass.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class unique_lock; + +// bool owns_lock() const; + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + + +int main() +{ + boost::mutex m; + + boost::unique_lock<boost::mutex> lk0; + BOOST_TEST(lk0.owns_lock() == false); + boost::unique_lock<boost::mutex> lk1(m); + BOOST_TEST(lk1.owns_lock() == true); + lk1.unlock(); + BOOST_TEST(lk1.owns_lock() == false); + + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/types_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/types_pass.cpp new file mode 100644 index 000000000..69b963a6f --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/unique_lock/types_pass.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/mutex.hpp> + +// <mutex> + +// template <class Mutex> +// class unique_lock +// { +// public: +// typedef Mutex mutex_type; +// ... +// }; + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/static_assert.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::unique_lock<boost::mutex>::mutex_type, + boost::mutex>::value), ""); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/adopt_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/adopt_lock_pass.cpp new file mode 100644 index 000000000..1822fe0b6 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/adopt_lock_pass.cpp @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// upgrade_lock(mutex_type& m, adopt_lock_t); + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + + +int main() +{ + boost::shared_mutex m; + m.lock_upgrade(); + boost::upgrade_lock<boost::shared_mutex> lk(m, boost::adopt_lock); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/copy_assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/copy_assign_fail.cpp new file mode 100644 index 000000000..521304d81 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/copy_assign_fail.cpp @@ -0,0 +1,41 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// upgrade_lock& operator=(upgrade_lock const&) = delete; + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m0; +boost::shared_mutex m1; + +int main() +{ + boost::upgrade_lock<boost::shared_mutex> lk0(m0); + boost::upgrade_lock<boost::shared_mutex> lk1(m1); + lk1 = lk0; + BOOST_TEST(lk1.mutex() == &m0); + BOOST_TEST(lk1.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + +} + +#include "../../../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/copy_ctor_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/copy_ctor_fail.cpp new file mode 100644 index 000000000..8e20196b1 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/copy_ctor_fail.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// upgrade_lock(upgrade_lock const&) = delete; + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m0; +boost::shared_mutex m1; + +int main() +{ + boost::upgrade_lock<boost::shared_mutex> lk0(m0); + boost::upgrade_lock<boost::shared_mutex> lk1(lk0); + BOOST_TEST(lk1.mutex() == &m1); + BOOST_TEST(lk1.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); +} + +#include "../../../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/default_pass.cpp new file mode 100644 index 000000000..59ea2a9a2 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/default_pass.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// upgrade_lock(upgrade_lock const&) = delete; + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::upgrade_lock<boost::shared_mutex> ul; + BOOST_TEST(!ul.owns_lock()); + BOOST_TEST(ul.mutex() == 0); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/defer_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/defer_lock_pass.cpp new file mode 100644 index 000000000..ececb845c --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/defer_lock_pass.cpp @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// upgrade_lock(mutex_type& m, adopt_lock_t); + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::shared_mutex m; + m.lock(); + boost::upgrade_lock<boost::shared_mutex> lk(m, boost::defer_lock); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == false); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/duration_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/duration_pass.cpp new file mode 100644 index 000000000..b6506b9b3 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/duration_pass.cpp @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// template <class Rep, class Period> +// upgrade_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time); + +#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/chrono/chrono_io.hpp> +#include "../../../../../timming.hpp" + +boost::shared_mutex m; + +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f1() +{ + t0 = Clock::now(); + boost::upgrade_lock<boost::shared_mutex> lk(m, ms(750)); + BOOST_TEST(lk.owns_lock() == true); + t1 = Clock::now(); +} + +void f2() +{ + t0 = Clock::now(); + boost::upgrade_lock<boost::shared_mutex> lk(m, ms(250)); + BOOST_TEST(lk.owns_lock() == false); + t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + BOOST_THREAD_TEST_IT(d, ns(max_diff)); +} + +int main() +{ + { + m.lock(); + boost::thread t(f1); + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); + m.unlock(); + t.join(); + + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); + } + { + m.lock(); + boost::thread t(f2); + boost::this_thread::sleep_for(ms(750)); + m.unlock(); + t.join(); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_assign_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_assign_pass.cpp new file mode 100644 index 000000000..42ef355c9 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_assign_pass.cpp @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/shared_mutex.hpp> + +// template <class Mutex> class upgrade_lock; + +// upgrade_lock(upgrade_lock const&) = delete; + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m0; +boost::shared_mutex m1; + +int main() +{ + { + boost::upgrade_lock<boost::shared_mutex> lk0(m0); + boost::upgrade_lock<boost::shared_mutex> lk1(m1); + lk1 = boost::move(lk0); + BOOST_TEST(lk1.mutex() == &m0); + BOOST_TEST(lk1.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + + boost::upgrade_lock<boost::shared_mutex> lk1; + lk1 = BOOST_THREAD_MAKE_RV_REF(boost::upgrade_lock<boost::shared_mutex>(m0)); + BOOST_TEST(lk1.mutex() == &m0); + BOOST_TEST(lk1.owns_lock() == true); + } + { + boost::unique_lock<boost::shared_mutex> lk0(m0); + boost::upgrade_lock<boost::shared_mutex> lk1(m1); + lk1 = BOOST_THREAD_MAKE_RV_REF(boost::upgrade_lock<boost::shared_mutex>(boost::move(lk0))); + BOOST_TEST(lk1.mutex() == &m0); + BOOST_TEST(lk1.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + + boost::upgrade_lock<boost::shared_mutex> lk1; + lk1 = BOOST_THREAD_MAKE_RV_REF(boost::upgrade_lock<boost::shared_mutex>(boost::unique_lock<boost::shared_mutex>(m0))); + BOOST_TEST(lk1.mutex() == &m0); + BOOST_TEST(lk1.owns_lock() == true); + } + return boost::report_errors(); + +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_pass.cpp new file mode 100644 index 000000000..5d5c0a948 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// upgrade_lock& operator=(upgrade_lock&& u); + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m; + +int main() +{ + { + boost::upgrade_lock<boost::shared_mutex> lk0(m); + boost::upgrade_lock<boost::shared_mutex> lk( (boost::move(lk0))); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::upgrade_lock<boost::shared_mutex> lk( (BOOST_THREAD_MAKE_RV_REF(boost::upgrade_lock<boost::shared_mutex>(m)))); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_for_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_for_pass.cpp new file mode 100644 index 000000000..ccad7b1ac --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_for_pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// template <class Clock, class Duration> +// upgrade_lock(shared_lock<mutex_type>&&, +// const chrono::duration<Rep, Period>&); + +#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS +#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION +#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m; + +int main() +{ + { + boost::shared_lock<boost::shared_mutex> lk0(m); + boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::upgrade_lock<boost::shared_mutex> + lk(boost::shared_lock<boost::shared_mutex>(m), boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + } + { + boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock); + boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock); + lk0.release(); + boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == 0); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_try_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_try_pass.cpp new file mode 100644 index 000000000..93deda8c3 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_try_pass.cpp @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// upgrade_lock(shared_lock&& u, try_to_lock); + +#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS +#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION +#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m; + +int main() +{ + { + boost::shared_lock<boost::shared_mutex> lk0(m); + boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock ); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::upgrade_lock<boost::shared_mutex> lk(boost::shared_lock<boost::shared_mutex>(m), boost::try_to_lock); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + } + { + boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock); + boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock); + lk0.release(); + boost::upgrade_lock<boost::shared_mutex> lk(boost::move(lk0), boost::try_to_lock); + BOOST_TEST(lk.mutex() == 0); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_until_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_until_pass.cpp new file mode 100644 index 000000000..3d2c2871b --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_shared_lock_until_pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// template <class Clock, class Duration> +// upgrade_lock(shared_lock<mutex_type>&&, +// const chrono::time_point<Clock, Duration>&); + +#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS +#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION +#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m; + +int main() +{ + { + boost::shared_lock<boost::shared_mutex> lk0(m); + boost::upgrade_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::upgrade_lock<boost::shared_mutex> + lk( boost::shared_lock<boost::shared_mutex>(m), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + } + { + boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock); + boost::upgrade_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::shared_lock<boost::shared_mutex> lk0(m, boost::defer_lock); + lk0.release(); + boost::upgrade_lock<boost::shared_mutex> lk( boost::move(lk0), boost::chrono::steady_clock::now()+boost::chrono::milliseconds(1)); + BOOST_TEST(lk.mutex() == 0); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_unique_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_unique_lock_pass.cpp new file mode 100644 index 000000000..3d591d176 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/move_ctor_unique_lock_pass.cpp @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// upgrade_lock& operator=(unique_lock&& u); + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m; + +int main() +{ + { + boost::unique_lock<boost::shared_mutex> lk0(m); + boost::upgrade_lock<boost::shared_mutex> lk( (boost::move(lk0))); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + BOOST_TEST(lk0.mutex() == 0); + BOOST_TEST(lk0.owns_lock() == false); + } + { + boost::upgrade_lock<boost::shared_mutex> lk( (boost::unique_lock<boost::shared_mutex>(m))); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/mutex_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/mutex_pass.cpp new file mode 100644 index 000000000..1e634807d --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/mutex_pass.cpp @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// explicit upgrade_lock(Mutex& m); + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <iostream> +#include "../../../../../timming.hpp" + +boost::shared_mutex m; + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + { + boost::upgrade_lock<boost::shared_mutex> ul(m); + t1 = Clock::now(); + } +#else + //time_point t0 = Clock::now(); + //time_point t1; + { + boost::upgrade_lock<boost::shared_mutex> ul(m); + //t1 = Clock::now(); + } + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#else +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/time_point_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/time_point_pass.cpp new file mode 100644 index 000000000..4cf71476b --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/time_point_pass.cpp @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// template <class Clock, class Duration> +// upgrade_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time); + +#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../../../timming.hpp" + +boost::shared_mutex m; + +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f1() +{ + t0 = Clock::now(); + boost::upgrade_lock<boost::shared_mutex> lk(m, Clock::now() + ms(750)); + BOOST_TEST(lk.owns_lock() == true); + t1 = Clock::now(); +} + +void f2() +{ + t0 = Clock::now(); + boost::upgrade_lock<boost::shared_mutex> lk(m, Clock::now() + ms(250)); + BOOST_TEST(lk.owns_lock() == false); + t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + BOOST_THREAD_TEST_IT(d, ns(max_diff)); +} + +int main() +{ + { + m.lock(); + boost::thread t(f1); + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); + m.unlock(); + t.join(); + + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); + } + { + m.lock(); + boost::thread t(f2); + boost::this_thread::sleep_for(ms(750)); + m.unlock(); + t.join(); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/try_to_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/try_to_lock_pass.cpp new file mode 100644 index 000000000..9a7fe26bf --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/cons/try_to_lock_pass.cpp @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// upgrade_lock(mutex_type& m, try_to_lock_t); + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../../../timming.hpp" + +boost::shared_mutex m; + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + { + boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock); + BOOST_TEST(lk.owns_lock() == false); + } + { + boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock); + BOOST_TEST(lk.owns_lock() == false); + } + { + boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock); + BOOST_TEST(lk.owns_lock() == false); + } + for (;;) + { + boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock); + if (lk.owns_lock()) { + t1 = Clock::now(); + break; + } + } + //m.unlock(); +#else +// time_point t0 = Clock::now(); +// { +// boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock); +// BOOST_TEST(lk.owns_lock() == false); +// } +// { +// boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock); +// BOOST_TEST(lk.owns_lock() == false); +// } +// { +// boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock); +// BOOST_TEST(lk.owns_lock() == false); +// } + for (;;) + { + boost::upgrade_lock<boost::shared_mutex> lk(m, boost::try_to_lock); + if (lk.owns_lock()) break; + } + //time_point t1 = Clock::now(); + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#else +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/lock_pass.cpp new file mode 100644 index 000000000..2ff49ac96 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/lock_pass.cpp @@ -0,0 +1,126 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// void lock(); + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <iostream> +#include "../../../../../timming.hpp" + +boost::shared_mutex m; + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + boost::upgrade_lock < boost::shared_mutex > lk(m, boost::defer_lock); + t0 = Clock::now(); + lk.lock(); + t1 = Clock::now(); + BOOST_TEST(lk.owns_lock() == true); + try + { + lk.lock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur); + } + lk.unlock(); + lk.release(); + try + { + lk.lock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted); + } +#else + boost::upgrade_lock < boost::shared_mutex > lk(m, boost::defer_lock); + //time_point t0 = Clock::now(); + lk.lock(); + //time_point t1 = Clock::now(); + BOOST_TEST(lk.owns_lock() == true); + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); + try + { + lk.lock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur); + } + lk.unlock(); + lk.release(); + try + { + lk.lock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted); + } +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#else +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_for_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_for_pass.cpp new file mode 100644 index 000000000..5f8f4f5fe --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_for_pass.cpp @@ -0,0 +1,78 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// template <class Rep, class Period> +// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); + +#include <boost/thread/lock_types.hpp> +//#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +bool try_lock_for_called = false; + +typedef boost::chrono::milliseconds ms; + +struct shared_mutex +{ + template <class Rep, class Period> + bool try_lock_upgrade_for(const boost::chrono::duration<Rep, Period>& rel_time) + { + BOOST_TEST(rel_time == ms(5)); + try_lock_for_called = !try_lock_for_called; + return try_lock_for_called; + } + void unlock_upgrade() + { + } +}; + +shared_mutex m; + +int main() +{ + boost::upgrade_lock<shared_mutex> lk(m, boost::defer_lock); + BOOST_TEST(lk.try_lock_for(ms(5)) == true); + BOOST_TEST(try_lock_for_called == true); + BOOST_TEST(lk.owns_lock() == true); + try + { + lk.try_lock_for(ms(5)); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur); + } + lk.unlock(); + BOOST_TEST(lk.try_lock_for(ms(5)) == false); + BOOST_TEST(try_lock_for_called == false); + BOOST_TEST(lk.owns_lock() == false); + lk.release(); + try + { + lk.try_lock_for(ms(5)); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_pass.cpp new file mode 100644 index 000000000..820fd71a3 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_pass.cpp @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// template <class Rep, class Period> +// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); + +#include <boost/thread/lock_types.hpp> +//#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +bool try_lock_called = false; + +struct shared_mutex +{ + bool try_lock_upgrade() + { + try_lock_called = !try_lock_called; + return try_lock_called; + } + void unlock_upgrade() + { + } +}; + +shared_mutex m; + +int main() +{ + boost::upgrade_lock<shared_mutex> lk(m, boost::defer_lock); + BOOST_TEST(lk.try_lock() == true); + BOOST_TEST(try_lock_called == true); + BOOST_TEST(lk.owns_lock() == true); + try + { + lk.try_lock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur); + } + lk.unlock(); + BOOST_TEST(lk.try_lock() == false); + BOOST_TEST(try_lock_called == false); + BOOST_TEST(lk.owns_lock() == false); + lk.release(); + try + { + lk.try_lock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_until_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_until_pass.cpp new file mode 100644 index 000000000..1c53d6a5b --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/try_lock_until_pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// template <class Clock, class Duration> +// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +bool try_lock_until_called = false; + +struct shared_mutex +{ + template <class Clock, class Duration> + bool try_lock_upgrade_until(const boost::chrono::time_point<Clock, Duration>& abs_time) + { + typedef boost::chrono::milliseconds ms; + BOOST_TEST(Clock::now() - abs_time < ms(5)); + try_lock_until_called = !try_lock_until_called; + return try_lock_until_called; + } + void unlock_upgrade() + { + } +}; + +shared_mutex m; + +int main() +{ + typedef boost::chrono::steady_clock Clock; + boost::upgrade_lock<shared_mutex> lk(m, boost::defer_lock); + BOOST_TEST(lk.try_lock_until(Clock::now()) == true); + BOOST_TEST(try_lock_until_called == true); + BOOST_TEST(lk.owns_lock() == true); + try + { + lk.try_lock_until(Clock::now()); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::resource_deadlock_would_occur); + } + lk.unlock(); + BOOST_TEST(lk.try_lock_until(Clock::now()) == false); + BOOST_TEST(try_lock_until_called == false); + BOOST_TEST(lk.owns_lock() == false); + lk.release(); + try + { + lk.try_lock_until(Clock::now()); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted); + } + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/unlock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/unlock_pass.cpp new file mode 100644 index 000000000..bc49a0433 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/locking/unlock_pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// template <class Rep, class Period> +// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); + +#include <boost/thread/lock_types.hpp> +//#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +bool unlock_called = false; + +struct shared_mutex +{ + void lock_upgrade() + { + } + void unlock_upgrade() + { + unlock_called = true; + } +}; + +shared_mutex m; + +int main() +{ + boost::upgrade_lock<shared_mutex> lk(m); + lk.unlock(); + BOOST_TEST(unlock_called == true); + BOOST_TEST(lk.owns_lock() == false); + try + { + lk.unlock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted); + } + lk.release(); + try + { + lk.unlock(); + BOOST_TEST(false); + } + catch (boost::system::system_error& e) + { + BOOST_TEST(e.code().value() == boost::system::errc::operation_not_permitted); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/member_swap_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/member_swap_pass.cpp new file mode 100644 index 000000000..4b0752ef5 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/member_swap_pass.cpp @@ -0,0 +1,48 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// void swap(upgrade_lock& u); + +#include <boost/thread/lock_types.hpp> +#include <boost/detail/lightweight_test.hpp> + +struct shared_mutex +{ + void lock_upgrade() + { + } + void unlock_upgrade() + { + } +}; + +shared_mutex m; + +int main() +{ + boost::upgrade_lock<shared_mutex> lk1(m); + boost::upgrade_lock<shared_mutex> lk2; + lk1.swap(lk2); + BOOST_TEST(lk1.mutex() == 0); + BOOST_TEST(lk1.owns_lock() == false); + BOOST_TEST(lk2.mutex() == &m); + BOOST_TEST(lk2.owns_lock() == true); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/non_member_swap_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/non_member_swap_pass.cpp new file mode 100644 index 000000000..c7ebaa271 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/non_member_swap_pass.cpp @@ -0,0 +1,47 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> +// void swap(upgrade_lock<Mutex>& x, upgrade_lock<Mutex>& y); + +#include <boost/thread/lock_types.hpp> +#include <boost/detail/lightweight_test.hpp> + +struct shared_mutex +{ + void lock_upgrade() + { + } + void unlock_upgrade() + { + } +}; + +shared_mutex m; + +int main() +{ + boost::upgrade_lock<shared_mutex> lk1(m); + boost::upgrade_lock<shared_mutex> lk2; + swap(lk1, lk2); + BOOST_TEST(lk1.mutex() == 0); + BOOST_TEST(lk1.owns_lock() == false); + BOOST_TEST(lk2.mutex() == &m); + BOOST_TEST(lk2.owns_lock() == true); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/release_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/release_pass.cpp new file mode 100644 index 000000000..226819446 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/mod/release_pass.cpp @@ -0,0 +1,58 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// void Mutex* release(); + +#include <boost/thread/lock_types.hpp> +#include <boost/detail/lightweight_test.hpp> + +struct shared_mutex +{ + static int lock_count; + static int unlock_count; + void lock_upgrade() + { + ++lock_count; + } + void unlock_upgrade() + { + ++unlock_count; + } +}; + +int shared_mutex::lock_count = 0; +int shared_mutex::unlock_count = 0; + +shared_mutex m; + +int main() +{ + boost::upgrade_lock<shared_mutex> lk(m); + BOOST_TEST(lk.mutex() == &m); + BOOST_TEST(lk.owns_lock() == true); + BOOST_TEST(shared_mutex::lock_count == 1); + BOOST_TEST(shared_mutex::unlock_count == 0); + BOOST_TEST(lk.release() == &m); + BOOST_TEST(lk.mutex() == 0); + BOOST_TEST(lk.owns_lock() == false); + BOOST_TEST(shared_mutex::lock_count == 1); + BOOST_TEST(shared_mutex::unlock_count == 0); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/mutex_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/mutex_pass.cpp new file mode 100644 index 000000000..276cd0a93 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/mutex_pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// Mutex *mutex() const; + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m; + +int main() +{ + boost::upgrade_lock<boost::shared_mutex> lk0; + BOOST_TEST(lk0.mutex() == 0); + boost::upgrade_lock<boost::shared_mutex> lk1(m); + BOOST_TEST(lk1.mutex() == &m); + lk1.unlock(); + BOOST_TEST(lk1.mutex() == &m); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/op_bool_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/op_bool_pass.cpp new file mode 100644 index 000000000..4e722d174 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/op_bool_pass.cpp @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// explicit operator bool() const; + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m; + +int main() +{ + boost::upgrade_lock < boost::shared_mutex > lk0; + BOOST_TEST(bool(lk0) == false); + boost::upgrade_lock < boost::shared_mutex > lk1(m); + BOOST_TEST(bool(lk1) == true); + lk1.unlock(); + BOOST_TEST(bool(lk1) == false); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/owns_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/owns_lock_pass.cpp new file mode 100644 index 000000000..9d8b80d69 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/obs/owns_lock_pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/locks.hpp> + +// template <class Mutex> class upgrade_lock; + +// bool owns_lock() const; + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +boost::shared_mutex m; + +int main() +{ + boost::upgrade_lock<boost::shared_mutex> lk0; + BOOST_TEST(lk0.owns_lock() == false); + boost::upgrade_lock<boost::shared_mutex> lk1(m); + BOOST_TEST(lk1.owns_lock() == true); + lk1.unlock(); + BOOST_TEST(lk1.owns_lock() == false); + + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/types_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/types_pass.cpp new file mode 100644 index 000000000..876428e46 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/locks/upgrade_lock/types_pass.cpp @@ -0,0 +1,40 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/mutex.hpp> + +// <mutex> + +// template <class Mutex> +// class upgrade_lock +// { +// public: +// typedef Mutex mutex_type; +// ... +// }; + + +#include <boost/thread/lock_types.hpp> +#include <boost/thread/shared_mutex.hpp> +#include <boost/static_assert.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + BOOST_STATIC_ASSERT_MSG((boost::is_same<boost::upgrade_lock<boost::upgrade_mutex>::mutex_type, + boost::upgrade_mutex>::value), ""); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/assign_fail.cpp new file mode 100644 index 000000000..fa1aff9b5 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/assign_fail.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/mutex.hpp> + +// class mutex; + +// mutex& operator=(const mutex&) = delete; + +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::mutex m0; + boost::mutex m1(m0); +} + +#include "../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/copy_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/copy_fail.cpp new file mode 100644 index 000000000..e6f6d6b88 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/copy_fail.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/mutex.hpp> + +// class mutex; + +// mutex(const mutex&) = delete; + +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::mutex m0; + boost::mutex m1(m0); +} + +#include "../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/default_pass.cpp new file mode 100644 index 000000000..a911eefcf --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/default_pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/mutex.hpp> + +// class mutex; + +// mutex(); + +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::mutex m0; + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/lock_compile_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/lock_compile_fail.cpp new file mode 100644 index 000000000..f6bf74b56 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/lock_compile_fail.cpp @@ -0,0 +1,19 @@ +// Copyright (C) 2017 Tom Hughes +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/mutex.hpp> + +// class mutex; + +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +void fail() +{ + boost::mutex m0; + m0.lock(); + m0.lock(); + m0.unlock(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/lock_compile_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/lock_compile_pass.cpp new file mode 100644 index 000000000..9da22a59d --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/lock_compile_pass.cpp @@ -0,0 +1,18 @@ +// Copyright (C) 2017 Tom Hughes +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/mutex.hpp> + +// class mutex; + +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +void pass() +{ + boost::mutex m0; + m0.lock(); + m0.unlock(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/lock_pass.cpp new file mode 100644 index 000000000..94818fbad --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/lock_pass.cpp @@ -0,0 +1,82 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/mutex.hpp> + +// class mutex; + +// void lock(); + +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + +boost::mutex m; + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + m.lock(); + t1 = Clock::now(); + m.unlock(); +#else + //time_point t0 = Clock::now(); + m.lock(); + //time_point t1 = Clock::now(); + m.unlock(); + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} + + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/native_handle_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/native_handle_pass.cpp new file mode 100644 index 000000000..489ec375d --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/native_handle_pass.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/mutex.hpp> + +// class mutex; + +// typedef pthread_mutex_t* native_handle_type; +// native_handle_type native_handle(); + +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ +#if defined BOOST_THREAD_DEFINES_MUTEX_NATIVE_HANDLE + boost::mutex m; + boost::mutex::native_handle_type h = m.native_handle(); + BOOST_TEST(h); +#else +#error "Test not applicable: BOOST_THREAD_DEFINES_MUTEX_NATIVE_HANDLE not defined for this platform as not supported" +#endif + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_compile_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_compile_fail.cpp new file mode 100644 index 000000000..05c2016cb --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_compile_fail.cpp @@ -0,0 +1,19 @@ +// Copyright (C) 2017 Tom Hughes +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/mutex.hpp> + +// class mutex; + +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +void fail() +{ + boost::mutex m0; + if (!m0.try_lock()) { + m0.unlock(); + } +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_compile_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_compile_pass.cpp new file mode 100644 index 000000000..e4cec906a --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_compile_pass.cpp @@ -0,0 +1,19 @@ +// Copyright (C) 2017 Tom Hughes +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/mutex.hpp> + +// class mutex; + +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +void pass() +{ + boost::mutex m0; + if (m0.try_lock()) { + m0.unlock(); + } +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_pass.cpp new file mode 100644 index 000000000..b973c1b23 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/mutex/try_lock_pass.cpp @@ -0,0 +1,91 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/mutex.hpp> + +// class mutex; + +// bool try_lock(); + +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + + +boost::mutex m; + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + BOOST_TEST(!m.try_lock()); + BOOST_TEST(!m.try_lock()); + BOOST_TEST(!m.try_lock()); + while (!m.try_lock()) + ; + t1 = Clock::now(); + m.unlock(); +#else + //time_point t0 = Clock::now(); + //BOOST_TEST(!m.try_lock()); + //BOOST_TEST(!m.try_lock()); + //BOOST_TEST(!m.try_lock()); + while (!m.try_lock()) + ; + //time_point t1 = Clock::now(); + m.unlock(); + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif + +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} + + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/assign_fail.cpp new file mode 100644 index 000000000..e8b440abd --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/assign_fail.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/null_mutex.hpp> + +// class null_mutex; + +// null_mutex& operator=(const null_mutex&) = delete; + +#include <boost/thread/null_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::null_mutex m0; + boost::null_mutex m1(m0); +} + +#include "../../../remove_error_code_unused_warning.hpp" diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/copy_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/copy_fail.cpp new file mode 100644 index 000000000..66668f5e0 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/copy_fail.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/null_mutex.hpp> + +// class null_mutex; + +// null_mutex(const null_mutex&) = delete; + +#include <boost/thread/null_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::null_mutex m0; + boost::null_mutex m1(m0); +} + +#include "../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/default_pass.cpp new file mode 100644 index 000000000..343431a9e --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/default_pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/null_mutex.hpp> + +// class null_mutex; + +// null_mutex(); + +#include <boost/thread/null_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::null_mutex m0; + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/lock_pass.cpp new file mode 100644 index 000000000..3c91e25f6 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/lock_pass.cpp @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/null_mutex.hpp> + +// class null_mutex; + +// void lock(); + +#include <boost/thread/null_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + +boost::null_mutex m; + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + time_point t0 = Clock::now(); + m.lock(); + time_point t1 = Clock::now(); + m.lock(); + m.unlock(); + m.unlock(); + ns d = t1 - t0 ; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); +#else + //time_point t0 = Clock::now(); + m.lock(); + //time_point t1 = Clock::now(); + m.lock(); + m.unlock(); + m.unlock(); + //ns d = t1 - t0 ; + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); + m.unlock(); + t.join(); + + return boost::report_errors(); +} + + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_for_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_for_pass.cpp new file mode 100644 index 000000000..1f5f5e9fc --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_for_pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/null_mutex.hpp> + +// class null_mutex; + +// template <class Rep, class Period> +// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); + +#include <boost/thread/null_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + +#if defined BOOST_THREAD_USES_CHRONO + + +boost::null_mutex m; + +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f1() +{ + time_point t0 = Clock::now(); + BOOST_TEST(m.try_lock_for(ms(250)) == true); + time_point t1 = Clock::now(); + BOOST_TEST(m.try_lock()); + m.unlock(); + m.unlock(); + ns d = t1 - t0 ; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); +} + +int main() +{ + { + m.lock(); + boost::thread t(f1); + m.unlock(); + t.join(); + } + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_pass.cpp new file mode 100644 index 000000000..cc51928bb --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/null_mutex.hpp> + +// class null_mutex; + +// bool try_lock(); + +#include <boost/thread/null_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + + + +boost::null_mutex m; + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + time_point t0 = Clock::now(); + BOOST_TEST(m.try_lock()); + time_point t1 = Clock::now(); + BOOST_TEST(m.try_lock()); + m.unlock(); + m.unlock(); + ns d = t1 - t0; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); +#else + BOOST_TEST(m.try_lock()); + BOOST_TEST(m.try_lock()); + m.unlock(); + m.unlock(); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); + m.unlock(); + t.join(); + + return boost::report_errors(); +} + + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_until_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_until_pass.cpp new file mode 100644 index 000000000..8a6985165 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/null_mutex/try_lock_until_pass.cpp @@ -0,0 +1,65 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/null_mutex> + +// class null_mutex; + +// template <class Clock, class Duration> +// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); + +#include <boost/thread/null_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + +#if defined BOOST_THREAD_USES_CHRONO + +boost::null_mutex m; + +typedef boost::chrono::steady_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f1() +{ + time_point t0 = Clock::now(); + BOOST_TEST(m.try_lock_until(Clock::now() + ms(250)) == true); + time_point t1 = Clock::now(); + m.unlock(); + ns d = t1 - t0 ; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); +} + + +int main() +{ + { + m.lock(); + boost::thread t(f1); + m.unlock(); + t.join(); + } + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp new file mode 100644 index 000000000..ac7b80769 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp @@ -0,0 +1,297 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/once.hpp> + +// struct once_flag; + +// template<class Callable, class ...Args> +// void call_once(once_flag& flag, Callable&& func, Args&&... args); + +//#define BOOST_THREAD_VERSION 4 +#define BOOST_THREAD_USES_MOVE +#define BOOST_THREAD_PROVIDES_ONCE_CXX11 + +#include <boost/thread/once.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> + +#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11 +#define BOOST_INIT_ONCE_INIT +#else +#define BOOST_INIT_ONCE_INIT =BOOST_ONCE_INIT +#endif + +typedef boost::chrono::milliseconds ms; + +boost::once_flag flg0 BOOST_INIT_ONCE_INIT; + +int init0_called = 0; + +void init0() +{ + boost::this_thread::sleep_for(ms(250)); + ++init0_called; +} + +void f0() +{ + boost::call_once(flg0, init0); +} + +boost::once_flag flg3 BOOST_INIT_ONCE_INIT; + +int init3_called = 0; +int init3_completed = 0; + +void init3() +{ + ++init3_called; + boost::this_thread::sleep_for(ms(250)); + if (init3_called == 1) + throw 1; + ++init3_completed; +} + +void f3() +{ + try + { + boost::call_once(flg3, init3); + } + catch (...) + { + } +} + +struct init1 +{ + static int called; + typedef void result_type; + + void operator()(int i) {called += i;} + void operator()(int i) const {called += i;} +}; + +int init1::called = 0; + +boost::once_flag flg1 BOOST_INIT_ONCE_INIT; + +void f1() +{ + boost::call_once(flg1, init1(), 1); +} + +boost::once_flag flg1_member BOOST_INIT_ONCE_INIT; + +struct init1_member +{ + static int called; + typedef void result_type; + void call(int i) { + called += i; + } +}; +int init1_member::called = 0; + +void f1_member_l() +{ + init1_member o; + int i=1; + boost::call_once(flg1_member, &init1_member::call, o, i); +} +void f1_member_r() +{ + init1_member o; + boost::call_once(flg1_member, &init1_member::call, o, 1); +} +struct init2 +{ + static int called; + typedef void result_type; + + void operator()(int i, int j) {called += i + j;} + void operator()(int i, int j) const {called += i + j;} +}; + +int init2::called = 0; + +boost::once_flag flg2 BOOST_INIT_ONCE_INIT; + +void f2() +{ + boost::call_once(flg2, init2(), 2, 3); + boost::call_once(flg2, init2(), 4, 5); +} + +boost::once_flag flg41 BOOST_INIT_ONCE_INIT; +boost::once_flag flg42 BOOST_INIT_ONCE_INIT; + +int init41_called = 0; +int init42_called = 0; + +void init42(); + +void init41() +{ + boost::this_thread::sleep_for(ms(250)); + ++init41_called; +} + +void init42() +{ + boost::this_thread::sleep_for(ms(250)); + ++init42_called; +} + +void f41() +{ + boost::call_once(flg41, init41); + boost::call_once(flg42, init42); +} + +void f42() +{ + boost::call_once(flg42, init42); + boost::call_once(flg41, init41); +} + +class MoveOnly +{ +public: + typedef void result_type; + + BOOST_THREAD_MOVABLE_ONLY(MoveOnly) + MoveOnly() + { + } + MoveOnly(BOOST_THREAD_RV_REF(MoveOnly)) + {} + + void operator()(BOOST_THREAD_RV_REF(MoveOnly)) + { + } + void operator()(int) + { + } + void operator()() + { + } +}; + + +struct id_string +{ + static boost::once_flag flag; + static void do_init(id_string & ) + {} + void operator()() + { + boost::call_once(flag, &id_string::do_init, boost::ref(*this)); + } +// void operator()(int,int) +// { +// // This should fail but works with gcc-4.6.3 +// //std::bind(&id_string::do_init, *this)(); +// std::bind(&id_string::do_init, std::ref(*this))(); +// } +// void operator()(int) const +// { +// //std::bind(&id_string::do_init, *this)(); +// } +}; + + +boost::once_flag id_string::flag BOOST_INIT_ONCE_INIT; + +int main() +{ + + // + { + id_string id; + id(); + //id(1,1); + } + // check basic functionality + { + boost::thread t0(f0); + boost::thread t1(f0); + t0.join(); + t1.join(); + BOOST_TEST(init0_called == 1); + } + // check basic exception safety + { + boost::thread t0(f3); + boost::thread t1(f3); + t0.join(); + t1.join(); + BOOST_TEST(init3_called == 2); + BOOST_TEST(init3_completed == 1); + } + // check deadlock avoidance + { + boost::thread t0(f41); + boost::thread t1(f42); + t0.join(); + t1.join(); + BOOST_TEST(init41_called == 1); + BOOST_TEST(init42_called == 1); + } + // check functors with 1 arg + { + boost::thread t0(f1); + boost::thread t1(f1); + t0.join(); + t1.join(); + BOOST_TEST(init1::called == 1); + } + // check functors with 2 args + { + boost::thread t0(f2); + boost::thread t1(f2); + t0.join(); + t1.join(); + BOOST_TEST(init2::called == 5); + } + + // check member function with 1 arg + { + boost::thread t0(f1_member_l); + boost::thread t1(f1_member_r); + t0.join(); + t1.join(); + BOOST_TEST(init1_member::called == 1); + } +#if defined BOOST_THREAD_PLATFORM_PTHREAD || (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ > 40600) + { + boost::once_flag f BOOST_INIT_ONCE_INIT; + boost::call_once(f, MoveOnly()); + } +#endif +#if defined BOOST_THREAD_PROVIDES_INVOKE + { + boost::once_flag f BOOST_INIT_ONCE_INIT; + boost::call_once(f, MoveOnly(), 1); + } + { + boost::once_flag f BOOST_INIT_ONCE_INIT; + boost::call_once(f, MoveOnly(), MoveOnly()); + } +#endif // BOOST_THREAD_PLATFORM_PTHREAD + return boost::report_errors(); +} + + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/queue_views/single_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/queue_views/single_thread_pass.cpp new file mode 100644 index 000000000..05a628230 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/queue_views/single_thread_pass.cpp @@ -0,0 +1,468 @@ +// Copyright (C) 2014 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/sync_queue.hpp> + +// class sync_queue<T> + +// sync_queue(); + +#define BOOST_THREAD_VERSION 4 +//#define BOOST_THREAD_QUEUE_DEPRECATE_OLD + +#include <boost/thread/concurrent_queues/sync_queue.hpp> +#include <boost/thread/concurrent_queues/queue_adaptor.hpp> +#include <boost/thread/concurrent_queues/queue_views.hpp> + +#include <boost/detail/lightweight_test.hpp> +#include <boost/static_assert.hpp> + +class non_copyable +{ + int val; +public: + BOOST_THREAD_MOVABLE_ONLY(non_copyable) + non_copyable(int v) : val(v){} + non_copyable(BOOST_RV_REF(non_copyable) x): val(x.val) {} + non_copyable& operator=(BOOST_RV_REF(non_copyable) x) { val=x.val; return *this; } + bool operator==(non_copyable const& x) const {return val==x.val;} + template <typename OSTREAM> + friend OSTREAM& operator <<(OSTREAM& os, non_copyable const&x ) + { + os << x.val; + return os; + } + +}; + +#if defined BOOST_NO_CXX11_RVALUE_REFERENCES +BOOST_STATIC_ASSERT( ! boost::is_copy_constructible<non_copyable>::value ); +BOOST_STATIC_ASSERT( boost::has_move_emulation_enabled<non_copyable>::value ); +#endif + +int main() +{ + + { + // default queue invariants + boost::queue_adaptor<boost::sync_queue<int> > sq; + boost::queue_back<int> q(sq); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // default queue invariants + boost::queue_adaptor<boost::sync_queue<int> > sq; + boost::queue_front<int> q(sq); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + + + { + // empty queue try_pull fails + boost::queue_adaptor<boost::sync_queue<int> > sq; + boost::queue_front<int> q(sq); + int i; + BOOST_TEST( boost::queue_op_status::empty == q.try_pull(i)); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // empty queue push rvalue/copyable succeeds + boost::queue_adaptor<boost::sync_queue<int> > sq; + boost::queue_back<int> q(sq); + q.push(1); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue push lvalue/copyable succeeds + boost::queue_adaptor<boost::sync_queue<int> > sq; + boost::queue_back<int> q(sq); + int i; + q.push(i); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + + +#if 0 + { + // empty queue push rvalue/non_copyable succeeds + boost::queue_adaptor<boost::sync_queue<non_copyable> > sq; + boost::queue_back<non_copyable> q(sq); + q.push(non_copyable(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900) + { + // empty queue push rvalue/non_copyable succeeds + boost::queue_adaptor<boost::sync_queue<non_copyable> > q; + //boost::sync_queue<non_copyable> q; + //boost::queue_back<non_copyable> q(sq); + non_copyable nc(1); + q.push(boost::move(nc)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif + + { + // empty queue push rvalue succeeds + boost::queue_adaptor<boost::sync_queue<int> > sq; + boost::queue_back<int> q(sq); + q.push(1); + q.push(2); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 2u); + BOOST_TEST(! q.closed()); + } + { + // empty queue push lvalue succeeds + boost::queue_adaptor<boost::sync_queue<int> > sq; + boost::queue_back<int> q(sq); + int i; + q.push(i); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue/copyable succeeds + boost::queue_adaptor<boost::sync_queue<int> > sq; + boost::queue_back<int> q(sq); + BOOST_TEST(boost::queue_op_status::success == q.try_push(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue/copyable succeeds + boost::queue_adaptor<boost::sync_queue<int> > sq; + boost::queue_back<int> q(sq); + BOOST_TEST(boost::queue_op_status::success == q.try_push(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + +#if 0 + { + // empty queue try_push rvalue/non-copyable succeeds + boost::queue_adaptor<boost::sync_queue<non_copyable> > sq; + boost::queue_back<non_copyable> q(sq); + non_copyable nc(1); + BOOST_TEST(boost::queue_op_status::success == q.try_push(boost::move(nc))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif + + { + // empty queue try_push lvalue succeeds + boost::queue_adaptor<boost::sync_queue<int> > sq; + boost::queue_back<int> q(sq); + int i=0; + BOOST_TEST(boost::queue_op_status::success == q.try_push(i)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue succeeds + boost::queue_adaptor<boost::sync_queue<int> > sq; + boost::queue_back<int> q(sq); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + + +#if 0 + { + // empty queue nonblocking_push rvalue/non-copyable succeeds + boost::queue_adaptor<boost::sync_queue<non_copyable> > sq; + boost::queue_back<non_copyable> q(sq); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(non_copyable(1))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900) + { + // empty queue nonblocking_push rvalue/non-copyable succeeds + boost::queue_adaptor<boost::sync_queue<non_copyable> > sq; + boost::queue_back<non_copyable> q(sq); + non_copyable nc(1); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(boost::move(nc))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif + { + // 1-element queue pull succeed + boost::queue_adaptor<boost::sync_queue<int> > sq; + boost::queue_front<int> q(sq); + sq.push(1); + int i; + q.pull(i); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900) + { + // 1-element queue pull succeed + boost::queue_adaptor<boost::sync_queue<non_copyable> > sq; + boost::queue_front<non_copyable> q(sq); + non_copyable nc1(1); + sq.push(boost::move(nc1)); + non_copyable nc2(2); + q.pull(nc2); + BOOST_TEST_EQ(nc1, nc2); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#endif + { + // 1-element queue pull succeed + boost::queue_adaptor<boost::sync_queue<int> > sq; + boost::queue_front<int> q(sq); + sq.push(1); + int i = q.pull(); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900) + { + // 1-element queue pull succeed + boost::queue_adaptor<boost::sync_queue<non_copyable> > sq; + boost::queue_front<non_copyable> q(sq); + non_copyable nc1(1); + sq.push(boost::move(nc1)); + non_copyable nc = q.pull(); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#endif + { + // 1-element queue try_pull succeed + boost::queue_adaptor<boost::sync_queue<int> > sq; + boost::queue_front<int> q(sq); + sq.push(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.try_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900) + { + // 1-element queue try_pull succeed + boost::queue_adaptor<boost::sync_queue<non_copyable> > sq; + boost::queue_front<non_copyable> q(sq); + non_copyable nc1(1); + sq.push(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.try_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#endif + { + // 1-element queue nonblocking_pull succeed + boost::queue_adaptor<boost::sync_queue<int> > sq; + boost::queue_front<int> q(sq); + sq.push(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900) + { + // 1-element queue nonblocking_pull succeed + boost::queue_adaptor<boost::sync_queue<non_copyable> > sq; + boost::queue_front<non_copyable> q(sq); + non_copyable nc1(1); + sq.push(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue wait_pull succeed + boost::queue_adaptor<boost::sync_queue<non_copyable> > sq; + boost::queue_front<non_copyable> q(sq); + non_copyable nc1(1); + sq.push(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#endif + { + // 1-element queue wait_pull succeed + boost::queue_adaptor<boost::sync_queue<int> > sq; + boost::queue_front<int> q(sq); + sq.push(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1900) + { + // 1-element queue wait_pull succeed + boost::queue_adaptor<boost::sync_queue<non_copyable> > sq; + boost::queue_front<non_copyable> q(sq); + non_copyable nc1(1); + sq.push(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#endif + { + // closed invariants + boost::queue_adaptor<boost::sync_queue<int> > sq; + boost::queue_back<int> q(sq); + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed invariants + boost::queue_adaptor<boost::sync_queue<int> > sq; + boost::queue_front<int> q(sq); + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed queue push fails + boost::queue_adaptor<boost::sync_queue<int> > sq; + boost::queue_back<int> q(sq); + q.close(); + try { + q.push(1); + BOOST_TEST(false); + } catch (...) { + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + } + { + // 1-element closed queue pull succeed + boost::queue_adaptor<boost::sync_queue<int> > sq; + boost::queue_front<int> q(sq); + sq.push(1); + q.close(); + int i; + q.pull(i); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // 1-element closed queue wait_pull succeed + boost::queue_adaptor<boost::sync_queue<int> > sq; + boost::queue_front<int> q(sq); + sq.push(1); + q.close(); + int i; + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed empty queue wait_pull fails + boost::queue_adaptor<boost::sync_queue<int> > sq; + boost::queue_front<int> q(sq); + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(q.closed()); + int i; + BOOST_TEST(boost::queue_op_status::closed == q.wait_pull(i)); + BOOST_TEST(q.empty()); + BOOST_TEST(q.closed()); + } + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/assign_fail.cpp new file mode 100644 index 000000000..041102e91 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/assign_fail.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/recursive_mutex.hpp> + +// class recursive_mutex; + +// recursive_mutex& operator=(const recursive_mutex&) = delete; + +#include <boost/thread/recursive_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::recursive_mutex m0; + boost::recursive_mutex m1(m0); +} + +#include "../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/copy_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/copy_fail.cpp new file mode 100644 index 000000000..932422d15 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/copy_fail.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/recursive_mutex.hpp> + +// class recursive_mutex; + +// recursive_mutex(const recursive_mutex&) = delete; + +#include <boost/thread/recursive_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::recursive_mutex m0; + boost::recursive_mutex m1(m0); +} + +#include "../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/default_pass.cpp new file mode 100644 index 000000000..6b6199720 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/default_pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/recursive_mutex.hpp> + +// class recursive_mutex; + +// recursive_mutex(); + +#include <boost/thread/recursive_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::recursive_mutex m0; + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/lock_pass.cpp new file mode 100644 index 000000000..a5410d25e --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/lock_pass.cpp @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/recursive_mutex.hpp> + +// class recursive_mutex; + +// void lock(); + +#include <boost/thread/recursive_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + + +boost::recursive_mutex m; + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + m.lock(); + t1 = Clock::now(); + m.lock(); + m.unlock(); + m.unlock(); +#else + //time_point t0 = Clock::now(); + m.lock(); + //time_point t1 = Clock::now(); + m.lock(); + m.unlock(); + m.unlock(); + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#else +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} + + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/native_handle_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/native_handle_pass.cpp new file mode 100644 index 000000000..b784f24e5 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/native_handle_pass.cpp @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/recursive_mutex.hpp> + +// class recursive_mutex; + +// typedef pthread_recursive_mutex_t* native_handle_type; +// native_handle_type native_handle(); + +#include <boost/thread/recursive_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ +#if defined BOOST_THREAD_DEFINES_RECURSIVE_MUTEX_NATIVE_HANDLE + boost::recursive_mutex m; + boost::recursive_mutex::native_handle_type h = m.native_handle(); + BOOST_TEST(h); +#else +#error "Test not applicable: BOOST_THREAD_DEFINES_RECURSIVE_MUTEX_NATIVE_HANDLE not defined for this platform as not supported" +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/try_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/try_lock_pass.cpp new file mode 100644 index 000000000..0f8fe822a --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_mutex/try_lock_pass.cpp @@ -0,0 +1,96 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/recursive_mutex.hpp> + +// class recursive_mutex; + +// bool try_lock(); + +#include <boost/thread/recursive_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <iostream> +#include "../../../timming.hpp" + +boost::recursive_mutex m; + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); +// BOOST_TEST(!m.try_lock()); +// BOOST_TEST(!m.try_lock()); +// BOOST_TEST(!m.try_lock()); + while (!m.try_lock()) + ; + t1 = Clock::now(); + BOOST_TEST(m.try_lock()); + m.unlock(); + m.unlock(); +#else + //time_point t0 = Clock::now(); + //BOOST_TEST(!m.try_lock()); + //BOOST_TEST(!m.try_lock()); + //BOOST_TEST(!m.try_lock()); + while (!m.try_lock()) + ; + //time_point t1 = Clock::now(); + BOOST_TEST(m.try_lock()); + m.unlock(); + m.unlock(); + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#else +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} + + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/assign_fail.cpp new file mode 100644 index 000000000..48b9cc47d --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/assign_fail.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/recursive_mutex.hpp> + +// class recursive_timed_mutex; + +// recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete; + +#include <boost/thread/recursive_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::recursive_timed_mutex m0; + boost::recursive_timed_mutex m1(m0); +} + +#include "../../../remove_error_code_unused_warning.hpp" diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/copy_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/copy_fail.cpp new file mode 100644 index 000000000..b4e96c7ac --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/copy_fail.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/recursive_mutex.hpp> + +// class recursive_timed_mutex; + +// recursive_timed_mutex(const recursive_timed_mutex&) = delete; + +#include <boost/thread/recursive_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::recursive_timed_mutex m0; + boost::recursive_timed_mutex m1(m0); +} + +#include "../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/default_pass.cpp new file mode 100644 index 000000000..1e75b7b04 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/default_pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/recursive_mutex.hpp> + +// class recursive_timed_mutex; + +// recursive_timed_mutex(); + +#include <boost/thread/recursive_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::recursive_timed_mutex m0; + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/lock_pass.cpp new file mode 100644 index 000000000..bd0646f64 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/lock_pass.cpp @@ -0,0 +1,88 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/recursive_mutex.hpp> + +// class recursive_timed_mutex; + +// void lock(); + +#include <boost/thread/recursive_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <iostream> +#include "../../../timming.hpp" + +boost::recursive_timed_mutex m; + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + m.lock(); + t1 = Clock::now(); + m.lock(); + m.unlock(); + m.unlock(); +#else + //time_point t0 = Clock::now(); + m.lock(); + //time_point t1 = Clock::now(); + m.lock(); + m.unlock(); + m.unlock(); + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#else +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} + + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/native_handle_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/native_handle_pass.cpp new file mode 100644 index 000000000..bcd375e53 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/native_handle_pass.cpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/recursive_mutex.hpp> + +// class recursive_timed_mutex; + +// typedef pthread_recursive_mutex_t* native_handle_type; +// native_handle_type native_handle(); + +#include <boost/thread/recursive_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ +#if defined BOOST_THREAD_DEFINES_RECURSIVE_TIMED_MUTEX_NATIVE_HANDLE + boost::recursive_timed_mutex m; + boost::recursive_timed_mutex::native_handle_type h = m.native_handle(); + BOOST_TEST(h); +#else +#error "Test not applicable: BOOST_THREAD_DEFINES_RECURSIVE_TIMED_MUTEX_NATIVE_HANDLE not defined for this platform as not supported" +#endif + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_for_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_for_pass.cpp new file mode 100644 index 000000000..c7f6d2b0b --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_for_pass.cpp @@ -0,0 +1,92 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/recursive_mutex.hpp> + +// class recursive_timed_mutex; + +// template <class Rep, class Period> +// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); + +#include <boost/thread/recursive_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + +#if defined BOOST_THREAD_USES_CHRONO + +boost::recursive_timed_mutex m; + +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f1() +{ + t0 = Clock::now(); + BOOST_TEST(m.try_lock_for(ms(750)) == true); + t1 = Clock::now(); + BOOST_TEST(m.try_lock()); + m.unlock(); + m.unlock(); +} + +void f2() +{ + time_point t0 = Clock::now(); + BOOST_TEST(m.try_lock_for(ms(250)) == false); + time_point t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + BOOST_THREAD_TEST_IT(d, ns(max_diff)); +} + +int main() +{ + { + m.lock(); + boost::thread t(f1); + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); + m.unlock(); + t.join(); + + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); + } + { + m.lock(); + boost::thread t(f2); + boost::this_thread::sleep_for(ms(750)); + m.unlock(); + t.join(); + } + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_pass.cpp new file mode 100644 index 000000000..3874d6853 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_pass.cpp @@ -0,0 +1,95 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/recursive_mutex.hpp> + +// class recursive_timed_mutex; + +// bool try_lock(); + +#include <boost/thread/recursive_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + +boost::recursive_timed_mutex m; + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + BOOST_TEST(!m.try_lock()); + BOOST_TEST(!m.try_lock()); + BOOST_TEST(!m.try_lock()); + while (!m.try_lock()) + ; + t1 = Clock::now(); + BOOST_TEST(m.try_lock()); + m.unlock(); + m.unlock(); +#else + //time_point t0 = Clock::now(); + //BOOST_TEST(!m.try_lock()); + //BOOST_TEST(!m.try_lock()); + //BOOST_TEST(!m.try_lock()); + while (!m.try_lock()) + ; + //time_point t1 = Clock::now(); + BOOST_TEST(m.try_lock()); + m.unlock(); + m.unlock(); + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#else +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} + + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_until_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_until_pass.cpp new file mode 100644 index 000000000..238467204 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/recursive_timed_mutex/try_lock_until_pass.cpp @@ -0,0 +1,92 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/recursive_mutex> + +// class recursive_timed_mutex; + +// template <class Clock, class Duration> +// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); + +#include <boost/thread/recursive_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + +#if defined BOOST_THREAD_USES_CHRONO + +boost::recursive_timed_mutex m; + +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f1() +{ + t0 = Clock::now(); + BOOST_TEST(m.try_lock_until(Clock::now() + ms(750)) == true); + t1 = Clock::now(); + m.unlock(); +} + +void f2() +{ + t0 = Clock::now(); + BOOST_TEST(m.try_lock_until(Clock::now() + ms(250)) == false); + t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + BOOST_THREAD_TEST_IT(d, ns(max_diff)); +} + +int main() +{ + { + m.lock(); + boost::thread t(f1); + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + } + { + m.lock(); + boost::thread t(f2); + boost::this_thread::sleep_for(ms(750)); + m.unlock(); + t.join(); + } + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/assign_fail.cpp new file mode 100644 index 000000000..ee6446d7e --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/assign_fail.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/shared_mutex.hpp> + +// class shared_mutex; + +// shared_mutex& operator=(const shared_mutex&) = delete; + +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::shared_mutex m0; + boost::shared_mutex m1(m0); +} + +#include "../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/copy_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/copy_fail.cpp new file mode 100644 index 000000000..9627f9f66 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/copy_fail.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/shared_mutex.hpp> + +// class shared_mutex; + +// shared_mutex(const shared_mutex&) = delete; + +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::shared_mutex m0; + boost::shared_mutex m1(m0); +} + +#include "../../../remove_error_code_unused_warning.hpp" + + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/default_pass.cpp new file mode 100644 index 000000000..730c9cafc --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/default_pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/timed_mutex.hpp> + +// class shared_mutex; + +// shared_mutex(); + +#include <boost/thread/shared_mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::shared_mutex m0; + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/lock_pass.cpp new file mode 100644 index 000000000..0b53fb275 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/lock_pass.cpp @@ -0,0 +1,82 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/shared_mutex.hpp> + +// class shared_mutex; + +// void lock(); + +#include <boost/thread/shared_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + +boost::shared_mutex m; + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + m.lock(); + t1 = Clock::now(); + m.unlock(); +#else + //time_point t0 = Clock::now(); + m.lock(); + //time_point t1 = Clock::now(); + m.unlock(); + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#else +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_for_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_for_pass.cpp new file mode 100644 index 000000000..bc06576ec --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_for_pass.cpp @@ -0,0 +1,86 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/shared_mutex.hpp> + +// class shared_mutex; + +// template <class Rep, class Period> +// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); + +#include <boost/thread/shared_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + +boost::shared_mutex m; + +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f1() +{ + t0 = Clock::now(); + BOOST_TEST(m.try_lock_for(ms(750)) == true); + t1 = Clock::now(); + m.unlock(); +} + +void f2() +{ + t0 = Clock::now(); + BOOST_TEST(m.try_lock_for(ms(250)) == false); + t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + BOOST_THREAD_TEST_IT(d, ns(max_diff)); +} + +int main() +{ + { + m.lock(); + boost::thread t(f1); + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + } + { + m.lock(); + boost::thread t(f2); + boost::this_thread::sleep_for(ms(750)); + m.unlock(); + t.join(); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_pass.cpp new file mode 100644 index 000000000..515589a6f --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_pass.cpp @@ -0,0 +1,90 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/shared_mutex.hpp> + +// class shared_mutex; + +// bool try_lock(); + +#include <boost/thread/shared_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + +boost::shared_mutex m; + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + BOOST_TEST(!m.try_lock()); + BOOST_TEST(!m.try_lock()); + BOOST_TEST(!m.try_lock()); + while (!m.try_lock()) + ; + t1 = Clock::now(); + m.unlock(); +#else + //time_point t0 = Clock::now(); + //BOOST_TEST(!m.try_lock()); + //BOOST_TEST(!m.try_lock()); + //BOOST_TEST(!m.try_lock()); + while (!m.try_lock()) + ; + //time_point t1 = Clock::now(); + m.unlock(); + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#else +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_until_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_until_pass.cpp new file mode 100644 index 000000000..dd8a1a816 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/shared_mutex/try_lock_until_pass.cpp @@ -0,0 +1,84 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2012 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/shared_mutex.hpp> + +// class shared_mutex; + +// template <class Clock, class Duration> +// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); + +#include <boost/thread/shared_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + +boost::shared_mutex m; + +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f1() +{ + t0 = Clock::now(); + BOOST_TEST(m.try_lock_until(Clock::now() + ms(750)) == true); + t1 = Clock::now(); + m.unlock(); +} + +void f2() +{ + t0 = Clock::now(); + BOOST_TEST(m.try_lock_until(Clock::now() + ms(250)) == false); + t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + BOOST_THREAD_TEST_IT(d, ns(max_diff)); +} + +int main() +{ + { + m.lock(); + boost::thread t(f1); + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); + m.unlock(); + t.join(); + + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); + } + { + m.lock(); + boost::thread t(f2); + boost::this_thread::sleep_for(ms(750)); + m.unlock(); + t.join(); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/multi_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/multi_thread_pass.cpp new file mode 100644 index 000000000..9975a995a --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/multi_thread_pass.cpp @@ -0,0 +1,252 @@ +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/sync_bounded_queue.hpp> + +// class sync_queue<T> + +// push || pull; + +#include <boost/config.hpp> +#if ! defined BOOST_NO_CXX11_DECLTYPE +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/sync_bounded_queue.hpp> +#include <boost/thread/future.hpp> +#include <boost/thread/barrier.hpp> + +#include <boost/detail/lightweight_test.hpp> + +struct call_push +{ + boost::sync_bounded_queue<int> &q_; + boost::barrier& go_; + + call_push(boost::sync_bounded_queue<int> &q, boost::barrier &go) : + q_(q), go_(go) + { + } + typedef void result_type; + void operator()() + { + go_.count_down_and_wait(); + q_.push(42); + + } +}; + +struct call_push_2 +{ + boost::sync_bounded_queue<int> &q_; + boost::barrier& go_; + boost::barrier& end_; + + call_push_2(boost::sync_bounded_queue<int> &q, boost::barrier &go, boost::barrier &end) : + q_(q), go_(go), end_(end) + { + } + typedef void result_type; + void operator()() + { + go_.count_down_and_wait(); + q_.push(42); + end_.count_down_and_wait(); + + } +}; + +struct call_pull +{ + boost::sync_bounded_queue<int> &q_; + boost::barrier& go_; + + call_pull(boost::sync_bounded_queue<int> &q, boost::barrier &go) : + q_(q), go_(go) + { + } + typedef int result_type; + int operator()() + { + go_.count_down_and_wait(); + return q_.pull(); + } +}; + +void test_concurrent_push_and_pull_on_empty_queue() +{ + boost::sync_bounded_queue<int> q(4); + + boost::barrier go(2); + + boost::future<void> push_done; + boost::future<int> pull_done; + + try + { + push_done=boost::async(boost::launch::async, +#if ! defined BOOST_NO_CXX11_LAMBDAS + [&q,&go]() + { + go.wait(); + q.push(42); + } +#else + call_push(q,go) +#endif + ); + pull_done=boost::async(boost::launch::async, +#if ! defined BOOST_NO_CXX11_LAMBDAS + [&q,&go]() -> int + { + go.wait(); + return q.pull(); + } +#else + call_pull(q,go) +#endif + ); + + push_done.get(); + BOOST_TEST_EQ(pull_done.get(), 42); + BOOST_TEST(q.empty()); + } + catch (...) + { + BOOST_TEST(false); + } +} + +void test_concurrent_push_on_empty_queue() +{ + boost::sync_bounded_queue<int> q(4); + const unsigned int n = 3; + boost::barrier go(n); + boost::future<void> push_done[n]; + + try + { + for (unsigned int i =0; i< n; ++i) + push_done[i]=boost::async(boost::launch::async, +#if ! defined BOOST_NO_CXX11_LAMBDAS + [&q,&go]() + { + go.wait(); + q.push(42); + } +#else + call_push(q,go) +#endif + ); + + for (unsigned int i = 0; i < n; ++i) + push_done[i].get(); + + BOOST_TEST(!q.empty()); + for (unsigned int i =0; i< n; ++i) + BOOST_TEST_EQ(q.pull(), 42); + BOOST_TEST(q.empty()); + + } + catch (...) + { + BOOST_TEST(false); + } +} + +void test_concurrent_push_on_full_queue() +{ + const unsigned int size = 2; + boost::sync_bounded_queue<int> q(size); + const unsigned int n = 2*size; + boost::barrier go(n); + boost::barrier end(size+1); + boost::future<void> push_done[n]; + + try + { + for (unsigned int i =0; i< n; ++i) + push_done[i]=boost::async(boost::launch::async, +#if ! defined BOOST_NO_CXX11_LAMBDAS + [&q,&go,&end]() + { + go.wait(); + q.push(42); + end.wait(); + } +#else + call_push_2(q,go,end) +#endif + ); + + end.wait(); + BOOST_TEST(!q.empty()); + BOOST_TEST(q.full()); + for (unsigned int i =0; i< size; ++i) + BOOST_TEST_EQ(q.pull(), 42); + end.wait(); + + for (unsigned int i = 0; i < n; ++i) + push_done[i].get(); + + BOOST_TEST(!q.empty()); + for (unsigned int i =0; i< size; ++i) + BOOST_TEST_EQ(q.pull(), 42); + BOOST_TEST(q.empty()); + + } + catch (...) + { + BOOST_TEST(false); + } +} +void test_concurrent_pull_on_queue() +{ + boost::sync_bounded_queue<int> q(4); + const unsigned int n = 3; + boost::barrier go(n); + + boost::future<int> pull_done[n]; + + try + { + for (unsigned int i =0; i< n; ++i) + q.push(42); + + for (unsigned int i =0; i< n; ++i) + pull_done[i]=boost::async(boost::launch::async, +#if ! defined BOOST_NO_CXX11_LAMBDAS + [&q,&go]() -> int + { + go.wait(); + return q.pull(); + } +#else + call_pull(q,go) +#endif + ); + + for (unsigned int i = 0; i < n; ++i) + BOOST_TEST_EQ(pull_done[i].get(), 42); + BOOST_TEST(q.empty()); + } + catch (...) + { + BOOST_TEST(false); + } +} + +int main() +{ + test_concurrent_push_and_pull_on_empty_queue(); + test_concurrent_push_on_empty_queue(); + test_concurrent_push_on_full_queue(); + test_concurrent_pull_on_queue(); + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/single_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/single_thread_pass.cpp new file mode 100644 index 000000000..201e0bc13 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_bounded_queue/single_thread_pass.cpp @@ -0,0 +1,600 @@ +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/sync_bounded_queue.hpp> + +// class sync_bounded_queue<T> + +// sync_bounded_queue(); + +#define BOOST_THREAD_VERSION 4 +//#define BOOST_THREAD_QUEUE_DEPRECATE_OLD + +#include <boost/thread/sync_bounded_queue.hpp> + +#include <boost/detail/lightweight_test.hpp> + +class non_copyable +{ + BOOST_THREAD_MOVABLE_ONLY(non_copyable) + int val; +public: + non_copyable() {} + non_copyable(int v) : val(v){} + non_copyable(BOOST_RV_REF(non_copyable) x): val(x.val) {} + non_copyable& operator=(BOOST_RV_REF(non_copyable) x) { val=x.val; return *this; } + bool operator==(non_copyable const& x) const {return val==x.val;} + template <typename OSTREAM> + friend OSTREAM& operator <<(OSTREAM& os, non_copyable const&x ) + { + os << x.val; + return os; + } + +}; + + +int main() +{ + + { + // default queue invariants + boost::sync_bounded_queue<int> q(2); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST_EQ(q.capacity(), 2u); + BOOST_TEST(! q.closed()); + } +#ifndef BOOST_THREAD_QUEUE_DEPRECATE_OLD + { + // empty queue try_pull fails + boost::sync_bounded_queue<int> q(2); + int i; + BOOST_TEST(! q.try_pull(i)); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_pull fails + boost::sync_bounded_queue<int> q(2); + BOOST_TEST(! q.try_pull()); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // empty queue push rvalue succeeds + boost::sync_bounded_queue<int> q(2); + q.push(1); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue push rvalue succeeds + boost::sync_bounded_queue<non_copyable> q(2); + non_copyable nc(1); + q.push(boost::move(nc)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue push rvalue succeeds + boost::sync_bounded_queue<int> q(3); + q.push(1); + BOOST_TEST_EQ(q.size(), 1u); + q.push(2); + BOOST_TEST_EQ(q.size(), 2u); + q.push(2); + BOOST_TEST_EQ(q.size(), 3u); + BOOST_TEST(! q.empty()); + BOOST_TEST( q.full()); + BOOST_TEST(! q.closed()); + } + { + // empty queue push value succeeds + boost::sync_bounded_queue<int> q(2); + int i; + q.push(i); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue succeeds + boost::sync_bounded_queue<int> q(2); + BOOST_TEST(q.try_push(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue succeeds + boost::sync_bounded_queue<non_copyable> q(2); + non_copyable nc(1); + BOOST_TEST(q.try_push(boost::move(nc))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push value succeeds + boost::sync_bounded_queue<int> q(2); + int i=1; + BOOST_TEST(q.try_push(i)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue succeeds + boost::sync_bounded_queue<int> q(2); + BOOST_TEST(q.try_push(boost::no_block, 1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue succeeds + boost::sync_bounded_queue<non_copyable> q(2); + non_copyable nc(1); + BOOST_TEST(q.try_push(boost::no_block, boost::move(nc))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue pull succeed + boost::sync_bounded_queue<int> q(2); + q.push(1); + int i; + q.pull(i); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue pull succeed + boost::sync_bounded_queue<non_copyable> q(2); + non_copyable nc(1); + q.push(boost::move(nc)); + non_copyable nc2(2); + q.pull(nc2); + BOOST_TEST_EQ(nc, nc2); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue pull succeed + boost::sync_bounded_queue<int> q(2); + q.push(1); + int i = q.pull(); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue try_pull succeed + boost::sync_bounded_queue<int> q(2); + q.push(1); + int i; + BOOST_TEST(q.try_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue try_pull succeed + boost::sync_bounded_queue<int> q(2); + q.push(1); + int i; + BOOST_TEST(q.try_pull(boost::no_block, i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue try_pull succeed + boost::sync_bounded_queue<int> q(2); + q.push(1); + boost::shared_ptr<int> i = q.try_pull(); + BOOST_TEST_EQ(*i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // full queue try_push rvalue fails + boost::sync_bounded_queue<int> q(2); + q.push(1); + q.push(2); + BOOST_TEST(! q.try_push(3)); + BOOST_TEST(! q.empty()); + BOOST_TEST( q.full()); + BOOST_TEST_EQ(q.size(), 2u); + BOOST_TEST(! q.closed()); + } + { + // full queue try_push succeeds + boost::sync_bounded_queue<int> q(2); + q.push(1); + q.push(2); + BOOST_TEST(q.try_pull()); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + + { + // closed invariants + boost::sync_bounded_queue<int> q(2); + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed queue push fails + boost::sync_bounded_queue<int> q(2); + q.close(); + try { + q.push(1); + BOOST_TEST(false); + } catch (...) { + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + } + { + // 1-element closed queue pull succeed + boost::sync_bounded_queue<int> q(2); + q.push(1); + q.close(); + int i; + q.pull(i); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } +#endif + { + // empty queue try_pull fails + boost::sync_bounded_queue<int> q(2); + int i; + BOOST_TEST( boost::queue_op_status::empty == q.try_pull_front(i)); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // empty queue push rvalue succeeds + boost::sync_bounded_queue<int> q(2); + q.push_back(1); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue push rvalue succeeds + boost::sync_bounded_queue<non_copyable> q(2); + non_copyable nc(1); + q.push_back(boost::move(nc)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue push rvalue succeeds + boost::sync_bounded_queue<int> q(3); + q.push_back(1); + BOOST_TEST_EQ(q.size(), 1u); + q.push_back(2); + BOOST_TEST_EQ(q.size(), 2u); + q.push_back(3); + BOOST_TEST_EQ(q.size(), 3u); + BOOST_TEST(! q.empty()); + BOOST_TEST( q.full()); + BOOST_TEST(! q.closed()); + } + { + // empty queue push value succeeds + boost::sync_bounded_queue<int> q(2); + int i; + q.push_back(i); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue succeeds + boost::sync_bounded_queue<int> q(2); + BOOST_TEST(boost::queue_op_status::success == q.try_push_back(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue succeeds + boost::sync_bounded_queue<non_copyable> q(2); + non_copyable nc(1); + BOOST_TEST(boost::queue_op_status::success == q.try_push_back(boost::move(nc))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push value succeeds + boost::sync_bounded_queue<int> q(2); + int i=1; + BOOST_TEST(boost::queue_op_status::success == q.try_push_back(i)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue succeeds + boost::sync_bounded_queue<int> q(2); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back( 1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue succeeds + boost::sync_bounded_queue<non_copyable> q(2); + non_copyable nc(1); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(boost::move(nc))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue wait_push rvalue succeeds + boost::sync_bounded_queue<int> q(2); + BOOST_TEST(boost::queue_op_status::success == q.wait_push_back(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue wait_push rvalue succeeds + boost::sync_bounded_queue<non_copyable> q(2); + non_copyable nc(1); + BOOST_TEST(boost::queue_op_status::success == q.wait_push_back(boost::move(nc))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue wait_push value succeeds + boost::sync_bounded_queue<int> q(2); + int i; + BOOST_TEST(boost::queue_op_status::success == q.wait_push_back(i)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue pull succeed + boost::sync_bounded_queue<int> q(2); + q.push_back(1); + int i; + q.pull_front(i); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue pull succeed + boost::sync_bounded_queue<non_copyable> q(2); + non_copyable nc(1); + q.push_back(boost::move(nc)); + non_copyable nc2(2); + q.pull_front(nc2); + BOOST_TEST_EQ(nc, nc2); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue pull succeed + boost::sync_bounded_queue<int> q(2); + q.push_back(1); + int i = q.pull_front(); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue try_pull succeed + boost::sync_bounded_queue<int> q(2); + q.push_back(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.try_pull_front(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue nonblocking_pull_front succeed + boost::sync_bounded_queue<int> q(2); + q.push_back(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull_front(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue wait_pull_front succeed + boost::sync_bounded_queue<int> q(2); + q.push_back(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // full queue try_push rvalue fails + boost::sync_bounded_queue<int> q(2); + q.push_back(1); + q.push_back(2); + BOOST_TEST(boost::queue_op_status::full == q.try_push_back(3)); + BOOST_TEST(! q.empty()); + BOOST_TEST( q.full()); + BOOST_TEST_EQ(q.size(), 2u); + BOOST_TEST(! q.closed()); + } + + { + // closed invariants + boost::sync_bounded_queue<int> q(2); + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed queue push fails + boost::sync_bounded_queue<int> q(2); + q.close(); + try { + q.push_back(1); + BOOST_TEST(false); + } catch (...) { + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + } + { + // closed empty queue try_pull_front closed + boost::sync_bounded_queue<int> q(2); + q.close(); + int i; + BOOST_TEST(boost::queue_op_status::closed == q.try_pull_front(i)); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed empty queue nonblocking_pull_front closed + boost::sync_bounded_queue<int> q(2); + q.close(); + int i; + BOOST_TEST(boost::queue_op_status::closed == q.nonblocking_pull_front(i)); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // 1-element closed queue pull_front succeed + boost::sync_bounded_queue<int> q(2); + q.push_back(1); + q.close(); + int i; + q.pull_front(i); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // 1-element closed queue wait_pull_front succeed + boost::sync_bounded_queue<int> q(2); + q.push_back(1); + q.close(); + int i; + BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed empty queue wait_pull_front closed + boost::sync_bounded_queue<int> q(2); + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(q.closed()); + int i; + BOOST_TEST(boost::queue_op_status::closed == q.wait_pull_front(i)); + BOOST_TEST(q.empty()); + BOOST_TEST(q.closed()); + } + { + // closed queue wait_push_back fails + boost::sync_bounded_queue<int> q(2); + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(q.closed()); + int i; + BOOST_TEST(boost::queue_op_status::closed == q.wait_push_back(i)); + BOOST_TEST(q.empty()); + BOOST_TEST(q.closed()); + } + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/sync_deque/multi_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_deque/multi_thread_pass.cpp new file mode 100644 index 000000000..703c54f40 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_deque/multi_thread_pass.cpp @@ -0,0 +1,256 @@ +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/concurrent_queues/sync_deque.hpp> + +// class sync_deque<T> + +// push || pull; + +#include <boost/config.hpp> +#if ! defined BOOST_NO_CXX11_DECLTYPE +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/concurrent_queues/sync_deque.hpp> +#include <boost/thread/future.hpp> +#include <boost/thread/barrier.hpp> + +#include <boost/detail/lightweight_test.hpp> + +template <typename ValueType> +struct call_push_back +{ + boost::sync_deque<ValueType> *q_; + boost::barrier *go_; + + call_push_back(boost::sync_deque<ValueType> *q, boost::barrier *go) : + q_(q), go_(go) + { + } + typedef void result_type; + void operator()() + { + go_->count_down_and_wait(); + q_->push_back(42); + } +}; + +template <typename ValueType> +struct call_pull_front +{ + boost::sync_deque<ValueType> *q_; + boost::barrier *go_; + + call_pull_front(boost::sync_deque<ValueType> *q, boost::barrier *go) : + q_(q), go_(go) + { + } + typedef ValueType result_type; + ValueType operator()() + { + go_->count_down_and_wait(); + return q_->pull_front(); + } +}; + +template <typename ValueType> +struct call_wait_pull_front +{ + boost::sync_deque<ValueType> *q_; + boost::barrier *go_; + + call_wait_pull_front(boost::sync_deque<ValueType> *q, boost::barrier *go) : + q_(q), go_(go) + { + } + typedef boost::queue_op_status result_type; + boost::queue_op_status operator()(ValueType& v) + { + go_->wait(); + return q_->wait_pull_front(v); + } +}; + +void test_concurrent_push_back_and_pull_front_on_empty_queue() +{ + boost::sync_deque<int> q; + + boost::barrier go(2); + + boost::future<void> push_done; + boost::future<int> pull_done; + + try + { + push_done=boost::async(boost::launch::async, + call_push_back<int>(&q,&go)); + pull_done=boost::async(boost::launch::async, + call_pull_front<int>(&q,&go)); + + push_done.get(); + BOOST_TEST_EQ(pull_done.get(), 42); + BOOST_TEST(q.empty()); + } + catch (...) + { + BOOST_TEST(false); + } +} + +#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +void test_concurrent_push_back_and_wait_pull_front_on_empty_queue() +{ + boost::sync_deque<int> q; + const unsigned int n = 3; + boost::barrier go(n); + + boost::future<boost::queue_op_status> pull_done[n]; + int results[n]; + + try + { + for (unsigned int i =0; i< n; ++i) + pull_done[i]=boost::async(boost::launch::async, + call_wait_pull_front<int>(&q,&go), + boost::ref(results[i])); + + for (unsigned int i =0; i< n; ++i) + q.push_back(42); + + for (unsigned int i = 0; i < n; ++i) { + BOOST_TEST(pull_done[i].get() == boost::queue_op_status::success); + BOOST_TEST_EQ(results[i], 42); + } + BOOST_TEST(q.empty()); + } + catch (...) + { + BOOST_TEST(false); + } +} + +void test_concurrent_wait_pull_front_and_close_on_empty_queue() +{ + boost::sync_deque<int> q; + const unsigned int n = 3; + boost::barrier go(n); + + boost::future<boost::queue_op_status> pull_done[n]; + int results[n]; + + try + { + for (unsigned int i =0; i< n; ++i) + pull_done[i]=boost::async(boost::launch::async, + call_wait_pull_front<int>(&q,&go), + boost::ref(results[i])); + + q.close(); + + for (unsigned int i = 0; i < n; ++i) { + BOOST_TEST(pull_done[i].get() == boost::queue_op_status::closed); + } + BOOST_TEST(q.empty()); + } + catch (...) + { + BOOST_TEST(false); + } +} +#endif + +void test_concurrent_push_back_on_empty_queue() +{ + boost::sync_deque<int> q; + const unsigned int n = 3; + boost::barrier go(n); + boost::future<void> push_done[n]; + + try + { + for (unsigned int i =0; i< n; ++i) + push_done[i]=boost::async(boost::launch::async, + call_push_back<int>(&q,&go)); + + } + catch (...) + { + BOOST_TEST(false); + } + try + { + for (unsigned int i = 0; i < n; ++i) + push_done[i].get(); + + } + catch (...) + { + BOOST_TEST(false); + } + try + { + BOOST_TEST(!q.empty()); + for (unsigned int i =0; i< n; ++i) + BOOST_TEST_EQ(q.pull_front(), 42); + BOOST_TEST(q.empty()); + + } + catch (...) + { + BOOST_TEST(false); + } +} + +void test_concurrent_pull_front_on_queue() +{ + boost::sync_deque<int> q; + const unsigned int n = 3; + boost::barrier go(n); + + boost::future<int> pull_done[n]; + + try + { + for (unsigned int i =0; i< n; ++i) + q.push_back(42); + + for (unsigned int i =0; i< n; ++i) + pull_done[i]=boost::async(boost::launch::async, +#if ! defined BOOST_NO_CXX11_LAMBDAS + [&q,&go]() -> int + { + go.wait(); + return q.pull_front(); + } +#else + call_pull_front<int>(&q,&go) +#endif + ); + + for (unsigned int i = 0; i < n; ++i) + BOOST_TEST_EQ(pull_done[i].get(), 42); + BOOST_TEST(q.empty()); + } + catch (...) + { + BOOST_TEST(false); + } +} + +int main() +{ + test_concurrent_push_back_and_pull_front_on_empty_queue(); +#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + test_concurrent_push_back_and_wait_pull_front_on_empty_queue(); + test_concurrent_wait_pull_front_and_close_on_empty_queue(); +#endif + test_concurrent_push_back_on_empty_queue(); + test_concurrent_pull_front_on_queue(); + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/sync_deque/single_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_deque/single_thread_pass.cpp new file mode 100644 index 000000000..5170bcf61 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_deque/single_thread_pass.cpp @@ -0,0 +1,403 @@ +// Copyright (C) 2013,2015 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/concurrent_queues/sync_deque.hpp> + +// class sync_deque<T> + +// sync_deque(); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/concurrent_queues/sync_deque.hpp> + +#include <boost/detail/lightweight_test.hpp> + +class non_copyable +{ + BOOST_THREAD_MOVABLE_ONLY(non_copyable) + int val; +public: + non_copyable(int v) : val(v){} + non_copyable(BOOST_RV_REF(non_copyable) x): val(x.val) {} + non_copyable& operator=(BOOST_RV_REF(non_copyable) x) { val=x.val; return *this; } + bool operator==(non_copyable const& x) const {return val==x.val;} + template <typename OSTREAM> + friend OSTREAM& operator <<(OSTREAM& os, non_copyable const&x ) + { + os << x.val; + return os; + } + +}; + + + +int main() +{ + + { + // default queue invariants + boost::sync_deque<int> q; + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_pull fails + boost::sync_deque<int> q; + int i; + BOOST_TEST( boost::queue_op_status::empty == q.try_pull_front(i)); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // empty queue push rvalue/copyable succeeds + boost::sync_deque<int> q; + q.push_back(1); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue push lvalue/copyable succeeds + boost::sync_deque<int> q; + int i; + q.push_back(i); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + { + // empty queue push rvalue/non_copyable succeeds + boost::sync_deque<non_copyable> q; + q.push_back(non_copyable(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif + { + // empty queue push rvalue/non_copyable succeeds + boost::sync_deque<non_copyable> q; + non_copyable nc(1); + q.push_back(boost::move(nc)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + + { + // empty queue push rvalue succeeds + boost::sync_deque<int> q; + q.push_back(1); + q.push_back(2); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 2u); + BOOST_TEST(! q.closed()); + } + { + // empty queue push lvalue succeeds + boost::sync_deque<int> q; + int i; + q.push_back(i); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue/copyable succeeds + boost::sync_deque<int> q; + BOOST_TEST(boost::queue_op_status::success == q.try_push_back(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue/copyable succeeds + boost::sync_deque<int> q; + BOOST_TEST(boost::queue_op_status::success == q.try_push_back(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + { + // empty queue try_push rvalue/non-copyable succeeds + boost::sync_deque<non_copyable> q; + BOOST_TEST(boost::queue_op_status::success ==q.try_push_back(non_copyable(1))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif + { + // empty queue try_push rvalue/non-copyable succeeds + boost::sync_deque<non_copyable> q; + non_copyable nc(1); + BOOST_TEST(boost::queue_op_status::success == q.try_push_back(boost::move(nc))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + + { + // empty queue try_push lvalue succeeds + boost::sync_deque<int> q; + int i=1; + BOOST_TEST(boost::queue_op_status::success == q.try_push_back(i)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue succeeds + boost::sync_deque<int> q; + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + { + // empty queue nonblocking_push_back rvalue/non-copyable succeeds + boost::sync_deque<non_copyable> q; + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(non_copyable(1))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif + { + // empty queue nonblocking_push_back rvalue/non-copyable succeeds + boost::sync_deque<non_copyable> q; + non_copyable nc(1); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push_back(boost::move(nc))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue pull_front succeed + boost::sync_deque<int> q; + q.push_back(1); + int i; + q.pull_front(i); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue pull_front succeed + boost::sync_deque<non_copyable> q; + non_copyable nc1(1); + q.push_back(boost::move(nc1)); + non_copyable nc2(2); + q.pull_front(nc2); + BOOST_TEST_EQ(nc1, nc2); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue pull_front succeed + boost::sync_deque<int> q; + q.push_back(1); + int i = q.pull_front(); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue pull_front succeed + boost::sync_deque<non_copyable> q; + non_copyable nc1(1); + q.push_back(boost::move(nc1)); + non_copyable nc = q.pull_front(); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue try_pull_front succeed + boost::sync_deque<int> q; + q.push_back(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.try_pull_front(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue try_pull_front succeed + boost::sync_deque<non_copyable> q; + non_copyable nc1(1); + q.push_back(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.try_pull_front(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue nonblocking_pull_front succeed + boost::sync_deque<int> q; + q.push_back(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull_front(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue nonblocking_pull_front succeed + boost::sync_deque<non_copyable> q; + non_copyable nc1(1); + q.push_back(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull_front(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue wait_pull_front succeed + boost::sync_deque<non_copyable> q; + non_copyable nc1(1); + q.push_back(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue wait_pull_front succeed + boost::sync_deque<int> q; + q.push_back(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue wait_pull_front succeed + boost::sync_deque<non_copyable> q; + non_copyable nc1(1); + q.push_back(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + + { + // closed invariants + boost::sync_deque<int> q; + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed queue push fails + boost::sync_deque<int> q; + q.close(); + try { + q.push_back(1); + BOOST_TEST(false); + } catch (...) { + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + } + { + // 1-element closed queue pull succeed + boost::sync_deque<int> q; + q.push_back(1); + q.close(); + int i; + q.pull_front(i); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // 1-element closed queue wait_pull_front succeed + boost::sync_deque<int> q; + q.push_back(1); + q.close(); + int i; + BOOST_TEST(boost::queue_op_status::success == q.wait_pull_front(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed empty queue wait_pull_front fails + boost::sync_deque<int> q; + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(q.closed()); + int i; + BOOST_TEST(boost::queue_op_status::closed == q.wait_pull_front(i)); + BOOST_TEST(q.empty()); + BOOST_TEST(q.closed()); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_multi_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_multi_thread_pass.cpp new file mode 100644 index 000000000..92e183079 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_multi_thread_pass.cpp @@ -0,0 +1,219 @@ +// Copyright (C) 2014 Ian Forbed +// Copyright (C) 2014 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include <boost/config.hpp> +#if ! defined BOOST_NO_CXX11_DECLTYPE +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif + +#define BOOST_THREAD_VERSION 4 +#define BOOST_THREAD_PROVIDES_EXECUTORS + +#include <exception> + +#include <boost/thread/thread.hpp> +#include <boost/thread/barrier.hpp> +#include <boost/thread/concurrent_queues/sync_priority_queue.hpp> + +#include <boost/core/lightweight_test.hpp> + +#ifdef BOOST_MSVC +#pragma warning(disable: 4127) // conditional expression is constant +#endif + +typedef boost::concurrent::sync_priority_queue<int> sync_pq; + +int call_pull(sync_pq* q, boost::barrier* go) +{ + go->wait(); + return q->pull(); + +} + +void call_push(sync_pq* q, boost::barrier* go, int val) +{ + go->wait(); + q->push(val); +} + +void test_pull(const int n) +{ + sync_pq pq; + BOOST_TEST(pq.empty()); + for(int i = 0; i < n; i++) + { + pq.push(i); + } + BOOST_TEST(!pq.empty()); + BOOST_TEST_EQ(pq.size(), std::size_t(n)); + pq.close(); + BOOST_TEST(pq.closed()); + boost::barrier b(n); + boost::thread_group tg; + for(int i = 0; i < n; i++) + { + tg.create_thread(boost::bind(call_pull, &pq, &b)); + } + tg.join_all(); + BOOST_TEST(pq.empty()); +} + +void test_push(const int n) +{ + sync_pq pq; + BOOST_TEST(pq.empty()); + + boost::barrier b(n); + boost::thread_group tg; + for(int i = 0; i < n; i++) + { + tg.create_thread(boost::bind(call_push, &pq, &b, i)); + } + tg.join_all(); + BOOST_TEST(!pq.empty()); + BOOST_TEST_EQ(pq.size(), std::size_t(n)); +} + +void test_both(const int n) +{ + sync_pq pq; + BOOST_TEST(pq.empty()); + + boost::barrier b(2*n); + boost::thread_group tg; + for(int i = 0; i < n; i++) + { + tg.create_thread(boost::bind(call_pull, &pq, &b)); + tg.create_thread(boost::bind(call_push, &pq, &b, i)); + } + tg.join_all(); + BOOST_TEST(pq.empty()); + BOOST_TEST_EQ(pq.size(), std::size_t(0)); +} + +void push_range(sync_pq* q, const int begin, const int end) +{ + for(int i = begin; i < end; i++) + q->push(i); +} + +void atomic_pull(sync_pq* q, boost::atomic<int>* sum) +{ + while(1) + { + try{ + const int val = q->pull(); + sum->fetch_add(val); + } + catch(std::exception& ){ + break; + } + } +} + +/** + * This test computes the sum of the first N integers upto $limit using + * $n threads for the push operation and $n threads for the pull and count + * operation. The push operation push a range of numbers on the queue while + * the pull operation pull from the queue and increments an atomic int. + * At the end of execution the value of atomic<int> $sum should be the same + * as n*(n+1)/2 as this is the closed form solution to this problem. + */ +void compute_sum(const int n) +{ + const int limit = 1000; + sync_pq pq; + BOOST_TEST(pq.empty()); + boost::atomic<int> sum(0); + boost::thread_group tg1; + boost::thread_group tg2; + for(int i = 0; i < n; i++) + { + tg1.create_thread(boost::bind(push_range, &pq, i*(limit/n)+1, (i+1)*(limit/n)+1)); + tg2.create_thread(boost::bind(atomic_pull, &pq, &sum)); + } + tg1.join_all(); + pq.close(); //Wait until all enqueuing is done before closing. + BOOST_TEST(pq.closed()); + tg2.join_all(); + BOOST_TEST(pq.empty()); + BOOST_TEST_EQ(sum.load(), limit*(limit+1)/2); +} + +void move_between_queues(sync_pq* q1, sync_pq* q2) +{ + while(1){ + try{ + const int val = q1->pull(); + q2->push(val); + } + catch(std::exception& ){ + break; + } + } +} + +/** + * This test computes the sum of the first N integers upto $limit by moving + * numbers between 2 sync_priority_queues. A range of numbers are pushed onto + * one queue by $n threads while $n threads pull from this queue and push onto + * another sync_pq. At the end the main thread ensures the the values in the + * second queue are in proper order and then sums all the values from this + * queue. The sum should match n*(n+1)/2, the closed form solution to this + * problem. + */ +void sum_with_moving(const int n) +{ + const int limit = 1000; + sync_pq pq1; + sync_pq pq2; + BOOST_TEST(pq1.empty()); + BOOST_TEST(pq2.empty()); + boost::thread_group tg1; + boost::thread_group tg2; + for(int i = 0; i < n; i++) + { + tg1.create_thread(boost::bind(push_range, &pq1, i*(limit/n)+1, (i+1)*(limit/n)+1)); + tg2.create_thread(boost::bind(move_between_queues, &pq1, &pq2)); + } + tg1.join_all(); + pq1.close(); //Wait until all enqueuing is done before closing. + BOOST_TEST(pq1.closed()); + tg2.join_all(); + BOOST_TEST(pq1.empty()); + BOOST_TEST(!pq2.empty()); + int sum = 0; + for(int i = 1000; i > 0; i--){ + const int val = pq2.pull(); + BOOST_TEST_EQ(i,val); + sum += val; + } + BOOST_TEST(pq2.empty()); + BOOST_TEST_EQ(sum, limit*(limit+1)/2); +} + +int main() +{ + for(int i = 1; i <= 64; i *= 2) + { + test_pull(i); + test_push(i); + test_both(i); + } + //These numbers must divide 1000 + compute_sum(1); + compute_sum(4); + compute_sum(10); + compute_sum(25); + compute_sum(50); + sum_with_moving(1); + sum_with_moving(4); + sum_with_moving(10); + sum_with_moving(25); + sum_with_moving(50); + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_single_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_single_thread_pass.cpp new file mode 100644 index 000000000..b51827731 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/pq_single_thread_pass.cpp @@ -0,0 +1,429 @@ +// Copyright (C) 2014 Ian Forbed +// Copyright (C) 2014,2015 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include <boost/config.hpp> +#if ! defined BOOST_NO_CXX11_DECLTYPE +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif + +#define BOOST_THREAD_VERSION 4 +#define BOOST_THREAD_PROVIDES_EXECUTORS + +#include <iostream> + +#include <boost/thread.hpp> +#include <boost/chrono.hpp> +#include <boost/thread/concurrent_queues/sync_priority_queue.hpp> + +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + +using namespace boost::chrono; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; + +typedef boost::concurrent::sync_priority_queue<int> sync_pq; + +class non_copyable +{ + BOOST_THREAD_MOVABLE_ONLY(non_copyable) + int val; +public: + non_copyable(int v) : val(v){} + non_copyable(BOOST_RV_REF(non_copyable) x): val(x.val) {} + non_copyable& operator=(BOOST_RV_REF(non_copyable) x) { val=x.val; return *this; } + bool operator==(non_copyable const& x) const {return val==x.val;} + template <typename OSTREAM> + friend OSTREAM& operator <<(OSTREAM& os, non_copyable const&x ) + { + os << x.val; + return os; + } + bool operator <(const non_copyable& other) const + { + return val < other.val; + } +}; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void test_pull_for() +{ + sync_pq pq; + steady_clock::time_point start = steady_clock::now(); + int val; + boost::queue_op_status st = pq.pull_for(milliseconds(500), val); + ns d = steady_clock::now() - start - milliseconds(500); + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + BOOST_TEST(boost::queue_op_status::timeout == st); +} + +void test_pull_until() +{ + sync_pq pq; + steady_clock::time_point start = steady_clock::now(); + int val; + boost::queue_op_status st = pq.pull_until(start + milliseconds(500), val); + ns d = steady_clock::now() - start - milliseconds(500); + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + BOOST_TEST(boost::queue_op_status::timeout == st); +} + +void test_nonblocking_pull() +{ + sync_pq pq; + steady_clock::time_point start = steady_clock::now(); + int val; + boost::queue_op_status st = pq.nonblocking_pull(val); + ns d = steady_clock::now() - start; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + BOOST_TEST(boost::queue_op_status::empty == st); +} + +void test_pull_for_when_not_empty() +{ + sync_pq pq; + pq.push(1); + steady_clock::time_point start = steady_clock::now(); + int val; + boost::queue_op_status st = pq.pull_for(milliseconds(500), val); + ns d = steady_clock::now() - start; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + BOOST_TEST(boost::queue_op_status::success == st); + BOOST_TEST(1 == val); +} + +void test_pull_until_when_not_empty() +{ + sync_pq pq; + pq.push(1); + steady_clock::time_point start = steady_clock::now(); + int val; + boost::queue_op_status st = pq.pull_until(start + milliseconds(500), val); + ns d = steady_clock::now() - start; + BOOST_THREAD_TEST_IT(d, ns(max_diff)); + BOOST_TEST(boost::queue_op_status::success == st); + BOOST_TEST(1 == val); +} + +int main() +{ + sync_pq pq; + BOOST_TEST(pq.empty()); + BOOST_TEST(!pq.closed()); + BOOST_TEST_EQ(pq.size(), std::size_t(0)); + + for(int i = 1; i <= 5; i++){ + pq.push(i); + BOOST_TEST(!pq.empty()); + BOOST_TEST_EQ(pq.size(), std::size_t(i)); + } + + for(int i = 6; i <= 10; i++){ + boost::queue_op_status succ = pq.try_push(i); + BOOST_TEST(succ == boost::queue_op_status::success ); + BOOST_TEST(!pq.empty()); + BOOST_TEST_EQ(pq.size(), std::size_t(i)); + } + + for(int i = 10; i > 5; i--){ + int val = pq.pull(); + BOOST_TEST_EQ(val, i); + } + +// for(int i = 5; i > 0; i--){ +// boost::optional<int> val = pq.try_pull(); +// BOOST_TEST(val); +// BOOST_TEST_EQ(*val, i); +// } + +// BOOST_TEST(pq.empty()); + pq.close(); + BOOST_TEST(pq.closed()); + + test_pull_for(); + test_pull_until(); + test_nonblocking_pull(); + + test_pull_for_when_not_empty(); + //test_pull_until_when_not_empty(); + +#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES + { + // empty queue try_push rvalue/non-copyable succeeds + boost::concurrent::sync_priority_queue<non_copyable> q; + BOOST_TEST(boost::queue_op_status::success ==q.try_push(non_copyable(1))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + //fixme + // empty queue try_push rvalue/non-copyable succeeds + boost::concurrent::sync_priority_queue<non_copyable> q; + non_copyable nc(1); + BOOST_TEST(boost::queue_op_status::success == q.try_push(boost::move(nc))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif + + { + // empty queue try_push lvalue succeeds + boost::concurrent::sync_priority_queue<int> q; + int i=1; + BOOST_TEST(boost::queue_op_status::success == q.try_push(i)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#if 0 + { + // empty queue try_push rvalue succeeds + boost::concurrent::sync_priority_queue<int> q; + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue nonblocking_push rvalue/non-copyable succeeds + boost::concurrent::sync_priority_queue<non_copyable> q; + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(non_copyable(1))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue nonblocking_push rvalue/non-copyable succeeds + boost::concurrent::sync_priority_queue<non_copyable> q; + non_copyable nc(1); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(boost::move(nc))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif + + { + // 1-element queue pull succeed + boost::concurrent::sync_priority_queue<int> q; + q.push(1); + int i; + i=q.pull(); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES + { + // 1-element queue pull succeed + boost::concurrent::sync_priority_queue<non_copyable> q; + non_copyable nc1(1); + q.push(boost::move(nc1)); + non_copyable nc2(2); + nc2=q.pull(); + BOOST_TEST_EQ(nc1, nc2); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#endif + + { + // 1-element queue pull succeed + boost::concurrent::sync_priority_queue<int> q; + q.push(1); + int i = q.pull(); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES + { + // 1-element queue pull succeed + boost::concurrent::sync_priority_queue<non_copyable> q; + non_copyable nc1(1); + q.push(boost::move(nc1)); + non_copyable nc = q.pull(); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#endif + + { + // 1-element queue try_pull succeed + boost::concurrent::sync_priority_queue<int> q; + q.push(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.try_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES + { + // 1-element queue try_pull succeed + boost::concurrent::sync_priority_queue<non_copyable> q; + non_copyable nc1(1); + q.push(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.try_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#endif + { + // 1-element queue nonblocking_pull succeed + boost::concurrent::sync_priority_queue<int> q; + q.push(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES + { + // 1-element queue nonblocking_pull succeed + boost::concurrent::sync_priority_queue<non_copyable> q; + non_copyable nc1(1); + q.push(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue wait_pull succeed + boost::concurrent::sync_priority_queue<non_copyable> q; + non_copyable nc1(1); + q.push(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#endif + { + // 1-element queue wait_pull succeed + boost::concurrent::sync_priority_queue<int> q; + q.push(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES + { + // 1-element queue wait_pull succeed + boost::concurrent::sync_priority_queue<non_copyable> q; + non_copyable nc1(1); + q.push(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } +#endif + + { + // closed invariants + boost::concurrent::sync_priority_queue<int> q; + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed queue push fails + boost::concurrent::sync_priority_queue<int> q; + q.close(); + try { + q.push(1); + BOOST_TEST(false); // fixme + } catch (...) { + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + } + { + // 1-element closed queue pull succeed + boost::concurrent::sync_priority_queue<int> q; + q.push(1); + q.close(); + int i; + i=q.pull(); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // 1-element closed queue wait_pull succeed + boost::concurrent::sync_priority_queue<int> q; + q.push(1); + q.close(); + int i; + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed empty queue wait_pull fails + boost::concurrent::sync_priority_queue<int> q; + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(q.closed()); + int i; + BOOST_TEST(boost::queue_op_status::closed == q.wait_pull(i)); + BOOST_TEST(q.empty()); + BOOST_TEST(q.closed()); + } + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/tq_multi_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/tq_multi_thread_pass.cpp new file mode 100644 index 000000000..77656f8b3 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/tq_multi_thread_pass.cpp @@ -0,0 +1,124 @@ +// Copyright (C) 2019 Austin Beer +// Copyright (C) 2019 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include <boost/config.hpp> +#if ! defined BOOST_NO_CXX11_DECLTYPE +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif + +#define BOOST_THREAD_VERSION 4 +#define BOOST_THREAD_PROVIDES_EXECUTORS + +#include <boost/thread.hpp> +#include <boost/chrono.hpp> +#include <boost/thread/concurrent_queues/sync_timed_queue.hpp> + +#include <boost/core/lightweight_test.hpp> +#include "../../../timming.hpp" + +using namespace boost::chrono; + +typedef boost::concurrent::sync_timed_queue<int> sync_tq; + +const int cnt = 5; + +void call_push(sync_tq* q, const steady_clock::time_point start) +{ + // push elements onto the queue every 500 milliseconds but with a decreasing delay each time + for (int i = 0; i < cnt; ++i) + { + boost::this_thread::sleep_until(start + milliseconds(i * 500)); + const steady_clock::time_point expected = start + milliseconds(i * 500) + seconds(cnt - i); + q->push(i, expected); + } +} + +void call_pull(sync_tq* q, const steady_clock::time_point start) +{ + // pull elements off of the queue (earliest element first) + for (int i = cnt - 1; i >= 0; --i) + { + int j; + q->pull(j); + BOOST_TEST_EQ(i, j); + const steady_clock::time_point expected = start + milliseconds(i * 500) + seconds(cnt - i); + BOOST_TEST_GE(steady_clock::now(), expected - milliseconds(BOOST_THREAD_TEST_TIME_MS)); + BOOST_TEST_LE(steady_clock::now(), expected + milliseconds(BOOST_THREAD_TEST_TIME_MS)); + } +} + +void call_pull_until(sync_tq* q, const steady_clock::time_point start) +{ + // pull elements off of the queue (earliest element first) + for (int i = cnt - 1; i >= 0; --i) + { + int j; + q->pull_until(steady_clock::now() + hours(1), j); + BOOST_TEST_EQ(i, j); + const steady_clock::time_point expected = start + milliseconds(i * 500) + seconds(cnt - i); + BOOST_TEST_GE(steady_clock::now(), expected - milliseconds(BOOST_THREAD_TEST_TIME_MS)); + BOOST_TEST_LE(steady_clock::now(), expected + milliseconds(BOOST_THREAD_TEST_TIME_MS)); + } +} + +void call_pull_for(sync_tq* q, const steady_clock::time_point start) +{ + // pull elements off of the queue (earliest element first) + for (int i = cnt - 1; i >= 0; --i) + { + int j; + q->pull_for(hours(1), j); + BOOST_TEST_EQ(i, j); + const steady_clock::time_point expected = start + milliseconds(i * 500) + seconds(cnt - i); + BOOST_TEST_GE(steady_clock::now(), expected - milliseconds(BOOST_THREAD_TEST_TIME_MS)); + BOOST_TEST_LE(steady_clock::now(), expected + milliseconds(BOOST_THREAD_TEST_TIME_MS)); + } +} + +void test_push_while_pull() +{ + sync_tq tq; + BOOST_TEST(tq.empty()); + boost::thread_group tg; + const steady_clock::time_point start = steady_clock::now(); + tg.create_thread(boost::bind(call_push, &tq, start)); + tg.create_thread(boost::bind(call_pull, &tq, start)); + tg.join_all(); + BOOST_TEST(tq.empty()); +} + +void test_push_while_pull_until() +{ + sync_tq tq; + BOOST_TEST(tq.empty()); + boost::thread_group tg; + const steady_clock::time_point start = steady_clock::now(); + tg.create_thread(boost::bind(call_push, &tq, start)); + tg.create_thread(boost::bind(call_pull_until, &tq, start)); + tg.join_all(); + BOOST_TEST(tq.empty()); +} + +void test_push_while_pull_for() +{ + sync_tq tq; + BOOST_TEST(tq.empty()); + boost::thread_group tg; + const steady_clock::time_point start = steady_clock::now(); + tg.create_thread(boost::bind(call_push, &tq, start)); + tg.create_thread(boost::bind(call_pull_for, &tq, start)); + tg.join_all(); + BOOST_TEST(tq.empty()); +} + +int main() +{ + test_push_while_pull(); + test_push_while_pull_until(); + test_push_while_pull_for(); + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/tq_single_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/tq_single_thread_pass.cpp new file mode 100644 index 000000000..dd4dfc17f --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_pq/tq_single_thread_pass.cpp @@ -0,0 +1,155 @@ +// Copyright (C) 2014 Ian Forbed +// Copyright (C) 2014 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include <boost/config.hpp> +#if ! defined BOOST_NO_CXX11_DECLTYPE +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif + +#define BOOST_THREAD_VERSION 4 +#define BOOST_THREAD_PROVIDES_EXECUTORS + +#include <boost/thread.hpp> +#include <boost/chrono.hpp> +#include <boost/function.hpp> +#include <boost/thread/concurrent_queues/sync_timed_queue.hpp> +#include <boost/thread/executors/work.hpp> + +#include <boost/core/lightweight_test.hpp> + +using namespace boost::chrono; + +typedef boost::concurrent::sync_timed_queue<int> sync_tq; + +void test_all() +{ + sync_tq pq; + BOOST_TEST(pq.empty()); + BOOST_TEST(!pq.closed()); + BOOST_TEST_EQ(pq.size(), std::size_t(0)); + + for(int i = 1; i <= 5; i++){ + pq.push(i, milliseconds(i*100)); + BOOST_TEST(!pq.empty()); + BOOST_TEST_EQ(pq.size(), std::size_t(i)); + } + + for(int i = 6; i <= 10; i++){ + pq.push(i,steady_clock::now() + milliseconds(i*100)); + BOOST_TEST(!pq.empty()); + BOOST_TEST_EQ(pq.size(), std::size_t(i)); + } + + for(int i = 1; i <= 10; i++){ + int val = pq.pull(); + BOOST_TEST_EQ(val, i); + } + + int val; + boost::queue_op_status st = pq.nonblocking_pull(val); + BOOST_TEST(boost::queue_op_status::empty == st); + + BOOST_TEST(pq.empty()); + pq.close(); + BOOST_TEST(pq.closed()); +} + +void test_all_with_try() +{ + sync_tq pq; + BOOST_TEST(pq.empty()); + BOOST_TEST(!pq.closed()); + BOOST_TEST_EQ(pq.size(), std::size_t(0)); + + for(int i = 1; i <= 5; i++){ + boost::queue_op_status st = pq.try_push(i, milliseconds(i*100)); + BOOST_TEST(st == boost::queue_op_status::success ); + BOOST_TEST(!pq.empty()); + BOOST_TEST_EQ(pq.size(), std::size_t(i)); + } + + for(int i = 6; i <= 10; i++){ + boost::queue_op_status st = pq.try_push(i,steady_clock::now() + milliseconds(i*100)); + BOOST_TEST(st == boost::queue_op_status::success ); + BOOST_TEST(!pq.empty()); + BOOST_TEST_EQ(pq.size(), std::size_t(i)); + } + + for(int i = 1; i <= 10; i++){ + int val=0; + boost::queue_op_status st = pq.wait_pull(val); + BOOST_TEST(st == boost::queue_op_status::success ); + BOOST_TEST_EQ(val, i); + } + + int val; + boost::queue_op_status st = pq.nonblocking_pull(val); + BOOST_TEST(st == boost::queue_op_status::empty ); + + BOOST_TEST(pq.empty()); + pq.close(); + BOOST_TEST(pq.closed()); +} + +void func(steady_clock::time_point pushed, steady_clock::duration dur) +{ + BOOST_TEST(pushed + dur <= steady_clock::now()); +} +void func2() +{ + BOOST_TEST(false); +} + +/** + * This test ensures that when items come of the front of the queue + * that at least $dur has elapsed. + */ +void test_deque_times() +{ + boost::concurrent::sync_timed_queue<boost::function<void()> > tq; + for(int i = 0; i < 10; i++) + { + steady_clock::duration d = milliseconds(i*100); + boost::function<void()> fn = boost::bind(func, steady_clock::now(), d); + tq.push(fn, d); + } + while(!tq.empty()) + { + boost::function<void()> fn = tq.pull(); + fn(); + } +} + +/** + * This test ensures that when items come of the front of the queue + * that at least $dur has elapsed. + */ +#if 0 +void test_deque_times2() +{ + boost::concurrent::sync_timed_queue<boost::executors::work> tq; + for(int i = 0; i < 10; i++) + { + steady_clock::duration d = milliseconds(i*100); + tq.push(func2, d); + } + while(!tq.empty()) + { + boost::executors::work fn = tq.pull(); + fn(); + } +} +#endif + +int main() +{ + test_all(); + test_all_with_try(); + test_deque_times(); + //test_deque_times2(); // rt fails + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp new file mode 100644 index 000000000..556ca68e9 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_queue/multi_thread_pass.cpp @@ -0,0 +1,256 @@ +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/sync_queue.hpp> + +// class sync_queue<T> + +// push || pull; + +#include <boost/config.hpp> +#if ! defined BOOST_NO_CXX11_DECLTYPE +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/sync_queue.hpp> +#include <boost/thread/future.hpp> +#include <boost/thread/barrier.hpp> + +#include <boost/detail/lightweight_test.hpp> + +template <typename ValueType> +struct call_push +{ + boost::sync_queue<ValueType> *q_; + boost::barrier *go_; + + call_push(boost::sync_queue<ValueType> *q, boost::barrier *go) : + q_(q), go_(go) + { + } + typedef void result_type; + void operator()() + { + go_->count_down_and_wait(); + q_->push(42); + } +}; + +template <typename ValueType> +struct call_pull +{ + boost::sync_queue<ValueType> *q_; + boost::barrier *go_; + + call_pull(boost::sync_queue<ValueType> *q, boost::barrier *go) : + q_(q), go_(go) + { + } + typedef ValueType result_type; + ValueType operator()() + { + go_->count_down_and_wait(); + return q_->pull(); + } +}; + +template <typename ValueType> +struct call_wait_pull +{ + boost::sync_queue<ValueType> *q_; + boost::barrier *go_; + + call_wait_pull(boost::sync_queue<ValueType> *q, boost::barrier *go) : + q_(q), go_(go) + { + } + typedef boost::queue_op_status result_type; + boost::queue_op_status operator()(ValueType& v) + { + go_->wait(); + return q_->wait_pull(v); + } +}; + +void test_concurrent_push_and_pull_on_empty_queue() +{ + boost::sync_queue<int> q; + + boost::barrier go(2); + + boost::future<void> push_done; + boost::future<int> pull_done; + + try + { + push_done=boost::async(boost::launch::async, + call_push<int>(&q,&go)); + pull_done=boost::async(boost::launch::async, + call_pull<int>(&q,&go)); + + push_done.get(); + BOOST_TEST_EQ(pull_done.get(), 42); + BOOST_TEST(q.empty()); + } + catch (...) + { + BOOST_TEST(false); + } +} + +#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +void test_concurrent_push_and_wait_pull_on_empty_queue() +{ + boost::sync_queue<int> q; + const unsigned int n = 3; + boost::barrier go(n); + + boost::future<boost::queue_op_status> pull_done[n]; + int results[n]; + + try + { + for (unsigned int i =0; i< n; ++i) + pull_done[i]=boost::async(boost::launch::async, + call_wait_pull<int>(&q,&go), + boost::ref(results[i])); + + for (unsigned int i =0; i< n; ++i) + q.push(42); + + for (unsigned int i = 0; i < n; ++i) { + BOOST_TEST(pull_done[i].get() == boost::queue_op_status::success); + BOOST_TEST_EQ(results[i], 42); + } + BOOST_TEST(q.empty()); + } + catch (...) + { + BOOST_TEST(false); + } +} + +void test_concurrent_wait_pull_and_close_on_empty_queue() +{ + boost::sync_queue<int> q; + const unsigned int n = 3; + boost::barrier go(n); + + boost::future<boost::queue_op_status> pull_done[n]; + int results[n]; + + try + { + for (unsigned int i =0; i< n; ++i) + pull_done[i]=boost::async(boost::launch::async, + call_wait_pull<int>(&q,&go), + boost::ref(results[i])); + + q.close(); + + for (unsigned int i = 0; i < n; ++i) { + BOOST_TEST(pull_done[i].get() == boost::queue_op_status::closed); + } + BOOST_TEST(q.empty()); + } + catch (...) + { + BOOST_TEST(false); + } +} +#endif + +void test_concurrent_push_on_empty_queue() +{ + boost::sync_queue<int> q; + const unsigned int n = 3; + boost::barrier go(n); + boost::future<void> push_done[n]; + + try + { + for (unsigned int i =0; i< n; ++i) + push_done[i]=boost::async(boost::launch::async, + call_push<int>(&q,&go)); + + } + catch (...) + { + BOOST_TEST(false); + } + try + { + for (unsigned int i = 0; i < n; ++i) + push_done[i].get(); + + } + catch (...) + { + BOOST_TEST(false); + } + try + { + BOOST_TEST(!q.empty()); + for (unsigned int i =0; i< n; ++i) + BOOST_TEST_EQ(q.pull(), 42); + BOOST_TEST(q.empty()); + + } + catch (...) + { + BOOST_TEST(false); + } +} + +void test_concurrent_pull_on_queue() +{ + boost::sync_queue<int> q; + const unsigned int n = 3; + boost::barrier go(n); + + boost::future<int> pull_done[n]; + + try + { + for (unsigned int i =0; i< n; ++i) + q.push(42); + + for (unsigned int i =0; i< n; ++i) + pull_done[i]=boost::async(boost::launch::async, +#if ! defined BOOST_NO_CXX11_LAMBDAS + [&q,&go]() -> int + { + go.wait(); + return q.pull(); + } +#else + call_pull<int>(&q,&go) +#endif + ); + + for (unsigned int i = 0; i < n; ++i) + BOOST_TEST_EQ(pull_done[i].get(), 42); + BOOST_TEST(q.empty()); + } + catch (...) + { + BOOST_TEST(false); + } +} + +int main() +{ + test_concurrent_push_and_pull_on_empty_queue(); +#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + test_concurrent_push_and_wait_pull_on_empty_queue(); + test_concurrent_wait_pull_and_close_on_empty_queue(); +#endif + test_concurrent_push_on_empty_queue(); + test_concurrent_pull_on_queue(); + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/sync_queue/single_thread_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_queue/single_thread_pass.cpp new file mode 100644 index 000000000..8f47ec82a --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/sync_queue/single_thread_pass.cpp @@ -0,0 +1,374 @@ +// Copyright (C) 2013,2015 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/sync_queue.hpp> + +// class sync_queue<T> + +// sync_queue(); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/sync_queue.hpp> + +#include <boost/detail/lightweight_test.hpp> + +class non_copyable +{ + BOOST_THREAD_MOVABLE_ONLY(non_copyable) + int val; +public: + non_copyable(int v) : val(v){} + non_copyable(BOOST_RV_REF(non_copyable) x): val(x.val) {} + non_copyable& operator=(BOOST_RV_REF(non_copyable) x) { val=x.val; return *this; } + bool operator==(non_copyable const& x) const {return val==x.val;} + template <typename OSTREAM> + friend OSTREAM& operator <<(OSTREAM& os, non_copyable const&x ) + { + os << x.val; + return os; + } + +}; + + + +int main() +{ + + { + // default queue invariants + boost::sync_queue<int> q; + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + { + // empty queue push rvalue/non_copyable succeeds + boost::sync_queue<non_copyable> q; + q.push(non_copyable(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif + { + // empty queue push rvalue/non_copyable succeeds + boost::sync_queue<non_copyable> q; + non_copyable nc(1); + q.push(boost::move(nc)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + + { + // empty queue push rvalue succeeds + boost::sync_queue<int> q; + q.push(1); + q.push(2); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 2u); + BOOST_TEST(! q.closed()); + } + { + // empty queue push lvalue succeeds + boost::sync_queue<int> q; + int i; + q.push(i); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue/copyable succeeds + boost::sync_queue<int> q; + BOOST_TEST(boost::queue_op_status::success == q.try_push(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue/copyable succeeds + boost::sync_queue<int> q; + BOOST_TEST(boost::queue_op_status::success == q.try_push(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + { + // empty queue try_push rvalue/non-copyable succeeds + boost::sync_queue<non_copyable> q; + BOOST_TEST(boost::queue_op_status::success ==q.try_push(non_copyable(1))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif + { + // empty queue try_push rvalue/non-copyable succeeds + boost::sync_queue<non_copyable> q; + non_copyable nc(1); + BOOST_TEST(boost::queue_op_status::success == q.try_push(boost::move(nc))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + + { + // empty queue try_push lvalue succeeds + boost::sync_queue<int> q; + int i=1; + BOOST_TEST(boost::queue_op_status::success == q.try_push(i)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // empty queue try_push rvalue succeeds + boost::sync_queue<int> q; + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(1)); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + { + // empty queue nonblocking_push rvalue/non-copyable succeeds + boost::sync_queue<non_copyable> q; + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(non_copyable(1))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } +#endif + { + // empty queue nonblocking_push rvalue/non-copyable succeeds + boost::sync_queue<non_copyable> q; + non_copyable nc(1); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_push(boost::move(nc))); + BOOST_TEST(! q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 1u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue pull succeed + boost::sync_queue<int> q; + q.push(1); + int i; + q.pull(i); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue pull succeed + boost::sync_queue<non_copyable> q; + non_copyable nc1(1); + q.push(boost::move(nc1)); + non_copyable nc2(2); + q.pull(nc2); + BOOST_TEST_EQ(nc1, nc2); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue pull succeed + boost::sync_queue<int> q; + q.push(1); + int i = q.pull(); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue pull succeed + boost::sync_queue<non_copyable> q; + non_copyable nc1(1); + q.push(boost::move(nc1)); + non_copyable nc = q.pull(); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue try_pull succeed + boost::sync_queue<int> q; + q.push(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.try_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue try_pull succeed + boost::sync_queue<non_copyable> q; + non_copyable nc1(1); + q.push(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.try_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue nonblocking_pull succeed + boost::sync_queue<int> q; + q.push(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue nonblocking_pull succeed + boost::sync_queue<non_copyable> q; + non_copyable nc1(1); + q.push(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.nonblocking_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue wait_pull succeed + boost::sync_queue<non_copyable> q; + non_copyable nc1(1); + q.push(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue wait_pull succeed + boost::sync_queue<int> q; + q.push(1); + int i; + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + { + // 1-element queue wait_pull succeed + boost::sync_queue<non_copyable> q; + non_copyable nc1(1); + q.push(boost::move(nc1)); + non_copyable nc(2); + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(nc)); + BOOST_TEST_EQ(nc, nc1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(! q.closed()); + } + + { + // closed invariants + boost::sync_queue<int> q; + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed queue push fails + boost::sync_queue<int> q; + q.close(); + try { + q.push(1); + BOOST_TEST(false); + } catch (...) { + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + } + { + // 1-element closed queue pull succeed + boost::sync_queue<int> q; + q.push(1); + q.close(); + int i; + q.pull(i); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // 1-element closed queue wait_pull succeed + boost::sync_queue<int> q; + q.push(1); + q.close(); + int i; + BOOST_TEST(boost::queue_op_status::success == q.wait_pull(i)); + BOOST_TEST_EQ(i, 1); + BOOST_TEST(q.empty()); + BOOST_TEST(! q.full()); + BOOST_TEST_EQ(q.size(), 0u); + BOOST_TEST(q.closed()); + } + { + // closed empty queue wait_pull fails + boost::sync_queue<int> q; + q.close(); + BOOST_TEST(q.empty()); + BOOST_TEST(q.closed()); + int i; + BOOST_TEST(boost::queue_op_status::closed == q.wait_pull(i)); + BOOST_TEST(q.empty()); + BOOST_TEST(q.closed()); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/call_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/call_pass.cpp new file mode 100644 index 000000000..f1ed8be4a --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/call_pass.cpp @@ -0,0 +1,144 @@ +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/synchronized_value.hpp> + +// class synchronized_value<T,M> + +// template <typename F> +// inline typename boost::result_of<F(value_type&)>::type +// operator()(BOOST_THREAD_RV_REF(F) fct); +// template <typename F> +// inline typename boost::result_of<F(value_type const&)>::type +// operator()(BOOST_THREAD_RV_REF(F) fct) const; + +#include <boost/config.hpp> +#if ! defined BOOST_NO_CXX11_DECLTYPE +#define BOOST_RESULT_OF_USE_DECLTYPE +#endif + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/synchronized_value.hpp> + +#include <boost/detail/lightweight_test.hpp> + +struct S { + int f() const {return 1;} + int g() {return 1;} +}; + +void c(S const& s) +{ + BOOST_TEST(s.f()==1); +} + +void nc(S & s) +{ + BOOST_TEST(s.f()==1); + BOOST_TEST(s.g()==1); +} + +struct cfctr { + typedef void result_type; + void operator()(S const& s) const { + BOOST_TEST(s.f()==1); + } +}; +struct ncfctr { + typedef void result_type; + void operator()(S& s) const { + BOOST_TEST(s.f()==1); + BOOST_TEST(s.g()==1); + } +}; + +struct cfctr3 { + typedef void result_type; + BOOST_THREAD_MOVABLE_ONLY(cfctr3) + cfctr3() + {} + cfctr3(BOOST_THREAD_RV_REF(cfctr3)) + {} + void operator()(S const& s) const { + BOOST_TEST(s.f()==1); + } +}; +struct ncfctr3 { + typedef void result_type; + BOOST_THREAD_MOVABLE_ONLY(ncfctr3) + ncfctr3() + {} + ncfctr3(BOOST_THREAD_RV_REF(ncfctr3)) + {} + void operator()(S& s) const { + BOOST_TEST(s.f()==1); + BOOST_TEST(s.g()==1); + } +}; + +cfctr3 make_cfctr3() { + return BOOST_THREAD_MAKE_RV_REF(cfctr3()); +} + +ncfctr3 make_ncfctr3() { + return BOOST_THREAD_MAKE_RV_REF(ncfctr3()); +} + +int main() +{ + { + boost::synchronized_value<S> v; + v(&nc); + v(&c); + } + { + const boost::synchronized_value<S> v; + v(&c); + } + { + boost::synchronized_value<S> v; + v(ncfctr()); + } + { + const boost::synchronized_value<S> v; + v(cfctr()); + } + { + boost::synchronized_value<S> v; + ncfctr fct; + v(fct); + } + { + const boost::synchronized_value<S> v; + cfctr fct; + v(fct); + } + { + boost::synchronized_value<S> v; + v(make_ncfctr3()); + } + { + const boost::synchronized_value<S> v; + v(make_cfctr3()); + } +#if ! defined BOOST_NO_CXX11_LAMBDAS + { + boost::synchronized_value<S> v; + v([](S& s) { + BOOST_TEST(s.f()==1); + BOOST_TEST(s.g()==1); + }); + } + { + const boost::synchronized_value<S> v; + v([](S const& s) { + BOOST_TEST(s.f()==1); + }); + } +#endif + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_T_assign_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_T_assign_pass.cpp new file mode 100644 index 000000000..3b43f8f90 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_T_assign_pass.cpp @@ -0,0 +1,30 @@ +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/synchronized_value.hpp> + +// class synchronized_value<T,M> + +// synchronized_value& operator=(T const&); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/synchronized_value.hpp> + +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + + { + int i = 1; + boost::synchronized_value<int> v; + v = i; + BOOST_TEST(v.value() == 1); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_T_ctor_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_T_ctor_pass.cpp new file mode 100644 index 000000000..e395c57aa --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_T_ctor_pass.cpp @@ -0,0 +1,29 @@ +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/synchronized_value.hpp> + +// class synchronized_value<T,M> + +// synchronized_value(T const&); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/synchronized_value.hpp> + +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + + { + int i = 1; + boost::synchronized_value<int> v(i); + BOOST_TEST(v.value() == 1); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_assign_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_assign_pass.cpp new file mode 100644 index 000000000..d4e80b0ce --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_assign_pass.cpp @@ -0,0 +1,31 @@ +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/synchronized_value.hpp> + +// class synchronized_value<T,M> + +// synchronized_value& operator=(synchronized_value const&); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/synchronized_value.hpp> + +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + + { + int i = 1; + boost::synchronized_value<int> v1(i); + boost::synchronized_value<int> v2; + v2 = v1; + BOOST_TEST(v2.value() == 1); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_ctor_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_ctor_pass.cpp new file mode 100644 index 000000000..13fcf6d80 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_ctor_pass.cpp @@ -0,0 +1,30 @@ +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/synchronized_value.hpp> + +// class synchronized_value<T,M> + +// synchronized_value(synchronized_value const&); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/synchronized_value.hpp> + +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + + { + int i = 1; + boost::synchronized_value<int> v1(i); + boost::synchronized_value<int> v2(v1); + BOOST_TEST(v2.value() == 1); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/default_ctor_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/default_ctor_pass.cpp new file mode 100644 index 000000000..7b4095650 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/default_ctor_pass.cpp @@ -0,0 +1,30 @@ +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/synchronized_value.hpp> + +// class synchronized_value<T,M> + +// synchronized_value(); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/synchronized_value.hpp> + +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + + { + boost::synchronized_value<int, boost::mutex > f; + } + { + boost::synchronized_value<int, boost::timed_mutex> f; + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/indirect_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/indirect_pass.cpp new file mode 100644 index 000000000..09b8e89d2 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/indirect_pass.cpp @@ -0,0 +1,38 @@ +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/synchronized_value.hpp> + +// class synchronized_value<T,M> + +// strict_lock_ptr<T,M> operator->(); +// const_strict_lock_ptr<T,M> operator->() const; + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/synchronized_value.hpp> + +#include <boost/detail/lightweight_test.hpp> + +struct S { + int f() const {return 1;} + int g() {return 1;} +}; + +int main() +{ + { + boost::synchronized_value<S> v; + BOOST_TEST(v->f()==1); + BOOST_TEST(v->g()==1); + } + { + const boost::synchronized_value<S> v; + BOOST_TEST(v->f()==1); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_T_assign_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_T_assign_pass.cpp new file mode 100644 index 000000000..146ed2e51 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_T_assign_pass.cpp @@ -0,0 +1,29 @@ +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/synchronized_value.hpp> + +// class synchronized_value<T,M> + +// synchronized_value& operator=(T &&); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/synchronized_value.hpp> + +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + + { + boost::synchronized_value<int> v; + v = 1; + BOOST_TEST(v.value() == 1); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_T_ctor_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_T_ctor_pass.cpp new file mode 100644 index 000000000..564d57da8 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_T_ctor_pass.cpp @@ -0,0 +1,28 @@ +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/synchronized_value.hpp> + +// class synchronized_value<T,M> + +// synchronized_value(T &&); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/synchronized_value.hpp> + +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + + { + boost::synchronized_value<int> v(1); + BOOST_TEST(v.value() == 1); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_assign_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_assign_pass.cpp new file mode 100644 index 000000000..818216382 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_assign_pass.cpp @@ -0,0 +1,30 @@ +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/synchronized_value.hpp> + +// class synchronized_value<T,M> + +// synchronized_value& operator=(synchronized_value &&); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/synchronized_value.hpp> + +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + + { + boost::synchronized_value<int> v1(1); + boost::synchronized_value<int> v2; + v2 = boost::move(v1); + BOOST_TEST(v2.value() == 1); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_ctor_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_ctor_pass.cpp new file mode 100644 index 000000000..7250e896f --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_ctor_pass.cpp @@ -0,0 +1,29 @@ +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/synchronized_value.hpp> + +// class synchronized_value<T,M> + +// synchronized_value(synchronized_value &&); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/synchronized_value.hpp> + +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + + { + boost::synchronized_value<int> v1(1); + boost::synchronized_value<int> v2(boost::move(v1)); + BOOST_TEST(v2.value() == 1); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/swap_T_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/swap_T_pass.cpp new file mode 100644 index 000000000..801b514d6 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/swap_T_pass.cpp @@ -0,0 +1,38 @@ +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/synchronized_value.hpp> + +// class synchronized_value<T,M> + +// void swap(synchronized_value&,synchronized_value&); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/synchronized_value.hpp> + +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + + { + boost::synchronized_value<int> v1(1); + int v2(2); + boost::swap(v1,v2); + BOOST_TEST(v1.value() == 2); + BOOST_TEST(v2 == 1); + } + { + boost::synchronized_value<int> v1(1); + int v2(2); + boost::swap(v2,v1); + BOOST_TEST(v1.value() == 2); + BOOST_TEST(v2 == 1); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/swap_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/swap_pass.cpp new file mode 100644 index 000000000..c52069ff3 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/swap_pass.cpp @@ -0,0 +1,31 @@ +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/synchronized_value.hpp> + +// class synchronized_value<T,M> + +// void swap(synchronized_value&,synchronized_value&); + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/synchronized_value.hpp> + +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + + { + boost::synchronized_value<int> v1(1); + boost::synchronized_value<int> v2(2); + swap(v1,v2); + BOOST_TEST(v1.value() == 2); + BOOST_TEST(v2.value() == 1); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/synchronize_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/synchronize_pass.cpp new file mode 100644 index 000000000..af24d79b6 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/synchronized_value/synchronize_pass.cpp @@ -0,0 +1,41 @@ +// Copyright (C) 2013 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/synchronized_value.hpp> + +// class synchronized_value<T,M> + +// strict_lock_ptr<T,M> synchronize(); +// const_strict_lock_ptr<T,M> synchronize() const; + + +#define BOOST_THREAD_VERSION 4 + +#include <boost/thread/synchronized_value.hpp> + +#include <boost/detail/lightweight_test.hpp> + +struct S { + int f() const {return 1;} + int g() {return 1;} +}; + +int main() +{ + { + boost::synchronized_value<S> v; + boost::strict_lock_ptr<S> ptr = v.synchronize(); + BOOST_TEST(ptr->f()==1); + BOOST_TEST(ptr->g()==1); + } + { + const boost::synchronized_value<S> v; + boost::const_strict_lock_ptr<S> ptr = v.synchronize(); + BOOST_TEST(ptr->f()==1); + } + + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/assign_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/assign_fail.cpp new file mode 100644 index 000000000..49188e130 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/assign_fail.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/timed_mutex.hpp> + +// class timed_mutex; + +// timed_mutex& operator=(const timed_mutex&) = delete; + +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::timed_mutex m0; + boost::timed_mutex m1(m0); +} + +#include "../../../remove_error_code_unused_warning.hpp" + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/copy_fail.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/copy_fail.cpp new file mode 100644 index 000000000..ed0a4c955 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/copy_fail.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/timed_mutex.hpp> + +// class timed_mutex; + +// timed_mutex(const timed_mutex&) = delete; + +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::timed_mutex m0; + boost::timed_mutex m1(m0); +} + +#include "../../../remove_error_code_unused_warning.hpp" diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/default_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/default_pass.cpp new file mode 100644 index 000000000..6b7c6f2b3 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/default_pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/timed_mutex.hpp> + +// class timed_mutex; + +// timed_mutex(); + +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + +int main() +{ + boost::timed_mutex m0; + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/lock_pass.cpp new file mode 100644 index 000000000..8d2733e1f --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/lock_pass.cpp @@ -0,0 +1,83 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/timed_mutex.hpp> + +// class timed_mutex; + +// void lock(); + +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + +boost::timed_mutex m; + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + m.lock(); + t1 = Clock::now(); + m.unlock(); +#else + //time_point t0 = Clock::now(); + m.lock(); + //time_point t1 = Clock::now(); + m.unlock(); + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#else +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} + + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/native_handle_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/native_handle_pass.cpp new file mode 100644 index 000000000..b203e5d91 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/native_handle_pass.cpp @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/timed_mutex.hpp> + +// class timed_mutex; + +// typedef pthread_timed_mutex_t* native_handle_type; +// native_handle_type native_handle(); + +#include <boost/thread/mutex.hpp> +#include <boost/detail/lightweight_test.hpp> + + +int main() +{ +#if defined BOOST_THREAD_DEFINES_TIMED_MUTEX_NATIVE_HANDLE + boost::timed_mutex m; + boost::timed_mutex::native_handle_type h = m.native_handle(); + BOOST_TEST(h); +#else +#error "Test not applicable: BOOST_THREAD_DEFINES_TIMED_MUTEX_NATIVE_HANDLE not defined for this platform as not supported" +#endif + return boost::report_errors(); +} + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_for_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_for_pass.cpp new file mode 100644 index 000000000..94d790e0e --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_for_pass.cpp @@ -0,0 +1,90 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/timed_mutex.hpp> + +// class timed_mutex; + +// template <class Rep, class Period> +// bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); + +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + +#if defined BOOST_THREAD_USES_CHRONO + +boost::timed_mutex m; + +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f1() +{ + t0 = Clock::now(); + BOOST_TEST(m.try_lock_for(ms(750)) == true); + t1 = Clock::now(); + m.unlock(); +} + +void f2() +{ + t0 = Clock::now(); + BOOST_TEST(m.try_lock_for(ms(250)) == false); + t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + BOOST_THREAD_TEST_IT(d, ns(max_diff)); +} + +int main() +{ + { + m.lock(); + boost::thread t(f1); + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); + m.unlock(); + t.join(); + + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); + } + { + m.lock(); + boost::thread t(f2); + boost::this_thread::sleep_for(ms(750)); + m.unlock(); + t.join(); + } + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_pass.cpp new file mode 100644 index 000000000..96e99e7f7 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_pass.cpp @@ -0,0 +1,92 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/timed_mutex.hpp> + +// class timed_mutex; + +// bool try_lock(); + +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + + +boost::timed_mutex m; + +#if defined BOOST_THREAD_USES_CHRONO +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; +#else +#endif + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f() +{ +#if defined BOOST_THREAD_USES_CHRONO + t0 = Clock::now(); + BOOST_TEST(!m.try_lock()); + BOOST_TEST(!m.try_lock()); + BOOST_TEST(!m.try_lock()); + while (!m.try_lock()) + ; + t1 = Clock::now(); + m.unlock(); +#else + //time_point t0 = Clock::now(); + //BOOST_TEST(!m.try_lock()); + //BOOST_TEST(!m.try_lock()); + //BOOST_TEST(!m.try_lock()); + while (!m.try_lock()) + ; + //time_point t1 = Clock::now(); + m.unlock(); + //ns d = t1 - t0 - ms(250); + //BOOST_TEST(d < max_diff); +#endif +} + +int main() +{ + m.lock(); + boost::thread t(f); +#if defined BOOST_THREAD_USES_CHRONO + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); +#else +#endif + m.unlock(); + t.join(); + +#if defined BOOST_THREAD_USES_CHRONO + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); +#endif + + return boost::report_errors(); +} + + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_until_pass.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_until_pass.cpp new file mode 100644 index 000000000..958a42d03 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/timed_mutex/try_lock_until_pass.cpp @@ -0,0 +1,90 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Copyright (C) 2011 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// <boost/thread/timed_mutex.hpp> + +// class timed_mutex; + +// template <class Clock, class Duration> +// bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); + +#include <boost/thread/mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/detail/lightweight_test.hpp> +#include "../../../timming.hpp" + +#if defined BOOST_THREAD_USES_CHRONO + +boost::timed_mutex m; + +typedef boost::chrono::high_resolution_clock Clock; +typedef Clock::time_point time_point; +typedef Clock::duration duration; +typedef boost::chrono::milliseconds ms; +typedef boost::chrono::nanoseconds ns; +time_point t0; +time_point t1; + +const ms max_diff(BOOST_THREAD_TEST_TIME_MS); + +void f1() +{ + t0 = Clock::now(); + BOOST_TEST(m.try_lock_until(Clock::now() + ms(750)) == true); + t1 = Clock::now(); + m.unlock(); +} + +void f2() +{ + t0 = Clock::now(); + BOOST_TEST(m.try_lock_until(Clock::now() + ms(250)) == false); + t1 = Clock::now(); + ns d = t1 - t0 - ms(250); + BOOST_THREAD_TEST_IT(d, ns(max_diff)); +} + +int main() +{ + { + m.lock(); + boost::thread t(f1); + time_point t2 = Clock::now(); + boost::this_thread::sleep_for(ms(250)); + time_point t3 = Clock::now(); + m.unlock(); + t.join(); + + ns sleep_time = t3 - t2; + ns d_ns = t1 - t0 - sleep_time; + ms d_ms = boost::chrono::duration_cast<boost::chrono::milliseconds>(d_ns); + // BOOST_TEST_GE(d_ms.count(), 0); + BOOST_THREAD_TEST_IT(d_ms, max_diff); + BOOST_THREAD_TEST_IT(d_ns, ns(max_diff)); + } + { + m.lock(); + boost::thread t(f2); + boost::this_thread::sleep_for(ms(750)); + m.unlock(); + t.join(); + } + + return boost::report_errors(); +} + +#else +#error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported" +#endif + diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_bind.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_bind.cpp new file mode 100644 index 000000000..9ec0dfdfb --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_bind.cpp @@ -0,0 +1,145 @@ +// (C) Copyright 2013 Ruslan Baratov +// Copyright (C) 2014 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See www.boost.org/libs/thread for documentation. + +#define BOOST_THREAD_VERSION 4 + +#include <boost/detail/lightweight_test.hpp> // BOOST_TEST + +#include <boost/thread/mutex.hpp> +#include <boost/thread/with_lock_guard.hpp> +#include <boost/bind/bind.hpp> + +class Foo { + public: + Foo(int value): value_(value) { + } + + int func(int a, int b) const { + BOOST_TEST(a == 1); + BOOST_TEST(b == 31); + return a + b + value_; + } + + int func_ref(int& a) const { + a = 133; + return 36; + } + + void func_ref(int& a, int& b, int* c) const { + BOOST_TEST(value_ == 3); + a = 567; + b = 897; + *c = 345; + } + + private: + int value_; +}; + +void test_bind() { + boost::mutex m; + + Foo foo(2); + + int res_bind = boost::with_lock_guard( + m, + boost::bind(&Foo::func, foo, 1, 31) + ); + BOOST_TEST(res_bind == 34); + + int a = 0; + int res_bind_ref = boost::with_lock_guard( + m, + boost::bind(&Foo::func_ref, foo, boost::ref(a)) + ); + BOOST_TEST(res_bind_ref == 36); + BOOST_TEST(a == 133); + + a = 0; + int b = 0; + int c = 0; + Foo boo(3); + boost::with_lock_guard( + m, boost::bind(&Foo::func_ref, boo, boost::ref(a), boost::ref(b), &c) + ); + BOOST_TEST(a == 567); + BOOST_TEST(b == 897); + BOOST_TEST(c == 345); +} + +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +void test_bind_non_const() { + std::cout << "c++11 variadic templates disabled" << std::endl; +} +#else + +// calling non-const bind methods supported only with c++11 variadic templates +class Boo { + public: + Boo(int value): value_(value) { + } + + int func(int a, int b) { + BOOST_TEST(a == 7); + BOOST_TEST(b == 3); + return a - b + value_; + } + + int func_ref(int& a) { + a = 598; + return 23; + } + + void func_ref(int& a, int& b, int* c) { + BOOST_TEST(value_ == 67); + a = 111; + b = 222; + *c = 333; + } + + private: + int value_; +}; + +void test_bind_non_const() { + boost::mutex m; + + Boo boo(20); + + int res_bind = boost::with_lock_guard( + m, + boost::bind(&Boo::func, boo, 7, 3) + ); + BOOST_TEST(res_bind == 24); + + int a = 0; + int res_bind_ref = boost::with_lock_guard( + m, + boost::bind(&Boo::func_ref, boo, boost::ref(a)) + ); + BOOST_TEST(res_bind_ref == 23); + BOOST_TEST(a == 598); + + a = 0; + int b = 0; + int c = 0; + Boo foo(67); + boost::with_lock_guard( + m, boost::bind(&Boo::func_ref, foo, boost::ref(a), boost::ref(b), &c) + ); + BOOST_TEST(a == 111); + BOOST_TEST(b == 222); + BOOST_TEST(c == 333); +} +#endif + +int main() { + test_bind(); + test_bind_non_const(); + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_lambda.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_lambda.cpp new file mode 100644 index 000000000..8eda53dea --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_lambda.cpp @@ -0,0 +1,59 @@ +// (C) Copyright 2013 Ruslan Baratov +// Copyright (C) 2014 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See www.boost.org/libs/thread for documentation. + +#include <boost/config.hpp> + +#if !defined(BOOST_NO_CXX11_DECLTYPE) +# define BOOST_RESULT_OF_USE_DECLTYPE +#endif + +#define BOOST_THREAD_VERSION 4 + +#include <boost/detail/lightweight_test.hpp> // BOOST_TEST + +#include <iostream> // std::cout +#include <boost/thread/mutex.hpp> +#include <boost/thread/with_lock_guard.hpp> + +#if defined(BOOST_NO_CXX11_LAMBDAS) || (defined BOOST_MSVC && _MSC_VER < 1700) +void test_lambda() { + std::cout << "C++11 lambda disabled" << std::endl; +} +#else +void test_lambda() { + boost::mutex m; + int res_1 = boost::with_lock_guard( + m, + [](int a) { + BOOST_TEST(a == 13); + return a + 3; + }, + 13 + ); + BOOST_TEST(res_1 == 16); + + int v = 0; + int res_2 = boost::with_lock_guard( + m, + [&v](int a) { + BOOST_TEST(a == 55); + v = 15; + return 45; + }, + 55 + ); + BOOST_TEST(res_2 == 45); + BOOST_TEST(v == 15); +} +#endif + +int main() { + std::cout << std::boolalpha; + test_lambda(); + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_move.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_move.cpp new file mode 100644 index 000000000..2c685790d --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_move.cpp @@ -0,0 +1,110 @@ +// (C) Copyright 2013 Ruslan Baratov +// Copyright (C) 2014 Vicente J. Botet Escriba +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See www.boost.org/libs/thread for documentation. + +#define BOOST_THREAD_VERSION 4 + +#include <boost/detail/lightweight_test.hpp> // BOOST_TEST + +#include <boost/thread/mutex.hpp> +#include <boost/thread/with_lock_guard.hpp> + +class Foo { + public: + explicit Foo(int a) : a_(a) { + } + + Foo(BOOST_RV_REF(Foo) foo) : a_(foo.a_) { + BOOST_ASSERT(&foo != this); + foo.a_ = 0; + } + + Foo& operator=(BOOST_RV_REF(Foo) foo) { + BOOST_ASSERT(&foo != this); + a_ = foo.a_; + foo.a_ = 0; + return *this; + } + + int get() const { + return a_; + } + + private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(Foo) + + int a_; +}; + +template <class T1, class T2> +bool func_with_2_arg(BOOST_FWD_REF(T1) arg_1, BOOST_FWD_REF(T2) arg_2) { + BOOST_TEST(arg_1.get() == 3); + BOOST_TEST(arg_2.get() == 767); + return false; +} + +void test_movable() { + boost::mutex m; + + Foo foo_1(3); + Foo foo_2(767); + + bool res = boost::with_lock_guard( + m, &func_with_2_arg<Foo, Foo>, boost::move(foo_1), boost::move(foo_2) + ); + BOOST_TEST(!res); +} + +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +void test_real_movable() { + std::cout << "c++11 move emulated" << std::endl; +} +#else +// test real one +class Boo { + public: + Boo(int a) : a_(a) { + } + + Boo(Boo&& boo) : a_(boo.a_) { + BOOST_ASSERT(&boo != this); + boo.a_ = 0; + } + + int get() const { + return a_; + } + + BOOST_DELETED_FUNCTION(Boo(Boo&)) + BOOST_DELETED_FUNCTION(Boo& operator=(Boo&)) + BOOST_DELETED_FUNCTION(Boo& operator=(Boo&&)) + private: + int a_; +}; + +void func_with_3_arg(Boo&& boo_1, Boo&& boo_2, Boo&& boo_3) { + BOOST_TEST(boo_1.get() == 11); + BOOST_TEST(boo_2.get() == 12); + BOOST_TEST(boo_3.get() == 13); +} + +void test_real_movable() { + boost::mutex m; + + Boo boo_3(13); + + boost::with_lock_guard( + m, func_with_3_arg, Boo(11), Boo(12), boost::move(boo_3) + ); +} +#endif + +int main() { + test_movable(); + test_real_movable(); + return boost::report_errors(); +} diff --git a/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_simple.cpp b/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_simple.cpp new file mode 100644 index 000000000..dc9c44455 --- /dev/null +++ b/src/boost/libs/thread/test/sync/mutual_exclusion/with_lock_guard/with_lock_guard_simple.cpp @@ -0,0 +1,139 @@ +// (C) Copyright 2013 Ruslan Baratov +// (C) Copyright 2013 Ruslan Baratov +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See www.boost.org/libs/thread for documentation. + +#define BOOST_THREAD_VERSION 4 + +#include <boost/detail/lightweight_test.hpp> // BOOST_TEST + +#include <boost/thread/mutex.hpp> +#include <boost/thread/with_lock_guard.hpp> +#include <boost/ref.hpp> + +void func_with_0_arg() { +} + +void func_with_1_arg(int arg_1) { + BOOST_TEST(arg_1 == 3); +} + +bool func_with_2_arg(int arg_1, bool arg_2) { + BOOST_TEST(arg_1 == 3); + BOOST_TEST(arg_2 == true); + return !arg_2; +} + +int func_with_3_arg(int arg_1, bool arg_2, const char* arg_3) { + BOOST_TEST(arg_1 == 13); + BOOST_TEST(arg_2 == false); + BOOST_TEST(std::string(arg_3) == "message for func with 3 arg"); + return 12; +} + +const char* func_with_4_arg(int arg_1, bool arg_2, int* arg_3, int& arg_4) { + BOOST_TEST(arg_1 == 23); + BOOST_TEST(arg_2 == false); + *arg_3 = 128; + arg_4 = 456; + return "hello"; +} + +void test_simple() { + boost::mutex m; + + // #0 + boost::with_lock_guard(m, func_with_0_arg); + + // #1 + boost::with_lock_guard(m, func_with_1_arg, 3); + + // #2 + bool res2 = boost::with_lock_guard(m, func_with_2_arg, 3, true); + BOOST_TEST(res2 == false); + + // #3 + int arg1 = 13; + const char* mes = "message for func with 3 arg"; + int res3 = boost::with_lock_guard(m, func_with_3_arg, arg1, false, mes); + BOOST_TEST(res3 == 12); + + // #4 + int arg3 = 0; + int arg4 = 0; + const char* res4 = boost::with_lock_guard( + m, + func_with_4_arg, + 23, + false, + &arg3, + boost::ref(arg4) + ); + BOOST_TEST(arg3 == 128); + BOOST_TEST(arg4 == 456); + BOOST_TEST(std::string(res4) == "hello"); +} + +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +void test_variadic_templates() { + std::cout << "C++11 variadic templates disabled" << std::endl; +} +#else +int func_with_5_args(int a1, char a2, int& a3, bool* a4, bool a5) { + BOOST_TEST(a1 == 12); + BOOST_TEST(a2 == 'x'); + BOOST_TEST(a5 == false); + a3 = 135; + *a4 = false; + return 45; +} + +int func_with_6_args(int a1, char a2, int& a3, bool* a4, int&& a5, bool a6) { + BOOST_TEST(a1 == 12); + BOOST_TEST(a2 == 'N'); + BOOST_TEST(a5 == 2 || a5 == 13); + BOOST_TEST(a6 == false); + a3 = 200; + *a4 = true; + return 888; +} + +void test_variadic_templates() { + boost::mutex m; + + int a3 = 0; + bool a4 = true; + int res5 = boost::with_lock_guard( + m, func_with_5_args, 12, 'x', a3, &a4, false + ); + BOOST_TEST(a3 == 135); + BOOST_TEST(a4 == false); + BOOST_TEST(res5 == 45); + + int res6 = boost::with_lock_guard( + m, func_with_6_args, 12, 'N', a3, &a4, 2, false + ); + BOOST_TEST(a3 == 200); + BOOST_TEST(a4 == true); + BOOST_TEST(res6 == 888); + + a3 = 0; + a4 = false; + int a5 = 13; + int res6_move = boost::with_lock_guard( + m, func_with_6_args, 12, 'N', a3, &a4, boost::move(a5), false + ); + BOOST_TEST(a3 == 200); + BOOST_TEST(a4 == true); + BOOST_TEST_EQ(res6_move, 888); +} +#endif + +int main() { + test_simple(); + test_variadic_templates(); + return boost::report_errors(); +} |