This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/master by this push:
     new f9a8468  Redo timeout for blocking operations
f9a8468 is described below

commit f9a8468e934d439cbb7bf9c47d6f427d3dd787f4
Author: remm <r...@apache.org>
AuthorDate: Tue Mar 10 10:45:18 2020 +0100

    Redo timeout for blocking operations
    
    Use nanoTime this time since it's probably not that "expensive" since it
    is only used when going into the poller. Add back special behavior to
    reset the timeout for write (= every time some data is written).
---
 java/org/apache/tomcat/util/net/NioEndpoint.java | 46 ++++++++++++++++--------
 1 file changed, 32 insertions(+), 14 deletions(-)

diff --git a/java/org/apache/tomcat/util/net/NioEndpoint.java 
b/java/org/apache/tomcat/util/net/NioEndpoint.java
index 5905bf3..88bddda 100644
--- a/java/org/apache/tomcat/util/net/NioEndpoint.java
+++ b/java/org/apache/tomcat/util/net/NioEndpoint.java
@@ -1144,28 +1144,35 @@ public class NioEndpoint extends 
AbstractJsseEndpoint<NioChannel,SocketChannel>
             }
             if (block) {
                 long timeout = getReadTimeout();
+                long startNanos = 0;
                 do {
+                    if (startNanos > 0) {
+                        long elapsedMillis = 
TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos);
+                        if (elapsedMillis == 0) {
+                            elapsedMillis = 1;
+                        }
+                        timeout -= elapsedMillis;
+                        if (timeout <= 0) {
+                            throw new SocketTimeoutException();
+                        }
+                    }
                     n = socket.read(buffer);
                     if (n == -1) {
                         throw new EOFException();
-                    }
-                    if (n == 0) {
+                    } else if (n == 0) {
                         readBlocking = true;
                         registerReadInterest();
                         synchronized (readLock) {
                             if (readBlocking) {
                                 try {
                                     if (timeout > 0) {
+                                        startNanos = System.nanoTime();
                                         readLock.wait(timeout);
                                     } else {
                                         readLock.wait();
                                     }
                                 } catch (InterruptedException e) {
-                                    // Continue ...
-                                }
-                                if (readBlocking) {
-                                    readBlocking = false;
-                                    throw new SocketTimeoutException();
+                                    // Continue
                                 }
                                 readBlocking = false;
                             }
@@ -1191,32 +1198,43 @@ public class NioEndpoint extends 
AbstractJsseEndpoint<NioChannel,SocketChannel>
             }
             if (block) {
                 long timeout = getWriteTimeout();
+                long startNanos = 0;
                 do {
+                    if (startNanos > 0) {
+                        long elapsedMillis = 
TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNanos);
+                        if (elapsedMillis == 0) {
+                            elapsedMillis = 1;
+                        }
+                        timeout -= elapsedMillis;
+                        if (timeout <= 0) {
+                            throw new SocketTimeoutException();
+                        }
+                    }
                     n = socket.write(buffer);
                     if (n == -1) {
                         throw new EOFException();
-                    }
-                    if (n == 0) {
+                    } else if (n == 0) {
                         writeBlocking = true;
                         registerWriteInterest();
                         synchronized (writeLock) {
                             if (writeBlocking) {
                                 try {
                                     if (timeout > 0) {
+                                        startNanos = System.nanoTime();
                                         writeLock.wait(timeout);
                                     } else {
                                         writeLock.wait();
                                     }
                                 } catch (InterruptedException e) {
-                                    // Continue ...
-                                }
-                                if (writeBlocking) {
-                                    writeBlocking = false;
-                                    throw new SocketTimeoutException();
+                                    // Continue
                                 }
                                 writeBlocking = false;
                             }
                         }
+                    } else if (startNanos > 0) {
+                        // If something was written, reset timeout
+                        timeout = getWriteTimeout();
+                        startNanos = 0;
                     }
                 } while (buffer.hasRemaining());
                 // If there is data left in the buffer the socket will be 
registered for


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

Reply via email to