11/*
2- * Copyright (c) 2008, 2023 , Oracle and/or its affiliates. All rights reserved.
3- * Copyright (c) 2012 SAP SE. All rights reserved.
2+ * Copyright (c) 2008, 2024 , Oracle and/or its affiliates. All rights reserved.
3+ * Copyright (c) 2012, 2024 SAP SE. All rights reserved.
44 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55 *
66 * This code is free software; you can redistribute it and/or modify it
2626
2727package sun .nio .ch ;
2828
29- import java .nio .channels .spi .AsynchronousChannelProvider ;
30- import sun .nio .ch .Pollset ;
29+ import java .io .FileDescriptor ;
3130import java .io .IOException ;
32- import java .util .HashSet ;
33- import java .util .Iterator ;
31+ import java .nio .channels .spi .AsynchronousChannelProvider ;
3432import java .util .concurrent .ArrayBlockingQueue ;
35- import java .util .concurrent .RejectedExecutionException ;
3633import java .util .concurrent .atomic .AtomicInteger ;
3734import java .util .concurrent .locks .ReentrantLock ;
35+ import java .util .concurrent .RejectedExecutionException ;
36+ import java .util .HashSet ;
37+ import java .util .Iterator ;
38+ import sun .nio .ch .IOUtil ;
39+ import sun .nio .ch .Pollset ;
3840
3941/**
4042 * AsynchronousChannelGroup implementation based on the AIX pollset framework.
@@ -141,6 +143,8 @@ static class ControlEvent {
141143 sv = new int [2 ];
142144 try {
143145 Pollset .socketpair (sv );
146+ // make the reading part of the socket nonblocking, so the drain (drain_all) method works
147+ IOUtil .configureBlocking (IOUtil .newFD (sv [0 ]), false );
144148 // register one end with pollset
145149 Pollset .pollsetCtl (pollset , Pollset .PS_ADD , sv [0 ], Net .POLLIN );
146150 } catch (IOException x ) {
@@ -271,23 +275,21 @@ private void queueControlEvent(ControlEvent ev) {
271275
272276 // Process all events currently stored in the control queue.
273277 private void processControlQueue () {
274- synchronized (controlQueue ) {
275- // On Aix it is only possible to set the event
276- // bits on the first call of pollsetCtl. Later
277- // calls only add bits, but cannot remove them.
278- // Therefore, we always remove the file
279- // descriptor ignoring the error and then add it.
280- Iterator <ControlEvent > iter = controlQueue .iterator ();
281- while (iter .hasNext ()) {
282- ControlEvent ev = iter .next ();
283- Pollset .pollsetCtl (pollset , Pollset .PS_DELETE , ev .fd (), 0 );
284- if (!ev .removeOnly ()) {
285- ev .setError (Pollset .pollsetCtl (pollset , Pollset .PS_MOD , ev .fd (), ev .events ()));
286- }
287- iter .remove ();
278+ // On Aix it is only possible to set the event
279+ // bits on the first call of pollsetCtl. Later
280+ // calls only add bits, but cannot remove them.
281+ // Therefore, we always remove the file
282+ // descriptor ignoring the error and then add it.
283+ Iterator <ControlEvent > iter = controlQueue .iterator ();
284+ while (iter .hasNext ()) {
285+ ControlEvent ev = iter .next ();
286+ Pollset .pollsetCtl (pollset , Pollset .PS_DELETE , ev .fd (), 0 );
287+ if (!ev .removeOnly ()) {
288+ ev .setError (Pollset .pollsetCtl (pollset , Pollset .PS_MOD , ev .fd (), ev .events ()));
288289 }
289- controlQueue . notifyAll ();
290+ iter . remove ();
290291 }
292+ controlQueue .notifyAll ();
291293 }
292294
293295 /*
@@ -306,8 +308,21 @@ private Event poll() throws IOException {
306308 int n ;
307309 controlLock .lock ();
308310 try {
309- n = Pollset .pollsetPoll (pollset , address ,
311+ int m ;
312+ m = n = Pollset .pollsetPoll (pollset , address ,
310313 MAX_EVENTS_TO_POLL , Pollset .PS_NO_TIMEOUT );
314+ while (m -- > 0 ) {
315+ long eventAddress = Pollset .getEvent (address , m );
316+ int fd = Pollset .getDescriptor (eventAddress );
317+
318+ // To emulate one shot semantic we need to remove
319+ // the file descriptor here.
320+ if (fd != sp [0 ] && fd != ctlSp [0 ]) {
321+ synchronized (controlQueue ) {
322+ Pollset .pollsetCtl (pollset , Pollset .PS_DELETE , fd , 0 );
323+ }
324+ }
325+ }
311326 } finally {
312327 controlLock .unlock ();
313328 }
@@ -323,14 +338,6 @@ private Event poll() throws IOException {
323338 long eventAddress = Pollset .getEvent (address , n );
324339 int fd = Pollset .getDescriptor (eventAddress );
325340
326- // To emulate one shot semantic we need to remove
327- // the file descriptor here.
328- if (fd != sp [0 ] && fd != ctlSp [0 ]) {
329- synchronized (controlQueue ) {
330- Pollset .pollsetCtl (pollset , Pollset .PS_DELETE , fd , 0 );
331- }
332- }
333-
334341 // wakeup
335342 if (fd == sp [0 ]) {
336343 if (wakeupCount .decrementAndGet () == 0 ) {
@@ -350,7 +357,7 @@ private Event poll() throws IOException {
350357 // wakeup to process control event
351358 if (fd == ctlSp [0 ]) {
352359 synchronized (controlQueue ) {
353- Pollset . drain1 (ctlSp [0 ]);
360+ IOUtil . drain (ctlSp [0 ]);
354361 processControlQueue ();
355362 }
356363 if (n > 0 ) {
0 commit comments