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
10*87d2adbcSAndrew Rist  *
11*87d2adbcSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*87d2adbcSAndrew Rist  *
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.
19*87d2adbcSAndrew Rist  *
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> {
49cdf0e10cSrcweir     const ::rtl::OUString operator () () {
50cdf0e10cSrcweir         return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CONST_TEST_STRING ));
51cdf0e10cSrcweir     }
52cdf0e10cSrcweir };
53cdf0e10cSrcweir }
54cdf0e10cSrcweir 
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 
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:
107cdf0e10cSrcweir     OGetThread()
108cdf0e10cSrcweir             :m_nOK(0),
109cdf0e10cSrcweir              m_nFails(0)
110cdf0e10cSrcweir         {
111cdf0e10cSrcweir             m_sConstStr = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CONST_TEST_STRING ));
112cdf0e10cSrcweir         }
113cdf0e10cSrcweir 
114cdf0e10cSrcweir     sal_Int32 getOK() { return m_nOK; }
115cdf0e10cSrcweir     sal_Int32 getFails() {return m_nFails;}
116cdf0e10cSrcweir 
117cdf0e10cSrcweir protected:
118cdf0e10cSrcweir 
119cdf0e10cSrcweir     /** guarded value which initialized 0
120cdf0e10cSrcweir 
121cdf0e10cSrcweir         @see ThreadSafeValue
122cdf0e10cSrcweir     */
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 
144cdf0e10cSrcweir     virtual void SAL_CALL suspend()
145cdf0e10cSrcweir         {
146cdf0e10cSrcweir             ::osl::Thread::suspend();
147cdf0e10cSrcweir         }
148cdf0e10cSrcweir 
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.
170cdf0e10cSrcweir         void setUp()
171cdf0e10cSrcweir             {
172cdf0e10cSrcweir             }
173cdf0e10cSrcweir 
174cdf0e10cSrcweir         void tearDown()
175cdf0e10cSrcweir             {
176cdf0e10cSrcweir             }
177cdf0e10cSrcweir 
178cdf0e10cSrcweir 
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 
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