1313import net .codecrete .usb .linux .gen .usbdevice_fs .usbdevfs_urb ;
1414
1515import java .lang .foreign .Arena ;
16- import java .lang .foreign .MemoryLayout ;
1716import java .lang .foreign .MemorySegment ;
18- import java .lang .invoke .VarHandle ;
1917import java .util .ArrayList ;
2018import java .util .LinkedHashMap ;
2119import java .util .List ;
@@ -57,11 +55,6 @@ class LinuxAsyncTask {
5755
5856 private static final int NUM_EVENTS = 5 ;
5957
60- private static final VarHandle epoll_event_data_fd$VH = epoll_event .$LAYOUT ().varHandle (
61- MemoryLayout .PathElement .groupElement ("data" ),
62- MemoryLayout .PathElement .groupElement ("fd" )
63- );
64-
6558 private final Arena urbArena = Arena .ofAuto ();
6659 /// available URBs
6760 private final List <MemorySegment > availableURBs = new ArrayList <>();
@@ -87,16 +80,18 @@ private void asyncCompletionTask() {
8780
8881 while (true ) {
8982
83+ // wait for file descriptor to be ready
9084 var res = epoll_wait (epollFd , events , NUM_EVENTS , -1 , errorState );
9185 if (res < 0 ) {
9286 var err = Linux .getErrno (errorState );
9387 if (err == EINTR ())
94- continue ;
88+ continue ; // continue on interrupt
9589 throwException (err , "internal error (epoll_wait)" );
9690 }
9791
92+ // for all ready file descriptors, reap URBs
9893 for (int i = 0 ; i < res ; i ++) {
99- var fd = (int ) epoll_event_data_fd $VH .get (events . asSlice ( epoll_event . sizeof () * i , epoll_event . sizeof ()) );
94+ var fd = (int ) EPoll . EVENT_ARRAY_DATA_FD $VH .get (events , i );
10095 reapURBs (fd , urbPointerHolder , errorState );
10196 }
10297 }
@@ -111,6 +106,7 @@ private void asyncCompletionTask() {
111106 * @param errorState native memory to receive the errno
112107 */
113108 private void reapURBs (int fd , MemorySegment urbPointerHolder , MemorySegment errorState ) {
109+
114110 while (true ) {
115111 var res = IO .ioctl (fd , REAPURBNDELAY , urbPointerHolder , errorState );
116112 if (res < 0 ) {
@@ -119,7 +115,7 @@ private void reapURBs(int fd, MemorySegment urbPointerHolder, MemorySegment erro
119115 return ; // no more pending URBs
120116 if (err == errno .ENODEV ()) {
121117 // device might have been unplugged
122- removeFdFromAsyncIOCompletion ( fd );
118+ EPoll . removeFileDescriptor ( epollFd , fd );
123119 return ;
124120 }
125121 throwException (err , "internal error (reap URB)" );
@@ -154,13 +150,9 @@ synchronized void removeFromAsyncIOCompletion(LinuxUsbDevice device) {
154150 EPoll .removeFileDescriptor (epollFd , device .fileDescriptor ());
155151 }
156152
157- private synchronized void removeFdFromAsyncIOCompletion (int fd ) {
158- EPoll .removeFileDescriptor (epollFd , fd );
159- }
160-
161153 synchronized void submitTransfer (LinuxUsbDevice device , int endpointAddress , UsbTransferType transferType , LinuxTransfer transfer ) {
162154
163- addURB (transfer );
155+ linkToUrb (transfer );
164156 var urb = transfer .urb ;
165157
166158 usbdevfs_urb .type$set (urb , (byte ) urbTransferType (transferType ));
@@ -188,7 +180,15 @@ private static int urbTransferType(UsbTransferType transferType) {
188180 };
189181 }
190182
191- private void addURB (LinuxTransfer transfer ) {
183+ /**
184+ * Links the specified transfer instance to a URB.
185+ * <p>
186+ * The transfer is assigned an URB instance, and a list
187+ * of associations from URB to transfer is maintained.
188+ * </p>
189+ * @param transfer the transfer to assign a URB.
190+ */
191+ private void linkToUrb (LinuxTransfer transfer ) {
192192 MemorySegment urb ;
193193 var size = availableURBs .size ();
194194 if (size > 0 ) {
@@ -201,6 +201,15 @@ private void addURB(LinuxTransfer transfer) {
201201 transfersByURB .put (urb , transfer );
202202 }
203203
204+ /**
205+ * Gets the transfer associated with the specified URB.
206+ * <p>
207+ * The URB is returned into the list of URBs available for further transfers.
208+ * </p>
209+ *
210+ * @param urb URB instance
211+ * @return transfer associated with the URB
212+ */
204213 @ SuppressWarnings ("java:S2259" )
205214 private synchronized LinuxTransfer getTransferResult (MemorySegment urb ) {
206215 var transfer = transfersByURB .remove (urb );
0 commit comments