309 lines
6.9 KiB
C++
309 lines
6.9 KiB
C++
/*
|
|
Copyright (C) 2004-2008 Grame
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <sys/time.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#ifdef __APPLE__
|
|
#include "JackMachThread.h"
|
|
#endif
|
|
|
|
#include "JackPosixThread.h"
|
|
#include "JackMutex.h"
|
|
#include "thread.h"
|
|
|
|
using namespace Jack;
|
|
|
|
static void CleanupHandler(void * arg)
|
|
{
|
|
JackLockAble* locked = (JackLockAble*)arg;
|
|
printf("CleanupHandler locked %px \n", locked);
|
|
locked->Unlock();
|
|
}
|
|
|
|
struct LockedObject : public JackLockAble {
|
|
|
|
int fCount;
|
|
|
|
LockedObject():fCount(0)
|
|
{}
|
|
|
|
virtual ~LockedObject()
|
|
{}
|
|
|
|
/*
|
|
void LockedMethod1()
|
|
{
|
|
JackLock lock(this);
|
|
fCount++;
|
|
printf("LockedMethod1 self %x fCount %d\n", pthread_self(), fCount);
|
|
if (fCount >= 1000) {
|
|
printf("Terminate self %x\n", pthread_self());
|
|
pthread_exit(NULL);
|
|
}
|
|
}
|
|
|
|
void LockedMethod2()
|
|
{
|
|
JackLock lock(this);
|
|
fCount++;
|
|
printf("LockedMethod2 self %x fCount %d\n", pthread_self(), fCount);
|
|
if (fCount >= 1500) {
|
|
printf("Terminate self %x\n", pthread_self());
|
|
pthread_exit(NULL);
|
|
}
|
|
}
|
|
|
|
void LockedMethod3()
|
|
{
|
|
JackLock lock(this);
|
|
fCount++;
|
|
printf("LockedMethod3 self %x fCount %d\n", pthread_self(), fCount);
|
|
if (fCount >= 3000) {
|
|
printf("Terminate self %x\n", pthread_self());
|
|
pthread_exit(NULL);
|
|
}
|
|
}
|
|
*/
|
|
|
|
void LockedMethod1()
|
|
{
|
|
pthread_cleanup_push(CleanupHandler, this);
|
|
Lock();
|
|
fCount++;
|
|
//printf("LockedMethod1 self %x fCount %d\n", pthread_self(), fCount);
|
|
if (fCount >= 1000) {
|
|
printf("Terminate self = %px count = %d\n", pthread_self(), fCount);
|
|
pthread_exit(NULL);
|
|
}
|
|
Unlock();
|
|
pthread_cleanup_pop(0);
|
|
}
|
|
|
|
void LockedMethod2()
|
|
{
|
|
pthread_cleanup_push(CleanupHandler, this);
|
|
Lock();
|
|
|
|
fCount++;
|
|
//printf("LockedMethod2 self %x fCount %d\n", pthread_self(), fCount);
|
|
if (fCount >= 1500) {
|
|
printf("Terminate self = %px count = %d\n", pthread_self(), fCount);
|
|
pthread_exit(NULL);
|
|
}
|
|
Unlock();
|
|
pthread_cleanup_pop(0);
|
|
}
|
|
|
|
void LockedMethod3()
|
|
{
|
|
pthread_cleanup_push(CleanupHandler, this);
|
|
Lock();
|
|
|
|
fCount++;
|
|
//printf("LockedMethod3 self %x fCount %d\n", pthread_self(), fCount);
|
|
if (fCount >= 3000) {
|
|
printf("Terminate self = %px count = %d\n", pthread_self(), fCount);
|
|
pthread_exit(NULL);
|
|
}
|
|
Unlock();
|
|
pthread_cleanup_pop(0);
|
|
}
|
|
|
|
|
|
};
|
|
|
|
struct TestThread : public JackRunnableInterface {
|
|
|
|
JackMachThread* fThread;
|
|
LockedObject* fObject;
|
|
int fNum;
|
|
|
|
TestThread(LockedObject* obj, int num)
|
|
{
|
|
printf("TestThread\n");
|
|
fThread = new JackMachThread(this);
|
|
fObject = obj;
|
|
fNum = num;
|
|
fThread->StartSync();
|
|
}
|
|
|
|
virtual ~TestThread()
|
|
{
|
|
printf("DELETE %px\n", fThread);
|
|
fThread->Kill();
|
|
delete fThread;
|
|
}
|
|
|
|
bool Execute()
|
|
{
|
|
//printf("TestThread Execute\n");
|
|
switch (fNum) {
|
|
|
|
case 1:
|
|
fObject->LockedMethod1();
|
|
/*
|
|
if (fObject->fCount >= 500) {
|
|
printf("Terminate self %x\n", pthread_self());
|
|
fThread->Terminate();
|
|
}
|
|
*/
|
|
break;
|
|
|
|
case 2:
|
|
fObject->LockedMethod2();
|
|
/*
|
|
if (fObject->fCount >= 1500) {
|
|
printf("Terminate self %x\n", pthread_self());
|
|
fThread->Terminate();
|
|
}
|
|
*/
|
|
break;
|
|
|
|
case 3:
|
|
fObject->LockedMethod3();
|
|
/*
|
|
if (fObject->fCount >= 2000) {
|
|
printf("Terminate self %x\n", pthread_self());
|
|
fThread->Terminate();
|
|
}
|
|
*/
|
|
break;
|
|
};
|
|
|
|
//usleep(fNum * 1000);
|
|
return true;
|
|
}
|
|
|
|
};
|
|
|
|
static void* TestThread1_Execute(void* arg);
|
|
|
|
struct TestThread1 : public JackRunnableInterface {
|
|
|
|
pthread_t fThread;
|
|
LockedObject* fObject;
|
|
int fNum;
|
|
|
|
TestThread1(LockedObject* obj, int num)
|
|
{
|
|
if (jack_client_create_thread(NULL, &fThread, 0, 0, TestThread1_Execute, this))
|
|
jack_error( "Can't create the network manager control thread." );
|
|
fObject = obj;
|
|
fNum = num;
|
|
}
|
|
|
|
virtual ~TestThread1()
|
|
{}
|
|
|
|
bool Execute()
|
|
{
|
|
printf("TestThread Execute\n");
|
|
switch (fNum) {
|
|
|
|
case 1:
|
|
fObject->LockedMethod1();
|
|
break;
|
|
|
|
case 2:
|
|
fObject->LockedMethod2();
|
|
break;
|
|
|
|
case 3:
|
|
fObject->LockedMethod3();
|
|
break;
|
|
};
|
|
|
|
//usleep(fNum * 1000);
|
|
return true;
|
|
}
|
|
|
|
};
|
|
|
|
static void* TestThread1_Execute(void* arg)
|
|
{
|
|
TestThread1* obj = (TestThread1*)arg;
|
|
|
|
while (true) {
|
|
//printf("TestThread Execute\n");
|
|
switch (obj->fNum) {
|
|
|
|
case 1:
|
|
obj->fObject->LockedMethod1();
|
|
break;
|
|
|
|
case 2:
|
|
obj->fObject->LockedMethod2();
|
|
break;
|
|
|
|
case 3:
|
|
obj->fObject->LockedMethod3();
|
|
break;
|
|
};
|
|
|
|
//usleep(obj->fNum * 1000);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int main (int argc, char * const argv[])
|
|
{
|
|
char c;
|
|
|
|
LockedObject obj;
|
|
|
|
TestThread th1(&obj, 1);
|
|
TestThread th2(&obj, 2);
|
|
TestThread th3(&obj, 3);
|
|
|
|
/*
|
|
LockedObject obj;
|
|
TestThread1 th1(&obj, 1);
|
|
TestThread th2(&obj, 2);
|
|
TestThread th3(&obj, 3);
|
|
*/
|
|
|
|
/*
|
|
while ((c = getchar()) != 'q') {
|
|
|
|
}
|
|
*/
|
|
|
|
while (true) {
|
|
usleep(1000);
|
|
th1.fThread->Kill();
|
|
}
|
|
|
|
/*
|
|
th1.fThread->Kill();
|
|
th2.fThread->Kill();
|
|
th3.fThread->Kill();
|
|
|
|
while (true) {
|
|
//usleep(100000);
|
|
th1.fThread->Kill();
|
|
}
|
|
*/
|
|
|
|
}
|