summaryrefslogtreecommitdiff
path: root/sal/qa/osl/process/osl_Thread.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sal/qa/osl/process/osl_Thread.cxx')
-rw-r--r--sal/qa/osl/process/osl_Thread.cxx2344
1 files changed, 2344 insertions, 0 deletions
diff --git a/sal/qa/osl/process/osl_Thread.cxx b/sal/qa/osl/process/osl_Thread.cxx
new file mode 100644
index 000000000000..794fcc82f9c9
--- /dev/null
+++ b/sal/qa/osl/process/osl_Thread.cxx
@@ -0,0 +1,2344 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sal.hxx"
+//------------------------------------------------------------------------
+// include files
+//------------------------------------------------------------------------
+#include <sal/types.h>
+
+#ifndef _RTL_USTRING_HXX_
+#include <rtl/string.hxx>
+#endif
+
+#ifndef _RTL_USTRING_HXX_
+#include <rtl/strbuf.hxx>
+#endif
+
+#ifndef _OSL_THREAD_HXX
+#include <osl/thread.hxx>
+#endif
+
+#ifndef _OSL_MUTEX_HXX
+#include <osl/mutex.hxx>
+#endif
+#include <osl/time.h>
+
+#include <testshl/simpleheader.hxx>
+
+using namespace osl;
+using namespace rtl;
+
+#ifdef UNX
+#include <unistd.h>
+#include <time.h>
+#endif
+// -----------------------------------------------------------------------------
+// Kleine Stopuhr
+class StopWatch {
+ TimeValue t1,t2; // Start und Stopzeit
+
+protected:
+ sal_Int32 m_nNanoSec;
+ sal_Int32 m_nSeconds;
+
+ bool m_bIsValid; // TRUE, wenn gestartet und gestoppt
+ bool m_bIsRunning; // TRUE, wenn gestartet.
+
+public:
+ StopWatch();
+ ~StopWatch() {}
+
+ void start(); // Startet Timer
+ void stop(); // Stoppt Timer
+
+ double getSeconds() const;
+ double getTenthSec() const;
+};
+
+// ================================= Stop Watch =================================
+
+// Eine kleine Stop-Uhr fuer den internen Gebrauch.
+// (c) Lars Langhans 29.12.1996 22:10
+
+StopWatch::StopWatch():m_bIsValid(false),m_bIsRunning(false) {}
+
+void StopWatch::start()
+{
+// pre: %
+// post: Start Timer
+
+ m_bIsValid = false;
+ m_bIsRunning = true;
+ osl_getSystemTime( &t1 );
+ t_print("# %d %d nsecs\n", t1.Seconds, t1.Nanosec);
+ // gettimeofday(&t1, 0);
+}
+
+void StopWatch::stop()
+{
+// pre: Timer should be started
+// post: Timer will stopped
+
+ // gettimeofday(&t2, 0); // Timer ausfragen
+ osl_getSystemTime( &t2 );
+ t_print("# %d %d nsecs\n", t2.Seconds, t2.Nanosec);
+
+ if (m_bIsRunning)
+ { // check ob gestartet.
+// LLA: old m_nNanoSec = static_cast<sal_Int32>(t2.Nanosec) - static_cast<sal_Int32>(t1.Nanosec);
+// LLA: old m_nSeconds = static_cast<sal_Int32>(t2.Seconds) - static_cast<sal_Int32>(t1.Seconds);
+// LLA: old if (m_nNanoSec < 0)
+// LLA: old {
+// LLA: old m_nNanoSec += 1000000000;
+// LLA: old m_nSeconds -= 1;
+// LLA: old }
+ //m_nNanoSec = t2.Nanosec - t1.Nanosec;
+ m_nSeconds = static_cast<sal_Int32>(t2.Seconds) - static_cast<sal_Int32>(t1.Seconds);
+ if ( t2.Nanosec > t1.Nanosec )
+ m_nNanoSec = static_cast<sal_Int32>(t2.Nanosec) - static_cast<sal_Int32>(t1.Nanosec);
+ else
+ {
+ m_nNanoSec = 1000000000 + static_cast<sal_Int32>(t2.Nanosec) - static_cast<sal_Int32>(t1.Nanosec);
+ m_nSeconds -= 1;
+ }
+ t_print("# %d %d nsecs\n", m_nSeconds, m_nNanoSec );
+ //if (m_nNanoSec < 0)
+ //{
+ //m_nNanoSec += 1000000000;
+ //m_nSeconds -= 1;
+ //}
+ m_bIsValid = true;
+ m_bIsRunning = false;
+ }
+}
+
+double StopWatch::getSeconds() const
+{
+// pre: gueltig = TRUE
+// BACK: Zeit in Sekunden.
+
+ double nValue = 0.0;
+ if (m_bIsValid)
+ {
+ nValue = double(m_nNanoSec) / 1000000000.0 + m_nSeconds; // milli micro nano
+ }
+ return nValue;
+}
+
+double StopWatch::getTenthSec() const
+{
+ double nValue = 0.0;
+ if (m_bIsValid)
+ {
+ nValue = double(m_nNanoSec) / 100000000.0 + m_nSeconds * 10;
+ }
+ return nValue ;
+}
+
+// -----------------------------------------------------------------------------
+template <class T>
+class ThreadSafeValue
+{
+ T m_nFlag;
+ Mutex m_aMutex;
+public:
+ ThreadSafeValue(T n = 0): m_nFlag(n) {}
+ T getValue()
+ {
+ //block if already acquired by another thread.
+ osl::MutexGuard g(m_aMutex);
+ return m_nFlag;
+ }
+ void addValue(T n)
+ {
+ //only one thread operate on the flag.
+ osl::MutexGuard g(m_aMutex);
+ m_nFlag += n;
+ }
+ void acquire() {m_aMutex.acquire();}
+ void release() {m_aMutex.release();}
+};
+
+// -----------------------------------------------------------------------------
+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<sal_uInt32>( _nTenthSec/10 );
+ nTV.Nanosec = ( (_nTenthSec%10 ) * 100000000 );
+ osl_waitThread(&nTV);
+#endif
+ // if (nVerbose == VERBOSE)
+ // {
+ // t_print("done\n");
+ // }
+ }
+
+ void outputPriority(oslThreadPriority const& _aPriority)
+ {
+ // LLA: output the priority
+ if (_aPriority == osl_Thread_PriorityHighest)
+ {
+ t_print("Prio is High\n");
+ }
+ else if (_aPriority == osl_Thread_PriorityAboveNormal)
+ {
+ t_print("Prio is above normal\n");
+ }
+ else if (_aPriority == osl_Thread_PriorityNormal)
+ {
+ t_print("Prio is normal\n");
+ }
+ else if (_aPriority == osl_Thread_PriorityBelowNormal)
+ {
+ t_print("Prio is below normal\n");
+ }
+ else if (_aPriority == osl_Thread_PriorityLowest)
+ {
+ t_print("Prio is lowest\n");
+ }
+ else
+ {
+ t_print("Prio is unknown\n");
+ }
+ }
+}
+
+/** Simple thread for testing Thread-create.
+
+ Just add 1 of value 0, and after running, result is 1.
+ */
+class myThread : public Thread
+{
+ ThreadSafeValue<sal_Int32> m_aFlag;
+public:
+ sal_Int32 getValue() { return m_aFlag.getValue(); }
+protected:
+ /** guarded value which initialized 0
+
+ @see ThreadSafeValue
+ */
+ void SAL_CALL run()
+ {
+ while(schedule())
+ {
+ m_aFlag.addValue(1);
+ ThreadHelper::thread_sleep_tenth_sec(1);
+ }
+ }
+
+public:
+
+ virtual void SAL_CALL suspend()
+ {
+ m_aFlag.acquire();
+ ::osl::Thread::suspend();
+ m_aFlag.release();
+ }
+
+ ~myThread()
+ {
+ if (isRunning())
+ {
+ t_print("error: not terminated.\n");
+ }
+ }
+
+};
+
+// -----------------------------------------------------------------------------
+/** Thread which has a flag add 1 every second until 20
+ */
+class OCountThread : public Thread
+{
+ ThreadSafeValue<sal_Int32> m_aFlag;
+public:
+ OCountThread()
+ {
+ m_nWaitSec = 0;
+ t_print("new OCountThread thread %d!\n", getIdentifier());
+ }
+ sal_Int32 getValue() { return m_aFlag.getValue(); }
+
+ void setWait(sal_Int32 nSec)
+ {
+ m_nWaitSec = nSec;
+ //m_bWait = sal_True;
+ }
+
+ virtual void SAL_CALL suspend()
+ {
+ m_aFlag.acquire();
+ ::osl::Thread::suspend();
+ m_aFlag.release();
+ }
+
+protected:
+ //sal_Bool m_bWait;
+ sal_Int32 m_nWaitSec;
+
+ void SAL_CALL run()
+ {
+ /// if the thread should terminate, schedule return false
+ while (m_aFlag.getValue() < 20 && schedule() == sal_True)
+ {
+ m_aFlag.addValue(1);
+ ThreadHelper::thread_sleep_tenth_sec(1);
+ // TimeValue nTV;
+ // nTV.Seconds = 1;
+ // nTV.Nanosec = 0;
+ // wait(nTV);
+
+ if (m_nWaitSec != 0)
+ {
+ //ThreadHelper::thread_sleep_tenth_sec(m_nWaitSec * 10);
+ TimeValue nTV;
+ nTV.Seconds = m_nWaitSec / 10 ;
+ nTV.Nanosec = ( m_nWaitSec%10 ) * 100000000 ;
+ wait( nTV );
+ m_nWaitSec = 0;
+ }
+ }
+ }
+ void SAL_CALL onTerminated()
+ {
+ t_print("normally terminate this thread %d!\n", getIdentifier());
+ }
+public:
+
+ ~OCountThread()
+ {
+ if (isRunning())
+ {
+ t_print("error: not terminated.\n");
+ }
+ }
+
+};
+
+/** call suspend in the run method
+*/
+class OSuspendThread : public Thread
+{
+ ThreadSafeValue<sal_Int32> m_aFlag;
+public:
+ OSuspendThread(){ m_bSuspend = sal_False; }
+ sal_Int32 getValue() { return m_aFlag.getValue(); }
+ void setSuspend()
+ {
+ m_bSuspend = sal_True;
+ }
+ virtual void SAL_CALL suspend()
+ {
+ m_aFlag.acquire();
+ ::osl::Thread::suspend();
+ m_aFlag.release();
+ }
+protected:
+ sal_Bool m_bSuspend;
+ void SAL_CALL run()
+ {
+ //if the thread should terminate, schedule return false
+ while (schedule() == sal_True)
+ {
+ m_aFlag.addValue(1);
+
+ ThreadHelper::thread_sleep_tenth_sec(1);
+ // m_bWait = sal_False;
+ // TimeValue nTV;
+ // nTV.Seconds = 1;
+ // nTV.Nanosec = 0;
+ // wait(nTV);
+ if (m_bSuspend == sal_True)
+ {
+ suspend();
+ m_bSuspend = sal_False;
+ }
+ }
+ }
+public:
+
+ ~OSuspendThread()
+ {
+ if (isRunning())
+ {
+ t_print("error: not terminated.\n");
+ }
+ }
+
+};
+
+/** no call schedule in the run method
+*/
+class ONoScheduleThread : public Thread
+{
+ ThreadSafeValue<sal_Int32> m_aFlag;
+public:
+ sal_Int32 getValue() { return m_aFlag.getValue(); }
+
+ virtual void SAL_CALL suspend()
+ {
+ m_aFlag.acquire();
+ ::osl::Thread::suspend();
+ m_aFlag.release();
+ }
+protected:
+ void SAL_CALL run()
+ {
+ while (m_aFlag.getValue() < 10)
+ {
+ m_aFlag.addValue(1);
+ ThreadHelper::thread_sleep_tenth_sec(1);
+ // TimeValue nTV;
+ // nTV.Seconds = 1;
+ // nTV.Nanosec = 0;
+ // wait(nTV);
+ }
+ }
+ void SAL_CALL onTerminated()
+ {
+ t_print("normally terminate this thread %d!\n", getIdentifier());
+ }
+public:
+ ONoScheduleThread()
+ {
+ t_print("new thread id %d!\n", getIdentifier());
+ }
+ ~ONoScheduleThread()
+ {
+ if (isRunning())
+ {
+ t_print("error: not terminated.\n");
+ }
+ }
+
+};
+
+/**
+*/
+class OAddThread : public Thread
+{
+ ThreadSafeValue<sal_Int32> m_aFlag;
+public:
+ //oslThreadIdentifier m_id, m_CurId;
+ OAddThread(){}
+ sal_Int32 getValue() { return m_aFlag.getValue(); }
+
+ virtual void SAL_CALL suspend()
+ {
+ m_aFlag.acquire();
+ ::osl::Thread::suspend();
+ m_aFlag.release();
+ }
+protected:
+ void SAL_CALL run()
+ {
+ //if the thread should terminate, schedule return false
+ while (schedule() == sal_True)
+ {
+ m_aFlag.addValue(1);
+ }
+ }
+ void SAL_CALL onTerminated()
+ {
+ // t_print("normally terminate this thread %d!\n", getIdentifier());
+ }
+public:
+
+ ~OAddThread()
+ {
+ if (isRunning())
+ {
+ // t_print("error: not terminated.\n");
+ }
+ }
+
+};
+
+namespace osl_Thread
+{
+
+ void resumeAndWaitThread(Thread* _pThread)
+ {
+ // This functions starts a thread, wait a second and suspends the thread
+ // Due to the fact, that a suspend and never run thread never really exists.
+
+ // Note: on UNX, after createSuspended, and then terminate the thread, it performs well;
+ // while on Windows, after createSuspended, the thread can not terminate, wait endlessly,
+ // so here call resume at first, then call terminate.
+#ifdef WNT
+ t_print("resumeAndWaitThread\n");
+ _pThread->resume();
+ ThreadHelper::thread_sleep_tenth_sec(1);
+#else
+ _pThread->resume();
+#endif
+ // ThreadHelper::thread_sleep_tenth_sec(1);
+ // _pThread->suspend();
+ // ThreadHelper::thread_sleep_tenth_sec(1);
+ }
+
+ // kill a running thread and join it, if it has terminated, do nothing
+ void termAndJoinThread(Thread* _pThread)
+ {
+ _pThread->terminate();
+
+// LLA: Windows feature???, a suspended thread can not terminated, so we have to weak it up
+#ifdef WNT
+ _pThread->resume();
+ ThreadHelper::thread_sleep_tenth_sec(1);
+#endif
+ t_print("#wait for join.\n");
+ _pThread->join();
+ }
+/** Test of the osl::Thread::create method
+ */
+
+ class create : public CppUnit::TestFixture
+ {
+ public:
+
+ // initialise your test code values here.
+ void setUp()
+ {
+ }
+
+ void tearDown()
+ {
+ }
+
+ /** Simple create a thread.
+
+ Create a simple thread, it just does add 1 to value(which initialized 0),
+ if the thread run, the value should be 1.
+ */
+ void create_001()
+ {
+ myThread* newthread = new myThread();
+ sal_Bool bRes = newthread->create();
+ CPPUNIT_ASSERT_MESSAGE("Can not creates a new thread!\n", bRes == sal_True );
+
+ ThreadHelper::thread_sleep_tenth_sec(1); // wait short
+ sal_Bool isRunning = newthread->isRunning(); // check if thread is running
+ /// wait for the new thread to assure it has run
+ ThreadHelper::thread_sleep_tenth_sec(3);
+ sal_Int32 nValue = newthread->getValue();
+ /// to assure the new thread has terminated
+ termAndJoinThread(newthread);
+ delete newthread;
+
+ t_print(" nValue = %d\n", nValue);
+ t_print("isRunning = %d\n", isRunning);
+
+ CPPUNIT_ASSERT_MESSAGE(
+ "Creates a new thread",
+ nValue >= 1 && isRunning == sal_True
+ );
+
+ }
+
+ /** only one running thread per instance, return false if create secondly
+ */
+ void create_002()
+ {
+ myThread* newthread = new myThread();
+ sal_Bool res1 = newthread->create();
+ sal_Bool res2 = newthread->create();
+ t_print("In non pro, an assertion should occured. This behaviour is right.\n");
+ termAndJoinThread(newthread);
+ delete newthread;
+
+ CPPUNIT_ASSERT_MESSAGE(
+ "Creates a new thread: can not create two threads per instance",
+ res1 && !res2
+ );
+
+ }
+
+ CPPUNIT_TEST_SUITE(create);
+ CPPUNIT_TEST(create_001);
+ CPPUNIT_TEST(create_002);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class create
+
+
+
+ /** Test of the osl::Thread::createSuspended method
+ */
+ class createSuspended : public CppUnit::TestFixture
+ {
+ public:
+ // initialise your test code values here.
+ void setUp()
+ {
+ }
+
+ void tearDown()
+ {
+ }
+
+ /** Create a suspended thread, use the same class as create_001
+
+ after create, wait enough time, check the value, if it's still the initial value, pass
+ */
+ void createSuspended_001()
+ {
+ myThread* newthread = new myThread();
+ sal_Bool bRes = newthread->createSuspended();
+ CPPUNIT_ASSERT_MESSAGE("Can not creates a new thread!", bRes == sal_True );
+
+ ThreadHelper::thread_sleep_tenth_sec(1);
+ sal_Bool isRunning = newthread->isRunning();
+ ThreadHelper::thread_sleep_tenth_sec(3);
+ sal_Int32 nValue = newthread->getValue();
+
+ resumeAndWaitThread(newthread);
+
+ termAndJoinThread(newthread);
+ delete newthread;
+
+ CPPUNIT_ASSERT_MESSAGE(
+ "Creates a new suspended thread",
+ nValue == 0 && isRunning
+ );
+ }
+
+ void createSuspended_002()
+ {
+ myThread* newthread = new myThread();
+ sal_Bool res1 = newthread->createSuspended();
+ sal_Bool res2 = newthread->createSuspended();
+
+ resumeAndWaitThread(newthread);
+
+ termAndJoinThread(newthread);
+
+ delete newthread;
+
+ CPPUNIT_ASSERT_MESSAGE(
+ "Creates a new thread: can not create two threads per instance",
+ res1 && !res2
+ );
+ }
+
+ CPPUNIT_TEST_SUITE(createSuspended);
+ CPPUNIT_TEST(createSuspended_001);
+ // LLA: Deadlocked!!!
+ CPPUNIT_TEST(createSuspended_002);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class createSuspended
+
+ /** when the count value equal to or more than 3, suspend the thread.
+ */
+ void suspendCountThread(OCountThread* _pCountThread)
+ {
+ sal_Int32 nValue = 0;
+ while (1)
+ {
+ nValue = _pCountThread->getValue();
+ if (nValue >= 3)
+ {
+ _pCountThread->suspend();
+ break;
+ }
+ }
+ }
+
+ /** Test of the osl::Thread::suspend method
+ */
+ class suspend : public CppUnit::TestFixture
+ {
+ public:
+ // initialise your test code values here.
+ void setUp()
+ {
+ }
+
+ void tearDown()
+ {
+ }
+
+ /** Use a thread which has a flag added 1 every second
+
+ ALGORITHM:
+ create the thread, after running special time, record value of flag, then suspend it,
+ wait a long time, check the flag, if it remains unchanged during suspending
+ */
+ void suspend_001()
+ {
+ OCountThread* aCountThread = new OCountThread();
+ sal_Bool bRes = aCountThread->create();
+ CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
+ // the thread run for some seconds, but not terminate
+ suspendCountThread( aCountThread );
+
+ // the value just after calling suspend
+ sal_Int32 nValue = aCountThread->getValue(); // (2)
+
+ ThreadHelper::thread_sleep_tenth_sec(3);
+
+ // the value after waiting 3 seconds
+ sal_Int32 nLaterValue = aCountThread->getValue(); // (3)
+
+ resumeAndWaitThread(aCountThread);
+ termAndJoinThread(aCountThread);
+ delete aCountThread;
+
+ CPPUNIT_ASSERT_MESSAGE(
+ "Suspend the thread",
+ bRes == sal_True && nValue == nLaterValue
+ );
+
+ }
+ /** suspend a thread in it's worker-function, the ALGORITHM is same as suspend_001
+ reason of deadlocked I think: no schedule can schedule other threads to go on excuting
+ */
+ void suspend_002()
+ {
+ OSuspendThread* aThread = new OSuspendThread();
+ sal_Bool bRes = aThread->create();
+ CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
+ // first the thread run for some seconds, but not terminate
+ sal_Int32 nValue = 0;
+ //while (1)
+ //{
+ ThreadHelper::thread_sleep_tenth_sec(3);
+ nValue = aThread->getValue(); // (1)
+ t_print(" getValue is %d !", nValue );
+ if (nValue >= 2)
+ {
+ aThread->setSuspend();
+ //break;
+ }
+ //}
+ t_print(" after while!");
+ // the value just after calling suspend
+ nValue = aThread->getValue(); // (2)
+
+ ThreadHelper::thread_sleep_tenth_sec(3);
+ t_print(" after sleep!");
+ // the value after waiting 3 seconds
+ sal_Int32 nLaterValue = aThread->getValue(); // (3)
+
+ //resumeAndWaitThread(aThread);
+ aThread->resume();
+ termAndJoinThread(aThread);
+ delete aThread;
+
+ CPPUNIT_ASSERT_MESSAGE(
+ "Suspend the thread",
+ bRes == sal_True && nValue == nLaterValue
+ );
+ }
+
+ CPPUNIT_TEST_SUITE(suspend);
+ CPPUNIT_TEST(suspend_001);
+ // LLA: Deadlocked!!!
+ // CPPUNIT_TEST(createSuspended_002);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class suspend
+
+ /** Test of the osl::Thread::resume method
+ */
+ class resume : public CppUnit::TestFixture
+ {
+ public:
+ // initialise your test code values here.
+ void setUp()
+ {
+ }
+
+ void tearDown()
+ {
+ }
+
+ /** check if the thread run samely as usual after suspend and resume
+
+ ALGORITHM:
+ compare the values before and after suspend, they should be same,
+ then compare values before and after resume, the difference should be same as the sleep seconds number
+ */
+ void resume_001()
+ {
+ OCountThread* pCountThread = new OCountThread();
+ sal_Bool bRes = pCountThread->create();
+ CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
+
+ suspendCountThread(pCountThread);
+
+ sal_Int32 nSuspendValue = pCountThread->getValue(); // (2)
+ // suspend for 3 seconds
+ ThreadHelper::thread_sleep_tenth_sec(3);
+ pCountThread->resume();
+
+ ThreadHelper::thread_sleep_tenth_sec(3);
+ sal_Int32 nResumeValue = pCountThread->getValue();
+
+ ThreadHelper::thread_sleep_tenth_sec(3);
+ sal_Int32 nLaterValue = pCountThread->getValue();
+
+ termAndJoinThread(pCountThread);
+ delete pCountThread;
+
+ t_print("SuspendValue: %d\n", nSuspendValue);
+ t_print("ResumeValue: %d\n", nResumeValue);
+ t_print("LaterValue: %d\n", nLaterValue);
+
+ /* LLA: this assumption is no longer relevant: nResumeValue == nSuspendValue && */
+ CPPUNIT_ASSERT_MESSAGE(
+ "Suspend then resume the thread",
+ nLaterValue >= 9 &&
+ nResumeValue > nSuspendValue &&
+ nLaterValue > nResumeValue
+ );
+
+ }
+
+ /** Create a suspended thread then resume, check if the thread has run
+ */
+ void resume_002()
+ {
+ myThread* newthread = new myThread();
+ sal_Bool bRes = newthread->createSuspended();
+ CPPUNIT_ASSERT_MESSAGE ( "Can't create thread!", bRes == sal_True );
+
+ newthread->resume();
+ ThreadHelper::thread_sleep_tenth_sec(2);
+ sal_Int32 nValue = newthread->getValue();
+
+ termAndJoinThread(newthread);
+ delete newthread;
+
+ t_print(" nValue = %d\n", nValue);
+
+ CPPUNIT_ASSERT_MESSAGE(
+ "Creates a suspended thread, then resume",
+ nValue >= 1
+ );
+ }
+
+ CPPUNIT_TEST_SUITE(resume);
+ CPPUNIT_TEST(resume_001);
+ CPPUNIT_TEST(resume_002);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class resume
+
+ /** Test of the osl::Thread::terminate method
+ */
+ class terminate : public CppUnit::TestFixture
+ {
+ public:
+ // initialise your test code values here.
+ void setUp()
+ {
+ }
+
+ void tearDown()
+ {
+ }
+
+ /** Check after call terminate if the running thread running go on executing
+
+ ALGORITHM:
+ before and after call terminate, the values should be the same
+ */
+ void terminate_001()
+ {
+ OCountThread* aCountThread = new OCountThread();
+ sal_Bool bRes = aCountThread->create();
+ CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
+
+ ThreadHelper::thread_sleep_tenth_sec(2);
+ sal_Int32 nValue = aCountThread->getValue();
+ aCountThread->terminate();
+ ThreadHelper::thread_sleep_tenth_sec(2);
+ sal_Int32 nLaterValue = aCountThread->getValue();
+
+ // isRunning should be false after terminate
+ sal_Bool isRunning = aCountThread->isRunning();
+ aCountThread->join();
+ delete aCountThread;
+
+ t_print(" nValue = %d\n", nValue);
+ t_print("nLaterValue = %d\n", nLaterValue);
+
+ CPPUNIT_ASSERT_MESSAGE(
+ "Terminate the thread",
+ isRunning == sal_False && nLaterValue >= nValue
+ );
+ }
+ /** Check if a suspended thread will terminate after call terminate, different on w32 and on UNX
+ */
+ void terminate_002()
+ {
+ OCountThread* aCountThread = new OCountThread();
+ sal_Bool bRes = aCountThread->create();
+ CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
+
+ ThreadHelper::thread_sleep_tenth_sec(1);
+ suspendCountThread(aCountThread);
+ sal_Int32 nValue = aCountThread->getValue();
+
+ // seems a suspended thread can not be terminated on W32, while on Solaris can
+ resumeAndWaitThread(aCountThread);
+
+ ThreadHelper::thread_sleep_tenth_sec(2);
+
+ termAndJoinThread(aCountThread);
+ sal_Int32 nLaterValue = aCountThread->getValue();
+ delete aCountThread;
+
+ t_print(" nValue = %d\n", nValue);
+ t_print("nLaterValue = %d\n", nLaterValue);
+
+ CPPUNIT_ASSERT_MESSAGE(
+ "Suspend then resume the thread",
+ nLaterValue > nValue );
+ }
+
+ CPPUNIT_TEST_SUITE(terminate);
+ CPPUNIT_TEST(terminate_001);
+ CPPUNIT_TEST(terminate_002);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class terminate
+
+ /** Test of the osl::Thread::join method
+ */
+ class join : public CppUnit::TestFixture
+ {
+ public:
+ // initialise your test code values here.
+ void setUp()
+ {
+ }
+
+ void tearDown()
+ {
+ }
+
+ /** Check after call terminate if the thread running function will not go on executing
+
+ the next statement after join will not exec before the thread terminate
+ ALGORITHM:
+ recode system time at the beginning of the thread run, call join, then record system time again,
+ the difference of the two time should be equal or more than 20 seconds, the CountThead normally terminate
+ */
+ void join_001()
+ {
+ OCountThread *aCountThread = new OCountThread();
+ sal_Bool bRes = aCountThread->create();
+ CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
+
+ StopWatch aStopWatch;
+ aStopWatch.start();
+ // TimeValue aTimeVal_befor;
+ // osl_getSystemTime( &aTimeVal_befor );
+ //t_print("#join:the system time is %d,%d\n", pTimeVal_befor->Seconds,pTimeVal_befor->Nanosec);
+
+ aCountThread->join();
+
+ //the below line will be executed after aCountThread terminate
+ // TimeValue aTimeVal_after;
+ // osl_getSystemTime( &aTimeVal_after );
+ aStopWatch.stop();
+ // sal_uInt32 nSec = aTimeVal_after.Seconds - aTimeVal_befor.Seconds;
+ double nSec = aStopWatch.getSeconds();
+ t_print("join_001 nSec=%f\n", nSec);
+ delete aCountThread;
+
+ CPPUNIT_ASSERT_MESSAGE(
+ "Join the thread: after the thread terminate",
+ nSec >= 2
+ );
+
+ }
+ /** after terminated by another thread, join exited immediately
+
+ ALGORITHM:
+ terminate the thread when value>=3, call join, check the beginning time and time after join,
+ the difference should be 3 seconds, join costs little time
+ */
+ void join_002()
+ {
+ OCountThread *aCountThread = new OCountThread();
+ sal_Bool bRes = aCountThread->create();
+ CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
+
+ //record the time when the running begin
+ // TimeValue aTimeVal_befor;
+ // osl_getSystemTime( &aTimeVal_befor );
+ StopWatch aStopWatch;
+ aStopWatch.start();
+
+ ThreadHelper::thread_sleep_tenth_sec(10);
+ termAndJoinThread(aCountThread);
+
+ //the below line will be executed after aCountThread terminate
+ // TimeValue aTimeVal_after;
+ // osl_getSystemTime( &aTimeVal_after );
+ // sal_uInt32 nSec = aTimeVal_after.Seconds - aTimeVal_befor.Seconds;
+ aStopWatch.stop();
+ double nSec = aStopWatch.getSeconds();
+ t_print("join_002 nSec=%f\n", nSec);
+
+ delete aCountThread;
+ CPPUNIT_ASSERT_MESSAGE(
+ "Join the thread: after thread terminate by another thread",
+ nSec >= 1
+ );
+ }
+
+ CPPUNIT_TEST_SUITE(join);
+ CPPUNIT_TEST(join_001);
+ CPPUNIT_TEST(join_002);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class join
+
+ /** Test of the osl::Thread::isRunning method
+ */
+ class isRunning : public CppUnit::TestFixture
+ {
+ public:
+ // initialise your test code values here.
+ void setUp()
+ {
+ }
+
+ void tearDown()
+ {
+ }
+
+ /**
+ */
+ void isRunning_001()
+ {
+ OCountThread *aCountThread = new OCountThread();
+ sal_Bool bRes = aCountThread->create();
+ CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
+
+ sal_Bool bRun = aCountThread->isRunning();
+
+ ThreadHelper::thread_sleep_tenth_sec(2);
+ termAndJoinThread(aCountThread);
+ sal_Bool bTer = aCountThread->isRunning();
+ delete aCountThread;
+
+ CPPUNIT_ASSERT_MESSAGE(
+ "Test isRunning",
+ bRun == sal_True && bTer == sal_False
+ );
+ }
+ /** check the value of isRunning when suspending and after resume
+ */
+ void isRunning_002()
+ {
+ OCountThread *aCountThread = new OCountThread();
+ sal_Bool bRes = aCountThread->create();
+ CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
+
+ // sal_Bool bRunning = aCountThread->isRunning();
+ // sal_Int32 nValue = 0;
+ suspendCountThread(aCountThread);
+
+ sal_Bool bRunning_sup = aCountThread->isRunning();
+ ThreadHelper::thread_sleep_tenth_sec(2);
+ aCountThread->resume();
+ ThreadHelper::thread_sleep_tenth_sec(2);
+ sal_Bool bRunning_res = aCountThread->isRunning();
+ termAndJoinThread(aCountThread);
+ sal_Bool bRunning_ter = aCountThread->isRunning();
+ delete aCountThread;
+
+ CPPUNIT_ASSERT_MESSAGE(
+ "Test isRunning",
+ bRes == sal_True &&
+ bRunning_sup == sal_True &&
+ bRunning_res == sal_True &&
+ bRunning_ter == sal_False
+ );
+
+ }
+
+ CPPUNIT_TEST_SUITE(isRunning);
+ CPPUNIT_TEST(isRunning_001);
+ CPPUNIT_TEST(isRunning_002);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class isRunning
+
+
+ /// check osl::Thread::setPriority
+ class setPriority : public CppUnit::TestFixture
+ {
+ public:
+ // initialise your test code values here.
+ void setUp()
+ {
+ }
+
+ void tearDown()
+ {
+ }
+
+ // insert your test code here.
+ rtl::OString getPrioName(oslThreadPriority _aPriority)
+ {
+ rtl::OString sPrioStr;
+ switch (_aPriority)
+ {
+ case osl_Thread_PriorityHighest:
+ sPrioStr = "Highest";
+ break;
+
+ case osl_Thread_PriorityAboveNormal:
+ sPrioStr = "AboveNormal";
+
+ case osl_Thread_PriorityNormal:
+ sPrioStr = "Normal";
+
+ case osl_Thread_PriorityBelowNormal:
+ sPrioStr = "BelowNormal";
+ break;
+
+ case osl_Thread_PriorityLowest:
+ sPrioStr = "Lowest";
+ break;
+ default:
+ sPrioStr = "unknown";
+ }
+ return sPrioStr;
+ }
+
+
+ /** 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 check2Threads(oslThreadPriority _aPriority)
+ {
+ // initial 5 threads with different priorities
+ OAddThread* pThread = new OAddThread();
+ OAddThread* p2Thread = new OAddThread();
+
+ //Create them and start running at the same time
+ pThread->create();
+ pThread->setPriority(_aPriority);
+ p2Thread->create();
+ p2Thread->setPriority(_aPriority);
+
+ ThreadHelper::thread_sleep_tenth_sec(5);
+
+ pThread->terminate();
+ p2Thread->terminate();
+
+ sal_Int32 nValueNormal = 0;
+ nValueNormal = pThread->getValue();
+
+ sal_Int32 nValueNormal2 = 0;
+ nValueNormal2 = p2Thread->getValue();
+
+ rtl::OString sPrio = getPrioName(_aPriority);
+ t_print("After 10 tenth seconds\n");
+
+ t_print("nValue in %s Prio Thread is %d\n",sPrio.getStr(), nValueNormal);
+ t_print("nValue in %s Prio Thread is %d\n", sPrio.getStr(), nValueNormal2);
+
+ // ThreadHelper::thread_sleep_tenth_sec(1);
+ pThread->join();
+ p2Thread->join();
+
+ delete pThread;
+ delete p2Thread;
+
+ sal_Int32 nDelta = abs(nValueNormal - nValueNormal2);
+ double nQuotient = std::max(nValueNormal, nValueNormal2);
+ CPPUNIT_ASSERT_MESSAGE(
+ "Quotient is zero, which means, there exist no right values.",
+ nQuotient != 0
+ );
+ double nDeltaPercent = nDelta / nQuotient * 100;
+
+ t_print("Delta value %d, percent %f\n",nDelta, nDeltaPercent);
+
+ // LLA: it's not a bug if the current OS is not able to handle thread scheduling right and good.
+ // like Windows XP
+ // LLA: CPPUNIT_ASSERT_MESSAGE(
+ // LLA: "Run 2 normal threads, the count diff more than 5 percent.",
+ // LLA: nDeltaPercent <= 5
+ // LLA: );
+ }
+
+ void setPriority_001_1()
+ {
+ check2Threads(osl_Thread_PriorityHighest);
+ }
+ void setPriority_001_2()
+ {
+ check2Threads(osl_Thread_PriorityAboveNormal);
+ }
+ void setPriority_001_3()
+ {
+ check2Threads(osl_Thread_PriorityNormal);
+ }
+ void setPriority_001_4()
+ {
+ check2Threads(osl_Thread_PriorityBelowNormal);
+ }
+ void setPriority_001_5()
+ {
+ check2Threads(osl_Thread_PriorityLowest);
+ }
+
+ void setPriority_002()
+ {
+ // initial 5 threads with different priorities
+
+ OAddThread aHighestThread;
+ OAddThread aAboveNormalThread;
+ OAddThread aNormalThread;
+ //OAddThread *aBelowNormalThread = new OAddThread();
+ //OAddThread *aLowestThread = new OAddThread();
+
+ //Create them and start running at the same time
+ aHighestThread.createSuspended();
+ aHighestThread.setPriority(osl_Thread_PriorityHighest);
+
+ aAboveNormalThread.createSuspended();
+ aAboveNormalThread.setPriority(osl_Thread_PriorityAboveNormal);
+
+ aNormalThread.createSuspended();
+ aNormalThread.setPriority(osl_Thread_PriorityNormal);
+ /*aBelowNormalThread->create();
+ aBelowNormalThread->setPriority(osl_Thread_PriorityBelowNormal);
+ aLowestThread->create();
+ aLowestThread->setPriority(osl_Thread_PriorityLowest);
+ */
+
+ aHighestThread.resume();
+ aAboveNormalThread.resume();
+ aNormalThread.resume();
+
+ ThreadHelper::thread_sleep_tenth_sec(5);
+
+ aHighestThread.suspend();
+ aAboveNormalThread.suspend();
+ aNormalThread.suspend();
+
+ termAndJoinThread(&aNormalThread);
+ termAndJoinThread(&aAboveNormalThread);
+ termAndJoinThread(&aHighestThread);
+ //aBelowNormalThread->terminate();
+ //aLowestThread->terminate();
+
+ sal_Int32 nValueHighest = 0;
+ nValueHighest = aHighestThread.getValue();
+
+ sal_Int32 nValueAboveNormal = 0;
+ nValueAboveNormal = aAboveNormalThread.getValue();
+
+ sal_Int32 nValueNormal = 0;
+ nValueNormal = aNormalThread.getValue();
+
+ // sal_Int32 nValueBelowNormal = 0;
+ //nValueBelowNormal = aBelowNormalThread->getValue();
+ // sal_Int32 nValueLowest = 0;
+ //nValueLowest = aLowestThread->getValue();
+ t_print("After 10 tenth seconds\n");
+ t_print("nValue in Highest Prio Thread is %d\n",nValueHighest);
+ t_print("nValue in AboveNormal Prio Thread is %d\n",nValueAboveNormal);
+ t_print("nValue in Normal Prio Thread is %d\n",nValueNormal);
+
+ // LLA: this is not a save test, so we only check if all values not zero
+ // LLA: CPPUNIT_ASSERT_MESSAGE(
+ // LLA: "SetPriority",
+ // LLA: nValueHighest >= nValueAboveNormal &&
+ // LLA: nValueAboveNormal >= nValueNormal &&
+ // LLA: nValueNormal > 0
+ // LLA: );
+
+// LLA: windows let starve threads with lower priority
+#ifndef WNT
+ CPPUNIT_ASSERT_MESSAGE(
+ "SetPriority",
+ nValueHighest > 0 &&
+ nValueAboveNormal > 0 &&
+ nValueNormal > 0
+ );
+#endif
+ }
+
+ void setPriority_003()
+ {
+ // initial 5 threads with different priorities
+ OAddThread *pHighestThread = new OAddThread();
+ OAddThread *pAboveNormalThread = new OAddThread();
+ OAddThread *pNormalThread = new OAddThread();
+ OAddThread *pBelowNormalThread = new OAddThread();
+ OAddThread *pLowestThread = new OAddThread();
+
+ //Create them and start running at the same time
+ pHighestThread->createSuspended();
+ pHighestThread->setPriority(osl_Thread_PriorityHighest);
+
+ pAboveNormalThread->createSuspended();
+ pAboveNormalThread->setPriority(osl_Thread_PriorityAboveNormal);
+
+ pNormalThread->createSuspended();
+ pNormalThread->setPriority(osl_Thread_PriorityNormal);
+
+ pBelowNormalThread->createSuspended();
+ pBelowNormalThread->setPriority(osl_Thread_PriorityBelowNormal);
+
+ pLowestThread->createSuspended();
+ pLowestThread->setPriority(osl_Thread_PriorityLowest);
+
+ pHighestThread->resume();
+ pAboveNormalThread->resume();
+ pNormalThread->resume();
+ pBelowNormalThread->resume();
+ pLowestThread->resume();
+
+ ThreadHelper::thread_sleep_tenth_sec(5);
+
+ pHighestThread->suspend();
+ pAboveNormalThread->suspend();
+ pNormalThread->suspend();
+ pBelowNormalThread->suspend();
+ pLowestThread->suspend();
+
+ termAndJoinThread(pHighestThread);
+ termAndJoinThread(pAboveNormalThread);
+ termAndJoinThread(pNormalThread);
+ termAndJoinThread(pBelowNormalThread);
+ termAndJoinThread(pLowestThread);
+
+ sal_Int32 nValueHighest = 0;
+ nValueHighest = pHighestThread->getValue();
+
+ sal_Int32 nValueAboveNormal = 0;
+ nValueAboveNormal = pAboveNormalThread->getValue();
+
+ sal_Int32 nValueNormal = 0;
+ nValueNormal = pNormalThread->getValue();
+
+ sal_Int32 nValueBelowNormal = 0;
+ nValueBelowNormal = pBelowNormalThread->getValue();
+
+ sal_Int32 nValueLowest = 0;
+ nValueLowest = pLowestThread->getValue();
+
+ t_print("After 10 tenth seconds\n");
+ t_print("nValue in Highest Prio Thread is %d\n",nValueHighest);
+ t_print("nValue in AboveNormal Prio Thread is %d\n",nValueAboveNormal);
+ t_print("nValue in Normal Prio Thread is %d\n",nValueNormal);
+ t_print("nValue in BelowNormal Prio Thread is %d\n",nValueBelowNormal);
+ t_print("nValue in Lowest Prio Thread is %d\n",nValueLowest);
+
+ delete pHighestThread;
+ delete pAboveNormalThread;
+ delete pNormalThread;
+ delete pBelowNormalThread;
+ delete pLowestThread;
+
+ // LLA: this is not a save test, so we only check if all values not zero
+ // LLA: CPPUNIT_ASSERT_MESSAGE(
+ // LLA: "SetPriority",
+ // LLA: nValueHighest > nValueAboveNormal &&
+ // LLA: nValueAboveNormal > nValueNormal &&
+ // LLA: nValueNormal > nValueBelowNormal &&
+ // LLA: nValueBelowNormal > nValueLowest &&
+ // LLA: nValueLowest > 0
+ // LLA: );
+
+// LLA: windows let starve threads with lower priority
+#ifndef WNT
+ CPPUNIT_ASSERT_MESSAGE(
+ "SetPriority",
+ nValueHighest > 0 &&
+ nValueAboveNormal > 0 &&
+ nValueNormal > 0 &&
+ nValueBelowNormal > 0 &&
+ nValueLowest > 0
+ );
+#endif
+ }
+
+ void setPriority_004()
+ {
+ // initial 5 threads with different priorities
+ // OAddThread *pHighestThread = new OAddThread();
+ OAddThread *pAboveNormalThread = new OAddThread();
+ OAddThread *pNormalThread = new OAddThread();
+ OAddThread *pBelowNormalThread = new OAddThread();
+ OAddThread *pLowestThread = new OAddThread();
+
+ //Create them and start running at the same time
+ // pHighestThread->createSuspended();
+ // pHighestThread->setPriority(osl_Thread_PriorityHighest);
+
+ pAboveNormalThread->createSuspended();
+ pAboveNormalThread->setPriority(osl_Thread_PriorityAboveNormal);
+
+ pNormalThread->createSuspended();
+ pNormalThread->setPriority(osl_Thread_PriorityNormal);
+
+ pBelowNormalThread->createSuspended();
+ pBelowNormalThread->setPriority(osl_Thread_PriorityBelowNormal);
+
+ pLowestThread->createSuspended();
+ pLowestThread->setPriority(osl_Thread_PriorityLowest);
+
+ // pHighestThread->resume();
+ pAboveNormalThread->resume();
+ pNormalThread->resume();
+ pBelowNormalThread->resume();
+ pLowestThread->resume();
+
+ ThreadHelper::thread_sleep_tenth_sec(5);
+
+ // pHighestThread->suspend();
+ pAboveNormalThread->suspend();
+ pNormalThread->suspend();
+ pBelowNormalThread->suspend();
+ pLowestThread->suspend();
+
+ // termAndJoinThread(pHighestThread);
+ termAndJoinThread(pAboveNormalThread);
+ termAndJoinThread(pNormalThread);
+ termAndJoinThread(pBelowNormalThread);
+ termAndJoinThread(pLowestThread);
+
+ // sal_Int32 nValueHighest = 0;
+ // nValueHighest = pHighestThread->getValue();
+
+ sal_Int32 nValueAboveNormal = 0;
+ nValueAboveNormal = pAboveNormalThread->getValue();
+
+ sal_Int32 nValueNormal = 0;
+ nValueNormal = pNormalThread->getValue();
+
+ sal_Int32 nValueBelowNormal = 0;
+ nValueBelowNormal = pBelowNormalThread->getValue();
+
+ sal_Int32 nValueLowest = 0;
+ nValueLowest = pLowestThread->getValue();
+
+ t_print("After 5 tenth seconds\n");
+ // t_print("nValue in Highest Prio Thread is %d\n",nValueHighest);
+ t_print("nValue in AboveNormal Prio Thread is %d\n",nValueAboveNormal);
+ t_print("nValue in Normal Prio Thread is %d\n",nValueNormal);
+ t_print("nValue in BelowNormal Prio Thread is %d\n",nValueBelowNormal);
+ t_print("nValue in Lowest Prio Thread is %d\n",nValueLowest);
+
+ // delete pHighestThread;
+ delete pAboveNormalThread;
+ delete pNormalThread;
+ delete pBelowNormalThread;
+ delete pLowestThread;
+
+ // LLA: this is not a save test, so we only check if all values not zero
+ // LLA: CPPUNIT_ASSERT_MESSAGE(
+ // LLA: "SetPriority",
+ // LLA: nValueHighest > nValueAboveNormal &&
+ // LLA: nValueAboveNormal > nValueNormal &&
+ // LLA: nValueNormal > nValueBelowNormal &&
+ // LLA: nValueBelowNormal > nValueLowest &&
+ // LLA: nValueLowest > 0
+ // LLA: );
+
+// LLA: windows let starve threads with lower priority
+#ifndef WNT
+ CPPUNIT_ASSERT_MESSAGE(
+ "SetPriority",
+ /* nValueHighest > 0 && */
+ nValueAboveNormal > 0 &&
+ nValueNormal > 0 &&
+ nValueBelowNormal > 0 &&
+ nValueLowest > 0
+ );
+#endif
+ }
+ void setPriority_005()
+ {
+ // initial 5 threads with different priorities
+ // OAddThread *pHighestThread = new OAddThread();
+ // OAddThread *pAboveNormalThread = new OAddThread();
+ OAddThread *pNormalThread = new OAddThread();
+ OAddThread *pBelowNormalThread = new OAddThread();
+ OAddThread *pLowestThread = new OAddThread();
+
+ //Create them and start running at the same time
+ // pHighestThread->createSuspended();
+ // pHighestThread->setPriority(osl_Thread_PriorityHighest);
+
+ // pAboveNormalThread->createSuspended();
+ // pAboveNormalThread->setPriority(osl_Thread_PriorityAboveNormal);
+
+ pNormalThread->createSuspended();
+ pNormalThread->setPriority(osl_Thread_PriorityNormal);
+
+ pBelowNormalThread->createSuspended();
+ pBelowNormalThread->setPriority(osl_Thread_PriorityBelowNormal);
+
+ pLowestThread->createSuspended();
+ pLowestThread->setPriority(osl_Thread_PriorityLowest);
+
+ // pHighestThread->resume();
+ // pAboveNormalThread->resume();
+ pNormalThread->resume();
+ pBelowNormalThread->resume();
+ pLowestThread->resume();
+
+ ThreadHelper::thread_sleep_tenth_sec(5);
+
+ // pHighestThread->suspend();
+ // pAboveNormalThread->suspend();
+ pNormalThread->suspend();
+ pBelowNormalThread->suspend();
+ pLowestThread->suspend();
+
+ // termAndJoinThread(pHighestThread);
+ // termAndJoinThread(pAboveNormalThread);
+ termAndJoinThread(pNormalThread);
+ termAndJoinThread(pBelowNormalThread);
+ termAndJoinThread(pLowestThread);
+
+ // sal_Int32 nValueHighest = 0;
+ // nValueHighest = pHighestThread->getValue();
+
+ // sal_Int32 nValueAboveNormal = 0;
+ // nValueAboveNormal = pAboveNormalThread->getValue();
+
+ sal_Int32 nValueNormal = 0;
+ nValueNormal = pNormalThread->getValue();
+
+ sal_Int32 nValueBelowNormal = 0;
+ nValueBelowNormal = pBelowNormalThread->getValue();
+
+ sal_Int32 nValueLowest = 0;
+ nValueLowest = pLowestThread->getValue();
+
+ t_print("After 5 tenth seconds\n");
+ // t_print("nValue in Highest Prio Thread is %d\n",nValueHighest);
+ // t_print("nValue in AboveNormal Prio Thread is %d\n",nValueAboveNormal);
+ t_print("nValue in Normal Prio Thread is %d\n",nValueNormal);
+ t_print("nValue in BelowNormal Prio Thread is %d\n",nValueBelowNormal);
+ t_print("nValue in Lowest Prio Thread is %d\n",nValueLowest);
+
+ // delete pHighestThread;
+ // delete pAboveNormalThread;
+ delete pNormalThread;
+ delete pBelowNormalThread;
+ delete pLowestThread;
+
+ // LLA: this is not a save test, so we only check if all values not zero
+ // LLA: CPPUNIT_ASSERT_MESSAGE(
+ // LLA: "SetPriority",
+ // LLA: nValueHighest > nValueAboveNormal &&
+ // LLA: nValueAboveNormal > nValueNormal &&
+ // LLA: nValueNormal > nValueBelowNormal &&
+ // LLA: nValueBelowNormal > nValueLowest &&
+ // LLA: nValueLowest > 0
+ // LLA: );
+
+// LLA: windows let starve threads with lower priority
+#ifndef WNT
+ CPPUNIT_ASSERT_MESSAGE(
+ "SetPriority",
+ /* nValueHighest > 0 && */
+ /* nValueAboveNormal > 0 && */
+ nValueNormal > 0 &&
+ nValueBelowNormal > 0 &&
+ nValueLowest > 0
+ );
+#endif
+ }
+
+
+ CPPUNIT_TEST_SUITE(setPriority);
+#ifndef SOLARIS
+ CPPUNIT_TEST(setPriority_002);
+ CPPUNIT_TEST(setPriority_003);
+ CPPUNIT_TEST(setPriority_004);
+ CPPUNIT_TEST(setPriority_005);
+#endif
+ CPPUNIT_TEST(setPriority_001_1);
+ CPPUNIT_TEST(setPriority_001_2);
+ CPPUNIT_TEST(setPriority_001_3);
+ CPPUNIT_TEST(setPriority_001_4);
+ CPPUNIT_TEST(setPriority_001_5);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class setPriority
+
+ /** Test of the osl::Thread::getPriority method
+ */
+ class getPriority : public CppUnit::TestFixture
+ {
+ public:
+ // initialise your test code values here.
+ void setUp()
+ {
+ }
+
+ void tearDown()
+ {
+ }
+
+ // insert your test code here.
+ void getPriority_001()
+ {
+ OAddThread *pHighestThread = new OAddThread();
+
+ //Create them and start running at the same time
+ pHighestThread->create();
+ pHighestThread->setPriority(osl_Thread_PriorityHighest);
+
+ oslThreadPriority aPriority = pHighestThread->getPriority();
+ termAndJoinThread(pHighestThread);
+ delete pHighestThread;
+
+ ThreadHelper::outputPriority(aPriority);
+
+// LLA: Priority settings may not work within some OS versions.
+#if ( defined WNT ) || ( defined SOLARIS )
+ CPPUNIT_ASSERT_MESSAGE(
+ "getPriority",
+ aPriority == osl_Thread_PriorityHighest
+ );
+#else
+// LLA: Linux
+// NO_PTHREAD_PRIORITY ???
+ CPPUNIT_ASSERT_MESSAGE(
+ "getPriority",
+ aPriority == osl_Thread_PriorityNormal
+ );
+#endif
+ }
+
+ void getPriority_002()
+ {
+
+ }
+
+ CPPUNIT_TEST_SUITE(getPriority);
+ CPPUNIT_TEST(getPriority_001);
+ CPPUNIT_TEST(getPriority_002);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class getPriority
+
+
+ class getIdentifier : public CppUnit::TestFixture
+ {
+ public:
+ // initialise your test code values here.
+ void setUp()
+ {
+ }
+
+ void tearDown()
+ {
+ }
+
+ // insert your test code here.
+ void getIdentifier_001()
+ {
+
+ }
+
+ void getIdentifier_002()
+ {
+
+ }
+
+ CPPUNIT_TEST_SUITE(getIdentifier);
+ CPPUNIT_TEST(getIdentifier_001);
+ CPPUNIT_TEST(getIdentifier_002);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class getIdentifier
+
+ /** Test of the osl::Thread::getCurrentIdentifier method
+ */
+ class getCurrentIdentifier : public CppUnit::TestFixture
+ {
+ public:
+ // initialise your test code values here.
+ void setUp()
+ {
+ }
+
+ void tearDown()
+ {
+ }
+
+ // insert your test code here.
+ void getCurrentIdentifier_001()
+ {
+ oslThreadIdentifier oId;
+ OCountThread* pCountThread = new OCountThread;
+ //OCountThread* pCountThread2 = new OCountThread;
+ pCountThread->create();
+ //pCountThread2->create();
+ pCountThread->setWait(3);
+ oId = Thread::getCurrentIdentifier();
+ oslThreadIdentifier oIdChild = pCountThread->getIdentifier();
+ //t_print("CurrentId is %ld, Child1 id is %ld, Child2 id is %ld\n",oId, oIdChild,pCountThread2->m_id );
+ termAndJoinThread(pCountThread);
+ delete pCountThread;
+ //termAndJoinThread(pCountThread2);
+ //delete pCountThread2;
+
+ CPPUNIT_ASSERT_MESSAGE(
+ "Get the identifier for the current active thread.",
+ oId != oIdChild
+ );
+
+ }
+
+ void getCurrentIdentifier_002()
+ {
+ }
+
+ CPPUNIT_TEST_SUITE(getCurrentIdentifier);
+ CPPUNIT_TEST(getCurrentIdentifier_001);
+ //CPPUNIT_TEST(getCurrentIdentifier_002);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class getCurrentIdentifier
+
+ /** Test of the osl::Thread::wait method
+ */
+ class wait : public CppUnit::TestFixture
+ {
+ public:
+ // initialise your test code values here.
+ void setUp()
+ {
+ }
+
+ void tearDown()
+ {
+ }
+
+ /** call wait in the run method
+
+ ALGORITHM:
+ tested thread wait nWaitSec seconds, main thread sleep (2) seconds,
+ then terminate the tested thread, due to the fact that the thread do a sleep(1) + wait(5)
+ it's finish after 6 seconds.
+ */
+ void wait_001()
+ {
+ OCountThread *aCountThread = new OCountThread();
+ sal_Int32 nWaitSec = 5;
+ aCountThread->setWait(nWaitSec);
+ // thread runs at least 5 seconds.
+ sal_Bool bRes = aCountThread->create();
+ CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
+
+ //record the time when the running begin
+ StopWatch aStopWatch;
+ aStopWatch.start();
+
+ // wait a little bit, to let the thread the time, to start
+ ThreadHelper::thread_sleep_tenth_sec( 4 );
+
+ // if wait works,
+ // this function returns, after 4 sec. later
+ termAndJoinThread(aCountThread);
+
+ // value should be one.
+ sal_Int32 nValue = aCountThread->getValue();
+
+ aStopWatch.stop();
+
+ // sal_uInt32 nSec = aTimeVal_after.Seconds - aTimeVal_befor.Seconds;
+ double nTenthSec = aStopWatch.getTenthSec();
+ double nSec = aStopWatch.getSeconds();
+ delete aCountThread;
+ t_print("nTenthSec = %f \n", nTenthSec);
+ t_print("nSec = %f \n", nSec);
+ t_print("nValue = %d \n", nValue);
+
+ CPPUNIT_ASSERT_MESSAGE(
+ "Wait: Blocks the calling thread for the given number of time.",
+ nTenthSec >= 5 && nValue == 1
+ );
+
+ }
+// LLA: wait_001 does the same.
+// LLA: /** wait then terminate the thread
+// LLA:
+// LLA: ALGORITHM:
+// LLA: wait nWaitSec seconds, and terminate when the wait does not finish
+// LLA: Windows & UNX: thread terminates immediatlly
+// LLA: */
+// LLA: void wait_002()
+// LLA: {
+// LLA: OCountThread aThread;
+// LLA:
+// LLA: sal_Int32 nWaitSec = 3;
+// LLA: aThread.setWait(nWaitSec);
+// LLA:
+// LLA: sal_Bool bRes = aThread.create();
+// LLA: CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
+// LLA:
+// LLA: StopWatch aStopWatch;
+// LLA: // TimeValue aTimeVal_befor;
+// LLA: // osl_getSystemTime( &aTimeVal_befor );
+// LLA: aStopWatch.start();
+// LLA:
+// LLA: termAndJoinThread(&aThread);
+// LLA: sal_Int32 nValue = aThread.getValue();
+// LLA:
+// LLA: // TimeValue aTimeVal_after;
+// LLA: // osl_getSystemTime( &aTimeVal_after );
+// LLA: aStopWatch.stop();
+// LLA: // sal_Int32 nSec = aTimeVal_after.Seconds - aTimeVal_befor.Seconds;
+// LLA: double nSec = aStopWatch.getSeconds();
+// LLA: t_print("sec=%f\n", nSec);
+// LLA: t_print("nValue = %d\n", nValue);
+// LLA:
+// LLA: CPPUNIT_ASSERT_MESSAGE(
+// LLA: "Wait: Blocks the calling thread for the given number of time.",
+// LLA: nSec < 1 && nValue == 0
+// LLA: );
+// LLA: }
+
+ CPPUNIT_TEST_SUITE(wait);
+ CPPUNIT_TEST(wait_001);
+ // LLA: CPPUNIT_TEST(wait_002);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class wait
+
+ /** osl::Thread::yield method: can not design good test scenario to test up to now
+ */
+ class yield : public CppUnit::TestFixture
+ {
+ public:
+ void setUp()
+ {
+ }
+
+ void tearDown()
+ {
+ }
+
+ // insert your test code here.
+ void yield_001()
+ {
+ }
+
+
+ CPPUNIT_TEST_SUITE(yield);
+ CPPUNIT_TEST(yield_001);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class yield
+
+ /** Test of the osl::Thread::schedule method
+ */
+ class schedule : public CppUnit::TestFixture
+ {
+ public:
+ // initialise your test code values here.
+ void setUp()
+ {
+ }
+
+ void tearDown()
+ {
+ }
+
+ /** The requested thread will get terminate the next time schedule() is called.
+
+ Note: on UNX, if call suspend thread is not the to be suspended thread, the to be
+ suspended thread will get suspended the next time schedule() is called,
+ while on w32, it's nothing with schedule.
+
+ check if suspend and terminate work well via schedule
+ */
+ void schedule_001()
+ {
+ OAddThread* aThread = new OAddThread();
+ sal_Bool bRes = aThread->create();
+ CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
+
+ ThreadHelper::thread_sleep_tenth_sec(2);
+ aThread->suspend();
+ ThreadHelper::thread_sleep_tenth_sec(1);
+ sal_Int32 nValue = aThread->getValue();
+ ThreadHelper::thread_sleep_tenth_sec(3);
+ sal_Int32 nLaterValue = aThread->getValue();
+ // resumeAndWaitThread(aThread);
+ t_print(" value = %d\n", nValue);
+ t_print("later value = %d\n", nLaterValue);
+ // if value and latervalue not equal, than the thread would not suspended
+
+ CPPUNIT_ASSERT_MESSAGE(
+ "Schedule: suspend works.",
+ nLaterValue == nValue
+ );
+
+ aThread->resume();
+ ThreadHelper::thread_sleep_tenth_sec(2);
+
+ aThread->terminate();
+ sal_Int32 nValue_term = aThread->getValue();
+
+ aThread->join();
+ sal_Int32 nValue_join = aThread->getValue();
+
+ t_print("value after term = %d\n", nValue_term);
+ t_print("value after join = %d\n", nValue_join);
+
+ // nValue_term and nValue_join should be the same
+ // but should be differ from nValue
+
+ delete aThread;
+ //check if thread really terminate after call terminate, if join immediatlly return
+ CPPUNIT_ASSERT_MESSAGE(
+ "Schedule: Returns False if the thread should terminate.",
+ nValue_join - nValue_term <= 1 && nValue_join - nValue_term >= 0
+ );
+
+ }
+
+ /** design a thread that has not call schedule in the workfunction--run method
+ */
+ void schedule_002()
+ {
+ ONoScheduleThread aThread; // this thread runs 10 sec. (no schedule() used)
+ sal_Bool bRes = aThread.create();
+ CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
+
+ ThreadHelper::thread_sleep_tenth_sec(2);
+ aThread.suspend();
+ sal_Int32 nValue = aThread.getValue();
+
+ ThreadHelper::thread_sleep_tenth_sec(3);
+ sal_Int32 nLaterValue = aThread.getValue();
+ ThreadHelper::thread_sleep_tenth_sec(5);
+
+ resumeAndWaitThread(&aThread);
+
+ t_print(" value = %d\n", nValue);
+ t_print("later value = %d\n", nLaterValue);
+
+ //On windows, suspend works, so the values are same
+#ifdef WNT
+ CPPUNIT_ASSERT_MESSAGE(
+ "Schedule: don't schedule in thread run method, suspend works.",
+ nLaterValue == nValue
+ );
+#endif
+
+ //On UNX, suspend does not work, so the difference of the values equals to sleep seconds number
+#ifdef UNX
+ aThread.resume();
+ CPPUNIT_ASSERT_MESSAGE(
+ "Schedule: don't schedule in thread run method, suspend does not work too.",
+ nLaterValue > nValue
+ );
+#endif
+
+ // terminate will not work if no schedule in thread's work function
+ termAndJoinThread(&aThread);
+ sal_Int32 nValue_term = aThread.getValue();
+
+ t_print(" value term = %d\n", nValue_term);
+
+ CPPUNIT_ASSERT_MESSAGE(
+ "Schedule: don't schedule in thread run method, terminate failed.",
+ nValue_term == 10
+ );
+ }
+
+ CPPUNIT_TEST_SUITE(schedule);
+ CPPUNIT_TEST(schedule_001);
+ CPPUNIT_TEST(schedule_002);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class schedule
+
+// -----------------------------------------------------------------------------
+ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::create, "osl_Thread");
+ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::createSuspended, "osl_Thread");
+ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::suspend, "osl_Thread");
+ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::resume, "osl_Thread");
+ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::terminate, "osl_Thread");
+ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::join, "osl_Thread");
+ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::isRunning, "osl_Thread");
+ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::setPriority, "osl_Thread");
+ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::getPriority, "osl_Thread");
+ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::getIdentifier, "osl_Thread");
+ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::getCurrentIdentifier, "osl_Thread");
+ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::wait, "osl_Thread");
+ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::yield, "osl_Thread");
+ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::schedule, "osl_Thread");
+} // namespace osl_Thread
+
+
+// -----------------------------------------------------------------------------
+// destroy function when the binding thread terminate
+void SAL_CALL destroyCallback(void * data)
+{
+ t_print("destroying local data %s\n", (char *) data);
+ delete[] (char *) data;
+}
+
+static ThreadData myThreadData(destroyCallback);
+
+/**
+*/
+class myKeyThread : public Thread
+{
+public:
+ // a public char member for test result checking
+ char m_Char_Test;
+ // for pass thread-special data to thread
+ myKeyThread(const char cData)
+ {
+ m_nData = cData;
+ }
+private:
+ char m_nData;
+
+ void SAL_CALL run()
+ {
+ char * pc = new char[2];
+// strcpy(pc, &m_nData);
+ memcpy(pc, &m_nData, 1);
+ pc[1] = '\0';
+
+ myThreadData.setData(pc);
+ char* pData = (char*)myThreadData.getData();
+ m_Char_Test = *pData;
+ // wait for long time to check the data value in main thread
+ ThreadHelper::thread_sleep_tenth_sec(3);
+ }
+public:
+ ~myKeyThread()
+ {
+ if (isRunning())
+ {
+ t_print("error: not terminated.\n");
+ }
+ }
+};
+
+static ThreadData idData;
+
+class idThread: public Thread
+{
+public:
+ oslThreadIdentifier m_Id;
+private:
+ void SAL_CALL run()
+ {
+ oslThreadIdentifier* pId = new oslThreadIdentifier;
+ *pId = getIdentifier();
+ idData.setData(pId);
+ oslThreadIdentifier* pIdData = (oslThreadIdentifier*)idData.getData();
+ //t_print("Thread %d has Data %d\n", getIdentifier(), *pIdData);
+ m_Id = *pIdData;
+ delete pId;
+ }
+
+public:
+ ~idThread()
+ {
+ if (isRunning())
+ {
+ t_print("error: not terminated.\n");
+ }
+ }
+};
+
+namespace osl_ThreadData
+{
+
+ class ctors : public CppUnit::TestFixture
+ {
+ public:
+ // initialise your test code values here.
+ void setUp()
+ {
+ }
+
+ void tearDown()
+ {
+ }
+
+ // insert your test code here.
+ void ctor_001()
+ {
+
+ }
+
+ CPPUNIT_TEST_SUITE(ctors);
+ CPPUNIT_TEST(ctor_001);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class ctors
+
+
+ class setData : public CppUnit::TestFixture
+ {
+ public:
+ // initialise your test code values here.
+ void setUp()
+ {
+ }
+
+ void tearDown()
+ {
+ }
+
+ /** the same instance of the class can have different values in different threads
+ */
+ void setData_001()
+ {
+ idThread aThread1;
+ aThread1.create();
+ idThread aThread2;
+ aThread2.create();
+
+ aThread1.join();
+ aThread2.join();
+
+ oslThreadIdentifier aThreadId1 = aThread1.getIdentifier();
+ oslThreadIdentifier aThreadId2 = aThread2.getIdentifier();
+
+ CPPUNIT_ASSERT_MESSAGE(
+ "ThreadData setData: ",
+ aThread1.m_Id == aThreadId1 && aThread2.m_Id == aThreadId2
+ );
+
+ }
+
+ void setData_002()
+ {
+ // at first, set the data a value
+ char* pc = new char[2];
+ char m_nData = 'm';
+// LLA: this is a copy functions only and really only for \0 terminated strings
+// m_nData is not a string, it's a character
+// strcpy(pc, &m_nData);
+ memcpy(pc, &m_nData, 1);
+ pc[1] = '\0';
+
+ myThreadData.setData(pc);
+
+ myKeyThread aThread1('a');
+ aThread1.create();
+ myKeyThread aThread2('b');
+ aThread2.create();
+ // aThread1 and aThread2 should have not terminated yet, check current data, not 'a' 'b'
+ char* pChar = (char*)myThreadData.getData();
+ char aChar = *pChar;
+
+ aThread1.join();
+ aThread2.join();
+
+ // the saved thread data of aThread1 & aThread2, different
+ char cData1 = aThread1.m_Char_Test;
+ char cData2 = aThread2.m_Char_Test;
+
+ CPPUNIT_ASSERT_MESSAGE(
+ "ThreadData setData: ",
+ cData1 == 'a' && cData2 == 'b' && aChar == 'm'
+ );
+
+ }
+ /** setData the second time, and then getData
+ */
+ void setData_003()
+ {
+ // at first, set the data a value
+ char* pc = new char[2];
+ char m_nData = 'm';
+// strcpy(pc, &m_nData);
+ memcpy(pc, &m_nData, 1);
+ pc[1] = '\0';
+ myThreadData.setData(pc);
+
+ myKeyThread aThread1('a');
+ aThread1.create();
+ myKeyThread aThread2('b');
+ aThread2.create();
+ // aThread1 and aThread2 should have not terminated yet
+ // setData the second time
+ char* pc2 = new char[2];
+ m_nData = 'o';
+// strcpy(pc2, &m_nData);
+ memcpy(pc2, &m_nData, 1);
+ pc2[1] = '\0';
+
+ myThreadData.setData(pc2);
+ char* pChar = (char*)myThreadData.getData();
+ char aChar = *pChar;
+
+ aThread1.join();
+ aThread2.join();
+
+ // the saved thread data of aThread1 & aThread2, different
+ char cData1 = aThread1.m_Char_Test;
+ char cData2 = aThread2.m_Char_Test;
+
+ CPPUNIT_ASSERT_MESSAGE(
+ "ThreadData setData: ",
+ cData1 == 'a' && cData2 == 'b' && aChar == 'o'
+ );
+
+ }
+
+ CPPUNIT_TEST_SUITE(setData);
+ CPPUNIT_TEST(setData_001);
+ CPPUNIT_TEST(setData_002);
+ CPPUNIT_TEST(setData_003);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class setData
+
+ //sal_Bool buildTwoThreads(char)
+
+ class getData : public CppUnit::TestFixture
+ {
+ public:
+ // initialise your test code values here.
+ void setUp()
+ {
+ }
+
+ void tearDown()
+ {
+ }
+
+ // After setData in child threads, get Data in the main thread, should be independent
+ void getData_001()
+ {
+ char* pc = new char[2];
+ char m_nData[] = "i";
+ strcpy(pc, m_nData);
+ t_print("pc %s\n", pc);
+ myThreadData.setData(pc);
+
+ myKeyThread aThread1('c');
+ aThread1.create();
+ myKeyThread aThread2('d');
+ aThread2.create();
+
+ aThread1.join();
+ aThread2.join();
+
+ char cData1 = aThread1.m_Char_Test;
+ char cData2 = aThread2.m_Char_Test;
+
+ char* pChar = (char*)myThreadData.getData();
+ char aChar = *pChar;
+
+ CPPUNIT_ASSERT_MESSAGE(
+ "ThreadData setData: ",
+ cData1 == 'c' && cData2 == 'd' && aChar == 'i'
+ );
+
+ }
+
+ // setData then change the value in the address data pointer points,
+ // and then getData, should get the new value
+ void getData_002()
+ {
+ char* pc = new char[2];
+ char m_nData = 'i';
+// strcpy(pc, &m_nData);
+ memcpy(pc, &m_nData, 1);
+ pc[1] = '\0';
+// strncpy(pc, &m_nData, sizeof(char);
+
+ t_print("pc %s\n", pc);
+ myThreadData.setData(pc);
+
+ myKeyThread aThread1('a');
+ aThread1.create();
+ myKeyThread aThread2('b');
+ aThread2.create();
+
+ // change the value which pc points
+ char m_nData2 = 'j';
+ // strcpy(pc, &m_nData2);
+ memcpy(pc, &m_nData2, 1);
+ pc[1] = '\0';
+
+ //t_print("pc %s\n", pc);
+ void* pChar = myThreadData.getData();
+ char aChar = *(char*)pChar;
+
+ aThread1.join();
+ aThread2.join();
+
+ char cData1 = aThread1.m_Char_Test;
+ char cData2 = aThread2.m_Char_Test;
+
+ CPPUNIT_ASSERT_MESSAGE(
+ "ThreadData setData: ",
+ cData1 == 'a' && cData2 == 'b' && aChar == 'j'
+ );
+
+ }
+
+ CPPUNIT_TEST_SUITE(getData);
+ CPPUNIT_TEST(getData_001);
+ CPPUNIT_TEST(getData_002);
+ CPPUNIT_TEST_SUITE_END();
+ }; // class getData
+
+// -----------------------------------------------------------------------------
+ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_ThreadData::ctors, "osl_ThreadData");
+ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_ThreadData::setData, "osl_ThreadData");
+ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_ThreadData::getData, "osl_ThreadData");
+} // namespace osl_ThreadData
+
+// 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;
+