db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kahat...@apache.org
Subject svn commit: r1499256 - in /db/derby/code/trunk/java/engine/org/apache/derby: impl/services/timer/Java5SingletonTimerFactory.java impl/services/timer/SingletonTimerFactory.java modules.properties
Date Wed, 03 Jul 2013 08:32:34 GMT
Author: kahatlen
Date: Wed Jul  3 08:32:34 2013
New Revision: 1499256

URL: http://svn.apache.org/r1499256
Log:
DERBY-6114: Fold Java5SingletonTimerFactory into SingletonTimerFactory

Removed:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/Java5SingletonTimerFactory.java
Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java
    db/derby/code/trunk/java/engine/org/apache/derby/modules.properties

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java?rev=1499256&r1=1499255&r2=1499256&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/timer/SingletonTimerFactory.java
Wed Jul  3 08:32:34 2013
@@ -30,6 +30,7 @@ import java.security.PrivilegedAction;
 import java.util.Timer;
 import java.util.Properties;
 import java.util.TimerTask;
+import java.util.concurrent.atomic.AtomicInteger;
 
 
 /**
@@ -53,6 +54,13 @@ public class SingletonTimerFactory
     private Timer singletonTimer;
 
     /**
+     * The number of times {@link #cancel(TimerTask)} has been called.
+     * Used for determining whether it's time to purge cancelled tasks from
+     * the timer.
+     */
+    private final AtomicInteger cancelCount = new AtomicInteger();
+
+    /**
      * Initializes this TimerFactory with a singleton Timer instance.
      */
     public SingletonTimerFactory()
@@ -66,65 +74,17 @@ public class SingletonTimerFactory
          // DERBY-3745 We want to avoid leaking class loaders, so 
          // we make sure the context class loader is null before
          // creating the thread
-        ClassLoader savecl = null;
-        boolean hasGetClassLoaderPerms = false;
-        try {
-            savecl = AccessController.doPrivileged(
-            new PrivilegedAction<ClassLoader>() {
-                public ClassLoader run()  {
-                    return Thread.currentThread().getContextClassLoader();
-                }
-            });
-            hasGetClassLoaderPerms = true;
-        } catch (SecurityException se) {
-            // Ignore security exception. Versions of Derby before
-            // the DERBY-3745 fix did not require getClassLoader 
-            // privs.  We may leak class loaders if we are not
-            // able to do this but we can't just fail.
+        ClassLoader savecl = getContextClassLoader();
+        if (savecl != null) {
+            setContextClassLoader(null);
         }
-        if (hasGetClassLoaderPerms)
-            try {
-                AccessController.doPrivileged(
-                new PrivilegedAction<Object>() {
-                    public Object run()  {
-                        Thread.currentThread().setContextClassLoader(null);
-                        return null;
-                    }
-                });
-            } catch (SecurityException se) {
-                // ignore security exception.  Earlier versions of Derby, before the 
-                // DERBY-3745 fix did not require setContextClassloader permissions.
-                // We may leak class loaders if we are not able to set this, but 
-                // cannot just fail.
-            }
+
         singletonTimer = new Timer(true); // Run as daemon
-        if (hasGetClassLoaderPerms)
-            try {
-                final ClassLoader tmpsavecl = savecl;
-                AccessController.doPrivileged(
-                new PrivilegedAction<Object>() {
-                    public Object run()  {
-                        Thread.currentThread().setContextClassLoader(tmpsavecl);
-                        return null;
-                    }
-                });
-            } catch (SecurityException se) {
-                // ignore security exception.  Earlier versions of Derby, before the 
-                // DERBY-3745 fix did not require setContextClassloader permissions.
-                // We may leak class loaders if we are not able to set this, but 
-                // cannot just fail.
-            }
-    }
 
-    /**
-     * Returns a Timer object that can be used for adding TimerTasks
-     * that cancel executing statements.
-     *
-     * @return a Timer object for cancelling statements.
-     */
-    Timer getCancellationTimer()
-    {
-        return singletonTimer;
+        if (savecl != null) {
+            // Restore the original context class loader.
+            setContextClassLoader(savecl);
+        }
     }
 
     // TimerFactory interface methods
@@ -137,6 +97,23 @@ public class SingletonTimerFactory
     /** {@inheritDoc} */
     public void cancel(TimerTask task) {
         task.cancel();
+
+        // DERBY-6114: Cancelled tasks stay in the timer's queue until they
+        // are scheduled to run, unless we call the purge() method. This
+        // prevents garbage collection of the tasks. Even though the tasks
+        // are small objects, there could be many of them, especially when
+        // both the transaction throughput and tasks' delays are high, it
+        // could lead to OutOfMemoryErrors. Since purge() could be a heavy
+        // operation if the queue is big, we don't call it every time a task
+        // is cancelled.
+        //
+        // When Java 7 has been made the lowest supported level, we should
+        // consider replacing the java.util.Timer instance with a
+        // java.util.concurrent.ScheduledThreadPoolExecutor, and call
+        // setRemoveOnCancelPolicy(true) on the executor.
+        if (cancelCount.incrementAndGet() % 1000 == 0) {
+            singletonTimer.purge();
+        }
     }
 
     // ModuleControl interface methods
@@ -167,4 +144,40 @@ public class SingletonTimerFactory
     {
         singletonTimer.cancel();
     }
+
+    // Helper methods
+
+    private static ClassLoader getContextClassLoader() {
+        try {
+            return AccessController.doPrivileged(
+                    new PrivilegedAction<ClassLoader>() {
+                public ClassLoader run() {
+                    return Thread.currentThread().getContextClassLoader();
+                }
+            });
+        } catch (SecurityException se) {
+            // Ignore security exception. Versions of Derby before
+            // the DERBY-3745 fix did not require getContextClassLoader
+            // privileges. We may leak class loaders if we are not
+            // able to do this, but we can't just fail.
+            return null;
+        }
+    }
+
+    private static void setContextClassLoader(final ClassLoader cl) {
+        try {
+            AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                public Void run() {
+                    Thread.currentThread().setContextClassLoader(cl);
+                    return null;
+                }
+            });
+        } catch (SecurityException se) {
+            // Ignore security exception. Earlier versions of Derby, before
+            // the DERBY-3745 fix, did not require setContextClassLoader
+            // permissions. We may leak class loaders if we are not able to
+            // set this, but cannot just fail.
+        }
+    }
+
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/modules.properties
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/modules.properties?rev=1499256&r1=1499255&r2=1499256&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/modules.properties (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/modules.properties Wed Jul  3 08:32:34
2013
@@ -132,11 +132,6 @@ cloudscape.config.uuidJ1=all
 derby.module.timerJ1=org.apache.derby.impl.services.timer.SingletonTimerFactory
 cloudscape.config.timerJ1=all
 
-# Use a different TimerFactory on Java 5 to take advantage of Timer.purge().
-derby.module.timerJ6=org.apache.derby.impl.services.timer.Java5SingletonTimerFactory
-derby.env.jdk.timerJ6=6
-cloudscape.config.timerJ6=all
-
 # ConcurrentCache requires JDK 1.5 (constant 6)
 derby.module.cacheManagerJ6=org.apache.derby.impl.services.cache.ConcurrentCacheFactory
 derby.env.jdk.cacheManagerJ6=6



Mime
View raw message