Esempio n. 1
0
void AbstractThread::run()
{
	// is the very first since there is a possibility of something being altered there
	onStart();

	int exceptions = 0;
	bool lastWasException = false;
	m_terminateRequested = false;

	for (;;)
	{
		bool gotException = false;

		//	report me being alive if I am being checked for status
		if( m_hangCheck != 0 )
		{
			m_hangCheck = 0;
		}

		try
		{
			tick();

			// ensure this is recorded as 'idle' time (ideally this should
			// be in tick() but we cannot guarantee it to be called there
			CurrentProfileData.Start(PROFILE_IDLE);
		}
		catch( const CException& e )
		{
			gotException = true;
			g_Log.CatchEvent(&e, "%s::tick", getName());
			CurrentProfileData.Count(PROFILE_STAT_FAULTS, 1);
		}
		catch( ... )
		{
			gotException = true;
			g_Log.CatchEvent(NULL, "%s::tick", getName());
			CurrentProfileData.Count(PROFILE_STAT_FAULTS, 1);
		}

		if( gotException )
		{
			if( lastWasException )
			{
				exceptions++;
			}
			else
			{
				lastWasException = true;
				exceptions = 0;
			}
			if( exceptions >= EXCEPTIONS_ALLOWED )
			{
				// a bad thing really happened. ALL previous EXCEPTIONS_ALLOWED ticks resulted in exception
				// almost for sure we have looped somewhere and have no way to get out from this situation
				// probably a thread restart can fix the problems
				// but there is no real need to restart a thread, we will just simulate a thread restart,
				// notifying a subclass like we have been just restarted, so it will restart it's operations
				g_Log.Event(LOGL_CRIT, "'%s' thread raised too many exceptions, restarting...\n", getName());
				onStart();
				lastWasException = false;
			}
		}
		else
		{
			lastWasException = false;
		}

		if( shouldExit() )
			break;

		m_sleepEvent.wait(m_tickPeriod);
	}
}