Consolidate file loading threading to CGameThreadPool

This commit is contained in:
savis
2026-01-05 17:42:13 +01:00
parent f19dfa1fe2
commit 4e68003fdd
6 changed files with 50 additions and 581 deletions

View File

@@ -3,171 +3,86 @@
#include "PackLib/PackManager.h"
#include "FileLoaderThread.h"
#include "ResourceManager.h"
#include "GameThreadPool.h"
CFileLoaderThread::CFileLoaderThread() : m_bShutdowned(false), m_pArg(NULL), m_hThread(NULL), m_uThreadID(0)
CFileLoaderThread::CFileLoaderThread() : m_bShutdowned(false)
{
}
CFileLoaderThread::~CFileLoaderThread()
{
Destroy();
Shutdown();
}
int CFileLoaderThread::Create(void * arg)
bool CFileLoaderThread::Create(void * arg)
{
Arg(arg);
m_hThread = (HANDLE) _beginthreadex(NULL, 0, EntryPoint, this, 0, &m_uThreadID);
if (!m_hThread)
return false;
SetThreadPriority(m_hThread, THREAD_PRIORITY_NORMAL);
// Modern implementation doesn't need explicit thread creation
// The global CGameThreadPool handles threading
m_bShutdowned = false;
return true;
}
UINT CFileLoaderThread::Run(void * arg)
{
if (!Setup())
return 0;
return (Execute(arg));
}
/* Static */
UINT CALLBACK CFileLoaderThread::EntryPoint(void * pThis)
{
CFileLoaderThread * pThread = (CFileLoaderThread *) pThis;
return pThread->Run(pThread->Arg());
}
//////////////////////////////////////////////////////////////////////////
void CFileLoaderThread::Destroy()
{
if (m_hSemaphore)
{
CloseHandle(m_hSemaphore);
m_hSemaphore = NULL;
}
stl_wipe(m_pRequestDeque);
stl_wipe(m_pCompleteDeque);
}
UINT CFileLoaderThread::Setup()
{
m_hSemaphore = CreateSemaphore(NULL, // no security attributes
0, // initial count
65535, // maximum count
NULL); // unnamed semaphore
if (!m_hSemaphore)
return 0;
return 1;
}
void CFileLoaderThread::Shutdown()
{
if (!m_hSemaphore)
return;
BOOL bRet;
m_bShutdowned = true;
do
// Clear any pending completed items
{
bRet = ReleaseSemaphore(m_hSemaphore, 1, NULL);
std::lock_guard<std::mutex> lock(m_CompleteMutex);
stl_wipe(m_pCompleteDeque);
}
while (!bRet);
WaitForSingleObject(m_hThread, 10000); // 쓰레드가 종료 되기를 10초 기다림
}
UINT CFileLoaderThread::Execute(void * /*pvArg*/)
void CFileLoaderThread::Request(const std::string& c_rstFileName)
{
while (!m_bShutdowned)
if (m_bShutdowned)
return;
// Enqueue file loading to the global thread pool
CGameThreadPool* pThreadPool = CGameThreadPool::InstancePtr();
if (pThreadPool)
{
DWORD dwWaitResult;
dwWaitResult = WaitForSingleObject(m_hSemaphore, INFINITE);
if (m_bShutdowned)
break;
switch (dwWaitResult)
{
case WAIT_OBJECT_0:
{
Process();
}
break;
case WAIT_TIMEOUT:
TraceError("CFileLoaderThread::Execute: Timeout occured while time-out interval is INIFITE");
break;
}
pThreadPool->Enqueue([this, c_rstFileName]()
{
ProcessFile(c_rstFileName);
});
}
else
{
// Fallback to synchronous loading if thread pool not available
ProcessFile(c_rstFileName);
}
Destroy();
return 1;
}
void CFileLoaderThread::Request(std::string & c_rstFileName) // called in main thread
bool CFileLoaderThread::Fetch(TData ** ppData)
{
TData * pData = new TData;
pData->File.clear();
pData->stFileName = c_rstFileName;
m_RequestMutex.Lock();
m_pRequestDeque.push_back(pData);
m_RequestMutex.Unlock();
++m_iRestSemCount;
if (!ReleaseSemaphore(m_hSemaphore, m_iRestSemCount, NULL))
TraceError("CFileLoaderThread::Request: ReleaseSemaphore error");
--m_iRestSemCount;
}
bool CFileLoaderThread::Fetch(TData ** ppData) // called in main thread
{
m_CompleteMutex.Lock();
std::lock_guard<std::mutex> lock(m_CompleteMutex);
if (m_pCompleteDeque.empty())
{
m_CompleteMutex.Unlock();
return false;
}
*ppData = m_pCompleteDeque.front();
m_pCompleteDeque.pop_front();
m_CompleteMutex.Unlock();
return true;
}
void CFileLoaderThread::Process() // called in loader thread
void CFileLoaderThread::ProcessFile(const std::string& fileName)
{
m_RequestMutex.Lock();
if (m_pRequestDeque.empty())
{
m_RequestMutex.Unlock();
if (m_bShutdowned)
return;
}
TData * pData = m_pRequestDeque.front();
m_pRequestDeque.pop_front();
m_RequestMutex.Unlock();
TData * pData = new TData;
pData->File.clear();
pData->stFileName = fileName;
CPackManager::instance().GetFile(pData->stFileName, pData->File);
m_CompleteMutex.Lock();
m_pCompleteDeque.push_back(pData);
m_CompleteMutex.Unlock();
// Add to completed queue
{
std::lock_guard<std::mutex> lock(m_CompleteMutex);
m_pCompleteDeque.push_back(pData);
}
Sleep(g_iLoadingDelayTime);
}