Skip to content

Commit 889ca99

Browse files
committed
Fix concurrency issue with AFSelector
Clients may iterate upon AFSelector.selectedKeys() while the selected keys are modified in another thread. Change the underlying datastructure to be thread-safe (use ConcurrentHashMap), and add all "ready" selectors even if they're marked invalid (they will be removed later). We reimplement the fix as the original patch caused a FileDescriptor leak and TIPC test failures. #142 #145
1 parent 4b2bfc8 commit 889ca99

1 file changed

Lines changed: 5 additions & 6 deletions

File tree

junixsocket-common/src/main/java/org/newsclub/net/unix/AFSelector.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import java.nio.channels.spi.AbstractSelectableChannel;
3030
import java.nio.channels.spi.AbstractSelector;
3131
import java.util.Collections;
32-
import java.util.HashSet;
3332
import java.util.Iterator;
3433
import java.util.Map;
3534
import java.util.Set;
@@ -47,8 +46,8 @@ final class AFSelector extends AbstractSelector {
4746
private final Set<SelectionKey> keysRegisteredPublic = Collections.unmodifiableSet(
4847
keysRegisteredKeySet);
4948

50-
private final Set<SelectionKey> selectedKeysSet = new HashSet<>();
51-
private final Set<SelectionKey> selectedKeysPublic = new UngrowableSet<>(selectedKeysSet);
49+
private final Map<SelectionKey, SelectionKey> selectedKeysSet = new ConcurrentHashMap<>();
50+
private final Set<SelectionKey> selectedKeysPublic = new UngrowableSet<>(selectedKeysSet.keySet());
5251

5352
private PollFd pollFd = null;
5453

@@ -185,8 +184,8 @@ private synchronized void setOpsReady(PollFd pfd) {
185184
int rops = pfd.rops[i];
186185
AFSelectionKey key = pfd.keys[i];
187186
key.setOpsReady(rops);
188-
if (rops != 0 && key.isValid()) {
189-
selectedKeysSet.add(key);
187+
if (rops != 0) {
188+
selectedKeysSet.put(key, key);
190189
}
191190
}
192191
}
@@ -197,7 +196,7 @@ private PollFd initPollFd(PollFd existingPollFd) throws IOException {
197196
synchronized (this) {
198197
for (Iterator<AFSelectionKey> it = keysRegisteredKeySet.iterator(); it.hasNext();) {
199198
AFSelectionKey key = it.next();
200-
if (!key.getAFCore().fd.valid() || key.hasOpInvalid()) {
199+
if (!key.getAFCore().fd.valid() || !key.isValid()) {
201200
key.cancelNoRemove();
202201
it.remove();
203202
existingPollFd = null;

0 commit comments

Comments
 (0)