/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sal.hxx" //------------------------------------------------------------------------ // include files //------------------------------------------------------------------------ #include #ifndef _RTL_USTRING_HXX_ #include #endif #ifndef _OSL_THREAD_HXX #include #endif #include #include #include // ----------------------------------------------------------------------------- #define CONST_TEST_STRING "gregorian" namespace { struct Gregorian : public rtl::StaticWithInit { const ::rtl::OUString operator () () { return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CONST_TEST_STRING )); } }; } inline void printOUString( ::rtl::OUString const & _suStr ) { rtl::OString aString; t_print( "OUString: " ); aString = ::rtl::OUStringToOString( _suStr, RTL_TEXTENCODING_ASCII_US ); t_print( "'%s'\n", aString.getStr( ) ); } // ----------------------------------------------------------------------------- namespace ThreadHelper { // typedef enum { // QUIET=1, // VERBOSE // } eSleepVerboseMode; void thread_sleep_tenth_sec(sal_Int32 _nTenthSec/*, eSleepVerboseMode nVerbose = VERBOSE*/) { // if (nVerbose == VERBOSE) // { // t_print("wait %d tenth seconds. ", _nTenthSec ); // fflush(stdout); // } #ifdef WNT //Windows Sleep(_nTenthSec * 100 ); #endif #if ( defined UNX ) || ( defined OS2 ) //Unix TimeValue nTV; nTV.Seconds = static_cast( _nTenthSec/10 ); nTV.Nanosec = ( (_nTenthSec%10 ) * 100000000 ); osl_waitThread(&nTV); #endif // if (nVerbose == VERBOSE) // { // t_print("done\n"); // } } } // ----------------------------------------------------------------------------- /** Simple thread for testing Thread-create. * Just add 1 of value 0, and after running, result is 1. */ class OGetThread : public osl::Thread { sal_Int32 m_nOK; sal_Int32 m_nFails; rtl::OUString m_sConstStr; public: OGetThread() :m_nOK(0), m_nFails(0) { m_sConstStr = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( CONST_TEST_STRING )); } sal_Int32 getOK() { return m_nOK; } sal_Int32 getFails() {return m_nFails;} protected: /** guarded value which initialized 0 @see ThreadSafeValue */ void SAL_CALL run() { while(schedule()) { rtl::OUString aStr = Gregorian::get(); // printOUString(aStr); // printOUString(m_sConstStr); if (aStr.equals(m_sConstStr)) { m_nOK++; } else { m_nFails++; } ThreadHelper::thread_sleep_tenth_sec(1); } } public: virtual void SAL_CALL suspend() { ::osl::Thread::suspend(); } ~OGetThread() { if (isRunning()) { t_print("error: not terminated.\n"); } } }; // ----------------------------------------------------------------------------- namespace rtl_DoubleLocking { /** Test of the osl::Thread::create method */ class getValue : public CppUnit::TestFixture { public: // initialise your test code values here. void setUp() { } void tearDown() { } void getValue_001() { rtl::OUString aStr = Gregorian::get(); printOUString(aStr); CPPUNIT_ASSERT_MESSAGE( "Gregorian::get() failed, wrong value expected.", aStr.getLength() != 0 ); } /** check 2 threads. ALGORITHM: Here the function should show, that 2 different threads, which only increase a value, should run at the same time with same prio. The test fails, if the difference between the two values is more than 5% but IMHO this isn't a failure, it's only a feature of the OS. */ void getValue_002() { // initial 5 threads with different priorities OGetThread* pThread = new OGetThread(); OGetThread* p2Thread = new OGetThread(); //Create them and start running at the same time pThread->create(); p2Thread->create(); ThreadHelper::thread_sleep_tenth_sec(50); pThread->terminate(); p2Thread->terminate(); sal_Int32 nValueOK = 0; nValueOK = pThread->getOK(); sal_Int32 nValueOK2 = 0; nValueOK2 = p2Thread->getOK(); t_print("Value in Thread #1 is %d\n", nValueOK); t_print("Value in Thread #2 is %d\n", nValueOK2); sal_Int32 nValueFails = 0; nValueFails = pThread->getFails(); sal_Int32 nValueFails2 = 0; nValueFails2 = p2Thread->getFails(); t_print("Fails in Thread #1 is %d\n", nValueFails); t_print("Fails in Thread #2 is %d\n", nValueFails2); // ThreadHelper::thread_sleep_tenth_sec(1); pThread->join(); p2Thread->join(); delete pThread; delete p2Thread; CPPUNIT_ASSERT_MESSAGE( "getValue() failed, wrong value expected.", nValueOK != 0 && nValueFails == 0 && nValueFails2 == 0 ); } CPPUNIT_TEST_SUITE(getValue); CPPUNIT_TEST(getValue_001); CPPUNIT_TEST(getValue_002); CPPUNIT_TEST_SUITE_END(); }; // class create // ----------------------------------------------------------------------------- CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(rtl_DoubleLocking::getValue, "rtl_DoubleLocking"); } // namespace rtl_DoubleLocking // this macro creates an empty function, which will called by the RegisterAllFunctions() // to let the user the possibility to also register some functions by hand. NOADDITIONAL;