1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sal.hxx" 30 //------------------------------------------------------------------------ 31 // include files 32 //------------------------------------------------------------------------ 33 #include <sal/types.h> 34 35 #ifndef _RTL_USTRING_HXX_ 36 #include <rtl/string.hxx> 37 #endif 38 39 #ifndef _OSL_THREAD_HXX 40 #include <osl/thread.hxx> 41 #endif 42 #include <osl/time.h> 43 44 #include <rtl/instance.hxx> 45 46 #include <testshl/simpleheader.hxx> 47 48 // ----------------------------------------------------------------------------- 49 #define CONST_TEST_STRING "gregorian" 50 51 namespace { 52 struct Gregorian : public rtl::StaticWithInit<const ::rtl::OUString, Gregorian> { 53 const ::rtl::OUString operator () () { 54 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CONST_TEST_STRING )); 55 } 56 }; 57 } 58 59 inline void printOUString( ::rtl::OUString const & _suStr ) 60 { 61 rtl::OString aString; 62 63 t_print( "OUString: " ); 64 aString = ::rtl::OUStringToOString( _suStr, RTL_TEXTENCODING_ASCII_US ); 65 t_print( "'%s'\n", aString.getStr( ) ); 66 } 67 68 // ----------------------------------------------------------------------------- 69 namespace ThreadHelper 70 { 71 // typedef enum { 72 // QUIET=1, 73 // VERBOSE 74 // } eSleepVerboseMode; 75 76 void thread_sleep_tenth_sec(sal_Int32 _nTenthSec/*, eSleepVerboseMode nVerbose = VERBOSE*/) 77 { 78 // if (nVerbose == VERBOSE) 79 // { 80 // t_print("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 // t_print("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: 111 OGetThread() 112 :m_nOK(0), 113 m_nFails(0) 114 { 115 m_sConstStr = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CONST_TEST_STRING )); 116 } 117 118 sal_Int32 getOK() { return m_nOK; } 119 sal_Int32 getFails() {return m_nFails;} 120 121 protected: 122 123 /** guarded value which initialized 0 124 125 @see ThreadSafeValue 126 */ 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 148 virtual void SAL_CALL suspend() 149 { 150 ::osl::Thread::suspend(); 151 } 152 153 ~OGetThread() 154 { 155 if (isRunning()) 156 { 157 t_print("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 CppUnit::TestFixture 170 { 171 public: 172 173 // initialise your test code values here. 174 void setUp() 175 { 176 } 177 178 void tearDown() 179 { 180 } 181 182 183 void getValue_001() 184 { 185 rtl::OUString aStr = Gregorian::get(); 186 printOUString(aStr); 187 188 CPPUNIT_ASSERT_MESSAGE( 189 "Gregorian::get() failed, wrong value expected.", 190 aStr.getLength() != 0 191 ); 192 } 193 194 /** check 2 threads. 195 196 ALGORITHM: 197 Here the function should show, that 2 different threads, 198 which only increase a value, should run at the same time with same prio. 199 The test fails, if the difference between the two values is more than 5% 200 but IMHO this isn't a failure, it's only a feature of the OS. 201 */ 202 203 void getValue_002() 204 { 205 // initial 5 threads with different priorities 206 OGetThread* pThread = new OGetThread(); 207 OGetThread* p2Thread = new OGetThread(); 208 209 //Create them and start running at the same time 210 pThread->create(); 211 p2Thread->create(); 212 213 ThreadHelper::thread_sleep_tenth_sec(50); 214 215 pThread->terminate(); 216 p2Thread->terminate(); 217 218 sal_Int32 nValueOK = 0; 219 nValueOK = pThread->getOK(); 220 221 sal_Int32 nValueOK2 = 0; 222 nValueOK2 = p2Thread->getOK(); 223 224 t_print("Value in Thread #1 is %d\n", nValueOK); 225 t_print("Value in Thread #2 is %d\n", nValueOK2); 226 227 sal_Int32 nValueFails = 0; 228 nValueFails = pThread->getFails(); 229 230 sal_Int32 nValueFails2 = 0; 231 nValueFails2 = p2Thread->getFails(); 232 233 t_print("Fails in Thread #1 is %d\n", nValueFails); 234 t_print("Fails in Thread #2 is %d\n", nValueFails2); 235 236 // ThreadHelper::thread_sleep_tenth_sec(1); 237 pThread->join(); 238 p2Thread->join(); 239 240 delete pThread; 241 delete p2Thread; 242 243 CPPUNIT_ASSERT_MESSAGE( 244 "getValue() failed, wrong value expected.", 245 nValueOK != 0 && nValueFails == 0 && nValueFails2 == 0 246 ); 247 } 248 249 CPPUNIT_TEST_SUITE(getValue); 250 CPPUNIT_TEST(getValue_001); 251 CPPUNIT_TEST(getValue_002); 252 CPPUNIT_TEST_SUITE_END(); 253 }; // class create 254 // ----------------------------------------------------------------------------- 255 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_DoubleLocking::getValue, "rtl_DoubleLocking"); 256 } // namespace rtl_DoubleLocking 257 258 // this macro creates an empty function, which will called by the RegisterAllFunctions() 259 // to let the user the possibility to also register some functions by hand. 260 NOADDITIONAL; 261