You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2006/05/18 20:29:08 UTC
svn commit: r407605 - in /tomcat/tc6.0.x/trunk/java/org/apache: catalina/
catalina/connector/ catalina/servlets/ coyote/ coyote/http11/
tomcat/util/net/
Author: remm
Date: Thu May 18 11:29:07 2006
New Revision: 407605
URL: http://svn.apache.org/viewvc?rev=407605&view=rev
Log:
- Ok, it seems to work at least a little bit (hopefully, nobody tried it before this). Overall, the
changes are fairly limited.
- In the end, I prefer adding a new method in Adapter, although it is easy to change back.
- I'll try to add the examples webapp back, and add the obligatory chat servlet (so lame ...).
Modified:
tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometProcessor.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java
tomcat/tc6.0.x/trunk/java/org/apache/catalina/servlets/CometServlet.java
tomcat/tc6.0.x/trunk/java/org/apache/coyote/Adapter.java
tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java
tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometProcessor.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometProcessor.java?rev=407605&r1=407604&r2=407605&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometProcessor.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/CometProcessor.java Thu May 18 11:29:07 2006
@@ -1,3 +1,20 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
package org.apache.catalina;
import java.io.IOException;
@@ -8,13 +25,56 @@
public interface CometProcessor {
+ /**
+ * Begin will be called by the main service method of the servlet at the beginning
+ * of the processing of the connection. It can be used to initialize any relevant
+ * fields using the request and response objects.
+ *
+ * @param request
+ * @param response
+ * @throws IOException
+ * @throws ServletException
+ */
public void begin(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException;
+
+ /**
+ * End may be called to end the processing of the request. Fields that have
+ * been initialized in the begin method should be reset.
+ *
+ * @param request
+ * @param response
+ * @throws IOException
+ * @throws ServletException
+ */
public void end(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException;
+ /**
+ * Error will be called by the container in the case where an IO exception
+ * or a similar unrecoverable error occurs on the connection. Fields that have
+ * been initialized in the begin method should be reset.
+ *
+ * @param request
+ * @param response
+ * @throws IOException
+ * @throws ServletException
+ */
public void error(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException;
+
+ /**
+ * This indicates that input data is available, and that one read can be made
+ * without blocking. The available and ready methods of the InputStream or
+ * Reader may be used to determine if there is a risk of blocking: the servlet
+ * should read while data is reported available, and can make one additional read
+ * without blocking.
+ *
+ * @param request
+ * @param response
+ * @throws IOException
+ * @throws ServletException
+ */
public void read(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException;
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java?rev=407605&r1=407604&r2=407605&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java Thu May 18 11:29:07 2006
@@ -103,6 +103,56 @@
// -------------------------------------------------------- Adapter Methods
+
+ /**
+ * Event method.
+ *
+ * @return false to indicate an error, expected or not
+ */
+ public boolean event(org.apache.coyote.Request req,
+ org.apache.coyote.Response res, boolean error) {
+
+ Request request = (Request) req.getNote(ADAPTER_NOTES);
+ Response response = (Response) res.getNote(ADAPTER_NOTES);
+
+ if (request.getWrapper() != null) {
+ CometProcessor servlet = null;
+ try {
+ servlet = (CometProcessor) request.getWrapper().allocate();
+ } catch (Throwable t) {
+ log.error(sm.getString("coyoteAdapter.service"), t);
+ request.removeAttribute("org.apache.tomcat.comet");
+ return false;
+ }
+ try {
+ if (error) {
+ servlet.error(request.getRequest(), response.getResponse());
+ } else {
+ servlet.read(request.getRequest(), response.getResponse());
+ }
+ return (!error);
+ } catch (Throwable t) {
+ if (!(t instanceof IOException)) {
+ log.error(sm.getString("coyoteAdapter.service"), t);
+ }
+ request.removeAttribute("org.apache.tomcat.comet");
+ try {
+ servlet.error(request.getRequest(), response.getResponse());
+ } catch (Throwable th) {
+ log.error(sm.getString("coyoteAdapter.service"), th);
+ }
+ return false;
+ } finally {
+ // Recycle the wrapper request and response
+ if (request.getAttribute("org.apache.tomcat.comet") == null) {
+ request.recycle();
+ response.recycle();
+ }
+ }
+ }
+ return true;
+ }
+
/**
* Service method.
@@ -136,29 +186,6 @@
}
- // Comet processing
- if (request.getWrapper() != null
- && request.getWrapper() instanceof CometProcessor) {
- try {
- if (request.getAttribute("org.apache.tomcat.comet.error") != null) {
- ((CometProcessor) request.getWrapper()).error(request.getRequest(), response.getResponse());
- } else {
- ((CometProcessor) request.getWrapper()).read(request.getRequest(), response.getResponse());
- }
- } catch (IOException e) {
- ;
- } catch (Throwable t) {
- log.error(sm.getString("coyoteAdapter.service"), t);
- } finally {
- // Recycle the wrapper request and response
- if (request.getAttribute("org.apache.tomcat.comet") == null) {
- request.recycle();
- response.recycle();
- }
- }
- return;
- }
-
if (connector.getXpoweredBy()) {
response.addHeader("X-Powered-By", "Servlet/2.5");
}
@@ -174,9 +201,8 @@
connector.getContainer().getPipeline().getFirst().invoke(request, response);
}
- if (request.getAttribute("org.apache.tomcat.comet.support") == Boolean.TRUE
- && request.getWrapper() instanceof CometProcessor) {
- request.setAttribute("org.apache.tomcat.comet", Boolean.TRUE);
+ if (request.getAttribute("org.apache.tomcat.comet") == Boolean.TRUE
+ && request.getWrapper().allocate() instanceof CometProcessor) {
comet = true;
}
Modified: tomcat/tc6.0.x/trunk/java/org/apache/catalina/servlets/CometServlet.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/catalina/servlets/CometServlet.java?rev=407605&r1=407604&r2=407605&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/catalina/servlets/CometServlet.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/catalina/servlets/CometServlet.java Thu May 18 11:29:07 2006
@@ -21,8 +21,6 @@
import java.io.IOException;
import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -38,7 +36,7 @@
public void begin(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
-
+ request.setAttribute("org.apache.tomcat.comet", Boolean.TRUE);
}
public void end(HttpServletRequest request, HttpServletResponse response)
Modified: tomcat/tc6.0.x/trunk/java/org/apache/coyote/Adapter.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/Adapter.java?rev=407605&r1=407604&r2=407605&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/coyote/Adapter.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/coyote/Adapter.java Thu May 18 11:29:07 2006
@@ -45,5 +45,7 @@
public void service(Request req, Response res)
throws Exception;
+ public boolean event(Request req, Response res, boolean error)
+ throws Exception;
}
Modified: tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java?rev=407605&r1=407604&r2=407605&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java Thu May 18 11:29:07 2006
@@ -743,15 +743,9 @@
try {
rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
- if (error) {
- request.setAttribute("org.apache.tomcat.comet.error", Boolean.TRUE);
- }
- // FIXME: It is also possible to add a new "event" method in the adapter
- // or something similar
- adapter.service(request, response);
+ error = !adapter.event(request, response, error);
if (request.getAttribute("org.apache.tomcat.comet") == null) {
comet = false;
- endpoint.getCometPoller().remove(socket);
}
} catch (InterruptedIOException e) {
error = true;
@@ -772,6 +766,7 @@
endpoint.getPoller().add(socket);
return SocketState.OPEN;
} else {
+ endpoint.getCometPoller().add(socket);
return SocketState.LONG;
}
}
@@ -815,7 +810,7 @@
boolean keptAlive = false;
boolean openSocket = false;
- while (!error && keepAlive) {
+ while (!error && keepAlive && !comet) {
// Parsing the request header
try {
@@ -927,7 +922,6 @@
recycle();
return SocketState.CLOSED;
} else {
- endpoint.getCometPoller().add(socket);
return SocketState.LONG;
}
} else {
Modified: tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java?rev=407605&r1=407604&r2=407605&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11AprProtocol.java Thu May 18 11:29:07 2006
@@ -617,6 +617,7 @@
public SocketState event(long socket, boolean error) {
Http11AprProcessor result = connections.get(socket);
+
SocketState state = SocketState.CLOSED;
if (result != null) {
boolean recycle = error;
@@ -708,10 +709,11 @@
// processor.
connections.put(socket, processor);
localProcessor.set(null);
+ proto.ep.getCometPoller().add(socket);
}
return state;
- } catch(java.net.SocketException e) {
+ } catch (java.net.SocketException e) {
// SocketExceptions are normal
Http11AprProtocol.log.debug
(sm.getString
Modified: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java?rev=407605&r1=407604&r2=407605&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Thu May 18 11:29:07 2006
@@ -796,6 +796,10 @@
pollers[i].destroy();
}
pollers = null;
+ for (int i = 0; i < cometPollers.length; i++) {
+ cometPollers[i].destroy();
+ }
+ cometPollers = null;
if (useSendfile) {
for (int i = 0; i < sendfiles.length; i++) {
sendfiles[i].destroy();
@@ -1107,8 +1111,6 @@
protected long[] addS;
protected int addCount = 0;
- protected long[] removeS;
- protected int removeCount = 0;
protected boolean comet = true;
@@ -1145,10 +1147,6 @@
keepAliveCount = 0;
addS = new long[size];
addCount = 0;
- if (comet) {
- removeS = new long[size];
- }
- removeCount = 0;
}
/**
@@ -1159,15 +1157,9 @@
for (int i = 0; i < addCount; i++) {
if (comet) {
processSocket(addS[i], true);
+ } else {
+ Socket.destroy(addS[i]);
}
- Socket.destroy(addS[i]);
- }
- // Close all sockets in the remove queue
- for (int i = 0; i < removeCount; i++) {
- if (comet) {
- processSocket(removeS[i], true);
- }
- Socket.destroy(removeS[i]);
}
// Close all sockets still in the poller
int rv = Poll.pollset(serverPollset, desc);
@@ -1175,14 +1167,14 @@
for (int n = 0; n < rv; n++) {
if (comet) {
processSocket(desc[n*2+1], true);
+ } else {
+ Socket.destroy(desc[n*2+1]);
}
- Socket.destroy(desc[n*2+1]);
}
}
Pool.destroy(pool);
keepAliveCount = 0;
addCount = 0;
- removeCount = 0;
}
/**
@@ -1201,8 +1193,9 @@
// Can't do anything: close the socket right away
if (comet) {
processSocket(socket, true);
+ } else {
+ Socket.destroy(socket);
}
- Socket.destroy(socket);
return;
}
addS[addCount] = socket;
@@ -1212,30 +1205,6 @@
}
/**
- * Remove specified socket and associated pool from the poller. The socket will
- * be added to a temporary array, and polled first after a maximum amount
- * of time equal to pollTime (in most cases, latency will be much lower,
- * however). Note that this is automatic, except if the poller is used for
- * comet.
- *
- * @param socket to remove from the poller
- */
- public void remove(long socket) {
- synchronized (this) {
- // Add socket to the list. Newly added sockets will wait
- // at most for pollTime before being polled
- if (removeCount >= removeS.length) {
- // Normally, it cannot happen ...
- Socket.destroy(socket);
- return;
- }
- removeS[removeCount] = socket;
- removeCount++;
- this.notify();
- }
- }
-
- /**
* The background thread that listens for incoming TCP/IP connections and
* hands them off to an appropriate processor.
*/
@@ -1279,26 +1248,18 @@
// Can't do anything: close the socket right away
if (comet) {
processSocket(addS[i], true);
+ } else {
+ Socket.destroy(addS[i]);
}
- Socket.destroy(addS[i]);
}
}
addCount = 0;
}
}
- // Remove sockets which are waiting to the poller
- if (removeCount > 0) {
- synchronized (this) {
- for (int i = 0; i < removeCount; i++) {
- int rv = Poll.remove(serverPollset, removeS[i]);
- }
- removeCount = 0;
- }
- }
maintainTime += pollTime;
// Pool for the specified interval
- int rv = Poll.poll(serverPollset, pollTime, desc, !comet);
+ int rv = Poll.poll(serverPollset, pollTime, desc, true);
if (rv > 0) {
keepAliveCount -= rv;
for (int n = 0; n < rv; n++) {
@@ -1306,13 +1267,13 @@
if (((desc[n*2] & Poll.APR_POLLHUP) == Poll.APR_POLLHUP)
|| ((desc[n*2] & Poll.APR_POLLERR) == Poll.APR_POLLERR)
|| (comet && (!processSocket(desc[n*2+1], false)))
- || (!processSocket(desc[n*2+1]))) {
+ || (!comet && (!processSocket(desc[n*2+1])))) {
// Close socket and clear pool
if (comet) {
processSocket(desc[n*2+1], true);
- Poll.remove(serverPollset, desc[n*2+1]);
+ } else {
+ Socket.destroy(desc[n*2+1]);
}
- Socket.destroy(desc[n*2+1]);
continue;
}
}
@@ -1343,8 +1304,9 @@
// FIXME: should really close in case of timeout ?
// FIXME: maybe comet should use an extended timeout
processSocket(desc[n], true);
+ } else {
+ Socket.destroy(desc[n]);
}
- Socket.destroy(desc[n]);
}
}
}
@@ -1467,7 +1429,7 @@
// Close socket and pool
Socket.destroy(socket);
socket = 0;
- } else if (handler.process(socket) == Handler.SocketState.CLOSED) {
+ } else if ((!event) && (handler.process(socket) == Handler.SocketState.CLOSED)) {
// Close socket and pool
Socket.destroy(socket);
socket = 0;
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org