Пример #1
0
/*
 * Thread beginning
 */
static void *ProxyFunc( void *arg )
{
	CPThread *parent = (CPThread*)arg;

	// Set this thread's thread specific storage to IThread instance pointer
	if(pthread_setspecific(threadSpecificKey, parent) != 0)
		throw EThread("cannot set thread ptr in thread specific storage.");

	// Allow to terminate the thread without cancellation point
	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);

	// Run the code of the thread
	parent->Runnable->run();

	{
		pthread_t thread_self = pthread_self();
		// Make sure the parent still cares
		// If this thread was replaced with a new thread (which should not happen),
		// and the IThread object has been deleted, this will likely crash.
		if (parent->_ThreadHandle == thread_self)
			parent->_State = CPThread::ThreadStateFinished;
		else
			throw EThread("Thread ended after being detached, this should not happen");
	}

	// Allow some clean
//	pthread_exit(0);
	return NULL;
}
Пример #2
0
	CPMainThread() : CPThread(NULL, 0)
	{
		if(pthread_key_create(&threadSpecificKey, NULL) != 0)
			throw EThread("cannot create thread specific storage key.");

		if(pthread_setspecific(threadSpecificKey, this) != 0)
			throw EThread("cannot set main thread ptr in thread specific storage.");
	}
Пример #3
0
void CWinThread::start ()
{
	if (isRunning())
		throw EThread("Starting a thread that is already started, existing thread will continue running, this should not happen");	
	
//	ThreadHandle = (void *) ::CreateThread (NULL, _StackSize, ProxyFunc, this, 0, (DWORD *)&ThreadId);
	ThreadHandle = (void *) ::CreateThread (NULL, 0, ProxyFunc, this, 0, (DWORD *)&ThreadId);
//	nldebug("NLMISC: thread %x started for runnable '%x'", typeid( Runnable ).name());
//	OutputDebugString(toString(NL_LOC_MSG " NLMISC: thread %x started for runnable '%s'\n", ThreadId, typeid( *Runnable ).name()).c_str());
	SetThreadPriorityBoost (ThreadHandle, TRUE); // FALSE == Enable Priority Boost
	if (ThreadHandle == NULL)
	{
		throw EThread ( "Cannot create new thread" );
	}

	_SuspendCount = 0;
}
Пример #4
0
/*
 * start
 */
void CPThread::start()
{
	pthread_attr_t tattr;
	int ret;

	if (_StackSize != 0)
	{
		/* initialized with default attributes */
		ret = pthread_attr_init(&tattr);

		/* setting the size of the stack also */
		ret = pthread_attr_setstacksize(&tattr, _StackSize);
	}

	bool detach_old_thread = false;
	pthread_t old_thread_handle;
	if (_State != ThreadStateNone)
	{
		if (_State == ThreadStateRunning)
		{
			// I don't know if this behaviour is allowed, but neither thread implementations
			// check the start function, and both simply let the existing running thread for what it is...
			// From now on, this is not allowed.
			throw EThread("Starting a thread that is already started, existing thread will continue running, this should not happen");
		}
		detach_old_thread = true;
		old_thread_handle = _ThreadHandle;
	}

	if (pthread_create(&_ThreadHandle, _StackSize != 0 ? &tattr : NULL, ProxyFunc, this) != 0)
	{
		throw EThread("Cannot start new thread");
	}
	_State = ThreadStateRunning;

	if (detach_old_thread)
	{
		// Docs don't say anything about what happens when pthread_create is called with existing handle referenced.
		if (old_thread_handle == _ThreadHandle)
			throw EThread("Thread handle did not change, this should not happen");
		// Don't care about old thread, free resources when it terminates.
		pthread_detach(old_thread_handle);
	}
}
/*
 * wait
 */
void CPThread::wait ()
{
	if(_State == 1)
	{
		if(pthread_join(_ThreadHandle, 0) != 0)
		{
			throw EThread( "Cannot join with thread" );
		}
		_State = 2;	// set to finished
	}
}
Пример #6
0
/*
 * wait
 */
void CPThread::wait ()
{
	if (_State == ThreadStateRunning)
	{
		int error = pthread_join(_ThreadHandle, 0);
		switch (error)
		{
		case 0:
			break;
		case EINVAL:
			throw EThread("Thread is not joinable");
		case ESRCH:
			throw EThread("No thread found with this id");
		case EDEADLK:
			throw EThread("Deadlock detected or calling thread waits for itself");
		default:
			throw EThread("Unknown thread join error");
		}
		if(_State != ThreadStateFinished)
			throw EThread("Thread did not finish, this should not happen");
	}
}
/*
 * start
 */
void CPThread::start()
{
	pthread_attr_t tattr;
	pthread_t tid;
	int ret;

	/* initialized with default attributes */
	ret = pthread_attr_init(&tattr);

	/* setting the size of the stack also */
	ret = pthread_attr_setstacksize(&tattr, _StackSize);

	if(pthread_create(&_ThreadHandle, _StackSize != 0 ? &tattr : 0, ProxyFunc, this) != 0)
	{
		throw EThread("Cannot start new thread");
	}
	_State = 1;
}
Пример #8
0
	~CPMainThread()
	{
		if(pthread_key_delete(threadSpecificKey) != 0)
			throw EThread("cannot delete thread specific storage key.");
	}