OmniSciDB  340b00dbf6
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RWLocks.h
Go to the documentation of this file.
1 /*
2  * Copyright 2019 MapD Technologies, 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 
20 #include "../Shared/mapd_shared_mutex.h"
21 
22 namespace Catalog_Namespace {
23 
24 /*
25  * The locking sequence for the locks below is as follows:
26  *
27  * inter catalog / syscatalog it is always
28  *
29  * read or write lock, then the sqlite_lock (if required)
30  *
31  * intra catalog and syscatalog
32  *
33  * always syscatalog locks (if required), then catalog locks
34  */
35 
36 template <typename T>
37 class read_lock {
38  const T* catalog;
39  mapd_shared_lock<mapd_shared_mutex> lock;
40  bool holds_lock;
41 
42  template <typename inner_type>
43  void lock_catalog(const inner_type* cat) {
44  std::thread::id tid = std::this_thread::get_id();
45 
46  if (cat->thread_holding_write_lock != tid && !inner_type::thread_holds_read_lock) {
47  lock = mapd_shared_lock<mapd_shared_mutex>(cat->sharedMutex_);
48  inner_type::thread_holds_read_lock = true;
49  holds_lock = true;
50  }
51  }
52 
53  public:
54  read_lock(const T* cat) : catalog(cat), holds_lock(false) { lock_catalog(cat); }
55 
56  ~read_lock() { unlock(); }
57 
58  void unlock() {
59  if (holds_lock) {
60  T::thread_holds_read_lock = false;
61  lock.unlock();
62  holds_lock = false;
63  }
64  }
65 };
66 
67 template <typename T>
68 class sqlite_lock {
69  // always obtain a read lock on catalog first
70  // to ensure correct locking order
72  const T* catalog;
73  std::unique_lock<std::mutex> lock;
74  bool holds_lock;
75 
76  template <typename inner_type>
77  void lock_catalog(const inner_type* cat) {
78  std::thread::id tid = std::this_thread::get_id();
79 
80  if (cat->thread_holding_sqlite_lock != tid) {
81  lock = std::unique_lock<std::mutex>(cat->sqliteMutex_);
82  cat->thread_holding_sqlite_lock = tid;
83  holds_lock = true;
84  }
85  }
86 
87  public:
89  lock_catalog(cat);
90  }
91 
93 
94  void unlock() {
95  if (holds_lock) {
96  std::thread::id no_thread;
97  catalog->thread_holding_sqlite_lock = no_thread;
98  lock.unlock();
100  holds_lock = false;
101  }
102  }
103 };
104 
105 template <typename T>
106 class write_lock {
107  const T* catalog;
108  mapd_unique_lock<mapd_shared_mutex> lock;
110 
111  template <typename inner_type>
112  void lock_catalog(const inner_type* cat) {
113  std::thread::id tid = std::this_thread::get_id();
114 
115  if (cat->thread_holding_write_lock != tid) {
116  lock = mapd_unique_lock<mapd_shared_mutex>(cat->sharedMutex_);
117  cat->thread_holding_write_lock = tid;
118  holds_lock = true;
119  }
120  }
121 
122  public:
123  write_lock(const T* cat) : catalog(cat), holds_lock(false) { lock_catalog(cat); }
124 
126 
127  void unlock() {
128  if (holds_lock) {
129  std::thread::id no_thread;
130  catalog->thread_holding_write_lock = no_thread;
131  lock.unlock();
132  holds_lock = false;
133  }
134  }
135 };
136 
137 } // namespace Catalog_Namespace
138 
139 #endif // RW_LOCKS_H
std::string cat(Ts &&...args)
void lock_catalog(const inner_type *cat)
Definition: RWLocks.h:112
mapd_unique_lock< mapd_shared_mutex > lock
Definition: RWLocks.h:108
write_lock(const T *cat)
Definition: RWLocks.h:123
sqlite_lock(const T *cat)
Definition: RWLocks.h:88
mapd_shared_lock< mapd_shared_mutex > lock
Definition: RWLocks.h:39
read_lock(const T *cat)
Definition: RWLocks.h:54
std::unique_lock< std::mutex > lock
Definition: RWLocks.h:73
read_lock< T > cat_read_lock
Definition: RWLocks.h:71
void lock_catalog(const inner_type *cat)
Definition: RWLocks.h:43
bool g_enable_watchdog false
Definition: Execute.cpp:73
void lock_catalog(const inner_type *cat)
Definition: RWLocks.h:77