Author: markt
Date: Mon Mar 11 20:30:49 2013
New Revision: 1455314

URL: http://svn.apache.org/r1455314
Log:
APR read/write need to use the same locks for changing the blocking status of 
the socket

Modified:
    
tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletInputStream.java
    
tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletOutputStream.java
    tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapper.java

Modified: 
tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletInputStream.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletInputStream.java?rev=1455314&r1=1455313&r2=1455314&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletInputStream.java 
(original)
+++ 
tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletInputStream.java 
Mon Mar 11 20:30:49 2013
@@ -18,7 +18,6 @@ package org.apache.coyote.http11.upgrade
 
 import java.io.IOException;
 import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
 
 import org.apache.tomcat.jni.Socket;
@@ -29,8 +28,6 @@ public class AprServletInputStream exten
 
     private final SocketWrapper<Long> wrapper;
     private final long socket;
-    private final Lock blockingStatusReadLock;
-    private final WriteLock blockingStatusWriteLock;
     private volatile boolean eagain = false;
     private volatile boolean closed = false;
 
@@ -38,9 +35,6 @@ public class AprServletInputStream exten
     public AprServletInputStream(SocketWrapper<Long> wrapper) {
         this.wrapper = wrapper;
         this.socket = wrapper.getSocket().longValue();
-        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-        this.blockingStatusReadLock = lock.readLock();
-        this.blockingStatusWriteLock =lock.writeLock();
     }
 
 
@@ -48,10 +42,13 @@ public class AprServletInputStream exten
     protected int doRead(boolean block, byte[] b, int off, int len)
             throws IOException {
 
+        Lock readLock = wrapper.getBlockingStatusReadLock();
+        WriteLock writeLock = wrapper.getBlockingStatusWriteLock();
+
         boolean readDone = false;
         int result = 0;
         try {
-            blockingStatusReadLock.lock();
+            readLock.lock();
             if (wrapper.getBlockingStatus() == block) {
                 if (closed) {
                     throw new IOException(sm.getString("apr.closed"));
@@ -60,31 +57,31 @@ public class AprServletInputStream exten
                 readDone = true;
             }
         } finally {
-            blockingStatusReadLock.unlock();
+            readLock.unlock();
         }
 
         if (!readDone) {
             try {
-                blockingStatusWriteLock.lock();
+                writeLock.lock();
                 wrapper.setBlockingStatus(block);
                 // Set the current settings for this socket
                 Socket.optSet(socket, Socket.APR_SO_NONBLOCK, (block ? 0 : 1));
                 // Downgrade the lock
                 try {
-                    blockingStatusReadLock.lock();
-                    blockingStatusWriteLock.unlock();
+                    readLock.lock();
+                    writeLock.unlock();
                     if (closed) {
                         throw new IOException(sm.getString("apr.closed"));
                     }
                     result = Socket.recv(socket, b, off, len);
                 } finally {
-                    blockingStatusReadLock.unlock();
+                    readLock.unlock();
                 }
             } finally {
                 // Should have been released above but may not have been on 
some
                 // exception paths
-                if (blockingStatusWriteLock.isHeldByCurrentThread()) {
-                    blockingStatusWriteLock.unlock();
+                if (writeLock.isHeldByCurrentThread()) {
+                    writeLock.unlock();
                 }
             }
         }

Modified: 
tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletOutputStream.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletOutputStream.java?rev=1455314&r1=1455313&r2=1455314&view=diff
==============================================================================
--- 
tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletOutputStream.java 
(original)
+++ 
tomcat/trunk/java/org/apache/coyote/http11/upgrade/AprServletOutputStream.java 
Mon Mar 11 20:30:49 2013
@@ -18,7 +18,6 @@ package org.apache.coyote.http11.upgrade
 
 import java.io.IOException;
 import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
 
 import org.apache.tomcat.jni.Socket;
@@ -31,8 +30,6 @@ public class AprServletOutputStream exte
     private final AprEndpoint endpoint;
     private final SocketWrapper<Long> wrapper;
     private final long socket;
-    private final Lock blockingStatusReadLock;
-    private final WriteLock blockingStatusWriteLock;
     private volatile boolean closed = false;
 
     public AprServletOutputStream(SocketWrapper<Long> wrapper,
@@ -40,9 +37,6 @@ public class AprServletOutputStream exte
         this.endpoint = endpoint;
         this.wrapper = wrapper;
         this.socket = wrapper.getSocket().longValue();
-        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
-        this.blockingStatusReadLock = lock.readLock();
-        this.blockingStatusWriteLock =lock.writeLock();
     }
 
 
@@ -50,10 +44,13 @@ public class AprServletOutputStream exte
     protected int doWrite(boolean block, byte[] b, int off, int len)
             throws IOException {
 
+        Lock readLock = wrapper.getBlockingStatusReadLock();
+        WriteLock writeLock = wrapper.getBlockingStatusWriteLock();
+
         boolean writeDone = false;
         int result = 0;
         try {
-            blockingStatusReadLock.lock();
+            readLock.lock();
             if (wrapper.getBlockingStatus() == block) {
                 if (closed) {
                     throw new IOException(sm.getString("apr.closed"));
@@ -62,31 +59,31 @@ public class AprServletOutputStream exte
                 writeDone = true;
             }
         } finally {
-            blockingStatusReadLock.unlock();
+            readLock.unlock();
         }
 
         if (!writeDone) {
             try {
-                blockingStatusWriteLock.lock();
+                writeLock.lock();
                 wrapper.setBlockingStatus(block);
                 // Set the current settings for this socket
                 Socket.optSet(socket, Socket.APR_SO_NONBLOCK, (block ? -1 : 
0));
                 // Downgrade the lock
                 try {
-                    blockingStatusReadLock.lock();
-                    blockingStatusWriteLock.unlock();
+                    readLock.lock();
+                    writeLock.unlock();
                     if (closed) {
                         throw new IOException(sm.getString("apr.closed"));
                     }
                     result = Socket.send(socket, b, off, len);
                 } finally {
-                    blockingStatusReadLock.unlock();
+                    readLock.unlock();
                 }
             } finally {
                 // Should have been released above but may not have been on 
some
                 // exception paths
-                if (blockingStatusWriteLock.isHeldByCurrentThread()) {
-                    blockingStatusWriteLock.unlock();
+                if (writeLock.isHeldByCurrentThread()) {
+                    writeLock.unlock();
                 }
             }
         }
@@ -96,8 +93,7 @@ public class AprServletOutputStream exte
                 endpoint.getPoller().add(socket, -1, false, true);
             }
             return result;
-        }
-        else if (-result == Status.EAGAIN) {
+        } else if (-result == Status.EAGAIN) {
             endpoint.getPoller().add(socket, -1, false, true);
             return 0;
         }

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapper.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapper.java?rev=1455314&r1=1455313&r2=1455314&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapper.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SocketWrapper.java Mon Mar 11 
20:30:49 2013
@@ -16,6 +16,10 @@
  */
 package org.apache.tomcat.util.net;
 
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
+
 public class SocketWrapper<E> {
 
     protected volatile E socket;
@@ -39,12 +43,18 @@ public class SocketWrapper<E> {
     private String remoteAddr = null;
     /*
      * Used if block/non-blocking is set at the socket level. The client is
-     * responsible for the thread-safe use of this field.
+     * responsible for the thread-safe use of this field via the locks 
provided.
      */
     private volatile boolean blockingStatus = true;
+    private final Lock blockingStatusReadLock;
+    private final WriteLock blockingStatusWriteLock;
+
 
     public SocketWrapper(E socket) {
         this.socket = socket;
+        ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+        this.blockingStatusReadLock = lock.readLock();
+        this.blockingStatusWriteLock =lock.writeLock();
     }
 
     public E getSocket() {
@@ -84,4 +94,8 @@ public class SocketWrapper<E> {
     public void setBlockingStatus(boolean blockingStatus) {
         this.blockingStatus = blockingStatus;
     }
+    public Lock getBlockingStatusReadLock() { return blockingStatusReadLock; }
+    public WriteLock getBlockingStatusWriteLock() {
+        return blockingStatusWriteLock;
+    }
 }



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

Reply via email to