1*87d2adbcSAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3*87d2adbcSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*87d2adbcSAndrew Rist * or more contributor license agreements. See the NOTICE file
5*87d2adbcSAndrew Rist * distributed with this work for additional information
6*87d2adbcSAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*87d2adbcSAndrew Rist * to you under the Apache License, Version 2.0 (the
8*87d2adbcSAndrew Rist * "License"); you may not use this file except in compliance
9*87d2adbcSAndrew Rist * with the License. You may obtain a copy of the License at
10cdf0e10cSrcweir *
11*87d2adbcSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
13*87d2adbcSAndrew Rist * Unless required by applicable law or agreed to in writing,
14*87d2adbcSAndrew Rist * software distributed under the License is distributed on an
15*87d2adbcSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*87d2adbcSAndrew Rist * KIND, either express or implied. See the License for the
17*87d2adbcSAndrew Rist * specific language governing permissions and limitations
18*87d2adbcSAndrew Rist * under the License.
19cdf0e10cSrcweir *
20*87d2adbcSAndrew Rist *************************************************************/
21*87d2adbcSAndrew Rist
22*87d2adbcSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sal.hxx"
26cdf0e10cSrcweir //------------------------------------------------------------------------
27cdf0e10cSrcweir // include files
28cdf0e10cSrcweir //------------------------------------------------------------------------
29cdf0e10cSrcweir #include <sal/types.h>
30cdf0e10cSrcweir
31cdf0e10cSrcweir #ifndef _RTL_USTRING_HXX_
32cdf0e10cSrcweir #include <rtl/string.hxx>
33cdf0e10cSrcweir #endif
34cdf0e10cSrcweir
35cdf0e10cSrcweir #ifndef _OSL_THREAD_HXX
36cdf0e10cSrcweir #include <osl/thread.hxx>
37cdf0e10cSrcweir #endif
38cdf0e10cSrcweir #include <osl/time.h>
39cdf0e10cSrcweir
40cdf0e10cSrcweir #include <rtl/instance.hxx>
41cdf0e10cSrcweir
42cdf0e10cSrcweir #include <testshl/simpleheader.hxx>
43cdf0e10cSrcweir
44cdf0e10cSrcweir // -----------------------------------------------------------------------------
45cdf0e10cSrcweir #define CONST_TEST_STRING "gregorian"
46cdf0e10cSrcweir
47cdf0e10cSrcweir namespace {
48cdf0e10cSrcweir struct Gregorian : public rtl::StaticWithInit<const ::rtl::OUString, Gregorian> {
operator ()__anon9e235ff60111::Gregorian49cdf0e10cSrcweir const ::rtl::OUString operator () () {
50cdf0e10cSrcweir return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CONST_TEST_STRING ));
51cdf0e10cSrcweir }
52cdf0e10cSrcweir };
53cdf0e10cSrcweir }
54cdf0e10cSrcweir
printOUString(::rtl::OUString const & _suStr)55cdf0e10cSrcweir inline void printOUString( ::rtl::OUString const & _suStr )
56cdf0e10cSrcweir {
57cdf0e10cSrcweir rtl::OString aString;
58cdf0e10cSrcweir
59cdf0e10cSrcweir t_print( "OUString: " );
60cdf0e10cSrcweir aString = ::rtl::OUStringToOString( _suStr, RTL_TEXTENCODING_ASCII_US );
61cdf0e10cSrcweir t_print( "'%s'\n", aString.getStr( ) );
62cdf0e10cSrcweir }
63cdf0e10cSrcweir
64cdf0e10cSrcweir // -----------------------------------------------------------------------------
65cdf0e10cSrcweir namespace ThreadHelper
66cdf0e10cSrcweir {
67cdf0e10cSrcweir // typedef enum {
68cdf0e10cSrcweir // QUIET=1,
69cdf0e10cSrcweir // VERBOSE
70cdf0e10cSrcweir // } eSleepVerboseMode;
71cdf0e10cSrcweir
thread_sleep_tenth_sec(sal_Int32 _nTenthSec)72cdf0e10cSrcweir void thread_sleep_tenth_sec(sal_Int32 _nTenthSec/*, eSleepVerboseMode nVerbose = VERBOSE*/)
73cdf0e10cSrcweir {
74cdf0e10cSrcweir // if (nVerbose == VERBOSE)
75cdf0e10cSrcweir // {
76cdf0e10cSrcweir // t_print("wait %d tenth seconds. ", _nTenthSec );
77cdf0e10cSrcweir // fflush(stdout);
78cdf0e10cSrcweir // }
79cdf0e10cSrcweir #ifdef WNT //Windows
80cdf0e10cSrcweir Sleep(_nTenthSec * 100 );
81cdf0e10cSrcweir #endif
82cdf0e10cSrcweir #if ( defined UNX ) || ( defined OS2 ) //Unix
83cdf0e10cSrcweir TimeValue nTV;
84cdf0e10cSrcweir nTV.Seconds = static_cast<sal_uInt32>( _nTenthSec/10 );
85cdf0e10cSrcweir nTV.Nanosec = ( (_nTenthSec%10 ) * 100000000 );
86cdf0e10cSrcweir osl_waitThread(&nTV);
87cdf0e10cSrcweir #endif
88cdf0e10cSrcweir // if (nVerbose == VERBOSE)
89cdf0e10cSrcweir // {
90cdf0e10cSrcweir // t_print("done\n");
91cdf0e10cSrcweir // }
92cdf0e10cSrcweir }
93cdf0e10cSrcweir }
94cdf0e10cSrcweir
95cdf0e10cSrcweir // -----------------------------------------------------------------------------
96cdf0e10cSrcweir
97cdf0e10cSrcweir /** Simple thread for testing Thread-create.
98cdf0e10cSrcweir * Just add 1 of value 0, and after running, result is 1.
99cdf0e10cSrcweir */
100cdf0e10cSrcweir class OGetThread : public osl::Thread
101cdf0e10cSrcweir {
102cdf0e10cSrcweir sal_Int32 m_nOK;
103cdf0e10cSrcweir sal_Int32 m_nFails;
104cdf0e10cSrcweir
105cdf0e10cSrcweir rtl::OUString m_sConstStr;
106cdf0e10cSrcweir public:
OGetThread()107cdf0e10cSrcweir OGetThread()
108cdf0e10cSrcweir :m_nOK(0),
109cdf0e10cSrcweir m_nFails(0)
110cdf0e10cSrcweir {
111cdf0e10cSrcweir m_sConstStr = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CONST_TEST_STRING ));
112cdf0e10cSrcweir }
113cdf0e10cSrcweir
getOK()114cdf0e10cSrcweir sal_Int32 getOK() { return m_nOK; }
getFails()115cdf0e10cSrcweir sal_Int32 getFails() {return m_nFails;}
116cdf0e10cSrcweir
117cdf0e10cSrcweir protected:
118cdf0e10cSrcweir
119cdf0e10cSrcweir /** guarded value which initialized 0
120cdf0e10cSrcweir
121cdf0e10cSrcweir @see ThreadSafeValue
122cdf0e10cSrcweir */
run()123cdf0e10cSrcweir void SAL_CALL run()
124cdf0e10cSrcweir {
125cdf0e10cSrcweir while(schedule())
126cdf0e10cSrcweir {
127cdf0e10cSrcweir rtl::OUString aStr = Gregorian::get();
128cdf0e10cSrcweir // printOUString(aStr);
129cdf0e10cSrcweir // printOUString(m_sConstStr);
130cdf0e10cSrcweir if (aStr.equals(m_sConstStr))
131cdf0e10cSrcweir {
132cdf0e10cSrcweir m_nOK++;
133cdf0e10cSrcweir }
134cdf0e10cSrcweir else
135cdf0e10cSrcweir {
136cdf0e10cSrcweir m_nFails++;
137cdf0e10cSrcweir }
138cdf0e10cSrcweir ThreadHelper::thread_sleep_tenth_sec(1);
139cdf0e10cSrcweir }
140cdf0e10cSrcweir }
141cdf0e10cSrcweir
142cdf0e10cSrcweir public:
143cdf0e10cSrcweir
suspend()144cdf0e10cSrcweir virtual void SAL_CALL suspend()
145cdf0e10cSrcweir {
146cdf0e10cSrcweir ::osl::Thread::suspend();
147cdf0e10cSrcweir }
148cdf0e10cSrcweir
~OGetThread()149cdf0e10cSrcweir ~OGetThread()
150cdf0e10cSrcweir {
151cdf0e10cSrcweir if (isRunning())
152cdf0e10cSrcweir {
153cdf0e10cSrcweir t_print("error: not terminated.\n");
154cdf0e10cSrcweir }
155cdf0e10cSrcweir }
156cdf0e10cSrcweir };
157cdf0e10cSrcweir
158cdf0e10cSrcweir // -----------------------------------------------------------------------------
159cdf0e10cSrcweir namespace rtl_DoubleLocking
160cdf0e10cSrcweir {
161cdf0e10cSrcweir
162cdf0e10cSrcweir /** Test of the osl::Thread::create method
163cdf0e10cSrcweir */
164cdf0e10cSrcweir
165cdf0e10cSrcweir class getValue : public CppUnit::TestFixture
166cdf0e10cSrcweir {
167cdf0e10cSrcweir public:
168cdf0e10cSrcweir
169cdf0e10cSrcweir // initialise your test code values here.
setUp()170cdf0e10cSrcweir void setUp()
171cdf0e10cSrcweir {
172cdf0e10cSrcweir }
173cdf0e10cSrcweir
tearDown()174cdf0e10cSrcweir void tearDown()
175cdf0e10cSrcweir {
176cdf0e10cSrcweir }
177cdf0e10cSrcweir
178cdf0e10cSrcweir
getValue_001()179cdf0e10cSrcweir void getValue_001()
180cdf0e10cSrcweir {
181cdf0e10cSrcweir rtl::OUString aStr = Gregorian::get();
182cdf0e10cSrcweir printOUString(aStr);
183cdf0e10cSrcweir
184cdf0e10cSrcweir CPPUNIT_ASSERT_MESSAGE(
185cdf0e10cSrcweir "Gregorian::get() failed, wrong value expected.",
186cdf0e10cSrcweir aStr.getLength() != 0
187cdf0e10cSrcweir );
188cdf0e10cSrcweir }
189cdf0e10cSrcweir
190cdf0e10cSrcweir /** check 2 threads.
191cdf0e10cSrcweir
192cdf0e10cSrcweir ALGORITHM:
193cdf0e10cSrcweir Here the function should show, that 2 different threads,
194cdf0e10cSrcweir which only increase a value, should run at the same time with same prio.
195cdf0e10cSrcweir The test fails, if the difference between the two values is more than 5%
196cdf0e10cSrcweir but IMHO this isn't a failure, it's only a feature of the OS.
197cdf0e10cSrcweir */
198cdf0e10cSrcweir
getValue_002()199cdf0e10cSrcweir void getValue_002()
200cdf0e10cSrcweir {
201cdf0e10cSrcweir // initial 5 threads with different priorities
202cdf0e10cSrcweir OGetThread* pThread = new OGetThread();
203cdf0e10cSrcweir OGetThread* p2Thread = new OGetThread();
204cdf0e10cSrcweir
205cdf0e10cSrcweir //Create them and start running at the same time
206cdf0e10cSrcweir pThread->create();
207cdf0e10cSrcweir p2Thread->create();
208cdf0e10cSrcweir
209cdf0e10cSrcweir ThreadHelper::thread_sleep_tenth_sec(50);
210cdf0e10cSrcweir
211cdf0e10cSrcweir pThread->terminate();
212cdf0e10cSrcweir p2Thread->terminate();
213cdf0e10cSrcweir
214cdf0e10cSrcweir sal_Int32 nValueOK = 0;
215cdf0e10cSrcweir nValueOK = pThread->getOK();
216cdf0e10cSrcweir
217cdf0e10cSrcweir sal_Int32 nValueOK2 = 0;
218cdf0e10cSrcweir nValueOK2 = p2Thread->getOK();
219cdf0e10cSrcweir
220cdf0e10cSrcweir t_print("Value in Thread #1 is %d\n", nValueOK);
221cdf0e10cSrcweir t_print("Value in Thread #2 is %d\n", nValueOK2);
222cdf0e10cSrcweir
223cdf0e10cSrcweir sal_Int32 nValueFails = 0;
224cdf0e10cSrcweir nValueFails = pThread->getFails();
225cdf0e10cSrcweir
226cdf0e10cSrcweir sal_Int32 nValueFails2 = 0;
227cdf0e10cSrcweir nValueFails2 = p2Thread->getFails();
228cdf0e10cSrcweir
229cdf0e10cSrcweir t_print("Fails in Thread #1 is %d\n", nValueFails);
230cdf0e10cSrcweir t_print("Fails in Thread #2 is %d\n", nValueFails2);
231cdf0e10cSrcweir
232cdf0e10cSrcweir // ThreadHelper::thread_sleep_tenth_sec(1);
233cdf0e10cSrcweir pThread->join();
234cdf0e10cSrcweir p2Thread->join();
235cdf0e10cSrcweir
236cdf0e10cSrcweir delete pThread;
237cdf0e10cSrcweir delete p2Thread;
238cdf0e10cSrcweir
239cdf0e10cSrcweir CPPUNIT_ASSERT_MESSAGE(
240cdf0e10cSrcweir "getValue() failed, wrong value expected.",
241cdf0e10cSrcweir nValueOK != 0 && nValueFails == 0 && nValueFails2 == 0
242cdf0e10cSrcweir );
243cdf0e10cSrcweir }
244cdf0e10cSrcweir
245cdf0e10cSrcweir CPPUNIT_TEST_SUITE(getValue);
246cdf0e10cSrcweir CPPUNIT_TEST(getValue_001);
247cdf0e10cSrcweir CPPUNIT_TEST(getValue_002);
248cdf0e10cSrcweir CPPUNIT_TEST_SUITE_END();
249cdf0e10cSrcweir }; // class create
250cdf0e10cSrcweir // -----------------------------------------------------------------------------
251cdf0e10cSrcweir CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_DoubleLocking::getValue, "rtl_DoubleLocking");
252cdf0e10cSrcweir } // namespace rtl_DoubleLocking
253cdf0e10cSrcweir
254cdf0e10cSrcweir // this macro creates an empty function, which will called by the RegisterAllFunctions()
255cdf0e10cSrcweir // to let the user the possibility to also register some functions by hand.
256cdf0e10cSrcweir NOADDITIONAL;
257