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:
84 using task = Base::intrusive_task_queue::task;
86 using native_socket_type = ::io::socket::native_socket_type;
89 std::allocator_traits<Allocator>::template rebind_alloc<event_type>;
91 using vector_type = std::vector<event_type, vector_allocator>;
92
100 intrusive_task_queue read_queue;
102 intrusive_task_queue write_queue;
103
109 };
110
113 std::allocator_traits<Allocator>::template rebind_alloc<demultiplexer>;
115 using map_type = std::deque<demultiplexer, map_allocator>;
116
123 template <Completion Fn> struct sender {
125 using sender_concept = stdexec::sender_t;
127 using completion_signatures = stdexec::completion_signatures<
128 stdexec::set_value_t(typename std::invoke_result_t<Fn>::value_type),
129 stdexec::set_error_t(int)>;
130
137 template <typename Receiver> struct state : public task {
142 static auto complete(task *task_ptr) noexcept -> void;
144 auto start() noexcept -> void;
145
149 std::shared_ptr<socket_handle> socket;
151 Receiver receiver{};
155 std::mutex *mtx = nullptr;
157 execution_trigger trigger{};
158 };
159
165 template <typename Receiver>
166 auto connect(Receiver &&receiver) -> state<std::decay_t<Receiver>>;
167
171 std::shared_ptr<socket_handle> socket;
173 map_type *demux = nullptr;
175 vector_type *list = nullptr;
177 std::mutex *mtx = nullptr;
179 execution_trigger trigger{};
180 };
181
187 auto wait_for(interval_type interval) -> size_type;
188
196 template <Completion Fn>
197 auto set(std::shared_ptr<socket_handle> socket, execution_trigger trigger,
198 Fn &&func) -> sender<std::decay_t<Fn>>;
199
205 const Allocator &alloc = Allocator()) noexcept(noexcept(Allocator()));
206
207private:
209 map_type demux_;
211 vector_type list_;
213 mutable std::mutex mtx_;
214};
215
221
222} // namespace io::execution
223
224#include "io/execution/impl/poll_multiplexer_impl.hpp" // IWYU pragma: export
225
226#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:113
std::allocator_traits< Allocator >::template rebind_alloc< event_type > vector_allocator
The allocator for the vector.
Definition poll_multiplexer.hpp:89
std::deque< demultiplexer, map_allocator > map_type
The map type.
Definition poll_multiplexer.hpp:115
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:91
Base::intrusive_task_queue::task task
The task type.
Definition poll_multiplexer.hpp:84
::io::socket::native_socket_type native_socket_type
The native socket type.
Definition poll_multiplexer.hpp:86
A thread-safe, move-only RAII wrapper for a native socket handle.
Definition socket_handle.hpp:42
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:98
socket_handle * socket
Associated socket used for setting and getting errors.
Definition poll_multiplexer.hpp:108
intrusive_task_queue write_queue
Pending write operations.
Definition poll_multiplexer.hpp:102
intrusive_task_queue read_queue
Pending read operations.
Definition poll_multiplexer.hpp:100
An operation state for the poll multiplexer.
Definition poll_multiplexer.hpp:137
execution_trigger trigger
The poll trigger.
Definition poll_multiplexer.hpp:157
std::shared_ptr< socket_handle > socket
The socket to operate on.
Definition poll_multiplexer.hpp:149
Fn func
The completion handler.
Definition poll_multiplexer.hpp:147
auto start() noexcept -> void
Starts the operation.
demultiplexer * demux
The demultiplexer for the socket.
Definition poll_multiplexer.hpp:153
Receiver receiver
The receiver to complete.
Definition poll_multiplexer.hpp:151
static auto complete(task *task_ptr) noexcept -> void
Completes the operation.
std::mutex * mtx
A mutex for thread safety.
Definition poll_multiplexer.hpp:155
A sender for the poll multiplexer.
Definition poll_multiplexer.hpp:123
Fn func
The completion handler.
Definition poll_multiplexer.hpp:169
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:175
stdexec::sender_t sender_concept
The sender concept type.
Definition poll_multiplexer.hpp:125
execution_trigger trigger
The poll trigger.
Definition poll_multiplexer.hpp:179
std::mutex * mtx
A mutex for thread safety.
Definition poll_multiplexer.hpp:177
stdexec::completion_signatures< stdexec::set_value_t(typename std::invoke_result_t< Fn >::value_type), stdexec::set_error_t(int)> completion_signatures
The completion signatures for the sender.
Definition poll_multiplexer.hpp:129
std::shared_ptr< socket_handle > socket
The socket to operate on.
Definition poll_multiplexer.hpp:171
map_type * demux
The demultiplexer for the socket.
Definition poll_multiplexer.hpp:173
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