merge of '01e66d36ba6e97474a6a11980be54d55d4897219'

and '6bdb396ca63eea516f2f5ada93d4d8d94ad76b77'
This commit is contained in:
kytv
2011-11-05 14:30:44 +00:00
4 changed files with 162 additions and 0 deletions

View File

@ -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;
}
}

View File

@ -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

View File

@ -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();
}
}

View File

@ -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();