3333import java .util .Map ;
3434import java .util .Set ;
3535import java .util .concurrent .ConcurrentHashMap ;
36+ import java .util .concurrent .atomic .AtomicInteger ;
3637
3738final class AFSelector extends AbstractSelector {
3839 private final AFPipe selectorPipe ;
@@ -41,13 +42,15 @@ final class AFSelector extends AbstractSelector {
4142 private final ByteBuffer pipeMsgWakeUp = ByteBuffer .allocate (1 );
4243 private final ByteBuffer pipeMsgReceiveBuffer = ByteBuffer .allocateDirect (256 );
4344
44- private final Map <AFSelectionKey , Boolean > keysRegistered = new ConcurrentHashMap <>();
45+ private final Map <AFSelectionKey , Integer > keysRegistered = new ConcurrentHashMap <>();
4546 private final Set <AFSelectionKey > keysRegisteredKeySet = keysRegistered .keySet ();
4647 private final Set <SelectionKey > keysRegisteredPublic = Collections .unmodifiableSet (
4748 keysRegisteredKeySet );
4849
49- private final Map <SelectionKey , SelectionKey > selectedKeysSet = new ConcurrentHashMap <>();
50- private final Set <SelectionKey > selectedKeysPublic = new UngrowableSet <>(selectedKeysSet .keySet ());
50+ private final AtomicInteger selectCount = new AtomicInteger (0 );
51+ private final MapValueSet <SelectionKey , Integer > selectedKeysSet =
52+ new MapValueSet <SelectionKey , Integer >(keysRegistered , selectCount ::get , 0 );
53+ private final Set <SelectionKey > selectedKeysPublic = new UngrowableSet <>(selectedKeysSet );
5154
5255 private PollFd pollFd = null ;
5356
@@ -63,7 +66,7 @@ protected SelectionKey register(AbstractSelectableChannel ch, int ops, Object at
6366 AFSelectionKey key = new AFSelectionKey (this , ch , ops , att );
6467 synchronized (this ) {
6568 pollFd = null ;
66- keysRegistered . put (key , Boolean . TRUE );
69+ selectedKeysSet . markRemoved (key );
6770 }
6871 return key ;
6972 }
@@ -106,12 +109,15 @@ public int select() throws IOException {
106109 @ SuppressWarnings ("PMD.CognitiveComplexity" )
107110 private int select0 (int timeout ) throws IOException {
108111 PollFd pfd ;
112+
113+ int selectId = updateSelectCount ();
114+
109115 synchronized (this ) {
110116 if (!isOpen ()) {
111117 throw new ClosedSelectorException ();
112118 }
119+
113120 pfd = pollFd = initPollFd (pollFd );
114- selectedKeysSet .clear ();
115121 }
116122 int num ;
117123 try {
@@ -121,7 +127,6 @@ private int select0(int timeout) throws IOException {
121127 end ();
122128 }
123129 synchronized (this ) {
124- selectedKeysSet .clear ();
125130 pfd = pollFd ;
126131 if (pfd != null ) {
127132 AFSelectionKey [] keys = pfd .keys ;
@@ -138,7 +143,7 @@ private int select0(int timeout) throws IOException {
138143 }
139144 if (num > 0 ) {
140145 consumeAllBytesAfterPoll ();
141- setOpsReady (pfd ); // updates keysSelected and numKeysSelected
146+ setOpsReady (pfd , selectId ); // updates keysSelected and numKeysSelected
142147 }
143148 return selectedKeysSet .size ();
144149 }
@@ -178,14 +183,24 @@ private synchronized void consumeAllBytesAfterPoll() throws IOException {
178183 }
179184 }
180185
181- private synchronized void setOpsReady (PollFd pfd ) {
186+ private int updateSelectCount () {
187+ int selectId = selectCount .incrementAndGet ();
188+ if (selectId == 0 ) {
189+ // overflow (unlikely)
190+ selectedKeysSet .markAllRemoved ();
191+ selectId = selectCount .incrementAndGet ();
192+ }
193+ return selectId ;
194+ }
195+
196+ private void setOpsReady (PollFd pfd , int selectId ) {
182197 if (pfd != null ) {
183198 for (int i = 1 ; i < pfd .rops .length ; i ++) {
184199 int rops = pfd .rops [i ];
185200 AFSelectionKey key = pfd .keys [i ];
186201 key .setOpsReady (rops );
187202 if (rops != 0 ) {
188- selectedKeysSet . put (key , key );
203+ keysRegistered . computeIfPresent (key , ( k , v ) -> selectId );
189204 }
190205 }
191206 }
0 commit comments