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> { 49 const ::rtl::OUString operator () () { 50 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CONST_TEST_STRING )); 51 } 52 }; 53 } 54 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 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: 107 OGetThread() 108 :m_nOK(0), 109 m_nFails(0) 110 { 111 m_sConstStr = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CONST_TEST_STRING )); 112 } 113 114 sal_Int32 getOK() { return m_nOK; } 115 sal_Int32 getFails() {return m_nFails;} 116 117 protected: 118 119 /** guarded value which initialized 0 120 121 @see ThreadSafeValue 122 */ 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 144 virtual void SAL_CALL suspend() 145 { 146 ::osl::Thread::suspend(); 147 } 148 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. 170 void setUp() 171 { 172 } 173 174 void tearDown() 175 { 176 } 177 178 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 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