xref: /aoo42x/main/sal/qa/osl/process/osl_Thread.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sal.hxx"
30 //------------------------------------------------------------------------
31 // include files
32 //------------------------------------------------------------------------
33 #include <sal/types.h>
34 
35 #ifndef _RTL_USTRING_HXX_
36 #include <rtl/string.hxx>
37 #endif
38 
39 #ifndef _RTL_USTRING_HXX_
40 #include <rtl/strbuf.hxx>
41 #endif
42 
43 #ifndef _OSL_THREAD_HXX
44 #include <osl/thread.hxx>
45 #endif
46 
47 #ifndef _OSL_MUTEX_HXX
48 #include <osl/mutex.hxx>
49 #endif
50 #include <osl/time.h>
51 
52 #include <testshl/simpleheader.hxx>
53 
54 using namespace osl;
55 using namespace rtl;
56 
57 #ifdef UNX
58 #include <unistd.h>
59 #include <time.h>
60 #endif
61 // -----------------------------------------------------------------------------
62 // Kleine Stopuhr
63 class StopWatch {
64     TimeValue t1,t2;                                // Start und Stopzeit
65 
66 protected:
67     sal_Int32 m_nNanoSec;
68     sal_Int32 m_nSeconds;
69 
70     bool m_bIsValid;                                   // TRUE, wenn gestartet und gestoppt
71     bool m_bIsRunning;                                 // TRUE, wenn gestartet.
72 
73 public:
74     StopWatch();
75     ~StopWatch() {}
76 
77     void start();                                 // Startet Timer
78     void stop();                                  // Stoppt Timer
79 
80     double getSeconds() const;
81     double getTenthSec() const;
82 };
83 
84 // ================================= Stop Watch =================================
85 
86 // Eine kleine Stop-Uhr fuer den internen Gebrauch.
87 // (c) Lars Langhans 29.12.1996 22:10
88 
89 StopWatch::StopWatch():m_bIsValid(false),m_bIsRunning(false) {}
90 
91 void StopWatch::start()
92 {
93 // pre: %
94 // post: Start Timer
95 
96     m_bIsValid = false;
97     m_bIsRunning = true;
98     osl_getSystemTime( &t1 );
99     t_print("# %d %d nsecs\n", t1.Seconds, t1.Nanosec);
100     // gettimeofday(&t1, 0);
101 }
102 
103 void StopWatch::stop()
104 {
105 // pre: Timer should be started
106 // post: Timer will stopped
107 
108     // gettimeofday(&t2, 0);                         // Timer ausfragen
109     osl_getSystemTime( &t2 );
110     t_print("# %d %d nsecs\n", t2.Seconds, t2.Nanosec);
111 
112     if (m_bIsRunning)
113     {                                // check ob gestartet.
114 // LLA: old         m_nNanoSec = static_cast<sal_Int32>(t2.Nanosec) - static_cast<sal_Int32>(t1.Nanosec);
115 // LLA: old         m_nSeconds = static_cast<sal_Int32>(t2.Seconds) - static_cast<sal_Int32>(t1.Seconds);
116 // LLA: old         if (m_nNanoSec < 0)
117 // LLA: old         {
118 // LLA: old             m_nNanoSec += 1000000000;
119 // LLA: old             m_nSeconds -= 1;
120 // LLA: old         }
121         //m_nNanoSec = t2.Nanosec - t1.Nanosec;
122         m_nSeconds = static_cast<sal_Int32>(t2.Seconds) - static_cast<sal_Int32>(t1.Seconds);
123         if ( t2.Nanosec > t1.Nanosec )
124        		m_nNanoSec = static_cast<sal_Int32>(t2.Nanosec) - static_cast<sal_Int32>(t1.Nanosec);
125        	else
126        	{
127 		m_nNanoSec = 1000000000 + static_cast<sal_Int32>(t2.Nanosec) - static_cast<sal_Int32>(t1.Nanosec);
128             	m_nSeconds -= 1;
129 	}
130 	t_print("# %d %d nsecs\n", m_nSeconds, m_nNanoSec );
131         //if (m_nNanoSec < 0)
132         //{
133             //m_nNanoSec += 1000000000;
134             //m_nSeconds -= 1;
135         //}
136         m_bIsValid = true;
137         m_bIsRunning = false;
138     }
139 }
140 
141 double StopWatch::getSeconds() const
142 {
143 // pre: gueltig = TRUE
144 // BACK: Zeit in Sekunden.
145 
146     double nValue = 0.0;
147     if (m_bIsValid)
148     {
149         nValue = double(m_nNanoSec) / 1000000000.0 + m_nSeconds; // milli micro nano
150     }
151     return nValue;
152 }
153 
154 double StopWatch::getTenthSec() const
155 {
156     double nValue = 0.0;
157     if (m_bIsValid)
158     {
159         nValue = double(m_nNanoSec) / 100000000.0 + m_nSeconds * 10;
160     }
161     return nValue ;
162 }
163 
164 // -----------------------------------------------------------------------------
165 template <class T>
166 class ThreadSafeValue
167 {
168     T   m_nFlag;
169     Mutex   m_aMutex;
170 public:
171     ThreadSafeValue(T n = 0): m_nFlag(n) {}
172     T getValue()
173         {
174             //block if already acquired by another thread.
175             osl::MutexGuard g(m_aMutex);
176             return m_nFlag;
177         }
178     void addValue(T n)
179         {
180             //only one thread operate on the flag.
181             osl::MutexGuard g(m_aMutex);
182             m_nFlag += n;
183         }
184     void acquire() {m_aMutex.acquire();}
185     void release() {m_aMutex.release();}
186 };
187 
188 // -----------------------------------------------------------------------------
189 namespace ThreadHelper
190 {
191     // typedef enum {
192     //     QUIET=1,
193     //     VERBOSE
194     // } eSleepVerboseMode;
195 
196     void thread_sleep_tenth_sec(sal_Int32 _nTenthSec/*, eSleepVerboseMode nVerbose = VERBOSE*/)
197     {
198         // if (nVerbose == VERBOSE)
199         // {
200         //     t_print("wait %d tenth seconds. ", _nTenthSec );
201         //     fflush(stdout);
202         // }
203 #ifdef WNT      //Windows
204         Sleep(_nTenthSec * 100 );
205 #endif
206 #if ( defined UNX ) || ( defined OS2 )  //Unix
207         TimeValue nTV;
208         nTV.Seconds = static_cast<sal_uInt32>( _nTenthSec/10 );
209         nTV.Nanosec = ( (_nTenthSec%10 ) * 100000000 );
210         osl_waitThread(&nTV);
211 #endif
212         // if (nVerbose == VERBOSE)
213         // {
214         //     t_print("done\n");
215         // }
216     }
217 
218     void outputPriority(oslThreadPriority const& _aPriority)
219     {
220         // LLA: output the priority
221         if (_aPriority == osl_Thread_PriorityHighest)
222         {
223             t_print("Prio is High\n");
224         }
225         else if (_aPriority == osl_Thread_PriorityAboveNormal)
226         {
227             t_print("Prio is above normal\n");
228         }
229         else if (_aPriority == osl_Thread_PriorityNormal)
230         {
231             t_print("Prio is normal\n");
232         }
233         else if (_aPriority == osl_Thread_PriorityBelowNormal)
234         {
235             t_print("Prio is below normal\n");
236         }
237         else if (_aPriority == osl_Thread_PriorityLowest)
238         {
239             t_print("Prio is lowest\n");
240         }
241         else
242         {
243             t_print("Prio is unknown\n");
244         }
245     }
246 }
247 
248 /** Simple thread for testing Thread-create.
249 
250     Just add 1 of value 0, and after running, result is 1.
251  */
252 class myThread : public Thread
253 {
254     ThreadSafeValue<sal_Int32> m_aFlag;
255 public:
256     sal_Int32 getValue() { return m_aFlag.getValue(); }
257 protected:
258     /** guarded value which initialized 0
259 
260         @see ThreadSafeValue
261     */
262     void SAL_CALL run()
263         {
264             while(schedule())
265             {
266                 m_aFlag.addValue(1);
267                 ThreadHelper::thread_sleep_tenth_sec(1);
268             }
269         }
270 
271 public:
272 
273     virtual void SAL_CALL suspend()
274         {
275             m_aFlag.acquire();
276             ::osl::Thread::suspend();
277             m_aFlag.release();
278         }
279 
280     ~myThread()
281         {
282             if (isRunning())
283             {
284                 t_print("error: not terminated.\n");
285             }
286         }
287 
288 };
289 
290 // -----------------------------------------------------------------------------
291 /** Thread which has a flag add 1 every second until 20
292  */
293 class OCountThread : public Thread
294 {
295     ThreadSafeValue<sal_Int32> m_aFlag;
296 public:
297     OCountThread()
298         {
299             m_nWaitSec = 0;
300             t_print("new OCountThread thread %d!\n", getIdentifier());
301         }
302     sal_Int32 getValue() { return m_aFlag.getValue(); }
303 
304     void setWait(sal_Int32 nSec)
305         {
306             m_nWaitSec = nSec;
307             //m_bWait = sal_True;
308         }
309 
310     virtual void SAL_CALL suspend()
311         {
312             m_aFlag.acquire();
313             ::osl::Thread::suspend();
314             m_aFlag.release();
315         }
316 
317 protected:
318     //sal_Bool m_bWait;
319     sal_Int32 m_nWaitSec;
320 
321     void SAL_CALL run()
322         {
323             /// if the thread should terminate, schedule return false
324             while (m_aFlag.getValue() < 20 && schedule() == sal_True)
325             {
326                 m_aFlag.addValue(1);
327                 ThreadHelper::thread_sleep_tenth_sec(1);
328                 // TimeValue nTV;
329                 // nTV.Seconds = 1;
330                 // nTV.Nanosec = 0;
331                 // wait(nTV);
332 
333                 if (m_nWaitSec != 0)
334                 {
335                     //ThreadHelper::thread_sleep_tenth_sec(m_nWaitSec * 10);
336                     TimeValue nTV;
337                     nTV.Seconds = m_nWaitSec / 10 ;
338                     nTV.Nanosec = ( m_nWaitSec%10 ) * 100000000 ;
339                     wait( nTV );
340                     m_nWaitSec = 0;
341                 }
342             }
343         }
344     void SAL_CALL onTerminated()
345         {
346             t_print("normally terminate this thread %d!\n", getIdentifier());
347         }
348 public:
349 
350     ~OCountThread()
351         {
352             if (isRunning())
353             {
354                 t_print("error: not terminated.\n");
355             }
356         }
357 
358 };
359 
360 /** call suspend in the run method
361 */
362 class OSuspendThread : public Thread
363 {
364     ThreadSafeValue<sal_Int32> m_aFlag;
365 public:
366     OSuspendThread(){ m_bSuspend = sal_False; }
367     sal_Int32 getValue() { return m_aFlag.getValue(); }
368     void setSuspend()
369         {
370             m_bSuspend = sal_True;
371         }
372     virtual void SAL_CALL suspend()
373         {
374             m_aFlag.acquire();
375             ::osl::Thread::suspend();
376             m_aFlag.release();
377         }
378 protected:
379     sal_Bool m_bSuspend;
380     void SAL_CALL run()
381         {
382             //if the thread should terminate, schedule return false
383             while (schedule() == sal_True)
384             {
385                 m_aFlag.addValue(1);
386 
387                 ThreadHelper::thread_sleep_tenth_sec(1);
388                 // m_bWait =    sal_False;
389                 // TimeValue nTV;
390                 // nTV.Seconds = 1;
391                 // nTV.Nanosec = 0;
392                 // wait(nTV);
393                 if (m_bSuspend == sal_True)
394                 {
395                     suspend();
396                     m_bSuspend  = sal_False;
397                 }
398             }
399         }
400 public:
401 
402     ~OSuspendThread()
403         {
404             if (isRunning())
405             {
406                 t_print("error: not terminated.\n");
407             }
408         }
409 
410 };
411 
412 /** no call schedule in the run method
413 */
414 class ONoScheduleThread : public Thread
415 {
416     ThreadSafeValue<sal_Int32> m_aFlag;
417 public:
418     sal_Int32 getValue() { return m_aFlag.getValue(); }
419 
420     virtual void SAL_CALL suspend()
421         {
422             m_aFlag.acquire();
423             ::osl::Thread::suspend();
424             m_aFlag.release();
425         }
426 protected:
427     void SAL_CALL run()
428         {
429             while (m_aFlag.getValue() < 10)
430             {
431                 m_aFlag.addValue(1);
432                 ThreadHelper::thread_sleep_tenth_sec(1);
433                 // TimeValue nTV;
434                 // nTV.Seconds = 1;
435                 // nTV.Nanosec = 0;
436                 // wait(nTV);
437             }
438         }
439     void SAL_CALL onTerminated()
440         {
441             t_print("normally terminate this thread %d!\n", getIdentifier());
442         }
443 public:
444     ONoScheduleThread()
445         {
446                 t_print("new thread id %d!\n", getIdentifier());
447         }
448     ~ONoScheduleThread()
449         {
450             if (isRunning())
451             {
452                 t_print("error: not terminated.\n");
453             }
454         }
455 
456 };
457 
458 /**
459 */
460 class OAddThread : public Thread
461 {
462     ThreadSafeValue<sal_Int32> m_aFlag;
463 public:
464     //oslThreadIdentifier m_id, m_CurId;
465     OAddThread(){}
466     sal_Int32 getValue() { return m_aFlag.getValue(); }
467 
468     virtual void SAL_CALL suspend()
469         {
470             m_aFlag.acquire();
471             ::osl::Thread::suspend();
472             m_aFlag.release();
473         }
474 protected:
475     void SAL_CALL run()
476         {
477             //if the thread should terminate, schedule return false
478             while (schedule() == sal_True)
479             {
480                 m_aFlag.addValue(1);
481             }
482         }
483     void SAL_CALL onTerminated()
484         {
485             // t_print("normally terminate this thread %d!\n", getIdentifier());
486         }
487 public:
488 
489     ~OAddThread()
490         {
491             if (isRunning())
492             {
493                 // t_print("error: not terminated.\n");
494             }
495         }
496 
497 };
498 
499 namespace osl_Thread
500 {
501 
502     void resumeAndWaitThread(Thread* _pThread)
503     {
504         // This functions starts a thread, wait a second and suspends the thread
505         // Due to the fact, that a suspend and never run thread never really exists.
506 
507         // Note: on UNX, after createSuspended, and then terminate the thread, it performs well;
508         // while on Windows, after createSuspended, the thread can not terminate, wait endlessly,
509         // so here call resume at first, then call terminate.
510 #ifdef WNT
511         t_print("resumeAndWaitThread\n");
512         _pThread->resume();
513         ThreadHelper::thread_sleep_tenth_sec(1);
514 #else
515         _pThread->resume();
516 #endif
517         // ThreadHelper::thread_sleep_tenth_sec(1);
518         // _pThread->suspend();
519         // ThreadHelper::thread_sleep_tenth_sec(1);
520     }
521 
522     // kill a running thread and join it, if it has terminated, do nothing
523     void termAndJoinThread(Thread* _pThread)
524     {
525         _pThread->terminate();
526 
527 // LLA: Windows feature???, a suspended thread can not terminated, so we have to weak it up
528 #ifdef WNT
529         _pThread->resume();
530         ThreadHelper::thread_sleep_tenth_sec(1);
531 #endif
532         t_print("#wait for join.\n");
533         _pThread->join();
534     }
535 /** Test of the osl::Thread::create method
536  */
537 
538     class create : public CppUnit::TestFixture
539     {
540     public:
541 
542         // initialise your test code values here.
543         void setUp()
544             {
545             }
546 
547         void tearDown()
548             {
549             }
550 
551         /** Simple create a thread.
552 
553             Create a simple thread, it just does add 1 to value(which initialized 0),
554             if the thread run, the value should be 1.
555         */
556         void create_001()
557             {
558                 myThread* newthread = new myThread();
559                 sal_Bool bRes = newthread->create();
560                 CPPUNIT_ASSERT_MESSAGE("Can not creates a new thread!\n", bRes == sal_True );
561 
562                 ThreadHelper::thread_sleep_tenth_sec(1);        // wait short
563                 sal_Bool isRunning = newthread->isRunning();    // check if thread is running
564                 /// wait for the new thread to assure it has run
565                 ThreadHelper::thread_sleep_tenth_sec(3);
566                 sal_Int32 nValue = newthread->getValue();
567                 /// to assure the new thread has terminated
568                 termAndJoinThread(newthread);
569                 delete newthread;
570 
571                 t_print("   nValue = %d\n", nValue);
572                 t_print("isRunning = %d\n", isRunning);
573 
574                 CPPUNIT_ASSERT_MESSAGE(
575                     "Creates a new thread",
576                     nValue >= 1 && isRunning == sal_True
577                     );
578 
579             }
580 
581         /** only one running thread per instance, return false if create secondly
582          */
583         void create_002()
584             {
585                 myThread* newthread = new myThread();
586                 sal_Bool res1 = newthread->create();
587                 sal_Bool res2 = newthread->create();
588                 t_print("In non pro, an assertion should occured. This behaviour is right.\n");
589                 termAndJoinThread(newthread);
590                 delete newthread;
591 
592                 CPPUNIT_ASSERT_MESSAGE(
593                     "Creates a new thread: can not create two threads per instance",
594                     res1 && !res2
595                     );
596 
597             }
598 
599         CPPUNIT_TEST_SUITE(create);
600         CPPUNIT_TEST(create_001);
601         CPPUNIT_TEST(create_002);
602         CPPUNIT_TEST_SUITE_END();
603     }; // class create
604 
605 
606 
607     /** Test of the osl::Thread::createSuspended method
608     */
609     class createSuspended : public CppUnit::TestFixture
610     {
611     public:
612         // initialise your test code values here.
613         void setUp()
614             {
615             }
616 
617         void tearDown()
618             {
619             }
620 
621         /** Create a suspended thread, use the same class as create_001
622 
623             after create, wait enough time, check the value, if it's still the initial value, pass
624         */
625         void createSuspended_001()
626             {
627                 myThread* newthread = new myThread();
628                 sal_Bool bRes = newthread->createSuspended();
629                 CPPUNIT_ASSERT_MESSAGE("Can not creates a new thread!", bRes == sal_True );
630 
631                 ThreadHelper::thread_sleep_tenth_sec(1);
632                 sal_Bool isRunning = newthread->isRunning();
633                 ThreadHelper::thread_sleep_tenth_sec(3);
634                 sal_Int32 nValue = newthread->getValue();
635 
636                 resumeAndWaitThread(newthread);
637 
638                 termAndJoinThread(newthread);
639                 delete newthread;
640 
641                 CPPUNIT_ASSERT_MESSAGE(
642                     "Creates a new suspended thread",
643                     nValue == 0 && isRunning
644                     );
645             }
646 
647         void createSuspended_002()
648             {
649                 myThread* newthread = new myThread();
650                 sal_Bool res1 = newthread->createSuspended();
651                 sal_Bool res2 = newthread->createSuspended();
652 
653                 resumeAndWaitThread(newthread);
654 
655                 termAndJoinThread(newthread);
656 
657                 delete newthread;
658 
659                 CPPUNIT_ASSERT_MESSAGE(
660                     "Creates a new thread: can not create two threads per instance",
661                     res1 && !res2
662                     );
663             }
664 
665         CPPUNIT_TEST_SUITE(createSuspended);
666         CPPUNIT_TEST(createSuspended_001);
667         // LLA: Deadlocked!!!
668         CPPUNIT_TEST(createSuspended_002);
669         CPPUNIT_TEST_SUITE_END();
670     }; // class createSuspended
671 
672     /** when the count value equal to or more than 3, suspend the thread.
673     */
674     void suspendCountThread(OCountThread* _pCountThread)
675     {
676         sal_Int32 nValue = 0;
677         while (1)
678         {
679             nValue = _pCountThread->getValue();
680             if (nValue >= 3)
681             {
682                 _pCountThread->suspend();
683                 break;
684             }
685         }
686     }
687 
688     /** Test of the osl::Thread::suspend method
689     */
690     class suspend : public CppUnit::TestFixture
691     {
692     public:
693         // initialise your test code values here.
694         void setUp()
695             {
696             }
697 
698         void tearDown()
699             {
700             }
701 
702         /** Use a thread which has a flag added 1 every second
703 
704             ALGORITHM:
705             create the thread, after running special time, record value of flag, then suspend it,
706             wait a long time, check the flag, if it remains unchanged during suspending
707         */
708         void suspend_001()
709             {
710                 OCountThread* aCountThread = new OCountThread();
711                 sal_Bool bRes = aCountThread->create();
712                 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
713                 // the thread run for some seconds, but not terminate
714                 suspendCountThread( aCountThread );
715 
716                 // the value just after calling suspend
717                 sal_Int32 nValue = aCountThread->getValue();       // (2)
718 
719                 ThreadHelper::thread_sleep_tenth_sec(3);
720 
721                 // the value after waiting 3 seconds
722                 sal_Int32 nLaterValue = aCountThread->getValue();    // (3)
723 
724                 resumeAndWaitThread(aCountThread);
725                 termAndJoinThread(aCountThread);
726                 delete aCountThread;
727 
728                 CPPUNIT_ASSERT_MESSAGE(
729                     "Suspend the thread",
730                     bRes == sal_True && nValue == nLaterValue
731                     );
732 
733             }
734         /** suspend a thread in it's worker-function, the ALGORITHM is same as suspend_001
735              reason of deadlocked I think: no schedule can schedule other threads to go on excuting
736          */
737         void suspend_002()
738             {
739                 OSuspendThread* aThread = new OSuspendThread();
740                 sal_Bool bRes = aThread->create();
741                 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
742                 // first the thread run for some seconds, but not terminate
743                 sal_Int32 nValue = 0;
744                 //while (1)
745                 //{
746                 ThreadHelper::thread_sleep_tenth_sec(3);
747                 nValue = aThread->getValue();    // (1)
748                 t_print(" getValue is %d !", nValue );
749                 if (nValue >= 2)
750                 {
751                         aThread->setSuspend();
752                         //break;
753                 }
754                 //}
755                 t_print(" after while!");
756                 // the value just after calling suspend
757                 nValue = aThread->getValue();       // (2)
758 
759                 ThreadHelper::thread_sleep_tenth_sec(3);
760                 t_print(" after sleep!");
761                 // the value after waiting 3 seconds
762                 sal_Int32 nLaterValue = aThread->getValue();        // (3)
763 
764                 //resumeAndWaitThread(aThread);
765                 aThread->resume();
766                 termAndJoinThread(aThread);
767                 delete aThread;
768 
769                 CPPUNIT_ASSERT_MESSAGE(
770                     "Suspend the thread",
771                     bRes == sal_True && nValue == nLaterValue
772                     );
773             }
774 
775         CPPUNIT_TEST_SUITE(suspend);
776         CPPUNIT_TEST(suspend_001);
777         // LLA: Deadlocked!!!
778         // CPPUNIT_TEST(createSuspended_002);
779         CPPUNIT_TEST_SUITE_END();
780     }; // class suspend
781 
782     /** Test of the osl::Thread::resume method
783     */
784     class resume : public CppUnit::TestFixture
785     {
786     public:
787         // initialise your test code values here.
788         void setUp()
789             {
790             }
791 
792         void tearDown()
793             {
794             }
795 
796         /** check if the thread run samely as usual after suspend and resume
797 
798             ALGORITHM:
799             compare the values before and after suspend, they should be same,
800             then compare values before and after resume, the difference should be same as the sleep seconds number
801         */
802         void resume_001()
803             {
804                 OCountThread* pCountThread = new OCountThread();
805                 sal_Bool bRes = pCountThread->create();
806                 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
807 
808                 suspendCountThread(pCountThread);
809 
810                 sal_Int32 nSuspendValue = pCountThread->getValue();  // (2)
811                 // suspend for 3 seconds
812                 ThreadHelper::thread_sleep_tenth_sec(3);
813                 pCountThread->resume();
814 
815                 ThreadHelper::thread_sleep_tenth_sec(3);
816                 sal_Int32 nResumeValue = pCountThread->getValue();
817 
818                 ThreadHelper::thread_sleep_tenth_sec(3);
819                 sal_Int32 nLaterValue = pCountThread->getValue();
820 
821                 termAndJoinThread(pCountThread);
822                 delete pCountThread;
823 
824                 t_print("SuspendValue: %d\n", nSuspendValue);
825                 t_print("ResumeValue:  %d\n", nResumeValue);
826                 t_print("LaterValue:   %d\n", nLaterValue);
827 
828                 /* LLA: this assumption is no longer relevant: nResumeValue ==  nSuspendValue && */
829                 CPPUNIT_ASSERT_MESSAGE(
830                     "Suspend then resume the thread",
831                     nLaterValue >= 9 &&
832                     nResumeValue > nSuspendValue &&
833                     nLaterValue > nResumeValue
834                     );
835 
836             }
837 
838         /** Create a suspended thread then resume, check if the thread has run
839          */
840         void resume_002()
841             {
842                 myThread* newthread = new myThread();
843                 sal_Bool bRes = newthread->createSuspended();
844                 CPPUNIT_ASSERT_MESSAGE ( "Can't create thread!", bRes == sal_True );
845 
846                 newthread->resume();
847                 ThreadHelper::thread_sleep_tenth_sec(2);
848                 sal_Int32 nValue = newthread->getValue();
849 
850                 termAndJoinThread(newthread);
851                 delete newthread;
852 
853                 t_print("   nValue = %d\n", nValue);
854 
855                 CPPUNIT_ASSERT_MESSAGE(
856                     "Creates a suspended thread, then resume",
857                     nValue >= 1
858                     );
859             }
860 
861         CPPUNIT_TEST_SUITE(resume);
862         CPPUNIT_TEST(resume_001);
863         CPPUNIT_TEST(resume_002);
864         CPPUNIT_TEST_SUITE_END();
865     }; // class resume
866 
867     /** Test of the osl::Thread::terminate method
868     */
869     class terminate : public CppUnit::TestFixture
870     {
871     public:
872         // initialise your test code values here.
873         void setUp()
874             {
875             }
876 
877         void tearDown()
878             {
879             }
880 
881         /** Check after call terminate if the running thread running go on executing
882 
883             ALGORITHM:
884             before and after call terminate, the values should be the same
885         */
886         void terminate_001()
887             {
888                 OCountThread* aCountThread = new OCountThread();
889                 sal_Bool bRes = aCountThread->create();
890                 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
891 
892                 ThreadHelper::thread_sleep_tenth_sec(2);
893                 sal_Int32 nValue = aCountThread->getValue();
894                 aCountThread->terminate();
895                 ThreadHelper::thread_sleep_tenth_sec(2);
896                 sal_Int32 nLaterValue = aCountThread->getValue();
897 
898                 // isRunning should be false after terminate
899                 sal_Bool isRunning = aCountThread->isRunning();
900                 aCountThread->join();
901                 delete aCountThread;
902 
903                 t_print("     nValue = %d\n", nValue);
904                 t_print("nLaterValue = %d\n", nLaterValue);
905 
906                 CPPUNIT_ASSERT_MESSAGE(
907                     "Terminate the thread",
908                     isRunning == sal_False && nLaterValue >= nValue
909                     );
910             }
911         /** Check if a suspended thread will terminate after call terminate, different on w32 and on UNX
912          */
913         void terminate_002()
914             {
915                 OCountThread* aCountThread = new OCountThread();
916                 sal_Bool bRes = aCountThread->create();
917                 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
918 
919                 ThreadHelper::thread_sleep_tenth_sec(1);
920                 suspendCountThread(aCountThread);
921                 sal_Int32 nValue = aCountThread->getValue();
922 
923                 // seems a suspended thread can not be terminated on W32, while on Solaris can
924                 resumeAndWaitThread(aCountThread);
925 
926                 ThreadHelper::thread_sleep_tenth_sec(2);
927 
928                 termAndJoinThread(aCountThread);
929                 sal_Int32 nLaterValue = aCountThread->getValue();
930                 delete aCountThread;
931 
932                 t_print("     nValue = %d\n", nValue);
933                 t_print("nLaterValue = %d\n", nLaterValue);
934 
935                 CPPUNIT_ASSERT_MESSAGE(
936                     "Suspend then resume the thread",
937                     nLaterValue > nValue );
938             }
939 
940         CPPUNIT_TEST_SUITE(terminate);
941         CPPUNIT_TEST(terminate_001);
942         CPPUNIT_TEST(terminate_002);
943         CPPUNIT_TEST_SUITE_END();
944     }; // class terminate
945 
946     /** Test of the osl::Thread::join method
947     */
948     class join : public CppUnit::TestFixture
949     {
950     public:
951         // initialise your test code values here.
952         void setUp()
953             {
954             }
955 
956         void tearDown()
957             {
958             }
959 
960         /** Check after call terminate if the thread running function will not go on executing
961 
962             the next statement after join will not exec before the thread terminate
963             ALGORITHM:
964             recode system time at the beginning of the thread run, call join, then record system time again,
965             the difference of the two time should be equal or more than 20 seconds, the CountThead normally terminate
966         */
967         void join_001()
968             {
969                 OCountThread *aCountThread = new OCountThread();
970                 sal_Bool bRes = aCountThread->create();
971                 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
972 
973                 StopWatch aStopWatch;
974                 aStopWatch.start();
975                 // TimeValue aTimeVal_befor;
976                 // osl_getSystemTime( &aTimeVal_befor );
977                 //t_print("#join:the system time is %d,%d\n", pTimeVal_befor->Seconds,pTimeVal_befor->Nanosec);
978 
979                 aCountThread->join();
980 
981                 //the below line will be executed after aCountThread terminate
982                 // TimeValue aTimeVal_after;
983                 // osl_getSystemTime( &aTimeVal_after );
984                 aStopWatch.stop();
985                 // sal_uInt32 nSec  = aTimeVal_after.Seconds - aTimeVal_befor.Seconds;
986                 double nSec = aStopWatch.getSeconds();
987                 t_print("join_001 nSec=%f\n", nSec);
988                 delete aCountThread;
989 
990                 CPPUNIT_ASSERT_MESSAGE(
991                     "Join the thread: after the thread terminate",
992                     nSec >= 2
993                     );
994 
995             }
996         /** after terminated by another thread, join exited immediately
997 
998             ALGORITHM:
999             terminate the thread when value>=3, call join, check the beginning time and time after join,
1000             the difference should be 3 seconds, join costs little time
1001         */
1002         void join_002()
1003             {
1004                 OCountThread *aCountThread = new OCountThread();
1005                 sal_Bool bRes = aCountThread->create();
1006                 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
1007 
1008                 //record the time when the running begin
1009                 // TimeValue aTimeVal_befor;
1010                 // osl_getSystemTime( &aTimeVal_befor );
1011                 StopWatch aStopWatch;
1012                 aStopWatch.start();
1013 
1014                 ThreadHelper::thread_sleep_tenth_sec(10);
1015                 termAndJoinThread(aCountThread);
1016 
1017                 //the below line will be executed after aCountThread terminate
1018                 // TimeValue aTimeVal_after;
1019                 // osl_getSystemTime( &aTimeVal_after );
1020                 // sal_uInt32 nSec  = aTimeVal_after.Seconds - aTimeVal_befor.Seconds;
1021                 aStopWatch.stop();
1022                 double nSec = aStopWatch.getSeconds();
1023                 t_print("join_002 nSec=%f\n", nSec);
1024 
1025                 delete aCountThread;
1026                 CPPUNIT_ASSERT_MESSAGE(
1027                     "Join the thread: after thread terminate by another thread",
1028                     nSec >= 1
1029                     );
1030             }
1031 
1032         CPPUNIT_TEST_SUITE(join);
1033         CPPUNIT_TEST(join_001);
1034         CPPUNIT_TEST(join_002);
1035         CPPUNIT_TEST_SUITE_END();
1036     }; // class join
1037 
1038     /** Test of the osl::Thread::isRunning method
1039     */
1040     class isRunning : public CppUnit::TestFixture
1041     {
1042     public:
1043         // initialise your test code values here.
1044         void setUp()
1045             {
1046             }
1047 
1048         void tearDown()
1049             {
1050             }
1051 
1052         /**
1053          */
1054         void isRunning_001()
1055             {
1056                 OCountThread *aCountThread = new OCountThread();
1057                 sal_Bool bRes = aCountThread->create();
1058                 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
1059 
1060                 sal_Bool bRun = aCountThread->isRunning();
1061 
1062                 ThreadHelper::thread_sleep_tenth_sec(2);
1063                 termAndJoinThread(aCountThread);
1064                 sal_Bool bTer = aCountThread->isRunning();
1065                 delete aCountThread;
1066 
1067                 CPPUNIT_ASSERT_MESSAGE(
1068                     "Test isRunning",
1069                     bRun == sal_True && bTer == sal_False
1070                     );
1071             }
1072         /** check the value of isRunning when suspending and after resume
1073          */
1074         void isRunning_002()
1075             {
1076                 OCountThread *aCountThread = new OCountThread();
1077                 sal_Bool bRes = aCountThread->create();
1078                 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
1079 
1080                 // sal_Bool bRunning = aCountThread->isRunning();
1081                 // sal_Int32 nValue = 0;
1082                 suspendCountThread(aCountThread);
1083 
1084                 sal_Bool bRunning_sup = aCountThread->isRunning();
1085                 ThreadHelper::thread_sleep_tenth_sec(2);
1086                 aCountThread->resume();
1087                 ThreadHelper::thread_sleep_tenth_sec(2);
1088                 sal_Bool bRunning_res = aCountThread->isRunning();
1089                 termAndJoinThread(aCountThread);
1090                 sal_Bool bRunning_ter = aCountThread->isRunning();
1091                 delete aCountThread;
1092 
1093                 CPPUNIT_ASSERT_MESSAGE(
1094                     "Test isRunning",
1095                     bRes == sal_True &&
1096                     bRunning_sup == sal_True &&
1097                     bRunning_res == sal_True &&
1098                     bRunning_ter == sal_False
1099                     );
1100 
1101             }
1102 
1103         CPPUNIT_TEST_SUITE(isRunning);
1104         CPPUNIT_TEST(isRunning_001);
1105         CPPUNIT_TEST(isRunning_002);
1106         CPPUNIT_TEST_SUITE_END();
1107     }; // class isRunning
1108 
1109 
1110     /// check osl::Thread::setPriority
1111     class setPriority : public CppUnit::TestFixture
1112     {
1113     public:
1114         // initialise your test code values here.
1115         void setUp()
1116             {
1117             }
1118 
1119         void tearDown()
1120             {
1121             }
1122 
1123         // insert your test code here.
1124         rtl::OString getPrioName(oslThreadPriority _aPriority)
1125             {
1126                 rtl::OString sPrioStr;
1127                 switch (_aPriority)
1128                 {
1129                 case osl_Thread_PriorityHighest:
1130                     sPrioStr = "Highest";
1131                     break;
1132 
1133                 case osl_Thread_PriorityAboveNormal:
1134                     sPrioStr = "AboveNormal";
1135 
1136                 case osl_Thread_PriorityNormal:
1137                     sPrioStr = "Normal";
1138 
1139                 case osl_Thread_PriorityBelowNormal:
1140                     sPrioStr = "BelowNormal";
1141                     break;
1142 
1143                 case osl_Thread_PriorityLowest:
1144                     sPrioStr = "Lowest";
1145                     break;
1146                 default:
1147                     sPrioStr = "unknown";
1148                 }
1149                 return sPrioStr;
1150             }
1151 
1152 
1153         /** check 2 threads.
1154 
1155             ALGORITHM:
1156             Here the function should show, that 2 different threads,
1157             which only increase a value, should run at the same time with same prio.
1158             The test fails, if the difference between the two values is more than 5%
1159             but IMHO this isn't a failure, it's only a feature of the OS.
1160         */
1161 
1162         void check2Threads(oslThreadPriority _aPriority)
1163             {
1164                 // initial 5 threads with different priorities
1165                 OAddThread* pThread = new OAddThread();
1166                 OAddThread* p2Thread = new OAddThread();
1167 
1168                 //Create them and start running at the same time
1169                 pThread->create();
1170                 pThread->setPriority(_aPriority);
1171                 p2Thread->create();
1172                 p2Thread->setPriority(_aPriority);
1173 
1174                 ThreadHelper::thread_sleep_tenth_sec(5);
1175 
1176                 pThread->terminate();
1177                 p2Thread->terminate();
1178 
1179                 sal_Int32 nValueNormal = 0;
1180                 nValueNormal = pThread->getValue();
1181 
1182                 sal_Int32 nValueNormal2 = 0;
1183                 nValueNormal2 = p2Thread->getValue();
1184 
1185                 rtl::OString sPrio = getPrioName(_aPriority);
1186                 t_print("After 10 tenth seconds\n");
1187 
1188                 t_print("nValue in %s Prio Thread is  %d\n",sPrio.getStr(), nValueNormal);
1189                 t_print("nValue in %s Prio Thread is %d\n", sPrio.getStr(), nValueNormal2);
1190 
1191                 // ThreadHelper::thread_sleep_tenth_sec(1);
1192                 pThread->join();
1193                 p2Thread->join();
1194 
1195                 delete pThread;
1196                 delete p2Thread;
1197 
1198                 sal_Int32 nDelta = abs(nValueNormal - nValueNormal2);
1199                 double nQuotient = std::max(nValueNormal, nValueNormal2);
1200                 CPPUNIT_ASSERT_MESSAGE(
1201                     "Quotient is zero, which means, there exist no right values.",
1202                     nQuotient != 0
1203                     );
1204                 double nDeltaPercent = nDelta / nQuotient * 100;
1205 
1206                 t_print("Delta value %d, percent %f\n",nDelta, nDeltaPercent);
1207 
1208                 // LLA: it's not a bug if the current OS is not able to handle thread scheduling right and good.
1209                 // like Windows XP
1210                 // LLA: CPPUNIT_ASSERT_MESSAGE(
1211                 // LLA:     "Run 2 normal threads, the count diff more than 5 percent.",
1212                 // LLA:     nDeltaPercent <= 5
1213                 // LLA:     );
1214             }
1215 
1216         void setPriority_001_1()
1217             {
1218                 check2Threads(osl_Thread_PriorityHighest);
1219             }
1220         void setPriority_001_2()
1221             {
1222                 check2Threads(osl_Thread_PriorityAboveNormal);
1223             }
1224         void setPriority_001_3()
1225             {
1226                 check2Threads(osl_Thread_PriorityNormal);
1227             }
1228         void setPriority_001_4()
1229             {
1230                 check2Threads(osl_Thread_PriorityBelowNormal);
1231             }
1232         void setPriority_001_5()
1233             {
1234                 check2Threads(osl_Thread_PriorityLowest);
1235             }
1236 
1237         void setPriority_002()
1238             {
1239                 // initial 5 threads with different priorities
1240 
1241                 OAddThread aHighestThread;
1242                 OAddThread aAboveNormalThread;
1243                 OAddThread aNormalThread;
1244                 //OAddThread *aBelowNormalThread = new OAddThread();
1245                 //OAddThread *aLowestThread = new OAddThread();
1246 
1247                 //Create them and start running at the same time
1248                 aHighestThread.createSuspended();
1249                 aHighestThread.setPriority(osl_Thread_PriorityHighest);
1250 
1251                 aAboveNormalThread.createSuspended();
1252                 aAboveNormalThread.setPriority(osl_Thread_PriorityAboveNormal);
1253 
1254                 aNormalThread.createSuspended();
1255                 aNormalThread.setPriority(osl_Thread_PriorityNormal);
1256                 /*aBelowNormalThread->create();
1257                   aBelowNormalThread->setPriority(osl_Thread_PriorityBelowNormal);
1258                   aLowestThread->create();
1259                   aLowestThread->setPriority(osl_Thread_PriorityLowest);
1260                 */
1261 
1262                 aHighestThread.resume();
1263                 aAboveNormalThread.resume();
1264                 aNormalThread.resume();
1265 
1266                 ThreadHelper::thread_sleep_tenth_sec(5);
1267 
1268                 aHighestThread.suspend();
1269                 aAboveNormalThread.suspend();
1270                 aNormalThread.suspend();
1271 
1272                 termAndJoinThread(&aNormalThread);
1273                 termAndJoinThread(&aAboveNormalThread);
1274                 termAndJoinThread(&aHighestThread);
1275                 //aBelowNormalThread->terminate();
1276                 //aLowestThread->terminate();
1277 
1278                 sal_Int32 nValueHighest = 0;
1279                 nValueHighest = aHighestThread.getValue();
1280 
1281                 sal_Int32 nValueAboveNormal = 0;
1282                 nValueAboveNormal = aAboveNormalThread.getValue();
1283 
1284                 sal_Int32 nValueNormal = 0;
1285                 nValueNormal = aNormalThread.getValue();
1286 
1287                 // sal_Int32 nValueBelowNormal = 0;
1288                 //nValueBelowNormal = aBelowNormalThread->getValue();
1289                 // sal_Int32 nValueLowest = 0;
1290                 //nValueLowest = aLowestThread->getValue();
1291                 t_print("After 10 tenth seconds\n");
1292                 t_print("nValue in Highest Prio Thread is %d\n",nValueHighest);
1293                 t_print("nValue in AboveNormal Prio Thread is %d\n",nValueAboveNormal);
1294                 t_print("nValue in Normal Prio Thread is %d\n",nValueNormal);
1295 
1296                 // LLA: this is not a save test, so we only check if all values not zero
1297                 // LLA: CPPUNIT_ASSERT_MESSAGE(
1298                 // LLA:     "SetPriority",
1299                 // LLA:     nValueHighest >= nValueAboveNormal &&
1300                 // LLA:     nValueAboveNormal >= nValueNormal &&
1301                 // LLA:     nValueNormal > 0
1302                 // LLA:     );
1303 
1304 // LLA: windows let starve threads with lower priority
1305 #ifndef WNT
1306                 CPPUNIT_ASSERT_MESSAGE(
1307                     "SetPriority",
1308                     nValueHighest     > 0 &&
1309                     nValueAboveNormal > 0 &&
1310                     nValueNormal > 0
1311                     );
1312 #endif
1313             }
1314 
1315         void setPriority_003()
1316             {
1317                 // initial 5 threads with different priorities
1318                 OAddThread *pHighestThread = new OAddThread();
1319                 OAddThread *pAboveNormalThread = new OAddThread();
1320                 OAddThread *pNormalThread = new OAddThread();
1321                 OAddThread *pBelowNormalThread = new OAddThread();
1322                 OAddThread *pLowestThread = new OAddThread();
1323 
1324                 //Create them and start running at the same time
1325                 pHighestThread->createSuspended();
1326                 pHighestThread->setPriority(osl_Thread_PriorityHighest);
1327 
1328                 pAboveNormalThread->createSuspended();
1329                 pAboveNormalThread->setPriority(osl_Thread_PriorityAboveNormal);
1330 
1331                 pNormalThread->createSuspended();
1332                 pNormalThread->setPriority(osl_Thread_PriorityNormal);
1333 
1334                 pBelowNormalThread->createSuspended();
1335                 pBelowNormalThread->setPriority(osl_Thread_PriorityBelowNormal);
1336 
1337                 pLowestThread->createSuspended();
1338                 pLowestThread->setPriority(osl_Thread_PriorityLowest);
1339 
1340                 pHighestThread->resume();
1341                 pAboveNormalThread->resume();
1342                 pNormalThread->resume();
1343                 pBelowNormalThread->resume();
1344                 pLowestThread->resume();
1345 
1346                 ThreadHelper::thread_sleep_tenth_sec(5);
1347 
1348                 pHighestThread->suspend();
1349                 pAboveNormalThread->suspend();
1350                 pNormalThread->suspend();
1351                 pBelowNormalThread->suspend();
1352                 pLowestThread->suspend();
1353 
1354                 termAndJoinThread(pHighestThread);
1355                 termAndJoinThread(pAboveNormalThread);
1356                 termAndJoinThread(pNormalThread);
1357                 termAndJoinThread(pBelowNormalThread);
1358                 termAndJoinThread(pLowestThread);
1359 
1360                 sal_Int32 nValueHighest = 0;
1361                 nValueHighest = pHighestThread->getValue();
1362 
1363                 sal_Int32 nValueAboveNormal = 0;
1364                 nValueAboveNormal = pAboveNormalThread->getValue();
1365 
1366                 sal_Int32 nValueNormal = 0;
1367                 nValueNormal = pNormalThread->getValue();
1368 
1369                 sal_Int32 nValueBelowNormal = 0;
1370                 nValueBelowNormal = pBelowNormalThread->getValue();
1371 
1372                 sal_Int32 nValueLowest = 0;
1373                 nValueLowest = pLowestThread->getValue();
1374 
1375                 t_print("After 10 tenth seconds\n");
1376                 t_print("nValue in Highest Prio Thread is     %d\n",nValueHighest);
1377                 t_print("nValue in AboveNormal Prio Thread is %d\n",nValueAboveNormal);
1378                 t_print("nValue in Normal Prio Thread is      %d\n",nValueNormal);
1379                 t_print("nValue in BelowNormal Prio Thread is %d\n",nValueBelowNormal);
1380                 t_print("nValue in Lowest Prio Thread is      %d\n",nValueLowest);
1381 
1382                 delete pHighestThread;
1383                 delete pAboveNormalThread;
1384                 delete pNormalThread;
1385                 delete pBelowNormalThread;
1386                 delete pLowestThread;
1387 
1388                 // LLA: this is not a save test, so we only check if all values not zero
1389                 // LLA: CPPUNIT_ASSERT_MESSAGE(
1390                 // LLA:     "SetPriority",
1391                 // LLA:     nValueHighest > nValueAboveNormal &&
1392                 // LLA:     nValueAboveNormal > nValueNormal &&
1393                 // LLA:     nValueNormal > nValueBelowNormal &&
1394                 // LLA:     nValueBelowNormal > nValueLowest &&
1395                 // LLA:     nValueLowest > 0
1396                 // LLA:     );
1397 
1398 // LLA: windows let starve threads with lower priority
1399 #ifndef WNT
1400                 CPPUNIT_ASSERT_MESSAGE(
1401                     "SetPriority",
1402                     nValueHighest     > 0 &&
1403                     nValueAboveNormal > 0 &&
1404                     nValueNormal      > 0 &&
1405                     nValueBelowNormal > 0 &&
1406                     nValueLowest      > 0
1407                     );
1408 #endif
1409             }
1410 
1411         void setPriority_004()
1412             {
1413                 // initial 5 threads with different priorities
1414                 // OAddThread *pHighestThread = new OAddThread();
1415                 OAddThread *pAboveNormalThread = new OAddThread();
1416                 OAddThread *pNormalThread = new OAddThread();
1417                 OAddThread *pBelowNormalThread = new OAddThread();
1418                 OAddThread *pLowestThread = new OAddThread();
1419 
1420                 //Create them and start running at the same time
1421                 // pHighestThread->createSuspended();
1422                 // pHighestThread->setPriority(osl_Thread_PriorityHighest);
1423 
1424                 pAboveNormalThread->createSuspended();
1425                 pAboveNormalThread->setPriority(osl_Thread_PriorityAboveNormal);
1426 
1427                 pNormalThread->createSuspended();
1428                 pNormalThread->setPriority(osl_Thread_PriorityNormal);
1429 
1430                 pBelowNormalThread->createSuspended();
1431                 pBelowNormalThread->setPriority(osl_Thread_PriorityBelowNormal);
1432 
1433                 pLowestThread->createSuspended();
1434                 pLowestThread->setPriority(osl_Thread_PriorityLowest);
1435 
1436                 // pHighestThread->resume();
1437                 pAboveNormalThread->resume();
1438                 pNormalThread->resume();
1439                 pBelowNormalThread->resume();
1440                 pLowestThread->resume();
1441 
1442                 ThreadHelper::thread_sleep_tenth_sec(5);
1443 
1444                 // pHighestThread->suspend();
1445                 pAboveNormalThread->suspend();
1446                 pNormalThread->suspend();
1447                 pBelowNormalThread->suspend();
1448                 pLowestThread->suspend();
1449 
1450                 // termAndJoinThread(pHighestThread);
1451                 termAndJoinThread(pAboveNormalThread);
1452                 termAndJoinThread(pNormalThread);
1453                 termAndJoinThread(pBelowNormalThread);
1454                 termAndJoinThread(pLowestThread);
1455 
1456                 // sal_Int32 nValueHighest  = 0;
1457                 // nValueHighest =  pHighestThread->getValue();
1458 
1459                 sal_Int32 nValueAboveNormal = 0;
1460                 nValueAboveNormal = pAboveNormalThread->getValue();
1461 
1462                 sal_Int32 nValueNormal = 0;
1463                 nValueNormal = pNormalThread->getValue();
1464 
1465                 sal_Int32 nValueBelowNormal = 0;
1466                 nValueBelowNormal = pBelowNormalThread->getValue();
1467 
1468                 sal_Int32 nValueLowest = 0;
1469                 nValueLowest = pLowestThread->getValue();
1470 
1471                 t_print("After 5 tenth seconds\n");
1472                 // t_print("nValue in Highest Prio Thread  is     %d\n",nValueHighest);
1473                 t_print("nValue in AboveNormal Prio Thread is %d\n",nValueAboveNormal);
1474                 t_print("nValue in Normal Prio Thread is      %d\n",nValueNormal);
1475                 t_print("nValue in BelowNormal Prio Thread is %d\n",nValueBelowNormal);
1476                 t_print("nValue in Lowest Prio Thread is      %d\n",nValueLowest);
1477 
1478                 // delete pHighestThread;
1479                 delete pAboveNormalThread;
1480                 delete pNormalThread;
1481                 delete pBelowNormalThread;
1482                 delete pLowestThread;
1483 
1484                 // LLA: this is not a save test, so we only check if all values not zero
1485                 // LLA: CPPUNIT_ASSERT_MESSAGE(
1486                 // LLA:     "SetPriority",
1487                 // LLA:     nValueHighest > nValueAboveNormal &&
1488                 // LLA:     nValueAboveNormal > nValueNormal &&
1489                 // LLA:     nValueNormal > nValueBelowNormal &&
1490                 // LLA:     nValueBelowNormal > nValueLowest &&
1491                 // LLA:     nValueLowest > 0
1492                 // LLA:     );
1493 
1494 // LLA: windows let starve threads with lower priority
1495 #ifndef WNT
1496                 CPPUNIT_ASSERT_MESSAGE(
1497                     "SetPriority",
1498                     /* nValueHighest     > 0 &&  */
1499                     nValueAboveNormal > 0 &&
1500                     nValueNormal      > 0 &&
1501                     nValueBelowNormal > 0 &&
1502                     nValueLowest      > 0
1503                     );
1504 #endif
1505             }
1506         void setPriority_005()
1507             {
1508                 // initial 5 threads with different priorities
1509                 // OAddThread *pHighestThread = new OAddThread();
1510                 // OAddThread *pAboveNormalThread = new OAddThread();
1511                 OAddThread *pNormalThread = new OAddThread();
1512                 OAddThread *pBelowNormalThread = new OAddThread();
1513                 OAddThread *pLowestThread = new OAddThread();
1514 
1515                 //Create them and start running at the same time
1516                 // pHighestThread->createSuspended();
1517                 // pHighestThread->setPriority(osl_Thread_PriorityHighest);
1518 
1519                 // pAboveNormalThread->createSuspended();
1520                 // pAboveNormalThread->setPriority(osl_Thread_PriorityAboveNormal);
1521 
1522                 pNormalThread->createSuspended();
1523                 pNormalThread->setPriority(osl_Thread_PriorityNormal);
1524 
1525                 pBelowNormalThread->createSuspended();
1526                 pBelowNormalThread->setPriority(osl_Thread_PriorityBelowNormal);
1527 
1528                 pLowestThread->createSuspended();
1529                 pLowestThread->setPriority(osl_Thread_PriorityLowest);
1530 
1531                 // pHighestThread->resume();
1532                 // pAboveNormalThread->resume();
1533                 pNormalThread->resume();
1534                 pBelowNormalThread->resume();
1535                 pLowestThread->resume();
1536 
1537                 ThreadHelper::thread_sleep_tenth_sec(5);
1538 
1539                 // pHighestThread->suspend();
1540                 // pAboveNormalThread->suspend();
1541                 pNormalThread->suspend();
1542                 pBelowNormalThread->suspend();
1543                 pLowestThread->suspend();
1544 
1545                 // termAndJoinThread(pHighestThread);
1546                 // termAndJoinThread(pAboveNormalThread);
1547                 termAndJoinThread(pNormalThread);
1548                 termAndJoinThread(pBelowNormalThread);
1549                 termAndJoinThread(pLowestThread);
1550 
1551                 // sal_Int32 nValueHighest  = 0;
1552                 // nValueHighest =  pHighestThread->getValue();
1553 
1554                 // sal_Int32 nValueAboveNormal = 0;
1555                 // nValueAboveNormal = pAboveNormalThread->getValue();
1556 
1557                 sal_Int32 nValueNormal = 0;
1558                 nValueNormal = pNormalThread->getValue();
1559 
1560                 sal_Int32 nValueBelowNormal = 0;
1561                 nValueBelowNormal = pBelowNormalThread->getValue();
1562 
1563                 sal_Int32 nValueLowest = 0;
1564                 nValueLowest = pLowestThread->getValue();
1565 
1566                 t_print("After 5 tenth seconds\n");
1567                 // t_print("nValue in Highest Prio Thread  is     %d\n",nValueHighest);
1568                 // t_print("nValue in AboveNormal  Prio Thread is %d\n",nValueAboveNormal);
1569                 t_print("nValue in Normal Prio Thread is      %d\n",nValueNormal);
1570                 t_print("nValue in BelowNormal Prio Thread is %d\n",nValueBelowNormal);
1571                 t_print("nValue in Lowest Prio Thread is      %d\n",nValueLowest);
1572 
1573                 // delete pHighestThread;
1574                 // delete pAboveNormalThread;
1575                 delete pNormalThread;
1576                 delete pBelowNormalThread;
1577                 delete pLowestThread;
1578 
1579                 // LLA: this is not a save test, so we only check if all values not zero
1580                 // LLA: CPPUNIT_ASSERT_MESSAGE(
1581                 // LLA:     "SetPriority",
1582                 // LLA:     nValueHighest > nValueAboveNormal &&
1583                 // LLA:     nValueAboveNormal > nValueNormal &&
1584                 // LLA:     nValueNormal > nValueBelowNormal &&
1585                 // LLA:     nValueBelowNormal > nValueLowest &&
1586                 // LLA:     nValueLowest > 0
1587                 // LLA:     );
1588 
1589 // LLA: windows let starve threads with lower priority
1590 #ifndef WNT
1591                 CPPUNIT_ASSERT_MESSAGE(
1592                     "SetPriority",
1593                     /* nValueHighest     > 0 &&  */
1594                     /* nValueAboveNormal > 0 &&  */
1595                     nValueNormal      > 0 &&
1596                     nValueBelowNormal > 0 &&
1597                     nValueLowest      > 0
1598                     );
1599 #endif
1600             }
1601 
1602 
1603         CPPUNIT_TEST_SUITE(setPriority);
1604 #ifndef SOLARIS
1605         CPPUNIT_TEST(setPriority_002);
1606         CPPUNIT_TEST(setPriority_003);
1607         CPPUNIT_TEST(setPriority_004);
1608         CPPUNIT_TEST(setPriority_005);
1609 #endif
1610         CPPUNIT_TEST(setPriority_001_1);
1611         CPPUNIT_TEST(setPriority_001_2);
1612         CPPUNIT_TEST(setPriority_001_3);
1613         CPPUNIT_TEST(setPriority_001_4);
1614         CPPUNIT_TEST(setPriority_001_5);
1615         CPPUNIT_TEST_SUITE_END();
1616     }; // class setPriority
1617 
1618     /** Test of the osl::Thread::getPriority method
1619     */
1620     class getPriority : public CppUnit::TestFixture
1621     {
1622     public:
1623         // initialise your test code values here.
1624         void setUp()
1625             {
1626             }
1627 
1628         void tearDown()
1629             {
1630             }
1631 
1632         // insert your test code here.
1633         void getPriority_001()
1634             {
1635                 OAddThread *pHighestThread = new OAddThread();
1636 
1637                 //Create them and start running at the same time
1638                 pHighestThread->create();
1639                 pHighestThread->setPriority(osl_Thread_PriorityHighest);
1640 
1641                 oslThreadPriority aPriority = pHighestThread->getPriority();
1642                 termAndJoinThread(pHighestThread);
1643                 delete pHighestThread;
1644 
1645                 ThreadHelper::outputPriority(aPriority);
1646 
1647 // LLA: Priority settings may not work within some OS versions.
1648 #if ( defined WNT ) || ( defined SOLARIS )
1649                 CPPUNIT_ASSERT_MESSAGE(
1650                     "getPriority",
1651                     aPriority == osl_Thread_PriorityHighest
1652                     );
1653 #else
1654 // LLA: Linux
1655 // NO_PTHREAD_PRIORITY ???
1656                 CPPUNIT_ASSERT_MESSAGE(
1657                     "getPriority",
1658                     aPriority == osl_Thread_PriorityNormal
1659                     );
1660 #endif
1661             }
1662 
1663         void getPriority_002()
1664             {
1665 
1666             }
1667 
1668         CPPUNIT_TEST_SUITE(getPriority);
1669         CPPUNIT_TEST(getPriority_001);
1670         CPPUNIT_TEST(getPriority_002);
1671         CPPUNIT_TEST_SUITE_END();
1672     }; // class getPriority
1673 
1674 
1675     class getIdentifier : public CppUnit::TestFixture
1676     {
1677     public:
1678         // initialise your test code values here.
1679         void setUp()
1680             {
1681             }
1682 
1683         void tearDown()
1684             {
1685             }
1686 
1687         // insert your test code here.
1688         void getIdentifier_001()
1689             {
1690 
1691             }
1692 
1693         void getIdentifier_002()
1694             {
1695 
1696             }
1697 
1698         CPPUNIT_TEST_SUITE(getIdentifier);
1699         CPPUNIT_TEST(getIdentifier_001);
1700         CPPUNIT_TEST(getIdentifier_002);
1701         CPPUNIT_TEST_SUITE_END();
1702     }; // class getIdentifier
1703 
1704     /** Test of the osl::Thread::getCurrentIdentifier method
1705     */
1706     class getCurrentIdentifier : public CppUnit::TestFixture
1707     {
1708     public:
1709         // initialise your test code values here.
1710         void setUp()
1711             {
1712             }
1713 
1714         void tearDown()
1715             {
1716             }
1717 
1718         // insert your test code here.
1719         void getCurrentIdentifier_001()
1720             {
1721                 oslThreadIdentifier oId;
1722                 OCountThread* pCountThread = new OCountThread;
1723                 //OCountThread* pCountThread2 = new OCountThread;
1724                 pCountThread->create();
1725                 //pCountThread2->create();
1726                 pCountThread->setWait(3);
1727                 oId = Thread::getCurrentIdentifier();
1728                 oslThreadIdentifier oIdChild = pCountThread->getIdentifier();
1729                 //t_print("CurrentId is %ld, Child1 id is %ld, Child2 id is %ld\n",oId, oIdChild,pCountThread2->m_id );
1730                 termAndJoinThread(pCountThread);
1731                 delete pCountThread;
1732                 //termAndJoinThread(pCountThread2);
1733                 //delete pCountThread2;
1734 
1735                 CPPUNIT_ASSERT_MESSAGE(
1736                     "Get the identifier for the current active thread.",
1737                     oId != oIdChild
1738                     );
1739 
1740             }
1741 
1742         void getCurrentIdentifier_002()
1743             {
1744             }
1745 
1746         CPPUNIT_TEST_SUITE(getCurrentIdentifier);
1747         CPPUNIT_TEST(getCurrentIdentifier_001);
1748         //CPPUNIT_TEST(getCurrentIdentifier_002);
1749         CPPUNIT_TEST_SUITE_END();
1750     }; // class getCurrentIdentifier
1751 
1752     /** Test of the osl::Thread::wait method
1753     */
1754     class wait : public CppUnit::TestFixture
1755     {
1756     public:
1757         // initialise your test code values here.
1758         void setUp()
1759             {
1760             }
1761 
1762         void tearDown()
1763             {
1764             }
1765 
1766         /** call wait in the run method
1767 
1768             ALGORITHM:
1769             tested thread wait nWaitSec seconds, main thread sleep (2) seconds,
1770             then terminate the tested thread, due to the fact that the thread do a sleep(1) + wait(5)
1771             it's finish after 6 seconds.
1772         */
1773         void wait_001()
1774             {
1775                 OCountThread *aCountThread = new OCountThread();
1776                 sal_Int32 nWaitSec = 5;
1777                 aCountThread->setWait(nWaitSec);
1778                 // thread runs at least 5 seconds.
1779                 sal_Bool bRes = aCountThread->create();
1780                 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
1781 
1782                 //record the time when the running begin
1783                 StopWatch aStopWatch;
1784                 aStopWatch.start();
1785 
1786                 // wait a little bit, to let the thread the time, to start
1787                 ThreadHelper::thread_sleep_tenth_sec( 4 );
1788 
1789                 // if wait works,
1790                 // this function returns, after 4 sec. later
1791                 termAndJoinThread(aCountThread);
1792 
1793                 // value should be one.
1794                 sal_Int32 nValue = aCountThread->getValue();
1795 
1796                 aStopWatch.stop();
1797 
1798                 // sal_uInt32 nSec  = aTimeVal_after.Seconds - aTimeVal_befor.Seconds;
1799                 double nTenthSec = aStopWatch.getTenthSec();
1800                 double nSec = aStopWatch.getSeconds();
1801                 delete aCountThread;
1802                 t_print("nTenthSec = %f \n", nTenthSec);
1803                 t_print("nSec = %f \n", nSec);
1804                 t_print("nValue = %d \n", nValue);
1805 
1806                 CPPUNIT_ASSERT_MESSAGE(
1807                     "Wait: Blocks the calling thread for the given number of time.",
1808                     nTenthSec >= 5 && nValue == 1
1809                     );
1810 
1811             }
1812 // LLA: wait_001 does the same.
1813 // LLA:         /** wait then terminate the thread
1814 // LLA:
1815 // LLA:         ALGORITHM:
1816 // LLA:         wait nWaitSec seconds, and terminate when the wait does not finish
1817 // LLA:         Windows & UNX: thread terminates immediatlly
1818 // LLA:     */
1819 // LLA:     void wait_002()
1820 // LLA:     {
1821 // LLA:         OCountThread aThread;
1822 // LLA:
1823 // LLA:         sal_Int32 nWaitSec = 3;
1824 // LLA:         aThread.setWait(nWaitSec);
1825 // LLA:
1826 // LLA:         sal_Bool bRes = aThread.create();
1827 // LLA:         CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
1828 // LLA:
1829 // LLA:         StopWatch aStopWatch;
1830 // LLA:         // TimeValue aTimeVal_befor;
1831 // LLA:         // osl_getSystemTime( &aTimeVal_befor );
1832 // LLA:         aStopWatch.start();
1833 // LLA:
1834 // LLA:         termAndJoinThread(&aThread);
1835 // LLA:         sal_Int32 nValue = aThread.getValue();
1836 // LLA:
1837 // LLA:         // TimeValue aTimeVal_after;
1838 // LLA:         // osl_getSystemTime( &aTimeVal_after );
1839 // LLA:         aStopWatch.stop();
1840 // LLA:         // sal_Int32 nSec = aTimeVal_after.Seconds  - aTimeVal_befor.Seconds;
1841 // LLA:         double nSec = aStopWatch.getSeconds();
1842 // LLA:         t_print("sec=%f\n", nSec);
1843 // LLA:         t_print("nValue = %d\n", nValue);
1844 // LLA:
1845 // LLA:         CPPUNIT_ASSERT_MESSAGE(
1846 // LLA:             "Wait: Blocks the calling thread for the given number of time.",
1847 // LLA:             nSec < 1 && nValue == 0
1848 // LLA:         );
1849 // LLA:     }
1850 
1851         CPPUNIT_TEST_SUITE(wait);
1852         CPPUNIT_TEST(wait_001);
1853         // LLA: CPPUNIT_TEST(wait_002);
1854         CPPUNIT_TEST_SUITE_END();
1855     }; // class wait
1856 
1857     /** osl::Thread::yield method: can not design good test scenario to test up to now
1858     */
1859     class yield : public CppUnit::TestFixture
1860     {
1861     public:
1862         void setUp()
1863             {
1864             }
1865 
1866         void tearDown()
1867             {
1868             }
1869 
1870         // insert your test code here.
1871         void yield_001()
1872             {
1873             }
1874 
1875 
1876         CPPUNIT_TEST_SUITE(yield);
1877         CPPUNIT_TEST(yield_001);
1878         CPPUNIT_TEST_SUITE_END();
1879     }; // class yield
1880 
1881     /** Test of the osl::Thread::schedule method
1882     */
1883     class schedule : public CppUnit::TestFixture
1884     {
1885     public:
1886         // initialise your test code values here.
1887         void setUp()
1888             {
1889             }
1890 
1891         void tearDown()
1892             {
1893             }
1894 
1895         /** The requested thread will get terminate the next time schedule() is called.
1896 
1897             Note: on UNX, if call suspend thread is not the to be suspended thread, the to be
1898             suspended   thread will get suspended the next time schedule() is called,
1899             while on w32, it's nothing with schedule.
1900 
1901             check if suspend and terminate work well via schedule
1902         */
1903         void schedule_001()
1904             {
1905                 OAddThread* aThread = new OAddThread();
1906                 sal_Bool bRes = aThread->create();
1907                 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
1908 
1909                 ThreadHelper::thread_sleep_tenth_sec(2);
1910                 aThread->suspend();
1911                 ThreadHelper::thread_sleep_tenth_sec(1);
1912                 sal_Int32 nValue = aThread->getValue();
1913                 ThreadHelper::thread_sleep_tenth_sec(3);
1914                 sal_Int32 nLaterValue = aThread->getValue();
1915                 // resumeAndWaitThread(aThread);
1916                 t_print("      value = %d\n", nValue);
1917                 t_print("later value = %d\n", nLaterValue);
1918                 // if value and latervalue not equal, than the thread would not suspended
1919 
1920                 CPPUNIT_ASSERT_MESSAGE(
1921                     "Schedule: suspend works.",
1922                     nLaterValue == nValue
1923                     );
1924 
1925                 aThread->resume();
1926                 ThreadHelper::thread_sleep_tenth_sec(2);
1927 
1928                 aThread->terminate();
1929                 sal_Int32 nValue_term = aThread->getValue();
1930 
1931                 aThread->join();
1932                 sal_Int32 nValue_join = aThread->getValue();
1933 
1934                 t_print("value after term = %d\n", nValue_term);
1935                 t_print("value after join = %d\n", nValue_join);
1936 
1937                 // nValue_term and nValue_join should be the same
1938                 // but should be differ from nValue
1939 
1940                 delete aThread;
1941                 //check if thread really terminate after call terminate, if join immediatlly return
1942                 CPPUNIT_ASSERT_MESSAGE(
1943                     "Schedule: Returns False if the thread should terminate.",
1944                     nValue_join -  nValue_term <= 1 && nValue_join -  nValue_term >= 0
1945                     );
1946 
1947             }
1948 
1949         /** design a thread that has not call schedule in the workfunction--run method
1950          */
1951         void schedule_002()
1952             {
1953                 ONoScheduleThread aThread; // this thread runs 10 sec. (no schedule() used)
1954                 sal_Bool bRes = aThread.create();
1955                 CPPUNIT_ASSERT_MESSAGE ( "Can't start thread!", bRes == sal_True );
1956 
1957                 ThreadHelper::thread_sleep_tenth_sec(2);
1958                 aThread.suspend();
1959                 sal_Int32 nValue = aThread.getValue();
1960 
1961                 ThreadHelper::thread_sleep_tenth_sec(3);
1962                 sal_Int32 nLaterValue = aThread.getValue();
1963                 ThreadHelper::thread_sleep_tenth_sec(5);
1964 
1965                 resumeAndWaitThread(&aThread);
1966 
1967                 t_print("      value = %d\n", nValue);
1968                 t_print("later value = %d\n", nLaterValue);
1969 
1970                 //On windows, suspend works, so the values are same
1971 #ifdef WNT
1972                 CPPUNIT_ASSERT_MESSAGE(
1973                     "Schedule: don't schedule in thread run method, suspend works.",
1974                     nLaterValue == nValue
1975                     );
1976 #endif
1977 
1978                 //On UNX, suspend does not work, so the difference of the values equals to sleep seconds number
1979 #ifdef UNX
1980                 aThread.resume();
1981                 CPPUNIT_ASSERT_MESSAGE(
1982                     "Schedule: don't schedule in thread run method, suspend does not work too.",
1983                     nLaterValue > nValue
1984                     );
1985 #endif
1986 
1987                 // terminate will not work if no schedule in thread's work function
1988                 termAndJoinThread(&aThread);
1989                 sal_Int32 nValue_term = aThread.getValue();
1990 
1991                 t_print(" value term = %d\n", nValue_term);
1992 
1993                 CPPUNIT_ASSERT_MESSAGE(
1994                     "Schedule: don't schedule in thread run method, terminate failed.",
1995                     nValue_term == 10
1996                     );
1997             }
1998 
1999         CPPUNIT_TEST_SUITE(schedule);
2000         CPPUNIT_TEST(schedule_001);
2001         CPPUNIT_TEST(schedule_002);
2002         CPPUNIT_TEST_SUITE_END();
2003     }; // class schedule
2004 
2005 // -----------------------------------------------------------------------------
2006     CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::create, "osl_Thread");
2007     CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::createSuspended, "osl_Thread");
2008     CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::suspend, "osl_Thread");
2009     CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::resume, "osl_Thread");
2010     CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::terminate, "osl_Thread");
2011     CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::join, "osl_Thread");
2012     CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::isRunning, "osl_Thread");
2013     CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::setPriority, "osl_Thread");
2014     CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::getPriority, "osl_Thread");
2015     CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::getIdentifier, "osl_Thread");
2016     CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::getCurrentIdentifier, "osl_Thread");
2017     CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::wait, "osl_Thread");
2018     CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::yield, "osl_Thread");
2019     CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_Thread::schedule, "osl_Thread");
2020 } // namespace osl_Thread
2021 
2022 
2023 // -----------------------------------------------------------------------------
2024 // destroy function when the binding thread terminate
2025 void SAL_CALL destroyCallback(void * data)
2026 {
2027     t_print("destroying local data %s\n", (char *) data);
2028     delete[] (char *) data;
2029 }
2030 
2031 static ThreadData myThreadData(destroyCallback);
2032 
2033 /**
2034 */
2035 class myKeyThread : public Thread
2036 {
2037 public:
2038     // a public char member for test result checking
2039     char m_Char_Test;
2040     // for pass thread-special data to thread
2041     myKeyThread(const char cData)
2042         {
2043             m_nData = cData;
2044         }
2045 private:
2046     char m_nData;
2047 
2048     void SAL_CALL run()
2049         {
2050             char * pc = new char[2];
2051 //      strcpy(pc, &m_nData);
2052             memcpy(pc, &m_nData, 1);
2053             pc[1] = '\0';
2054 
2055             myThreadData.setData(pc);
2056             char* pData = (char*)myThreadData.getData();
2057             m_Char_Test = *pData;
2058             // wait for long time to check the data value in main thread
2059             ThreadHelper::thread_sleep_tenth_sec(3);
2060         }
2061 public:
2062     ~myKeyThread()
2063         {
2064             if (isRunning())
2065             {
2066                 t_print("error: not terminated.\n");
2067             }
2068         }
2069 };
2070 
2071 static ThreadData idData;
2072 
2073 class idThread: public Thread
2074 {
2075 public:
2076     oslThreadIdentifier m_Id;
2077 private:
2078     void SAL_CALL run()
2079         {
2080             oslThreadIdentifier* pId = new oslThreadIdentifier;
2081             *pId = getIdentifier();
2082             idData.setData(pId);
2083             oslThreadIdentifier* pIdData = (oslThreadIdentifier*)idData.getData();
2084             //t_print("Thread %d has Data %d\n", getIdentifier(), *pIdData);
2085             m_Id = *pIdData;
2086             delete pId;
2087         }
2088 
2089 public:
2090     ~idThread()
2091         {
2092             if (isRunning())
2093             {
2094                 t_print("error: not terminated.\n");
2095             }
2096         }
2097 };
2098 
2099 namespace osl_ThreadData
2100 {
2101 
2102     class ctors : public CppUnit::TestFixture
2103     {
2104     public:
2105         // initialise your test code values here.
2106         void setUp()
2107             {
2108             }
2109 
2110         void tearDown()
2111             {
2112             }
2113 
2114         // insert your test code here.
2115         void ctor_001()
2116             {
2117 
2118             }
2119 
2120         CPPUNIT_TEST_SUITE(ctors);
2121         CPPUNIT_TEST(ctor_001);
2122         CPPUNIT_TEST_SUITE_END();
2123     }; // class ctors
2124 
2125 
2126     class setData : public CppUnit::TestFixture
2127     {
2128     public:
2129         // initialise your test code values here.
2130         void setUp()
2131             {
2132             }
2133 
2134         void tearDown()
2135             {
2136             }
2137 
2138         /** the same instance of the class can have different values in different threads
2139          */
2140         void setData_001()
2141             {
2142                 idThread aThread1;
2143                 aThread1.create();
2144                 idThread aThread2;
2145                 aThread2.create();
2146 
2147                 aThread1.join();
2148                 aThread2.join();
2149 
2150                 oslThreadIdentifier aThreadId1 = aThread1.getIdentifier();
2151                 oslThreadIdentifier aThreadId2 = aThread2.getIdentifier();
2152 
2153                 CPPUNIT_ASSERT_MESSAGE(
2154                     "ThreadData setData: ",
2155                     aThread1.m_Id == aThreadId1 && aThread2.m_Id == aThreadId2
2156                     );
2157 
2158             }
2159 
2160         void setData_002()
2161             {
2162                 // at first, set the data a value
2163                 char* pc = new char[2];
2164                 char m_nData = 'm';
2165 // LLA: this is a copy functions only and really only for \0 terminated strings
2166 //      m_nData is not a string, it's a character
2167 //          strcpy(pc, &m_nData);
2168                 memcpy(pc, &m_nData, 1);
2169                 pc[1] = '\0';
2170 
2171                 myThreadData.setData(pc);
2172 
2173                 myKeyThread aThread1('a');
2174                 aThread1.create();
2175                 myKeyThread aThread2('b');
2176                 aThread2.create();
2177                 // aThread1 and aThread2 should have not terminated yet, check current data, not 'a' 'b'
2178                 char* pChar = (char*)myThreadData.getData();
2179                 char aChar = *pChar;
2180 
2181                 aThread1.join();
2182                 aThread2.join();
2183 
2184                 // the saved thread data of aThread1 & aThread2, different
2185                 char cData1 = aThread1.m_Char_Test;
2186                 char cData2 = aThread2.m_Char_Test;
2187 
2188                 CPPUNIT_ASSERT_MESSAGE(
2189                     "ThreadData setData: ",
2190                     cData1 == 'a' && cData2 == 'b' && aChar == 'm'
2191                     );
2192 
2193             }
2194         /** setData the second time, and then getData
2195          */
2196         void setData_003()
2197             {
2198                 // at first, set the data a value
2199                 char* pc = new char[2];
2200                 char m_nData = 'm';
2201 //          strcpy(pc, &m_nData);
2202                 memcpy(pc, &m_nData, 1);
2203                 pc[1] = '\0';
2204                 myThreadData.setData(pc);
2205 
2206                 myKeyThread aThread1('a');
2207                 aThread1.create();
2208                 myKeyThread aThread2('b');
2209                 aThread2.create();
2210                 // aThread1 and aThread2 should have not terminated yet
2211                 // setData the second time
2212                 char* pc2 = new char[2];
2213                 m_nData = 'o';
2214 //          strcpy(pc2, &m_nData);
2215                 memcpy(pc2, &m_nData, 1);
2216                 pc2[1] = '\0';
2217 
2218                 myThreadData.setData(pc2);
2219                 char* pChar = (char*)myThreadData.getData();
2220                 char aChar = *pChar;
2221 
2222                 aThread1.join();
2223                 aThread2.join();
2224 
2225                 // the saved thread data of aThread1 & aThread2, different
2226                 char cData1 = aThread1.m_Char_Test;
2227                 char cData2 = aThread2.m_Char_Test;
2228 
2229                 CPPUNIT_ASSERT_MESSAGE(
2230                     "ThreadData setData: ",
2231                     cData1 == 'a' && cData2 == 'b' && aChar == 'o'
2232                     );
2233 
2234             }
2235 
2236         CPPUNIT_TEST_SUITE(setData);
2237         CPPUNIT_TEST(setData_001);
2238         CPPUNIT_TEST(setData_002);
2239         CPPUNIT_TEST(setData_003);
2240         CPPUNIT_TEST_SUITE_END();
2241     }; // class setData
2242 
2243     //sal_Bool buildTwoThreads(char)
2244 
2245     class getData : public CppUnit::TestFixture
2246     {
2247     public:
2248         // initialise your test code values here.
2249         void setUp()
2250             {
2251             }
2252 
2253         void tearDown()
2254             {
2255             }
2256 
2257         // After setData in child threads, get Data in the main thread, should be independent
2258         void getData_001()
2259             {
2260                 char* pc = new char[2];
2261                 char m_nData[] = "i";
2262                 strcpy(pc, m_nData);
2263                 t_print("pc %s\n", pc);
2264                 myThreadData.setData(pc);
2265 
2266                 myKeyThread aThread1('c');
2267                 aThread1.create();
2268                 myKeyThread aThread2('d');
2269                 aThread2.create();
2270 
2271                 aThread1.join();
2272                 aThread2.join();
2273 
2274                 char cData1 = aThread1.m_Char_Test;
2275                 char cData2 = aThread2.m_Char_Test;
2276 
2277                 char* pChar = (char*)myThreadData.getData();
2278                 char aChar = *pChar;
2279 
2280                 CPPUNIT_ASSERT_MESSAGE(
2281                     "ThreadData setData: ",
2282                     cData1 == 'c' && cData2 == 'd' && aChar == 'i'
2283                     );
2284 
2285             }
2286 
2287         // setData then change the value in the address data pointer points,
2288         // and then getData, should get the new value
2289         void getData_002()
2290             {
2291                 char* pc = new char[2];
2292                 char m_nData = 'i';
2293 //          strcpy(pc, &m_nData);
2294                 memcpy(pc, &m_nData, 1);
2295                 pc[1] = '\0';
2296 //          strncpy(pc, &m_nData, sizeof(char);
2297 
2298                 t_print("pc %s\n", pc);
2299                 myThreadData.setData(pc);
2300 
2301                 myKeyThread aThread1('a');
2302                 aThread1.create();
2303                 myKeyThread aThread2('b');
2304                 aThread2.create();
2305 
2306                 // change the value which pc points
2307                 char m_nData2 = 'j';
2308                 // strcpy(pc, &m_nData2);
2309                 memcpy(pc, &m_nData2, 1);
2310                 pc[1] = '\0';
2311 
2312                 //t_print("pc %s\n", pc);
2313                 void* pChar = myThreadData.getData();
2314                 char aChar = *(char*)pChar;
2315 
2316                 aThread1.join();
2317                 aThread2.join();
2318 
2319                 char cData1 = aThread1.m_Char_Test;
2320                 char cData2 = aThread2.m_Char_Test;
2321 
2322                 CPPUNIT_ASSERT_MESSAGE(
2323                     "ThreadData setData: ",
2324                     cData1 == 'a' && cData2 == 'b' && aChar == 'j'
2325                     );
2326 
2327             }
2328 
2329         CPPUNIT_TEST_SUITE(getData);
2330         CPPUNIT_TEST(getData_001);
2331         CPPUNIT_TEST(getData_002);
2332         CPPUNIT_TEST_SUITE_END();
2333     }; // class getData
2334 
2335 // -----------------------------------------------------------------------------
2336     CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_ThreadData::ctors, "osl_ThreadData");
2337     CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_ThreadData::setData, "osl_ThreadData");
2338     CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(osl_ThreadData::getData, "osl_ThreadData");
2339 } // namespace osl_ThreadData
2340 
2341 // this macro creates an empty function, which will called by the RegisterAllFunctions()
2342 // to let the user the possibility to also register some functions by hand.
2343 NOADDITIONAL;
2344 
2345