ifw-daq  3.0.1
IFW Data Acquisition modules
resourceToken.hpp
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 #ifndef DAQ_RESOURCE_TOKEN_HPP
9 #define DAQ_RESOURCE_TOKEN_HPP
10 
11 #include <daq/config.hpp>
12 #include <optional>
13 #include <queue>
14 
15 #include <boost/signals2.hpp>
16 #include <boost/thread/future.hpp>
17 
18 namespace daq {
19 class Resource;
20 /**
21  * RAII token
22  */
24 public:
25  ResourceToken(Resource*) noexcept;
26  ResourceToken(ResourceToken const&) = delete;
28 
29  ResourceToken(ResourceToken&&) noexcept;
30  ResourceToken& operator=(ResourceToken&&) noexcept;
31 
32  ~ResourceToken() noexcept;
33 
34 private:
35  Resource* m_resource;
36 };
37 
38 class Resource {
39 public:
40  /**
41  * Signal that emits on changes to resources.
42  */
43  using Signal = boost::signals2::signal<void()>;
44  Resource() = default;
45  explicit Resource(unsigned limit) noexcept : m_limit(limit) {
46  }
47  Resource& operator=(Resource const&) noexcept = delete;
48 
49  boost::future<ResourceToken> AsyncAcquire() noexcept;
50 
51  std::optional<ResourceToken> Acquire() noexcept;
52 
53  bool HasResource() const noexcept {
54  return m_limit == 0 || m_used < m_limit;
55  }
56 
57  void SetLimit(unsigned new_limit) noexcept {
58  m_limit = new_limit;
59  }
60  unsigned GetLimit() const noexcept {
61  return m_limit;
62  }
63  unsigned GetUsed() const noexcept {
64  return m_used;
65  }
66 
67  /**
68  * Connect to signal that is emitted when a resource become available.
69  *
70  * @note There's no guarantee that once signalled there are resources still available.
71  */
72  boost::signals2::connection Connect(Signal::slot_type const& slot);
73 
74 protected:
75  void Release() noexcept;
76 
77 private:
78  friend class ResourceToken;
79  unsigned m_limit = 0;
80  unsigned m_used = 0;
81  Signal m_signal;
82  std::queue<boost::promise<ResourceToken>> m_promises;
83 };
84 } // namespace daq
85 #endif // #ifndef DAQ_RESOURCE_TOKEN_HPP
ResourceToken & operator=(ResourceToken &)=delete
ResourceToken(Resource *) noexcept
ResourceToken(ResourceToken const &)=delete
boost::signals2::signal< void()> Signal
Signal that emits on changes to resources.
Resource()=default
Resource(unsigned limit) noexcept
Resource & operator=(Resource const &) noexcept=delete
unsigned GetLimit() const noexcept
void SetLimit(unsigned new_limit) noexcept
unsigned GetUsed() const noexcept