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