Merge pull request #573 from diamante0018/feature/scoped-crit-sections
Feature: Scoped crit sections
This commit is contained in:
commit
c23557ff9a
@ -1,4 +1,5 @@
|
|||||||
#include <STDInclude.hpp>
|
#include <STDInclude.hpp>
|
||||||
|
#include "Game/Engine/ScopedCriticalSection.hpp"
|
||||||
|
|
||||||
namespace Components
|
namespace Components
|
||||||
{
|
{
|
||||||
@ -288,7 +289,7 @@ namespace Components
|
|||||||
|
|
||||||
sprintf_s(newFileName, "%s_%s.log", bug, Game::Live_GetLocalClientName(0));
|
sprintf_s(newFileName, "%s_%s.log", bug, Game::Live_GetLocalClientName(0));
|
||||||
|
|
||||||
Game::Sys_EnterCriticalSection(Game::CRITSECT_CONSOLE);
|
Game::Engine::ScopedCriticalSection _(Game::CRITSECT_CONSOLE, Game::Engine::SCOPED_CRITSECT_NORMAL);
|
||||||
|
|
||||||
if (*Game::logfile)
|
if (*Game::logfile)
|
||||||
{
|
{
|
||||||
@ -301,8 +302,6 @@ namespace Components
|
|||||||
const auto result = CopyFileA(from_ospath, to_ospath, 0);
|
const auto result = CopyFileA(from_ospath, to_ospath, 0);
|
||||||
Game::Com_OpenLogFile();
|
Game::Com_OpenLogFile();
|
||||||
|
|
||||||
Game::Sys_LeaveCriticalSection(Game::CRITSECT_CONSOLE);
|
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
Logger::PrintError(1, "CopyFile failed({}) {} {}\n", GetLastError(), "console_mp.log", newFileName);
|
Logger::PrintError(1, "CopyFile failed({}) {} {}\n", GetLastError(), "console_mp.log", newFileName);
|
||||||
|
82
src/Game/Engine/ScopedCriticalSection.cpp
Normal file
82
src/Game/Engine/ScopedCriticalSection.cpp
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
#include <STDInclude.hpp>
|
||||||
|
#include "ScopedCriticalSection.hpp"
|
||||||
|
|
||||||
|
namespace Game::Engine
|
||||||
|
{
|
||||||
|
ScopedCriticalSection::ScopedCriticalSection(const CriticalSection s, const ScopedCriticalSectionType type)
|
||||||
|
: s_(s), isScopedRelease_(false)
|
||||||
|
{
|
||||||
|
if (type == SCOPED_CRITSECT_NORMAL)
|
||||||
|
{
|
||||||
|
Sys_EnterCriticalSection(this->s_);
|
||||||
|
this->hasOwnership_ = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (type == SCOPED_CRITSECT_TRY)
|
||||||
|
{
|
||||||
|
this->hasOwnership_ = Sys_TryEnterCriticalSection(this->s_);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (type == SCOPED_CRITSECT_RELEASE)
|
||||||
|
{
|
||||||
|
Sys_LeaveCriticalSection(this->s_);
|
||||||
|
this->isScopedRelease_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->hasOwnership_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ScopedCriticalSection::~ScopedCriticalSection()
|
||||||
|
{
|
||||||
|
if (!this->hasOwnership_ || this->isScopedRelease_)
|
||||||
|
{
|
||||||
|
if (!this->hasOwnership_ && this->isScopedRelease_)
|
||||||
|
{
|
||||||
|
Sys_EnterCriticalSection(this->s_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Sys_LeaveCriticalSection(this->s_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScopedCriticalSection::enterCritSect()
|
||||||
|
{
|
||||||
|
assert(!this->hasOwnership_);
|
||||||
|
|
||||||
|
this->hasOwnership_ = true;
|
||||||
|
Sys_EnterCriticalSection(this->s_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScopedCriticalSection::leaveCritSect()
|
||||||
|
{
|
||||||
|
assert(this->hasOwnership_);
|
||||||
|
|
||||||
|
this->hasOwnership_ = false;
|
||||||
|
Sys_LeaveCriticalSection(this->s_);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScopedCriticalSection::tryEnterCritSect()
|
||||||
|
{
|
||||||
|
assert(!this->hasOwnership_);
|
||||||
|
|
||||||
|
const auto result = Sys_TryEnterCriticalSection(this->s_);
|
||||||
|
this->hasOwnership_ = result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScopedCriticalSection::hasOwnership() const
|
||||||
|
{
|
||||||
|
return this->hasOwnership_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScopedCriticalSection::isScopedRelease() const
|
||||||
|
{
|
||||||
|
return this->isScopedRelease_;
|
||||||
|
}
|
||||||
|
}
|
31
src/Game/Engine/ScopedCriticalSection.hpp
Normal file
31
src/Game/Engine/ScopedCriticalSection.hpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Game::Engine
|
||||||
|
{
|
||||||
|
enum ScopedCriticalSectionType
|
||||||
|
{
|
||||||
|
SCOPED_CRITSECT_NORMAL = 0x0,
|
||||||
|
SCOPED_CRITSECT_DISABLED = 0x1,
|
||||||
|
SCOPED_CRITSECT_RELEASE = 0x2,
|
||||||
|
SCOPED_CRITSECT_TRY = 0x3,
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScopedCriticalSection
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScopedCriticalSection(CriticalSection s, ScopedCriticalSectionType type);
|
||||||
|
~ScopedCriticalSection();
|
||||||
|
|
||||||
|
void enterCritSect();
|
||||||
|
void leaveCritSect();
|
||||||
|
[[nodiscard]] bool tryEnterCritSect();
|
||||||
|
|
||||||
|
[[nodiscard]] bool hasOwnership() const;
|
||||||
|
[[nodiscard]] bool isScopedRelease() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
CriticalSection s_;
|
||||||
|
bool hasOwnership_;
|
||||||
|
bool isScopedRelease_;
|
||||||
|
};
|
||||||
|
}
|
@ -24,6 +24,8 @@ namespace Game
|
|||||||
|
|
||||||
char(*sys_exitCmdLine)[1024] = reinterpret_cast<char(*)[1024]>(0x649FB68);
|
char(*sys_exitCmdLine)[1024] = reinterpret_cast<char(*)[1024]>(0x649FB68);
|
||||||
|
|
||||||
|
RTL_CRITICAL_SECTION* s_criticalSection = reinterpret_cast<RTL_CRITICAL_SECTION*>(0x6499BC8);
|
||||||
|
|
||||||
void Sys_LockRead(FastCriticalSection* critSect)
|
void Sys_LockRead(FastCriticalSection* critSect)
|
||||||
{
|
{
|
||||||
InterlockedIncrement(&critSect->readCount);
|
InterlockedIncrement(&critSect->readCount);
|
||||||
@ -35,4 +37,12 @@ namespace Game
|
|||||||
assert(critSect->readCount > 0);
|
assert(critSect->readCount > 0);
|
||||||
InterlockedDecrement(&critSect->readCount);
|
InterlockedDecrement(&critSect->readCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Sys_TryEnterCriticalSection(CriticalSection critSect)
|
||||||
|
{
|
||||||
|
assert(static_cast<unsigned int>(critSect) <
|
||||||
|
static_cast<unsigned int>(CRITSECT_COUNT));
|
||||||
|
|
||||||
|
return TryEnterCriticalSection(&s_criticalSection[critSect]) != FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,10 @@ namespace Game
|
|||||||
|
|
||||||
extern char(*sys_exitCmdLine)[1024];
|
extern char(*sys_exitCmdLine)[1024];
|
||||||
|
|
||||||
|
extern RTL_CRITICAL_SECTION* s_criticalSection;
|
||||||
|
|
||||||
extern void Sys_LockRead(FastCriticalSection* critSect);
|
extern void Sys_LockRead(FastCriticalSection* critSect);
|
||||||
extern void Sys_UnlockRead(FastCriticalSection* critSect);
|
extern void Sys_UnlockRead(FastCriticalSection* critSect);
|
||||||
|
|
||||||
|
extern bool Sys_TryEnterCriticalSection(CriticalSection critSect);
|
||||||
}
|
}
|
||||||
|
@ -162,31 +162,31 @@ namespace Steam
|
|||||||
Interface clientUtils(Proxy::ClientEngine->GetIClientUtils(Proxy::SteamPipe));
|
Interface clientUtils(Proxy::ClientEngine->GetIClientUtils(Proxy::SteamPipe));
|
||||||
clientUtils.invoke<void>("SetAppIDForCurrentPipe", Proxy::AppId, false);
|
clientUtils.invoke<void>("SetAppIDForCurrentPipe", Proxy::AppId, false);
|
||||||
|
|
||||||
char ourPath[MAX_PATH] = {0};
|
char ourPath[MAX_PATH]{};
|
||||||
GetModuleFileNameA(GetModuleHandle(nullptr), ourPath, sizeof(ourPath));
|
GetModuleFileNameA(GetModuleHandle(nullptr), ourPath, sizeof(ourPath));
|
||||||
|
|
||||||
char ourDirectory[MAX_PATH] = { 0 };
|
char ourDirectory[MAX_PATH]{};
|
||||||
GetCurrentDirectoryA(sizeof(ourDirectory), ourDirectory);
|
GetCurrentDirectoryA(sizeof(ourDirectory), ourDirectory);
|
||||||
|
|
||||||
std::string cmdline = ::Utils::String::VA("\"%s\" -proc %d", ourPath, GetCurrentProcessId());
|
const auto* cmdline = ::Utils::String::VA("\"%s\" -proc %d", ourPath, GetCurrentProcessId());
|
||||||
|
|
||||||
// As of 02/19/2017, the SpawnProcess method doesn't require the app id anymore,
|
// As of 02/19/2017, the SpawnProcess method doesn't require the app id anymore,
|
||||||
// but only for those who participate in the beta.
|
// but only for those who participate in the beta.
|
||||||
// Therefore we have to check how many bytes the method expects as arguments
|
// Therefore we have to check how many bytes the method expects as arguments
|
||||||
// and adapt our call accordingly!
|
// and adapt our call accordingly!
|
||||||
size_t expectedParams = Proxy::ClientUser.paramSize("SpawnProcess");
|
const auto expectedParams = Proxy::ClientUser.paramSize("SpawnProcess");
|
||||||
if (expectedParams == 40) // Release
|
if (expectedParams == 40) // Release
|
||||||
{
|
{
|
||||||
Proxy::ClientUser.invoke<bool>("SpawnProcess", ourPath, cmdline.data(), ourDirectory, gameID.bits, mod.data(), Proxy::AppId, 0, 0);
|
Proxy::ClientUser.invoke<bool>("SpawnProcess", ourPath, cmdline, ourDirectory, gameID.bits, mod.data(), Proxy::AppId, 0, 0, 0);
|
||||||
}
|
}
|
||||||
else if (expectedParams == 36) // Beta
|
else if (expectedParams == 36) // Beta
|
||||||
{
|
{
|
||||||
Proxy::ClientUser.invoke<bool>("SpawnProcess", ourPath, cmdline.data(), ourDirectory, gameID.bits, mod.data(), Proxy::AppId, 0, 0);
|
Proxy::ClientUser.invoke<bool>("SpawnProcess", ourPath, cmdline, ourDirectory, gameID.bits, mod.data(), Proxy::AppId, 0, 0);
|
||||||
}
|
}
|
||||||
else if (expectedParams == 48) // Legacy, expects VAC blob
|
else if (expectedParams == 48) // Legacy, expects VAC blob
|
||||||
{
|
{
|
||||||
char blob[8] = { 0 };
|
char blob[8] = { 0 };
|
||||||
Proxy::ClientUser.invoke<bool>("SpawnProcess", blob, 0, ourPath, cmdline.data(), 0, ourDirectory, gameID.bits, Proxy::AppId, mod.data(), 0, 0);
|
Proxy::ClientUser.invoke<bool>("SpawnProcess", blob, 0, ourPath, cmdline, 0, ourDirectory, gameID.bits, Proxy::AppId, mod.data(), 0, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -260,7 +260,7 @@ namespace Steam
|
|||||||
Proxy::Callbacks.erase(callId);
|
Proxy::Callbacks.erase(callId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Proxy::RunCallback(int32_t callId, void* data, size_t /*size*/)
|
void Proxy::RunCallback(int32_t callId, void* data, std::size_t /*size*/)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> _(Proxy::CallMutex);
|
std::lock_guard<std::recursive_mutex> _(Proxy::CallMutex);
|
||||||
|
|
||||||
|
@ -169,8 +169,8 @@ namespace Steam
|
|||||||
return T();
|
return T();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t argc = method.second;
|
std::size_t argc = method.second;
|
||||||
constexpr size_t passedArgc = Interface::AddSizes<sizeof(Args)...>::value;
|
constexpr std::size_t passedArgc = Interface::AddSizes<sizeof(Args)...>::value;
|
||||||
if(passedArgc != argc)
|
if(passedArgc != argc)
|
||||||
{
|
{
|
||||||
OutputDebugStringA(::Utils::String::VA("Steam interface arguments for method %s do not match (expected %d bytes, but got %d bytes)!\n", methodName.data(), argc, passedArgc));
|
OutputDebugStringA(::Utils::String::VA("Steam interface arguments for method %s do not match (expected %d bytes, but got %d bytes)!\n", methodName.data(), argc, passedArgc));
|
||||||
@ -185,7 +185,7 @@ namespace Steam
|
|||||||
return this->interfacePtr != nullptr;
|
return this->interfacePtr != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t paramSize(const std::string& methodName)
|
std::size_t paramSize(const std::string& methodName)
|
||||||
{
|
{
|
||||||
auto method = this->getMethod(methodName);
|
auto method = this->getMethod(methodName);
|
||||||
return method.second;
|
return method.second;
|
||||||
@ -222,9 +222,9 @@ namespace Steam
|
|||||||
private:
|
private:
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
|
|
||||||
inline void packBytes(const void* bytes, size_t size)
|
inline void packBytes(const void* bytes, std::size_t size)
|
||||||
{
|
{
|
||||||
this->buffer.append(reinterpret_cast<const char*>(bytes), size);
|
this->buffer.append(static_cast<const char*>(bytes), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void packDataType(uint8_t type)
|
inline void packDataType(uint8_t type)
|
||||||
@ -358,7 +358,7 @@ namespace Steam
|
|||||||
static std::function<SteamFreeLastCallbackFn> SteamFreeLastCallback;
|
static std::function<SteamFreeLastCallbackFn> SteamFreeLastCallback;
|
||||||
static std::function<SteamGetAPICallResultFn> SteamGetAPICallResult;
|
static std::function<SteamGetAPICallResultFn> SteamGetAPICallResult;
|
||||||
|
|
||||||
static void RunCallback(int32_t callId, void* data, size_t size);
|
static void RunCallback(int32_t callId, void* data, std::size_t size);
|
||||||
|
|
||||||
static void UnregisterCalls();
|
static void UnregisterCalls();
|
||||||
static void LaunchWatchGuard();
|
static void LaunchWatchGuard();
|
||||||
|
Loading…
Reference in New Issue
Block a user