diff --git a/include/bank.hpp b/include/bank.hpp index c53c7f1..ea4f24b 100644 --- a/include/bank.hpp +++ b/include/bank.hpp @@ -15,11 +15,14 @@ private: std::mutex> users; + std::mutex size_users; + public: std::string admin_pass; bool AddUser(const std::string &name, std::string &&init_pass) { + std::unique_lock lock{size_users}; return users.try_emplace_l( name, [](User &) {}, std::forward(init_pass)); } @@ -28,6 +31,7 @@ public: bool state = (admin_pass == attempt); if (state) { + std::unique_lock lock{size_users}; state = users.try_emplace_l( name, [](User &) {}, init_bal, std::forward(init_pass)); } @@ -36,10 +40,12 @@ public: bool DelUser(const std::string &name, const std::string &attempt) { + std::unique_lock lock{size_users}; return users.erase_if(name, [&attempt](const User &u) { return (attempt == u.password); }); } bool AdminDelUser(const std::string &name, const std::string &attempt) { + std::unique_lock lock{size_users}; return users.erase_if(name, [this, &attempt](const User &) { return (admin_pass == attempt); }); } @@ -82,18 +88,21 @@ public: return state; } - //NOT THREAD SAFE, BY NO MEANS SHOULD THIS BE CALLED WHILE RECEIEVING REQUESTS - void Save() const + void Save() { Json::StreamWriterBuilder builder; const std::unique_ptr writer(builder.newStreamWriter()); std::ofstream user_save("users.json"); Json::Value temp; + //this gets access to the parallel map with the size being constant + std::unique_lock lock{size_users}; for (const auto &u : users) { - std::cout << u.first << '\n'; - temp[u.first] = u.second.Serialize(); + //this gets read access to prevent writes + users.if_contains(u.first, [&temp, &u](const User &u_val) { + temp[u.first] = u_val.Serialize(); + }) } writer->write(temp, &user_save); user_save.close(); diff --git a/main.cpp b/main.cpp index 1ebf72f..9906fdf 100644 --- a/main.cpp +++ b/main.cpp @@ -5,8 +5,14 @@ int main() { - Bank.Load(); - Bank.SendFunds("0", "1", 50, "root"); + std::thread([&]() { + for (int i = 0; i < 10000; ++i) + { + Bank.AddUser(std::to_string(i), "root"); + } + }).detach(); + std::this_thread::sleep_for(std::chrono::nanoseconds(10)); Bank.Save(); + std::this_thread::sleep_for(std::chrono::seconds(1)); return 0; } \ No newline at end of file