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