[SNMP4J] Fix for High CPU usage and SNMP4J DefaultTcpTransportMapping
Jim Snyder
jim.snyder at unboundid.com
Thu Apr 15 22:37:17 CEST 2010
This problem has been seen with other applications, and the underlying cause is an OS/JVM dependency using the Selectors. The fix for this code is listed below, and a summary can be found here ( http://stackoverflow.com/questions/204186/java-nio-select-returns-without-selected-keys-why)
Essentially, once a connection is established, we should remove the registration for OP_CONNECT, and this will prevent the Thread from going into the 100% CPU spin loop.
Can someone at SNMP4J confirm this fix works?
Thanks
Jim Snyder
UnboundID
private void connectChannel(SelectionKey sk, TcpAddress incomingAddress) {
SocketEntry entry = (SocketEntry) sk.attachment();
try {
SocketChannel sc = (SocketChannel) sk.channel();
if (!sc.isConnected()) {
if (sc.finishConnect()) {
sc.configureBlocking(false);
logger.debug("Connected to " + entry.getPeerAddress());
// make sure conncetion is closed if not used for timeout
// micro seconds
timeoutSocket(entry);
// begin fix -------->
entry.removeRegistration(selector, SelectionKey.OP_CONNECT);
// end fix ---------->
entry.addRegistration(selector, SelectionKey.OP_WRITE);
}
else {
entry = null;
}
}
if (entry != null) {
Address addr = (incomingAddress == null) ?
entry.getPeerAddress() : incomingAddress;
logger.debug("Fire connected event for "+addr);
TransportStateEvent e =
new TransportStateEvent(UBIDTcpTransportMapping.this,
addr,
TransportStateEvent.
STATE_CONNECTED,
null);
fireConnectionStateChanged(e);
}
}
catch (IOException iox) {
logger.warn(iox);
sk.cancel();
closeChannel(sk.channel());
if (entry != null) {
pending.remove(entry);
}
}
}
More information about the SNMP4J
mailing list