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 2021/08/23 11:40:21 UTC

[tomcat] branch main updated: Refactor to remove use of finalize()

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

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


The following commit(s) were added to refs/heads/main by this push:
     new 4745922  Refactor to remove use of finalize()
4745922 is described below

commit 4745922c8ddd81d537770c8519f7fa39e239dba3
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Mon Aug 23 12:40:11 2021 +0100

    Refactor to remove use of finalize()
---
 .../tribes/transport/nio/ParallelNioSender.java    | 74 ++++++++++++++--------
 webapps/docs/changelog.xml                         |  8 +++
 2 files changed, 57 insertions(+), 25 deletions(-)

diff --git a/java/org/apache/catalina/tribes/transport/nio/ParallelNioSender.java b/java/org/apache/catalina/tribes/transport/nio/ParallelNioSender.java
index 3372b39..c90f4c7 100644
--- a/java/org/apache/catalina/tribes/transport/nio/ParallelNioSender.java
+++ b/java/org/apache/catalina/tribes/transport/nio/ParallelNioSender.java
@@ -17,6 +17,7 @@
 package org.apache.catalina.tribes.transport.nio;
 
 import java.io.IOException;
+import java.lang.ref.Cleaner;
 import java.net.UnknownHostException;
 import java.nio.channels.SelectionKey;
 import java.nio.channels.Selector;
@@ -46,12 +47,16 @@ public class ParallelNioSender extends AbstractSender implements MultiPointSende
 
     private static final Log log = LogFactory.getLog(ParallelNioSender.class);
     protected static final StringManager sm = StringManager.getManager(ParallelNioSender.class);
+
+    private static final Cleaner cleaner = Cleaner.create();
+
+    private final InternalState state;
+
     protected final long selectTimeout = 5000; //default 5 seconds, same as send timeout
-    protected final Selector selector;
-    protected final HashMap<Member, NioSender> nioSenders = new HashMap<>();
 
     public ParallelNioSender() throws IOException {
-        selector = Selector.open();
+        state = new InternalState(Selector.open());
+        cleaner.register(this, state);
         setConnected(true);
     }
 
@@ -143,7 +148,7 @@ public class ParallelNioSender extends AbstractSender implements MultiPointSende
         SendResult result = new SendResult();
         int selectedKeys;
         try {
-            selectedKeys = selector.select(selectTimeOut);
+            selectedKeys = state.selector.select(selectTimeOut);
         } catch (IOException ioe) {
             throw new ChannelException(sm.getString("parallelNioSender.send.failed"), ioe);
         }
@@ -152,7 +157,7 @@ public class ParallelNioSender extends AbstractSender implements MultiPointSende
             return result;
         }
 
-        Iterator<SelectionKey> it = selector.selectedKeys().iterator();
+        Iterator<SelectionKey> it = state.selector.selectedKeys().iterator();
         while (it.hasNext()) {
             SelectionKey sk = it.next();
             it.remove();
@@ -287,17 +292,17 @@ public class ParallelNioSender extends AbstractSender implements MultiPointSende
         ChannelException cx = null;
         NioSender[] result = new NioSender[destination.length];
         for ( int i=0; i<destination.length; i++ ) {
-            NioSender sender = nioSenders.get(destination[i]);
+            NioSender sender = state.nioSenders.get(destination[i]);
             try {
 
                 if (sender == null) {
                     sender = new NioSender();
                     AbstractSender.transferProperties(this, sender);
-                    nioSenders.put(destination[i], sender);
+                    state.nioSenders.put(destination[i], sender);
                 }
                 sender.reset();
                 sender.setDestination(destination[i]);
-                sender.setSelector(selector);
+                sender.setSelector(state.selector);
                 sender.setUdpBased(isUdpBased());
                 result[i] = sender;
             }catch ( UnknownHostException x ) {
@@ -323,7 +328,7 @@ public class ParallelNioSender extends AbstractSender implements MultiPointSende
 
     private synchronized void close() throws ChannelException  {
         ChannelException x = null;
-        Iterator<Map.Entry<Member,NioSender>> iter = nioSenders.entrySet().iterator();
+        Iterator<Map.Entry<Member,NioSender>> iter = state.nioSenders.entrySet().iterator();
         while (iter.hasNext()) {
             Map.Entry<Member,NioSender> entry = iter.next();
             try {
@@ -349,7 +354,7 @@ public class ParallelNioSender extends AbstractSender implements MultiPointSende
     @Override
     public void remove(Member member) {
         //disconnect senders
-        NioSender sender = nioSenders.remove(member);
+        NioSender sender = state.nioSenders.remove(member);
         if ( sender != null ) {
             sender.disconnect();
         }
@@ -367,22 +372,9 @@ public class ParallelNioSender extends AbstractSender implements MultiPointSende
     }
 
     @Override
-    protected void finalize() throws Throwable {
-        try {disconnect(); }catch ( Exception e){/*Ignore*/}
-        try {
-            selector.close();
-        }catch (Exception e) {
-            if (log.isDebugEnabled()) {
-                log.debug("Failed to close selector", e);
-            }
-        }
-        super.finalize();
-    }
-
-    @Override
     public boolean keepalive() {
         boolean result = false;
-        for (Iterator<Entry<Member,NioSender>> i = nioSenders.entrySet().iterator(); i.hasNext();) {
+        for (Iterator<Entry<Member,NioSender>> i = state.nioSenders.entrySet().iterator(); i.hasNext();) {
             Map.Entry<Member, NioSender> entry = i.next();
             NioSender sender = entry.getValue();
             if ( sender.keepalive() ) {
@@ -405,8 +397,40 @@ public class ParallelNioSender extends AbstractSender implements MultiPointSende
         }
         //clean up any cancelled keys
         if ( result ) {
-            try { selector.selectNow(); }catch (Exception e){/*Ignore*/}
+            try { state.selector.selectNow(); }catch (Exception e){/*Ignore*/}
         }
         return result;
     }
+
+
+    private static class InternalState implements Runnable {
+
+        private final Selector selector;
+        private final HashMap<Member, NioSender> nioSenders = new HashMap<>();
+
+        private InternalState(Selector selector) {
+            this.selector = selector;
+        }
+
+        @Override
+        public void run() {
+            Iterator<NioSender> iter = nioSenders.values().iterator();
+            while (iter.hasNext()) {
+                NioSender nioSender = iter.next();
+                try {
+                    nioSender.disconnect();
+                } catch (Exception e) {
+                    // Ignore
+                }
+                iter.remove();
+            }
+            try {
+                selector.close();
+            } catch (Exception e) {
+                if (log.isDebugEnabled()) {
+                    log.debug("Failed to close selector", e);
+                }
+            }
+        }
+    }
 }
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index ba8a5c4..3c644e6 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -185,6 +185,14 @@
       </fix>
     </changelog>
   </subsection>
+  <subsection name="Tribes">
+    <changelog>
+      <scode>
+        Refactor the <code>ParallelNioSender</code> to avoid the use of
+        <code>finalize()</code>. (markt)
+      </scode>
+    </changelog>
+  </subsection>
   <subsection name="Other">
     <changelog>
       <fix>

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