Skip to content

Instantly share code, notes, and snippets.

@jaredpar
Forked from anonymous/SelectorWrapper.java
Created February 14, 2014 21:29
Show Gist options
  • Save jaredpar/9009709 to your computer and use it in GitHub Desktop.
Save jaredpar/9009709 to your computer and use it in GitHub Desktop.
package com.koushikdutta.async;
import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Set;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/**
* Created by koush on 2/13/14.
*/
public class SelectorWrapper {
private Selector selector;
boolean isWaking;
Semaphore semaphore = new Semaphore(0);
public Selector getSelector() {
return selector;
}
public SelectorWrapper(Selector selector) {
this.selector = selector;
}
public int selectNow() throws IOException {
return selector.selectNow();
}
public void select() throws IOException {
select(0);
}
public void select(long timeout) throws IOException {
try {
semaphore.drainPermits();
selector.select(timeout);
}
finally {
semaphore.release(Integer.MAX_VALUE);
}
}
public Set<SelectionKey> keys() {
return selector.keys();
}
public Set<SelectionKey> selectedKeys() {
return selector.selectedKeys();
}
public void close() throws IOException {
selector.close();
}
public boolean isOpen() {
return selector.isOpen();
}
public void wakeupOnce() {
// see if it is selecting, ie, can't acquire a permit
boolean selecting = !semaphore.tryAcquire();
selector.wakeup();
// if it was selecting, then the wakeup definitely worked.
if (selecting)
return;
// now, we NEED to wait for the select to start to forcibly wake it.
synchronized (this) {
// check if another thread is already waiting
if (isWaking) {
// System.out.println("race wakeup already progressing");
return;
}
isWaking = true;
}
try {
// System.out.println("performing race wakup");
// try to wake up 10 times
for (int i = 0; i < 100; i++) {
try {
if (semaphore.tryAcquire(10, TimeUnit.MILLISECONDS)) {
// System.out.println("race wakeup success");
return;
}
}
catch (InterruptedException e) {
}
selector.wakeup();
}
}
finally {
synchronized (this) {
isWaking = false;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment