Coverage Report

Created: 2025-08-26 06:06

/src/libzmq/src/mutex.hpp
Line
Count
Source (jump to first uncovered line)
1
/* SPDX-License-Identifier: MPL-2.0 */
2
3
#ifndef __ZMQ_MUTEX_HPP_INCLUDED__
4
#define __ZMQ_MUTEX_HPP_INCLUDED__
5
6
#include "err.hpp"
7
#include "macros.hpp"
8
9
//  Mutex class encapsulates OS mutex in a platform-independent way.
10
11
#if defined(ZMQ_HAVE_WINDOWS) && !defined(ZMQ_USE_CV_IMPL_PTHREADS)
12
13
#include "windows.hpp"
14
15
namespace zmq
16
{
17
class mutex_t
18
{
19
  public:
20
    mutex_t () { InitializeCriticalSection (&_cs); }
21
22
    ~mutex_t () { DeleteCriticalSection (&_cs); }
23
24
    void lock () { EnterCriticalSection (&_cs); }
25
26
    bool try_lock () { return (TryEnterCriticalSection (&_cs)) ? true : false; }
27
28
    void unlock () { LeaveCriticalSection (&_cs); }
29
30
    CRITICAL_SECTION *get_cs () { return &_cs; }
31
32
  private:
33
    CRITICAL_SECTION _cs;
34
35
    ZMQ_NON_COPYABLE_NOR_MOVABLE (mutex_t)
36
};
37
}
38
39
#elif defined ZMQ_HAVE_VXWORKS
40
41
#include <vxWorks.h>
42
#include <semLib.h>
43
44
namespace zmq
45
{
46
class mutex_t
47
{
48
  public:
49
    inline mutex_t ()
50
    {
51
        _semId =
52
          semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE);
53
    }
54
55
    inline ~mutex_t () { semDelete (_semId); }
56
57
    inline void lock () { semTake (_semId, WAIT_FOREVER); }
58
59
    inline bool try_lock ()
60
    {
61
        if (semTake (_semId, NO_WAIT) == OK) {
62
            return true;
63
        }
64
        return false;
65
    }
66
67
    inline void unlock () { semGive (_semId); }
68
69
  private:
70
    SEM_ID _semId;
71
72
    ZMQ_NON_COPYABLE_NOR_MOVABLE (mutex_t)
73
};
74
}
75
76
#else
77
78
#include <pthread.h>
79
80
namespace zmq
81
{
82
class mutex_t
83
{
84
  public:
85
    inline mutex_t ()
86
0
    {
87
0
        int rc = pthread_mutexattr_init (&_attr);
88
0
        posix_assert (rc);
89
90
0
        rc = pthread_mutexattr_settype (&_attr, PTHREAD_MUTEX_RECURSIVE);
91
0
        posix_assert (rc);
92
93
0
        rc = pthread_mutex_init (&_mutex, &_attr);
94
0
        posix_assert (rc);
95
0
    }
96
97
    inline ~mutex_t ()
98
0
    {
99
0
        int rc = pthread_mutex_destroy (&_mutex);
100
0
        posix_assert (rc);
101
102
0
        rc = pthread_mutexattr_destroy (&_attr);
103
0
        posix_assert (rc);
104
0
    }
105
106
    inline void lock ()
107
0
    {
108
0
        int rc = pthread_mutex_lock (&_mutex);
109
0
        posix_assert (rc);
110
0
    }
111
112
    inline bool try_lock ()
113
0
    {
114
0
        int rc = pthread_mutex_trylock (&_mutex);
115
0
        if (rc == EBUSY)
116
0
            return false;
117
118
0
        posix_assert (rc);
119
0
        return true;
120
0
    }
121
122
    inline void unlock ()
123
0
    {
124
0
        int rc = pthread_mutex_unlock (&_mutex);
125
0
        posix_assert (rc);
126
0
    }
127
128
0
    inline pthread_mutex_t *get_mutex () { return &_mutex; }
129
130
  private:
131
    pthread_mutex_t _mutex;
132
    pthread_mutexattr_t _attr;
133
134
    ZMQ_NON_COPYABLE_NOR_MOVABLE (mutex_t)
135
};
136
}
137
138
#endif
139
140
141
namespace zmq
142
{
143
struct scoped_lock_t
144
{
145
0
    scoped_lock_t (mutex_t &mutex_) : _mutex (mutex_) { _mutex.lock (); }
146
147
0
    ~scoped_lock_t () { _mutex.unlock (); }
148
149
  private:
150
    mutex_t &_mutex;
151
152
    ZMQ_NON_COPYABLE_NOR_MOVABLE (scoped_lock_t)
153
};
154
155
156
struct scoped_optional_lock_t
157
{
158
0
    scoped_optional_lock_t (mutex_t *mutex_) : _mutex (mutex_)
159
0
    {
160
0
        if (_mutex != NULL)
161
0
            _mutex->lock ();
162
0
    }
163
164
    ~scoped_optional_lock_t ()
165
0
    {
166
0
        if (_mutex != NULL)
167
0
            _mutex->unlock ();
168
0
    }
169
170
  private:
171
    mutex_t *_mutex;
172
173
    ZMQ_NON_COPYABLE_NOR_MOVABLE (scoped_optional_lock_t)
174
};
175
}
176
177
#endif