1 /*
  2  * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 
 26 package sun.nio.ch.iouring;
 27 
 28 import java.lang.foreign.MemorySegment;
 29 import java.util.Optional;
 30 import java.util.OptionalInt;
 31 import java.util.OptionalLong;
 32 import java.util.concurrent.CompletableFuture;
 33 
 34 /**
 35  *  Submission Q entry (user view). The setter and getter methods of this
 36  *  class have the same name as the respective field in the io_uring_sqe
 37  *  structure. Support for all fields is not provided yet.
 38  *  The exception is the xxx_flags field. This sets/gets any/all of
 39  *  the 32 bit values in the unnamed union in io_uring_sqe with
 40  *  the large number of 32bit flag variants.
 41  *  <p>
 42  *  The (externally set) user_data field acts as a request id.
 43  *  This (64 bit) value must be unique in the context of operations on
 44  *  the same ring that may overlap, as the same user_data is returned
 45  *  in the {@link Cqe} for that operation.
 46  */
 47 
 48 public class Sqe {
 49     int opcode;
 50     int flags;
 51     OptionalInt xxx_flags;
 52     OptionalInt poll_events;
 53     OptionalInt buf_index;
 54     int fd;
 55     Optional<MemorySegment> addr;
 56     Optional<MemorySegment> addr2;
 57     OptionalInt len;
 58     OptionalLong off;
 59     long user_data;
 60 
 61     public String toString() {
 62         return "[opcode: " + Util.sqe_opcode(opcode) + " user_data: 0x" +
 63                 Long.toHexString(user_data) + " flags: " + flags +
 64                 " addr: " + addr + " addr2: " + addr2 + " xxx_flags: " +
 65                 xxx_flags + " buf_index: " + buf_index + " fd: " +
 66                 fd + " len: " + len + "]";
 67     }
 68 
 69     public Sqe() {
 70         addr = Optional.empty();
 71         addr2 = Optional.empty();
 72         len = OptionalInt.empty();
 73         off = OptionalLong.empty();
 74         xxx_flags = OptionalInt.empty();
 75         poll_events = OptionalInt.empty();
 76         buf_index = OptionalInt.empty();
 77         fd = -1;
 78     }
 79     public OptionalLong off() {
 80         return off;
 81     }
 82 
 83     public Sqe off(long off) {
 84         checkOptionalMemSeg(addr2,
 85             "off may not be set if addr2 is already set");
 86         this.off = OptionalLong.of(off);
 87         return this;
 88     }
 89 
 90     public Sqe buf_index(int index) {
 91         this.buf_index = OptionalInt.of(index);
 92         return this;
 93     }
 94 
 95     public Sqe opcode(int opcode) {
 96         this.opcode = opcode;
 97         return this;
 98     }
 99 
100     Sqe flags(int flags) {
101         this.flags = flags;
102         return this;
103     }
104     public Sqe xxx_flags(int xxx_flags) {
105         checkOptionalInt(poll_events,
106             "poll_events can't be set if xxx_flags is");
107         this.xxx_flags = OptionalInt.of(xxx_flags);
108         return this;
109     }
110     public Sqe poll_events(int poll_events) {
111         checkOptionalInt(xxx_flags,
112             "xxx_flags can't be set if poll_events is");
113         this.poll_events = OptionalInt.of(poll_events);
114         return this;
115     }
116     public Sqe fd(int fd) {
117         this.fd = fd;
118         return this;
119     }
120     public Sqe user_data(long user_data) {
121         this.user_data = user_data;
122         return this;
123     }
124     public Sqe addr(MemorySegment buffer) {
125         this.addr = Optional.of(buffer);
126         return this;
127     }
128 
129     Sqe addr2(MemorySegment buffer) {
130         checkOptionalLong(off, "addr2 can't be set if off is already");
131         this.addr2 = Optional.of(buffer);
132         return this;
133     }
134     private void checkOptionalInt(OptionalInt opt, String exceptionMsg) {
135         if (opt.isPresent())
136             throw new IllegalArgumentException(exceptionMsg);
137     }
138     private void checkOptionalLong(OptionalLong opt, String exceptionmsg) {
139         if (opt.isPresent())
140             throw new IllegalArgumentException(exceptionmsg);
141     }
142     private void checkOptionalMemSeg(Optional<MemorySegment> opt,
143                                      String exceptionMsg) {
144         if (opt.isPresent())
145             throw new IllegalArgumentException(exceptionMsg);
146     }
147     public Sqe len(int len) {
148         this.len = OptionalInt.of(len);
149         return this;
150     }
151 
152     // Getters
153 
154     public int opcode() {
155         return opcode;
156     }
157 
158     public int flags() {
159         return flags;
160     }
161 
162     public OptionalInt xxx_flags() {
163         return xxx_flags;
164     }
165 
166     public OptionalInt poll_events() {
167         return poll_events;
168     }
169 
170     public int fd() {
171         return fd;
172     }
173 
174     public long user_data() {
175         return user_data;
176     }
177 
178     public Optional<MemorySegment> addr() {
179         return addr;
180     }
181 
182     public Optional<MemorySegment> addr2() {
183         return addr2;
184     }
185     public OptionalInt len() {
186         return len;
187     }
188     public OptionalInt buf_index() { return buf_index;}
189 }