ifw-daq  3.0.1
IFW Data Acquisition modules
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  */
8 #include <daq/resourceToken.hpp>
9 
10 #include <log4cplus/loggingmacros.h>
11 
12 namespace daq {
13 ResourceToken::ResourceToken(Resource* resource) noexcept : m_resource(resource) {
14 }
15 
17  if (m_resource) {
18  m_resource->Release();
19  }
20 }
21 ResourceToken::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 
34 std::optional<ResourceToken> Resource::Acquire() noexcept {
35  if (HasResource()) {
36  m_used++;
37  return ResourceToken(this);
38  }
39  return {};
40 }
41 
42 boost::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 
52 boost::signals2::connection Resource::Connect(Signal::slot_type const& slot) {
53  return m_signal.connect(slot);
54 }
55 
56 void 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 & operator=(ResourceToken &)=delete
ResourceToken(Resource *) noexcept
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