userver: userver/engine/io/fd_poller.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
fd_poller.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/engine/io/fd_poller.hpp
4/// @brief Low-level file descriptor r/w poller
5
6#include <memory>
7#include <optional>
8
9#include <userver/engine/deadline.hpp>
10#include <userver/utils/fast_pimpl.hpp>
11
12USERVER_NAMESPACE_BEGIN
13
14namespace engine::impl {
15class ContextAccessor;
16}
17
18namespace engine::io {
19
20namespace impl {
21class Direction;
22}
23
24/// @brief Low-level poller that can wait for read, write, and read/write
25/// operations on a file descriptor. It does not provide read/write operations.
26/// @note FdPoller is not thread safe and its methods must not be called from
27/// multiple threads simultaneously.
28class FdPoller final {
29 public:
30 /// @brief Operation kind to wait for
31 enum class Kind {
32 kRead = 1, /// < wait for read availability
33 kWrite = 2, /// < wait for write availability
34 kReadWrite = 3, /// < wait for either read or write availability
35 };
36
37 FdPoller();
38 FdPoller(const FdPoller&) = delete;
39 FdPoller(FdPoller&&) = delete;
40 FdPoller& operator=(const FdPoller&) = delete;
41 FdPoller& operator=(FdPoller&&) = delete;
42 ~FdPoller();
43
44 /// The same as `IsValid()`.
45 explicit operator bool() const noexcept;
46 /// Whether the file descriptor is valid.
47 bool IsValid() const noexcept;
48
49 /// If IsValid(), get file descriptor.
50 int GetFd() const;
51
52 /// When you're done with fd, call Invalidate(). It unregisters the fd, after
53 /// that you have to call close(2) by yourself. After Invalidate() you may not
54 /// call Wait().
55 void Invalidate();
56
57 /// Setup fd and kind to wait for. After Reset() you may call Wait().
58 /// FdPoller does not take the ownership of `fd`, you still have to close `fd`
59 /// when you're done.
60 void Reset(int fd, Kind kind);
61
62 /// Wait for an event kind that was passed in the latest Reset() call. If the
63 /// operation (read/write) can already be handled, Wait() returns
64 /// immediately. You have to call Reset() at least once before call to
65 /// Wait().
66 [[nodiscard]] std::optional<Kind> Wait(Deadline);
67
68 /// Reset "ready" flag for WaitAny().
69 void ResetReady() noexcept;
70
71 /// Get event kind that was triggered on this poller.
72 /// Resets "ready" flag.
73 std::optional<FdPoller::Kind> GetReady() noexcept;
74
75 /// @cond
76 // For internal use only.
77 engine::impl::ContextAccessor* TryGetContextAccessor() noexcept;
78 /// @endcond
79
80 private:
81 friend class impl::Direction;
82
83 enum class State : int {
84 kInvalid,
85 kReadyToUse,
86 kInUse, /// < used only in debug to detect invalid concurrent usage
87 };
88
89 void WakeupWaiters();
90 void SwitchStateToInUse();
91 void SwitchStateToReadyToUse();
92
93 struct Impl;
94 utils::FastPimpl<Impl, 144, 16> pimpl_;
95};
96
97} // namespace engine::io
98
99USERVER_NAMESPACE_END