ba_externallly_locked.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. // Copyright (C) 2012 Vicente Botet
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #define BOOST_THREAD_VERSION 4
  6. #include <boost/thread/mutex.hpp>
  7. #include <boost/thread/lockable_adapter.hpp>
  8. #include <boost/thread/externally_locked.hpp>
  9. #include <boost/thread/strict_lock.hpp>
  10. #include <boost/thread/lock_types.hpp>
  11. #include <iostream>
  12. #ifdef BOOST_MSVC
  13. # pragma warning(disable: 4355) // 'this' : used in base member initializer list
  14. #endif
  15. using namespace boost;
  16. class BankAccount
  17. {
  18. int balance_;
  19. public:
  20. void Deposit(int amount)
  21. {
  22. balance_ += amount;
  23. }
  24. void Withdraw(int amount)
  25. {
  26. balance_ -= amount;
  27. }
  28. int GetBalance()
  29. {
  30. return balance_;
  31. }
  32. };
  33. //[AccountManager
  34. class AccountManager: public basic_lockable_adapter<mutex>
  35. {
  36. public:
  37. typedef basic_lockable_adapter<mutex> lockable_base_type;
  38. AccountManager() :
  39. lockable_base_type(), checkingAcct_(*this), savingsAcct_(*this)
  40. {
  41. }
  42. inline void Checking2Savings(int amount);
  43. inline void AMoreComplicatedChecking2Savings(int amount);
  44. private:
  45. /*<-*/
  46. bool some_condition()
  47. {
  48. return true;
  49. } /*->*/
  50. externally_locked<BankAccount, AccountManager > checkingAcct_;
  51. externally_locked<BankAccount, AccountManager > savingsAcct_;
  52. };
  53. //]
  54. //[Checking2Savings
  55. void AccountManager::Checking2Savings(int amount)
  56. {
  57. strict_lock<AccountManager> guard(*this);
  58. checkingAcct_.get(guard).Withdraw(amount);
  59. savingsAcct_.get(guard).Deposit(amount);
  60. }
  61. //]
  62. //#if DO_NOT_COMPILE
  63. ////[AMoreComplicatedChecking2Savings_DO_NOT_COMPILE
  64. //void AccountManager::AMoreComplicatedChecking2Savings(int amount) {
  65. // unique_lock<AccountManager> guard(*this);
  66. // if (some_condition()) {
  67. // guard.lock();
  68. // }
  69. // checkingAcct_.get(guard).Withdraw(amount);
  70. // savingsAcct_.get(guard).Deposit(amount);
  71. // guard1.unlock();
  72. //}
  73. ////]
  74. //#elif DO_NOT_COMPILE_2
  75. ////[AMoreComplicatedChecking2Savings_DO_NOT_COMPILE2
  76. //void AccountManager::AMoreComplicatedChecking2Savings(int amount) {
  77. // unique_lock<AccountManager> guard1(*this);
  78. // if (some_condition()) {
  79. // guard1.lock();
  80. // }
  81. // {
  82. // strict_lock<AccountManager> guard(guard1);
  83. // checkingAcct_.get(guard).Withdraw(amount);
  84. // savingsAcct_.get(guard).Deposit(amount);
  85. // }
  86. // guard1.unlock();
  87. //}
  88. ////]
  89. //#else
  90. ////[AMoreComplicatedChecking2Savings
  91. void AccountManager::AMoreComplicatedChecking2Savings(int amount) {
  92. unique_lock<AccountManager> guard1(*this);
  93. if (some_condition()) {
  94. guard1.lock();
  95. }
  96. {
  97. nested_strict_lock<unique_lock<AccountManager> > guard(guard1);
  98. checkingAcct_.get(guard).Withdraw(amount);
  99. savingsAcct_.get(guard).Deposit(amount);
  100. }
  101. guard1.unlock();
  102. }
  103. ////]
  104. //#endif
  105. int main()
  106. {
  107. AccountManager mgr;
  108. mgr.Checking2Savings(100);
  109. return 0;
  110. }