Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/thread/test/test_tss.cpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 4.3 KB
Line 
1// Copyright (C) 2001-2003
2// William E. Kempf
3//
4//  Distributed under the Boost Software License, Version 1.0. (See accompanying
5//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7#include <boost/thread/detail/config.hpp>
8
9#include <boost/thread/tss.hpp>
10#include <boost/thread/mutex.hpp>
11#include <boost/thread/thread.hpp>
12
13#include <boost/test/unit_test.hpp>
14
15#include <libs/thread/test/util.inl>
16
17#include <iostream>
18
19#if defined(BOOST_HAS_WINTHREADS)
20    #define WIN32_LEAN_AND_MEAN
21    #include <windows.h>    
22#endif
23
24boost::mutex check_mutex;
25boost::mutex tss_mutex;
26int tss_instances = 0;
27int tss_total = 0;
28
29struct tss_value_t
30{
31    tss_value_t()
32    {
33        boost::mutex::scoped_lock lock(tss_mutex);
34        ++tss_instances;
35        ++tss_total;
36        value = 0;
37    }
38    ~tss_value_t()
39    {
40        boost::mutex::scoped_lock lock(tss_mutex);
41        --tss_instances;
42    }
43    int value;
44};
45
46boost::thread_specific_ptr<tss_value_t> tss_value;
47
48void test_tss_thread()
49{
50    tss_value.reset(new tss_value_t());
51    for (int i=0; i<1000; ++i)
52    {
53        int& n = tss_value->value;
54        // Don't call BOOST_CHECK_EQUAL directly, as it doesn't appear to
55        // be thread safe. Must evaluate further.
56        if (n != i)
57        {
58            boost::mutex::scoped_lock lock(check_mutex);
59            BOOST_CHECK_EQUAL(n, i);
60        }
61        ++n;
62    }
63}
64
65#if defined(BOOST_HAS_WINTHREADS)
66    typedef HANDLE native_thread_t;
67
68    DWORD WINAPI test_tss_thread_native(LPVOID lpParameter)
69    {
70        test_tss_thread();
71        return 0;
72    }
73
74    native_thread_t create_native_thread(void)
75    {
76        return CreateThread(
77            0, //security attributes (0 = not inheritable)
78            0, //stack size (0 = default)
79            &test_tss_thread_native, //function to execute
80            0, //parameter to pass to function
81            0, //creation flags (0 = run immediately)
82            0  //thread id (0 = thread id not returned)
83            );
84    }
85
86    void join_native_thread(native_thread_t thread)
87    {
88        DWORD res = WaitForSingleObject(thread, INFINITE);
89        BOOST_CHECK(res == WAIT_OBJECT_0);
90
91        res = CloseHandle(thread);
92        BOOST_CHECK(SUCCEEDED(res));
93    }
94#endif
95
96void do_test_tss()
97{
98    tss_instances = 0;
99    tss_total = 0;
100
101    const int NUMTHREADS=5;
102    boost::thread_group threads;
103    for (int i=0; i<NUMTHREADS; ++i)
104        threads.create_thread(&test_tss_thread);
105    threads.join_all();
106
107    std::cout
108        << "tss_instances = " << tss_instances
109        << "; tss_total = " << tss_total
110        << "\n";
111    std::cout.flush();
112
113    BOOST_CHECK_EQUAL(tss_instances, 0);
114    BOOST_CHECK_EQUAL(tss_total, 5);
115
116    #if defined(BOOST_HAS_WINTHREADS)
117        tss_instances = 0;
118        tss_total = 0;
119
120        native_thread_t thread1 = create_native_thread();
121        BOOST_CHECK(thread1 != 0);
122
123        native_thread_t thread2 = create_native_thread();
124        BOOST_CHECK(thread2 != 0);
125
126        native_thread_t thread3 = create_native_thread();
127        BOOST_CHECK(thread3 != 0);
128
129        native_thread_t thread4 = create_native_thread();
130        BOOST_CHECK(thread3 != 0);
131
132        native_thread_t thread5 = create_native_thread();
133        BOOST_CHECK(thread3 != 0);
134
135        join_native_thread(thread5);
136        join_native_thread(thread4);
137        join_native_thread(thread3);
138        join_native_thread(thread2);
139        join_native_thread(thread1);
140
141        std::cout
142            << "tss_instances = " << tss_instances
143            << "; tss_total = " << tss_total
144            << "\n";
145        std::cout.flush();
146
147        // The following is not really an error. TSS cleanup support still is available for boost threads.
148        // Also this usually will be triggered only when bound to the static version of thread lib.
149        // 2006-10-02 Roland Schwarz
150        //BOOST_CHECK_EQUAL(tss_instances, 0);
151        BOOST_CHECK_MESSAGE(tss_instances == 0, "Support of automatic tss cleanup for native threading API not available");
152        BOOST_CHECK_EQUAL(tss_total, 5);
153    #endif
154}
155
156void test_tss()
157{
158    timed_test(&do_test_tss, 2);
159}
160
161boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
162{
163    boost::unit_test_framework::test_suite* test =
164        BOOST_TEST_SUITE("Boost.Threads: tss test suite");
165
166    test->add(BOOST_TEST_CASE(test_tss));
167
168    return test;
169}
Note: See TracBrowser for help on using the repository browser.