diff --git a/module/deps/ThreadSafeContainer.h b/module/deps/ThreadSafeContainer.h new file mode 100644 index 0000000..0aa68fe --- /dev/null +++ b/module/deps/ThreadSafeContainer.h @@ -0,0 +1,66 @@ +#pragma once + +#include +#include +#include + +/// \brief Safe thread associative container +/// \tparam K type of key +/// \tparam V type of value +template +class ThreadSafeContainer final +{ +public: + ThreadSafeContainer() = default; + ~ThreadSafeContainer() noexcept = default; + + /// \brief Insert value in container by key + /// \param K key + /// \param V value + void Insert(K key, V value); + + /// \brief Check value exists by key + /// \param K key + /// \return true - if value exists, else - false + bool Find(K key) const; + + /// \brief Get element from container + /// \param K key + /// \return value + std::optional GetElement(K key) const; + +private: + std::unordered_map container; + mutable std::mutex mutex; + + ThreadSafeContainer(ThreadSafeContainer&& other) = delete; + ThreadSafeContainer(const ThreadSafeContainer& other) = delete; + ThreadSafeContainer& operator=(ThreadSafeContainer&& other) = delete; + ThreadSafeContainer& operator=(const ThreadSafeContainer& other) = delete; +}; + +template +void ThreadSafeContainer::Insert(K key, V value) +{ + std::lock_guard lock{ mutex }; + container[key] = value; +} + +template +bool ThreadSafeContainer::Find(K key) const +{ + std::lock_guard lock{ mutex }; + return container.find(key) != container.end(); +} + +template +std::optional ThreadSafeContainer::GetElement(K key) const +{ + std::lock_guard lock{ mutex }; + auto it = container.find(key); + if (it == container.end()) + { + return std::nullopt; + } + return it->second; +} diff --git a/module/src/CScriptRuntimeInfo.h b/module/src/CScriptRuntimeInfo.h index ecde5b6..0547837 100644 --- a/module/src/CScriptRuntimeInfo.h +++ b/module/src/CScriptRuntimeInfo.h @@ -1,16 +1,31 @@ #pragma once +#include +#include +#include + #include "v8.h" -#include +#include "Log.h" +#include "ThreadSafeContainer.h" +#include "libplatform/libplatform.h" class CScriptRuntimeInfo { private: - v8::Isolate* isolate; + ThreadSafeContainer isolates; std::unique_ptr platform; public: - v8::Isolate* GetIsolate() { return isolate; } + v8::Isolate* GetIsolate() { + if (!isolates.Find(std::this_thread::get_id())) + { + Log::Colored << "NOT FOUND" << std::this_thread::get_id() << Log::Endl; + v8::Isolate* isolate = MakeIsolate(); + isolates.Insert(std::this_thread::get_id(), isolate); + return isolate; + } + return isolates.GetElement(std::this_thread::get_id()).value_or(nullptr); + } v8::Isolate* MakeIsolate() { @@ -28,7 +43,7 @@ class CScriptRuntimeInfo v8::V8::Initialize(); - isolate = MakeIsolate(); + isolates.Insert(std::this_thread::get_id(), MakeIsolate()); } static CScriptRuntimeInfo& Instance() diff --git a/module/src/runtime.cpp b/module/src/runtime.cpp index 93aa8a3..26881e5 100644 --- a/module/src/runtime.cpp +++ b/module/src/runtime.cpp @@ -7,7 +7,7 @@ void JSBytecodeRuntime::ProcessClientFile(alt::IResource* resource, alt::IPackage* package) { - v8::Isolate* isolate = CScriptRuntimeInfo::Instance().MakeIsolate(); + v8::Isolate* isolate = CScriptRuntimeInfo::Instance().GetIsolate(); v8::Isolate::Scope isolateScope(isolate); v8::HandleScope handleScope(isolate);