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