Devin Anderson jackmp-fix-ffado-midi-2.diff patch.
[jack2.git] / tests / testMutex.cpp
blob234fd06cd63574659b4610d03df43fb63a81059b
1 /*
2 Copyright (C) 2004-2008 Grame
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include <stdio.h>
21 #include <sys/time.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
26 #ifdef __APPLE__
27 #include "JackMachThread.h"
28 #endif
30 #include "JackPosixThread.h"
31 #include "JackMutex.h"
32 #include "thread.h"
34 using namespace Jack;
36 static void CleanupHandler(void * arg)
38 JackLockAble* locked = (JackLockAble*)arg;
39 printf("CleanupHandler locked %px \n", locked);
40 locked->Unlock();
43 struct LockedObject : public JackLockAble {
45 int fCount;
47 LockedObject():fCount(0)
50 virtual ~LockedObject()
54 void LockedMethod1()
56 JackLock lock(this);
57 fCount++;
58 printf("LockedMethod1 self %x fCount %d\n", pthread_self(), fCount);
59 if (fCount >= 1000) {
60 printf("Terminate self %x\n", pthread_self());
61 pthread_exit(NULL);
65 void LockedMethod2()
67 JackLock lock(this);
68 fCount++;
69 printf("LockedMethod2 self %x fCount %d\n", pthread_self(), fCount);
70 if (fCount >= 1500) {
71 printf("Terminate self %x\n", pthread_self());
72 pthread_exit(NULL);
76 void LockedMethod3()
78 JackLock lock(this);
79 fCount++;
80 printf("LockedMethod3 self %x fCount %d\n", pthread_self(), fCount);
81 if (fCount >= 3000) {
82 printf("Terminate self %x\n", pthread_self());
83 pthread_exit(NULL);
88 void LockedMethod1()
90 pthread_cleanup_push(CleanupHandler, this);
91 Lock();
92 fCount++;
93 //printf("LockedMethod1 self %x fCount %d\n", pthread_self(), fCount);
94 if (fCount >= 1000) {
95 printf("Terminate self = %px count = %d\n", pthread_self(), fCount);
96 pthread_exit(NULL);
98 Unlock();
99 pthread_cleanup_pop(0);
102 void LockedMethod2()
104 pthread_cleanup_push(CleanupHandler, this);
105 Lock();
107 fCount++;
108 //printf("LockedMethod2 self %x fCount %d\n", pthread_self(), fCount);
109 if (fCount >= 1500) {
110 printf("Terminate self = %px count = %d\n", pthread_self(), fCount);
111 pthread_exit(NULL);
113 Unlock();
114 pthread_cleanup_pop(0);
117 void LockedMethod3()
119 pthread_cleanup_push(CleanupHandler, this);
120 Lock();
122 fCount++;
123 //printf("LockedMethod3 self %x fCount %d\n", pthread_self(), fCount);
124 if (fCount >= 3000) {
125 printf("Terminate self = %px count = %d\n", pthread_self(), fCount);
126 pthread_exit(NULL);
128 Unlock();
129 pthread_cleanup_pop(0);
135 struct TestThread : public JackRunnableInterface {
137 JackMachThread* fThread;
138 LockedObject* fObject;
139 int fNum;
141 TestThread(LockedObject* obj, int num)
143 printf("TestThread\n");
144 fThread = new JackMachThread(this);
145 fObject = obj;
146 fNum = num;
147 fThread->StartSync();
150 virtual ~TestThread()
152 printf("DELETE %px\n", fThread);
153 fThread->Kill();
154 delete fThread;
157 bool Execute()
159 //printf("TestThread Execute\n");
160 switch (fNum) {
162 case 1:
163 fObject->LockedMethod1();
165 if (fObject->fCount >= 500) {
166 printf("Terminate self %x\n", pthread_self());
167 fThread->Terminate();
170 break;
172 case 2:
173 fObject->LockedMethod2();
175 if (fObject->fCount >= 1500) {
176 printf("Terminate self %x\n", pthread_self());
177 fThread->Terminate();
180 break;
182 case 3:
183 fObject->LockedMethod3();
185 if (fObject->fCount >= 2000) {
186 printf("Terminate self %x\n", pthread_self());
187 fThread->Terminate();
190 break;
193 //usleep(fNum * 1000);
194 return true;
199 static void* TestThread1_Execute(void* arg);
201 struct TestThread1 : public JackRunnableInterface {
203 pthread_t fThread;
204 LockedObject* fObject;
205 int fNum;
207 TestThread1(LockedObject* obj, int num)
209 if (jack_client_create_thread(NULL, &fThread, 0, 0, TestThread1_Execute, this))
210 jack_error( "Can't create the network manager control thread." );
211 fObject = obj;
212 fNum = num;
215 virtual ~TestThread1()
218 bool Execute()
220 printf("TestThread Execute\n");
221 switch (fNum) {
223 case 1:
224 fObject->LockedMethod1();
225 break;
227 case 2:
228 fObject->LockedMethod2();
229 break;
231 case 3:
232 fObject->LockedMethod3();
233 break;
236 //usleep(fNum * 1000);
237 return true;
242 static void* TestThread1_Execute(void* arg)
244 TestThread1* obj = (TestThread1*)arg;
246 while (true) {
247 //printf("TestThread Execute\n");
248 switch (obj->fNum) {
250 case 1:
251 obj->fObject->LockedMethod1();
252 break;
254 case 2:
255 obj->fObject->LockedMethod2();
256 break;
258 case 3:
259 obj->fObject->LockedMethod3();
260 break;
263 //usleep(obj->fNum * 1000);
266 return 0;
269 int main (int argc, char * const argv[])
271 char c;
273 LockedObject obj;
275 TestThread th1(&obj, 1);
276 TestThread th2(&obj, 2);
277 TestThread th3(&obj, 3);
280 LockedObject obj;
281 TestThread1 th1(&obj, 1);
282 TestThread th2(&obj, 2);
283 TestThread th3(&obj, 3);
287 while ((c = getchar()) != 'q') {
292 while (true) {
293 usleep(1000);
294 th1.fThread->Kill();
298 th1.fThread->Kill();
299 th2.fThread->Kill();
300 th3.fThread->Kill();
302 while (true) {
303 //usleep(100000);
304 th1.fThread->Kill();