AsyncBerkeley
Asynchronous Berkeley sockets. Simple.
Loading...
Searching...
No Matches
executor.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
20#pragma once
21#ifndef IO_EXECUTOR_HPP
22#define IO_EXECUTOR_HPP
25#include "io/error.hpp"
27
28#include <exec/async_scope.hpp>
29#include <stdexec/execution.hpp>
30
31#include <utility>
32// Forward declarations
33namespace io::execution {
34template <Multiplexer Mux> class basic_triggers;
35} // namespace io::execution
36
41namespace io::execution {
46template <Multiplexer Mux> class executor : public Mux {
51 friend class basic_triggers<Mux>;
61 using async_scope = exec::async_scope;
62
63public:
65 using Mux::Mux;
76 template <SocketLike Socket>
77 static auto push(std::shared_ptr<Socket> socket) -> decltype(auto)
78 {
79 if (::io::fcntl(*socket, F_SETFL,
80 ::io::fcntl(*socket, F_GETFL) | O_NONBLOCK))
81 {
82 throw_system_error(IO_ERROR_MESSAGE("fcntl failed."));
83 }
84 return socket;
85 }
91 template <SocketLike Socket>
92 static auto push(Socket &&handle) -> decltype(auto)
93 {
94 return push(std::make_shared<Socket>(std::forward<Socket>(handle)));
95 }
101 template <typename... Args>
102 static auto emplace(Args &&...args) -> std::shared_ptr<socket_handle>
103 {
104 return push(socket_handle{std::forward<Args>(args)...});
105 }
112 template <typename... Args> auto set(Args &&...args) -> decltype(auto)
113 {
114 return scope_.nest(Mux::set(std::forward<Args>(args)...));
115 }
120 [[nodiscard]] auto on_empty() -> decltype(auto) { return scope_.on_empty(); }
121
122private:
128 constexpr auto wait_for(int interval = -1) -> decltype(auto)
129 {
130 return Mux::wait_for(typename Mux::interval_type{interval});
131 }
136 constexpr auto wait() -> decltype(auto) { return wait_for(); }
138 async_scope scope_;
139};
140
141} // namespace io::execution
142#endif // IO_EXECUTOR_HPP
A class that provides a high-level interface for an executor.
Definition triggers.hpp:38
An executor that uses a multiplexer to wait for events.
Definition executor.hpp:46
static auto emplace(Args &&...args) -> std::shared_ptr< socket_handle >
Emplaces a socket handle in the collection.
Definition executor.hpp:102
static auto push(std::shared_ptr< Socket > socket) -> decltype(auto)
Configures the socket to be non-blocking.
Definition executor.hpp:77
auto on_empty() -> decltype(auto)
Sends a notice when the executor is empty.
Definition executor.hpp:120
auto set(Args &&...args) -> decltype(auto)
Sets a completion handler for an event.
Definition executor.hpp:112
static auto push(Socket &&handle) -> decltype(auto)
Pushes a socket handle to the collection.
Definition executor.hpp:92
A thread-safe, move-only RAII wrapper for a native socket handle.
Definition socket_handle.hpp:42
This file defines concepts for the execution components.
This file defines generic customization points.
auto fcntl(auto &&socket, int cmd, auto &&...args) -> decltype(auto)
Performs a file control operation on a socket.
Definition customization.hpp:134
Provides high-level interfaces for executors and completion triggers.
Definition executor.hpp:33
Cross-platform, thread-safe RAII socket wrapper.