/[svn]/linuxsampler/trunk/src/testcases/ThreadTest.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/testcases/ThreadTest.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3766 - (show annotations) (download)
Mon Apr 6 12:41:49 2020 UTC (4 years ago) by schoenebeck
File size: 3782 byte(s)
Fixed deadlocks (e.g. when restarting engines).

* Individual thread implementations (e.g. disk thread, etc.):
  Disable thread cancellation on critical sections, e.g. when holding
  mutex locks, to prevent deadlocks if thread is stopped and/or
  restarted.

* Added TestCancel() calls to thread implementations if missing.

* No need to wrap Thread::TestCancel() calls into
  CONFIG_PTHREAD_TESTCANCEL macro conditions (since TestCancel() is
  already a stub on systems which don't have pthread_testcancel()
  available).

* If compiled for debugging: give each thread a human readable name
  to simplify debugging of multi-threading issues.

* DiskThreadBase: TestCancel() and pthread_testcancel() calls are
  per-se redundant, so only call TestCancel().

* Added missing override keywords to silent compiler warnings.

* Bumped version (2.1.1.svn54).

1 #include "ThreadTest.h"
2
3 #include <iostream>
4
5 CPPUNIT_TEST_SUITE_REGISTRATION(ThreadTest);
6
7 using namespace std;
8
9 static ThreadTest::DummyThread dummythread;
10
11
12 // DummyThread
13
14 ThreadTest::DummyThread::DummyThread() : LinuxSampler::Thread(false, false, 0, -4) {
15 wasRunning = false;
16 }
17
18 int ThreadTest::DummyThread::Main() {
19 wasRunning = true;
20 while (true) {
21 someVariable = -1;
22 TestCancel();
23 }
24 return 0;
25 }
26
27
28 // HelperThread
29
30 ThreadTest::HelperThread::HelperThread(DummyThread* pDummyThread) : LinuxSampler::Thread(false, false, 0, -4) {
31 returnedFromDummyStop = false;
32 this->pDummyThread = pDummyThread;
33 }
34
35 int ThreadTest::HelperThread::Main() {
36 pDummyThread->StopThread();
37 pDummyThread->someVariable = 0; // we set this to another value than -1 so we can check if the DummyThread was still running
38 returnedFromDummyStop = true;
39 return 0;
40 }
41
42 bool ThreadTest::HelperThread::dummyThreadWasNotRunningAnymoreAfter_StopThread_call() {
43 return (pDummyThread->someVariable == 0);
44 }
45
46
47 // WaitingThread
48
49 ThreadTest::WaitingThread::WaitingThread() : LinuxSampler::Thread(false, false, 0, -4) {
50 }
51
52 int ThreadTest::WaitingThread::Main() {
53 while (true) condition.WaitIf(false);
54 }
55
56
57 // ThreadTest
58
59 void ThreadTest::printTestSuiteName() {
60 cout << "\b \nRunning Thread Tests: " << flush;
61 }
62
63 // Check if Thread class actually deploys a thread
64 void ThreadTest::testThreadRunning() {
65 dummythread.StartThread();
66 usleep(25000); // wait 25ms
67 CPPUNIT_ASSERT(dummythread.wasRunning);
68 CPPUNIT_ASSERT(dummythread.IsRunning());
69 }
70
71 // Check if SignalStopThread() method actually stops the thread
72 void ThreadTest::testSignalStopThread() {
73 CPPUNIT_ASSERT(dummythread.wasRunning);
74 CPPUNIT_ASSERT(dummythread.IsRunning());
75 dummythread.SignalStopThread();
76 usleep(80000); // wait 40ms
77 CPPUNIT_ASSERT(!dummythread.IsRunning());
78 }
79
80 // Check if the thread can be relaunched
81 void ThreadTest::testRelaunchThread() {
82 dummythread.StartThread();
83 usleep(25000); // wait 25ms
84 CPPUNIT_ASSERT(dummythread.wasRunning);
85 CPPUNIT_ASSERT(dummythread.IsRunning());
86 dummythread.StopThread();
87 usleep(25000); // wait 25ms
88 dummythread.wasRunning = false;
89 dummythread.StartThread();
90 usleep(25000); // wait 25ms
91 CPPUNIT_ASSERT(dummythread.wasRunning);
92 CPPUNIT_ASSERT(dummythread.IsRunning());
93 }
94
95 // Check if the StopThread() method actually stops the thread and doesn't freeze the calling thread which wants to stop it and also check if the thread was still running after the StopThread() method was called.
96 void ThreadTest::testStopThread() {
97 HelperThread* phelper = new HelperThread(&dummythread);
98 phelper->StartThread(); // let the helper thread kill the dummy thread
99 usleep(25000); // wait 25ms
100 CPPUNIT_ASSERT(!dummythread.IsRunning());
101 CPPUNIT_ASSERT(phelper->returnedFromDummyStop);
102 bool wasnotrunning = phelper->dummyThreadWasNotRunningAnymoreAfter_StopThread_call();
103 if (wasnotrunning && phelper) delete phelper;
104 CPPUNIT_ASSERT(wasnotrunning);
105 }
106
107 // Check if the thread can be stopped even when it's waiting for a condition
108 void ThreadTest::testThreadKillableWhenWaiting() {
109 WaitingThread* pwaitingthread = new WaitingThread;
110 pwaitingthread->SignalStartThread();
111 usleep(150000); // wait 150ms
112 CPPUNIT_ASSERT(pwaitingthread->IsRunning());
113 pwaitingthread->SignalStopThread();
114 for (uint trials = 400; trials; trials--) {
115 bool success = !pwaitingthread->IsRunning();
116 if (success) {
117 usleep(15000); // wait 15ms
118 delete pwaitingthread;
119 CPPUNIT_ASSERT(true); // success
120 return;
121 }
122 else usleep(150000); // wait 150ms and try again
123 }
124 CPPUNIT_ASSERT(false); // failure
125 }

  ViewVC Help
Powered by ViewVC