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

markt pushed a commit to branch 7.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 4e2384dc59c9d7e98a430a75e090e625dcfca808
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Tue May 21 21:57:03 2019 +0100

    Refactor to remove use of session#lock and #unlock in the DeltaManager
---
 .../catalina/ha/session/ClusterManagerBase.java    | 21 ++++++++++-----
 .../apache/catalina/ha/session/DeltaManager.java   | 28 ++++++++++----------
 .../apache/catalina/ha/session/DeltaSession.java   | 30 ++++++++++++++++++++++
 3 files changed, 59 insertions(+), 20 deletions(-)

diff --git a/java/org/apache/catalina/ha/session/ClusterManagerBase.java 
b/java/org/apache/catalina/ha/session/ClusterManagerBase.java
index 475f7bf..89121aa 100644
--- a/java/org/apache/catalina/ha/session/ClusterManagerBase.java
+++ b/java/org/apache/catalina/ha/session/ClusterManagerBase.java
@@ -5,9 +5,9 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -33,9 +33,10 @@ import org.apache.catalina.session.ManagerBase;
 import org.apache.catalina.tribes.io.ReplicationStream;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.util.collections.SynchronizedStack;
 
 /**
- * 
+ *
  * @author Filip Hanik
  */
 public abstract class ClusterManagerBase extends ManagerBase
@@ -63,6 +64,14 @@ public abstract class ClusterManagerBase extends ManagerBase
      */
     private boolean recordAllActions = false;
 
+    private SynchronizedStack<DeltaRequest> deltaRequestPool = new 
SynchronizedStack<DeltaRequest>();
+
+
+    protected SynchronizedStack<DeltaRequest> getDeltaRequestPool() {
+        return deltaRequestPool;
+    }
+
+
     @Override
     public CatalinaCluster getCluster() {
         return cluster;
@@ -164,7 +173,7 @@ public abstract class ClusterManagerBase extends ManagerBase
     public ReplicationStream getReplicationStream(byte[] data, int offset, int 
length) throws IOException {
         ByteArrayInputStream fis = new ByteArrayInputStream(data, offset, 
length);
         return new ReplicationStream(fis, getClassLoaders());
-    }    
+    }
 
 
     //  ---------------------------------------------------- persistence 
handler
@@ -175,7 +184,7 @@ public abstract class ClusterManagerBase extends ManagerBase
      */
     @Override
     public void load() {
-        // NOOP 
+        // NOOP
     }
 
     /**
@@ -229,7 +238,7 @@ public abstract class ClusterManagerBase extends ManagerBase
 
                     if(replicationValve == null && log.isDebugEnabled()) {
                         log.debug("no ReplicationValve found for CrossContext 
Support");
-                    }//endif 
+                    }//endif
                 }//end if
             }//endif
         }//end if
diff --git a/java/org/apache/catalina/ha/session/DeltaManager.java 
b/java/org/apache/catalina/ha/session/DeltaManager.java
index d7b86ab..84a3b16 100644
--- a/java/org/apache/catalina/ha/session/DeltaManager.java
+++ b/java/org/apache/catalina/ha/session/DeltaManager.java
@@ -99,7 +99,6 @@ public class DeltaManager extends ClusterManagerBase{
     private boolean receiverQueue = false ;
     private boolean stateTimestampDrop = true ;
     private volatile long stateTransferCreateSendTime;
-    private SynchronizedStack<DeltaRequest> deltaRequestPool = new 
SynchronizedStack<DeltaRequest>();
 
     // ------------------------------------------------------------------ 
stats attributes
 
@@ -562,17 +561,23 @@ public class DeltaManager extends ClusterManagerBase{
      * @param session
      * @param data message data
      * @return The request
-     * @throws ClassNotFoundException
-     * @throws IOException
+     * @throws ClassNotFoundException Serialization error
+     * @throws IOException IO error with serialization
+     *
+     * @deprecated Unused. This will be removed in Tomcat 10.
+     *             Calling this method may result in a deadlock. See:
+     *             https://bz.apache.org/bugzilla/show_bug.cgi?id=62841
      */
-    protected DeltaRequest deserializeDeltaRequest(DeltaSession session, 
byte[] data) throws ClassNotFoundException, IOException {
+    @Deprecated
+    protected DeltaRequest deserializeDeltaRequest(DeltaSession session, 
byte[] data)
+            throws ClassNotFoundException, IOException {
+        session.lock();
         try {
-            session.lock();
             ReplicationStream ois = getReplicationStream(data);
             session.getDeltaRequest().readExternal(ois);
             ois.close();
             return session.getDeltaRequest();
-        }finally {
+        } finally {
             session.unlock();
         }
     }
@@ -966,6 +971,7 @@ public class DeltaManager extends ClusterManagerBase{
     public ClusterMessage requestCompleted(String sessionId, boolean expires) {
         DeltaSession session = null;
         SessionMessage msg = null;
+        SynchronizedStack<DeltaRequest> deltaRequestPool = 
getDeltaRequestPool();
         DeltaRequest deltaRequest = null;
         try {
             session = (DeltaSession) findSession(sessionId);
@@ -1244,14 +1250,8 @@ public class DeltaManager extends ClusterManagerBase{
                 log.debug(sm.getString("deltaManager.receiveMessage.delta",
                         getName(), msg.getSessionID()));
             }
-            try {
-                session.lock();
-                DeltaRequest dreq = deserializeDeltaRequest(session, delta);
-                dreq.execute(session, isNotifyListenersOnReplication());
-                session.setPrimarySession(false);
-            } finally {
-                session.unlock();
-            }
+
+            session.deserializeAndExecuteDeltaRequest(delta);
         }
     }
 
diff --git a/java/org/apache/catalina/ha/session/DeltaSession.java 
b/java/org/apache/catalina/ha/session/DeltaSession.java
index 151b1d6..7efafc6 100644
--- a/java/org/apache/catalina/ha/session/DeltaSession.java
+++ b/java/org/apache/catalina/ha/session/DeltaSession.java
@@ -44,6 +44,7 @@ import org.apache.catalina.session.StandardManager;
 import org.apache.catalina.session.StandardSession;
 import org.apache.catalina.tribes.io.ReplicationStream;
 import org.apache.catalina.tribes.tipis.ReplicatedMapEntry;
+import org.apache.tomcat.util.collections.SynchronizedStack;
 import org.apache.tomcat.util.res.StringManager;
 
 /**
@@ -640,6 +641,35 @@ public class DeltaSession extends StandardSession 
implements Externalizable,Clus
     }
 
 
+    protected void deserializeAndExecuteDeltaRequest(byte[] delta) throws 
IOException, ClassNotFoundException {
+        if (manager instanceof ClusterManagerBase) {
+            SynchronizedStack<DeltaRequest> deltaRequestPool =
+                    ((ClusterManagerBase) manager).getDeltaRequestPool();
+
+            DeltaRequest newDeltaRequest = deltaRequestPool.pop();
+            if (newDeltaRequest == null) {
+                newDeltaRequest = new DeltaRequest();
+            }
+
+            ReplicationStream ois = ((ClusterManagerBase) 
manager).getReplicationStream(delta);
+            newDeltaRequest.readExternal(ois);
+            ois.close();
+
+            DeltaRequest oldDeltaRequest = null;
+            lock();
+            try {
+                oldDeltaRequest = replaceDeltaRequest(newDeltaRequest);
+                newDeltaRequest.execute(this, ((ClusterManagerBase) 
manager).isNotifyListenersOnReplication());
+                setPrimarySession(false);
+            } finally {
+                unlock();
+                if (oldDeltaRequest != null) {
+                    oldDeltaRequest.reset();
+                    deltaRequestPool.push(oldDeltaRequest);
+                }
+            }
+        }
+    }
     // ------------------------------------------------- HttpSession Properties
 
     // ----------------------------------------------HttpSession Public Methods


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

Reply via email to