// Copyright (C) 2001-2003 // William E. Kempf // // Distributed under the 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 #include #include #include #include #include #include #if defined(BOOST_HAS_WINTHREADS) #define WIN32_LEAN_AND_MEAN #include #endif boost::mutex check_mutex; boost::mutex tss_mutex; int tss_instances = 0; int tss_total = 0; struct tss_value_t { tss_value_t() { boost::mutex::scoped_lock lock(tss_mutex); ++tss_instances; ++tss_total; value = 0; } ~tss_value_t() { boost::mutex::scoped_lock lock(tss_mutex); --tss_instances; } int value; }; boost::thread_specific_ptr tss_value; void test_tss_thread() { tss_value.reset(new tss_value_t()); for (int i=0; i<1000; ++i) { int& n = tss_value->value; // Don't call BOOST_CHECK_EQUAL directly, as it doesn't appear to // be thread safe. Must evaluate further. if (n != i) { boost::mutex::scoped_lock lock(check_mutex); BOOST_CHECK_EQUAL(n, i); } ++n; } } #if defined(BOOST_HAS_WINTHREADS) typedef HANDLE native_thread_t; DWORD WINAPI test_tss_thread_native(LPVOID lpParameter) { test_tss_thread(); return 0; } native_thread_t create_native_thread(void) { return CreateThread( 0, //security attributes (0 = not inheritable) 0, //stack size (0 = default) &test_tss_thread_native, //function to execute 0, //parameter to pass to function 0, //creation flags (0 = run immediately) 0 //thread id (0 = thread id not returned) ); } void join_native_thread(native_thread_t thread) { DWORD res = WaitForSingleObject(thread, INFINITE); BOOST_CHECK(res == WAIT_OBJECT_0); res = CloseHandle(thread); BOOST_CHECK(SUCCEEDED(res)); } #endif void do_test_tss() { tss_instances = 0; tss_total = 0; const int NUMTHREADS=5; boost::thread_group threads; for (int i=0; iadd(BOOST_TEST_CASE(test_tss)); return test; }