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 
31*29922ad4SDamjan Jovanovic #include <rtl/ustring.h>
32*29922ad4SDamjan 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 
41*29922ad4SDamjan Jovanovic #include "gtest/gtest.h"
42cdf0e10cSrcweir 
43cdf0e10cSrcweir // -----------------------------------------------------------------------------
44cdf0e10cSrcweir #define CONST_TEST_STRING "gregorian"
45cdf0e10cSrcweir 
46cdf0e10cSrcweir namespace {
47cdf0e10cSrcweir struct Gregorian : public rtl::StaticWithInit<const ::rtl::OUString, Gregorian> {
48cdf0e10cSrcweir     const ::rtl::OUString operator () () {
49cdf0e10cSrcweir         return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CONST_TEST_STRING ));
50cdf0e10cSrcweir     }
51cdf0e10cSrcweir };
52cdf0e10cSrcweir }
53cdf0e10cSrcweir 
54cdf0e10cSrcweir inline void printOUString( ::rtl::OUString const & _suStr )
55cdf0e10cSrcweir {
56cdf0e10cSrcweir     rtl::OString aString;
57cdf0e10cSrcweir 
58*29922ad4SDamjan Jovanovic     printf( "OUString: " );
59cdf0e10cSrcweir     aString = ::rtl::OUStringToOString( _suStr, RTL_TEXTENCODING_ASCII_US );
60*29922ad4SDamjan Jovanovic     printf( "'%s'\n", aString.getStr( ) );
61cdf0e10cSrcweir }
62cdf0e10cSrcweir 
63cdf0e10cSrcweir // -----------------------------------------------------------------------------
64cdf0e10cSrcweir namespace ThreadHelper
65cdf0e10cSrcweir {
66cdf0e10cSrcweir     // typedef enum {
67cdf0e10cSrcweir     //     QUIET=1,
68cdf0e10cSrcweir     //     VERBOSE
69cdf0e10cSrcweir     // } eSleepVerboseMode;
70cdf0e10cSrcweir 
71cdf0e10cSrcweir     void thread_sleep_tenth_sec(sal_Int32 _nTenthSec/*, eSleepVerboseMode nVerbose = VERBOSE*/)
72cdf0e10cSrcweir     {
73cdf0e10cSrcweir         // if (nVerbose == VERBOSE)
74cdf0e10cSrcweir         // {
75*29922ad4SDamjan Jovanovic         //     printf("wait %d tenth seconds. ", _nTenthSec );
76cdf0e10cSrcweir         //     fflush(stdout);
77cdf0e10cSrcweir         // }
78cdf0e10cSrcweir #ifdef WNT      //Windows
79cdf0e10cSrcweir         Sleep(_nTenthSec * 100 );
80cdf0e10cSrcweir #endif
81cdf0e10cSrcweir #if ( defined UNX ) || ( defined OS2 )  //Unix
82cdf0e10cSrcweir         TimeValue nTV;
83cdf0e10cSrcweir         nTV.Seconds = static_cast<sal_uInt32>( _nTenthSec/10 );
84cdf0e10cSrcweir         nTV.Nanosec = ( (_nTenthSec%10 ) * 100000000 );
85cdf0e10cSrcweir         osl_waitThread(&nTV);
86cdf0e10cSrcweir #endif
87cdf0e10cSrcweir         // if (nVerbose == VERBOSE)
88cdf0e10cSrcweir         // {
89*29922ad4SDamjan Jovanovic         //     printf("done\n");
90cdf0e10cSrcweir         // }
91cdf0e10cSrcweir     }
92cdf0e10cSrcweir }
93cdf0e10cSrcweir 
94cdf0e10cSrcweir // -----------------------------------------------------------------------------
95cdf0e10cSrcweir 
96cdf0e10cSrcweir /** Simple thread for testing Thread-create.
97cdf0e10cSrcweir  * Just add 1 of value 0, and after running, result is 1.
98cdf0e10cSrcweir  */
99cdf0e10cSrcweir class OGetThread : public osl::Thread
100cdf0e10cSrcweir {
101cdf0e10cSrcweir     sal_Int32 m_nOK;
102cdf0e10cSrcweir     sal_Int32 m_nFails;
103cdf0e10cSrcweir 
104cdf0e10cSrcweir     rtl::OUString m_sConstStr;
105cdf0e10cSrcweir public:
106cdf0e10cSrcweir     OGetThread()
107cdf0e10cSrcweir             :m_nOK(0),
108cdf0e10cSrcweir              m_nFails(0)
109cdf0e10cSrcweir         {
110cdf0e10cSrcweir             m_sConstStr = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CONST_TEST_STRING ));
111cdf0e10cSrcweir         }
112cdf0e10cSrcweir 
113cdf0e10cSrcweir     sal_Int32 getOK() { return m_nOK; }
114cdf0e10cSrcweir     sal_Int32 getFails() {return m_nFails;}
115cdf0e10cSrcweir 
116cdf0e10cSrcweir protected:
117cdf0e10cSrcweir 
118cdf0e10cSrcweir     /** guarded value which initialized 0
119cdf0e10cSrcweir 
120cdf0e10cSrcweir         @see ThreadSafeValue
121cdf0e10cSrcweir     */
122cdf0e10cSrcweir     void SAL_CALL run()
123cdf0e10cSrcweir         {
124cdf0e10cSrcweir             while(schedule())
125cdf0e10cSrcweir             {
126cdf0e10cSrcweir                 rtl::OUString aStr = Gregorian::get();
127cdf0e10cSrcweir                 // printOUString(aStr);
128cdf0e10cSrcweir                 // printOUString(m_sConstStr);
129cdf0e10cSrcweir                 if (aStr.equals(m_sConstStr))
130cdf0e10cSrcweir                 {
131cdf0e10cSrcweir                     m_nOK++;
132cdf0e10cSrcweir                 }
133cdf0e10cSrcweir                 else
134cdf0e10cSrcweir                 {
135cdf0e10cSrcweir                     m_nFails++;
136cdf0e10cSrcweir                 }
137cdf0e10cSrcweir                 ThreadHelper::thread_sleep_tenth_sec(1);
138cdf0e10cSrcweir             }
139cdf0e10cSrcweir         }
140cdf0e10cSrcweir 
141cdf0e10cSrcweir public:
142cdf0e10cSrcweir 
143cdf0e10cSrcweir     virtual void SAL_CALL suspend()
144cdf0e10cSrcweir         {
145cdf0e10cSrcweir             ::osl::Thread::suspend();
146cdf0e10cSrcweir         }
147cdf0e10cSrcweir 
148cdf0e10cSrcweir     ~OGetThread()
149cdf0e10cSrcweir         {
150cdf0e10cSrcweir             if (isRunning())
151cdf0e10cSrcweir             {
152*29922ad4SDamjan Jovanovic                 printf("error: not terminated.\n");
153cdf0e10cSrcweir             }
154cdf0e10cSrcweir         }
155cdf0e10cSrcweir };
156cdf0e10cSrcweir 
157cdf0e10cSrcweir // -----------------------------------------------------------------------------
158cdf0e10cSrcweir namespace rtl_DoubleLocking
159cdf0e10cSrcweir {
160cdf0e10cSrcweir 
161cdf0e10cSrcweir /** Test of the osl::Thread::create method
162cdf0e10cSrcweir  */
163cdf0e10cSrcweir 
164*29922ad4SDamjan Jovanovic     class getValue : public ::testing::Test
165cdf0e10cSrcweir     {
166cdf0e10cSrcweir     public:
167cdf0e10cSrcweir 
168cdf0e10cSrcweir         // initialise your test code values here.
169*29922ad4SDamjan Jovanovic         void SetUp()
170cdf0e10cSrcweir             {
171cdf0e10cSrcweir             }
172cdf0e10cSrcweir 
173*29922ad4SDamjan Jovanovic         void TearDown()
174cdf0e10cSrcweir             {
175cdf0e10cSrcweir             }
176*29922ad4SDamjan Jovanovic     }; // class create
177cdf0e10cSrcweir 
178*29922ad4SDamjan Jovanovic     TEST_F(getValue, getValue_001)
179*29922ad4SDamjan Jovanovic     {
180*29922ad4SDamjan Jovanovic         rtl::OUString aStr = Gregorian::get();
181*29922ad4SDamjan Jovanovic         printOUString(aStr);
182cdf0e10cSrcweir 
183*29922ad4SDamjan Jovanovic         ASSERT_TRUE(aStr.getLength() != 0)
184*29922ad4SDamjan Jovanovic             << "Gregorian::get() failed, wrong value expected.";
185*29922ad4SDamjan Jovanovic     }
186cdf0e10cSrcweir 
187*29922ad4SDamjan Jovanovic     /** check 2 threads.
188cdf0e10cSrcweir 
189*29922ad4SDamjan Jovanovic         ALGORITHM:
190*29922ad4SDamjan Jovanovic         Here the function should show, that 2 different threads,
191*29922ad4SDamjan Jovanovic         which only increase a value, should run at the same time with same prio.
192*29922ad4SDamjan Jovanovic         The test fails, if the difference between the two values is more than 5%
193*29922ad4SDamjan Jovanovic         but IMHO this isn't a failure, it's only a feature of the OS.
194*29922ad4SDamjan Jovanovic     */
195*29922ad4SDamjan Jovanovic     TEST_F(getValue, getValue_002)
196*29922ad4SDamjan Jovanovic     {
197*29922ad4SDamjan Jovanovic         // initial 5 threads with different priorities
198*29922ad4SDamjan Jovanovic         OGetThread* pThread = new OGetThread();
199*29922ad4SDamjan Jovanovic         OGetThread* p2Thread = new OGetThread();
200cdf0e10cSrcweir 
201*29922ad4SDamjan Jovanovic         //Create them and start running at the same time
202*29922ad4SDamjan Jovanovic         pThread->create();
203*29922ad4SDamjan Jovanovic         p2Thread->create();
204cdf0e10cSrcweir 
205*29922ad4SDamjan Jovanovic         ThreadHelper::thread_sleep_tenth_sec(50);
206cdf0e10cSrcweir 
207*29922ad4SDamjan Jovanovic         pThread->terminate();
208*29922ad4SDamjan Jovanovic         p2Thread->terminate();
209cdf0e10cSrcweir 
210*29922ad4SDamjan Jovanovic         sal_Int32 nValueOK = 0;
211*29922ad4SDamjan Jovanovic         nValueOK = pThread->getOK();
212cdf0e10cSrcweir 
213*29922ad4SDamjan Jovanovic         sal_Int32 nValueOK2 = 0;
214*29922ad4SDamjan Jovanovic         nValueOK2 = p2Thread->getOK();
215cdf0e10cSrcweir 
216*29922ad4SDamjan Jovanovic         printf("Value in Thread #1 is %d\n", nValueOK);
217*29922ad4SDamjan Jovanovic         printf("Value in Thread #2 is %d\n", nValueOK2);
218cdf0e10cSrcweir 
219*29922ad4SDamjan Jovanovic         sal_Int32 nValueFails = 0;
220*29922ad4SDamjan Jovanovic         nValueFails = pThread->getFails();
221cdf0e10cSrcweir 
222*29922ad4SDamjan Jovanovic         sal_Int32 nValueFails2 = 0;
223*29922ad4SDamjan Jovanovic         nValueFails2 = p2Thread->getFails();
224cdf0e10cSrcweir 
225*29922ad4SDamjan Jovanovic         printf("Fails in Thread #1 is %d\n", nValueFails);
226*29922ad4SDamjan Jovanovic         printf("Fails in Thread #2 is %d\n", nValueFails2);
227cdf0e10cSrcweir 
228*29922ad4SDamjan Jovanovic         // ThreadHelper::thread_sleep_tenth_sec(1);
229*29922ad4SDamjan Jovanovic         pThread->join();
230*29922ad4SDamjan Jovanovic         p2Thread->join();
231cdf0e10cSrcweir 
232*29922ad4SDamjan Jovanovic         delete pThread;
233*29922ad4SDamjan Jovanovic         delete p2Thread;
234cdf0e10cSrcweir 
235*29922ad4SDamjan Jovanovic         ASSERT_TRUE(nValueOK != 0 && nValueFails == 0 && nValueFails2 == 0)
236*29922ad4SDamjan Jovanovic             << "getValue() failed, wrong value expected.";
237*29922ad4SDamjan Jovanovic     }
238cdf0e10cSrcweir 
239cdf0e10cSrcweir } // namespace rtl_DoubleLocking
240cdf0e10cSrcweir 
241*29922ad4SDamjan Jovanovic int main(int argc, char **argv)
242*29922ad4SDamjan Jovanovic {
243*29922ad4SDamjan Jovanovic     ::testing::InitGoogleTest(&argc, argv);
244*29922ad4SDamjan Jovanovic     return RUN_ALL_TESTS();
245*29922ad4SDamjan Jovanovic }
246