mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-12-15 12:22:30 +00:00
feat(whoa): implement the ability to shut down the client gracefully, saving CVars upon exit
This commit is contained in:
parent
17ccf2a8bb
commit
0105c72da0
11 changed files with 186 additions and 25 deletions
|
|
@ -1,4 +1,5 @@
|
|||
#include "event/Context.hpp"
|
||||
#include "Event.hpp"
|
||||
#include "event/Event.hpp"
|
||||
#include "event/EvtThread.hpp"
|
||||
#include <common/Time.hpp>
|
||||
|
|
@ -53,8 +54,32 @@ HEVENTCONTEXT AttachContextToThread(EvtContext* context) {
|
|||
return context;
|
||||
}
|
||||
|
||||
void DetachContextFromThread(uint32_t a1, EvtContext* a2) {
|
||||
// TODO
|
||||
void DetachContextFromThread(uint32_t hThread, EvtContext* context) {
|
||||
SInterlockedIncrement(&Event::s_threadListContention);
|
||||
Event::s_threadListCritsect.Enter();
|
||||
|
||||
auto threadSlot = Event::s_threadSlots[hThread];
|
||||
if (threadSlot) {
|
||||
threadSlot->m_weightTotal -= context->m_schedWeight;
|
||||
threadSlot->m_contextCount--;
|
||||
|
||||
threadSlot->m_weightAvg = threadSlot->m_contextCount ? threadSlot->m_weightTotal / threadSlot->m_contextCount : 0;
|
||||
|
||||
auto thread = Event::s_threadList.Head();
|
||||
while (thread) {
|
||||
if (thread != threadSlot && thread->m_weightAvg) {
|
||||
if ((thread->m_weightAvg + threadSlot->m_weightTotal) <= thread->m_weightTotal) {
|
||||
thread->m_rebalance += (thread->m_weightTotal - threadSlot->m_weightTotal) / thread->m_weightAvg;
|
||||
}
|
||||
thread->m_rebalance = std::min(thread->m_rebalance, thread->m_contextCount);
|
||||
}
|
||||
|
||||
thread = thread->Next();
|
||||
}
|
||||
}
|
||||
|
||||
Event::s_threadListCritsect.Leave();
|
||||
SInterlockedDecrement(&Event::s_threadListContention);
|
||||
}
|
||||
|
||||
EvtContext* GetNextContext(uint32_t hThread) {
|
||||
|
|
|
|||
|
|
@ -86,6 +86,10 @@ HEVENTCONTEXT EventCreateContextEx(int32_t interactive, int32_t (*initializeHand
|
|||
return IEvtSchedulerCreateContext(interactive, initializeHandler, destroyHandler, idleTime, debugFlags);
|
||||
}
|
||||
|
||||
void EventDestroy() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void EventDoMessageLoop() {
|
||||
IEvtSchedulerProcess();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ namespace Event {
|
|||
|
||||
HEVENTCONTEXT EventCreateContextEx(int32_t interactive, int32_t (*initializeHandler)(const void*, void*), int32_t (*destroyHandler)(const void*, void*), uint32_t idleTime, uint32_t debugFlags);
|
||||
|
||||
void EventDestroy();
|
||||
|
||||
void EventDoMessageLoop();
|
||||
|
||||
HEVENTCONTEXT EventGetCurrentContext();
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ void ResetSyncState(EvtContext* context) {
|
|||
|
||||
auto list = &context->m_queueSyncKeyDownList;
|
||||
|
||||
while (node = list->Head()) {
|
||||
while ((node = list->Head())) {
|
||||
list->UnlinkNode(node);
|
||||
list->DeleteNode(node);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "event/Scheduler.hpp"
|
||||
#include "Event.hpp"
|
||||
#include "event/Context.hpp"
|
||||
#include "event/Event.hpp"
|
||||
#include "event/EvtContext.hpp"
|
||||
|
|
@ -149,6 +150,18 @@ void IEvtSchedulerProcess() {
|
|||
|
||||
void IEvtSchedulerShutdown() {
|
||||
// TODO
|
||||
Event::s_shutdownEvent.Set();
|
||||
if (Event::s_netServer) {
|
||||
return;
|
||||
}
|
||||
|
||||
Event::s_threadListCritsect.Enter();
|
||||
for (uint32_t i = 0; i < Event::s_threadSlotCount; i++) {
|
||||
if (Event::s_threadSlots[i]) {
|
||||
Event::s_threadSlots[i]->m_wakeEvent.Set();
|
||||
}
|
||||
}
|
||||
Event::s_threadListCritsect.Leave();
|
||||
}
|
||||
|
||||
uint32_t InitializeSchedulerThread() {
|
||||
|
|
|
|||
|
|
@ -1,19 +1,55 @@
|
|||
#include "event/Synthesize.hpp"
|
||||
#include "event/Event.hpp"
|
||||
#include "event/Queue.hpp"
|
||||
#include "event/Types.hpp"
|
||||
#include "event/Scheduler.hpp"
|
||||
#include "event/EvtContext.hpp"
|
||||
#include "event/Queue.hpp"
|
||||
#include <common/Time.hpp>
|
||||
#include <common/Call.hpp>
|
||||
|
||||
#if defined(WHOA_SYSTEM_WIN)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
void SynthesizeDestroy(EvtContext* context) {
|
||||
// TODO
|
||||
#if defined(WHOA_SYSTEM_WIN)
|
||||
ExitProcess(0);
|
||||
#else
|
||||
exit(0);
|
||||
#endif
|
||||
if (!(context->m_schedFlags & 0x1)) {
|
||||
context->m_schedFlags |= 0x1;
|
||||
context->m_schedLastIdle = OsGetAsyncTimeMs();
|
||||
IEvtQueueDispatch(context, EVENT_ID_INITIALIZE, nullptr);
|
||||
}
|
||||
|
||||
if (context->m_schedFlags & 0x2) {
|
||||
SInterlockedDecrement(&Event::s_interactiveCount);
|
||||
if (!Event::s_interactiveCount) {
|
||||
IEvtSchedulerShutdown();
|
||||
}
|
||||
}
|
||||
|
||||
IEvtQueueDispatch(context, EVENT_ID_3, nullptr);
|
||||
context->m_critsect.Enter();
|
||||
context->m_schedState = EvtContext::SCHEDSTATE_DESTROYED;
|
||||
context->m_critsect.Leave();
|
||||
IEvtQueueDispatchAll(context);
|
||||
IEvtQueueDispatch(context, EVENT_ID_DESTROY, nullptr);
|
||||
|
||||
OsCallResetContext(context->m_callContext);
|
||||
PropSelectContext(0);
|
||||
|
||||
int32_t findMask;
|
||||
TSingletonInstanceId<EvtContext, offsetof(EvtContext, m_id)>::s_idTable.Ptr(
|
||||
context->m_id,
|
||||
1,
|
||||
&findMask);
|
||||
|
||||
DEL(context);
|
||||
|
||||
if (findMask != -1) {
|
||||
TSingletonInstanceId<EvtContext, offsetof(EvtContext, m_id)>::s_idTable.Unlock(
|
||||
findMask & (INSTANCE_TABLE_SLOT_COUNT - 1),
|
||||
findMask >= INSTANCE_TABLE_SLOT_COUNT
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void SynthesizeIdle(EvtContext* context, uint32_t currTime, float elapsedSec) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue