Author: fhanik Date: Sat Apr 5 13:44:42 2008 New Revision: 645175 URL: http://svn.apache.org/viewvc?rev=645175&view=rev Log: Implement asynchronous callbacks for CometEvent.close and CometEvent.setTimeout to avoid connections with very long timeouts getting stuck CometProcessor implements servlet interface, or the code will fail deployment if no keepalive, close the connection after comet transaction is complete
Modified: tomcat/trunk/java/org/apache/catalina/CometProcessor.java tomcat/trunk/java/org/apache/catalina/connector/CometEventImpl.java tomcat/trunk/java/org/apache/catalina/connector/Request.java tomcat/trunk/java/org/apache/coyote/ActionCode.java tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Modified: tomcat/trunk/java/org/apache/catalina/CometProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/CometProcessor.java?rev=645175&r1=645174&r2=645175&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/CometProcessor.java (original) +++ tomcat/trunk/java/org/apache/catalina/CometProcessor.java Sat Apr 5 13:44:42 2008 @@ -21,6 +21,7 @@ import java.io.IOException; import javax.servlet.ServletException; +import javax.servlet.Servlet; /** * This interface should be implemented by servlets which would like to handle @@ -29,7 +30,7 @@ * Note: When this interface is implemented, the service method of the servlet will * never be called, and will be replaced with a begin event. */ -public interface CometProcessor { +public interface CometProcessor extends Servlet{ /** * Process the given Comet event. Modified: tomcat/trunk/java/org/apache/catalina/connector/CometEventImpl.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/CometEventImpl.java?rev=645175&r1=645174&r2=645175&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/CometEventImpl.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/CometEventImpl.java Sat Apr 5 13:44:42 2008 @@ -26,6 +26,7 @@ import org.apache.catalina.CometEvent; import org.apache.catalina.util.StringManager; +import org.apache.coyote.ActionCode; public class CometEventImpl implements CometEvent { @@ -92,8 +93,10 @@ if (request == null) { throw new IllegalStateException(sm.getString("cometEvent.nullRequest")); } + boolean iscomet = request.isComet(); request.setComet(false); response.finishResponse(); + if (iscomet) request.cometClose(); } public EventSubType getEventSubType() { @@ -116,6 +119,7 @@ UnsupportedOperationException { if (request.getAttribute("org.apache.tomcat.comet.timeout.support") == Boolean.TRUE) { request.setAttribute("org.apache.tomcat.comet.timeout", new Integer(timeout)); + if (request.isComet()) request.setCometTimeout((long)timeout); } else { throw new UnsupportedOperationException(); } Modified: tomcat/trunk/java/org/apache/catalina/connector/Request.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Request.java?rev=645175&r1=645174&r2=645175&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/Request.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/Request.java Sat Apr 5 13:44:42 2008 @@ -2256,6 +2256,13 @@ return (inputBuffer.available() > 0); } + public void cometClose() { + coyoteRequest.action(ActionCode.ACTION_COMET_CLOSE,getEvent()); + } + + public void setCometTimeout(long timeout) { + coyoteRequest.action(ActionCode.ACTION_COMET_SETTIMEOUT,new Long(timeout)); + } // ------------------------------------------------------ Protected Methods Modified: tomcat/trunk/java/org/apache/coyote/ActionCode.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ActionCode.java?rev=645175&r1=645174&r2=645175&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/ActionCode.java (original) +++ tomcat/trunk/java/org/apache/coyote/ActionCode.java Sat Apr 5 13:44:42 2008 @@ -141,7 +141,7 @@ /** - * Callback for begin Comet processing + * Callback for end Comet processing */ public static final ActionCode ACTION_COMET_END = new ActionCode(22); @@ -151,7 +151,16 @@ */ public static final ActionCode ACTION_AVAILABLE = new ActionCode(23); + /** + * Callback for an asynchronous close of the Comet event + */ + public static final ActionCode ACTION_COMET_CLOSE = new ActionCode(24); + /** + * Callback for setting the timeout asynchronously + */ + public static final ActionCode ACTION_COMET_SETTIMEOUT = new ActionCode(25); + // ----------------------------------------------------------- Constructors int code; Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java?rev=645175&r1=645174&r2=645175&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java Sat Apr 5 13:44:42 2008 @@ -1205,6 +1205,10 @@ comet = true; } else if (actionCode == ActionCode.ACTION_COMET_END) { comet = false; + } else if (actionCode == ActionCode.ACTION_COMET_CLOSE) { + //no op + } else if (actionCode == ActionCode.ACTION_COMET_SETTIMEOUT) { + //no op } } Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java?rev=645175&r1=645174&r2=645175&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java Sat Apr 5 13:44:42 2008 @@ -777,7 +777,8 @@ return SocketState.CLOSED; } else if (!comet) { recycle(); - return SocketState.OPEN; + //pay attention to the keep alive flag set in process() + return (keepAlive)?SocketState.OPEN:SocketState.CLOSED; } else { return SocketState.LONG; } @@ -1219,6 +1220,21 @@ comet = true; } else if (actionCode == ActionCode.ACTION_COMET_END) { comet = false; + } else if (actionCode == ActionCode.ACTION_COMET_CLOSE) { + NioEndpoint.KeyAttachment attach = (NioEndpoint.KeyAttachment)socket.getAttachment(false); + attach.setCometOps(NioEndpoint.OP_CALLBACK); + //notify poller if not on a tomcat thread + RequestInfo rp = request.getRequestProcessor(); + if ( rp.getStage() != org.apache.coyote.Constants.STAGE_SERVICE ) //async handling + socket.getPoller().cometInterest(socket); + } else if (actionCode == ActionCode.ACTION_COMET_SETTIMEOUT) { + if (param==null) return; + NioEndpoint.KeyAttachment attach = (NioEndpoint.KeyAttachment)socket.getAttachment(false); + long timeout = ((Long)param).longValue(); + //if we are not piggy backing on a worker thread, set the timeout + RequestInfo rp = request.getRequestProcessor(); + if ( rp.getStage() != org.apache.coyote.Constants.STAGE_SERVICE ) //async handling + attach.setTimeout(timeout); } } Modified: tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java?rev=645175&r1=645174&r2=645175&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Sat Apr 5 13:44:42 2008 @@ -1635,6 +1635,7 @@ protected void reg(SelectionKey sk, KeyAttachment attachment, int intops) { sk.interestOps(intops); attachment.interestOps(intops); + attachment.setCometOps(intops); } protected void timeout(int keyCount, boolean hasEvents) { @@ -1659,6 +1660,7 @@ } else if ( ka.getError() ) { cancelledKey(key, SocketStatus.ERROR,true); } else if (ka.getComet() && ka.getCometNotify() ) { + ka.setCometNotify(false); reg(key,ka,0);//avoid multiple calls, this gets reregistered after invokation //if (!processSocket(ka.getChannel(), SocketStatus.OPEN_CALLBACK)) processSocket(ka.getChannel(), SocketStatus.DISCONNECT); if (!processSocket(ka.getChannel(), SocketStatus.OPEN)) processSocket(ka.getChannel(), SocketStatus.DISCONNECT); --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]