2015-12-06 23:42:47 +08:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <memory>
|
2016-08-30 22:12:30 +08:00
|
|
|
#include <vector>
|
2016-01-03 05:20:09 +08:00
|
|
|
#include "storage/locking/lock_status.hpp"
|
2017-09-27 20:02:24 +08:00
|
|
|
#include "storage/locking/record_lock.hpp"
|
|
|
|
#include "transactions/type.hpp"
|
2017-02-24 17:15:18 +08:00
|
|
|
#include "utils/assert.hpp"
|
2015-12-06 23:42:47 +08:00
|
|
|
|
2017-02-18 18:54:37 +08:00
|
|
|
namespace tx {
|
2015-12-06 23:42:47 +08:00
|
|
|
|
2017-09-27 20:02:24 +08:00
|
|
|
class Engine;
|
|
|
|
class Transaction;
|
|
|
|
|
2017-02-18 18:54:37 +08:00
|
|
|
class LockStore {
|
|
|
|
class LockHolder {
|
|
|
|
public:
|
2017-07-28 22:15:24 +08:00
|
|
|
LockHolder() = default;
|
2017-02-18 18:54:37 +08:00
|
|
|
|
2017-09-27 20:02:24 +08:00
|
|
|
LockHolder(RecordLock *lock, const Transaction &tx, tx::Engine &engine)
|
|
|
|
: lock_(lock) {
|
2017-02-24 17:15:18 +08:00
|
|
|
debug_assert(lock != nullptr, "Lock is nullptr.");
|
2017-09-27 20:02:24 +08:00
|
|
|
auto status = lock_->Lock(tx, engine);
|
2015-12-06 23:42:47 +08:00
|
|
|
|
2017-07-28 22:15:24 +08:00
|
|
|
if (status != LockStatus::Acquired) {
|
|
|
|
lock_ = nullptr;
|
|
|
|
}
|
2017-02-18 18:54:37 +08:00
|
|
|
}
|
2015-12-06 23:42:47 +08:00
|
|
|
|
2017-02-18 18:54:37 +08:00
|
|
|
LockHolder(const LockHolder &) = delete;
|
2017-07-28 22:15:24 +08:00
|
|
|
LockHolder &operator=(const LockHolder &) = delete;
|
|
|
|
|
|
|
|
LockHolder(LockHolder &&other) : lock_(other.lock_) {
|
|
|
|
other.lock_ = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
LockHolder &operator=(LockHolder &&other) {
|
|
|
|
if (this == &other) return *this;
|
|
|
|
lock_ = other.lock_;
|
|
|
|
other.lock_ = nullptr;
|
2017-09-27 20:02:24 +08:00
|
|
|
return *this;
|
2015-12-06 23:42:47 +08:00
|
|
|
}
|
|
|
|
|
2017-02-18 18:54:37 +08:00
|
|
|
~LockHolder() {
|
2017-07-28 22:15:24 +08:00
|
|
|
if (lock_ != nullptr) {
|
|
|
|
lock_->Unlock();
|
|
|
|
}
|
2017-02-18 18:54:37 +08:00
|
|
|
}
|
|
|
|
|
2017-07-28 22:15:24 +08:00
|
|
|
bool active() const { return lock_ != nullptr; }
|
2017-02-18 18:54:37 +08:00
|
|
|
|
|
|
|
private:
|
2017-09-27 20:02:24 +08:00
|
|
|
RecordLock *lock_{nullptr};
|
2017-02-18 18:54:37 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
public:
|
2017-09-27 20:02:24 +08:00
|
|
|
void Take(RecordLock *lock, const tx::Transaction &tx, tx::Engine &engine) {
|
|
|
|
locks_.emplace_back(LockHolder(lock, tx, engine));
|
2017-07-28 22:15:24 +08:00
|
|
|
if (!locks_.back().active()) {
|
|
|
|
locks_.pop_back();
|
2017-03-22 21:19:10 +08:00
|
|
|
}
|
2017-02-18 18:54:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2017-07-28 22:15:24 +08:00
|
|
|
std::vector<LockHolder> locks_;
|
2015-12-06 23:42:47 +08:00
|
|
|
};
|
2017-07-28 22:15:24 +08:00
|
|
|
}
|