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