GCC Code Coverage Report


Directory: ./
File: pdserv/src/PThread.h
Date: 2023-11-12 04:06:57
Exec Total Coverage
Lines: 35 48 72.9%
Branches: 5 10 50.0%

Line Branch Exec Source
1 /*****************************************************************************
2 *
3 * $Id$
4 *
5 * Copyright 2017 Richard Hacker (lerichi at gmx dot net)
6 *
7 * This file is part of the pdserv library.
8 *
9 * The pdserv library is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation, either version 3 of the License, or (at
12 * your option) any later version.
13 *
14 * The pdserv library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 * License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with the pdserv library. If not, see <http://www.gnu.org/licenses/>.
21 *
22 *****************************************************************************/
23
24 #ifndef PTHREAD_H
25 #define PTHREAD_H
26
27 #include <pthread.h>
28 #include <stdexcept>
29
30 namespace pthread {
31
32 //////////////////////////////////////////////////////////////////////
33 class RWLock {
34 public:
35 RWLock();
36 ~RWLock();
37
38 70 void writelock() {
39
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 70 times.
70 pthread_rwlock_wrlock(&lock);
40 70 }
41
42 6674 void readlock() {
43
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6674 times.
6674 pthread_rwlock_rdlock(&lock);
44 6674 }
45
46 6744 void unlock() {
47
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6744 times.
6744 pthread_rwlock_unlock(&lock);
48 6744 }
49
50 private:
51 pthread_rwlock_t lock;
52 };
53
54 class ReadLock {
55 public:
56 6674 ReadLock(RWLock &l): lock(l) {
57 6674 lock.readlock();
58 6674 }
59
60 13348 ~ReadLock() {
61 6674 lock.unlock();
62 6674 }
63
64 private:
65 RWLock &lock;
66 };
67
68 class WriteLock {
69 public:
70 70 WriteLock(RWLock &l): lock(l) {
71 70 lock.writelock();
72 70 }
73
74 140 ~WriteLock() {
75 70 lock.unlock();
76 70 }
77
78 private:
79 RWLock &lock;
80 };
81
82
83 //////////////////////////////////////////////////////////////////////
84 class Mutex {
85 public:
86 Mutex();
87 ~Mutex();
88
89 6910 void lock() {
90
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6910 times.
6910 pthread_mutex_lock(&mutex);
91 6910 }
92
93 6910 void unlock() {
94
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6910 times.
6910 pthread_mutex_unlock(&mutex);
95 6910 }
96
97
98 private:
99 pthread_mutex_t mutex;
100 };
101
102 class MutexLock {
103 public:
104 6910 MutexLock(Mutex &m): mutex(m) {
105 6910 mutex.lock();
106 6910 }
107
108 13820 ~MutexLock() {
109 6910 mutex.unlock();
110 6910 }
111
112 private:
113 Mutex &mutex;
114 };
115
116 //////////////////////////////////////////////////////////////////////
117 template <class T>
118 class AtomicCounter {
119 public:
120 AtomicCounter(const T &initval = T()) {
121 counter = initval;
122 }
123
124 T operator++() {
125 MutexLock l(mutex);
126 return ++counter;
127 }
128
129 T operator--() {
130 MutexLock l(mutex);
131 return --counter;
132 }
133
134 operator T() {
135 MutexLock l(mutex);
136 return counter;
137 }
138
139 private:
140 T counter;
141 Mutex mutex;
142 };
143
144 //////////////////////////////////////////////////////////////////////
145 class Thread {
146 public:
147 // throw this to cancel a Thread from within
148 8 struct CancelThread : std::exception
149 {};
150
151 Thread();
152 virtual ~Thread();
153
154 void set_priority(int);
155 int start();
156 int detach();
157 void terminate() noexcept;
158 void *join() noexcept;
159
160 static void sleep(int msec);
161
162 static constexpr int priority_unset_value = -1;
163
164 protected:
165 250 virtual void initial() {};
166 virtual void run() = 0;
167 virtual void final() {};
168
169 private:
170 static void *start_routine(void *arg);
171
172 pthread_attr_t attr;
173 pthread_t id;
174 int rt_priority = priority_unset_value;
175 bool was_started = false;
176 };
177 }
178
179 #endif // PTHREAD_H
180