mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-12-14 12:09:36 +00:00
Improve load screen responsiveness
This commit is contained in:
152
PortabilityLayer/WorkerThread.cpp
Normal file
152
PortabilityLayer/WorkerThread.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
#include "WorkerThread.h"
|
||||
#include "HostSystemServices.h"
|
||||
#include "HostThreadEvent.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <new>
|
||||
|
||||
namespace PortabilityLayer
|
||||
{
|
||||
class WorkerThreadImpl final : public WorkerThread
|
||||
{
|
||||
public:
|
||||
WorkerThreadImpl();
|
||||
|
||||
bool Init();
|
||||
void Destroy() override;
|
||||
|
||||
void AsyncExecuteTask(Callback_t callback, void *context) override;
|
||||
|
||||
private:
|
||||
~WorkerThreadImpl() override;
|
||||
|
||||
static int StaticThreadFuncThunk(void *context);
|
||||
int ThreadFunc();
|
||||
|
||||
HostThreadEvent *m_wakeSignal;
|
||||
HostThreadEvent *m_wakeConsumedSignal;
|
||||
|
||||
Callback_t m_waitingCallback;
|
||||
void *m_waitingContext;
|
||||
|
||||
bool m_terminated;
|
||||
bool m_threadRunning;
|
||||
};
|
||||
}
|
||||
|
||||
void PortabilityLayer::WorkerThreadImpl::Destroy()
|
||||
{
|
||||
this->~WorkerThreadImpl();
|
||||
free(this);
|
||||
}
|
||||
|
||||
void PortabilityLayer::WorkerThreadImpl::AsyncExecuteTask(PortabilityLayer::WorkerThread::Callback_t callback, void *context)
|
||||
{
|
||||
m_waitingCallback = callback;
|
||||
m_waitingContext = context;
|
||||
m_wakeSignal->Signal();
|
||||
m_wakeConsumedSignal->Wait();
|
||||
}
|
||||
|
||||
PortabilityLayer::WorkerThreadImpl::WorkerThreadImpl()
|
||||
: m_wakeSignal(nullptr)
|
||||
, m_wakeConsumedSignal(nullptr)
|
||||
, m_waitingCallback(nullptr)
|
||||
, m_waitingContext(nullptr)
|
||||
, m_terminated(false)
|
||||
, m_threadRunning(false)
|
||||
{
|
||||
}
|
||||
|
||||
PortabilityLayer::WorkerThreadImpl::~WorkerThreadImpl()
|
||||
{
|
||||
if (m_threadRunning)
|
||||
{
|
||||
m_terminated = true;
|
||||
m_wakeSignal->Signal();
|
||||
m_wakeConsumedSignal->Wait();
|
||||
}
|
||||
|
||||
if (m_wakeSignal)
|
||||
m_wakeSignal->Destroy();
|
||||
if (m_wakeConsumedSignal)
|
||||
m_wakeConsumedSignal->Destroy();
|
||||
}
|
||||
|
||||
|
||||
int PortabilityLayer::WorkerThreadImpl::StaticThreadFuncThunk(void *context)
|
||||
{
|
||||
return static_cast<PortabilityLayer::WorkerThreadImpl*>(context)->ThreadFunc();
|
||||
}
|
||||
|
||||
int PortabilityLayer::WorkerThreadImpl::ThreadFunc()
|
||||
{
|
||||
m_wakeSignal->Wait();
|
||||
m_wakeConsumedSignal->Signal();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
m_wakeSignal->Wait();
|
||||
|
||||
if (m_terminated)
|
||||
{
|
||||
m_wakeConsumedSignal->Signal();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Callback_t callback = m_waitingCallback;
|
||||
void *context = m_waitingContext;
|
||||
m_wakeConsumedSignal->Signal();
|
||||
|
||||
callback(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PortabilityLayer::WorkerThreadImpl::Init()
|
||||
{
|
||||
HostSystemServices *sysServices = HostSystemServices::GetInstance();
|
||||
|
||||
m_wakeSignal = sysServices->CreateThreadEvent(true, false);
|
||||
if (!m_wakeSignal)
|
||||
return false;
|
||||
|
||||
m_wakeConsumedSignal = sysServices->CreateThreadEvent(true, false);
|
||||
if (!m_wakeConsumedSignal)
|
||||
return false;
|
||||
|
||||
if (!sysServices->CreateThread(PortabilityLayer::WorkerThreadImpl::StaticThreadFuncThunk, this))
|
||||
return false;
|
||||
|
||||
m_threadRunning = true;
|
||||
m_wakeSignal->Signal();
|
||||
m_wakeConsumedSignal->Wait();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
PortabilityLayer::WorkerThread::WorkerThread()
|
||||
{
|
||||
}
|
||||
|
||||
PortabilityLayer::WorkerThread::~WorkerThread()
|
||||
{
|
||||
}
|
||||
|
||||
PortabilityLayer::WorkerThread *PortabilityLayer::WorkerThread::Create()
|
||||
{
|
||||
void *storage = malloc(sizeof(PortabilityLayer::WorkerThreadImpl));
|
||||
if (!storage)
|
||||
return nullptr;
|
||||
|
||||
PortabilityLayer::WorkerThreadImpl *thread = new (storage) PortabilityLayer::WorkerThreadImpl();
|
||||
if (!thread->Init())
|
||||
{
|
||||
thread->Destroy();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return thread;
|
||||
}
|
||||
Reference in New Issue
Block a user