From 2ccd17fb33c24a68bf249d53cda93d266819d4df Mon Sep 17 00:00:00 2001 From: Anonymous275 <36374260+Anonymous-275@users.noreply.github.com> Date: Mon, 25 Jul 2022 10:02:57 +0300 Subject: [PATCH] Custom thread safe wrapper for std::queue --- include/atomic_queue.h | 56 ++++++++++++++++++++++++++++++++++++++++++ src/Memory/BeamNG.cpp | 11 ++++++--- 2 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 include/atomic_queue.h diff --git a/include/atomic_queue.h b/include/atomic_queue.h new file mode 100644 index 0000000..e1f4b25 --- /dev/null +++ b/include/atomic_queue.h @@ -0,0 +1,56 @@ +// +// Created by Anonymous275 on 24/07/22. +// + +#pragma once +#include +#include + +template +class atomic_queue { +public: + bool try_pop(T& val) { + lock_guard guard(semaphore); + if(queue.empty())return false; + val = queue.front(); + queue.pop(); + full.release(); + return true; + } + + void push(const T& val) { + check_full(); + lock_guard guard(semaphore); + queue.push(val); + } + + size_t size() { + lock_guard guard(semaphore); + return queue.size(); + } + + bool empty() { + lock_guard guard(semaphore); + return queue.empty(); + } +private: + void check_full() { + if(size() >= Size) { + full.acquire(); + } + } +private: + struct lock_guard { + explicit lock_guard(std::binary_semaphore& lock) : lock(lock){ + lock.acquire(); + } + ~lock_guard() { + lock.release(); + } + private: + std::binary_semaphore& lock; + }; + std::binary_semaphore semaphore{1}, full{0}; + std::queue queue{}; +}; + diff --git a/src/Memory/BeamNG.cpp b/src/Memory/BeamNG.cpp index 7ee973c..6dd59c7 100644 --- a/src/Memory/BeamNG.cpp +++ b/src/Memory/BeamNG.cpp @@ -4,11 +4,13 @@ /// -#include "atomic_queue/atomic_queue.h" +#include "atomic_queue.h" #include "Memory/BeamNG.h" #include "Memory/Memory.h" -atomic_queue::AtomicQueue2 AtomicQueue; +//atomic_queue::AtomicQueue2 AtomicQueue; +std::unique_ptr> Queue; + int BeamNG::lua_open_jit_D(lua_State* State) { Memory::Print("Got lua State"); @@ -18,6 +20,7 @@ int BeamNG::lua_open_jit_D(lua_State* State) { } void BeamNG::EntryPoint() { + Queue = std::make_unique>(); auto status = MH_Initialize(); if(status != MH_OK)Memory::Print(std::string("MH Error -> ") + MH_StatusToString(status)); Memory::Print("PID : " + std::to_string(Memory::GetPID())); @@ -55,7 +58,7 @@ int Game(lua_State* L) { int LuaPop(lua_State* L) { std::string MSG; - if (AtomicQueue.try_pop(MSG)) { + if (Queue->try_pop(MSG)) { GELua::lua_push_fstring(L, "%s", MSG.c_str()); return 1; } @@ -82,7 +85,7 @@ void BeamNG::IPCListener() { IPCFromLauncher->receive(); if (!IPCFromLauncher->receive_timed_out()) { TimeOuts = 0; - AtomicQueue.push(IPCFromLauncher->msg()); + Queue->push(IPCFromLauncher->msg()); IPCFromLauncher->confirm_receive(); } else TimeOuts++; }