View Javadoc
1   /*
2    * Copyright 2024 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://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, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.channel.uring;
17  
18  import io.netty.channel.IoOps;
19  
20  /**
21   * {@link IoOps} for implementation for
22   * <a href="https://github.com/axboe/liburing/blob/liburing-2.6/src/include/liburing/io_uring.h">IO_uring</a>.
23   */
24  public final class IoUringIoOps implements IoOps {
25  
26      private final byte opcode;
27      private final int flags;
28      private final short ioPrio;
29      private final int fd;
30      private final int rwFlags;
31      private final long bufferAddress;
32      private final int length;
33      private final long offset;
34      private final short data;
35  
36      /**
37       * Create a new instance
38       *
39       * @param opcode        the operation.
40       * @param flags         the flags
41       * @param ioPrio        the priority.
42       * @param fd            the filedescriptor.
43       * @param rwFlags       the flags specific for the op.
44       * @param bufferAddress the bufferaddress
45       * @param length        the length
46       * @param offset        the offset.
47       * @param data          the user data that will be passed back on completion.
48       */
49      public IoUringIoOps(byte opcode, int flags, short ioPrio, int fd, int rwFlags, long bufferAddress,
50                          int length, long offset, short data) {
51          this.opcode = opcode;
52          this.flags = flags;
53          this.ioPrio = ioPrio;
54          this.fd = fd;
55          this.rwFlags = rwFlags;
56          this.bufferAddress = bufferAddress;
57          this.length = length;
58          this.offset = offset;
59          this.data = data;
60      }
61  
62      /**
63       * Returns the filedescriptor.
64       *
65       * @return  fd
66       */
67      public int fd() {
68          return fd;
69      }
70  
71      /**
72       * Returns the opcode.
73       *
74       * @return  opcode
75       */
76      public byte opcode() {
77          return opcode;
78      }
79  
80      /**
81       * Returns the flags that will be applied.
82       *
83       * @return  flags
84       */
85      public int flags() {
86          return flags;
87      }
88  
89      /**
90       * Returns the priority.
91       *
92       * @return ioPrio
93       */
94      public short ioPrio() {
95          return ioPrio;
96      }
97  
98      /**
99       * Returns the rwFlags that will be applied. These are specific to the opcode.
100      *
101      * @return  rwFlags
102      */
103     public int rwFlags() {
104         return rwFlags;
105     }
106 
107     /**
108      * Returns the bufferAddress that will be used. This is specific to the opcode.
109      *
110      * @return  bufferAddress
111      */
112     public long bufferAddress() {
113         return bufferAddress;
114     }
115 
116     /**
117      * Returns the length that will be used. This is specific to the opcode.
118      *
119      * @return  length
120      */
121     public int length() {
122         return length;
123     }
124 
125     /**
126      * Returns the offset that will be used. This is specific to the opcode.
127      *
128      * @return  offset
129      */
130     public long offset() {
131         return offset;
132     }
133 
134     /**
135      * Returns the data that the user attached to the op. This data will be passed back on completion.
136      *
137      * @return  data
138      */
139     public short data() {
140         return data;
141     }
142 
143     @Override
144     public String toString() {
145         return "IOUringIoOps{" +
146                 "opcode=" + opcode +
147                 ", flags=" + flags +
148                 ", ioPrio=" + ioPrio +
149                 ", fd=" + fd +
150                 ", rwFlags=" + rwFlags +
151                 ", bufferAddress=" + bufferAddress +
152                 ", length=" + length +
153                 ", offset=" + offset +
154                 ", data=" + data +
155                 '}';
156     }
157 
158     /**
159      * Returns a new {@code OP_ASYNC_CANCEL} {@link IoUringIoOps}.
160      *
161      * @param fd        the filedescriptor
162      * @param flags     the flags.
163      * @param userData  the user data that identify a previous submitted {@link IoUringIoOps} that should be cancelled.
164      *                  The value to use here is returned by {@link IoUringIoRegistration#submit(IoOps)}.
165      * @param data      the data
166      * @return          ops.
167      */
168     public static IoUringIoOps newAsyncCancel(int fd, int flags, long userData, short data) {
169         // Best effort to cancel the
170         return new IoUringIoOps(Native.IORING_OP_ASYNC_CANCEL, flags, (short) 0, fd, 0,
171                 userData, 0, 0, data);
172     }
173 
174     /**
175      * Returns a new {@code OP_CLOSE} {@link IoUringIoOps}.
176      *
177      * @param fd        the filedescriptor
178      * @param flags     the flags.
179      * @param data      the data
180      * @return          ops.
181      */
182     public static IoUringIoOps newClose(int fd, int flags, short data) {
183         return new IoUringIoOps(Native.IORING_OP_CLOSE, flags, (short) 0, fd, 0, 0, 0, 0, data);
184     }
185 
186     /**
187      * Returns a new {@code OP_POLL_ADD} {@link IoUringIoOps}.
188      *
189      * @param fd        the filedescriptor
190      * @param flags     the flags.
191      * @param mask      the mask.
192      * @param data      the data
193      * @return          ops.
194      */
195     public static IoUringIoOps newPollAdd(int fd, int flags, int mask, short data) {
196         return new IoUringIoOps(Native.IORING_OP_POLL_ADD, flags, (short) 0, fd, mask, 0, 0, 0, data);
197     }
198 
199     /**
200      * Returns a new {@code OP_SENDMSG} {@link IoUringIoOps}.
201      *
202      * @param fd        the filedescriptor
203      * @param flags     the flags.
204      * @param msgFlags  the msg flags.
205      * @param data      the data
206      * @return          ops.
207      */
208     public static IoUringIoOps newSendmsg(int fd, int flags, int msgFlags, long address, short data) {
209         return new IoUringIoOps(Native.IORING_OP_SENDMSG, flags, (short) 0, fd, msgFlags, address, 1, 0, data);
210     }
211 
212     /**
213      * Returns a new {@code OP_CONNECT} {@link IoUringIoOps}.
214      *
215      * @param fd                    the filedescriptor
216      * @param flags                 the flags.
217      * @param remoteMemoryAddress   the memory address of the sockaddr_storage.
218      * @param data                  the data
219      * @return                      ops.
220      */
221     public static IoUringIoOps newConnect(int fd, int flags, long remoteMemoryAddress, short data) {
222         return new IoUringIoOps(Native.IORING_OP_CONNECT, flags, (short) 0, fd, 0, remoteMemoryAddress,
223                 0, Native.SIZEOF_SOCKADDR_STORAGE, data);
224     }
225 
226     /**
227      * Returns a new {@code OP_POLL_REMOVE} {@link IoUringIoOps}.
228      *
229      * @param fd        the filedescriptor
230      * @param flags     the flags.
231      * @param userData  the user data that identify a previous submitted {@link IoUringIoOps} that should be cancelled.
232      *                  The value to use here is returned by {@link IoUringIoRegistration#submit(IoOps)}.
233      * @param data      the data
234      * @return          ops.
235      */
236     public static IoUringIoOps newPollRemove(int fd, int flags, long userData, short data) {
237         return new IoUringIoOps(Native.IORING_OP_POLL_REMOVE, flags, (short) 0, fd, 0, userData, 0, 0, data);
238     }
239 
240     /**
241      * Returns a new {@code OP_ACCEPT} {@link IoUringIoOps}.
242      *
243      * @param fd                                    the filedescriptor
244      * @param flags                                 the flags.
245      * @param acceptedAddressMemoryAddress          the memory address of the sockaddr_storage.
246      * @param acceptedAddressLengthMemoryAddress    the memory address of the length that will be updated once a new
247      *                                              connection was accepted.
248      * @param data                                  the data
249      * @return                                      ops.
250      */
251     public static IoUringIoOps newAccept(int fd, int flags, int acceptFlags, long acceptedAddressMemoryAddress,
252                                          long acceptedAddressLengthMemoryAddress, short data) {
253         return new IoUringIoOps(Native.IORING_OP_ACCEPT, flags, (short) 0, fd, acceptFlags,
254                 acceptedAddressMemoryAddress, 0, acceptedAddressLengthMemoryAddress, data);
255     }
256 
257     /**
258      * Returns a new {@code OP_WRITEV} {@link IoUringIoOps}.
259      *
260      * @param fd                                    the filedescriptor
261      * @param flags                                 the flags.
262      * @param writevFlags                           the writev flags.
263      * @param memoryAddress                         the memory address of the io_vec array.
264      * @param length                                the length of the io_vec array.
265      * @param data                                  the data
266      * @return                                      ops.
267      */
268     public static IoUringIoOps newWritev(int fd, int flags, int writevFlags, long memoryAddress,
269                                          int length, short data) {
270         return new IoUringIoOps(Native.IORING_OP_WRITEV, flags, (short) 0, fd,
271                 writevFlags, memoryAddress, length, 0, data);
272     }
273 
274     /**
275      * Returns a new {@code OP_WRITE} {@link IoUringIoOps}.
276      *
277      * @param fd                                    the filedescriptor
278      * @param flags                                 the flags.
279      * @param writeFlags                            the write flags.
280      * @param memoryAddress                         the memory address of the buffer
281      * @param length                                the length of the buffer.
282      * @param data                                  the data
283      * @return                                      ops.
284      */
285     public static IoUringIoOps newWrite(
286             int fd, int flags, int writeFlags, long memoryAddress, int length, short data) {
287         return new IoUringIoOps(Native.IORING_OP_WRITE, flags, (short) 0, fd,
288                 writeFlags, memoryAddress, length, 0, data);
289     }
290 
291     /**
292      * Returns a new {@code OP_RECV} {@link IoUringIoOps}.
293      *
294      * @param fd                                    the filedescriptor
295      * @param flags                                 the flags.
296      * @param recvFlags                             the recv flags.
297      * @param memoryAddress                         the memory address of the buffer
298      * @param length                                the length of the buffer.
299      * @param data                                  the data
300      * @return                                      ops.
301      */
302     public static IoUringIoOps newRecv(
303             int fd, int flags, int recvFlags, long memoryAddress, int length, short data) {
304         return new IoUringIoOps(
305                 Native.IORING_OP_RECV, flags, (short) 0, fd, recvFlags, memoryAddress, length, 0, data);
306     }
307 
308     /**
309      * Returns a new {@code OP_RECVMSG} {@link IoUringIoOps}.
310      *
311      * @param fd                                    the filedescriptor
312      * @param flags                                 the flags.
313      * @param msgFlags                              the recvmsg flags.
314      * @param memoryAddress                         the memory address of the msghdr struct
315      * @param data                                  the data
316      * @return                                      ops.
317      */
318     public static IoUringIoOps newRecvmsg(int fd, int flags, int msgFlags, long memoryAddress, short data) {
319         return new IoUringIoOps(
320                 Native.IORING_OP_RECVMSG, flags, (short) 0, fd, msgFlags, memoryAddress, 1, 0, data);
321     }
322 
323     /**
324      * Returns a new {@code OP_SEND} {@link IoUringIoOps}.
325      *
326      * @param fd                                    the filedescriptor
327      * @param flags                                 the flags.
328      * @param sendFlags                             the send flags.
329      * @param memoryAddress                         the memory address of the buffer.
330      * @param length                                the length of the buffer.
331      * @param data                                  the data
332      * @return                                      ops.
333      */
334     public static IoUringIoOps newSend(
335             int fd, int flags, int sendFlags, long memoryAddress, int length, short data) {
336         return new IoUringIoOps(
337                 Native.IORING_OP_SEND, flags, (short) 0, fd, sendFlags, memoryAddress, length, 0, data);
338     }
339 
340     /**
341      * Returns a new {@code OP_SHUTDOWN} {@link IoUringIoOps}.
342      *
343      * @param fd                                    the filedescriptor
344      * @param flags                                 the flags.
345      * @param how                                   how the shutdown will be done.
346      * @param data                                  the data
347      * @return                                      ops.
348      */
349     public static IoUringIoOps newShutdown(int fd, int flags, int how, int id, short data) {
350         return new IoUringIoOps(Native.IORING_OP_SHUTDOWN, flags, (short) 0, fd, 0, 0, how, 0, data);
351     }
352 }