AsyncBerkeley
Asynchronous Berkeley sockets. Simple.
Loading...
Searching...
No Matches
poll_multiplexer.hpp
Go to the documentation of this file.
1/* Copyright 2025 Kevin Exton
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
23#pragma once
24#ifndef IO_POLL_MULTIPLEXER_HPP
25#define IO_POLL_MULTIPLEXER_HPP
26#include "detail/execution_trigger.hpp"
27#include "multiplexer.hpp"
28
29#include <stdexec/execution.hpp>
30
31#include <deque>
32#include <memory>
33
34#include <poll.h>
35// Forward declarations.
36namespace io::socket {
37class socket_handle;
38} // namespace io::socket
39
44namespace io::execution {
50struct poll_t {
52 using event_type = struct pollfd;
54 using interval_type = std::chrono::milliseconds;
56 using size_type = std::size_t;
61 template <typename Op> struct is_eager_t : public std::false_type {};
66 template <typename Op>
67 static constexpr bool is_eager_v = is_eager_t<Op>::value;
68};
69
76template <AllocatorLike Allocator = std::allocator<char>>
78public:
82 using mutex = std::mutex;
86 using task = Base::intrusive_task_queue::task;
88 using native_socket_type = ::io::socket::native_socket_type;
91 std::allocator_traits<Allocator>::template rebind_alloc<event_type>;
93 using vector_type = std::vector<event_type, vector_allocator>;
94
102 intrusive_task_queue read_queue;
104 intrusive_task_queue write_queue;
105
111 };
112
115 std::allocator_traits<Allocator>::template rebind_alloc<demultiplexer>;
117 using map_type = std::deque<demultiplexer, map_allocator>;
118
125 template <Completion Fn> struct sender {
127 using sender_concept = stdexec::sender_t;
129 using completion_signatures = stdexec::completion_signatures<
130 stdexec::set_value_t(typename std::invoke_result_t<Fn>::value_type),
131 stdexec::set_error_t(std::error_code)>;
132
139 template <typename Receiver> struct state : public task {
144 static auto complete(task *task_ptr) noexcept -> void;
146 auto start() noexcept -> void;
147
151 std::shared_ptr<socket_handle> socket;
153 Receiver receiver{};
157 mutex *mtx = nullptr;
159 execution_trigger trigger{};
160 };
161
167 template <typename Receiver>
168 auto connect(Receiver &&receiver) -> state<std::decay_t<Receiver>>;
169
173 std::shared_ptr<socket_handle> socket;
175 map_type *demux = nullptr;
177 vector_type *list = nullptr;
179 mutex *mtx = nullptr;
181 execution_trigger trigger{};
182 };
183
189 auto wait_for(interval_type interval) -> size_type;
190
198 template <Completion Fn>
199 auto set(std::shared_ptr<socket_handle> socket, execution_trigger trigger,
200 Fn &&func) -> sender<std::decay_t<Fn>>;
201
207 const Allocator &alloc = Allocator()) noexcept(noexcept(Allocator()));
208
209private:
211 map_type demux_;
213 vector_type list_;
215 mutable mutex mtx_;
216};
217
223
224} // namespace io::execution
225
226#include "io/execution/impl/poll_multiplexer_impl.hpp" // IWYU pragma: export
227
228#endif // IO_POLL_MULTIPLEXER_HPP
A multiplexer that uses the poll system call.
Definition poll_multiplexer.hpp:77
std::allocator_traits< Allocator >::template rebind_alloc< demultiplexer > map_allocator
The allocator for the map.
Definition poll_multiplexer.hpp:115
std::allocator_traits< Allocator >::template rebind_alloc< event_type > vector_allocator
The allocator for the vector.
Definition poll_multiplexer.hpp:91
std::deque< demultiplexer, map_allocator > map_type
The map type.
Definition poll_multiplexer.hpp:117
auto wait_for(interval_type interval) -> size_type
Waits for events to occur.
constexpr basic_poll_multiplexer(const Allocator &alloc=Allocator()) noexcept(noexcept(Allocator()))
Default constructor.
auto set(std::shared_ptr< socket_handle > socket, execution_trigger trigger, Fn &&func) -> sender< std::decay_t< Fn > >
Sets a completion handler for an event.
std::vector< event_type, vector_allocator > vector_type
The vector type.
Definition poll_multiplexer.hpp:93
Base::intrusive_task_queue::task task
The task type.
Definition poll_multiplexer.hpp:86
::io::socket::native_socket_type native_socket_type
The native socket type.
Definition poll_multiplexer.hpp:88
std::mutex mutex
The mutex type.
Definition poll_multiplexer.hpp:82
A thread-safe, move-only RAII wrapper for a native socket handle.
Definition socket_handle.hpp:38
This file provides generic operation state definitions.
Provides high-level interfaces for executors and completion triggers.
Definition executor.hpp:33
The io::socket namespace provides a cross-platform abstraction for socket-level I/O operations.
Definition poll_multiplexer.hpp:36
A basic multiplexer that can be used with different event types.
Definition multiplexer.hpp:37
Demultiplexes I/O operations for a socket.
Definition poll_multiplexer.hpp:100
socket_handle * socket
Associated socket used for setting and getting errors.
Definition poll_multiplexer.hpp:110
intrusive_task_queue write_queue
Pending write operations.
Definition poll_multiplexer.hpp:104
intrusive_task_queue read_queue
Pending read operations.
Definition poll_multiplexer.hpp:102
An operation state for the poll multiplexer.
Definition poll_multiplexer.hpp:139
execution_trigger trigger
The poll trigger.
Definition poll_multiplexer.hpp:159
std::shared_ptr< socket_handle > socket
The socket to operate on.
Definition poll_multiplexer.hpp:151
Fn func
The completion handler.
Definition poll_multiplexer.hpp:149
auto start() noexcept -> void
Starts the operation.
demultiplexer * demux
The demultiplexer for the socket.
Definition poll_multiplexer.hpp:155
Receiver receiver
The receiver to complete.
Definition poll_multiplexer.hpp:153
static auto complete(task *task_ptr) noexcept -> void
Completes the operation.
mutex * mtx
A mutex for thread safety.
Definition poll_multiplexer.hpp:157
A sender for the poll multiplexer.
Definition poll_multiplexer.hpp:125
Fn func
The completion handler.
Definition poll_multiplexer.hpp:171
auto connect(Receiver &&receiver) -> state< std::decay_t< Receiver > >
Connects the sender to a receiver.
vector_type * list
The list of poll events.
Definition poll_multiplexer.hpp:177
stdexec::sender_t sender_concept
The sender concept type.
Definition poll_multiplexer.hpp:127
stdexec::completion_signatures< stdexec::set_value_t(typename std::invoke_result_t< Fn >::value_type), stdexec::set_error_t(std::error_code)> completion_signatures
The completion signatures for the sender.
Definition poll_multiplexer.hpp:131
execution_trigger trigger
The poll trigger.
Definition poll_multiplexer.hpp:181
mutex * mtx
A mutex for thread safety.
Definition poll_multiplexer.hpp:179
std::shared_ptr< socket_handle > socket
The socket to operate on.
Definition poll_multiplexer.hpp:173
map_type * demux
The demultiplexer for the socket.
Definition poll_multiplexer.hpp:175
Type trait to check if an operation should evaluate eagerly.
Definition poll_multiplexer.hpp:61
Tag type for a polling multiplexer.
Definition poll_multiplexer.hpp:50
static constexpr bool is_eager_v
Helper variable template for is_eager_t.
Definition poll_multiplexer.hpp:67
std::size_t size_type
A size type.
Definition poll_multiplexer.hpp:56
std::chrono::milliseconds interval_type
The type used to specify timeouts.
Definition poll_multiplexer.hpp:54