forked from I2P_Developers/i2p.i2p
merge of '01e66d36ba6e97474a6a11980be54d55d4897219'
and '6bdb396ca63eea516f2f5ada93d4d8d94ad76b77'
This commit is contained in:
@ -0,0 +1,15 @@
|
||||
package net.i2p.client.streaming;
|
||||
|
||||
import net.i2p.client.streaming.I2PSocket;
|
||||
import net.i2p.client.streaming.I2PSocketManager;
|
||||
import net.i2p.I2PException;
|
||||
import java.net.ConnectException;
|
||||
import java.nio.channels.SelectableChannel;
|
||||
|
||||
public abstract class AcceptingChannel extends SelectableChannel {
|
||||
abstract I2PSocket accept() throws I2PException, ConnectException;
|
||||
I2PSocketManager _socketManager;
|
||||
AcceptingChannel(I2PSocketManager manager) {
|
||||
this._socketManager = manager;
|
||||
}
|
||||
}
|
@ -31,6 +31,8 @@ public interface I2PServerSocket {
|
||||
*/
|
||||
public I2PSocket accept() throws I2PException, ConnectException, SocketTimeoutException;
|
||||
|
||||
public AcceptingChannel getChannel();
|
||||
|
||||
/**
|
||||
* Set Sock Option accept timeout
|
||||
* @param x timeout in ms
|
||||
|
@ -0,0 +1,141 @@
|
||||
package net.i2p.client.streaming;
|
||||
|
||||
import net.i2p.I2PException;
|
||||
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.ConnectException;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.ClosedChannelException;
|
||||
import java.nio.channels.SelectableChannel;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.Selector;
|
||||
import java.nio.channels.spi.AbstractSelectionKey;
|
||||
import java.nio.channels.spi.SelectorProvider;
|
||||
|
||||
public class AcceptingChannelImpl extends AcceptingChannel {
|
||||
boolean _isRegistered = false;
|
||||
SelectionKey whichKey = null;
|
||||
SelectorProvider provider = null;
|
||||
Selector sel = null;
|
||||
Object lock = null;
|
||||
I2PSocket next = null;
|
||||
I2PServerSocket socket;
|
||||
|
||||
I2PSocket accept() throws I2PException, ConnectException {
|
||||
I2PSocket sock;
|
||||
try {
|
||||
sock = socket.accept();
|
||||
} catch(SocketTimeoutException ex) {
|
||||
return null;
|
||||
}
|
||||
I2PSocket temp = next;
|
||||
next = sock;
|
||||
return temp;
|
||||
}
|
||||
|
||||
AcceptingChannelImpl(I2PSocketManager manager) {
|
||||
super(manager);
|
||||
// this cheats and just sets the manager timeout low in order to repeatedly poll it.
|
||||
// that means we can "only" accept one new connection every 100 milliseconds.
|
||||
socket = manager.getServerSocket();
|
||||
socket.setSoTimeout(100);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectorProvider provider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int validOps() {
|
||||
return SelectionKey.OP_ACCEPT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRegistered() {
|
||||
return _isRegistered;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectionKey keyFor(Selector arg0) {
|
||||
return whichKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectionKey register(final Selector sel, final int ops, Object lock) throws ClosedChannelException {
|
||||
this.sel = sel;
|
||||
this.provider = sel.provider();
|
||||
this.lock = lock;
|
||||
this._isRegistered = true;
|
||||
final AcceptingChannel that = this; // lol java
|
||||
SelectionKey key = new AbstractSelectionKey() {
|
||||
int operations = ops;
|
||||
@Override
|
||||
public SelectableChannel channel() {
|
||||
return that;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Selector selector() {
|
||||
return sel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int interestOps() {
|
||||
return this.operations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectionKey interestOps(int ops) {
|
||||
this.operations = ops;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readyOps() {
|
||||
if((operations & OP_ACCEPT) != 0)
|
||||
if(next != null) {
|
||||
return OP_ACCEPT;
|
||||
} else {
|
||||
try {
|
||||
accept(); // ping it again.
|
||||
} catch(I2PException ex) {
|
||||
} catch(ConnectException ex) {}
|
||||
if(next != null)
|
||||
return OP_ACCEPT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
key.attach(lock);
|
||||
// I... THINK this is right?
|
||||
sel.keys().add(key);
|
||||
return key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SelectableChannel configureBlocking(boolean blocking) throws IOException {
|
||||
if (blocking == false) {
|
||||
return this;
|
||||
}
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBlocking() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object blockingLock() {
|
||||
return this.lock;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void implCloseChannel() throws IOException {
|
||||
if(next != null) {
|
||||
next.close();
|
||||
}
|
||||
_socketManager.destroySocketManager();
|
||||
}
|
||||
}
|
@ -24,6 +24,10 @@ class I2PServerSocketFull implements I2PServerSocket {
|
||||
public I2PSocket accept() throws I2PException, SocketTimeoutException {
|
||||
return _socketManager.receiveSocket();
|
||||
}
|
||||
|
||||
public AcceptingChannel getChannel() {
|
||||
return new AcceptingChannelImpl(_socketManager);
|
||||
}
|
||||
|
||||
public long getSoTimeout() {
|
||||
return _socketManager.getConnectionManager().getSoTimeout();
|
||||
|
Reference in New Issue
Block a user