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 2015/05/22 11:25:41 UTC

svn commit: r1681050 - /tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java

Author: remm
Date: Fri May 22 09:25:41 2015
New Revision: 1681050

URL: http://svn.apache.org/r1681050
Log:
Cleanup and move around the NIO2 sendfile code, addressing a fixme. There should be no functional change.

Modified:
    tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java

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=1681050&r1=1681049&r2=1681050&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/Nio2Endpoint.java Fri May 22 09:25:41 2015
@@ -592,6 +592,80 @@ public class Nio2Endpoint extends Abstra
             }
         };
 
+        private CompletionHandler<Integer, SendfileData> sendfileHandler
+            = new CompletionHandler<Integer, SendfileData>() {
+
+            @Override
+            public void completed(Integer nWrite, SendfileData attachment) {
+                if (nWrite.intValue() < 0) {
+                    failed(new EOFException(), attachment);
+                    return;
+                }
+                attachment.pos += nWrite.intValue();
+                ByteBuffer buffer = getSocket().getBufHandler().getWriteBuffer();
+                if (!buffer.hasRemaining()) {
+                    if (attachment.length <= 0) {
+                        // All data has now been written
+                        setSendfileData(null);
+                        try {
+                            attachment.fchannel.close();
+                        } catch (IOException e) {
+                            // Ignore
+                        }
+                        if (attachment.keepAlive) {
+                            if (!isInline()) {
+                                awaitBytes();
+                            } else {
+                                attachment.doneInline = true;
+                            }
+                        } else {
+                            if (!isInline()) {
+                                getEndpoint().processSocket(Nio2SocketWrapper.this, SocketStatus.DISCONNECT, false);
+                            } else {
+                                attachment.doneInline = true;
+                            }
+                        }
+                        return;
+                    } else {
+                        getSocket().getBufHandler().configureWriteBufferForWrite();
+                        int nRead = -1;
+                        try {
+                            nRead = attachment.fchannel.read(buffer);
+                        } catch (IOException e) {
+                            failed(e, attachment);
+                            return;
+                        }
+                        if (nRead > 0) {
+                            getSocket().getBufHandler().configureWriteBufferForRead();
+                            if (attachment.length < buffer.remaining()) {
+                                buffer.limit(buffer.limit() - buffer.remaining() + (int) attachment.length);
+                            }
+                            attachment.length -= nRead;
+                        } else {
+                            failed(new EOFException(), attachment);
+                            return;
+                        }
+                    }
+                }
+                getSocket().write(buffer, getNio2WriteTimeout(), TimeUnit.MILLISECONDS, attachment, this);
+            }
+
+            @Override
+            public void failed(Throwable exc, SendfileData attachment) {
+                try {
+                    attachment.fchannel.close();
+                } catch (IOException e) {
+                    // Ignore
+                }
+                if (!isInline()) {
+                    getEndpoint().processSocket(Nio2SocketWrapper.this, SocketStatus.ERROR, false);
+                } else {
+                    attachment.doneInline = true;
+                    attachment.error = true;
+                }
+            }
+        };
+
         public Nio2SocketWrapper(Nio2Channel channel, Nio2Endpoint endpoint) {
             super(channel, endpoint);
             socketBufferHandler = channel.getBufHandler();
@@ -1284,8 +1358,46 @@ public class Nio2Endpoint extends Abstra
 
         @Override
         public SendfileState processSendfile(SendfileDataBase sendfileData) {
-            setSendfileData((SendfileData) sendfileData);
-            return ((Nio2Endpoint) getEndpoint()).processSendfile(this);
+            SendfileData data = (SendfileData) sendfileData;
+            setSendfileData(data);
+            // Configure the send file data
+            if (data.fchannel == null || !data.fchannel.isOpen()) {
+                java.nio.file.Path path = new File(sendfileData.fileName).toPath();
+                try {
+                    data.fchannel = java.nio.channels.FileChannel
+                            .open(path, StandardOpenOption.READ).position(sendfileData.pos);
+                } catch (IOException e) {
+                    return SendfileState.ERROR;
+                }
+            }
+            getSocket().getBufHandler().configureWriteBufferForWrite();
+            ByteBuffer buffer = getSocket().getBufHandler().getWriteBuffer();
+            int nRead = -1;
+            try {
+                nRead = data.fchannel.read(buffer);
+            } catch (IOException e1) {
+                return SendfileState.ERROR;
+            }
+
+            if (nRead >= 0) {
+                data.length -= nRead;
+                getSocket().getBufHandler().configureWriteBufferForRead();
+                Nio2Endpoint.startInline();
+                getSocket().write(buffer, getNio2WriteTimeout(), TimeUnit.MILLISECONDS,
+                        data, sendfileHandler);
+                Nio2Endpoint.endInline();
+                if (data.doneInline) {
+                    if (data.error) {
+                        return SendfileState.ERROR;
+                    } else {
+                        return SendfileState.DONE;
+                    }
+                } else {
+                    return SendfileState.PENDING;
+                }
+            } else {
+                return SendfileState.ERROR;
+            }
         }
 
 
@@ -1467,126 +1579,6 @@ public class Nio2Endpoint extends Abstra
         }
     }
 
-    private CompletionHandler<Integer, SendfileData> sendfile = new CompletionHandler<Integer, SendfileData>() {
-
-        @Override
-        public void completed(Integer nWrite, SendfileData attachment) {
-            if (nWrite.intValue() < 0) { // Reach the end of stream
-                failed(new EOFException(), attachment);
-                return;
-            }
-            // TODO: Lots of direct access to the socketWriteBuffer.
-            //       Refactor to use socketBufferHandler
-            attachment.pos += nWrite.intValue();
-            if (!attachment.buffer.hasRemaining()) {
-                if (attachment.length <= 0) {
-                    // All data has now been written
-                    attachment.socket.setSendfileData(null);
-                    try {
-                        attachment.fchannel.close();
-                    } catch (IOException e) {
-                        // Ignore
-                    }
-                    if (attachment.keepAlive) {
-                        if (!isInline()) {
-                            attachment.socket.awaitBytes();
-                        } else {
-                            attachment.doneInline = true;
-                        }
-                    } else {
-                        if (!isInline()) {
-                            processSocket(attachment.socket, SocketStatus.DISCONNECT, false);
-                        } else {
-                            attachment.doneInline = true;
-                        }
-                    }
-                    return;
-                } else {
-                    attachment.buffer.clear();
-                    int nRead = -1;
-                    try {
-                        nRead = attachment.fchannel.read(attachment.buffer);
-                    } catch (IOException e) {
-                        failed(e, attachment);
-                        return;
-                    }
-                    if (nRead > 0) {
-                        attachment.buffer.flip();
-                        if (attachment.length < attachment.buffer.remaining()) {
-                            attachment.buffer.limit(attachment.buffer.limit() - attachment.buffer.remaining() + (int) attachment.length);
-                        }
-                        attachment.length -= nRead;
-                    } else {
-                        failed(new EOFException(), attachment);
-                        return;
-                    }
-                }
-            }
-            attachment.socket.getSocket().write(attachment.buffer,
-                    attachment.socket.getNio2WriteTimeout(), TimeUnit.MILLISECONDS,
-                    attachment, this);
-        }
-
-        @Override
-        public void failed(Throwable exc, SendfileData attachment) {
-            try {
-                attachment.fchannel.close();
-            } catch (IOException e) {
-                // Ignore
-            }
-            if (!isInline()) {
-                processSocket(attachment.socket, SocketStatus.ERROR, false);
-            } else {
-                attachment.doneInline = true;
-                attachment.error = true;
-            }
-        }
-    };
-
-    public SendfileState processSendfile(Nio2SocketWrapper socket) {
-
-        // Configure the send file data
-        SendfileData data = socket.getSendfileData();
-        if (data.fchannel == null || !data.fchannel.isOpen()) {
-            java.nio.file.Path path = new File(data.fileName).toPath();
-            try {
-                data.fchannel = java.nio.channels.FileChannel
-                        .open(path, StandardOpenOption.READ).position(data.pos);
-            } catch (IOException e) {
-                return SendfileState.ERROR;
-            }
-        }
-        socket.getSocket().getBufHandler().configureWriteBufferForWrite();
-        ByteBuffer buffer = socket.getSocket().getBufHandler().getWriteBuffer();
-        int nRead = -1;
-        try {
-            nRead = data.fchannel.read(buffer);
-        } catch (IOException e1) {
-            return SendfileState.ERROR;
-        }
-
-        if (nRead >= 0) {
-            data.socket = socket;
-            data.buffer = buffer;
-            data.length -= nRead;
-            socket.getSocket().getBufHandler().configureWriteBufferForRead();
-            Nio2Endpoint.startInline();
-            socket.getSocket().write(buffer, socket.getNio2WriteTimeout(), TimeUnit.MILLISECONDS,
-                    data, sendfile);
-            Nio2Endpoint.endInline();
-            if (data.doneInline) {
-                if (data.error) {
-                    return SendfileState.ERROR;
-                } else {
-                    return SendfileState.DONE;
-                }
-            } else {
-                return SendfileState.PENDING;
-            }
-        } else {
-            return SendfileState.ERROR;
-        }
-    }
 
     // ---------------------------------------------- SocketProcessor Inner Class
     /**
@@ -1697,10 +1689,8 @@ public class Nio2Endpoint extends Abstra
      * SendfileData class.
      */
     public static class SendfileData extends SendfileDataBase {
-        protected FileChannel fchannel;
+        private FileChannel fchannel;
         // Internal use only
-        private Nio2SocketWrapper socket;
-        private ByteBuffer buffer;
         private boolean doneInline = false;
         private boolean error = false;
 



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org