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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3766 - (hide 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 schoenebeck 57 #include "ThreadTest.h"
2    
3     #include <iostream>
4    
5     CPPUNIT_TEST_SUITE_REGISTRATION(ThreadTest);
6    
7 schoenebeck 211 using namespace std;
8 schoenebeck 57
9 schoenebeck 1221 static ThreadTest::DummyThread dummythread;
10 schoenebeck 211
11 schoenebeck 1221
12 schoenebeck 57 // DummyThread
13    
14 schoenebeck 1221 ThreadTest::DummyThread::DummyThread() : LinuxSampler::Thread(false, false, 0, -4) {
15 schoenebeck 57 wasRunning = false;
16     }
17    
18     int ThreadTest::DummyThread::Main() {
19     wasRunning = true;
20 nagata 1649 while (true) {
21     someVariable = -1;
22     TestCancel();
23     }
24 schoenebeck 3552 return 0;
25 schoenebeck 57 }
26    
27    
28     // HelperThread
29    
30 schoenebeck 1221 ThreadTest::HelperThread::HelperThread(DummyThread* pDummyThread) : LinuxSampler::Thread(false, false, 0, -4) {
31 schoenebeck 57 returnedFromDummyStop = false;
32     this->pDummyThread = pDummyThread;
33     }
34    
35     int ThreadTest::HelperThread::Main() {
36     pDummyThread->StopThread();
37 schoenebeck 211 pDummyThread->someVariable = 0; // we set this to another value than -1 so we can check if the DummyThread was still running
38 schoenebeck 57 returnedFromDummyStop = true;
39 schoenebeck 3552 return 0;
40 schoenebeck 57 }
41    
42 schoenebeck 211 bool ThreadTest::HelperThread::dummyThreadWasNotRunningAnymoreAfter_StopThread_call() {
43     return (pDummyThread->someVariable == 0);
44     }
45 schoenebeck 57
46 schoenebeck 211
47 schoenebeck 63 // WaitingThread
48    
49 schoenebeck 1221 ThreadTest::WaitingThread::WaitingThread() : LinuxSampler::Thread(false, false, 0, -4) {
50 schoenebeck 63 }
51    
52     int ThreadTest::WaitingThread::Main() {
53     while (true) condition.WaitIf(false);
54     }
55    
56    
57 schoenebeck 57 // ThreadTest
58    
59 schoenebeck 211 void ThreadTest::printTestSuiteName() {
60     cout << "\b \nRunning Thread Tests: " << flush;
61     }
62    
63 schoenebeck 63 // Check if Thread class actually deploys a thread
64 schoenebeck 57 void ThreadTest::testThreadRunning() {
65     dummythread.StartThread();
66     usleep(25000); // wait 25ms
67     CPPUNIT_ASSERT(dummythread.wasRunning);
68     CPPUNIT_ASSERT(dummythread.IsRunning());
69     }
70    
71 schoenebeck 63 // Check if SignalStopThread() method actually stops the thread
72 schoenebeck 57 void ThreadTest::testSignalStopThread() {
73 schoenebeck 1221 CPPUNIT_ASSERT(dummythread.wasRunning);
74     CPPUNIT_ASSERT(dummythread.IsRunning());
75 schoenebeck 57 dummythread.SignalStopThread();
76 schoenebeck 1221 usleep(80000); // wait 40ms
77 schoenebeck 57 CPPUNIT_ASSERT(!dummythread.IsRunning());
78     }
79    
80 schoenebeck 63 // Check if the thread can be relaunched
81 schoenebeck 57 void ThreadTest::testRelaunchThread() {
82 schoenebeck 63 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 schoenebeck 57 dummythread.wasRunning = false;
89     dummythread.StartThread();
90     usleep(25000); // wait 25ms
91     CPPUNIT_ASSERT(dummythread.wasRunning);
92     CPPUNIT_ASSERT(dummythread.IsRunning());
93     }
94    
95 schoenebeck 211 // 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 schoenebeck 57 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 schoenebeck 211 bool wasnotrunning = phelper->dummyThreadWasNotRunningAnymoreAfter_StopThread_call();
103     if (wasnotrunning && phelper) delete phelper;
104     CPPUNIT_ASSERT(wasnotrunning);
105 schoenebeck 57 }
106 schoenebeck 63
107     // Check if the thread can be stopped even when it's waiting for a condition
108     void ThreadTest::testThreadKillableWhenWaiting() {
109 schoenebeck 211 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 schoenebeck 63 }

  ViewVC Help
Powered by ViewVC