aboutsummaryrefslogtreecommitdiff
path: root/src/linda.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/linda.cpp')
-rw-r--r--src/linda.cpp28
1 files changed, 16 insertions, 12 deletions
diff --git a/src/linda.cpp b/src/linda.cpp
index e1633b0..dc5864b 100644
--- a/src/linda.cpp
+++ b/src/linda.cpp
@@ -50,7 +50,7 @@ THE SOFTWARE.
50* Actual data is kept within a keeper state, which is hashed by the 'Linda' 50* Actual data is kept within a keeper state, which is hashed by the 'Linda'
51* pointer (which is same to all userdatas pointing to it). 51* pointer (which is same to all userdatas pointing to it).
52*/ 52*/
53struct Linda : public DeepPrelude // Deep userdata MUST start with this header 53class Linda : public DeepPrelude // Deep userdata MUST start with this header
54{ 54{
55 private: 55 private:
56 56
@@ -61,19 +61,28 @@ struct Linda : public DeepPrelude // Deep userdata MUST start with this header
61 size_t len{ 0 }; 61 size_t len{ 0 };
62 char* name{ nullptr }; 62 char* name{ nullptr };
63 }; 63 };
64 // depending on the name length, it is either embedded inside the Linda, or allocated separately
65 std::variant<AllocatedName, EmbeddedName> m_name;
64 66
65 public: 67 public:
66 68
67 SIGNAL_T read_happened; 69 SIGNAL_T read_happened;
68 SIGNAL_T write_happened; 70 SIGNAL_T write_happened;
69 Universe* const U; // the universe this linda belongs to 71 Universe* const U; // the universe this linda belongs to
70 ptrdiff_t const group; // a group to control keeper allocation between lindas 72 uintptr_t const group; // a group to control keeper allocation between lindas
71 CancelRequest simulate_cancel{ CancelRequest::None }; 73 CancelRequest simulate_cancel{ CancelRequest::None };
72 std::variant<AllocatedName, EmbeddedName> m_name;
73 74
74 public: 75 public:
75 76
76 Linda(Universe* U_, ptrdiff_t group_, char const* name_, size_t len_) 77 // a fifo full userdata has one uservalue, the table that holds the actual fifo contents
78 static void* operator new(size_t size_, Universe* U_) noexcept { return U_->internal_allocator.alloc(size_); }
79 // always embedded somewhere else or "in-place constructed" as a full userdata
80 // can't actually delete the operator because the compiler generates stack unwinding code that could call it in case of exception
81 static void operator delete(void* p_, Universe* U_) { U_->internal_allocator.free(p_, sizeof(Linda)); }
82 // this one is for us, to make sure memory is freed by the correct allocator
83 static void operator delete(void* p_) { static_cast<Linda*>(p_)->U->internal_allocator.free(p_, sizeof(Linda)); }
84
85 Linda(Universe* U_, uintptr_t group_, char const* name_, size_t len_)
77 : U{ U_ } 86 : U{ U_ }
78 , group{ group_ << KEEPER_MAGIC_SHIFT } 87 , group{ group_ << KEEPER_MAGIC_SHIFT }
79 { 88 {
@@ -122,7 +131,7 @@ struct Linda : public DeepPrelude // Deep userdata MUST start with this header
122 131
123 public: 132 public:
124 133
125 ptrdiff_t hashSeed() const { return group ? group : std::bit_cast<ptrdiff_t>(this); } 134 uintptr_t hashSeed() const { return group ? group : std::bit_cast<uintptr_t>(this); }
126 135
127 char const* getName() const 136 char const* getName() const
128 { 137 {
@@ -887,11 +896,7 @@ static void* linda_id( lua_State* L, DeepOp op_)
887 * just don't use L's allocF because we don't know which state will get the honor of GCing the linda 896 * just don't use L's allocF because we don't know which state will get the honor of GCing the linda
888 */ 897 */
889 Universe* const U{ universe_get(L) }; 898 Universe* const U{ universe_get(L) };
890 Linda* s{ static_cast<Linda*>(U->internal_allocator.alloc(sizeof(Linda))) }; // terminating 0 is already included 899 Linda* s{ new (U) Linda{ U, linda_group, linda_name, name_len } };
891 if (s)
892 {
893 s->Linda::Linda(U, linda_group, linda_name, name_len);
894 }
895 return s; 900 return s;
896 } 901 }
897 902
@@ -909,8 +914,7 @@ static void* linda_id( lua_State* L, DeepOp op_)
909 } 914 }
910 keeper_release( K); 915 keeper_release( K);
911 916
912 linda->Linda::~Linda(); 917 delete linda; // operator delete overload ensures things go as expected
913 linda->U->internal_allocator.free(linda, sizeof(Linda));
914 return nullptr; 918 return nullptr;
915 } 919 }
916 920