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 2015/01/23 20:03:12 UTC
svn commit: r1654323 - in /tomcat/trunk/java/org/apache: coyote/http11/
tomcat/util/net/
Author: markt
Date: Fri Jan 23 19:03:11 2015
New Revision: 1654323
URL: http://svn.apache.org/r1654323
Log:
Push socket type specific sendfile code down to SocketWrapper
Modified:
tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java
tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Processor.java
tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java
tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java
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=1654323&r1=1654322&r2=1654323&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java Fri Jan 23 19:03:11 2015
@@ -96,22 +96,19 @@ public class Http11AprProcessor extends
// Do sendfile as needed: add socket to sendfile and end
if (sendfileData != null && !getErrorState().isError()) {
sendfileData.keepAlive = keepAlive;
- sendfileData.socket = socketWrapper.getSocket().longValue();
- if (!((AprEndpoint)endpoint).getSendfile().add(sendfileData)) {
- // Didn't send all of the data to sendfile.
- if (sendfileData.socket == 0) {
- // The socket is no longer set. Something went wrong.
- // Close the connection. Too late to set status code.
- if (log.isDebugEnabled()) {
- log.debug(sm.getString(
- "http11processor.sendfile.error"));
- }
- setErrorState(ErrorState.CLOSE_NOW, null);
- } else {
- // The sendfile Poller will add the socket to the main
- // Poller once sendfile processing is complete
- sendfileInProgress = true;
+ switch (socketWrapper.processSendfile(sendfileData)) {
+ case DONE:
+ // If sendfile is complete, no need to break keep-alive loop
+ return false;
+ case PENDING:
+ sendfileInProgress = true;
+ return true;
+ case ERROR:
+ // Write failed
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("http11processor.sendfile.error"));
}
+ setErrorState(ErrorState.CLOSE_NOW, null);
return true;
}
}
Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Processor.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Processor.java?rev=1654323&r1=1654322&r2=1654323&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Processor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Processor.java Fri Jan 23 19:03:11 2015
@@ -120,17 +120,18 @@ public class Http11Nio2Processor extends
@Override
- protected boolean breakKeepAliveLoop(
- SocketWrapperBase<Nio2Channel> socketWrapper) {
+ protected boolean breakKeepAliveLoop(SocketWrapperBase<Nio2Channel> socketWrapper) {
openSocket = keepAlive;
// Do sendfile as needed: add socket to sendfile and end
if (sendfileData != null && !getErrorState().isError()) {
sendfileData.keepAlive = keepAlive;
- ((Nio2Endpoint.Nio2SocketWrapper) socketWrapper).setSendfileData(sendfileData);
- switch (((Nio2Endpoint) endpoint)
- .processSendfile((Nio2Endpoint.Nio2SocketWrapper) socketWrapper)) {
+ switch (socketWrapper.processSendfile(sendfileData)) {
case DONE:
+ // If sendfile is complete, no need to break keep-alive loop
return false;
+ case PENDING:
+ sendfileInProgress = true;
+ return true;
case ERROR:
// Write failed
if (log.isDebugEnabled()) {
@@ -138,9 +139,6 @@ public class Http11Nio2Processor extends
}
setErrorState(ErrorState.CLOSE_NOW, null);
return true;
- case PENDING:
- sendfileInProgress = true;
- return true;
}
}
return false;
@@ -155,7 +153,6 @@ public class Http11Nio2Processor extends
// ----------------------------------------------------- ActionHook Methods
-
/**
* Send an action to the connector.
*
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=1654323&r1=1654322&r2=1654323&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java Fri Jan 23 19:03:11 2015
@@ -30,7 +30,6 @@ import org.apache.juli.logging.LogFactor
import org.apache.tomcat.util.net.AbstractEndpoint;
import org.apache.tomcat.util.net.NioChannel;
import org.apache.tomcat.util.net.NioEndpoint;
-import org.apache.tomcat.util.net.NioEndpoint.NioSocketWrapper;
import org.apache.tomcat.util.net.SSLSupport;
import org.apache.tomcat.util.net.SecureNioChannel;
import org.apache.tomcat.util.net.SocketWrapperBase;
@@ -119,21 +118,21 @@ public class Http11NioProcessor extends
// Do sendfile as needed: add socket to sendfile and end
if (sendfileData != null && !getErrorState().isError()) {
sendfileData.keepAlive = keepAlive;
- ((NioSocketWrapper) socketWrapper).setSendfileData(sendfileData);
- SelectionKey key = socketWrapper.getSocket().getIOChannel().keyFor(
- socketWrapper.getSocket().getPoller().getSelector());
- //do the first write on this thread, might as well
- if (socketWrapper.getSocket().getPoller().processSendfile(key,
- (NioSocketWrapper) socketWrapper, true)) {
+ switch (socketWrapper.processSendfile(sendfileData)) {
+ case DONE:
+ // If sendfile is complete, no need to break keep-alive loop
+ return false;
+ case PENDING:
sendfileInProgress = true;
- } else {
+ return true;
+ case ERROR:
// Write failed
if (log.isDebugEnabled()) {
log.debug(sm.getString("http11processor.sendfile.error"));
}
setErrorState(ErrorState.CLOSE_NOW, null);
+ return true;
}
- return true;
}
return false;
}
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java?rev=1654323&r1=1654322&r2=1654323&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Fri Jan 23 19:03:11 2015
@@ -1919,10 +1919,10 @@ public class AprEndpoint extends Abstrac
*/
public static class SendfileData extends SendfileDataBase {
// File
- public long fd;
- public long fdpool;
+ protected long fd;
+ protected long fdpool;
// Socket and socket pool
- public long socket;
+ protected long socket;
}
@@ -2010,7 +2010,7 @@ public class AprEndpoint extends Abstrac
* @return true if all the data has been sent right away, and false
* otherwise
*/
- public boolean add(SendfileData data) {
+ public SendfileState add(SendfileData data) {
// Initialize fd from data given
try {
data.fdpool = Socket.pool(data.socket);
@@ -2027,7 +2027,7 @@ public class AprEndpoint extends Abstrac
if (!(-nw == Status.EAGAIN)) {
Pool.destroy(data.fdpool);
data.socket = 0;
- return false;
+ return SendfileState.ERROR;
} else {
// Break the loop and add the socket to poller.
break;
@@ -2039,15 +2039,14 @@ public class AprEndpoint extends Abstrac
// Entire file has been sent
Pool.destroy(data.fdpool);
// Set back socket to blocking mode
- Socket.timeoutSet(
- data.socket, getSoTimeout() * 1000);
- return true;
+ Socket.timeoutSet(data.socket, getSoTimeout() * 1000);
+ return SendfileState.DONE;
}
}
}
} catch (Exception e) {
log.warn(sm.getString("endpoint.sendfile.error"), e);
- return false;
+ return SendfileState.ERROR;
}
// Add socket to the list. Newly added sockets will wait
// at most for pollTime before being polled
@@ -2055,7 +2054,7 @@ public class AprEndpoint extends Abstrac
addS.add(data);
this.notify();
}
- return false;
+ return SendfileState.PENDING;
}
/**
@@ -2643,5 +2642,12 @@ public class AprEndpoint extends Abstrac
((AprEndpoint) getEndpoint()).getPoller().add(
getSocket().longValue(), -1, read, write);
}
+
+
+ @Override
+ public SendfileState processSendfile(SendfileDataBase sendfileData) {
+ ((SendfileData) sendfileData).socket = getSocket().longValue();
+ return ((AprEndpoint) getEndpoint()).getSendfile().add((SendfileData) sendfileData);
+ }
}
}
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java?rev=1654323&r1=1654322&r2=1654323&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java Fri Jan 23 19:03:11 2015
@@ -1291,6 +1291,7 @@ public class Nio2Endpoint extends Abstra
// NO-OP. Appropriate handlers will already have been registered.
}
+
public void awaitBytes() {
if (getSocket() == null) {
return;
@@ -1304,6 +1305,12 @@ public class Nio2Endpoint extends Abstra
}
}
+
+ @Override
+ public SendfileState processSendfile(SendfileDataBase sendfileData) {
+ setSendfileData((SendfileData) sendfileData);
+ return ((Nio2Endpoint) getEndpoint()).processSendfile(this);
+ }
}
@@ -1612,7 +1619,7 @@ public class Nio2Endpoint extends Abstra
* SendfileData class.
*/
public static class SendfileData extends SendfileDataBase {
- public FileChannel fchannel;
+ protected FileChannel fchannel;
// Internal use only
private Nio2SocketWrapper socket;
private ByteBuffer buffer;
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=1654323&r1=1654322&r2=1654323&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Fri Jan 23 19:03:11 2015
@@ -1114,45 +1114,51 @@ public class NioEndpoint extends Abstrac
return result;
}
- public boolean processSendfile(SelectionKey sk, NioSocketWrapper attachment, boolean event) {
+ public SendfileState processSendfile(SelectionKey sk, NioSocketWrapper socketWrapper, boolean event) {
NioChannel sc = null;
try {
- unreg(sk, attachment, sk.readyOps());
- SendfileData sd = attachment.getSendfileData();
+ unreg(sk, socketWrapper, sk.readyOps());
+ SendfileData sd = socketWrapper.getSendfileData();
if (log.isTraceEnabled()) {
log.trace("Processing send file for: " + sd.fileName);
}
- //setup the file channel
- if ( sd.fchannel == null ) {
+ // This method is called by the Http11Processor for the first
+ // execution and then subsequent executions are via the Poller.
+ // This boolean keeps track of the current caller as the
+ // required behaviour varies slightly.
+ boolean calledByProcessor = (sd.fchannel == null);
+
+ if (calledByProcessor) {
+ // Setup the file channel
File f = new File(sd.fileName);
- if ( !f.exists() ) {
+ if (!f.exists()) {
cancelledKey(sk);
- return false;
+ return SendfileState.ERROR;
}
@SuppressWarnings("resource") // Closed when channel is closed
FileInputStream fis = new FileInputStream(f);
sd.fchannel = fis.getChannel();
}
- //configure output channel
- sc = attachment.getSocket();
+ // Configure output channel
+ sc = socketWrapper.getSocket();
sc.setSendFile(true);
- //ssl channel is slightly different
+ // TLS/SSL channel is slightly different
WritableByteChannel wc = ((sc instanceof SecureNioChannel)?sc:sc.getIOChannel());
- //we still have data in the buffer
+ // We still have data in the buffer
if (sc.getOutboundRemaining()>0) {
if (sc.flushOutbound()) {
- attachment.access();
+ socketWrapper.access();
}
} else {
long written = sd.fchannel.transferTo(sd.pos,sd.length,wc);
- if ( written > 0 ) {
+ if (written > 0) {
sd.pos += written;
sd.length -= written;
- attachment.access();
+ socketWrapper.access();
} else {
// Unusual not to be able to transfer any bytes
// Check the length was set correctly
@@ -1162,53 +1168,57 @@ public class NioEndpoint extends Abstrac
}
}
}
- if ( sd.length <= 0 && sc.getOutboundRemaining()<=0) {
+ if (sd.length <= 0 && sc.getOutboundRemaining()<=0) {
if (log.isDebugEnabled()) {
log.debug("Send file complete for: "+sd.fileName);
}
- attachment.setSendfileData(null);
+ socketWrapper.setSendfileData(null);
try {
sd.fchannel.close();
} catch (Exception ignore) {
}
- if ( sd.keepAlive ) {
+ if (!calledByProcessor) {
+ if (sd.keepAlive) {
if (log.isDebugEnabled()) {
log.debug("Connection is keep alive, registering back for OP_READ");
}
if (event) {
- this.add(attachment.getSocket(),SelectionKey.OP_READ);
+ this.add(socketWrapper.getSocket(),SelectionKey.OP_READ);
} else {
- reg(sk,attachment,SelectionKey.OP_READ);
+ reg(sk,socketWrapper,SelectionKey.OP_READ);
}
- } else {
- if (log.isDebugEnabled()) {
- log.debug("Send file connection is being closed");
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug("Send file connection is being closed");
+ }
+ cancelledKey(sk);
}
- cancelledKey(sk);
- return false;
}
+ return SendfileState.DONE;
} else {
- if (log.isDebugEnabled()) {
- log.debug("OP_WRITE for sendfile: " + sd.fileName);
- }
- if (event) {
- add(attachment.getSocket(),SelectionKey.OP_WRITE);
- } else {
- reg(sk,attachment,SelectionKey.OP_WRITE);
+ if (!calledByProcessor) {
+ if (log.isDebugEnabled()) {
+ log.debug("OP_WRITE for sendfile: " + sd.fileName);
+ }
+ if (event) {
+ add(socketWrapper.getSocket(),SelectionKey.OP_WRITE);
+ } else {
+ reg(sk,socketWrapper,SelectionKey.OP_WRITE);
+ }
}
+ return SendfileState.PENDING;
}
- }catch ( IOException x ) {
- if ( log.isDebugEnabled() ) log.debug("Unable to complete sendfile request:", x);
+ } catch (IOException x) {
+ if (log.isDebugEnabled()) log.debug("Unable to complete sendfile request:", x);
cancelledKey(sk);
- return false;
- }catch ( Throwable t ) {
- log.error("",t);
+ return SendfileState.ERROR;
+ } catch (Throwable t) {
+ log.error("", t);
cancelledKey(sk);
- return false;
- }finally {
+ return SendfileState.ERROR;
+ } finally {
if (sc!=null) sc.setSendFile(false);
}
- return true;
}
protected void unreg(SelectionKey sk, NioSocketWrapper attachment, int readyOps) {
@@ -1575,6 +1585,16 @@ public class NioEndpoint extends Abstrac
key.interestOps(key.interestOps() | SelectionKey.OP_READ);
}
}
+
+
+ @Override
+ public SendfileState processSendfile(SendfileDataBase sendfileData) {
+ setSendfileData((SendfileData) sendfileData);
+ SelectionKey key = getSocket().getIOChannel().keyFor(
+ getSocket().getPoller().getSelector());
+ // Might as well do the first write on this thread
+ return getSocket().getPoller().processSendfile(key, this, true);
+ }
}
@@ -1756,6 +1776,6 @@ public class NioEndpoint extends Abstrac
* SendfileData class.
*/
public static class SendfileData extends SendfileDataBase {
- public volatile FileChannel fchannel;
+ protected volatile FileChannel fchannel;
}
}
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java?rev=1654323&r1=1654322&r2=1654323&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapperBase.java Fri Jan 23 19:03:11 2015
@@ -511,6 +511,8 @@ public abstract class SocketWrapperBase<
public abstract void regsiterForEvent(boolean read, boolean write);
+ public abstract SendfileState processSendfile(SendfileDataBase sendfileData);
+
// --------------------------------------------------------- Utility methods
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org