GCC Code Coverage Report


Directory: ./
File: pdserv/src/PThread.h
Date: 2025-07-20 04:11:05
Exec Total Coverage
Lines: 35 48 72.9%
Branches: 5 10 50.0%

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