diff options
Diffstat (limited to 'src/linda.cpp')
-rw-r--r-- | src/linda.cpp | 28 |
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 | */ |
53 | struct Linda : public DeepPrelude // Deep userdata MUST start with this header | 53 | class 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 | ||