aboutsummaryrefslogtreecommitdiff
path: root/src/linda.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/linda.h')
-rw-r--r--src/linda.h70
1 files changed, 70 insertions, 0 deletions
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 @@
1#pragma once
2
3#include "cancel.h"
4#include "deep.h"
5#include "keeper.h"
6#include "universe.h"
7
8#include <array>
9#include <condition_variable>
10#include <variant>
11
12struct Keeper;
13
14// #################################################################################################
15
16using LindaGroup = Unique<int>;
17
18class Linda : public DeepPrelude // Deep userdata MUST start with this header
19{
20 private:
21
22 static constexpr size_t kEmbeddedNameLength = 24;
23 using EmbeddedName = std::array<char, kEmbeddedNameLength>;
24 struct AllocatedName
25 {
26 size_t len{ 0 };
27 char* name{ nullptr };
28 };
29 // depending on the name length, it is either embedded inside the Linda, or allocated separately
30 std::variant<AllocatedName, EmbeddedName> m_name;
31
32 public:
33
34 std::condition_variable m_read_happened;
35 std::condition_variable m_write_happened;
36 Universe* const U{ nullptr }; // the universe this linda belongs to
37 int const m_keeper_index{ -1 }; // the keeper associated to this linda
38 CancelRequest simulate_cancel{ CancelRequest::None };
39
40 public:
41
42 // a fifo full userdata has one uservalue, the table that holds the actual fifo contents
43 [[nodiscard]] static void* operator new(size_t size_, Universe* U_) noexcept { return U_->internal_allocator.alloc(size_); }
44 // always embedded somewhere else or "in-place constructed" as a full userdata
45 // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception
46 static void operator delete(void* p_, Universe* U_) { U_->internal_allocator.free(p_, sizeof(Linda)); }
47 // this one is for us, to make sure memory is freed by the correct allocator
48 static void operator delete(void* p_) { static_cast<Linda*>(p_)->U->internal_allocator.free(p_, sizeof(Linda)); }
49
50 ~Linda();
51 Linda(Universe* U_, LindaGroup group_, char const* name_, size_t len_);
52 Linda() = delete;
53 Linda(Linda const&) = delete;
54 Linda(Linda const&&) = delete;
55 Linda& operator=(Linda const&) = delete;
56 Linda& operator=(Linda const&&) = delete;
57
58 static int ProtectedCall(lua_State* L, lua_CFunction f_);
59
60 private :
61
62 void setName(char const* name_, size_t len_);
63
64 public:
65
66 [[nodiscard]] char const* getName() const;
67 [[nodiscard]] Keeper* whichKeeper() const { return U->keepers->nb_keepers ? &U->keepers->keeper_array[m_keeper_index] : nullptr; }
68 [[nodiscard]] Keeper* acquireKeeper() const;
69 void releaseKeeper(Keeper* keeper_) const;
70};