made Add/Del User operations locking as to allow Saving to be thread safe

This commit is contained in:
EntireTwix 2021-04-02 14:57:11 -07:00
parent 8ebe23fa15
commit ea511c71b2
2 changed files with 21 additions and 6 deletions

View file

@ -15,11 +15,14 @@ private:
std::mutex> std::mutex>
users; users;
std::mutex size_users;
public: public:
std::string admin_pass; std::string admin_pass;
bool AddUser(const std::string &name, std::string &&init_pass) bool AddUser(const std::string &name, std::string &&init_pass)
{ {
std::unique_lock<std::mutex> lock{size_users};
return users.try_emplace_l( return users.try_emplace_l(
name, [](User &) {}, std::forward<std::string &&>(init_pass)); name, [](User &) {}, std::forward<std::string &&>(init_pass));
} }
@ -28,6 +31,7 @@ public:
bool state = (admin_pass == attempt); bool state = (admin_pass == attempt);
if (state) if (state)
{ {
std::unique_lock<std::mutex> lock{size_users};
state = users.try_emplace_l( state = users.try_emplace_l(
name, [](User &) {}, init_bal, std::forward<std::string &&>(init_pass)); name, [](User &) {}, init_bal, std::forward<std::string &&>(init_pass));
} }
@ -36,10 +40,12 @@ public:
bool DelUser(const std::string &name, const std::string &attempt) bool DelUser(const std::string &name, const std::string &attempt)
{ {
std::unique_lock<std::mutex> lock{size_users};
return users.erase_if(name, [&attempt](const User &u) { return (attempt == u.password); }); return users.erase_if(name, [&attempt](const User &u) { return (attempt == u.password); });
} }
bool AdminDelUser(const std::string &name, const std::string &attempt) bool AdminDelUser(const std::string &name, const std::string &attempt)
{ {
std::unique_lock<std::mutex> lock{size_users};
return users.erase_if(name, [this, &attempt](const User &) { return (admin_pass == attempt); }); return users.erase_if(name, [this, &attempt](const User &) { return (admin_pass == attempt); });
} }
@ -82,18 +88,21 @@ public:
return state; return state;
} }
//NOT THREAD SAFE, BY NO MEANS SHOULD THIS BE CALLED WHILE RECEIEVING REQUESTS void Save()
void Save() const
{ {
Json::StreamWriterBuilder builder; Json::StreamWriterBuilder builder;
const std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter()); const std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
std::ofstream user_save("users.json"); std::ofstream user_save("users.json");
Json::Value temp; Json::Value temp;
//this gets access to the parallel map with the size being constant
std::unique_lock<std::mutex> lock{size_users};
for (const auto &u : users) for (const auto &u : users)
{ {
std::cout << u.first << '\n'; //this gets read access to prevent writes
temp[u.first] = u.second.Serialize(); users.if_contains(u.first, [&temp, &u](const User &u_val) {
temp[u.first] = u_val.Serialize();
})
} }
writer->write(temp, &user_save); writer->write(temp, &user_save);
user_save.close(); user_save.close();

View file

@ -5,8 +5,14 @@
int main() int main()
{ {
Bank.Load(); std::thread([&]() {
Bank.SendFunds("0", "1", 50, "root"); 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(); Bank.Save();
std::this_thread::sleep_for(std::chrono::seconds(1));
return 0; return 0;
} }