tdf#130857 qt weld: Implement QtInstanceWidget::get_text_height
[LibreOffice.git] / sal / qa / osl / process / osl_Thread.cxx
blob0cb0e773dbe69a4e0b9d3ec0eba89d5b3eb90524
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <algorithm>
21 #ifdef _WIN32
22 #if !defined WIN32_LEAN_AND_MEAN
23 # define WIN32_LEAN_AND_MEAN
24 #endif
25 #include <windows.h>
26 #endif
28 // include files
30 #include <sal/types.h>
31 #include <rtl/string.hxx>
32 #include <osl/thread.hxx>
33 #include <osl/mutex.hxx>
34 #include <osl/time.h>
36 #include <string.h>
37 #include <memory>
39 #include <cppunit/TestFixture.h>
40 #include <cppunit/extensions/HelperMacros.h>
42 #define t_print printf
44 using namespace osl;
46 namespace {
48 // Small stopwatch
49 class StopWatch {
50 TimeValue t1,t2; // Start and stoptime
52 protected:
53 sal_Int32 m_nNanoSec;
54 sal_Int32 m_nSeconds;
56 bool m_bIsValid; // TRUE, when started and stopped
57 bool m_bIsRunning; // TRUE, when started
59 public:
60 StopWatch();
62 void start(); // Starts time
63 void stop(); // Stops time
65 double getSeconds() const;
66 double getTenthSec() const;
71 // ================================= Stop Watch =================================
73 // A small stopwatch for internal use
74 // (c) Lars Langhans 29.12.1996 22:10
76 StopWatch::StopWatch()
77 : m_nNanoSec(0)
78 , m_nSeconds(0)
79 , m_bIsValid(false)
80 , m_bIsRunning(false)
82 t1.Seconds = 0;
83 t1.Nanosec = 0;
84 t2.Seconds = 0;
85 t2.Nanosec = 0;
88 void StopWatch::start()
90 // pre: %
91 // post: Start Timer
93 m_bIsValid = false;
94 m_bIsRunning = true;
95 osl_getSystemTime( &t1 );
96 t_print("# %u %u nsecs\n", static_cast<unsigned>(t1.Seconds), static_cast<unsigned>(t1.Nanosec));
97 // gettimeofday(&t1, 0);
100 void StopWatch::stop()
102 // pre: Timer should be started
103 // post: Timer will stopped
105 osl_getSystemTime( &t2 );
106 t_print("# %u %u nsecs\n", static_cast<unsigned>(t2.Seconds), static_cast<unsigned>(t2.Nanosec));
108 if (m_bIsRunning)
109 { // check if started.
110 m_nSeconds = static_cast<sal_Int32>(t2.Seconds) - static_cast<sal_Int32>(t1.Seconds);
111 if ( t2.Nanosec > t1.Nanosec )
112 m_nNanoSec = static_cast<sal_Int32>(t2.Nanosec) - static_cast<sal_Int32>(t1.Nanosec);
113 else
115 m_nNanoSec = 1000000000 + static_cast<sal_Int32>(t2.Nanosec) - static_cast<sal_Int32>(t1.Nanosec);
116 m_nSeconds -= 1;
118 t_print("# %u %u nsecs\n", static_cast<unsigned>(m_nSeconds), static_cast<unsigned>(m_nNanoSec) );
119 m_bIsValid = true;
120 m_bIsRunning = false;
124 double StopWatch::getSeconds() const
126 // pre: valid = TRUE
127 // BACK: time in seconds
129 double nValue = 0.0;
130 if (m_bIsValid)
132 nValue = double(m_nNanoSec) / 1000000000.0 + m_nSeconds; // milli micro nano
134 return nValue;
137 double StopWatch::getTenthSec() const
139 double nValue = 0.0;
140 if (m_bIsValid)
142 nValue = double(m_nNanoSec) / 100000000.0 + m_nSeconds * 10;
144 return nValue ;
147 namespace {
149 template <class T>
150 class ThreadSafeValue
152 T m_nFlag;
153 Mutex m_aMutex;
154 public:
155 explicit ThreadSafeValue(T n = 0): m_nFlag(n) {}
156 T getValue()
158 //block if already acquired by another thread.
159 osl::MutexGuard g(m_aMutex);
160 return m_nFlag;
162 void incValue()
164 //only one thread operate on the flag.
165 osl::MutexGuard g(m_aMutex);
166 m_nFlag++;
168 void acquire() {m_aMutex.acquire();}
169 void release() {m_aMutex.release();}
174 namespace ThreadHelper
176 static void thread_sleep_tenth_sec(sal_Int32 _nTenthSec)
178 osl::Thread::wait(std::chrono::milliseconds(_nTenthSec * 100));
181 static void outputPriority(oslThreadPriority const& _aPriority)
183 // LLA: output the priority
184 if (_aPriority == osl_Thread_PriorityHighest)
186 t_print("Prio is High\n");
188 else if (_aPriority == osl_Thread_PriorityAboveNormal)
190 t_print("Prio is above normal\n");
192 else if (_aPriority == osl_Thread_PriorityNormal)
194 t_print("Prio is normal\n");
196 else if (_aPriority == osl_Thread_PriorityBelowNormal)
198 t_print("Prio is below normal\n");
200 else if (_aPriority == osl_Thread_PriorityLowest)
202 t_print("Prio is lowest\n");
204 else
206 t_print("Prio is unknown\n");
211 namespace {
213 /** Simple thread for testing Thread-create.
215 Just add 1 of value 0, and after running, result is 1.
217 class myThread : public Thread
219 ThreadSafeValue<sal_Int32> m_aFlag;
220 public:
221 sal_Int32 getValue() { return m_aFlag.getValue(); }
222 protected:
223 /** guarded value which initialized 0
225 @see ThreadSafeValue
227 void SAL_CALL run() override
229 while(schedule())
231 m_aFlag.incValue();
232 ThreadHelper::thread_sleep_tenth_sec(1);
236 public:
238 virtual void SAL_CALL suspend() override
240 m_aFlag.acquire();
241 ::osl::Thread::suspend();
242 m_aFlag.release();
245 virtual ~myThread() override
247 if (isRunning())
249 t_print("error: not terminated.\n");
255 /** Thread which has a flag add 1 every second until 20
257 class OCountThread : public Thread
259 ThreadSafeValue<sal_Int32> m_aFlag;
260 public:
261 OCountThread() : m_nWaitSec(0)
263 t_print("new OCountThread thread %u!\n", static_cast<unsigned>(getIdentifier()));
265 sal_Int32 getValue() { return m_aFlag.getValue(); }
267 void setWait(sal_Int32 nSec)
269 m_nWaitSec = nSec;
270 //m_bWait = sal_True;
273 virtual void SAL_CALL suspend() override
275 m_aFlag.acquire();
276 ::osl::Thread::suspend();
277 m_aFlag.release();
280 protected:
281 //sal_Bool m_bWait;
282 sal_Int32 m_nWaitSec;
284 void SAL_CALL run() override
286 /// if the thread should terminate, schedule return false
287 while (m_aFlag.getValue() < 20 && schedule())
289 m_aFlag.incValue();
290 ThreadHelper::thread_sleep_tenth_sec(1);
292 if (m_nWaitSec != 0)
294 TimeValue nTV;
295 nTV.Seconds = m_nWaitSec / 10 ;
296 nTV.Nanosec = ( m_nWaitSec%10 ) * 100000000 ;
297 wait( nTV );
298 m_nWaitSec = 0;
302 void SAL_CALL onTerminated() override
304 t_print("normally terminate this thread %u!\n", static_cast<unsigned>(getIdentifier()));
306 public:
308 virtual ~OCountThread() override
310 if (isRunning())
312 t_print("error: not terminated.\n");
318 /** no call schedule in the run method
320 class ONoScheduleThread : public Thread
322 ThreadSafeValue<sal_Int32> m_aFlag;
323 public:
324 sal_Int32 getValue() { return m_aFlag.getValue(); }
326 virtual void SAL_CALL suspend() override
328 m_aFlag.acquire();
329 ::osl::Thread::suspend();
330 m_aFlag.release();
332 protected:
333 void SAL_CALL run() override
335 while (m_aFlag.getValue() < 10)
337 m_aFlag.incValue();
338 ThreadHelper::thread_sleep_tenth_sec(1);
341 void SAL_CALL onTerminated() override
343 t_print("normally terminate this thread %u!\n", static_cast<unsigned>(getIdentifier()));
345 public:
346 ONoScheduleThread()
348 t_print("new thread id %u!\n", static_cast<unsigned>(getIdentifier()));
350 virtual ~ONoScheduleThread() override
352 if (isRunning())
354 t_print("error: not terminated.\n");
361 class OAddThread : public Thread
363 ThreadSafeValue<sal_Int32> m_aFlag;
364 public:
365 //oslThreadIdentifier m_id, m_CurId;
366 OAddThread(){}
367 sal_Int32 getValue() { return m_aFlag.getValue(); }
369 virtual void SAL_CALL suspend() override
371 m_aFlag.acquire();
372 ::osl::Thread::suspend();
373 m_aFlag.release();
375 protected:
376 void SAL_CALL run() override
378 //if the thread should terminate, schedule return false
379 while (schedule())
381 m_aFlag.incValue();
384 void SAL_CALL onTerminated() override
386 // t_print("normally terminate this thread %d!\n", getIdentifier());
388 public:
390 virtual ~OAddThread() override
392 if (isRunning())
394 // t_print("error: not terminated.\n");
402 namespace osl_Thread
405 static void resumeAndWaitThread(Thread* _pThread)
407 // This function starts a thread, wait a second and suspends the thread
408 // Due to the fact, that a suspend and never run thread never really exists.
410 // Note: on UNX, after createSuspended, and then terminate the thread, it performs well;
411 // while on Windows, after createSuspended, the thread can not terminate, wait endlessly,
412 // so here call resume at first, then call terminate.
413 #ifdef _WIN32
414 t_print("resumeAndWaitThread\n");
415 _pThread->resume();
416 ThreadHelper::thread_sleep_tenth_sec(1);
417 #else
418 _pThread->resume();
419 #endif
422 // kill a running thread and join it, if it has terminated, do nothing
423 static void termAndJoinThread(Thread* _pThread)
425 _pThread->terminate();
427 // LLA: Windows feature???, a suspended thread can not terminated, so we have to weak it up
428 #ifdef _WIN32
429 _pThread->resume();
430 ThreadHelper::thread_sleep_tenth_sec(1);
431 #endif
432 t_print("#wait for join.\n");
433 _pThread->join();
435 /** Test of the osl::Thread::create method
438 class create : public CppUnit::TestFixture
440 public:
441 /** Simple create a thread.
443 Create a simple thread, it just does add 1 to value(which initialized 0),
444 if the thread run, the value should be 1.
446 void create_001()
448 myThread* newthread = new myThread;
449 bool bRes = newthread->create();
450 CPPUNIT_ASSERT_MESSAGE("Can not creates a new thread!\n", bRes);
452 ThreadHelper::thread_sleep_tenth_sec(1); // wait short
453 bool isRunning = newthread->isRunning(); // check if thread is running
454 /// wait for the new thread to assure it has run
455 ThreadHelper::thread_sleep_tenth_sec(3);
456 sal_Int32 nValue = newthread->getValue();
457 /// to assure the new thread has terminated
458 termAndJoinThread(newthread);
459 delete newthread;
461 t_print(" nValue = %d\n", static_cast<int>(nValue));
462 t_print("isRunning = %s\n", isRunning ? "true" : "false");
464 CPPUNIT_ASSERT_MESSAGE(
465 "Creates a new thread",
466 nValue >= 1
468 CPPUNIT_ASSERT_MESSAGE(
469 "Creates a new thread",
470 isRunning
475 /** only one running thread per instance, return false if create secondly
477 void create_002()
479 myThread* newthread = new myThread;
480 bool res1 = newthread->create();
481 bool res2 = newthread->create();
482 t_print("In non pro, an assertion should occurred. This behaviour is right.\n");
483 termAndJoinThread(newthread);
484 delete newthread;
486 CPPUNIT_ASSERT_MESSAGE(
487 "Creates a new thread: can not create two threads per instance",
488 res1
490 CPPUNIT_ASSERT_MESSAGE(
491 "Creates a new thread: can not create two threads per instance",
492 !res2
497 CPPUNIT_TEST_SUITE(create);
498 CPPUNIT_TEST(create_001);
499 CPPUNIT_TEST(create_002);
500 CPPUNIT_TEST_SUITE_END();
501 }; // class create
503 /** Test of the osl::Thread::createSuspended method
505 class createSuspended : public CppUnit::TestFixture
507 public:
508 /** Create a suspended thread, use the same class as create_001
510 after create, wait enough time, check the value, if it's still the initial value, pass
512 void createSuspended_001()
514 myThread* newthread = new myThread;
515 bool bRes = newthread->createSuspended();
516 CPPUNIT_ASSERT_MESSAGE("Can not creates a new thread!", bRes);
518 ThreadHelper::thread_sleep_tenth_sec(1);
519 bool isRunning = newthread->isRunning();
520 ThreadHelper::thread_sleep_tenth_sec(3);
521 sal_Int32 nValue = newthread->getValue();
523 resumeAndWaitThread(newthread);
525 termAndJoinThread(newthread);
526 delete newthread;
528 CPPUNIT_ASSERT_EQUAL_MESSAGE(
529 "Creates a new suspended thread",
530 sal_Int32(0), nValue
532 CPPUNIT_ASSERT_MESSAGE(
533 "Creates a new suspended thread",
534 isRunning
538 void createSuspended_002()
540 myThread* newthread = new myThread;
541 bool res1 = newthread->createSuspended();
542 bool res2 = newthread->createSuspended();
544 resumeAndWaitThread(newthread);
546 termAndJoinThread(newthread);
548 delete newthread;
550 CPPUNIT_ASSERT_MESSAGE(
551 "Creates a new thread: can not create two threads per instance",
552 res1
554 CPPUNIT_ASSERT_MESSAGE(
555 "Creates a new thread: can not create two threads per instance",
556 !res2
560 CPPUNIT_TEST_SUITE(createSuspended);
561 CPPUNIT_TEST(createSuspended_001);
562 // LLA: Deadlocked!!!
563 CPPUNIT_TEST(createSuspended_002);
564 CPPUNIT_TEST_SUITE_END();
565 }; // class createSuspended
567 /** when the count value equal to or more than 3, suspend the thread.
569 static void suspendCountThread(OCountThread* _pCountThread)
571 sal_Int32 nValue = 0;
572 while (true)
574 nValue = _pCountThread->getValue();
575 if (nValue >= 3)
577 _pCountThread->suspend();
578 break;
583 /** Test of the osl::Thread::suspend method
585 class suspend : public CppUnit::TestFixture
587 public:
588 /** Use a thread which has a flag added 1 every second
590 ALGORITHM:
591 create the thread, after running special time, record value of flag, then suspend it,
592 wait a long time, check the flag, if it remains unchanged during suspending
594 void suspend_001()
596 OCountThread* aCountThread = new OCountThread();
597 bool bRes = aCountThread->create();
598 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
599 // the thread run for some seconds, but not terminate
600 suspendCountThread( aCountThread );
602 // the value just after calling suspend
603 sal_Int32 nValue = aCountThread->getValue(); // (2)
605 ThreadHelper::thread_sleep_tenth_sec(3);
607 // the value after waiting 3 seconds
608 sal_Int32 nLaterValue = aCountThread->getValue(); // (3)
610 resumeAndWaitThread(aCountThread);
611 termAndJoinThread(aCountThread);
612 delete aCountThread;
614 CPPUNIT_ASSERT_MESSAGE(
615 "Suspend the thread",
616 bRes
618 CPPUNIT_ASSERT_EQUAL_MESSAGE(
619 "Suspend the thread",
620 nValue, nLaterValue
625 CPPUNIT_TEST_SUITE(suspend);
626 CPPUNIT_TEST(suspend_001);
627 // LLA: Deadlocked!!!
628 // CPPUNIT_TEST(createSuspended_002);
629 CPPUNIT_TEST_SUITE_END();
630 }; // class suspend
632 /** Test of the osl::Thread::resume method
634 class resume : public CppUnit::TestFixture
636 public:
637 /** check if the thread run samely as usual after suspend and resume
639 ALGORITHM:
640 compare the values before and after suspend, they should be same,
641 then compare values before and after resume, the difference should be same as the sleep seconds number
643 void resume_001()
645 OCountThread* pCountThread = new OCountThread();
646 bool bRes = pCountThread->create();
647 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
649 suspendCountThread(pCountThread);
651 sal_Int32 nSuspendValue = pCountThread->getValue(); // (2)
652 // suspend for 3 seconds
653 ThreadHelper::thread_sleep_tenth_sec(3);
654 pCountThread->resume();
656 ThreadHelper::thread_sleep_tenth_sec(3);
657 sal_Int32 nResumeValue = pCountThread->getValue();
659 ThreadHelper::thread_sleep_tenth_sec(3);
660 sal_Int32 nLaterValue = pCountThread->getValue();
662 termAndJoinThread(pCountThread);
663 delete pCountThread;
665 t_print("SuspendValue: %d\n", static_cast<int>(nSuspendValue));
666 t_print("ResumeValue: %d\n", static_cast<int>(nResumeValue));
667 t_print("LaterValue: %d\n", static_cast<int>(nLaterValue));
669 /* LLA: this assumption is no longer relevant: nResumeValue == nSuspendValue && */
670 CPPUNIT_ASSERT_MESSAGE(
671 "Suspend then resume the thread",
672 nLaterValue >= 9
674 CPPUNIT_ASSERT_MESSAGE(
675 "Suspend then resume the thread",
676 nResumeValue > nSuspendValue
678 CPPUNIT_ASSERT_MESSAGE(
679 "Suspend then resume the thread",
680 nLaterValue > nResumeValue
685 /** Create a suspended thread then resume, check if the thread has run
687 void resume_002()
689 myThread* newthread = new myThread;
690 bool bRes = newthread->createSuspended();
691 CPPUNIT_ASSERT_MESSAGE ( "Can't create thread!", bRes );
693 newthread->resume();
694 ThreadHelper::thread_sleep_tenth_sec(2);
695 sal_Int32 nValue = newthread->getValue();
697 termAndJoinThread(newthread);
698 delete newthread;
700 t_print(" nValue = %d\n", static_cast<int>(nValue));
702 CPPUNIT_ASSERT_MESSAGE(
703 "Creates a suspended thread, then resume",
704 nValue >= 1
708 CPPUNIT_TEST_SUITE(resume);
709 CPPUNIT_TEST(resume_001);
710 CPPUNIT_TEST(resume_002);
711 CPPUNIT_TEST_SUITE_END();
712 }; // class resume
714 /** Test of the osl::Thread::terminate method
716 class terminate : public CppUnit::TestFixture
718 public:
719 /** Check after call terminate if the running thread running go on executing
721 ALGORITHM:
722 before and after call terminate, the values should be the same
724 void terminate_001()
726 OCountThread* aCountThread = new OCountThread();
727 bool bRes = aCountThread->create();
728 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
730 ThreadHelper::thread_sleep_tenth_sec(2);
731 sal_Int32 nValue = aCountThread->getValue();
732 aCountThread->terminate();
733 ThreadHelper::thread_sleep_tenth_sec(2);
734 sal_Int32 nLaterValue = aCountThread->getValue();
736 // isRunning should be false after terminate
737 bool isRunning = aCountThread->isRunning();
738 aCountThread->join();
739 delete aCountThread;
741 t_print(" nValue = %d\n", static_cast<int>(nValue));
742 t_print("nLaterValue = %d\n", static_cast<int>(nLaterValue));
744 CPPUNIT_ASSERT_MESSAGE(
745 "Terminate the thread",
746 !isRunning
748 CPPUNIT_ASSERT_MESSAGE(
749 "Terminate the thread",
750 nLaterValue >= nValue
753 /** Check if a suspended thread will terminate after call terminate, different on w32 and on UNX
755 void terminate_002()
757 OCountThread* aCountThread = new OCountThread();
758 bool bRes = aCountThread->create();
759 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
761 ThreadHelper::thread_sleep_tenth_sec(1);
762 suspendCountThread(aCountThread);
763 sal_Int32 nValue = aCountThread->getValue();
765 // seems a suspended thread can not be terminated on W32, while on Solaris can
766 resumeAndWaitThread(aCountThread);
768 ThreadHelper::thread_sleep_tenth_sec(2);
770 termAndJoinThread(aCountThread);
771 sal_Int32 nLaterValue = aCountThread->getValue();
772 delete aCountThread;
774 t_print(" nValue = %d\n", static_cast<int>(nValue));
775 t_print("nLaterValue = %d\n", static_cast<int>(nLaterValue));
777 CPPUNIT_ASSERT_MESSAGE(
778 "Suspend then resume the thread",
779 nLaterValue > nValue );
782 CPPUNIT_TEST_SUITE(terminate);
783 CPPUNIT_TEST(terminate_001);
784 CPPUNIT_TEST(terminate_002);
785 CPPUNIT_TEST_SUITE_END();
786 }; // class terminate
788 /** Test of the osl::Thread::join method
790 class join : public CppUnit::TestFixture
792 public:
793 /** Check after call terminate if the thread running function will not go on executing
795 the next statement after join will not exec before the thread terminates
796 ALGORITHM:
797 recode system time at the beginning of the thread run, call join, then record system time again,
798 the difference of the two times should be equal or more than 20 seconds, the CountThread normally terminates
800 void join_001()
802 OCountThread *aCountThread = new OCountThread();
803 bool bRes = aCountThread->create();
804 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
806 StopWatch aStopWatch;
807 aStopWatch.start();
808 // TimeValue aTimeVal_befor;
809 // osl_getSystemTime( &aTimeVal_befor );
810 //t_print("#join:the system time is %d,%d\n", pTimeVal_befor->Seconds,pTimeVal_befor->Nanosec);
812 aCountThread->join();
814 //the below line will be executed after aCountThread terminate
815 // TimeValue aTimeVal_after;
816 // osl_getSystemTime( &aTimeVal_after );
817 aStopWatch.stop();
818 // sal_uInt32 nSec = aTimeVal_after.Seconds - aTimeVal_befor.Seconds;
819 double nSec = aStopWatch.getSeconds();
820 t_print("join_001 nSec=%f\n", nSec);
821 delete aCountThread;
823 CPPUNIT_ASSERT_MESSAGE(
824 "Join the thread: after the thread terminate",
825 nSec >= 2
829 /** after terminated by another thread, join exited immediately
831 ALGORITHM:
832 terminate the thread when value>=3, call join, check the beginning time and time after join,
833 the difference should be 3 seconds, join costs little time
835 void join_002()
837 OCountThread *aCountThread = new OCountThread();
838 bool bRes = aCountThread->create();
839 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
841 //record the time when the running begin
842 // TimeValue aTimeVal_befor;
843 // osl_getSystemTime( &aTimeVal_befor );
844 StopWatch aStopWatch;
845 aStopWatch.start();
847 ThreadHelper::thread_sleep_tenth_sec(10);
848 termAndJoinThread(aCountThread);
850 //the below line will be executed after aCountThread terminate
851 // TimeValue aTimeVal_after;
852 // osl_getSystemTime( &aTimeVal_after );
853 // sal_uInt32 nSec = aTimeVal_after.Seconds - aTimeVal_befor.Seconds;
854 aStopWatch.stop();
855 double nSec = aStopWatch.getSeconds();
856 t_print("join_002 nSec=%f\n", nSec);
858 delete aCountThread;
859 CPPUNIT_ASSERT_MESSAGE(
860 "Join the thread: after thread terminate by another thread",
861 nSec >= 1
865 CPPUNIT_TEST_SUITE(join);
866 CPPUNIT_TEST(join_001);
867 CPPUNIT_TEST(join_002);
868 CPPUNIT_TEST_SUITE_END();
869 }; // class join
871 /** Test of the osl::Thread::isRunning method
873 class isRunning : public CppUnit::TestFixture
875 public:
876 void isRunning_001()
878 OCountThread *aCountThread = new OCountThread();
879 bool bRes = aCountThread->create();
880 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
882 bool bRun = aCountThread->isRunning();
884 ThreadHelper::thread_sleep_tenth_sec(2);
885 termAndJoinThread(aCountThread);
886 bool bTer = aCountThread->isRunning();
887 delete aCountThread;
889 CPPUNIT_ASSERT_MESSAGE(
890 "Test isRunning",
891 bRun
893 CPPUNIT_ASSERT_MESSAGE(
894 "Test isRunning",
895 !bTer
898 /** check the value of isRunning when suspending and after resume
900 void isRunning_002()
902 OCountThread *aCountThread = new OCountThread();
903 bool bRes = aCountThread->create();
904 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
906 // sal_Bool bRunning = aCountThread->isRunning();
907 // sal_Int32 nValue = 0;
908 suspendCountThread(aCountThread);
910 bool bRunning_sup = aCountThread->isRunning();
911 ThreadHelper::thread_sleep_tenth_sec(2);
912 aCountThread->resume();
913 ThreadHelper::thread_sleep_tenth_sec(2);
914 bool bRunning_res = aCountThread->isRunning();
915 termAndJoinThread(aCountThread);
916 bool bRunning_ter = aCountThread->isRunning();
917 delete aCountThread;
919 CPPUNIT_ASSERT_MESSAGE(
920 "Test isRunning",
921 bRes );
922 CPPUNIT_ASSERT_MESSAGE(
923 "Test isRunning",
924 bRunning_sup );
925 CPPUNIT_ASSERT_MESSAGE(
926 "Test isRunning",
927 bRunning_res );
928 CPPUNIT_ASSERT_MESSAGE(
929 "Test isRunning",
930 !bRunning_ter );
934 CPPUNIT_TEST_SUITE(isRunning);
935 CPPUNIT_TEST(isRunning_001);
936 CPPUNIT_TEST(isRunning_002);
937 CPPUNIT_TEST_SUITE_END();
938 }; // class isRunning
940 /// check osl::Thread::setPriority
941 class setPriority : public CppUnit::TestFixture
943 public:
944 // insert your test code here.
945 OString getPrioName(oslThreadPriority _aPriority)
947 OString sPrioStr;
948 switch (_aPriority)
950 case osl_Thread_PriorityHighest:
951 sPrioStr = "Highest"_ostr;
952 break;
954 case osl_Thread_PriorityAboveNormal:
955 sPrioStr = "AboveNormal"_ostr;
956 break;
958 case osl_Thread_PriorityNormal:
959 sPrioStr = "Normal"_ostr;
960 break;
962 case osl_Thread_PriorityBelowNormal:
963 sPrioStr = "BelowNormal"_ostr;
964 break;
966 case osl_Thread_PriorityLowest:
967 sPrioStr = "Lowest"_ostr;
968 break;
969 default:
970 sPrioStr = "unknown"_ostr;
972 return sPrioStr;
975 /** check 2 threads.
977 ALGORITHM:
978 Here the function should show, that 2 different threads,
979 which only increase a value, should run at the same time with same prio.
980 The test fails, if the difference between the two values is more than 5%
981 but IMHO this isn't a failure, it's only a feature of the OS.
984 void check2Threads(oslThreadPriority _aPriority)
986 // initial 5 threads with different priorities
987 OAddThread* pThread = new OAddThread();
988 OAddThread* p2Thread = new OAddThread();
990 //Create them and start running at the same time
991 pThread->create();
992 pThread->setPriority(_aPriority);
993 p2Thread->create();
994 p2Thread->setPriority(_aPriority);
996 ThreadHelper::thread_sleep_tenth_sec(5);
998 pThread->terminate();
999 p2Thread->terminate();
1001 sal_Int32 nValueNormal = pThread->getValue();
1003 sal_Int32 nValueNormal2 = p2Thread->getValue();
1005 OString sPrio = getPrioName(_aPriority);
1006 t_print("After 10 tenth seconds\n");
1008 t_print("nValue in %s Prio Thread is %d\n",sPrio.getStr(), static_cast<int>(nValueNormal));
1009 t_print("nValue in %s Prio Thread is %d\n", sPrio.getStr(), static_cast<int>(nValueNormal2));
1011 // ThreadHelper::thread_sleep_tenth_sec(1);
1012 pThread->join();
1013 p2Thread->join();
1015 delete pThread;
1016 delete p2Thread;
1018 sal_Int32 nDelta = abs(nValueNormal - nValueNormal2);
1019 double nQuotient = std::max(nValueNormal, nValueNormal2);
1020 CPPUNIT_ASSERT_MESSAGE(
1021 "Quotient is zero, which means, there exist no right values.",
1022 nQuotient != 0
1024 double nDeltaPercent = nDelta / nQuotient * 100;
1026 t_print("Delta value %d, percent %f\n", static_cast<int>(nDelta), nDeltaPercent);
1028 // LLA: it's not a bug if the current OS is not able to handle thread scheduling right and good.
1029 // like Windows XP
1030 // LLA: CPPUNIT_ASSERT_MESSAGE(
1031 // LLA: "Run 2 normal threads, the count diff more than 5 percent.",
1032 // LLA: nDeltaPercent <= 5
1033 // LLA: );
1036 void setPriority_001_1()
1038 check2Threads(osl_Thread_PriorityHighest);
1040 void setPriority_001_2()
1042 check2Threads(osl_Thread_PriorityAboveNormal);
1044 void setPriority_001_3()
1046 check2Threads(osl_Thread_PriorityNormal);
1048 void setPriority_001_4()
1050 check2Threads(osl_Thread_PriorityBelowNormal);
1052 void setPriority_001_5()
1054 check2Threads(osl_Thread_PriorityLowest);
1057 void setPriority_002()
1059 // initial 5 threads with different priorities
1061 OAddThread aHighestThread;
1062 OAddThread aAboveNormalThread;
1063 OAddThread aNormalThread;
1064 //OAddThread *aBelowNormalThread = new OAddThread();
1065 //OAddThread *aLowestThread = new OAddThread();
1067 //Create them and start running at the same time
1068 aHighestThread.createSuspended();
1069 aHighestThread.setPriority(osl_Thread_PriorityHighest);
1071 aAboveNormalThread.createSuspended();
1072 aAboveNormalThread.setPriority(osl_Thread_PriorityAboveNormal);
1074 aNormalThread.createSuspended();
1075 aNormalThread.setPriority(osl_Thread_PriorityNormal);
1076 /*aBelowNormalThread->create();
1077 aBelowNormalThread->setPriority(osl_Thread_PriorityBelowNormal);
1078 aLowestThread->create();
1079 aLowestThread->setPriority(osl_Thread_PriorityLowest);
1082 aHighestThread.resume();
1083 aAboveNormalThread.resume();
1084 aNormalThread.resume();
1086 ThreadHelper::thread_sleep_tenth_sec(5);
1088 aHighestThread.suspend();
1089 aAboveNormalThread.suspend();
1090 aNormalThread.suspend();
1092 termAndJoinThread(&aNormalThread);
1093 termAndJoinThread(&aAboveNormalThread);
1094 termAndJoinThread(&aHighestThread);
1095 //aBelowNormalThread->terminate();
1096 //aLowestThread->terminate();
1098 sal_Int32 nValueHighest = aHighestThread.getValue();
1100 sal_Int32 nValueAboveNormal = aAboveNormalThread.getValue();
1102 sal_Int32 nValueNormal = aNormalThread.getValue();
1104 t_print("After 10 tenth seconds\n");
1105 t_print("nValue in Highest Prio Thread is %d\n", static_cast<int>(nValueHighest));
1106 t_print("nValue in AboveNormal Prio Thread is %d\n", static_cast<int>(nValueAboveNormal));
1107 t_print("nValue in Normal Prio Thread is %d\n", static_cast<int>(nValueNormal));
1109 #ifndef _WIN32
1110 CPPUNIT_ASSERT_MESSAGE(
1111 "SetPriority",
1112 nValueHighest > 0
1114 CPPUNIT_ASSERT_MESSAGE(
1115 "SetPriority",
1116 nValueAboveNormal > 0
1118 CPPUNIT_ASSERT_MESSAGE(
1119 "SetPriority",
1120 nValueNormal > 0
1122 #endif
1125 void setPriority_003()
1127 // initial 5 threads with different priorities
1128 OAddThread pHighestThread;
1129 OAddThread pAboveNormalThread;
1130 OAddThread pNormalThread;
1131 OAddThread pBelowNormalThread;
1132 OAddThread pLowestThread;
1134 //Create them and start running at the same time
1135 pHighestThread.createSuspended();
1136 pHighestThread.setPriority(osl_Thread_PriorityHighest);
1138 pAboveNormalThread.createSuspended();
1139 pAboveNormalThread.setPriority(osl_Thread_PriorityAboveNormal);
1141 pNormalThread.createSuspended();
1142 pNormalThread.setPriority(osl_Thread_PriorityNormal);
1144 pBelowNormalThread.createSuspended();
1145 pBelowNormalThread.setPriority(osl_Thread_PriorityBelowNormal);
1147 pLowestThread.createSuspended();
1148 pLowestThread.setPriority(osl_Thread_PriorityLowest);
1150 pHighestThread.resume();
1151 pAboveNormalThread.resume();
1152 pNormalThread.resume();
1153 pBelowNormalThread.resume();
1154 pLowestThread.resume();
1156 ThreadHelper::thread_sleep_tenth_sec(5);
1158 pHighestThread.suspend();
1159 pAboveNormalThread.suspend();
1160 pNormalThread.suspend();
1161 pBelowNormalThread.suspend();
1162 pLowestThread.suspend();
1164 termAndJoinThread(&pHighestThread);
1165 termAndJoinThread(&pAboveNormalThread);
1166 termAndJoinThread(&pNormalThread);
1167 termAndJoinThread(&pBelowNormalThread);
1168 termAndJoinThread(&pLowestThread);
1170 sal_Int32 nValueHighest = pHighestThread.getValue();
1172 sal_Int32 nValueAboveNormal = pAboveNormalThread.getValue();
1174 sal_Int32 nValueNormal = pNormalThread.getValue();
1176 sal_Int32 nValueBelowNormal = pBelowNormalThread.getValue();
1178 sal_Int32 nValueLowest = pLowestThread.getValue();
1180 t_print("After 10 tenth seconds\n");
1181 t_print("nValue in Highest Prio Thread is %d\n", static_cast<int>(nValueHighest));
1182 t_print("nValue in AboveNormal Prio Thread is %d\n", static_cast<int>(nValueAboveNormal));
1183 t_print("nValue in Normal Prio Thread is %d\n", static_cast<int>(nValueNormal));
1184 t_print("nValue in BelowNormal Prio Thread is %d\n", static_cast<int>(nValueBelowNormal));
1185 t_print("nValue in Lowest Prio Thread is %d\n", static_cast<int>(nValueLowest));
1187 #ifndef _WIN32
1188 CPPUNIT_ASSERT_MESSAGE(
1189 "SetPriority",
1190 nValueHighest > 0
1192 CPPUNIT_ASSERT_MESSAGE(
1193 "SetPriority",
1194 nValueAboveNormal > 0
1196 CPPUNIT_ASSERT_MESSAGE(
1197 "SetPriority",
1198 nValueNormal > 0
1200 CPPUNIT_ASSERT_MESSAGE(
1201 "SetPriority",
1202 nValueBelowNormal > 0
1204 CPPUNIT_ASSERT_MESSAGE(
1205 "SetPriority",
1206 nValueLowest > 0
1208 #endif
1211 void setPriority_004()
1213 // initial 5 threads with different priorities
1214 // OAddThread *pHighestThread = new OAddThread();
1215 OAddThread pAboveNormalThread;
1216 OAddThread pNormalThread;
1217 OAddThread pBelowNormalThread;
1218 OAddThread pLowestThread;
1220 //Create them and start running at the same time
1221 // pHighestThread->createSuspended();
1222 // pHighestThread->setPriority(osl_Thread_PriorityHighest);
1224 pAboveNormalThread.createSuspended();
1225 pAboveNormalThread.setPriority(osl_Thread_PriorityAboveNormal);
1227 pNormalThread.createSuspended();
1228 pNormalThread.setPriority(osl_Thread_PriorityNormal);
1230 pBelowNormalThread.createSuspended();
1231 pBelowNormalThread.setPriority(osl_Thread_PriorityBelowNormal);
1233 pLowestThread.createSuspended();
1234 pLowestThread.setPriority(osl_Thread_PriorityLowest);
1236 // pHighestThread->resume();
1237 pAboveNormalThread.resume();
1238 pNormalThread.resume();
1239 pBelowNormalThread.resume();
1240 pLowestThread.resume();
1242 ThreadHelper::thread_sleep_tenth_sec(5);
1244 // pHighestThread->suspend();
1245 pAboveNormalThread.suspend();
1246 pNormalThread.suspend();
1247 pBelowNormalThread.suspend();
1248 pLowestThread.suspend();
1250 // termAndJoinThread(pHighestThread);
1251 termAndJoinThread(&pAboveNormalThread);
1252 termAndJoinThread(&pNormalThread);
1253 termAndJoinThread(&pBelowNormalThread);
1254 termAndJoinThread(&pLowestThread);
1256 // sal_Int32 nValueHighest = 0;
1257 // nValueHighest = pHighestThread->getValue();
1259 sal_Int32 nValueAboveNormal = pAboveNormalThread.getValue();
1261 sal_Int32 nValueNormal = pNormalThread.getValue();
1263 sal_Int32 nValueBelowNormal = pBelowNormalThread.getValue();
1265 sal_Int32 nValueLowest = pLowestThread.getValue();
1267 t_print("After 5 tenth seconds\n");
1268 t_print("nValue in AboveNormal Prio Thread is %d\n", static_cast<int>(nValueAboveNormal));
1269 t_print("nValue in Normal Prio Thread is %d\n", static_cast<int>(nValueNormal));
1270 t_print("nValue in BelowNormal Prio Thread is %d\n", static_cast<int>(nValueBelowNormal));
1271 t_print("nValue in Lowest Prio Thread is %d\n", static_cast<int>(nValueLowest));
1273 // delete pHighestThread;
1275 #ifndef _WIN32
1276 CPPUNIT_ASSERT_MESSAGE(
1277 "SetPriority",
1278 /* nValueHighest > 0 && */
1279 nValueAboveNormal > 0
1281 CPPUNIT_ASSERT_MESSAGE(
1282 "SetPriority",
1283 nValueNormal > 0
1285 CPPUNIT_ASSERT_MESSAGE(
1286 "SetPriority",
1287 nValueBelowNormal > 0
1289 CPPUNIT_ASSERT_MESSAGE(
1290 "SetPriority",
1291 nValueLowest > 0
1293 #endif
1295 void setPriority_005()
1297 // initial 5 threads with different priorities
1298 // OAddThread *pHighestThread = new OAddThread();
1299 // OAddThread *pAboveNormalThread = new OAddThread();
1300 OAddThread pNormalThread;
1301 OAddThread pBelowNormalThread;
1302 OAddThread pLowestThread;
1304 //Create them and start running at the same time
1305 // pHighestThread->createSuspended();
1306 // pHighestThread->setPriority(osl_Thread_PriorityHighest);
1308 // pAboveNormalThread->createSuspended();
1309 // pAboveNormalThread->setPriority(osl_Thread_PriorityAboveNormal);
1311 pNormalThread.createSuspended();
1312 pNormalThread.setPriority(osl_Thread_PriorityNormal);
1314 pBelowNormalThread.createSuspended();
1315 pBelowNormalThread.setPriority(osl_Thread_PriorityBelowNormal);
1317 pLowestThread.createSuspended();
1318 pLowestThread.setPriority(osl_Thread_PriorityLowest);
1320 // pHighestThread->resume();
1321 // pAboveNormalThread->resume();
1322 pNormalThread.resume();
1323 pBelowNormalThread.resume();
1324 pLowestThread.resume();
1326 ThreadHelper::thread_sleep_tenth_sec(5);
1328 // pHighestThread->suspend();
1329 // pAboveNormalThread->suspend();
1330 pNormalThread.suspend();
1331 pBelowNormalThread.suspend();
1332 pLowestThread.suspend();
1334 // termAndJoinThread(pHighestThread);
1335 // termAndJoinThread(pAboveNormalThread);
1336 termAndJoinThread(&pNormalThread);
1337 termAndJoinThread(&pBelowNormalThread);
1338 termAndJoinThread(&pLowestThread);
1340 // sal_Int32 nValueHighest = 0;
1341 // nValueHighest = pHighestThread->getValue();
1343 // sal_Int32 nValueAboveNormal = 0;
1344 // nValueAboveNormal = pAboveNormalThread->getValue();
1346 sal_Int32 nValueNormal = pNormalThread.getValue();
1348 sal_Int32 nValueBelowNormal = pBelowNormalThread.getValue();
1350 sal_Int32 nValueLowest = pLowestThread.getValue();
1352 t_print("After 5 tenth seconds\n");
1353 t_print("nValue in Normal Prio Thread is %d\n", static_cast<int>(nValueNormal));
1354 t_print("nValue in BelowNormal Prio Thread is %d\n", static_cast<int>(nValueBelowNormal));
1355 t_print("nValue in Lowest Prio Thread is %d\n", static_cast<int>(nValueLowest));
1357 #ifndef _WIN32
1358 CPPUNIT_ASSERT_MESSAGE(
1359 "SetPriority",
1360 /* nValueHighest > 0 && */
1361 /* nValueAboveNormal > 0 && */
1362 nValueNormal > 0
1364 CPPUNIT_ASSERT_MESSAGE(
1365 "SetPriority",
1366 nValueBelowNormal > 0
1368 CPPUNIT_ASSERT_MESSAGE(
1369 "SetPriority",
1370 nValueLowest > 0
1372 #endif
1375 CPPUNIT_TEST_SUITE(setPriority);
1376 #ifndef __sun
1377 CPPUNIT_TEST(setPriority_002);
1378 CPPUNIT_TEST(setPriority_003);
1379 CPPUNIT_TEST(setPriority_004);
1380 CPPUNIT_TEST(setPriority_005);
1381 #endif
1382 CPPUNIT_TEST(setPriority_001_1);
1383 CPPUNIT_TEST(setPriority_001_2);
1384 CPPUNIT_TEST(setPriority_001_3);
1385 CPPUNIT_TEST(setPriority_001_4);
1386 CPPUNIT_TEST(setPriority_001_5);
1387 CPPUNIT_TEST_SUITE_END();
1388 }; // class setPriority
1390 /** Test of the osl::Thread::getPriority method
1392 class getPriority : public CppUnit::TestFixture
1394 public:
1395 // insert your test code here.
1396 void getPriority_001()
1398 OAddThread *pHighestThread = new OAddThread();
1400 //Create them and start running at the same time
1401 pHighestThread->create();
1402 pHighestThread->setPriority(osl_Thread_PriorityHighest);
1404 oslThreadPriority aPriority = pHighestThread->getPriority();
1405 termAndJoinThread(pHighestThread);
1406 delete pHighestThread;
1408 ThreadHelper::outputPriority(aPriority);
1410 // LLA: Priority settings may not work within some OS versions.
1411 #if defined(_WIN32) || defined(__sun)
1412 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1413 "getPriority",
1414 osl_Thread_PriorityHighest, aPriority
1416 #else
1417 // LLA: Linux
1418 // NO_PTHREAD_PRIORITY ???
1419 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1420 "getPriority",
1421 osl_Thread_PriorityNormal, aPriority
1423 #endif
1426 CPPUNIT_TEST_SUITE(getPriority);
1427 CPPUNIT_TEST(getPriority_001);
1428 CPPUNIT_TEST_SUITE_END();
1429 }; // class getPriority
1431 class getIdentifier : public CppUnit::TestFixture
1433 public:
1434 // initialise your test code values here.
1436 void getIdentifier_001()
1438 // insert your test code here.
1441 CPPUNIT_TEST_SUITE(getIdentifier);
1442 CPPUNIT_TEST(getIdentifier_001);
1443 CPPUNIT_TEST_SUITE_END();
1444 }; // class getIdentifier
1446 /** Test of the osl::Thread::getCurrentIdentifier method
1448 class getCurrentIdentifier : public CppUnit::TestFixture
1450 public:
1451 void getCurrentIdentifier_001()
1453 oslThreadIdentifier oId;
1454 OCountThread* pCountThread = new OCountThread;
1455 pCountThread->create();
1456 pCountThread->setWait(3);
1457 oId = Thread::getCurrentIdentifier();
1458 oslThreadIdentifier oIdChild = pCountThread->getIdentifier();
1459 termAndJoinThread(pCountThread);
1460 delete pCountThread;
1462 CPPUNIT_ASSERT_MESSAGE(
1463 "Get the identifier for the current active thread.",
1464 oId != oIdChild);
1467 CPPUNIT_TEST_SUITE(getCurrentIdentifier);
1468 CPPUNIT_TEST(getCurrentIdentifier_001);
1469 CPPUNIT_TEST_SUITE_END();
1470 }; // class getCurrentIdentifier
1472 /** Test of the osl::Thread::wait method
1474 class waittest : public CppUnit::TestFixture
1476 public:
1477 /** call wait in the run method
1479 ALGORITHM:
1480 tested thread wait nWaitSec seconds, main thread sleep (2) seconds,
1481 then terminate the tested thread, due to the fact that the thread do a sleep(1) + wait(5)
1482 it's finish after 6 seconds.
1484 void wait_001()
1486 OCountThread *aCountThread = new OCountThread();
1487 sal_Int32 nWaitSec = 5;
1488 aCountThread->setWait(nWaitSec);
1489 // thread runs at least 5 seconds.
1490 bool bRes = aCountThread->create();
1491 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
1493 //record the time when the running begin
1494 StopWatch aStopWatch;
1495 aStopWatch.start();
1497 // wait a little bit, to let the thread the time, to start
1498 ThreadHelper::thread_sleep_tenth_sec( 4 );
1500 // if wait works,
1501 // this function returns, after 4 sec. later
1502 termAndJoinThread(aCountThread);
1504 // value should be one.
1505 sal_Int32 nValue = aCountThread->getValue();
1507 aStopWatch.stop();
1509 // sal_uInt32 nSec = aTimeVal_after.Seconds - aTimeVal_befor.Seconds;
1510 double nTenthSec = aStopWatch.getTenthSec();
1511 double nSec = aStopWatch.getSeconds();
1512 delete aCountThread;
1513 t_print("nTenthSec = %f \n", nTenthSec);
1514 t_print("nSec = %f \n", nSec);
1515 t_print("nValue = %d \n", static_cast<int>(nValue));
1517 CPPUNIT_ASSERT_MESSAGE(
1518 "Wait: Blocks the calling thread for the given number of time.",
1519 nTenthSec >= 5
1521 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1522 "Wait: Blocks the calling thread for the given number of time.",
1523 sal_Int32(1), nValue
1528 CPPUNIT_TEST_SUITE(waittest);
1529 CPPUNIT_TEST(wait_001);
1530 CPPUNIT_TEST_SUITE_END();
1531 }; // class waittest
1533 /** osl::Thread::yield method: can not design good test scenario to test up to now
1535 class yield : public CppUnit::TestFixture
1537 public:
1538 void yield_001()
1540 // insert your test code here.
1543 CPPUNIT_TEST_SUITE(yield);
1544 CPPUNIT_TEST(yield_001);
1545 CPPUNIT_TEST_SUITE_END();
1546 }; // class yield
1548 /** Test of the osl::Thread::schedule method
1550 class schedule : public CppUnit::TestFixture
1552 public:
1554 /** The requested thread will get terminate the next time schedule() is called.
1556 Note: on UNX, if call suspend thread is not the to be suspended thread, the to be
1557 suspended thread will get suspended the next time schedule() is called,
1558 while on w32, it's nothing with schedule.
1560 check if suspend and terminate work well via schedule
1562 void schedule_001()
1564 OAddThread* aThread = new OAddThread();
1565 bool bRes = aThread->create();
1566 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
1568 ThreadHelper::thread_sleep_tenth_sec(2);
1569 aThread->suspend();
1570 ThreadHelper::thread_sleep_tenth_sec(1);
1571 sal_Int32 nValue = aThread->getValue();
1572 ThreadHelper::thread_sleep_tenth_sec(3);
1573 sal_Int32 nLaterValue = aThread->getValue();
1574 // resumeAndWaitThread(aThread);
1575 t_print(" value = %d\n", static_cast<int>(nValue));
1576 t_print("later value = %d\n", static_cast<int>(nLaterValue));
1577 // if value and latervalue not equal, then the thread would not suspended
1579 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1580 "Schedule: suspend works.",
1581 nValue, nLaterValue
1584 aThread->resume();
1585 ThreadHelper::thread_sleep_tenth_sec(2);
1587 aThread->terminate();
1588 sal_Int32 nValue_term = aThread->getValue();
1590 aThread->join();
1591 sal_Int32 nValue_join = aThread->getValue();
1593 t_print("value after term = %d\n", static_cast<int>(nValue_term));
1594 t_print("value after join = %d\n", static_cast<int>(nValue_join));
1596 // nValue_term and nValue_join should be the same
1597 // but should be differ from nValue
1599 delete aThread;
1600 //check if thread really terminate after call terminate, if join immediately return
1601 CPPUNIT_ASSERT_MESSAGE(
1602 "Schedule: Returns False if the thread should terminate.",
1603 nValue_join - nValue_term <= 1
1605 CPPUNIT_ASSERT_MESSAGE(
1606 "Schedule: Returns False if the thread should terminate.",
1607 nValue_join - nValue_term >= 0
1612 /** design a thread that has not call schedule in the workfunction--run method
1614 void schedule_002()
1616 ONoScheduleThread aThread; // this thread runs 10 sec. (no schedule() used)
1617 bool bRes = aThread.create();
1618 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes );
1620 ThreadHelper::thread_sleep_tenth_sec(2);
1621 aThread.suspend();
1622 sal_Int32 nValue = aThread.getValue();
1624 ThreadHelper::thread_sleep_tenth_sec(3);
1625 sal_Int32 nLaterValue = aThread.getValue();
1626 ThreadHelper::thread_sleep_tenth_sec(5);
1628 resumeAndWaitThread(&aThread);
1630 t_print(" value = %d\n", static_cast<int>(nValue));
1631 t_print("later value = %d\n", static_cast<int>(nLaterValue));
1633 //On windows, suspend works, so the values are same
1634 #ifdef _WIN32
1635 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1636 "Schedule: don't schedule in thread run method, suspend works.",
1637 nValue, nLaterValue
1639 #endif
1641 //On UNX, suspend does not work, so the difference of the values equals to sleep seconds number
1642 #ifdef UNX
1643 aThread.resume();
1644 CPPUNIT_ASSERT_MESSAGE(
1645 "Schedule: don't schedule in thread run method, suspend does not work too.",
1646 nLaterValue > nValue
1648 #endif
1650 // terminate will not work if no schedule in thread's work function
1651 termAndJoinThread(&aThread);
1652 sal_Int32 nValue_term = aThread.getValue();
1654 t_print(" value term = %d\n", static_cast<int>(nValue_term));
1656 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1657 "Schedule: don't schedule in thread run method, terminate failed.",
1658 static_cast<sal_Int32>(10), nValue_term
1662 CPPUNIT_TEST_SUITE(schedule);
1663 CPPUNIT_TEST(schedule_001);
1664 CPPUNIT_TEST(schedule_002);
1665 CPPUNIT_TEST_SUITE_END();
1666 }; // class schedule
1668 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::create, "osl_Thread");
1669 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::createSuspended, "osl_Thread");
1670 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::suspend, "osl_Thread");
1671 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::resume, "osl_Thread");
1672 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::terminate, "osl_Thread");
1673 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::join, "osl_Thread");
1674 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::isRunning, "osl_Thread");
1675 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::setPriority, "osl_Thread");
1676 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::getPriority, "osl_Thread");
1677 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::getIdentifier, "osl_Thread");
1678 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::getCurrentIdentifier, "osl_Thread");
1679 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::waittest, "osl_Thread");
1680 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::yield, "osl_Thread");
1681 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::schedule, "osl_Thread");
1682 } // namespace osl_Thread
1684 // destroy function when the binding thread terminate
1685 static void destroyCallback(void * data)
1687 delete[] static_cast<char *>(data);
1690 static ThreadData myThreadData(destroyCallback);
1692 namespace {
1694 class myKeyThread : public Thread
1696 public:
1697 // a public char member for test result checking
1698 char m_Char_Test;
1699 // for pass thread-special data to thread
1700 explicit myKeyThread(const char cData)
1701 : m_Char_Test(0)
1703 m_nData = cData;
1705 private:
1706 char m_nData;
1708 void SAL_CALL run() override
1710 char * pc = new char[2];
1711 // strcpy(pc, &m_nData);
1712 memcpy(pc, &m_nData, 1);
1713 pc[1] = '\0';
1715 myThreadData.setData(pc);
1716 char* pData = static_cast<char*>(myThreadData.getData());
1717 m_Char_Test = *pData;
1718 // wait for long time to check the data value in main thread
1719 ThreadHelper::thread_sleep_tenth_sec(3);
1721 public:
1722 virtual ~myKeyThread() override
1724 if (isRunning())
1726 t_print("error: not terminated.\n");
1733 static ThreadData idData;
1735 namespace {
1737 class idThread: public Thread
1739 public:
1740 oslThreadIdentifier m_Id;
1741 private:
1742 void SAL_CALL run() override
1744 std::unique_ptr<oslThreadIdentifier> pId( new oslThreadIdentifier );
1745 *pId = getIdentifier();
1746 idData.setData(pId.get());
1747 oslThreadIdentifier* pIdData = static_cast<oslThreadIdentifier*>(idData.getData());
1748 //t_print("Thread %d has Data %d\n", getIdentifier(), *pIdData);
1749 m_Id = *pIdData;
1752 public:
1753 virtual ~idThread() override
1755 if (isRunning())
1757 t_print("error: not terminated.\n");
1764 namespace osl_ThreadData
1767 class ctors : public CppUnit::TestFixture
1769 public:
1771 // insert your test code here.
1772 void ctor_001()
1777 CPPUNIT_TEST_SUITE(ctors);
1778 CPPUNIT_TEST(ctor_001);
1779 CPPUNIT_TEST_SUITE_END();
1780 }; // class ctors
1782 class setData : public CppUnit::TestFixture
1784 public:
1786 /** the same instance of the class can have different values in different threads
1788 void setData_001()
1790 idThread aThread1;
1791 aThread1.create();
1792 idThread aThread2;
1793 aThread2.create();
1795 aThread1.join();
1796 aThread2.join();
1798 oslThreadIdentifier aThreadId1 = aThread1.getIdentifier();
1799 oslThreadIdentifier aThreadId2 = aThread2.getIdentifier();
1801 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1802 "ThreadData setData: ",
1803 aThread1.m_Id, aThreadId1
1805 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1806 "ThreadData setData: ",
1807 aThread2.m_Id, aThreadId2
1812 void setData_002()
1814 // at first, set the data a value
1815 char* pc = new char[2];
1816 char nData = 'm';
1817 pc[0] = nData;
1818 pc[1] = '\0';
1820 myThreadData.setData(pc);
1822 myKeyThread aThread1('a');
1823 aThread1.create();
1824 myKeyThread aThread2('b');
1825 aThread2.create();
1826 // aThread1 and aThread2 should have not terminated yet, check current data, not 'a' 'b'
1827 char* pChar = static_cast<char*>(myThreadData.getData());
1828 char aChar = *pChar;
1830 aThread1.join();
1831 aThread2.join();
1833 // the saved thread data of aThread1 & aThread2, different
1834 char cData1 = aThread1.m_Char_Test;
1835 char cData2 = aThread2.m_Char_Test;
1837 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1838 "ThreadData setData: ",
1839 'a', cData1
1841 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1842 "ThreadData setData: ",
1843 'b', cData2
1845 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1846 "ThreadData setData: ",
1847 'm', aChar
1851 /** setData the second time, and then getData
1853 void setData_003()
1855 // at first, set the data a value
1856 char* pc = new char[2];
1857 char nData = 'm';
1858 memcpy(pc, &nData, 1);
1859 pc[1] = '\0';
1860 myThreadData.setData(pc);
1862 myKeyThread aThread1('a');
1863 aThread1.create();
1864 myKeyThread aThread2('b');
1865 aThread2.create();
1866 // aThread1 and aThread2 should have not terminated yet
1867 // setData the second time
1868 char* pc2 = new char[2];
1869 nData = 'o';
1870 memcpy(pc2, &nData, 1);
1871 pc2[1] = '\0';
1873 myThreadData.setData(pc2);
1874 char* pChar = static_cast<char*>(myThreadData.getData());
1875 char aChar = *pChar;
1877 aThread1.join();
1878 aThread2.join();
1880 // the saved thread data of aThread1 & aThread2, different
1881 char cData1 = aThread1.m_Char_Test;
1882 char cData2 = aThread2.m_Char_Test;
1884 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1885 "ThreadData setData: ",
1886 'a', cData1
1888 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1889 "ThreadData setData: ",
1890 'b', cData2
1892 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1893 "ThreadData setData: ",
1894 'o', aChar
1898 CPPUNIT_TEST_SUITE(setData);
1899 CPPUNIT_TEST(setData_001);
1900 CPPUNIT_TEST(setData_002);
1901 CPPUNIT_TEST(setData_003);
1902 CPPUNIT_TEST_SUITE_END();
1903 }; // class setData
1905 class getData : public CppUnit::TestFixture
1907 public:
1909 // After setData in child threads, get Data in the main thread, should be independent
1910 void getData_001()
1912 char* pc = new char[2];
1913 strcpy(pc, "i");
1914 myThreadData.setData(pc);
1916 myKeyThread aThread1('c');
1917 aThread1.create();
1918 myKeyThread aThread2('d');
1919 aThread2.create();
1921 aThread1.join();
1922 aThread2.join();
1924 char cData1 = aThread1.m_Char_Test;
1925 char cData2 = aThread2.m_Char_Test;
1927 char* pChar = static_cast<char*>(myThreadData.getData());
1928 char aChar = *pChar;
1930 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1931 "ThreadData setData: ",
1932 'c', cData1
1934 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1935 "ThreadData setData: ",
1936 'd', cData2
1938 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1939 "ThreadData setData: ",
1940 'i', aChar
1944 // setData then change the value in the address data pointer points,
1945 // and then getData, should get the new value
1946 void getData_002()
1948 char* pc = new char[2];
1949 char nData = 'i';
1950 memcpy(pc, &nData, 1);
1951 pc[1] = '\0';
1953 myThreadData.setData(pc);
1955 myKeyThread aThread1('a');
1956 aThread1.create();
1957 myKeyThread aThread2('b');
1958 aThread2.create();
1960 // change the value which pc points
1961 char nData2 = 'j';
1962 memcpy(pc, &nData2, 1);
1963 pc[1] = '\0';
1965 void* pChar = myThreadData.getData();
1966 char aChar = *static_cast<char*>(pChar);
1968 aThread1.join();
1969 aThread2.join();
1971 char cData1 = aThread1.m_Char_Test;
1972 char cData2 = aThread2.m_Char_Test;
1974 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1975 "ThreadData setData: ",
1976 'a', cData1
1978 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1979 "ThreadData setData: ",
1980 'b', cData2
1982 CPPUNIT_ASSERT_EQUAL_MESSAGE(
1983 "ThreadData setData: ",
1984 'j', aChar
1989 CPPUNIT_TEST_SUITE(getData);
1990 CPPUNIT_TEST(getData_001);
1991 CPPUNIT_TEST(getData_002);
1992 CPPUNIT_TEST_SUITE_END();
1993 }; // class getData
1995 CPPUNIT_TEST_SUITE_REGISTRATION(osl_ThreadData::ctors);
1996 CPPUNIT_TEST_SUITE_REGISTRATION(osl_ThreadData::setData);
1997 CPPUNIT_TEST_SUITE_REGISTRATION(osl_ThreadData::getData);
1998 } // namespace osl_ThreadData
2000 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */