Esempio n. 1
0
static deTimerThread* deTimerThread_create (deTimerCallback callback, void* arg, int interval, TimerState state)
{
	deTimerThread* thread = (deTimerThread*)deCalloc(sizeof(deTimerThread));

	DE_ASSERT(state == TIMERSTATE_INTERVAL || state == TIMERSTATE_SINGLE);

	if (!thread)
		return DE_NULL;

	thread->callback	= callback;
	thread->callbackArg	= arg;
	thread->interval	= interval;
	thread->lock		= deMutex_create(DE_NULL);
	thread->state		= state;

	thread->thread		= deThread_create(timerThread, thread, DE_NULL);
	if (!thread->thread)
	{
		deMutex_destroy(thread->lock);
		deFree(thread);
		return DE_NULL;
	}

	return thread;
}
Esempio n. 2
0
void deTimer_disable (deTimer* timer)
{
	if (!timer->curThread)
		return;

	deMutex_lock(timer->curThread->lock);

	if (timer->curThread->state != TIMERSTATE_DISABLED)
	{
		/* Just set state to disabled and destroy thread handle. */
		/* \note Assumes that deThread_destroy() can be called while thread is still running
		 *       and it will not terminate the thread.
		 */
		timer->curThread->state = TIMERSTATE_DISABLED;
		deThread_destroy(timer->curThread->thread);
		timer->curThread->thread = 0;
		deMutex_unlock(timer->curThread->lock);

		/* Thread will destroy timer->curThread. */
	}
	else
	{
		/* Single timer has expired - we must destroy whole thread structure. */
		deMutex_unlock(timer->curThread->lock);
		deThread_destroy(timer->curThread->thread);
		deMutex_destroy(timer->curThread->lock);
		deFree(timer->curThread);
	}

	timer->curThread = DE_NULL;
}
Esempio n. 3
0
/*--------------------------------------------------------------------*//*!
 * \brief Destroy a logger instance
 * \param a	qpTestLog instance
 *//*--------------------------------------------------------------------*/
void qpTestLog_destroy (qpTestLog* log)
{
	DE_ASSERT(log);

	if (log->isSessionOpen)
		endSession(log);

	if (log->writer)
		qpXmlWriter_destroy(log->writer);

	if (log->outputFile)
		fclose(log->outputFile);

	if (log->lock)
		deMutex_destroy(log->lock);

	deFree(log);
}
Esempio n. 4
0
static void timerThread (void* arg)
{
	deTimerThread*	thread			= (deTimerThread*)arg;
	int				numCallbacks	= 0;
	deBool			destroy			= DE_TRUE;
	deInt64			lastCallback	= (deInt64)deGetMicroseconds();

	for (;;)
	{
		int sleepTime = 0;

		deMutex_lock(thread->lock);

		if (thread->state == TIMERSTATE_SINGLE && numCallbacks > 0)
		{
			destroy = DE_FALSE; /* Will be destroyed by deTimer_disable(). */
			thread->state = TIMERSTATE_DISABLED;
			break;
		}
		else if (thread->state == TIMERSTATE_DISABLED)
			break;

		deMutex_unlock(thread->lock);

		sleepTime = thread->interval - (int)(((deInt64)deGetMicroseconds()-lastCallback)/1000);
		if (sleepTime > 0)
			deSleep(sleepTime);

		lastCallback = (deInt64)deGetMicroseconds();
		thread->callback(thread->callbackArg);
		numCallbacks += 1;
	}

	/* State lock is held when loop is exited. */
	deMutex_unlock(thread->lock);

	if (destroy)
	{
		/* Destroy thread except thread->thread. */
		deMutex_destroy(thread->lock);
		deFree(thread);
	}
}
Esempio n. 5
0
void deMutex_selfTest (void)
{
	/* Default mutex from single thread. */
	{
		deMutex mutex = deMutex_create(DE_NULL);
		deBool	ret;
		DE_TEST_ASSERT(mutex);

		deMutex_lock(mutex);
		deMutex_unlock(mutex);

		/* Should succeed. */
		ret = deMutex_tryLock(mutex);
		DE_TEST_ASSERT(ret);
		deMutex_unlock(mutex);

		deMutex_destroy(mutex);
	}

	/* Recursive mutex. */
	{
		deMutexAttributes	attrs;
		deMutex				mutex;
		int					ndx;
		int					numLocks	= 10;

		deMemset(&attrs, 0, sizeof(attrs));

		attrs.flags = DE_MUTEX_RECURSIVE;

		mutex = deMutex_create(&attrs);
		DE_TEST_ASSERT(mutex);

		for (ndx = 0; ndx < numLocks; ndx++)
			deMutex_lock(mutex);

		for (ndx = 0; ndx < numLocks; ndx++)
			deMutex_unlock(mutex);

		deMutex_destroy(mutex);
	}

	/* Mutex and threads. */
	{
		deMutex		mutex;
		deThread	thread;

		mutex = deMutex_create(DE_NULL);
		DE_TEST_ASSERT(mutex);

		deMutex_lock(mutex);

		thread = deThread_create(mutexTestThr1, &mutex, DE_NULL);
		DE_TEST_ASSERT(thread);

		deSleep(100);
		deMutex_unlock(mutex);

		deMutex_lock(mutex);
		deMutex_unlock(mutex);

		deThread_join(thread);

		deThread_destroy(thread);
		deMutex_destroy(mutex);
	}

	/* A bit more complex mutex test. */
	{
		MutexData2	data;
		deThread	threads[2];
		int			ndx;

		data.mutex	= deMutex_create(DE_NULL);
		DE_TEST_ASSERT(data.mutex);

		data.counter	= 0;
		data.counter2	= 0;
		data.maxVal		= 1000;

		deMutex_lock(data.mutex);

		for (ndx = 0; ndx < (int)DE_LENGTH_OF_ARRAY(threads); ndx++)
		{
			threads[ndx] = deThread_create(mutexTestThr2, &data, DE_NULL);
			DE_TEST_ASSERT(threads[ndx]);
		}

		deMutex_unlock(data.mutex);

		for (ndx = 0; ndx < (int)DE_LENGTH_OF_ARRAY(threads); ndx++)
		{
			deBool ret = deThread_join(threads[ndx]);
			DE_TEST_ASSERT(ret);
			deThread_destroy(threads[ndx]);
		}

		DE_TEST_ASSERT(data.counter == data.counter2);
		DE_TEST_ASSERT(data.maxVal == data.counter);

		deMutex_destroy(data.mutex);
	}

	/* tryLock() deadlock test. */
	{
		deThread	thread;
		deMutex		mutex	= deMutex_create(DE_NULL);
		deBool		ret;
		DE_TEST_ASSERT(mutex);

		deMutex_lock(mutex);

		thread = deThread_create(mutexTestThr3, &mutex, DE_NULL);
		DE_TEST_ASSERT(mutex);

		ret = deThread_join(thread);
		DE_TEST_ASSERT(ret);

		deMutex_unlock(mutex);
		deMutex_destroy(mutex);
		deThread_destroy(thread);
	}
}