diff options
Diffstat (limited to 'src/linda.h')
-rw-r--r-- | src/linda.h | 32 |
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>; | |||
23 | class Linda | 23 | class 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 | }; |