Line data Source code
1 : #include "uhallibs/ipc/RobustMutex.hpp"
2 :
3 : #include <cstring>
4 : #include "uhal/log/log.hpp"
5 :
6 :
7 : namespace uhallibs {
8 : namespace ipc {
9 :
10 0 : RobustMutex::RobustMutex() : mCount(0), mSessionActive(false) {
11 0 : pthread_mutexattr_t lAttr;
12 :
13 0 : int s = pthread_mutexattr_init(&lAttr);
14 0 : if (s != 0) {
15 0 : exception::MutexError lExc;
16 0 : log(lExc, "Error code ", uhal::Integer(s), " (", strerror(s),
17 : ") returned in mutex attr initialisation");
18 0 : throw lExc;
19 0 : }
20 :
21 0 : s = pthread_mutexattr_setpshared(&lAttr, PTHREAD_PROCESS_SHARED);
22 0 : if (s != 0) {
23 0 : exception::MutexError lExc;
24 0 : log(lExc, "Error code ", uhal::Integer(s), " (", strerror(s),
25 : ") returned by pthread_mutexattr_setpshared");
26 0 : throw lExc;
27 0 : }
28 :
29 0 : s = pthread_mutexattr_setrobust(&lAttr, PTHREAD_MUTEX_ROBUST);
30 0 : if (s != 0) {
31 0 : exception::MutexError lExc;
32 0 : log(lExc, "Error code ", uhal::Integer(s), " (", strerror(s),
33 : ") returned by pthread_mutexattr_setrobust");
34 0 : throw lExc;
35 0 : }
36 :
37 0 : s = pthread_mutex_init(&mMutex, &lAttr);
38 0 : if (s != 0) {
39 0 : exception::MutexError lExc;
40 0 : log(lExc, "Error code ", uhal::Integer(s), " (", strerror(s),
41 : ") returned in mutex initialisation");
42 0 : throw lExc;
43 0 : }
44 0 : }
45 :
46 0 : RobustMutex::~RobustMutex() {}
47 :
48 0 : void RobustMutex::lock() {
49 0 : int s = pthread_mutex_lock(&mMutex);
50 0 : bool lLastOwnerDied = (s == EOWNERDEAD);
51 0 : if (lLastOwnerDied) s = pthread_mutex_consistent(&mMutex);
52 :
53 0 : if (s != 0) {
54 0 : exception::MutexError lExc;
55 0 : log(lExc, "Error code ", uhal::Integer(s), " (", strerror(s), ") returned when ",
56 0 : lLastOwnerDied ? "making mutex state consistent" : "locking mutex");
57 0 : throw lExc;
58 0 : }
59 0 : }
60 :
61 0 : void RobustMutex::unlock() {
62 0 : int s = pthread_mutex_unlock(&mMutex);
63 0 : if (s != 0)
64 0 : log(uhal::Error(), "Error code ", uhal::Integer(s), " (", strerror(s),
65 : ") returned when unlocking mutex");
66 0 : }
67 :
68 0 : uint64_t RobustMutex::getCounter() const { return mCount; }
69 :
70 0 : bool RobustMutex::isActive() const { return mSessionActive; }
71 :
72 0 : void RobustMutex::startSession() {
73 0 : mCount++;
74 0 : mSessionActive = true;
75 0 : }
76 :
77 0 : void RobustMutex::endSession() { mSessionActive = false; }
78 :
79 : } // namespace ipc
80 : } // namespace uhal
|