virtual ~myThread() override
{ 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 %u!\n", static_cast<unsigned>(getIdentifier()));
}
sal_Int32 getValue() { return m_aFlag.getValue(); }
virtual ~OCountThread() override
{ 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 ~OAddThread() override
{ if (isRunning())
{ // t_print("error: not terminated.\n");
}
}
};
}
namespace osl_Thread
{
staticvoid resumeAndWaitThread(Thread* _pThread)
{ // This function 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 _WIN32
t_print("resumeAndWaitThread\n");
_pThread->resume();
ThreadHelper::thread_sleep_tenth_sec(1); #else
_pThread->resume(); #endif
}
// kill a running thread and join it, if it has terminated, do nothing staticvoid termAndJoinThread(Thread* _pThread)
{
_pThread->terminate();
// LLA: Windows feature???, a suspended thread can not terminated, so we have to weak it up #ifdef _WIN32
_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: /** Simple create a thread.
Createasimplethread,itjustdoesadd1tovalue(whichinitialized0), ifthethreadrun,thevalueshouldbe1.
*/ void create_001()
{
myThread* newthread = new myThread; bool bRes = newthread->create();
CPPUNIT_ASSERT_MESSAGE("Can not creates a new thread!\n", bRes);
ThreadHelper::thread_sleep_tenth_sec(1); // wait short 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;
CPPUNIT_ASSERT_MESSAGE( "Creates a new thread",
nValue >= 1
);
CPPUNIT_ASSERT_MESSAGE( "Creates a new thread",
isRunning
);
}
/** only one running thread per instance, return false if create secondly
*/ void create_002()
{
myThread* newthread = new myThread; bool res1 = newthread->create(); bool res2 = newthread->create();
t_print("In non pro, an assertion should occurred. This behaviour is right.\n");
termAndJoinThread(newthread); delete newthread;
CPPUNIT_ASSERT_MESSAGE( "Creates a new thread: can not create two threads per instance",
res1
);
CPPUNIT_ASSERT_MESSAGE( "Creates a new thread: can not create two threads per instance",
!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: /** Create a suspended thread, use the same class as create_001
aftercreate,waitenoughtime,checkthevalue,ifit'sstilltheinitialvalue,pass
*/ void createSuspended_001()
{
myThread* newthread = new myThread; bool bRes = newthread->createSuspended();
CPPUNIT_ASSERT_MESSAGE("Can not creates a new thread!", bRes);
CPPUNIT_ASSERT_EQUAL_MESSAGE( "Creates a new suspended thread",
sal_Int32(0), nValue
);
CPPUNIT_ASSERT_MESSAGE( "Creates a new suspended thread",
isRunning
);
}
CPPUNIT_ASSERT_MESSAGE( "Creates a new thread: can not create two threads per instance",
res1
);
CPPUNIT_ASSERT_MESSAGE( "Creates a new thread: can not create two threads per instance",
!res2
);
}
/** when the count value equal to or more than 3, suspend the thread.
*/ staticvoid suspendCountThread(OCountThread* _pCountThread)
{
sal_Int32 nValue = 0; while (true)
{
nValue = _pCountThread->getValue(); if (nValue >= 3)
{
_pCountThread->suspend(); break;
}
}
}
/** Test of the osl::Thread::suspend method
*/ class suspend : public CppUnit::TestFixture
{ public: /** Use a thread which has a flag added 1 every second
ALGORITHM: createthethread,afterrunningspecialtime,recordvalueofflag,thensuspendit, waitalongtime,checktheflag,ifitremainsunchangedduringsuspending
*/ void suspend_001()
{
OCountThread* aCountThread = new OCountThread(); bool bRes = aCountThread->create();
CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes ); // 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)
/** Test of the osl::Thread::resume method
*/ class resume : public CppUnit::TestFixture
{ public: /** check if the thread run samely as usual after suspend and resume
/* LLA: this assumption is no longer relevant: nResumeValue == nSuspendValue && */
CPPUNIT_ASSERT_MESSAGE( "Suspend then resume the thread",
nLaterValue >= 9
);
CPPUNIT_ASSERT_MESSAGE( "Suspend then resume the thread",
nResumeValue > nSuspendValue
);
CPPUNIT_ASSERT_MESSAGE( "Suspend then resume the thread",
nLaterValue > nResumeValue
);
}
/** Create a suspended thread then resume, check if the thread has run
*/ void resume_002()
{
myThread* newthread = new myThread; bool bRes = newthread->createSuspended();
CPPUNIT_ASSERT_MESSAGE ( "Can't create thread!", bRes );
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: /** Check after call terminate if the running thread running go on executing
CPPUNIT_ASSERT_MESSAGE( "Terminate the thread",
!isRunning
);
CPPUNIT_ASSERT_MESSAGE( "Terminate the thread",
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(); bool bRes = aCountThread->create();
CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
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: /** Check after call terminate if the thread running function will not go on executing
//record the time when the running begin // TimeValue aTimeVal_befor; // osl_getSystemTime( &aTimeVal_befor );
StopWatch aStopWatch;
aStopWatch.start();
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);
t_print("nValue in %s Prio Thread is %d\n",sPrio.getStr(), static_cast<int>(nValueNormal));
t_print("nValue in %s Prio Thread is %d\n", sPrio.getStr(), static_cast<int>(nValueNormal2));
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", static_cast<int>(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: );
}
t_print("After 10 tenth seconds\n");
t_print("nValue in Highest Prio Thread is %d\n", static_cast<int>(nValueHighest));
t_print("nValue in AboveNormal Prio Thread is %d\n", static_cast<int>(nValueAboveNormal));
t_print("nValue in Normal Prio Thread is %d\n", static_cast<int>(nValueNormal));
t_print("After 10 tenth seconds\n");
t_print("nValue in Highest Prio Thread is %d\n", static_cast<int>(nValueHighest));
t_print("nValue in AboveNormal Prio Thread is %d\n", static_cast<int>(nValueAboveNormal));
t_print("nValue in Normal Prio Thread is %d\n", static_cast<int>(nValueNormal));
t_print("nValue in BelowNormal Prio Thread is %d\n", static_cast<int>(nValueBelowNormal));
t_print("nValue in Lowest Prio Thread is %d\n", static_cast<int>(nValueLowest));
t_print("After 5 tenth seconds\n");
t_print("nValue in AboveNormal Prio Thread is %d\n", static_cast<int>(nValueAboveNormal));
t_print("nValue in Normal Prio Thread is %d\n", static_cast<int>(nValueNormal));
t_print("nValue in BelowNormal Prio Thread is %d\n", static_cast<int>(nValueBelowNormal));
t_print("nValue in Lowest Prio Thread is %d\n", static_cast<int>(nValueLowest));
t_print("After 5 tenth seconds\n");
t_print("nValue in Normal Prio Thread is %d\n", static_cast<int>(nValueNormal));
t_print("nValue in BelowNormal Prio Thread is %d\n", static_cast<int>(nValueBelowNormal));
t_print("nValue in Lowest Prio Thread is %d\n", static_cast<int>(nValueLowest));
/** Test of the osl::Thread::getPriority method
*/ class getPriority : public CppUnit::TestFixture
{ public: // 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);
// LLA: Priority settings may not work within some OS versions. #ifdefined(_WIN32) || defined(__sun)
CPPUNIT_ASSERT_EQUAL_MESSAGE( "getPriority",
osl_Thread_PriorityHighest, aPriority
); #else // LLA: Linux // NO_PTHREAD_PRIORITY ???
CPPUNIT_ASSERT_EQUAL_MESSAGE( "getPriority",
osl_Thread_PriorityNormal, aPriority
); #endif
}
CPPUNIT_TEST_SUITE(getPriority);
CPPUNIT_TEST(getPriority_001);
CPPUNIT_TEST_SUITE_END();
}; // class getPriority
class getIdentifier : public CppUnit::TestFixture
{ public: // initialise your test code values here.
void getIdentifier_001()
{ // insert your test code here.
}
CPPUNIT_TEST_SUITE(getIdentifier);
CPPUNIT_TEST(getIdentifier_001);
CPPUNIT_TEST_SUITE_END();
}; // class getIdentifier
/** Test of the osl::Thread::getCurrentIdentifier method
*/ class getCurrentIdentifier : public CppUnit::TestFixture
{ public: void getCurrentIdentifier_001()
{
oslThreadIdentifier oId;
OCountThread* pCountThread = new OCountThread;
pCountThread->create();
pCountThread->setWait(3);
oId = Thread::getCurrentIdentifier();
oslThreadIdentifier oIdChild = pCountThread->getIdentifier();
termAndJoinThread(pCountThread); delete pCountThread;
CPPUNIT_ASSERT_MESSAGE( "Get the identifier for the current active thread.",
oId != oIdChild);
}
CPPUNIT_TEST_SUITE(getCurrentIdentifier);
CPPUNIT_TEST(getCurrentIdentifier_001);
CPPUNIT_TEST_SUITE_END();
}; // class getCurrentIdentifier
/** Test of the osl::Thread::wait method
*/ class waittest : public CppUnit::TestFixture
{ public: /** call wait in the run method
CPPUNIT_ASSERT_MESSAGE( "Wait: Blocks the calling thread for the given number of time.",
nTenthSec >= 5
);
CPPUNIT_ASSERT_EQUAL_MESSAGE( "Wait: Blocks the calling thread for the given number of time.",
sal_Int32(1), nValue
);
}
CPPUNIT_TEST_SUITE(waittest);
CPPUNIT_TEST(wait_001);
CPPUNIT_TEST_SUITE_END();
}; // class waittest
/** osl::Thread::yield method: can not design good test scenario to test up to now
*/ class yield : public CppUnit::TestFixture
{ public: void yield_001()
{ // insert your test code here.
}
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:
/** The requested thread will get terminate the next time schedule() is called.
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", static_cast<int>(nValue));
t_print("later value = %d\n", static_cast<int>(nLaterValue)); // if value and latervalue not equal, then the thread would not suspended
t_print("value after term = %d\n", static_cast<int>(nValue_term));
t_print("value after join = %d\n", static_cast<int>(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 immediately return
CPPUNIT_ASSERT_MESSAGE( "Schedule: Returns False if the thread should terminate.",
nValue_join - nValue_term <= 1
);
CPPUNIT_ASSERT_MESSAGE( "Schedule: Returns False if the thread should terminate.",
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) bool bRes = aThread.create();
CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
t_print(" value = %d\n", static_cast<int>(nValue));
t_print("later value = %d\n", static_cast<int>(nLaterValue));
//On windows, suspend works, so the values are same #ifdef _WIN32
CPPUNIT_ASSERT_EQUAL_MESSAGE( "Schedule: don't schedule in thread run method, suspend works.",
nValue, nLaterValue
); #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", static_cast<int>(nValue_term));
CPPUNIT_ASSERT_EQUAL_MESSAGE( "Schedule: don't schedule in thread run method, terminate failed.", static_cast<sal_Int32>(10), nValue_term
);
}
CPPUNIT_TEST_SUITE(schedule);
CPPUNIT_TEST(schedule_001);
CPPUNIT_TEST(schedule_002);
CPPUNIT_TEST_SUITE_END();
}; // class schedule
// destroy function when the binding thread terminate staticvoid destroyCallback(void * data)
{ delete[] static_cast<char *>(data);
}
static ThreadData myThreadData(destroyCallback);
namespace {
class myKeyThread : public Thread
{ public: // a public char member for test result checking char m_Char_Test; // for pass thread-special data to thread explicit myKeyThread(constchar cData)
: m_Char_Test(0)
{
m_nData = cData;
} private: char m_nData;
myThreadData.setData(pc); char* pData = static_cast<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: virtual ~myKeyThread() override
{ if (isRunning())
{
t_print("error: not terminated.\n");
}
}
};
}
static ThreadData idData;
namespace {
class idThread: public Thread
{ public:
oslThreadIdentifier m_Id; private: void SAL_CALL run() override
{
std::unique_ptr<oslThreadIdentifier> pId( new oslThreadIdentifier );
*pId = getIdentifier();
idData.setData(pId.get());
oslThreadIdentifier* pIdData = static_cast<oslThreadIdentifier*>(idData.getData()); //t_print("Thread %d has Data %d\n", getIdentifier(), *pIdData);
m_Id = *pIdData;
}
public: virtual ~idThread() override
{ if (isRunning())
{
t_print("error: not terminated.\n");
}
}
};
}
namespace osl_ThreadData
{
class ctors : public CppUnit::TestFixture
{ public:
// 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:
/** the same instance of the class can have different values in different threads
*/ void setData_001()
{
idThread aThread1;
aThread1.create();
idThread aThread2;
aThread2.create();
void setData_002()
{ // at first, set the data a value char* pc = newchar[2]; char nData = 'm';
pc[0] = nData;
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 = static_cast<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;
} /** setData the second time, and then getData
*/ void setData_003()
{ // at first, set the data a value char* pc = newchar[2]; char nData = 'm';
memcpy(pc, &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 = newchar[2];
nData = 'o';
memcpy(pc2, &nData, 1);
pc2[1] = '\0';
CPPUNIT_TEST_SUITE(setData);
CPPUNIT_TEST(setData_001);
CPPUNIT_TEST(setData_002);
CPPUNIT_TEST(setData_003);
CPPUNIT_TEST_SUITE_END();
}; // class setData
class getData : public CppUnit::TestFixture
{ public:
// After setData in child threads, get Data in the main thread, should be independent void getData_001()
{ char* pc = newchar[2];
strcpy(pc, "i");
myThreadData.setData(pc);
// setData then change the value in the address data pointer points, // and then getData, should get the new value void getData_002()
{ char* pc = newchar[2]; char nData = 'i';
memcpy(pc, &nData, 1);
pc[1] = '\0';
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.