Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : // include files
21 :
22 : #include <sal/types.h>
23 :
24 : #include <osl/thread.hxx>
25 : #include <osl/time.h>
26 :
27 : #include <rtl/instance.hxx>
28 : #include <rtl/ustring.hxx>
29 :
30 : #include <cppunit/TestFixture.h>
31 : #include <cppunit/extensions/HelperMacros.h>
32 : #include <cppunit/plugin/TestPlugIn.h>
33 :
34 : #ifdef WNT
35 : #include <windows.h>
36 : #else
37 : #include <unistd.h>
38 : #include <time.h>
39 : #endif
40 :
41 : #define CONST_TEST_STRING "gregorian"
42 :
43 : namespace {
44 : struct Gregorian : public rtl::StaticWithInit<rtl::OUString, Gregorian> {
45 1 : const rtl::OUString operator () () {
46 1 : return rtl::OUString( CONST_TEST_STRING );
47 : }
48 : };
49 : }
50 :
51 : namespace ThreadHelper
52 : {
53 : // typedef enum {
54 : // QUIET=1,
55 : // VERBOSE
56 : // } eSleepVerboseMode;
57 :
58 11 : void thread_sleep_tenth_sec(sal_Int32 _nTenthSec/*, eSleepVerboseMode nVerbose = VERBOSE*/)
59 : {
60 : // if (nVerbose == VERBOSE)
61 : // {
62 : // printf("wait %d tenth seconds. ", _nTenthSec );
63 : // fflush(stdout);
64 : // }
65 : #ifdef WNT //Windows
66 : Sleep(_nTenthSec * 100 );
67 : #endif
68 : #if ( defined UNX )
69 : TimeValue nTV;
70 11 : nTV.Seconds = static_cast<sal_uInt32>( _nTenthSec/10 );
71 11 : nTV.Nanosec = ( (_nTenthSec%10 ) * 100000000 );
72 11 : osl_waitThread(&nTV);
73 : #endif
74 : // if (nVerbose == VERBOSE)
75 : // {
76 : // printf("done\n");
77 : // }
78 11 : }
79 : }
80 :
81 : /** Simple thread for testing Thread-create.
82 : * Just add 1 of value 0, and after running, result is 1.
83 : */
84 : class OGetThread : public osl::Thread
85 : {
86 : sal_Int32 m_nOK;
87 : sal_Int32 m_nFails;
88 :
89 : rtl::OUString m_sConstStr;
90 : public:
91 2 : OGetThread()
92 : :m_nOK(0),
93 2 : m_nFails(0)
94 : {
95 2 : m_sConstStr = CONST_TEST_STRING;
96 2 : }
97 :
98 2 : sal_Int32 getOK() { return m_nOK; }
99 2 : sal_Int32 getFails() {return m_nFails;}
100 :
101 : protected:
102 :
103 : /** guarded value which initialized 0
104 :
105 : @see ThreadSafeValue
106 : */
107 2 : void SAL_CALL run() SAL_OVERRIDE
108 : {
109 14 : while(schedule())
110 : {
111 10 : rtl::OUString aStr = Gregorian::get();
112 10 : if (aStr.equals(m_sConstStr))
113 : {
114 10 : m_nOK++;
115 : }
116 : else
117 : {
118 0 : m_nFails++;
119 : }
120 10 : ThreadHelper::thread_sleep_tenth_sec(1);
121 10 : }
122 2 : }
123 :
124 : public:
125 :
126 0 : virtual void SAL_CALL suspend() SAL_OVERRIDE
127 : {
128 0 : ::osl::Thread::suspend();
129 0 : }
130 :
131 4 : virtual ~OGetThread()
132 4 : {
133 2 : if (isRunning())
134 : {
135 0 : printf("error: not terminated.\n");
136 : }
137 4 : }
138 : };
139 :
140 : namespace rtl_DoubleLocking
141 : {
142 :
143 : /** Test of the osl::Thread::create method
144 : */
145 :
146 6 : class getValue : public CppUnit::TestFixture
147 : {
148 : public:
149 :
150 : // initialise your test code values here.
151 2 : void setUp() SAL_OVERRIDE
152 : {
153 2 : }
154 :
155 2 : void tearDown() SAL_OVERRIDE
156 : {
157 2 : }
158 :
159 1 : void getValue_001()
160 : {
161 1 : rtl::OUString aStr = Gregorian::get();
162 :
163 2 : CPPUNIT_ASSERT_MESSAGE(
164 : "Gregorian::get() failed, wrong value expected.",
165 : !aStr.isEmpty()
166 2 : );
167 1 : }
168 :
169 : /** check 2 threads.
170 :
171 : ALGORITHM:
172 : Here the function should show, that 2 different threads,
173 : which only increase a value, should run at the same time with same prio.
174 : The test fails, if the difference between the two values is more than 5%
175 : but IMHO this isn't a failure, it's only a feature of the OS.
176 : */
177 :
178 1 : void getValue_002()
179 : {
180 : // initial 5 threads with different priorities
181 1 : OGetThread* pThread = new OGetThread();
182 1 : OGetThread* p2Thread = new OGetThread();
183 :
184 : //Create them and start running at the same time
185 1 : pThread->create();
186 1 : p2Thread->create();
187 :
188 1 : ThreadHelper::thread_sleep_tenth_sec(5);
189 :
190 1 : pThread->terminate();
191 1 : p2Thread->terminate();
192 :
193 1 : pThread->join();
194 1 : p2Thread->join();
195 :
196 1 : sal_Int32 nValueOK = 0;
197 1 : nValueOK = pThread->getOK();
198 :
199 1 : sal_Int32 nValueOK2 = 0;
200 1 : nValueOK2 = p2Thread->getOK();
201 :
202 : #if OSL_DEBUG_LEVEL > 2
203 : printf("Value in Thread #1 is %" SAL_PRIdINT32 "\n", nValueOK);
204 : printf("Value in Thread #2 is %" SAL_PRIdINT32 "\n", nValueOK2);
205 : #else
206 : (void)nValueOK2;
207 : #endif
208 :
209 1 : sal_Int32 nValueFails = 0;
210 1 : nValueFails = pThread->getFails();
211 :
212 1 : sal_Int32 nValueFails2 = 0;
213 1 : nValueFails2 = p2Thread->getFails();
214 :
215 : #if OSL_DEBUG_LEVEL > 2
216 : printf("Fails in Thread #1 is %" SAL_PRIdINT32 "\n", nValueFails);
217 : printf("Fails in Thread #2 is %" SAL_PRIdINT32 "\n", nValueFails2);
218 : #endif
219 :
220 1 : delete pThread;
221 1 : delete p2Thread;
222 :
223 2 : CPPUNIT_ASSERT_MESSAGE(
224 : "getValue() failed, wrong value expected.",
225 : nValueOK != 0 && nValueFails == 0 && nValueFails2 == 0
226 1 : );
227 1 : }
228 :
229 2 : CPPUNIT_TEST_SUITE(getValue);
230 1 : CPPUNIT_TEST(getValue_001);
231 1 : CPPUNIT_TEST(getValue_002);
232 5 : CPPUNIT_TEST_SUITE_END();
233 : }; // class create
234 :
235 1 : CPPUNIT_TEST_SUITE_REGISTRATION(rtl_DoubleLocking::getValue);
236 : } // namespace rtl_DoubleLocking
237 :
238 : // this macro creates an empty function, which will called by the RegisterAllFunctions()
239 : // to let the user the possibility to also register some functions by hand.
240 4 : CPPUNIT_PLUGIN_IMPLEMENT();
241 :
242 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|