From 0b5108a8a0d9b7a4a63bd6aae0271b71a887beea Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Thu, 25 Apr 2024 13:36:47 +0200 Subject: C++ integration: cleanup in Linda/Keeper interaction --- src/linda.h | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/linda.h (limited to 'src/linda.h') diff --git a/src/linda.h b/src/linda.h new file mode 100644 index 0000000..559ef24 --- /dev/null +++ b/src/linda.h @@ -0,0 +1,70 @@ +#pragma once + +#include "cancel.h" +#include "deep.h" +#include "keeper.h" +#include "universe.h" + +#include +#include +#include + +struct Keeper; + +// ################################################################################################# + +using LindaGroup = Unique; + +class Linda : public DeepPrelude // Deep userdata MUST start with this header +{ + private: + + static constexpr size_t kEmbeddedNameLength = 24; + using EmbeddedName = std::array; + struct AllocatedName + { + size_t len{ 0 }; + char* name{ nullptr }; + }; + // depending on the name length, it is either embedded inside the Linda, or allocated separately + std::variant m_name; + + public: + + std::condition_variable m_read_happened; + std::condition_variable m_write_happened; + Universe* const U{ nullptr }; // the universe this linda belongs to + int const m_keeper_index{ -1 }; // the keeper associated to this linda + CancelRequest simulate_cancel{ CancelRequest::None }; + + public: + + // a fifo full userdata has one uservalue, the table that holds the actual fifo contents + [[nodiscard]] static void* operator new(size_t size_, Universe* U_) noexcept { return U_->internal_allocator.alloc(size_); } + // always embedded somewhere else or "in-place constructed" as a full userdata + // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception + static void operator delete(void* p_, Universe* U_) { U_->internal_allocator.free(p_, sizeof(Linda)); } + // this one is for us, to make sure memory is freed by the correct allocator + static void operator delete(void* p_) { static_cast(p_)->U->internal_allocator.free(p_, sizeof(Linda)); } + + ~Linda(); + Linda(Universe* U_, LindaGroup group_, char const* name_, size_t len_); + Linda() = delete; + Linda(Linda const&) = delete; + Linda(Linda const&&) = delete; + Linda& operator=(Linda const&) = delete; + Linda& operator=(Linda const&&) = delete; + + static int ProtectedCall(lua_State* L, lua_CFunction f_); + + private : + + void setName(char const* name_, size_t len_); + + public: + + [[nodiscard]] char const* getName() const; + [[nodiscard]] Keeper* whichKeeper() const { return U->keepers->nb_keepers ? &U->keepers->keeper_array[m_keeper_index] : nullptr; } + [[nodiscard]] Keeper* acquireKeeper() const; + void releaseKeeper(Keeper* keeper_) const; +}; -- cgit v1.2.3-55-g6feb