Exemple #1
0
void XEWinSocketSvr::ProcessLoginedList()
{
	XVector<XSPWinConnInServer> aryDestroy;
	auto llMilli1 = GET_FREQ_TIME();
	XPROF_OBJ( "listLogined" );
	auto plistLogined = &m_Logined.m_shoList.GetSharedObj();
	// 동접이 많으면 이 많은 커넥션들 다 패킷펌핑하기전까진 워커스레드 접속스레드 멈춰야 되는데... 이래선 싱글스레드와 다를바 없지 않은가.
	// 로그인된 커넥션들 프로세스
	XINT64 llProcessTotal = 0;
	XINT64 lllock = 0;
//	for( auto spConnect : *plistLogined ) {
	
	XINT64 llStart = XE::GetFreqTime();;
	for( auto itor = (*plistLogined).begin(); itor != (*plistLogined).end(); ) {
		auto spConnect = (*itor);
		auto pConnect = spConnect.get();
		XINT64 lllock1 = XE::GetFreqTime();;
		if( lllock1 - llStart > 100000 )		// 처리속도가 너무 올래걸릴거 같으면 일단 그냥 루프 빠져나감.
			break;
		pConnect->GetspLock()->Lock( __TFUNC__ );
		lllock += GET_FREQ_TIME() - lllock1;
		const int cntUse = spConnect.use_count();
		if( XASSERT( pConnect ) ) {
			if( pConnect->IsDisconnected() ) {
				OnDisconnectConnection( spConnect );
				pConnect->OnDisconnect();
			}
			if( !pConnect->GetbDestroy() ) {
				auto llProcess = GET_FREQ_TIME();
				pConnect->Process();
				llProcessTotal += (GET_FREQ_TIME() - llProcess);
				//
				if( pConnect->IsDisconnected() ) {	// 연결은 끊어졌어도 클라측에서 중요한 패킷을 보냈을수도 있으므로 패킷펌핑은 다 끝내고 삭제하도록 바뀜.
					pConnect->SetbDestroy( true );
				}
				// 커넥션이 비동기 파괴명령을 처리
				pConnect->ProcesssAsyncDisconnect();
			}
			if( pConnect->GetbDestroy() ) {
				++m_numDestroyAdd;
				aryDestroy.Add( spConnect );
				plistLogined->erase( itor++ );
			} else
				++itor;
		}
		pConnect->GetspLock()->Unlock();
	}

	auto llPass = GET_FREQ_TIME() - llMilli1;
	m_aryTime.Add( xProfile(_T("process list"), llPass ) );
	m_aryTime.Add( xProfile(_T("process"), llProcessTotal ) );
	m_aryTime.Add( xProfile( _T( "lock" ), lllock ) );
	m_aryTime.Add( xProfile( _T( "num process" ), plistLogined->size() ) );
	// Logined 프로세스 & destroy
	//////////////////////////////////////////////////////////////////////////
	auto pListConnected = &m_Connected.m_shoList.GetSharedObj();
	m_numConnected = pListConnected->size();		// 멀티스레드이므로 여기에 값이 있을 수 있음.
	if( m_numConnected > m_maxConnected )
		m_maxConnected = m_numConnected;
	m_Connected.m_shoList.ReleaseSharedObj();
	m_numLogined = plistLogined->size();
	if( m_numLogined > m_maxLogined )
		m_maxLogined = m_numLogined;
	// 순간적으로 numConnect수보다 커넥션객체의 생성수가 훨씬 많을때가 있다. 
	// leak으로 보이지만 봇 클라이언트를 종료시키는 순간 모두 사라지는걸로 보아 순간적으로 접속이 몰릴때 메인스레드 프로세스에서
	// 다 처리를 못해서 그런듯 하다.
	// unlock
	m_Logined.m_shoList.ReleaseSharedObj();
	// 삭제예정된 커넥션들 참조해제
	ProcessDestroyList( aryDestroy );
	aryDestroy.clear();
} // process & destroy