Toolbox snapshot
The Reactive C++ Toolbox
Loading...
Searching...
No Matches
Signal.cpp
Go to the documentation of this file.
1// The Reactive C++ Toolbox.
2// Copyright (C) 2013-2019 Swirly Cloud Limited
3// Copyright (C) 2021 Reactive Markets Limited
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17#include "Signal.hpp"
18
19#include "Error.hpp"
20
22
23namespace toolbox {
24inline namespace sys {
25
26SigWait::SigWait(std::initializer_list<int> mask)
27{
28 sigemptyset(&new_mask_);
29 for (auto sig : mask) {
30 sigaddset(&new_mask_, sig);
31 }
32
33 const auto err = pthread_sigmask(SIG_BLOCK, &new_mask_, &old_mask_);
34 if (err != 0) {
35 throw std::system_error{make_error(err), "pthread_sigmask"};
36 }
37}
38
40{
41 // Restore original signal mask.
42 pthread_sigmask(SIG_SETMASK, &old_mask_, nullptr);
43}
44
46{
47 const auto finally = make_finally([&]() noexcept { CyclTime::now(); });
48 for (;;) {
50 if (sigwaitinfo(&new_mask_, &info) < 0) {
51 if (errno == EINTR) {
52 // Restart if interrupted by unblocked signal.
53 continue;
54 }
55 throw std::system_error{make_error(errno), "sigwaitinfo"};
56 }
57 return info.si_signo;
58 }
59}
60
62{
63 const auto finally = make_finally([&]() noexcept { CyclTime::now(); });
64 const auto ts = to_timespec(timeout);
65 for (;;) {
67 if (sigtimedwait(&new_mask_, &info, &ts) < 0) {
68 if (errno == EINTR) {
69 // Restart if interrupted by unblocked signal.
70 continue;
71 }
72 if (errno == EAGAIN) {
73 // Timeout.
74 return 0;
75 }
76 throw std::system_error{make_error(errno), "sigtimedwait"};
77 }
78 return info.si_signo;
79 }
80}
81
83{
85 sigfillset(&ss);
86 const auto err = pthread_sigmask(SIG_SETMASK, &ss, nullptr);
87 if (err != 0) {
88 throw std::system_error{make_error(err), "pthread_sigmask"};
89 }
90}
91
92} // namespace sys
93} // namespace toolbox
static CyclTime now() noexcept
Definition Time.hpp:129
SigWait(std::initializer_list< int > mask={SIGHUP, SIGINT, SIGUSR1, SIGUSR2, SIGTERM})
Definition Signal.cpp:26
int operator()() const
Definition Signal.cpp:45
std::error_code make_error(int err) noexcept
Definition Error.hpp:25
constexpr timespec to_timespec(std::chrono::duration< RepT, PeriodT > d) noexcept
Definition Time.hpp:234
void sig_block_all()
Block all signals.
Definition Signal.cpp:82
Nanos Duration
Definition Time.hpp:40
auto make_finally(FnT fn) noexcept
Definition Finally.hpp:48
constexpr auto bind() noexcept
Definition Slot.hpp:92