/**x2 * CSE 374 18sp example * A simple bank account class that we'll use to demonstrate proper * synchronization. */ #include #include "BankAccountThread.h" std::atomic BankAccount::accountCount_(0); BankAccount::BankAccount() : accountId_(++accountCount_), // initialize fields balance_(0) {} void BankAccount::withdraw(double amount) { std::lock_guard lock(m_); double b = getBalance(); if (amount > b) { throw std::invalid_argument("can't withdraw"); } setBalanceWithLock(b - amount); } void BankAccount::deposit(double amount) { std::lock_guard lock(m_); setBalanceWithLock(getBalance() + amount); } double BankAccount::getBalance() { std::lock_guard lock(m_); return balance_; } void BankAccount::setBalance(double balance) { std::lock_guard lock(m_); setBalanceWithLock(balance); // m is unlcoked at the lock guard is deconstructed off stack } void BankAccount::transferTo(double amount, BankAccount& other) { // We must lock the mutexes in a specific order to avoid a deadlock: smaller // account id first. std::mutex* first; std::mutex* second; if (accountId_ < other.accountId_) { first = &m_; second = &other.m_; } else { first = &other.m_; second = &m_; } std::lock_guard lock1(*first); std::lock_guard lock2(*second); if (getBalance() < amount) { throw std::invalid_argument("can't transfer, not enough funds"); } setBalanceWithLock(getBalance() - amount); other.setBalanceWithLock(other.getBalance() + amount); } void BankAccount::setBalanceWithLock(double amount) { balance_ = amount; } int main() { BankAccount my_account; // do not construct with my_account() BankAccount your_account; my_account.deposit (374.00); my_account.transferTo (374.00, your_account); // pass by reference std::cout << "Now you have " << your_account.getBalance() << std::endl; return 0; }