347 lines
6.8 KiB
C++
347 lines
6.8 KiB
C++
|
|
|
|
#include "tthread.h"
|
|
#include <pthread.h>
|
|
|
|
//---------------------------------------------------------------------------
|
|
// TMutex & TMutexImp
|
|
//---------------------------------------------------------------------------
|
|
|
|
class TMutexImp
|
|
{
|
|
pthread_mutex_t id;
|
|
|
|
public:
|
|
TMutexImp();
|
|
~TMutexImp();
|
|
void lock();
|
|
void unlock();
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
TMutex lockForTheList;
|
|
|
|
class TThreadGroupImp
|
|
{
|
|
list<TThread *> threads;
|
|
|
|
public:
|
|
TThreadGroupImp();
|
|
~TThreadGroupImp();
|
|
void add(TThread *);
|
|
void remove(TThread *);
|
|
void wait();
|
|
};
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
TMutexImp::TMutexImp()
|
|
{
|
|
pthread_mutex_init(&id, 0);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
TMutexImp::~TMutexImp()
|
|
{
|
|
pthread_mutex_destroy(&id);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TMutexImp::lock()
|
|
{
|
|
pthread_mutex_lock(&id);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TMutexImp::unlock()
|
|
{
|
|
pthread_mutex_unlock(&id);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
TMutex::TMutex()
|
|
: m_imp(new TMutexImp)
|
|
{
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
TMutex::~TMutex()
|
|
{
|
|
delete m_imp;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TMutex::lock()
|
|
{
|
|
m_imp->lock();
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TMutex::unlock()
|
|
{
|
|
m_imp->unlock();
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
//---------------------------------------------------------------------------
|
|
// TThread & TThreadImp
|
|
//---------------------------------------------------------------------------
|
|
|
|
class TThreadImp
|
|
{
|
|
pthread_t threadId;
|
|
|
|
public:
|
|
TThreadImp();
|
|
~TThreadImp();
|
|
|
|
TThread *thread;
|
|
|
|
void start();
|
|
|
|
bool setThreadPriority(TThread::TThreadPriority p);
|
|
bool setPreferredProcessor(int processorId);
|
|
|
|
TMutex secureLock;
|
|
bool isRunning;
|
|
|
|
static void incNThreads()
|
|
{
|
|
mutex.lock();
|
|
nThreads++;
|
|
mutex.unlock();
|
|
}
|
|
static void decNThreads()
|
|
{
|
|
mutex.lock();
|
|
nThreads--;
|
|
mutex.unlock();
|
|
}
|
|
|
|
//some static stuff
|
|
static TUINT32 nThreads;
|
|
static TMutex mutex;
|
|
|
|
friend class TThreadGroupImp;
|
|
void setOwner(TThreadGroupImp *_owner) { owner = _owner; }
|
|
TThreadGroupImp *owner;
|
|
};
|
|
|
|
TUINT32 TThreadImp::nThreads = 0;
|
|
TMutex TThreadImp::mutex = TMutex();
|
|
//---------------------------------------------------------------------------
|
|
|
|
TThreadImp::TThreadImp()
|
|
: isRunning(false), owner(0), thread(0)
|
|
{
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
TThreadImp::~TThreadImp()
|
|
{
|
|
//CloseHandle(threadId);
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
static void * /*__stdcall*/ fun(void *data)
|
|
{
|
|
TThreadImp *t = (TThreadImp *)data;
|
|
|
|
t->secureLock.lock();
|
|
if (t->isRunning) {
|
|
t->secureLock.unlock();
|
|
assert(!"thread is already running");
|
|
return 0;
|
|
}
|
|
t->isRunning = true;
|
|
|
|
t->secureLock.unlock();
|
|
|
|
t->thread->run();
|
|
|
|
t->decNThreads();
|
|
if (t->owner)
|
|
t->owner->remove(t->thread);
|
|
|
|
return 0;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TThreadImp::start()
|
|
{
|
|
incNThreads();
|
|
pthread_create(&threadId, 0, fun, (void *)this);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
bool TThreadImp::setThreadPriority(TThread::TThreadPriority)
|
|
{
|
|
assert(!"not implemented");
|
|
return false;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
bool TThreadImp::setPreferredProcessor(int processorId)
|
|
{
|
|
#ifdef __sgi
|
|
#if (OP_RELEASE == rel_2)
|
|
assert(!"Not implemented");
|
|
return false;
|
|
#else
|
|
int rc = pthread_setrunon_np(processorId);
|
|
return (rc != -1);
|
|
#endif
|
|
#else
|
|
assert(0);
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
TThread::TThread()
|
|
: m_imp(new TThreadImp())
|
|
{
|
|
m_imp->thread = this;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
TThread::~TThread()
|
|
{
|
|
delete m_imp;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TThread::start()
|
|
{
|
|
m_imp->start();
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
bool TThread::setPreferredProcessor(int processorId)
|
|
{
|
|
return m_imp->setPreferredProcessor(processorId);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
bool TThread::setThreadPriority(TThread::TThreadPriority p)
|
|
{
|
|
return m_imp->setThreadPriority(p);
|
|
}
|
|
|
|
//=======================
|
|
// TThreadGroupImp
|
|
|
|
TThreadGroupImp::TThreadGroupImp()
|
|
{
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
TThreadGroupImp::~TThreadGroupImp()
|
|
{
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TThreadGroupImp::add(TThread *t)
|
|
{
|
|
lockForTheList.lock();
|
|
threads.push_back(t);
|
|
lockForTheList.unlock();
|
|
t->m_imp->setOwner(this);
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TThreadGroupImp::remove(TThread *t)
|
|
{
|
|
lockForTheList.lock();
|
|
threads.remove(t);
|
|
lockForTheList.unlock();
|
|
t->m_imp->setOwner(0);
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
static void * /*__stdcall*/ mainFun(void *data)
|
|
{
|
|
//cout << "mainfun" << endl;
|
|
list<TThread *> *threads = (list<TThread *> *)data;
|
|
//lockForTheList.lock();
|
|
ULONG s = threads->size();
|
|
//lockForTheList.unlock();
|
|
//cout <<"ci sono " << s << "thread in ballo..." << endl;
|
|
|
|
while (s != 0) {
|
|
lockForTheList.lock();
|
|
s = threads->size();
|
|
lockForTheList.unlock();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
void TThreadGroupImp::wait()
|
|
{
|
|
//cout << "wait()" << endl;
|
|
lockForTheList.lock();
|
|
ULONG count = threads.size();
|
|
|
|
for (list<TThread *>::iterator it = threads.begin(); it != threads.end(); it++) {
|
|
TThread *t = *it;
|
|
t->start();
|
|
}
|
|
lockForTheList.unlock();
|
|
|
|
if (count == 0)
|
|
return;
|
|
void *mainRet = 0;
|
|
pthread_t mainThread;
|
|
//cout << "creo il main" << endl;
|
|
pthread_create(&mainThread, 0, mainFun, &threads);
|
|
//cout << mainThread << endl;
|
|
pthread_join(mainThread, &mainRet);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
TThreadGroup::TThreadGroup()
|
|
: m_imp(new TThreadGroupImp())
|
|
|
|
{
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
TThreadGroup::~TThreadGroup()
|
|
{
|
|
delete m_imp;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TThreadGroup::add(TThread *t)
|
|
{
|
|
m_imp->add(t);
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TThreadGroup::wait()
|
|
{
|
|
m_imp->wait();
|
|
}
|