Advertisement
Guest User

Untitled

a guest
Sep 5th, 2016
176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.01 KB | None | 0 0
  1. //Mutex for readers-writers locking.
  2. //Simultaneously can work some readers or one writer.
  3. //If there are no write requests, readers can work and be added.
  4. //If there are write requests, readers can work, but can't be added.
  5. //If there are no readers or writers, read and write requests will be executed concurrently
  6. class RWLocker final
  7. {
  8.     mutable std::mutex general_lock_;
  9.     mutable std::mutex write_lock_;
  10.     mutable std::mutex read_lock_;
  11.  
  12.     mutable std::size_t number_of_readers_ = 0;
  13.  
  14.     RWLocker (const RWLocker &) = delete;
  15.     RWLocker & operator= (const RWLocker &) = delete;
  16.  
  17.     RWLocker () = default;
  18.  
  19.     //Only read and write abstractions can work with RWLocker
  20.     friend class ReadGuard;
  21.     friend class WriteGuard;
  22. };
  23.  
  24. class WriteGuard final
  25. {
  26.     const RWLocker & locker_;
  27.  
  28.     WriteGuard (const WriteGuard &) = delete;
  29.     WriteGuard & operator= (const WriteGuard &) = delete;
  30.  
  31. public:
  32.  
  33.     //Strong exception guarantee
  34.     explicit WriteGuard (const RWLocker & input_lock) :
  35.         locker_ { input_lock }
  36.     {
  37.         locker_.general_lock_.lock ();
  38.         locker_.write_lock_.lock ();
  39.         locker_.general_lock_.unlock ();
  40.     }
  41.  
  42.     ~WriteGuard ()
  43.     {
  44.         //Anyway UB if unlock fails
  45.         locker_.write_lock_.unlock (); 
  46.     }
  47. };
  48.  
  49. class ReadGuard final
  50. {
  51.     const RWLocker & locker_;
  52.  
  53.     ReadGuard (const ReadGuard &) = delete;
  54.     ReadGuard & operator= (const ReadGuard &) = delete;
  55.  
  56. public:
  57.  
  58.     //Strong exception guarantee
  59.     explicit ReadGuard (const RWLocker & input_lock) :
  60.         locker_ { input_lock }
  61.     {
  62.         locker_.general_lock_.lock ();
  63.         locker_.read_lock_.lock ();
  64.         locker_.general_lock_.unlock ();
  65.  
  66.         if (0 < ++locker_.number_of_readers_)
  67.             locker_.write_lock_.lock ();
  68.  
  69.         locker_.read_lock_.unlock ();
  70.     }
  71.  
  72.     ~ReadGuard ()
  73.     {
  74.         ErrorMaster::getInstance ().runUntilSuccess ("ReadGuard::~ReadGuard () noexcept border",
  75.                                                      [=]
  76.         {
  77.             locker_.read_lock_.lock ();
  78.         });
  79.            
  80.         //Anyway UB if unlock fails
  81.         if (1 > --locker_.number_of_readers_)
  82.             locker_.write_lock_.unlock ();
  83.  
  84.         locker_.read_lock_.unlock ();
  85.     }
  86. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement