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