#include <iostream>
#include "ProcessStatus.h"

#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>


#define MX_LOCK_SEND_CNT()\
do \
{\
	pthread_mutex_lock(&m_mx_nSendCount);\
} while( 0 );

#define MX_UNLOCK_SEND_CNT()\
do \
{\
	pthread_mutex_unlock(&m_mx_nSendCount);\
	UpdateTitle();\
} while( 0 );

#define MX_LOCK_RECV_CNT()\
do \
{\
	pthread_mutex_lock(&m_mx_nReceiveCount);\
} while( 0 );

#define MX_UNLOCK_RECV_CNT()\
do \
{\
	pthread_mutex_unlock(&m_mx_nReceiveCount);\
	UpdateTitle();\
} while( 0 );

#define MX_LOCK_TRAN_RATE()\
do \
{\
	pthread_mutex_lock(&m_mx_nTransferRate);\
} while( 0 );

#define MX_UNLOCK_TRAN_RATE()\
do \
{\
	pthread_mutex_unlock(&m_mx_nTransferRate);\
} while( 0 );


// Constructor
CProcessStatus::CProcessStatus()
	: m_nSendCount(0)
	, m_nReceiveCount(0)
	, m_nTransferRate(100)
{ 
	// Initialize Mutext variable 
	//m_mx_nSendCount    = PTHREAD_MUTEX_INITIALIZER;
	//m_mx_nReceiveCount = PTHREAD_MUTEX_INITIALIZER;
	//m_mx_nTransferRate = PTHREAD_MUTEX_INITIALIZER;

	pthread_mutex_init( &m_mx_nSendCount,    NULL );
	pthread_mutex_init( &m_mx_nReceiveCount, NULL );
	pthread_mutex_init( &m_mx_nTransferRate, NULL );


	
	return;
}

CProcessStatus::~CProcessStatus()
{ 
	// Destory Mutext variable 
	pthread_mutex_destroy(&m_mx_nSendCount);
	pthread_mutex_destroy(&m_mx_nReceiveCount);
	pthread_mutex_destroy(&m_mx_nTransferRate);

	return;
}


void CProcessStatus::UpdateTitle()
{

#if defined(__FreeBSD__)
	setproctitle("Worker [S:%3d R:%3d N:%3d]", m_nSendCount, m_nReceiveCount, m_nTransferRate );
#endif

	return ;
}

int CProcessStatus::GetSendCount(void)
{
	int nValue = 0;
	
	MX_LOCK_SEND_CNT();
	nValue = m_nSendCount;
	MX_UNLOCK_SEND_CNT();

	return nValue;
}

bool CProcessStatus::SetSendCount(const int nSendCount)
{
	// 입력값이 0 보다 작은 경우 false 반환.
	if( nSendCount < 0 )
	{
		return false;
	}

	MX_LOCK_SEND_CNT();
	m_nSendCount = nSendCount;
	MX_UNLOCK_SEND_CNT();

	return true;
}

bool CProcessStatus::AddSendCount()
{
	MX_LOCK_SEND_CNT();
	++m_nSendCount;
	MX_UNLOCK_SEND_CNT();
	
	return true;
}

bool CProcessStatus::SubtractSendCount()
{
	MX_LOCK_SEND_CNT();
	
	--m_nSendCount;
	if( m_nSendCount < 0 )
		m_nSendCount = 0;
	
	MX_UNLOCK_SEND_CNT();
	
	return true;
}


int CProcessStatus::GetReceiveCount(void)
{
	int nValue = 0;

	MX_LOCK_RECV_CNT();
	nValue = m_nReceiveCount;
	MX_UNLOCK_RECV_CNT();

	return nValue;
}

bool CProcessStatus::SetReceiveCount(const int nReceiveCount)
{
	if( nReceiveCount < 0 )
	{
		return false;
	}

	MX_LOCK_RECV_CNT();
	m_nReceiveCount = nReceiveCount;
	MX_UNLOCK_RECV_CNT();
	
	return true;
}

bool CProcessStatus::AddReceiveCount()
{
	MX_LOCK_RECV_CNT();
	++m_nReceiveCount;
	MX_UNLOCK_RECV_CNT();

	return true;
}

bool CProcessStatus::SubtractReceiveCount()
{
	MX_LOCK_RECV_CNT();
	
	--m_nReceiveCount;
	if( m_nReceiveCount < 0 )
		m_nReceiveCount = 0;

	MX_UNLOCK_RECV_CNT();
	
	return true;
}

int CProcessStatus::GetTransferRate()
{
	int nValue = 0;
	
	MX_LOCK_TRAN_RATE();
	nValue = m_nTransferRate;
	MX_UNLOCK_TRAN_RATE();

	return nValue;
}

bool CProcessStatus::SetTransferRate(const int nTransferRate)
{
	if ( nTransferRate < 0 || nTransferRate > 100 )
	{
		return false;
	}
	
	MX_LOCK_TRAN_RATE();
	m_nTransferRate = nTransferRate;
	MX_UNLOCK_TRAN_RATE();
	
	return true;
}

