#include "StdAfx.h"
#include "IPv4Listener.h"
#include "ServerException.h"

#define	CLASS_NAME	_U8("NormalListener")


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

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



/*!
	開始
*/
void CIPv4Listener::Start(IServerToolPtr serverTool, IClientConnectionQueuePtr 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, _U16("待ち受けポートがひとつも指定されていません"));

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

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

	StopListenerBase();
}

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

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

/*!
	接続追加
*/
void CIPv4Listener::OnNewConnection(SOCKET newSock)
{
	try
	{
		m_queue->AddNewConnection(new CIPv4ClientConnection(newSock, m_timeoutTime));
	}
	catch(CBadAllocException &e)
	{
		//	使わないので...
		UNREFERENCED_PARAMETER(e);

		//	ログへ
		m_serverTool.WriteSystemLog(GetListenerClassName(), SYSTEM_LOG_ERROR, _U16("メモリ不足が発生しました、一時的に接続を拒否します"));

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