GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/util/mutex.h
Date: 2024-04-21 02:33:16
Exec Total Coverage
Lines: 20 20 100.0%
Branches: 0 0 -%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #ifndef CVMFS_UTIL_MUTEX_H_
6 #define CVMFS_UTIL_MUTEX_H_
7
8 #include <pthread.h>
9
10 #include "util/single_copy.h"
11
12 #ifdef CVMFS_NAMESPACE_GUARD
13 namespace CVMFS_NAMESPACE_GUARD {
14 #endif
15
16 /**
17 * Used to allow for static polymorphism in the RAII template to statically
18 * decide which 'lock' functions to use, if we have more than one possibility.
19 * (I.e. Read/Write locks)
20 * Note: Static Polymorphism - Strategy Pattern
21 *
22 * TODO(jblomer): eventually replace this by C++11 typed enum
23 */
24 struct RAII_Polymorphism {
25 enum T {
26 None,
27 ReadLock,
28 WriteLock
29 };
30 };
31
32
33 /**
34 * Basic template wrapper class for any kind of RAII-like behavior.
35 * The user is supposed to provide a template specialization of Enter() and
36 * Leave(). On creation of the RAII object it will call Enter() respectively
37 * Leave() on destruction. The gold standard example is a LockGard (see below).
38 *
39 * Note: Resource Acquisition Is Initialization (Bjarne Stroustrup)
40 */
41 template <typename T, RAII_Polymorphism::T P = RAII_Polymorphism::None>
42 class RAII : SingleCopy {
43 public:
44 149679056 inline explicit RAII(T &object) : ref_(object) { Enter(); }
45 10461813 inline explicit RAII(T *object) : ref_(*object) { Enter(); }
46 163665931 inline ~RAII() { Leave(); }
47
48 protected:
49 4 inline void Enter() { ref_.Lock(); }
50 2 inline void Leave() { ref_.Unlock(); }
51
52 private:
53 T &ref_;
54 };
55
56
57 /**
58 * This is a simple scoped lock implementation. Every object that provides the
59 * methods Lock() and Unlock() should work with it. Classes that will be used
60 * with this template should therefore simply inherit from Lockable.
61 *
62 * Creating a LockGuard object on the stack will lock the provided object. When
63 * the LockGuard runs out of scope it will automatically release the lock. This
64 * ensures a clean unlock in a lot of situations!
65 *
66 * TODO(jblomer): C++11 replace this by a type alias to RAII
67 */
68 template <typename LockableT>
69 class LockGuard : public RAII<LockableT> {
70 public:
71 4 inline explicit LockGuard(LockableT *object) : RAII<LockableT>(object) {}
72 };
73
74
75 template <>
76 155050942 inline void RAII<pthread_mutex_t>::Enter() { pthread_mutex_lock(&ref_); }
77 template <>
78 159892333 inline void RAII<pthread_mutex_t>::Leave() { pthread_mutex_unlock(&ref_); }
79 typedef RAII<pthread_mutex_t> MutexLockGuard;
80
81
82 template <>
83 1086129 inline void RAII<pthread_rwlock_t,
84 RAII_Polymorphism::ReadLock>::Enter() {
85 1086129 pthread_rwlock_rdlock(&ref_);
86 1086580 }
87 template <>
88 1086350 inline void RAII<pthread_rwlock_t,
89 RAII_Polymorphism::ReadLock>::Leave() {
90 1086350 pthread_rwlock_unlock(&ref_);
91 1086577 }
92 template <>
93 598819 inline void RAII<pthread_rwlock_t,
94 RAII_Polymorphism::WriteLock>::Enter() {
95 598819 pthread_rwlock_wrlock(&ref_);
96 598899 }
97 template <>
98 598738 inline void RAII<pthread_rwlock_t,
99 RAII_Polymorphism::WriteLock>::Leave() {
100 598738 pthread_rwlock_unlock(&ref_);
101 598895 }
102 typedef RAII<pthread_rwlock_t, RAII_Polymorphism::ReadLock> ReadLockGuard;
103 typedef RAII<pthread_rwlock_t, RAII_Polymorphism::WriteLock> WriteLockGuard;
104
105 #ifdef CVMFS_NAMESPACE_GUARD
106 } // namespace CVMFS_NAMESPACE_GUARD
107 #endif
108
109 #endif // CVMFS_UTIL_MUTEX_H_
110