ifw-daq 3.1.0
IFW Data Acquisition modules
Loading...
Searching...
No Matches
resourceToken.cpp
Go to the documentation of this file.
1/**
2 * @file
3 * @ingroup daq
4 * @copyright (c) Copyright ESO 2023
5 * All Rights Reserved
6 * ESO (eso.org) is an Intergovernmental Organisation, and therefore special legal conditions apply.
7 */
9
10#include <log4cplus/loggingmacros.h>
11
12namespace daq {
13ResourceToken::ResourceToken(Resource* resource) noexcept : m_resource(resource) {
14}
15
17 if (m_resource) {
18 m_resource->Release();
19 }
20}
21ResourceToken::ResourceToken(ResourceToken&& rhs) noexcept : m_resource(nullptr) {
22 *this = std::move(rhs);
23}
24
26 if (m_resource) {
27 m_resource->Release();
28 }
29 m_resource = rhs.m_resource;
30 rhs.m_resource = nullptr;
31 return *this;
32}
33
34std::optional<ResourceToken> Resource::Acquire() noexcept {
35 if (HasResource()) {
36 m_used++;
37 return ResourceToken(this);
38 }
39 return {};
40}
41
42boost::future<ResourceToken> Resource::AsyncAcquire() noexcept {
43 auto maybe_token = Acquire();
44 if (maybe_token) {
45 return boost::make_ready_future<ResourceToken>(*std::move(maybe_token));
46 } else {
47 auto& ref = m_promises.emplace();
48 return ref.get_future();
49 }
50}
51
52boost::signals2::connection Resource::Connect(Signal::slot_type const& slot) {
53 return m_signal.connect(slot);
54}
55
56void Resource::Release() noexcept {
57 m_used--;
58
59 while (HasResource() && !m_promises.empty()) {
60 // If future invokes completion function that releases resource we need to protected against
61 // recursive calls.
62 auto promise = std::move(m_promises.front());
63 m_promises.pop();
64 m_used++;
65 promise.set_value(ResourceToken(this)); // may trigger recursive call
66 }
67
68 // If we still have resources signal slots
69 if (HasResource()) {
70 m_signal();
71 }
72}
73} // namespace daq
~ResourceToken() noexcept
ResourceToken(Resource *) noexcept
ResourceToken & operator=(ResourceToken &)=delete
boost::future< ResourceToken > AsyncAcquire() noexcept
boost::signals2::connection Connect(Signal::slot_type const &slot)
Connect to signal that is emitted when a resource become available.
void Release() noexcept
std::optional< ResourceToken > Acquire() noexcept
friend class ResourceToken
bool HasResource() const noexcept