//
// Created by 马也驰 on 2024/12/28.
//

#ifndef LEVELDB_SHARED_LOCK_H
#define LEVELDB_SHARED_LOCK_H

#include <mutex>

class SharedLock {
 public:
  SharedLock() : read_count_(0) {}

 public:
  void soft_lock() {
    write_latch_.lock();

    read_count_latch_.lock();
    if (!read_count_) {
      read_latch_.lock();
    }
    read_count_ ++;
    read_count_latch_.unlock();

    write_latch_.unlock();
  }
  void soft_unlock() {
    read_count_latch_.lock();
    read_count_ --;
    if (!read_count_) {
      read_latch_.unlock();
    }
    read_count_latch_.unlock();
  }
  void hard_lock() {
    read_latch_.lock();
    write_latch_.lock();
    read_latch_.unlock();
  }
  void hard_unlock() {
    write_latch_.unlock();
  }

 private:
  std::mutex read_latch_; // indicate if any read is proceeding
  std::mutex read_count_latch_;
  volatile size_t read_count_;
  std::mutex write_latch_;  // indicate if any write is proceeding
};

#endif  // LEVELDB_SHARED_LOCK_H
