From 447458ca25bef556a4347fc395b68da9a09a2a3b Mon Sep 17 00:00:00 2001 From: EntireTwix Date: Fri, 9 Apr 2021 02:16:50 -0700 Subject: [PATCH] :racehorse: reworked locking based on frequency of fucking called --- include/bank.hpp | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/include/bank.hpp b/include/bank.hpp index 768151a..81770b8 100644 --- a/include/bank.hpp +++ b/include/bank.hpp @@ -18,20 +18,23 @@ private: users; /** - * @brief any function that WRITES to users in a way that CHANGES its SIZE OR takes MORE THEN ONE OPERATION must share lock this lock - * as to be stopped when saving, as saving data must not be corrupted. one operation writes that done modify size aswell as reads are - * permitted while saving so they do not have to share this lock + * @brief size_lock should be grabbed if the operation MODIFIES the size (unique) or READS from the users where size changes could distort (shared) * */ std::shared_mutex size_lock; - std::shared_mutex bal_lock; + + /** + * @brief send_funds_l should be grabbed if balances are being MODIFIED (shared) or if an operation needs to READ without the intermediary states that sendfunds has (unique) + * + */ + std::shared_mutex send_funds_l; public: std::string admin_pass; bool AddUser(const std::string &name, std::string &&init_pass) { - std::shared_lock lock{size_lock}; + std::unique_lock lock{size_lock}; return users.try_emplace_l( name, [](User &) {}, std::move(init_pass)); } @@ -40,7 +43,7 @@ public: bool state = (admin_pass == attempt); if (state) { - std::shared_lock lock{size_lock}; + std::unique_lock lock{size_lock}; state = users.try_emplace_l( name, [](User &) {}, init_bal, std::move(init_pass)); } @@ -49,12 +52,12 @@ public: bool DelUser(const std::string &name, const std::string &attempt) { - std::shared_lock lock{size_lock}; + std::unique_lock lock{size_lock}; return users.erase_if(name, [&attempt](const User &u) { return (attempt == u.password); }); } bool AdminDelUser(const std::string &name, const std::string &attempt) { - std::shared_lock lock{size_lock}; + std::unique_lock lock{size_lock}; return users.erase_if(name, [this, &attempt](const User &) { return (admin_pass == attempt); }); } @@ -69,7 +72,7 @@ public: //if A exists, A can afford it, and A's password matches bool state = false; - std::shared_lock lock{bal_lock}; //because SendFunds requires 3 locking operations + std::shared_lock lock{send_funds_l}; //because SendFunds requires 3 locking operations users.modify_if(a_name, [&state, amount, &attempt](User &a) { if (state = (a.balance >= amount) && (a.password == attempt), state) { @@ -143,7 +146,7 @@ public: { Json::Value temp; Json::UInt i = 0; - std::unique_lock lock{size_lock}; + std::shared_lock lock{size_lock}; //gives readers of users the lock for (const auto &u : users) { //we know it contains this key but we call this func to grab mutex @@ -162,7 +165,8 @@ public: //loading info into json temp { - std::scoped_lock lock{size_lock, bal_lock}; //grabbing it from any busy add/del/sendfunds opperations + std::shared_lock lock{size_lock}; //gives readers of users the lock + std::unique_lock halt_funds{send_funds_l}; //halts all send fund requests for (const auto &u : users) { //we know it contains this key but we call this func to grab mutex