Fix concurrent access to several CConsole members

* Fix concurrent access to CConsole::m_Logger.
* Fix concurrent access to CConsole::m_vHistory.
* Additional DX system cleanup.
This commit is contained in:
Kawe Mazidjatari 2022-08-21 19:35:06 +02:00
parent 6f79d11696
commit 8476d22777
7 changed files with 54 additions and 41 deletions

View File

@ -124,7 +124,7 @@ void CBrowser::RunFrame(void)
}
//-----------------------------------------------------------------------------
// Purpose: runs tasks for the browser while not being drawn
// Purpose: think
//-----------------------------------------------------------------------------
void CBrowser::Think(void)
{
@ -619,7 +619,7 @@ void CBrowser::SendHostingPostRequest(void)
}
//-----------------------------------------------------------------------------
// Purpose: executes submitted commands in a separate thread
// Purpose: processes submitted commands for the main thread
// Input : *pszCommand -
//-----------------------------------------------------------------------------
void CBrowser::ProcessCommand(const char* pszCommand) const

View File

@ -51,8 +51,6 @@ CConsole::CConsole(void)
//-----------------------------------------------------------------------------
CConsole::~CConsole(void)
{
ClearLog();
m_vHistory.clear();
}
//-----------------------------------------------------------------------------
@ -144,6 +142,7 @@ void CConsole::RunFrame(void)
//-----------------------------------------------------------------------------
void CConsole::RunTask()
{
std::lock_guard<std::mutex> l(m_Mutex);
if (m_Logger.GetTotalLines() > con_max_size_logvector->GetInt())
{
while (m_Logger.GetTotalLines() > con_max_size_logvector->GetInt())
@ -156,6 +155,10 @@ void CConsole::RunTask()
m_Logger.MoveCursor(m_nSelectBack, false);
m_nSelectBack = 0;
}
while (m_vHistory.size() > 512)
{
m_vHistory.erase(m_vHistory.begin());
}
}
//-----------------------------------------------------------------------------
@ -165,11 +168,6 @@ void CConsole::Think(void)
{
for (;;) // Loop running at 100-tps.
{
while (m_vHistory.size() > 512)
{
m_vHistory.erase(m_vHistory.begin());
}
if (m_bActivate)
{
if (m_flFadeAlpha <= 1.f)
@ -198,6 +196,8 @@ void CConsole::DrawSurface(void)
return;
}
std::lock_guard<std::mutex> l(m_Mutex);
// Reserve enough left-over height and width for 1 separator + 1 input text
const float flFooterHeightReserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
const float flFooterWidthReserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetWindowWidth();
@ -359,7 +359,7 @@ void CConsole::SuggestPanel(void)
for (size_t i = 0; i < m_vSuggest.size(); i++)
{
bool bIsIndexActive = m_nSuggestPos == i;
ImGui::PushID(i);
ImGui::PushID(static_cast<int>(i));
if (con_suggestion_showflags->GetBool())
{
@ -534,7 +534,7 @@ void CConsole::FindFromPartial(void)
}
//-----------------------------------------------------------------------------
// Purpose: executes submitted commands in a separate thread
// Purpose: processes submitted commands for the main thread
// Input : pszCommand -
//-----------------------------------------------------------------------------
void CConsole::ProcessCommand(const char* pszCommand)
@ -793,7 +793,7 @@ int CConsole::TextEditCallback(ImGuiInputTextCallbackData* iData)
}
else if (i == (n - 1))
{
iData->DeleteChars(0, n);
iData->DeleteChars(0, static_cast<int>(n));
}
}
@ -822,17 +822,24 @@ int CConsole::TextEditCallbackStub(ImGuiInputTextCallbackData* iData)
//-----------------------------------------------------------------------------
void CConsole::AddLog(const ConLog_t& conLog)
{
if (!ThreadInRenderThread())
{
std::lock_guard<std::mutex> l(m_Mutex);
m_Logger.InsertText(conLog);
return;
}
m_Logger.InsertText(conLog);
}
//-----------------------------------------------------------------------------
// Purpose: adds logs to the vector
// Purpose: adds logs to the vector (internal)
// Input : *fmt -
// ... -
//-----------------------------------------------------------------------------
void CConsole::AddLog(const ImVec4& color, const char* fmt, ...) IM_FMTARGS(2)
{
char buf[1024];
char buf[4096];
va_list args{};
va_start(args, fmt);
vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args);

View File

@ -20,6 +20,7 @@ public:
virtual void DrawSurface(void);
private:
void OptionsPanel(void);
void SuggestPanel(void);
@ -38,7 +39,10 @@ public:
static int TextEditCallbackStub(ImGuiInputTextCallbackData* pData);
///////////////////////////////////////////////////////////////////////////
public:
void AddLog(const ConLog_t& conLog);
private:
void AddLog(const ImVec4& color, const char* fmt, ...) IM_FMTARGS(2);
void ClearLog(void);
@ -81,6 +85,7 @@ private:
ImVec2 m_ivSuggestWindowPos;
ImVec2 m_ivSuggestWindowSize;
CTextLogger m_Logger;
mutable std::mutex m_Mutex;
ImGuiInputTextFlags m_nInputFlags =
ImGuiInputTextFlags_AutoCaretEnd |

View File

@ -62,12 +62,12 @@ void ImGuiConfig::Load()
if (!jsIn["config"].is_null())
{
// IConsole
IConsole_Config.m_nBind0 = jsIn["config"]["IConsole"]["bind0"].get<int>();
IConsole_Config.m_nBind1 = jsIn["config"]["IConsole"]["bind1"].get<int>();
IConsole_Config.m_nBind0 = jsIn["config"]["GameConsole"]["bind0"].get<int>();
IConsole_Config.m_nBind1 = jsIn["config"]["GameConsole"]["bind1"].get<int>();
// IBrowser
IBrowser_Config.m_nBind0 = jsIn["config"]["IBrowser"]["bind0"].get<int>();
IBrowser_Config.m_nBind1 = jsIn["config"]["IBrowser"]["bind1"].get<int>();
IBrowser_Config.m_nBind0 = jsIn["config"]["GameBrowser"]["bind0"].get<int>();
IBrowser_Config.m_nBind1 = jsIn["config"]["GameBrowser"]["bind1"].get<int>();
}
}
}
@ -84,12 +84,12 @@ void ImGuiConfig::Save()
nlohmann::json jsOut;
// IConsole
jsOut["config"]["IConsole"]["bind0"] = IConsole_Config.m_nBind0;
jsOut["config"]["IConsole"]["bind1"] = IConsole_Config.m_nBind1;
jsOut["config"]["GameConsole"]["bind0"] = IConsole_Config.m_nBind0;
jsOut["config"]["GameConsole"]["bind1"] = IConsole_Config.m_nBind1;
// IBrowser
jsOut["config"]["IBrowser"]["bind0"] = IBrowser_Config.m_nBind0;
jsOut["config"]["IBrowser"]["bind1"] = IBrowser_Config.m_nBind1;
jsOut["config"]["GameBrowser"]["bind0"] = IBrowser_Config.m_nBind0;
jsOut["config"]["GameBrowser"]["bind1"] = IBrowser_Config.m_nBind1;
fs::path fsPath = "platform\\imgui.json";

View File

@ -35,6 +35,11 @@ bool ThreadInMainThread()
return (ThreadGetCurrentId() == (*g_ThreadMainThreadID));
}
bool ThreadInRenderThread()
{
return (ThreadGetCurrentId() == g_ThreadRenderThreadID);
}
ThreadId_t ThreadGetCurrentId()
{
#ifdef _WIN32

View File

@ -54,6 +54,7 @@ inline void ThreadPause()
}
bool ThreadInMainThread();
bool ThreadInRenderThread();
ThreadId_t ThreadGetCurrentId();
//-----------------------------------------------------------------------------
@ -212,7 +213,8 @@ inline auto v_MutexInternal_ReleaseWaiter = p_MutexInternal_ReleaseWaiter.RCast<
inline CMemory p_DeclareCurrentThreadIsMainThread;
inline auto v_DeclareCurrentThreadIsMainThread = p_DeclareCurrentThreadIsMainThread.RCast<ThreadId_t (*)(void)>();
inline ThreadId_t* g_ThreadMainThreadID;
inline ThreadId_t* g_ThreadMainThreadID = nullptr;
inline ThreadId_t g_ThreadRenderThreadID = NULL;
///////////////////////////////////////////////////////////////////////////////
class CThreadFastMutex

View File

@ -2,6 +2,7 @@
#ifndef DEDICATED // This file should not be compiled for DEDICATED!
//------------------------------
#define STB_IMAGE_IMPLEMENTATION
#include "tier0/threadtools.h"
#include "tier1/cvar.h"
#include "windows/id3dx.h"
#include "windows/input.h"
@ -210,13 +211,9 @@ void GetPresent()
&nFeatureLevelsSupported,
&pContext)))
{
if (mat_showdxoutput->GetBool())
{
Error(eDLL_T::MS, "+--------------------------------------------------------+\n");
Error(eDLL_T::MS, "| >>>>>>>>>| VIRTUAL METHOD TABLE HOOK FAILED |<<<<<<<<< |\n");
Error(eDLL_T::MS, "+--------------------------------------------------------+\n");
}
Error(eDLL_T::MS, "Failed to create device and swap chain: error code = %08x\n", hr);
DirectX_Shutdown();
return;
}
@ -349,9 +346,9 @@ void DestroyRenderTarget()
if (mat_showdxoutput->GetBool())
{
DevMsg(eDLL_T::MS, "+--------------------------------------------------------+\n");
DevMsg(eDLL_T::MS, "| >>>>>>>>>>>>>>| RENDER TARGET DESTROYED |<<<<<<<<<<<<< |\n");
DevMsg(eDLL_T::MS, "+--------------------------------------------------------+\n");
DevMsg(eDLL_T::MS, "+----------------------------------------------------------------+\n");
DevMsg(eDLL_T::MS, "| >>>>>>>>>>>>>>>| RENDER TARGET VIEW DESTROYED |<<<<<<<<<<<<<<< |\n");
DevMsg(eDLL_T::MS, "+----------------------------------------------------------------+\n");
}
}
}
@ -391,14 +388,10 @@ HRESULT __stdcall Present(IDXGISwapChain* pSwapChain, UINT nSyncInterval, UINT n
{
if (!g_bInitialized)
{
if (FAILED(GetDeviceAndCtxFromSwapchain(pSwapChain, &g_pDevice, &g_pDeviceContext)))
HRESULT hr = 0;
if (FAILED(hr = GetDeviceAndCtxFromSwapchain(pSwapChain, &g_pDevice, &g_pDeviceContext)))
{
if (mat_showdxoutput->GetBool())
{
Error(eDLL_T::MS, "+--------------------------------------------------------+\n");
Error(eDLL_T::MS, "| >>>>>>>>>>| GET DVS AND CTX FROM SCP FAILED |<<<<<<<<< |\n");
Error(eDLL_T::MS, "+--------------------------------------------------------+\n");
}
Error(eDLL_T::MS, "Failed to get device and context from swap chain: error code = %08x\n", hr);
return g_fnIDXGISwapChainPresent(pSwapChain, nSyncInterval, nFlags);
}
@ -410,12 +403,12 @@ HRESULT __stdcall Present(IDXGISwapChain* pSwapChain, UINT nSyncInterval, UINT n
g_oWndProc = (WNDPROC)SetWindowLongPtr(g_hGameWindow, GWLP_WNDPROC, (LONG_PTR)HwndProc);
}
g_pSwapChain = pSwapChain;
g_ThreadRenderThreadID = GetCurrentThreadId();
g_bInitialized = true;
g_pSwapChain = pSwapChain;
}
DrawImGui();
g_bInitialized = true;
///////////////////////////////////////////////////////////////////////////////
return g_fnIDXGISwapChainPresent(pSwapChain, nSyncInterval, nFlags);
}
@ -532,6 +525,7 @@ void DirectX_Shutdown()
ImGui_ImplDX11_Shutdown();
g_bImGuiInitialized = false;
}
g_bInitialized = false;
}
void VDXGI::GetAdr(void) const