OmniSciDB  06b3bd477c
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
LockMgrImpl.h
Go to the documentation of this file.
1 /*
2  * Copyright 2020 OmniSci, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <atomic>
20 #include <map>
21 #include <memory>
22 #include <string>
23 #include <type_traits>
24 
25 #include "Catalog/Catalog.h"
27 #include "Shared/types.h"
28 
29 namespace lockmgr {
30 
32 
33 using WriteLockBase = mapd_unique_lock<MutexTypeBase>;
34 using ReadLockBase = mapd_shared_lock<MutexTypeBase>;
35 
36 class MutexTracker {
37  public:
39 
41  ref_count_.fetch_add(1u);
42  return mutex_;
43  }
44 
45  void release() {
46  const auto stored_ref_count = ref_count_.fetch_sub(1u);
47  CHECK_GE(stored_ref_count, size_t(1));
48  }
49 
50  bool isAcquired() const { return ref_count_.load() > 0; }
51 
52  private:
53  std::atomic<size_t> ref_count_;
55 };
56 
57 template <typename LOCK>
59  public:
61 
63  if (mutex_) {
64  // This call only decrements the ref count. The actual unlock is done once the
65  // lock is destroyed.
66  mutex_->release();
67  }
68  }
69 
71  : mutex_(other.mutex_), lock_(std::move(other.lock_)) {
72  other.mutex_ = nullptr;
73  }
74 
75  TrackedRefLock(const TrackedRefLock&) = delete;
76  TrackedRefLock& operator=(const TrackedRefLock&) = delete;
77 
78  private:
80  LOCK lock_;
81 }; // namespace lockmgr
82 
84 
87 
88 template <typename T>
90  public:
91  virtual T operator()() const = 0;
92 
94 };
95 
96 template <typename T, typename LOCK>
98  public:
99  T operator()() const final { return obj_; }
100 
101  protected:
102  LockContainerImpl(T obj, LOCK&& lock) : obj_(obj), lock_(std::move(lock)) {}
103 
104  T obj_;
105  LOCK lock_;
106 };
107 
108 namespace helpers {
110  const std::string& tableName);
111 
112 template <typename LOCK_TYPE, typename LOCK_MGR_TYPE>
113 LOCK_TYPE getLockForKeyImpl(const ChunkKey& chunk_key) {
114  auto& table_lock_mgr = LOCK_MGR_TYPE::instance();
115  return LOCK_TYPE(table_lock_mgr.getTableMutex(chunk_key));
116 }
117 
118 template <typename LOCK_TYPE, typename LOCK_MGR_TYPE>
120  const std::string& table_name) {
121  const auto chunk_key = chunk_key_for_table(cat, table_name);
122 
123  auto& table_lock_mgr = LOCK_MGR_TYPE::instance();
124  return LOCK_TYPE(table_lock_mgr.getTableMutex(chunk_key));
125 }
126 
127 } // namespace helpers
128 
129 template <class T>
131  public:
132  MutexType* getTableMutex(const ChunkKey table_key) {
133  std::lock_guard<std::mutex> access_map_lock(map_mutex_);
134  auto mutex_it = table_mutex_map_.find(table_key);
135  if (mutex_it == table_mutex_map_.end()) {
136  table_mutex_map_.insert(std::make_pair(table_key, std::make_unique<MutexType>()));
137  } else {
138  return mutex_it->second.get();
139  }
140  return table_mutex_map_[table_key].get();
141  }
142 
143  std::set<ChunkKey> getLockedTables() const {
144  std::set<ChunkKey> ret;
145  std::lock_guard<std::mutex> access_map_lock(map_mutex_);
146  for (const auto& kv : table_mutex_map_) {
147  if (kv.second->isAcquired()) {
148  ret.insert(kv.first);
149  }
150  }
151 
152  return ret;
153  }
154 
156  const std::string& table_name) {
157  return helpers::getLockForTableImpl<WriteLock, T>(cat, table_name);
158  }
159  static WriteLock getWriteLockForTable(const ChunkKey table_key) {
160  auto& table_lock_mgr = T::instance();
161  return WriteLock(table_lock_mgr.getTableMutex(table_key));
162  }
163 
165  const std::string& table_name) {
166  return helpers::getLockForTableImpl<ReadLock, T>(cat, table_name);
167  }
168  static ReadLock getReadLockForTable(const ChunkKey table_key) {
169  auto& table_lock_mgr = T::instance();
170  return ReadLock(table_lock_mgr.getTableMutex(table_key));
171  }
172 
173  protected:
175 
176  mutable std::mutex map_mutex_;
177  std::map<ChunkKey, std::unique_ptr<MutexType>> table_mutex_map_;
178 };
179 
180 template <typename T>
181 std::ostream& operator<<(std::ostream& os, const TableLockMgrImpl<T>& lock_mgr) {
182  for (const auto& table_key : lock_mgr.getLockedTables()) {
183  for (const auto& k : table_key) {
184  os << k << " ";
185  }
186  os << "\n";
187  }
188  return os;
189 }
190 
191 } // namespace lockmgr
MutexTypeBase mutex_
Definition: LockMgrImpl.h:54
std::vector< int > ChunkKey
Definition: types.h:35
static ReadLock getReadLockForTable(const Catalog_Namespace::Catalog &cat, const std::string &table_name)
Definition: LockMgrImpl.h:164
std::string cat(Ts &&...args)
mapd_shared_mutex MutexTypeBase
Definition: LockMgrImpl.h:31
class for a per-database catalog. also includes metadata for the current database and the current use...
Definition: Catalog.h:86
static WriteLock getWriteLockForTable(const Catalog_Namespace::Catalog &cat, const std::string &table_name)
Definition: LockMgrImpl.h:155
std::map< ChunkKey, std::unique_ptr< MutexType > > table_mutex_map_
Definition: LockMgrImpl.h:177
#define CHECK_GE(x, y)
Definition: Logger.h:210
mapd_shared_lock< MutexTypeBase > ReadLockBase
Definition: LockMgrImpl.h:34
std::set< ChunkKey > getLockedTables() const
Definition: LockMgrImpl.h:143
static WriteLock getWriteLockForTable(const ChunkKey table_key)
Definition: LockMgrImpl.h:159
LOCK_TYPE getLockForKeyImpl(const ChunkKey &chunk_key)
Definition: LockMgrImpl.h:113
T operator()() const final
Definition: LockMgrImpl.h:99
This file contains the class specification and related data structures for Catalog.
TrackedRefLock< WriteLockBase > WriteLock
Definition: LockMgrImpl.h:85
TrackedRefLock< ReadLockBase > ReadLock
Definition: LockMgrImpl.h:86
CHECK(cgen_state)
virtual T operator()() const =0
std::shared_timed_mutex mapd_shared_mutex
static ReadLock getReadLockForTable(const ChunkKey table_key)
Definition: LockMgrImpl.h:168
bool isAcquired() const
Definition: LockMgrImpl.h:50
mapd_unique_lock< MutexTypeBase > WriteLockBase
Definition: LockMgrImpl.h:33
ChunkKey chunk_key_for_table(const Catalog_Namespace::Catalog &cat, const std::string &tableName)
Definition: LockMgr.cpp:32
TrackedRefLock(MutexTracker *m)
Definition: LockMgrImpl.h:60
LOCK_TYPE getLockForTableImpl(const Catalog_Namespace::Catalog &cat, const std::string &table_name)
Definition: LockMgrImpl.h:119
MutexTracker * mutex_
Definition: LockMgrImpl.h:79
TrackedRefLock(TrackedRefLock &&other)
Definition: LockMgrImpl.h:70
std::atomic< size_t > ref_count_
Definition: LockMgrImpl.h:53
TrackedRefLock & operator=(const TrackedRefLock &)=delete
MutexType * getTableMutex(const ChunkKey table_key)
Definition: LockMgrImpl.h:132
LockContainerImpl(T obj, LOCK &&lock)
Definition: LockMgrImpl.h:102
MutexTypeBase & acquire()
Definition: LockMgrImpl.h:40