You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2017/01/04 16:51:22 UTC
svn commit: r1777342 - in /tomcat/tc6.0.x/trunk/java/org/apache:
coyote/http11/Http11NioProcessor.java coyote/http11/Http11NioProtocol.java
tomcat/util/net/NioEndpoint.java tomcat/util/net/SendfileState.java
Author: markt
Date: Wed Jan 4 16:51:21 2017
New Revision: 1777342
URL: http://svn.apache.org/viewvc?rev=1777342&view=rev
Log:
Align implementation of Poller.processSendFile() in 6.0.x with 7.0.x
Back-port additional changes required to support this.
Added:
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/SendfileState.java
- copied unchanged from r1777213, tomcat/tc7.0.x/trunk/java/org/apache/tomcat/util/net/SendfileState.java
Modified:
tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
Modified: tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java?rev=1777342&r1=1777341&r2=1777342&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java Wed Jan 4 16:51:21 2017
@@ -82,7 +82,7 @@ public class Http11NioProcessor implemen
protected SSLSupport sslSupport;
private int maxCookieCount = 200;
-
+
/*
* Tracks how many internal filters are in the filter library so they
* are skipped when looking for pluggable filters.
@@ -162,6 +162,13 @@ public class Http11NioProcessor implemen
/**
+ * Flag that indicates that send file processing is in progress and that the
+ * socket should not be returned to the poller (where a poller is used).
+ */
+ protected boolean sendfileInProgress = false;
+
+
+ /**
* HTTP/1.1 flag.
*/
protected boolean http11 = true;
@@ -796,7 +803,7 @@ public class Http11NioProcessor implemen
error = false;
keepAlive = true;
comet = false;
-
+ sendfileInProgress = false;
int keepAliveLeft = maxKeepAliveRequests;
long soTimeout = endpoint.getSoTimeout();
@@ -928,20 +935,11 @@ public class Http11NioProcessor implemen
outputBuffer.nextRequest();
}
- // Do sendfile as needed: add socket to sendfile and end
- if (sendfileData != null && !error) {
- KeyAttachment ka = (KeyAttachment)socket.getAttachment(false);
- ka.setSendfileData(sendfileData);
- sendfileData.keepAlive = keepAlive;
- SelectionKey key = socket.getIOChannel().keyFor(socket.getPoller().getSelector());
- //do the first write on this thread, might as well
- openSocket = socket.getPoller().processSendfile(key,ka,true,true);
- break;
- }
-
-
rp.setStage(org.apache.coyote.Constants.STAGE_KEEPALIVE);
+ if (breakKeepAliveLoop(socket)) {
+ break;
+ }
}
rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
@@ -953,15 +951,47 @@ public class Http11NioProcessor implemen
} else {
return SocketState.LONG;
}
+ } else if (sendfileInProgress) {
+ return SocketState.SENDFILE;
} else {
- if ( recycle ) recycle();
- //return (openSocket) ? (SocketState.OPEN) : SocketState.CLOSED;
+ if (recycle) {
+ recycle();
+ }
return (openSocket) ? (recycle?SocketState.OPEN:SocketState.LONG) : SocketState.CLOSED;
}
}
+ private boolean breakKeepAliveLoop(NioChannel socket) {
+ // Do sendfile as needed: add socket to sendfile and end
+ if (sendfileData != null && !error) {
+ KeyAttachment ka = (KeyAttachment)socket.getAttachment(false);
+ ka.setSendfileData(sendfileData);
+ sendfileData.keepAlive = keepAlive;
+ SelectionKey key = socket.getIOChannel().keyFor(socket.getPoller().getSelector());
+ //do the first write on this thread, might as well
+ switch (socket.getPoller().processSendfile(key, ka, true)) {
+ case DONE:
+ // If sendfile is complete, no need to break keep-alive loop
+ sendfileData = null;
+ return false;
+ case PENDING:
+ sendfileInProgress = true;
+ return true;
+ case ERROR:
+ // Write failed
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("http11processor.sendfile.error"));
+ }
+ error = true;
+ return true;
+ }
+ }
+ return false;
+ }
+
+
public void endRequest() {
// Finish the handling of the request
@@ -1261,7 +1291,7 @@ public class Http11NioProcessor implemen
this.sslSupport = sslSupport;
}
-
+
public int getMaxCookieCount() {
return maxCookieCount;
}
@@ -1271,7 +1301,7 @@ public class Http11NioProcessor implemen
this.maxCookieCount = maxCookieCount;
}
-
+
/**
* Get the associated adapter.
*
Modified: tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java?rev=1777342&r1=1777341&r2=1777342&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java Wed Jan 4 16:51:21 2017
@@ -764,6 +764,12 @@ public class Http11NioProtocol extends A
// processor. Continue to poll for the next request.
release(socket, processor);
socket.getPoller().add(socket);
+ } else if (state == SocketState.SENDFILE) {
+ // Sendfile in progress. If it fails, the socket will be
+ // closed. If it works, the socket will be re-added to the
+ // poller
+ connections.remove(socket);
+ release(socket, processor);
} else {
// Connection closed. OK to recycle the processor.
release(socket, processor);
Modified: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
URL: http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java?rev=1777342&r1=1777341&r2=1777342&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java (original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Wed Jan 4 16:51:21 2017
@@ -1740,7 +1740,7 @@ public class NioEndpoint extends Abstrac
NioChannel channel = attachment.getChannel();
if (sk.isReadable() || sk.isWritable() ) {
if ( attachment.getSendfileData() != null ) {
- processSendfile(sk,attachment,true, false);
+ processSendfile(sk, attachment, false);
} else if ( attachment.getComet() ) {
//check if thread is available
if ( isWorkerAvailable() ) {
@@ -1785,7 +1785,8 @@ public class NioEndpoint extends Abstrac
return result;
}
- public boolean processSendfile(SelectionKey sk, KeyAttachment attachment, boolean reg, boolean event) {
+ public SendfileState processSendfile(SelectionKey sk, KeyAttachment attachment,
+ boolean calledByProcessor) {
NioChannel sc = null;
try {
unreg(sk, attachment, sk.readyOps());
@@ -1800,7 +1801,7 @@ public class NioEndpoint extends Abstrac
File f = new File(sd.fileName);
if ( !f.exists() ) {
cancelledKey(sk,SocketStatus.ERROR,false);
- return false;
+ return SendfileState.ERROR;
}
@SuppressWarnings("resource") // Closed when channel is closed
FileInputStream fis = new FileInputStream(f);
@@ -1844,7 +1845,7 @@ public class NioEndpoint extends Abstrac
// For calls from outside the Poller, the caller is
// responsible for registering the socket for the
// appropriate event(s) if sendfile completes.
- if (!event) {
+ if (!calledByProcessor) {
if ( sd.keepAlive ) {
if (log.isDebugEnabled()) {
log.debug("Connection is keep alive, registering back for OP_READ");
@@ -1855,29 +1856,29 @@ public class NioEndpoint extends Abstrac
log.debug("Send file connection is being closed");
}
cancelledKey(sk,SocketStatus.STOP,false);
- return false;
}
}
+ return SendfileState.DONE;
} else {
if (log.isDebugEnabled()) {
log.debug("OP_WRITE for sendfile: " + sd.fileName);
}
- if (event) {
+ if (calledByProcessor) {
add(attachment.getChannel(),SelectionKey.OP_WRITE);
} else {
reg(sk,attachment,SelectionKey.OP_WRITE);
}
+ return SendfileState.PENDING;
}
}catch ( IOException x ) {
if ( log.isDebugEnabled() ) log.debug("Unable to complete sendfile request:", x);
cancelledKey(sk,SocketStatus.ERROR,false);
- return false;
+ return SendfileState.ERROR;
}catch ( Throwable t ) {
log.error("",t);
cancelledKey(sk, SocketStatus.ERROR, false);
- return false;
+ return SendfileState.ERROR;
}
- return true;
}
protected void unreg(SelectionKey sk, KeyAttachment attachment, int readyOps) {
@@ -2245,7 +2246,7 @@ public class NioEndpoint extends Abstrac
*/
public interface Handler {
public enum SocketState {
- OPEN, CLOSED, LONG
+ OPEN, CLOSED, LONG, SENDFILE
}
public SocketState process(NioChannel socket);
public SocketState event(NioChannel socket, SocketStatus status);
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org