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