#include "StdAfx.h"
#include "NormalListener.h"
#include "ServerStartErrorException.h"
#include "TextTools.h"

#define	CLASS_NAME	"NormalListener"


CNormalListener::CNormalListener(void)
{
	m_init = 0;
}

CNormalListener::~CNormalListener(void)
{
	Stop();
}



/*!
	開始
*/
void CNormalListener::Start(IServerToolIIPtr serverTool, IClientConnectionQueueIIPtr queue)
{
	//	初期化済み？
	if(m_init)
		return;
	m_init = TRUE;

	//	コピー
	m_serverTool = serverTool;
	m_queue = queue;
	m_setting = m_serverTool->GetManagerSetting(m_setting.GetSettingName());

	//	設定取得
	m_timeoutTime = m_setting.GetConnectionTimeoutTime();

	//	リスナ初期化
	InitListenerBase(m_serverTool->GetIServerTool(), m_setting.GetListenErrorRetryTime());

	//	ポート追加
	AddPortsFromSetting(m_setting.GetPort());

	//	ポート数確認
	if(GetPortCount() == 0)
		throw CServerStartErrorException(CLASS_NAME, "待ち受けポートがひとつも指定されていません");

	//	スレッド起動
	StartListenerBase();
}

/*!
	停止
*/
void CNormalListener::Stop()
{
	//	初期化チェック
	if(!m_init)
		return;
	m_init = FALSE;

	StopListenerBase();
}

/*!
	停止準備
*/
void CNormalListener::ShutdownListen()
{
	Stop();	//	このクラスでは同じ
}

/////////////////////////////////////////////////////////////////////////////////////
//	オーバーロード
/////////////////////////////////////////////////////////////////////////////////////
/*!
	クラス名取得
*/
LPCTSTR CNormalListener::GetListenerClassName()
{
	return CLASS_NAME;
}

/*!
	接続追加
*/
void CNormalListener::OnNewConnection(SOCKET newSock)
{
	try
	{
		m_queue->AddNewConnection(IClientConnectionRet(new CNormalListenerConnection(newSock, m_timeoutTime), TRUE));
	}
	catch(CMemoryException *e)
	{
		e->Delete();

		m_serverTool->WriteSystemLog(GetListenerClassName(), SERVER_STATUS_ERROR, "メモリ不足が発生しました、一時的に接続を拒否します");

		//	メモリ不足のため、サーバ一時停止
		ForceDisableNewConnection(30 * 1000);
	}
}
