258 lines
7 KiB
C++
258 lines
7 KiB
C++
|
||
#include "stdafx.h"
|
||
#include "DNBackGroundLoader.h"
|
||
#include "ExceptionReport.h"
|
||
#if defined( PRE_WORLDUSERSTATE_OPTIMIZE )
|
||
#include "DNGameWorldUserState.hpp"
|
||
#endif // #if defined( PRE_WORLDUSERSTATE_OPTIMIZE )
|
||
#include "DNServiceConnection.h"
|
||
|
||
extern TGameConfig g_Config;
|
||
CDNBackGroundLoader * g_pBackLoader = NULL;
|
||
HANDLE CDNBackGroundLoader::m_hCallSignal = INVALID_HANDLE_VALUE;
|
||
|
||
CDNBackGroundLoader::CDNBackGroundLoader( bool bLog ) : Thread("BackLoader"), m_bLog(bLog)
|
||
{
|
||
m_hCallSignal = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||
m_inowLoading = 0;
|
||
m_pStandbyList = new _STANDBY_ROOM[MAX_SESSION_COUNT];
|
||
m_bRunning = true;
|
||
Start();
|
||
}
|
||
|
||
CDNBackGroundLoader::~CDNBackGroundLoader()
|
||
{
|
||
m_bRunning = false;
|
||
SetEvent( m_hCallSignal );
|
||
WaitForTerminate();
|
||
|
||
while (!m_CallList.empty())
|
||
{
|
||
m_CallList.pop();
|
||
}
|
||
CloseHandle(m_hCallSignal);
|
||
|
||
delete [] m_pStandbyList;
|
||
}
|
||
|
||
bool CDNBackGroundLoader::PushToLoadProcess(CDNGameRoom * pRoom, bool bContinue)
|
||
{
|
||
if (m_pStandbyList[pRoom->GetRoomID()].pRoom == NULL)
|
||
{
|
||
_ASSERT(m_pStandbyList[pRoom->GetRoomID()].pRoom == NULL);
|
||
|
||
m_CallSync.Lock();
|
||
m_CallList.push(pRoom->GetRoomID());
|
||
|
||
m_pStandbyList[pRoom->GetRoomID()].bIsLoaded = false;
|
||
m_pStandbyList[pRoom->GetRoomID()].bIsContinue = bContinue;
|
||
m_pStandbyList[pRoom->GetRoomID()].pRoom = pRoom;
|
||
#if defined( PRE_THREAD_ROOMDESTROY )
|
||
m_pStandbyList[pRoom->GetRoomID()].bIsDestroyProcess = false;
|
||
#endif // #if defined( PRE_THREAD_ROOMDESTROY )
|
||
SetEvent(m_hCallSignal);
|
||
m_CallSync.UnLock();
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
#if defined( PRE_THREAD_ROOMDESTROY )
|
||
bool CDNBackGroundLoader::PushToDestroyProcess( CDNGameRoom* pRoom )
|
||
{
|
||
if (m_pStandbyList[pRoom->GetRoomID()].pRoom == NULL)
|
||
{
|
||
m_CallSync.Lock();
|
||
m_CallList.push(pRoom->GetRoomID());
|
||
|
||
m_pStandbyList[pRoom->GetRoomID()].bIsDestroyProcess = true;
|
||
m_pStandbyList[pRoom->GetRoomID()].pRoom = pRoom;
|
||
SetEvent(m_hCallSignal);
|
||
m_CallSync.UnLock();
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
void CDNBackGroundLoader::DestroyConfirm( int idx )
|
||
{
|
||
_ASSERT(m_pStandbyList[idx].pRoom != NULL);
|
||
m_pStandbyList[idx].bIsLoaded = false;
|
||
m_pStandbyList[idx].bIsContinue = false;
|
||
m_pStandbyList[idx].bIsInitFail = false;
|
||
m_pStandbyList[idx].pRoom = NULL;
|
||
m_pStandbyList[idx].bIsDestroyProcess = false;
|
||
#ifdef _DEBUG
|
||
if( m_bLog )
|
||
g_Log.Log( LogType::_NORMAL, L"CDNBackGroundLoader Destroy Confirm RoomID : %d\n", idx );
|
||
#endif
|
||
}
|
||
|
||
#endif // #if defined( PRE_THREAD_ROOMDESTROY )
|
||
|
||
bool CDNBackGroundLoader::IsLoaded(int idx)
|
||
{
|
||
_ASSERT(m_pStandbyList[idx].pRoom != NULL);
|
||
if (m_pStandbyList[idx].bIsLoaded == true)
|
||
return true;
|
||
return false;
|
||
}
|
||
|
||
bool CDNBackGroundLoader::LoadConfirm(int idx)
|
||
{
|
||
_ASSERT(m_pStandbyList[idx].pRoom != NULL);
|
||
bool bInitFail = m_pStandbyList[idx].bIsInitFail;
|
||
m_pStandbyList[idx].bIsLoaded = false;
|
||
m_pStandbyList[idx].bIsContinue = false;
|
||
m_pStandbyList[idx].bIsInitFail = false;
|
||
m_pStandbyList[idx].pRoom = NULL;
|
||
#if defined( PRE_THREAD_ROOMDESTROY )
|
||
m_pStandbyList[idx].bIsDestroyProcess = false;
|
||
#endif // #if defined( PRE_THREAD_ROOMDESTROY )
|
||
#ifdef _DEBUG
|
||
if( m_bLog )
|
||
g_Log.Log( LogType::_NORMAL, L"CDNBackGroundLoader Load Confirm RoomID : %d\n", idx );
|
||
#endif
|
||
return bInitFail;
|
||
}
|
||
|
||
bool CDNBackGroundLoader::LoadCancel(int idx)
|
||
{
|
||
if (m_inowLoading == idx)
|
||
return false;
|
||
|
||
if (m_pStandbyList[idx].pRoom == NULL)
|
||
return true;
|
||
|
||
m_pStandbyList[idx].bIsLoaded = false;
|
||
m_pStandbyList[idx].bIsContinue = false;
|
||
m_pStandbyList[idx].pRoom = NULL;
|
||
#if defined( PRE_THREAD_ROOMDESTROY )
|
||
m_pStandbyList[idx].bIsDestroyProcess = false;
|
||
#endif // #if defined( PRE_THREAD_ROOMDESTROY )
|
||
#ifdef _DEBUG
|
||
if( m_bLog )
|
||
g_Log.Log( LogType::_NORMAL, L"CDNBackGroundLoader Cancel Load RoomID : %d\n", idx );
|
||
#endif
|
||
return true;
|
||
}
|
||
|
||
bool CDNBackGroundLoader::IsLoading( int idx )
|
||
{
|
||
if (m_inowLoading == idx)
|
||
return true;
|
||
|
||
return false;
|
||
}
|
||
|
||
void CDNBackGroundLoader::Run()
|
||
{
|
||
// 2009.01.20 <20><><EFBFBD><EFBFBD>
|
||
// <20><><EFBFBD>ѷ<EFBFBD><D1B7><EFBFBD><EFBFBD><EFBFBD> <20>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>찡 <20>־<EFBFBD> m_bRunning <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> üũ
|
||
while (m_bRunning)
|
||
{
|
||
if (!m_CallList.empty())
|
||
{
|
||
#if defined( PRE_WORLDUSERSTATE_OPTIMIZE )
|
||
if( g_pWorldUserState )
|
||
g_pWorldUserState->SnapShotUserState();
|
||
#endif // #if defined( PRE_WORLDUSERSTATE_OPTIMIZE )
|
||
m_CallSync.Lock();
|
||
int nCallID = m_CallList.front();
|
||
m_CallList.pop();
|
||
m_CallSync.UnLock();
|
||
|
||
m_inowLoading = nCallID;
|
||
#if defined( PRE_THREAD_ROOMDESTROY )
|
||
if( m_pStandbyList[nCallID].pRoom && m_pStandbyList[nCallID].bIsDestroyProcess == true )
|
||
{
|
||
InterlockedCompareExchange( &m_pStandbyList[nCallID].pRoom->m_lRoomDestroyInterLocked, CDNGameRoom::eRoomDestoryStep::Destroyed, CDNGameRoom::eRoomDestoryStep::PushQueue );
|
||
m_inowLoading = -1;
|
||
continue;
|
||
}
|
||
#endif // #if defined( PRE_THREAD_ROOMDESTROY )
|
||
|
||
// try catch <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Scope <20>Լ<EFBFBD><D4BC><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>..<2E><>~
|
||
//CScopeNowLoading Scope( &m_inowLoading, nCallID );
|
||
|
||
if (m_pStandbyList[nCallID].pRoom == NULL || m_pStandbyList[nCallID].bIsLoaded != false)
|
||
{
|
||
m_inowLoading = -1;
|
||
continue;
|
||
}
|
||
|
||
static bool bProcessLog = true;
|
||
if( m_pStandbyList[nCallID].pRoom->m_lRoomProcessInterLocked > 0 )
|
||
{
|
||
m_CallSync.Lock();
|
||
m_CallList.push( nCallID );
|
||
if( bProcessLog )
|
||
{
|
||
g_Log.Log( LogType::_NORMAL, L"[%d] CDNBackGroundLoader Process <20><><EFBFBD>̾ <20>ٽ<EFBFBD> Push<73><68> RoomID : %d\n", g_Config.nManagedID, nCallID );
|
||
bProcessLog = false;
|
||
}
|
||
m_CallSync.UnLock();
|
||
m_inowLoading = -1;
|
||
continue;
|
||
}
|
||
|
||
bProcessLog = true;
|
||
|
||
#if defined(_WORK)
|
||
if( m_bLog )
|
||
g_Log.Log( LogType::_NORMAL, L"CDNBackGroundLoader Start Load RoomID : %d\n", nCallID );
|
||
#endif // #if defined(_WORK)
|
||
|
||
if (m_pStandbyList[nCallID].pRoom != NULL)
|
||
{
|
||
#ifdef _FINAL_BUILD
|
||
__try
|
||
{
|
||
#endif
|
||
m_pStandbyList[nCallID].bIsInitFail = m_pStandbyList[nCallID].pRoom->LoadData( m_pStandbyList[nCallID].bIsContinue );
|
||
#ifdef _FINAL_BUILD
|
||
}
|
||
|
||
__except(CExceptionReport::GetInstancePtr()->Proc(GetExceptionInformation(), MiniDumpNormal))
|
||
{
|
||
if( m_pStandbyList[nCallID].pRoom )
|
||
m_pStandbyList[nCallID].pRoom->SetRoomCrashFlag( true );
|
||
|
||
g_Log.Log( LogType::_ROOMCRASH, L"[%d] DNBackGroundLoader Room Crash! RoomID=%d\n", g_Config.nManagedID, m_pStandbyList[nCallID].pRoom->GetRoomID() );
|
||
LoadCancel(nCallID);
|
||
//g_Log.Log(L"Destroy|BackLoader Crash\n");
|
||
|
||
#if !defined (_TH)
|
||
if (g_pServiceConnection)
|
||
g_pServiceConnection->SendDetectException(_EXCEPTIONTYPE_ROOMCRASH);
|
||
#endif // #if !defined (_TH)
|
||
}
|
||
#endif
|
||
}
|
||
else
|
||
LoadCancel(nCallID);
|
||
|
||
m_pStandbyList[nCallID].bIsLoaded = true;
|
||
|
||
#if defined(_WORK)
|
||
if( m_bLog )
|
||
g_Log.Log( LogType::_NORMAL, L"CDNBackGroundLoader Finish Load RoomID : %d\n", nCallID );
|
||
#endif // #if defined(_WORK)
|
||
m_inowLoading = -1;
|
||
}
|
||
else
|
||
{
|
||
#if defined( PRE_WORLDUSERSTATE_OPTIMIZE )
|
||
if( g_pWorldUserState )
|
||
g_pWorldUserState->SnapShotUserState();
|
||
#endif // #if defined( PRE_WORLDUSERSTATE_OPTIMIZE )
|
||
|
||
ResetEvent(m_hCallSignal);
|
||
#if defined( PRE_WORLDUSERSTATE_OPTIMIZE )
|
||
::WaitForSingleObject(m_hCallSignal, 1000 );
|
||
#else
|
||
::WaitForSingleObject(m_hCallSignal, INFINITE);
|
||
#endif // #if defined( PRE_WORLDUSERSTATE_OPTIMIZE )
|
||
}
|
||
}
|
||
}
|