package org.playorm.nio.impl.cm.basic;
import java.io.IOException;
import java.net.PortUnreachableException;
import java.nio.ByteBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.playorm.nio.api.handlers.OperationCallback;
public class WriteRunnable implements DelayedWritesCloses {
private static final Logger apiLog = Logger.getLogger(OperationCallback.class.getName());
private static final Logger log = Logger.getLogger(WriteRunnable.class.getName());
private ByteBuffer buffer;
private OperationCallback handler;
private BasChannelImpl channel;
public WriteRunnable(BasChannelImpl c, ByteBuffer b, OperationCallback h) {
channel = c;
buffer = b;
handler = h;
}
public boolean runDelayedAction(boolean isSelectorThread) {
try {
channel.writeImpl(buffer);
//log.info("count="+count+++" remain="+buffer.remaining()+" wasRemain="+remain);
// log.info(channel+"CCwriter thread id="+id);
} catch(PortUnreachableException e) {
//if a client sends a stream of udp, we fire a failure for each one, but only log it
//at the finest level as these are not really devastating sometimes. They are really just
//telling someone that you are sending to a bad port or bad host or unreachable host
log.log(Level.FINEST, channel+"Client sent data to a host or port that is not listening " +
"to udp, or udp can't get through to that machine", e);
handler.failed(channel, e);
} catch(Exception e) {
log.log(Level.WARNING, channel+"Fire failure to client", e);
handler.failed(channel, e);
//we failed so return that the write was tried...no more data is going out
//at least I don't think so...is it different when getting an icmp(PortUnreachableException)?
return true;
}
if(buffer.hasRemaining())
return false;
if(apiLog.isLoggable(Level.FINER))
log.finer(channel+"WriteCloseCallback.finished called on client");
try {
handler.finished(channel);
} catch(IOException e) {
log.log(Level.WARNING, "Exception firing finished", e);
}
return true;
}
}