Instrument Neutral Distributed Interface INDI 2.2.5
indisinglethreadpool.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2021 by Pawel Soja <[email protected]>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17*/
18
21
22namespace INDI
23{
24
26{
27 thread = std::thread([this]
28 {
29 std::unique_lock<std::mutex> lock(runLock);
30 for(;;)
31 {
32 acquire.wait(lock, [&]()
33 {
34 return pendingFunction != nullptr || isThreadAboutToQuit;
35 });
37 break;
38
41 relased.notify_all();
42
43 lock.unlock();
45 lock.lock();
46
47 runningFunction = nullptr;
48 }
49 });
50}
51
53{
54 {
57 std::unique_lock<std::mutex> lock(runLock);
58 acquire.notify_one();
59 }
60 if (thread.joinable())
61 thread.join();
62}
63
67
70
71void SingleThreadPool::start(const std::function<void(const std::atomic_bool &isAboutToClose)> &functionToRun)
72{
73 D_PTR(SingleThreadPool);
74 std::unique_lock<std::mutex> lock(d->runLock);
75 d->pendingFunction = functionToRun;
76 d->isFunctionAboutToQuit = true;
77 d->acquire.notify_one();
78
79 // wait for run
80 if (std::this_thread::get_id() != d->thread.get_id())
81 d->relased.wait(lock, [&d] { return d->pendingFunction == nullptr; });
82}
83
84bool SingleThreadPool::tryStart(const std::function<void(const std::atomic_bool &)> &functionToRun)
85{
86 D_PTR(SingleThreadPool);
87 std::unique_lock<std::mutex> lock(d->runLock);
88 if (d->runningFunction != nullptr)
89 return false;
90
91 d->isFunctionAboutToQuit = true;
92 d->pendingFunction = functionToRun;
93 d->acquire.notify_one();
94
95 // wait for run
96 if (std::this_thread::get_id() != d->thread.get_id())
97 d->relased.wait(lock, [&d] { return d->pendingFunction == nullptr; });
98
99 return true;
100}
101
103{
104 start(nullptr);
105}
106
107}
std::function< void(const std::atomic_bool &isAboutToClose)> pendingFunction
std::condition_variable_any relased
std::function< void(const std::atomic_bool &isAboutToClose)> runningFunction
std::condition_variable_any acquire
void quit()
Sets the 'isAboutToClose' flag to 'true' and waits for the end of running function.
bool tryStart(const std::function< void(const std::atomic_bool &isAboutToClose)> &functionToRun)
If thread isn't available at the time of calling, then this function does nothing and returns false....
void start(const std::function< void(const std::atomic_bool &isAboutToClose)> &functionToRun)
Reserves a thread and uses it to run functionToRun. A running function can check the 'isAboutToClose'...
Namespace to encapsulate INDI client, drivers, and mediator classes.
NLOHMANN_BASIC_JSON_TPL_DECLARATION void swap(nlohmann::NLOHMANN_BASIC_JSON_TPL &j1, nlohmann::NLOHMANN_BASIC_JSON_TPL &j2) noexcept(//NOLINT(readability-inconsistent-declaration-parameter-name) is_nothrow_move_constructible< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value &&//NOLINT(misc-redundant-expression) is_nothrow_move_assignable< nlohmann::NLOHMANN_BASIC_JSON_TPL >::value)
exchanges the values of two JSON objects