#include "ProcessStatus.h"

#include "Logger.h"
#include "ProcessRename.h"

#include <errno.h>
#include <stdio.h>
#include <string.h>


// Process 정보 update 주기  (sec)
#define PROCESS_STATUS_UPDATE_TIME  2


// 생성자
CProcessStatus::CProcessStatus()
{
	m_threadHandle = 0;

	m_nCurrentClientCount = 0;
		
	// Lock 초기화
	pthread_mutex_init( &m_mxClientThread, NULL );	
}

// 소멸자
CProcessStatus::~CProcessStatus()
{
	// Thread 동작 정지 처리
	// - 만약 Thread 가 이미 종료된 경우 m_threadHandle 이 다른 Thread Handle 일 수 있으므로 
	//   업무 Flow 수정시 주의할 것
	if( m_threadHandle != 0 )
		pthread_cancel( m_threadHandle );

	pthread_mutex_destroy( &m_mxClientThread );	
}

// thread를 생성하여 관련 작업을 수행.
bool CProcessStatus::Start()
{
	int nRet = ::pthread_create( &m_threadHandle, NULL, CProcessStatus::threadFunc, this );
	if( nRet != 0 )
	{
		// Thread 생성 실패시
		int errorNum = errno;
		LOG( LERR, "Thread create failed.[%d][%s]", errorNum, strerror( errorNum ) );

		return false;
	}

	return true;
}

void* CProcessStatus::threadFunc( void* arg )
{
	CProcessStatus* pObject = reinterpret_cast<CProcessStatus *>( arg );
	pthread_detach( pthread_self() );

	while( 1 )
	{		
		pObject->Execute();
				
		sleep( PROCESS_STATUS_UPDATE_TIME );
	}
		
	// Thread 종료시 m_threadHandle 값을 초기화 처리.
	// - 소멸자에서 잘못된 Thread 를 종료할 수 있기 때문.
	pObject->m_threadHandle = 0;

	return NULL;
}


// 현재 프로세스 표시 정보 업데이트 
void CProcessStatus::Execute( void )
{
	// C: client count
	// M: master job count
	// S: slave job count
	// Y: sync job count
		
#if defined(__FreeBSD__)
	setproctitle("[C%d]",
		    m_nCurrentClientCount 
			);

#else
	char szTemp[100] = {0};	
	sprintf(szTemp,	 "%s: Worker [C%d]"
			 , PROG_NAME
			 , m_nCurrentClientCount			 
			);
	
	set_ps_display(szTemp, false);

#endif

	return ;
}


// Client 수를 1 증가 처리
void CProcessStatus::PlusClientCount()
{
	pthread_mutex_lock( &m_mxClientThread );
	++m_nCurrentClientCount;
	pthread_mutex_unlock( &m_mxClientThread );
}

// Client 수를 1 감소 처리
// - 정확히 동작하는지 확인을 위해 일부로 (-) 값 보정 처리 안함.
void CProcessStatus::MinusClientCount()
{
	pthread_mutex_lock( &m_mxClientThread );
	--m_nCurrentClientCount;
	pthread_mutex_unlock( &m_mxClientThread );
}

