1 //
2 // Copyright (C) 2022 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 #include <errno.h>
17 #include <string.h>
18 
19 #include <algorithm>
20 #include <iostream>
21 #include <numeric>
22 #include <type_traits>
23 #include <vector>
24 
25 #ifndef __IO_URING_SQE_CPP_H
26 #define __IO_URING_SQE_CPP_H
27 
28 namespace io_uring_cpp {
29 
30 struct [[nodiscard]] IoUringSubmitResult {
IsOkIoUringSubmitResult31   constexpr bool IsOk() const { return ret > 0; }
ErrMsgIoUringSubmitResult32   const char *ErrMsg() const {
33     if (IsOk()) {
34       return nullptr;
35     }
36     return strerror(-ret);
37   }
ErrCodeIoUringSubmitResult38   constexpr auto ErrCode() const { return std::min(ret, 0); }
EntriesSubmittedIoUringSubmitResult39   constexpr auto EntriesSubmitted() const { return std::max(ret, 0); }
40 
41   int ret;
42 };
43 
44 struct [[nodiscard]] Errno {
ErrnoErrno45   constexpr Errno(int ret) : error_code(ret) {
46     error_code = std::abs(error_code);
47   }
48   int error_code;
ErrCodeErrno49   constexpr int ErrCode() { return error_code; }
50   const char *ErrMsg();
IsOkErrno51   constexpr bool IsOk() const { return error_code == 0; }
52 };
53 
54 std::ostream &operator<<(std::ostream &, Errno err);
55 
56 struct [[nodiscard]] IoUringSQE {
IoUringSQEIoUringSQE57   constexpr IoUringSQE(void *p) : sqe(p) {}
58   IoUringSQE &SetFlags(unsigned int flags);
59   template <typename T>
SetDataIoUringSQE60   IoUringSQE &SetData(const T &data) {
61     static_assert(
62         std::is_trivially_copy_constructible_v<T>,
63         "Only trivially copiable types can be passed for io_uring data");
64     static_assert(sizeof(T) <= 8,
65                   "io_uring SQE's data field has size of 8 bytes, can't pass "
66                   "data larger than that.");
67     return SetData(*reinterpret_cast<const uint64_t*>(&data));
68   }
69   IoUringSQE& SetData(uint64_t data);
70 
IsOkIoUringSQE71   constexpr bool IsOk() const { return sqe != nullptr; }
72 
73  private:
74   void *sqe;
75 };
76 
77 }  // namespace io_uring_cpp
78 
79 #endif
80