userver: userver/engine/io/common.hpp Source File
Loading...
Searching...
No Matches
common.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/engine/io/common.hpp
4/// @brief Common definitions and base classes for stream like objects
5
6#include <cstddef>
7#include <memory>
8#include <optional>
9
10#include <userver/engine/deadline.hpp>
11#include <userver/utils/assert.hpp>
12
13USERVER_NAMESPACE_BEGIN
14
15namespace engine::impl {
16class ContextAccessor;
17}
18
19namespace engine::io {
20
21/// File descriptor of an invalid pipe end.
22inline constexpr int kInvalidFd = -1;
23
24/// @ingroup userver_base_classes
25///
26/// Base class for readable stream waiting
28public:
29 virtual ~ReadAwaiter();
30
31 /// Suspends current task until the stream has data available.
32 [[nodiscard]] virtual bool WaitReadable(Deadline) = 0;
33
34 /// For internal use only
35 impl::ContextAccessor* TryGetContextAccessor() { return ca_; }
36
37protected:
38 void SetReadableContextAccessor(impl::ContextAccessor* ca) { ca_ = ca; }
39
40private:
41 impl::ContextAccessor* ca_{nullptr};
42};
43
44/// @ingroup userver_base_classes
45///
46/// Interface for readable streams
47class ReadableBase : public ReadAwaiter {
48public:
49 ~ReadableBase() override;
50
51 /// Whether the stream is valid.
52 virtual bool IsValid() const = 0;
53
54 /// Receives up to len (including zero) bytes from the stream.
55 /// @returns filled-in optional on data presence (e.g. 0, 1, 2... bytes)
56 /// empty optional otherwise
57 [[nodiscard]] virtual std::optional<size_t> ReadNoblock(void* buf, size_t len) {
58 (void)buf;
59 (void)len;
60 UINVARIANT(false, "not implemented yet");
61 return {};
62 }
63
64 /// Receives at least one byte from the stream.
65 [[nodiscard]] virtual size_t ReadSome(void* buf, size_t len, Deadline deadline) = 0;
66
67 /// Receives exactly len bytes from the stream.
68 /// @note Can return less than len if stream is closed by peer.
69 [[nodiscard]] virtual size_t ReadAll(void* buf, size_t len, Deadline deadline) = 0;
70};
71
72/// @ingroup userver_base_classes
73///
74/// Base class for writable stream waiting
76public:
77 virtual ~WriteAwaiter();
78
79 /// Suspends current task until the data is available.
80 [[nodiscard]] virtual bool WaitWriteable(Deadline deadline) = 0;
81
82 /// For internal use only
83 impl::ContextAccessor* TryGetContextAccessor() { return ca_; }
84
85protected:
86 void SetWritableContextAccessor(impl::ContextAccessor* ca) { ca_ = ca; }
87
88private:
89 impl::ContextAccessor* ca_{nullptr};
90};
91
92/// IoData for vector send
93struct IoData final {
94 const void* data;
95 size_t len;
96};
97
98/// @ingroup userver_base_classes
99///
100/// Interface for writable streams
102public:
103 ~WritableBase() override;
104
105 /// @brief Sends exactly len bytes of buf.
106 /// @note Can return less than len if stream is closed by peer.
107 [[nodiscard]] virtual size_t WriteAll(const void* buf, size_t len, Deadline deadline) = 0;
108
109 [[nodiscard]] virtual size_t WriteAll(std::initializer_list<IoData> list, Deadline deadline) {
110 size_t result{0};
111 for (const auto& io_data : list) {
112 result += WriteAll(io_data.data, io_data.len, deadline);
113 }
114 return result;
115 }
116};
117
118/// @ingroup userver_base_classes
119///
120/// Interface for readable and writable streams
121// NOLINTNEXTLINE(fuchsia-multiple-inheritance)
122class RwBase : public ReadableBase, public WritableBase {
123public:
124 ~RwBase() override;
125
126 ReadableBase& GetReadableBase() { return *this; }
127
128 WritableBase& GetWritableBase() { return *this; }
129};
130
131using ReadableBasePtr = std::shared_ptr<ReadableBase>;
132
133} // namespace engine::io
134
135USERVER_NAMESPACE_END