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 I2PSocket accept() throws I2PException, ConnectException, SocketTimeoutException;
|
||||||
|
|
||||||
|
public AcceptingChannel getChannel();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set Sock Option accept timeout
|
* Set Sock Option accept timeout
|
||||||
* @param x timeout in ms
|
* @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 {
|
public I2PSocket accept() throws I2PException, SocketTimeoutException {
|
||||||
return _socketManager.receiveSocket();
|
return _socketManager.receiveSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AcceptingChannel getChannel() {
|
||||||
|
return new AcceptingChannelImpl(_socketManager);
|
||||||
|
}
|
||||||
|
|
||||||
public long getSoTimeout() {
|
public long getSoTimeout() {
|
||||||
return _socketManager.getConnectionManager().getSoTimeout();
|
return _socketManager.getConnectionManager().getSoTimeout();
|
||||||
|
Reference in New Issue
Block a user