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