OmniSciDB  c0231cc57d
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RWLocks.h
Go to the documentation of this file.
1 /*
2  * Copyright 2022 HEAVY.AI, 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 #ifndef RW_LOCKS_H
18 #define RW_LOCKS_H
19 
22 
23 namespace Catalog_Namespace {
24 
25 /*
26  * The locking sequence for the locks below is as follows:
27  *
28  * inter catalog / syscatalog it is always
29  *
30  * read or write lock, then the sqlite_lock (if required)
31  *
32  * intra catalog and syscatalog
33  *
34  * always syscatalog locks (if required), then catalog locks
35  */
36 
37 template <typename T>
38 class read_lock {
39  const T* catalog;
42  bool holds_lock;
43 
44  template <typename inner_type>
45  void lock_catalog(const inner_type* cat) {
46  std::thread::id tid = std::this_thread::get_id();
47 
48  if (cat->thread_holding_write_lock != tid && !inner_type::thread_holds_read_lock) {
49  if (!g_multi_instance) {
51  } else {
52  dlock =
54  }
55  inner_type::thread_holds_read_lock = true;
56  holds_lock = true;
57  }
58  }
59 
60  public:
61  read_lock(const T* cat) : catalog(cat), holds_lock(false) { lock_catalog(cat); }
62 
63  ~read_lock() { unlock(); }
64 
65  void unlock() {
66  if (holds_lock) {
67  T::thread_holds_read_lock = false;
68  if (!g_multi_instance) {
69  lock.unlock();
70  } else {
71  dlock.unlock();
72  }
73  holds_lock = false;
74  }
75  }
76 };
77 
78 template <typename T>
79 class sqlite_lock {
80  // always obtain a read lock on catalog first
81  // to ensure correct locking order
83  const T* catalog;
86  bool holds_lock;
87 
88  template <typename inner_type>
89  void lock_catalog(const inner_type* cat) {
90  std::thread::id tid = std::this_thread::get_id();
91 
92  if (cat->thread_holding_sqlite_lock != tid) {
93  if (!g_multi_instance) {
94  lock = heavyai::unique_lock<std::mutex>(cat->sqliteMutex_);
95  } else {
96  dlock =
98  }
99  cat->thread_holding_sqlite_lock = tid;
100  holds_lock = true;
101  }
102  }
103 
104  public:
106  lock_catalog(cat);
107  }
108 
110 
111  void unlock() {
112  if (holds_lock) {
113  std::thread::id no_thread;
114  catalog->thread_holding_sqlite_lock = no_thread;
115  if (!g_multi_instance) {
116  lock.unlock();
117  } else {
118  dlock.unlock();
119  }
121  holds_lock = false;
122  }
123  }
124 };
125 
126 template <typename T>
127 class write_lock {
128  const T* catalog;
132 
133  template <typename inner_type>
134  void lock_catalog(const inner_type* cat) {
135  std::thread::id tid = std::this_thread::get_id();
136 
137  if (cat->thread_holding_write_lock != tid) {
138  if (!g_multi_instance) {
140  } else {
141  dlock =
143  }
144  cat->thread_holding_write_lock = tid;
145  holds_lock = true;
146  }
147  }
148 
149  public:
150  write_lock(const T* cat) : catalog(cat), holds_lock(false) { lock_catalog(cat); }
151 
153 
154  void unlock() {
155  if (holds_lock) {
156  std::thread::id no_thread;
157  catalog->thread_holding_write_lock = no_thread;
158  if (!g_multi_instance) {
159  lock.unlock();
160  } else {
161  dlock.unlock();
162  }
163  holds_lock = false;
164  }
165  }
166 };
167 
168 } // namespace Catalog_Namespace
169 
170 #endif // RW_LOCKS_H
bool g_multi_instance
Definition: heavyai_locks.h:21
std::string cat(Ts &&...args)
void lock_catalog(const inner_type *cat)
Definition: RWLocks.h:134
std::shared_lock< T > shared_lock
write_lock(const T *cat)
Definition: RWLocks.h:150
heavyai::unique_lock< heavyai::DistributedSharedMutex > dlock
Definition: RWLocks.h:130
read_lock(const T *cat)
Definition: RWLocks.h:61
std::unique_lock< T > unique_lock
heavyai::shared_lock< heavyai::DistributedSharedMutex > dlock
Definition: RWLocks.h:41
heavyai::unique_lock< heavyai::shared_mutex > lock
Definition: RWLocks.h:129
read_lock< T > cat_read_lock
Definition: RWLocks.h:82
void lock_catalog(const inner_type *cat)
Definition: RWLocks.h:45
bool g_enable_watchdog false
Definition: Execute.cpp:79
heavyai::unique_lock< heavyai::DistributedSharedMutex > dlock
Definition: RWLocks.h:85
heavyai::shared_lock< heavyai::shared_mutex > lock
Definition: RWLocks.h:40
heavyai::unique_lock< std::mutex > lock
Definition: RWLocks.h:84
void lock_catalog(const inner_type *cat)
Definition: RWLocks.h:89