Blob Blame Raw


#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();
}