SeqAn3 3.3.0-rc.1
The Modern C++ library for sequence analysis.
reader_writer_manager.hpp
Go to the documentation of this file.
1// -----------------------------------------------------------------------------------------------------
2// Copyright (c) 2006-2022, Knut Reinert & Freie Universität Berlin
3// Copyright (c) 2016-2022, Knut Reinert & MPI für molekulare Genetik
4// This file may be used, modified and/or redistributed under the terms of the 3-clause BSD-License
5// shipped with this file and also available at: https://github.com/seqan/seqan3/blob/master/LICENSE.md
6// -----------------------------------------------------------------------------------------------------
7
13#pragma once
14
15#include <cassert>
16#include <functional>
17#include <mutex>
18#include <seqan3/std/new>
19
23
24namespace seqan3::detail
25{
26
30struct writer_count : public detail::strong_type<size_t, writer_count>
31{
34
36 using base_t::base_t;
37};
38
42struct reader_count : public detail::strong_type<size_t, reader_count>
43{
46
48 using base_t::base_t;
49};
50
73{
74private:
76 class [[nodiscard]] scoped_writer_type
77 {
78 public:
83 scoped_writer_type() = delete;
88
92 explicit scoped_writer_type(reader_writer_manager & _manager) : manager{_manager}
93 {}
94
97 {
98 manager.writer_arrive();
99 }
101
104 };
105
107 class [[nodiscard]] scoped_reader_type
108 {
109 public:
118
122 explicit scoped_reader_type(reader_writer_manager & _manager) : manager{_manager}
123 {}
124
127 {
128 manager.reader_arrive();
129 }
131
134 };
135
136public:
146
163 template <typename concurrent_t>
164 requires requires { std::declval<concurrent_t>().close(); } // requires closable concurrent data structure.
165 reader_writer_manager(reader_count const rcount, writer_count const wcount, concurrent_t & ds) :
166 reader_latch{static_cast<ptrdiff_t>(rcount.get())},
167 writer_latch{static_cast<ptrdiff_t>(wcount.get())},
168 completion_fn{[&ds]()
169 {
170 ds.close();
171 }}
172 {
173 if (rcount.get() < 1 || wcount.get() < 1)
174 throw std::invalid_argument{"Both, reader count and writer count must be at least 1."};
175 }
177
195 {
196 writer_latch.arrive_and_wait();
197
198 std::call_once(flag, completion_fn);
199 }
200
217 void writer_arrive() noexcept
218 {
219 writer_latch.arrive();
220
221 if (writer_latch.try_wait())
222 std::call_once(flag, completion_fn);
223 }
224
241 {
242 reader_latch.arrive_and_wait();
243 }
244
259 void reader_arrive() noexcept
260 {
261 reader_latch.arrive();
262 }
263
282 {
283 return scoped_writer_type{*this};
284 }
285
304 {
305 return scoped_reader_type{*this};
306 }
307
308private:
317};
318
319} // namespace seqan3::detail
T call_once(T... args)
A single-use synchronisation point to coordinate concurrent threads.
Definition: latch.hpp:39
A strictly scope-based seqan3::detail::reader_writer_manager wrapper for consumer threads.
Definition: reader_writer_manager.hpp:108
scoped_reader_type & operator=(scoped_reader_type const &)=default
Deleted.
~scoped_reader_type()
Calls reader_arrive on the wrapped latch and destructs.
Definition: reader_writer_manager.hpp:126
scoped_reader_type(reader_writer_manager &_manager)
Constructs the scoped reader with the associated manager.
Definition: reader_writer_manager.hpp:122
scoped_reader_type(scoped_reader_type const &)=default
Deleted.
scoped_reader_type(scoped_reader_type &&)=default
Defaulted.
reader_writer_manager & manager
The wrapped latch.
Definition: reader_writer_manager.hpp:133
scoped_reader_type & operator=(scoped_reader_type &&)=default
Defaulted.
A strictly scope-based seqan3::detail::reader_writer_manager wrapper for producer threads.
Definition: reader_writer_manager.hpp:77
~scoped_writer_type()
Calls writer_arrive on the wrapped latch and destructs.
Definition: reader_writer_manager.hpp:96
reader_writer_manager & manager
The wrapped latch.
Definition: reader_writer_manager.hpp:103
scoped_writer_type & operator=(scoped_writer_type &&)=default
Defaulted.
scoped_writer_type & operator=(scoped_writer_type const &)=default
Deleted.
scoped_writer_type(reader_writer_manager &_manager)
Constructs the scoped writer with the associated manager.
Definition: reader_writer_manager.hpp:92
scoped_writer_type(scoped_writer_type &&)=default
Defaulted.
scoped_writer_type(scoped_writer_type const &)=default
Deleted.
A single-use synchronisation point for closable concurrent data structures.
Definition: reader_writer_manager.hpp:73
scoped_writer_type register_writer() noexcept
Registers the current thread as a producer thread for the monitored resource.
Definition: reader_writer_manager.hpp:281
reader_writer_manager(reader_count const rcount, writer_count const wcount, concurrent_t &ds)
Constructs the reader_writer_manager with the reader count, writer count and the associated data stru...
Definition: reader_writer_manager.hpp:165
std::function< void()> completion_fn
The stored completion function.
Definition: reader_writer_manager.hpp:316
void reader_arrive_and_wait() noexcept
Atomically decrements writer counter by one and blocks the calling thread.
Definition: reader_writer_manager.hpp:240
latch writer_latch
The internal latch for producer threads.
Definition: reader_writer_manager.hpp:312
reader_writer_manager(reader_writer_manager const &)=delete
Deleted.
~reader_writer_manager()=default
Defaulted.
void writer_arrive() noexcept
Atomically decrements writer counter by one.
Definition: reader_writer_manager.hpp:217
latch reader_latch
The internal latch for consumer threads.
Definition: reader_writer_manager.hpp:310
reader_writer_manager(reader_writer_manager &&)=delete
Deleted.
void reader_arrive() noexcept
Atomically decrements reader counter by one.
Definition: reader_writer_manager.hpp:259
void writer_arrive_and_wait() noexcept
Atomically decrements writer counter by one and blocks the calling thread.
Definition: reader_writer_manager.hpp:194
reader_writer_manager & operator=(reader_writer_manager &&)=delete
Deleted.
scoped_reader_type register_reader() noexcept
Registers the current thread as a consumer thread for the monitored resource.
Definition: reader_writer_manager.hpp:303
reader_writer_manager & operator=(reader_writer_manager const &)=delete
Deleted.
CRTP base class to declare a strong typedef for a regular type to avoid ambiguous parameter settings ...
Definition: strong_type.hpp:177
@ flag
The alignment flag (bit information), uint16_t value.
constexpr std::size_t hardware_destructive_interference_size
Minimum offset between two objects to avoid false sharing.
Definition: new:34
Provides seqan3::detail::latch.
The internal SeqAn3 namespace.
Definition: aligned_sequence_concept.hpp:29
constexpr auto const & get(configuration< configs_t... > const &config) noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: configuration.hpp:415
The <new> header from C++17's standard library.
Provides seqan3::detail::spin_delay.
Provides basic data structure for strong types.
A strong type to set the reader count of a seqan3::detail::reader_writer_manager.
Definition: reader_writer_manager.hpp:43
A strong type to set the writer count of a seqan3::detail::reader_writer_manager.
Definition: reader_writer_manager.hpp:31