187d2adbcSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
387d2adbcSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
487d2adbcSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
587d2adbcSAndrew Rist  * distributed with this work for additional information
687d2adbcSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
787d2adbcSAndrew Rist  * to you under the Apache License, Version 2.0 (the
887d2adbcSAndrew Rist  * "License"); you may not use this file except in compliance
987d2adbcSAndrew Rist  * with the License.  You may obtain a copy of the License at
1087d2adbcSAndrew Rist  *
1187d2adbcSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
1287d2adbcSAndrew Rist  *
1387d2adbcSAndrew Rist  * Unless required by applicable law or agreed to in writing,
1487d2adbcSAndrew Rist  * software distributed under the License is distributed on an
1587d2adbcSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1687d2adbcSAndrew Rist  * KIND, either express or implied.  See the License for the
1787d2adbcSAndrew Rist  * specific language governing permissions and limitations
1887d2adbcSAndrew Rist  * under the License.
1987d2adbcSAndrew Rist  *
2087d2adbcSAndrew Rist  *************************************************************/
2187d2adbcSAndrew Rist 
2287d2adbcSAndrew 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 
3129922ad4SDamjan Jovanovic #include <rtl/ustring.h>
3229922ad4SDamjan Jovanovic #include <rtl/ustring.hxx>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir #ifndef _OSL_THREAD_HXX
35cdf0e10cSrcweir #include <osl/thread.hxx>
36cdf0e10cSrcweir #endif
37cdf0e10cSrcweir #include <osl/time.h>
38cdf0e10cSrcweir 
39cdf0e10cSrcweir #include <rtl/instance.hxx>
40cdf0e10cSrcweir 
4129922ad4SDamjan Jovanovic #include "gtest/gtest.h"
42cdf0e10cSrcweir 
43*a03c9fa9SDamjan Jovanovic #ifdef WNT
44*a03c9fa9SDamjan Jovanovic #define WIN32_LEAN_AND_MEAN
45*a03c9fa9SDamjan Jovanovic #include <tools/prewin.h>
46*a03c9fa9SDamjan Jovanovic #include <windows.h>
47*a03c9fa9SDamjan Jovanovic #include <tools/postwin.h>
48*a03c9fa9SDamjan Jovanovic #endif
49*a03c9fa9SDamjan Jovanovic 
50cdf0e10cSrcweir // -----------------------------------------------------------------------------
51cdf0e10cSrcweir #define CONST_TEST_STRING "gregorian"
52cdf0e10cSrcweir 
53cdf0e10cSrcweir namespace {
54cdf0e10cSrcweir struct Gregorian : public rtl::StaticWithInit<const ::rtl::OUString, Gregorian> {
55cdf0e10cSrcweir     const ::rtl::OUString operator () () {
56cdf0e10cSrcweir         return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CONST_TEST_STRING ));
57cdf0e10cSrcweir     }
58cdf0e10cSrcweir };
59cdf0e10cSrcweir }
60cdf0e10cSrcweir 
61cdf0e10cSrcweir inline void printOUString( ::rtl::OUString const & _suStr )
62cdf0e10cSrcweir {
63cdf0e10cSrcweir     rtl::OString aString;
64cdf0e10cSrcweir 
6529922ad4SDamjan Jovanovic     printf( "OUString: " );
66cdf0e10cSrcweir     aString = ::rtl::OUStringToOString( _suStr, RTL_TEXTENCODING_ASCII_US );
6729922ad4SDamjan Jovanovic     printf( "'%s'\n", aString.getStr( ) );
68cdf0e10cSrcweir }
69cdf0e10cSrcweir 
70cdf0e10cSrcweir // -----------------------------------------------------------------------------
71cdf0e10cSrcweir namespace ThreadHelper
72cdf0e10cSrcweir {
73cdf0e10cSrcweir     // typedef enum {
74cdf0e10cSrcweir     //     QUIET=1,
75cdf0e10cSrcweir     //     VERBOSE
76cdf0e10cSrcweir     // } eSleepVerboseMode;
77cdf0e10cSrcweir 
78cdf0e10cSrcweir     void thread_sleep_tenth_sec(sal_Int32 _nTenthSec/*, eSleepVerboseMode nVerbose = VERBOSE*/)
79cdf0e10cSrcweir     {
80cdf0e10cSrcweir         // if (nVerbose == VERBOSE)
81cdf0e10cSrcweir         // {
8229922ad4SDamjan Jovanovic         //     printf("wait %d tenth seconds. ", _nTenthSec );
83cdf0e10cSrcweir         //     fflush(stdout);
84cdf0e10cSrcweir         // }
85cdf0e10cSrcweir #ifdef WNT      //Windows
86cdf0e10cSrcweir         Sleep(_nTenthSec * 100 );
87cdf0e10cSrcweir #endif
88cdf0e10cSrcweir #if ( defined UNX ) || ( defined OS2 )  //Unix
89cdf0e10cSrcweir         TimeValue nTV;
90cdf0e10cSrcweir         nTV.Seconds = static_cast<sal_uInt32>( _nTenthSec/10 );
91cdf0e10cSrcweir         nTV.Nanosec = ( (_nTenthSec%10 ) * 100000000 );
92cdf0e10cSrcweir         osl_waitThread(&nTV);
93cdf0e10cSrcweir #endif
94cdf0e10cSrcweir         // if (nVerbose == VERBOSE)
95cdf0e10cSrcweir         // {
9629922ad4SDamjan Jovanovic         //     printf("done\n");
97cdf0e10cSrcweir         // }
98cdf0e10cSrcweir     }
99cdf0e10cSrcweir }
100cdf0e10cSrcweir 
101cdf0e10cSrcweir // -----------------------------------------------------------------------------
102cdf0e10cSrcweir 
103cdf0e10cSrcweir /** Simple thread for testing Thread-create.
104cdf0e10cSrcweir  * Just add 1 of value 0, and after running, result is 1.
105cdf0e10cSrcweir  */
106cdf0e10cSrcweir class OGetThread : public osl::Thread
107cdf0e10cSrcweir {
108cdf0e10cSrcweir     sal_Int32 m_nOK;
109cdf0e10cSrcweir     sal_Int32 m_nFails;
110cdf0e10cSrcweir 
111cdf0e10cSrcweir     rtl::OUString m_sConstStr;
112cdf0e10cSrcweir public:
113cdf0e10cSrcweir     OGetThread()
114cdf0e10cSrcweir             :m_nOK(0),
115cdf0e10cSrcweir              m_nFails(0)
116cdf0e10cSrcweir         {
117cdf0e10cSrcweir             m_sConstStr = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CONST_TEST_STRING ));
118cdf0e10cSrcweir         }
119cdf0e10cSrcweir 
120cdf0e10cSrcweir     sal_Int32 getOK() { return m_nOK; }
121cdf0e10cSrcweir     sal_Int32 getFails() {return m_nFails;}
122cdf0e10cSrcweir 
123cdf0e10cSrcweir protected:
124cdf0e10cSrcweir 
125cdf0e10cSrcweir     /** guarded value which initialized 0
126cdf0e10cSrcweir 
127cdf0e10cSrcweir         @see ThreadSafeValue
128cdf0e10cSrcweir     */
129cdf0e10cSrcweir     void SAL_CALL run()
130cdf0e10cSrcweir         {
131cdf0e10cSrcweir             while(schedule())
132cdf0e10cSrcweir             {
133cdf0e10cSrcweir                 rtl::OUString aStr = Gregorian::get();
134cdf0e10cSrcweir                 // printOUString(aStr);
135cdf0e10cSrcweir                 // printOUString(m_sConstStr);
136cdf0e10cSrcweir                 if (aStr.equals(m_sConstStr))
137cdf0e10cSrcweir                 {
138cdf0e10cSrcweir                     m_nOK++;
139cdf0e10cSrcweir                 }
140cdf0e10cSrcweir                 else
141cdf0e10cSrcweir                 {
142cdf0e10cSrcweir                     m_nFails++;
143cdf0e10cSrcweir                 }
144cdf0e10cSrcweir                 ThreadHelper::thread_sleep_tenth_sec(1);
145cdf0e10cSrcweir             }
146cdf0e10cSrcweir         }
147cdf0e10cSrcweir 
148cdf0e10cSrcweir public:
149cdf0e10cSrcweir 
150cdf0e10cSrcweir     virtual void SAL_CALL suspend()
151cdf0e10cSrcweir         {
152cdf0e10cSrcweir             ::osl::Thread::suspend();
153cdf0e10cSrcweir         }
154cdf0e10cSrcweir 
155cdf0e10cSrcweir     ~OGetThread()
156cdf0e10cSrcweir         {
157cdf0e10cSrcweir             if (isRunning())
158cdf0e10cSrcweir             {
15929922ad4SDamjan Jovanovic                 printf("error: not terminated.\n");
160cdf0e10cSrcweir             }
161cdf0e10cSrcweir         }
162cdf0e10cSrcweir };
163cdf0e10cSrcweir 
164cdf0e10cSrcweir // -----------------------------------------------------------------------------
165cdf0e10cSrcweir namespace rtl_DoubleLocking
166cdf0e10cSrcweir {
167cdf0e10cSrcweir 
168cdf0e10cSrcweir /** Test of the osl::Thread::create method
169cdf0e10cSrcweir  */
170cdf0e10cSrcweir 
17129922ad4SDamjan Jovanovic     class getValue : public ::testing::Test
172cdf0e10cSrcweir     {
173cdf0e10cSrcweir     public:
174cdf0e10cSrcweir 
175cdf0e10cSrcweir         // initialise your test code values here.
17629922ad4SDamjan Jovanovic         void SetUp()
177cdf0e10cSrcweir             {
178cdf0e10cSrcweir             }
179cdf0e10cSrcweir 
18029922ad4SDamjan Jovanovic         void TearDown()
181cdf0e10cSrcweir             {
182cdf0e10cSrcweir             }
18329922ad4SDamjan Jovanovic     }; // class create
184cdf0e10cSrcweir 
18529922ad4SDamjan Jovanovic     TEST_F(getValue, getValue_001)
18629922ad4SDamjan Jovanovic     {
18729922ad4SDamjan Jovanovic         rtl::OUString aStr = Gregorian::get();
18829922ad4SDamjan Jovanovic         printOUString(aStr);
189cdf0e10cSrcweir 
19029922ad4SDamjan Jovanovic         ASSERT_TRUE(aStr.getLength() != 0)
19129922ad4SDamjan Jovanovic             << "Gregorian::get() failed, wrong value expected.";
19229922ad4SDamjan Jovanovic     }
193cdf0e10cSrcweir 
19429922ad4SDamjan Jovanovic     /** check 2 threads.
195cdf0e10cSrcweir 
19629922ad4SDamjan Jovanovic         ALGORITHM:
19729922ad4SDamjan Jovanovic         Here the function should show, that 2 different threads,
19829922ad4SDamjan Jovanovic         which only increase a value, should run at the same time with same prio.
19929922ad4SDamjan Jovanovic         The test fails, if the difference between the two values is more than 5%
20029922ad4SDamjan Jovanovic         but IMHO this isn't a failure, it's only a feature of the OS.
20129922ad4SDamjan Jovanovic     */
20229922ad4SDamjan Jovanovic     TEST_F(getValue, getValue_002)
20329922ad4SDamjan Jovanovic     {
20429922ad4SDamjan Jovanovic         // initial 5 threads with different priorities
20529922ad4SDamjan Jovanovic         OGetThread* pThread = new OGetThread();
20629922ad4SDamjan Jovanovic         OGetThread* p2Thread = new OGetThread();
207cdf0e10cSrcweir 
20829922ad4SDamjan Jovanovic         //Create them and start running at the same time
20929922ad4SDamjan Jovanovic         pThread->create();
21029922ad4SDamjan Jovanovic         p2Thread->create();
211cdf0e10cSrcweir 
21229922ad4SDamjan Jovanovic         ThreadHelper::thread_sleep_tenth_sec(50);
213cdf0e10cSrcweir 
21429922ad4SDamjan Jovanovic         pThread->terminate();
21529922ad4SDamjan Jovanovic         p2Thread->terminate();
216cdf0e10cSrcweir 
21729922ad4SDamjan Jovanovic         sal_Int32 nValueOK = 0;
21829922ad4SDamjan Jovanovic         nValueOK = pThread->getOK();
219cdf0e10cSrcweir 
22029922ad4SDamjan Jovanovic         sal_Int32 nValueOK2 = 0;
22129922ad4SDamjan Jovanovic         nValueOK2 = p2Thread->getOK();
222cdf0e10cSrcweir 
22329922ad4SDamjan Jovanovic         printf("Value in Thread #1 is %d\n", nValueOK);
22429922ad4SDamjan Jovanovic         printf("Value in Thread #2 is %d\n", nValueOK2);
225cdf0e10cSrcweir 
22629922ad4SDamjan Jovanovic         sal_Int32 nValueFails = 0;
22729922ad4SDamjan Jovanovic         nValueFails = pThread->getFails();
228cdf0e10cSrcweir 
22929922ad4SDamjan Jovanovic         sal_Int32 nValueFails2 = 0;
23029922ad4SDamjan Jovanovic         nValueFails2 = p2Thread->getFails();
231cdf0e10cSrcweir 
23229922ad4SDamjan Jovanovic         printf("Fails in Thread #1 is %d\n", nValueFails);
23329922ad4SDamjan Jovanovic         printf("Fails in Thread #2 is %d\n", nValueFails2);
234cdf0e10cSrcweir 
23529922ad4SDamjan Jovanovic         // ThreadHelper::thread_sleep_tenth_sec(1);
23629922ad4SDamjan Jovanovic         pThread->join();
23729922ad4SDamjan Jovanovic         p2Thread->join();
238cdf0e10cSrcweir 
23929922ad4SDamjan Jovanovic         delete pThread;
24029922ad4SDamjan Jovanovic         delete p2Thread;
241cdf0e10cSrcweir 
24229922ad4SDamjan Jovanovic         ASSERT_TRUE(nValueOK != 0 && nValueFails == 0 && nValueFails2 == 0)
24329922ad4SDamjan Jovanovic             << "getValue() failed, wrong value expected.";
24429922ad4SDamjan Jovanovic     }
245cdf0e10cSrcweir 
246cdf0e10cSrcweir } // namespace rtl_DoubleLocking
247cdf0e10cSrcweir 
24829922ad4SDamjan Jovanovic int main(int argc, char **argv)
24929922ad4SDamjan Jovanovic {
25029922ad4SDamjan Jovanovic     ::testing::InitGoogleTest(&argc, argv);
25129922ad4SDamjan Jovanovic     return RUN_ALL_TESTS();
25229922ad4SDamjan Jovanovic }
253