#include "stdafx.h"
#include "DJS_WorkerThread.h"
#include <errno.h>

#define JOBSERVER_IMPORT
#include "..\Common\IJobServer.h"

cDJS_WorkerThread::~cDJS_WorkerThread()
{
	if( m_szJobServerName )
		delete [] m_szJobServerName;
	if( m_szJob )
		delete [] m_szJob;
	if( m_szWorkPath )
		delete [] m_szWorkPath;
}


//----------------------------------------------------------------------
// Store the job & the relevant datas
//----------------------------------------------------------------------
bool	cDJS_WorkerThread::SetJob( const char* szJobServerName,const char* szJob,const char* szWorkPath,const int nCPUID )
{
	if( m_szJobServerName )
		delete [] m_szJobServerName;
	if( m_szJob )
		delete [] m_szJob;

	m_szJobServerName = new char[1024];
	m_szJob = new char[1024];
	m_szWorkPath = new char[1024];

	strcpy_s( m_szJobServerName, 1024, szJobServerName );
	strcpy_s( m_szJob, 1024, szJob );
	strcpy_s( m_szWorkPath, 1024, szWorkPath );
	m_nCPUID = nCPUID;

	//Don't enable more thread untill our one haven't got real info..
	m_nUsedMemoryMB = 2048;
	return true;
}

//////////////////////////////////////////////////////////////////////////
DWORD	cDJS_WorkerThread::Done()
{
	// Force closing of the Job server for this thread when aborted abnormally.
	if (m_pJobServer)
		m_pJobServer->Done();

	return cWorkerThread::Done();
}

//----------------------------------------------------------------------
// Start & run a new worker thread
//----------------------------------------------------------------------
UINT	cDJS_WorkerThread::ThreadStart()
{
	if( NULL == m_szJob || NULL == m_szJobServerName )
		return -1;

	//set the thread priority & affinity
	HANDLE Handle = GetCurrentThread();
  SetThreadAffinityMask(Handle, 1 << m_nCPUID );
	SetThreadPriority(Handle,THREAD_PRIORITY_BELOW_NORMAL);
	CloseHandle( Handle );

	HMODULE JobServerDLL = DJS_GetAndLoadLibrary( m_szJobServerName );

	if (!JobServerDLL)
	{
		printf("%s dll not found  <<\n\n",m_szJobServerName);
		SignalThreadClose();
		return -1;
	}

	IJobServer::TCreateFunction CreateJobServer = (IJobServer::TCreateFunction)DJS_GetProcAddress( JobServerDLL, "CreateJobServer" );

	if( !CreateJobServer )
	{
		printf("%s createjobserver not found  <<\n\n",m_szJobServerName);
		DJS_FreeLibrary( JobServerDLL );
		SignalThreadClose();
		return -1;
	}

	IJobServer::TDeleteFunction DeleteJobServer = (IJobServer::TDeleteFunction)DJS_GetProcAddress( JobServerDLL, "DeleteJobServer" );

	if( !DeleteJobServer )
	{
		printf("%s deletejobserver not found  <<\n\n",m_szJobServerName);
		DJS_FreeLibrary( JobServerDLL );
		SignalThreadClose();
		return -1;
	}

#ifdef WINDOWS_VERSION
	IJobServer *pJobServer = CreateJobServer( m_nCPUID, JSP_WINDOWS, IJOBSERVERVERSION );
#else
	IJobServer *pJobServer = CreateJobServer( m_nCPUID, JPS_LINUX, IJOBSERVERVERSION );
#endif

	if( NULL == pJobServer )
	{
		printf("%s jobserver not created <<\n\n",m_szJobServerName);
		DJS_FreeLibrary( JobServerDLL );
		SignalThreadClose();
		return -1;
	}

	m_pJobServer = pJobServer;

	JobServerResult JSResult;

//	JobServerResult = pJobServer->Init( szDirectory, m_FileID, 2,2,1,m_SSID, JOB_RENDERER );//18,18,9 );
	JSResult = pJobServer->Init( m_szJob,m_szWorkPath );
	if( JSResult != JSRESULT_OK  )
	{
		printf("%s jobserver %s job init failed <<\n\n",m_szJobServerName,m_szJob);
		pJobServer->Done();
		DeleteJobServer( pJobServer );
		m_pJobServer = 0;
		DJS_FreeLibrary( JobServerDLL );
		SignalThreadClose();
		return (JSResult == JSRESULT_DATA_ERROR) ? 0 : -1;
	}

	//check interruption
	if(WaitForMultipleObjects(1,&m_hEvent,FALSE,0)!=WAIT_TIMEOUT)
	{
		printf("interruption\n\n");
		pJobServer->Done();
		DeleteJobServer( pJobServer );
		m_pJobServer = 0;
		DJS_FreeLibrary( JobServerDLL );
		SignalThreadClose();
		return -1;
	}
	Sleep(1);

	//do the rendering
	printf("DLC   Job server %d started.\n", m_nCPUID );

	//get info about the used memory
	m_nUsedMemoryMB = pJobServer->GetUsedMemoryMB();

	while(true)
	{
		JSResult = pJobServer->Tick();
		if( JSRESULT_FINISHED == JSResult )
			break;

		SetPercent( pJobServer->GetPercent() );

		if( JSRESULT_OK != JSResult )
		{
			printf("%s jobserver %s job failed (%s).. <<\n\n",m_szJobServerName,m_szJob, JSResult == JSRESULT_INTERNAL_ERROR ? "Internal error" : "Data error" );
			pJobServer->Done();
			DeleteJobServer( pJobServer );
			m_pJobServer = 0;
			DJS_FreeLibrary( JobServerDLL );
			SignalThreadClose();
			return (JSResult == JSRESULT_DATA_ERROR) ? 0 : -1;
		}

		//check interruption
		if(WaitForMultipleObjects(1,&m_hEvent,FALSE,0)!=WAIT_TIMEOUT)
		{
			printf("interruption2<<\n\n");
			pJobServer->Done();
			DeleteJobServer( pJobServer );
			m_pJobServer = 0;
			DJS_FreeLibrary( JobServerDLL );
			SignalThreadClose();
			return -1;
		}
		Sleep(1);
	}

	//save the finished picture

	Sleep(1);
	//finish the execution of that thread
	printf("DLC   Job server %d closed.\n", m_nCPUID );
	pJobServer->Done();
	DeleteJobServer( pJobServer );
	m_pJobServer = 0;
	DJS_FreeLibrary( JobServerDLL );
	SignalThreadClose();
	return 0;
}
