OpenVPN 3 Core Library
Loading...
Searching...
No Matches
pthreadcond.hpp
Go to the documentation of this file.
1
// OpenVPN -- An application to securely tunnel IP networks
2
// over a single port, with support for SSL/TLS-based
3
// session authentication and key exchange,
4
// packet encryption, packet authentication, and
5
// packet compression.
6
//
7
// Copyright (C) 2012- OpenVPN Inc.
8
//
9
// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10
//
11
12
#ifndef OPENVPN_COMMON_PTHREADCOND_H
13
#define OPENVPN_COMMON_PTHREADCOND_H
14
15
#include <mutex>
16
#include <condition_variable>
17
#include <chrono>
18
19
#include <
openvpn/common/stop.hpp
>
20
21
namespace
openvpn
{
22
23
// Barrier class that is useful in cases where all threads
24
// need to reach a known point before executing some action.
25
// Note that this barrier implementation is
26
// constructed using C++11 condition variables.
27
class
PThreadBarrier
28
{
29
enum
State
30
{
31
UNSIGNALED
= 0,
// initial state
32
SIGNALED
,
// signal() was called
33
ERROR_THROWN
,
// error() was called
34
};
35
36
public
:
37
// status return from wait()
38
enum
Status
39
{
40
SUCCESS
= 0,
// successful
41
CHOSEN_ONE
,
// successful and chosen (only one thread is chosen)
42
TIMEOUT
,
// timeout
43
ERROR_SIGNAL
,
// at least one thread called error()
44
};
45
46
PThreadBarrier
(
const
int
initial_limit = -1)
47
:
stop
(nullptr),
48
limit
(initial_limit)
49
{
50
}
51
52
PThreadBarrier
(
Stop
*stop_arg,
const
int
initial_limit = -1)
53
:
stop
(stop_arg),
54
limit
(initial_limit)
55
{
56
}
57
58
// All callers will increment count and block until
59
// count == limit. CHOSEN_ONE will be returned to
60
// the first caller to reach limit. This caller can
61
// then release all the other callers by calling
62
// signal().
63
int
wait
(
const
unsigned
int
seconds)
64
{
65
// allow asynchronous stop
66
Stop::Scope
stop_scope(
stop
, [
this
]()
67
{
error
(); });
68
69
bool
timeout =
false
;
70
int
ret
;
71
std::unique_lock<std::mutex> lock(
mutex
);
72
const
unsigned
int
c = ++
count
;
73
while
(
state
==
UNSIGNALED
74
&& (
limit
< 0 || c <
static_cast<
unsigned
int
>
(
limit
))
75
&& !timeout)
76
timeout = (
cv
.wait_for(lock, std::chrono::seconds(seconds)) == std::cv_status::timeout);
77
if
(timeout)
78
ret
=
TIMEOUT
;
79
else
if
(
state
==
ERROR_THROWN
)
80
ret
=
ERROR_SIGNAL
;
81
else
if
(
state
==
UNSIGNALED
&& !
chosen
)
82
{
83
ret
=
CHOSEN_ONE
;
84
chosen
=
true
;
85
}
86
else
87
ret
=
SUCCESS
;
88
return
ret
;
89
}
90
91
void
set_limit
(
const
int
new_limit)
92
{
93
std::unique_lock<std::mutex> lock(
mutex
);
94
limit
= new_limit;
95
cv
.notify_all();
96
}
97
98
// Generally, only the CHOSEN_ONE calls signal() after its work
99
// is complete, to allow the other threads to pass the barrier.
100
void
signal
()
101
{
102
signal_
(
SIGNALED
);
103
}
104
105
// Causes all threads waiting on wait() (and those which call wait()
106
// in the future) to exit with ERROR_SIGNAL status.
107
void
error
()
108
{
109
signal_
(
ERROR_THROWN
);
110
}
111
112
private
:
113
void
signal_
(
const
State
newstate)
114
{
115
std::unique_lock<std::mutex> lock(
mutex
);
116
if
(
state
==
UNSIGNALED
)
117
{
118
state
= newstate;
119
cv
.notify_all();
120
}
121
}
122
123
std::mutex
mutex
;
124
std::condition_variable
cv
;
125
Stop
*
stop
;
126
State
state
{
UNSIGNALED
};
127
bool
chosen
=
false
;
128
int
count
= 0;
129
int
limit
;
130
};
131
132
}
// namespace openvpn
133
134
#endif
openvpn::PThreadBarrier
Definition
pthreadcond.hpp:28
openvpn::PThreadBarrier::chosen
bool chosen
Definition
pthreadcond.hpp:127
openvpn::PThreadBarrier::cv
std::condition_variable cv
Definition
pthreadcond.hpp:124
openvpn::PThreadBarrier::count
int count
Definition
pthreadcond.hpp:128
openvpn::PThreadBarrier::signal_
void signal_(const State newstate)
Definition
pthreadcond.hpp:113
openvpn::PThreadBarrier::set_limit
void set_limit(const int new_limit)
Definition
pthreadcond.hpp:91
openvpn::PThreadBarrier::error
void error()
Definition
pthreadcond.hpp:107
openvpn::PThreadBarrier::limit
int limit
Definition
pthreadcond.hpp:129
openvpn::PThreadBarrier::PThreadBarrier
PThreadBarrier(const int initial_limit=-1)
Definition
pthreadcond.hpp:46
openvpn::PThreadBarrier::signal
void signal()
Definition
pthreadcond.hpp:100
openvpn::PThreadBarrier::PThreadBarrier
PThreadBarrier(Stop *stop_arg, const int initial_limit=-1)
Definition
pthreadcond.hpp:52
openvpn::PThreadBarrier::mutex
std::mutex mutex
Definition
pthreadcond.hpp:123
openvpn::PThreadBarrier::wait
int wait(const unsigned int seconds)
Definition
pthreadcond.hpp:63
openvpn::PThreadBarrier::Status
Status
Definition
pthreadcond.hpp:39
openvpn::PThreadBarrier::CHOSEN_ONE
@ CHOSEN_ONE
Definition
pthreadcond.hpp:41
openvpn::PThreadBarrier::SUCCESS
@ SUCCESS
Definition
pthreadcond.hpp:40
openvpn::PThreadBarrier::ERROR_SIGNAL
@ ERROR_SIGNAL
Definition
pthreadcond.hpp:43
openvpn::PThreadBarrier::TIMEOUT
@ TIMEOUT
Definition
pthreadcond.hpp:42
openvpn::PThreadBarrier::stop
Stop * stop
Definition
pthreadcond.hpp:125
openvpn::PThreadBarrier::state
State state
Definition
pthreadcond.hpp:126
openvpn::PThreadBarrier::State
State
Definition
pthreadcond.hpp:30
openvpn::PThreadBarrier::UNSIGNALED
@ UNSIGNALED
Definition
pthreadcond.hpp:31
openvpn::PThreadBarrier::SIGNALED
@ SIGNALED
Definition
pthreadcond.hpp:32
openvpn::PThreadBarrier::ERROR_THROWN
@ ERROR_THROWN
Definition
pthreadcond.hpp:33
openvpn::Stop::Scope
Definition
stop.hpp:30
openvpn::Stop
Definition
stop.hpp:27
openvpn
Definition
ovpncli.cpp:97
stop.hpp
ret
std::string ret
Definition
test_capture.cpp:268
openvpn
common
pthreadcond.hpp
Generated by
1.9.8