aboutsummaryrefslogtreecommitdiff
path: root/src/linda.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/linda.h')
-rw-r--r--src/linda.h32
1 files changed, 29 insertions, 3 deletions
diff --git a/src/linda.h b/src/linda.h
index 8db380a..809ade5 100644
--- a/src/linda.h
+++ b/src/linda.h
@@ -23,15 +23,39 @@ using LindaGroup = Unique<int>;
23class Linda 23class Linda
24: public DeepPrelude // Deep userdata MUST start with this header 24: public DeepPrelude // Deep userdata MUST start with this header
25{ 25{
26 public:
27 class KeeperOperationInProgress
28 {
29 private:
30 Linda& linda;
31 [[maybe_unused]] lua_State* const L; // just here for inspection while debugging
32
33 public:
34 KeeperOperationInProgress(Linda& linda_, lua_State* const L_)
35 : linda{ linda_ }
36 , L{ L_ }
37 {
38 [[maybe_unused]] int const _prev{ linda.keeperOperationCount.fetch_add(1, std::memory_order_seq_cst) };
39 }
40
41 public:
42 ~KeeperOperationInProgress()
43 {
44 [[maybe_unused]] int const _prev{ linda.keeperOperationCount.fetch_sub(1, std::memory_order_seq_cst) };
45 }
46 };
47
26 private: 48 private:
27 static constexpr size_t kEmbeddedNameLength = 24; 49 static constexpr size_t kEmbeddedNameLength = 24;
28 using EmbeddedName = std::array<char, kEmbeddedNameLength>; 50 using EmbeddedName = std::array<char, kEmbeddedNameLength>;
29 // depending on the name length, it is either embedded inside the Linda, or allocated separately 51 // depending on the name length, it is either embedded inside the Linda, or allocated separately
30 std::variant<std::string_view, EmbeddedName> nameVariant; 52 std::variant<std::string_view, EmbeddedName> nameVariant{};
53 // counts the keeper operations in progress
54 std::atomic<int> keeperOperationCount{};
31 55
32 public: 56 public:
33 std::condition_variable readHappened; 57 std::condition_variable readHappened{};
34 std::condition_variable writeHappened; 58 std::condition_variable writeHappened{};
35 Universe* const U{ nullptr }; // the universe this linda belongs to 59 Universe* const U{ nullptr }; // the universe this linda belongs to
36 int const keeperIndex{ -1 }; // the keeper associated to this linda 60 int const keeperIndex{ -1 }; // the keeper associated to this linda
37 CancelRequest cancelRequest{ CancelRequest::None }; 61 CancelRequest cancelRequest{ CancelRequest::None };
@@ -60,7 +84,9 @@ class Linda
60 public: 84 public:
61 [[nodiscard]] Keeper* acquireKeeper() const; 85 [[nodiscard]] Keeper* acquireKeeper() const;
62 [[nodiscard]] std::string_view getName() const; 86 [[nodiscard]] std::string_view getName() const;
87 [[nodiscard]] bool inKeeperOperation() const { return keeperOperationCount.load(std::memory_order_seq_cst) != 0; }
63 void releaseKeeper(Keeper* keeper_) const; 88 void releaseKeeper(Keeper* keeper_) const;
64 [[nodiscard]] static int ProtectedCall(lua_State* L_, lua_CFunction f_); 89 [[nodiscard]] static int ProtectedCall(lua_State* L_, lua_CFunction f_);
90 [[nodiscard]] KeeperOperationInProgress startKeeperOperation(lua_State* const L_) { return KeeperOperationInProgress{ *this, L_ }; };
65 [[nodiscard]] Keeper* whichKeeper() const { return U->keepers.getKeeper(keeperIndex); } 91 [[nodiscard]] Keeper* whichKeeper() const { return U->keepers.getKeeper(keeperIndex); }
66}; 92};