[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