You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by mr...@apache.org on 2006/10/24 11:27:53 UTC

svn commit: r467292 - in /jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit: core/SearchManager.java core/query/lucene/MultiIndex.java util/Timer.java

Author: mreutegg
Date: Tue Oct 24 02:27:52 2006
New Revision: 467292

URL: http://svn.apache.org/viewvc?view=rev&rev=467292
Log:
JCR-600: Repository does not release all resources on shutdown

Added:
    jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/util/Timer.java   (with props)
Modified:
    jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/SearchManager.java
    jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java

Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/SearchManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/SearchManager.java?view=diff&rev=467292&r1=467291&r2=467292
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/SearchManager.java (original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/SearchManager.java Tue Oct 24 02:27:52 2006
@@ -35,6 +35,7 @@
 import org.apache.jackrabbit.name.NoPrefixDeclaredException;
 import org.apache.jackrabbit.name.Path;
 import org.apache.jackrabbit.name.PathFormat;
+import org.apache.jackrabbit.util.Timer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -55,8 +56,6 @@
 import java.util.NoSuchElementException;
 import java.util.Properties;
 import java.util.Set;
-import java.util.Timer;
-import java.util.TimerTask;
 import java.util.WeakHashMap;
 
 /**
@@ -176,7 +175,7 @@
      * Task that checks if the query handler can be shut down because it
      * had been idle for {@link #idleTime} seconds.
      */
-    private final TimerTask idleChecker;
+    private final Timer.Task idleChecker;
 
     /**
      * Idle time in seconds. After the query handler had been idle for this
@@ -267,7 +266,7 @@
         // initialize query handler
         initializeQueryHandler();
 
-        idleChecker = new TimerTask() {
+        idleChecker = new Timer.Task() {
             public void run() {
                 if (lastAccess + (idleTime * 1000) < System.currentTimeMillis()) {
                     int inUse = activeQueries.size();

Modified: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java?view=diff&rev=467292&r1=467291&r2=467292
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java (original)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndex.java Tue Oct 24 02:27:52 2006
@@ -23,6 +23,7 @@
 import org.apache.jackrabbit.core.state.NodeState;
 import org.apache.jackrabbit.uuid.Constants;
 import org.apache.jackrabbit.uuid.UUID;
+import org.apache.jackrabbit.util.Timer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.lucene.document.Document;
@@ -36,8 +37,6 @@
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Timer;
-import java.util.TimerTask;
 import java.util.Arrays;
 import java.util.Set;
 import java.util.HashSet;
@@ -167,7 +166,7 @@
      * Task that is periodically called by {@link #FLUSH_TIMER} and checks
      * if index should be flushed.
      */
-    private final TimerTask flushTask;
+    private final Timer.Task flushTask;
 
     /**
      * The RedoLog of this <code>MultiIndex</code>.
@@ -288,7 +287,7 @@
         }
 
         lastFlushTime = System.currentTimeMillis();
-        flushTask = new TimerTask() {
+        flushTask = new Timer.Task() {
             public void run() {
                 checkFlush();
             }

Added: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/util/Timer.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/util/Timer.java?view=auto&rev=467292
==============================================================================
--- jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/util/Timer.java (added)
+++ jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/util/Timer.java Tue Oct 24 02:27:52 2006
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.util;
+
+import java.util.TimerTask;
+
+/**
+ * <code>Timer</code> wraps the standard Java {@link java.util.Timer} class
+ * and implements a guaranteed shutdown of the background thread running
+ * in the <code>Timer</code> instance.
+ */
+public class Timer {
+
+    /**
+     * The timer implementation we us internally.
+     */
+    private java.util.Timer delegatee;
+
+    /**
+     * Indicates whether the timer thread should run as deamon.
+     */
+    private final boolean runAsDeamon;
+
+    /**
+     * The number of currently scheduled tasks. If this value drops to zero
+     * the internal {@link java.util.Timer} instance is canceled. Whenever
+     * this value increases from zero to one a new {@link java.util.Timer}
+     * instance is created and started.
+     */
+    private int numScheduledTasks = 0;
+
+    /**
+     * Creates a new <code>Timer</code> instance.
+     *
+     * @param isDeamon if <code>true</code> the background thread wil run as
+     *                 deamon.
+     */
+    public Timer(boolean isDeamon) {
+        runAsDeamon = isDeamon;
+    }
+
+    /**
+     * Schedules the specified task for repeated <i>fixed-delay execution</i>,
+     * beginning after the specified delay.  Subsequent executions take place
+     * at approximately regular intervals separated by the specified period.
+     *
+     * @param task   task to be scheduled.
+     * @param delay  delay in milliseconds before task is to be executed.
+     * @param period time in milliseconds between successive task executions.
+     * @throws IllegalArgumentException if <tt>delay</tt> is negative, or
+     *         <tt>delay + System.currentTimeMillis()</tt> is negative.
+     * @throws IllegalStateException if task was already scheduled or
+     *         cancelled, timer was cancelled, or timer thread terminated.
+     * @see java.util.Timer#schedule(java.util.TimerTask, long, long)
+     */
+    public void schedule(Task task, long delay, long period) {
+        if (delay < 0)
+            throw new IllegalArgumentException("Negative delay.");
+        if (period <= 0)
+            throw new IllegalArgumentException("Non-positive period.");
+        synchronized (this) {
+            if (delegatee == null) {
+                delegatee = new java.util.Timer(runAsDeamon);
+            }
+            delegatee.schedule(task, delay, period);
+            task.setTimer(this);
+            numScheduledTasks++;
+        }
+    }
+
+    /**
+     * Terminates this timer, discarding any currently scheduled tasks.
+     * Does not interfere with a currently executing task (if it exists).
+     * Once a timer has been terminated, its execution thread terminates
+     * gracefully, and no more tasks may be scheduled on it.
+     *
+     * <p>Note that calling this method from within the run method of a
+     * timer task that was invoked by this timer absolutely guarantees that
+     * the ongoing task execution is the last task execution that will ever
+     * be performed by this timer.
+     *
+     * <p>This method may be called repeatedly; the second and subsequent
+     * calls have no effect.
+     */
+    public void cancel() {
+        synchronized (this) {
+            if (delegatee != null) {
+                delegatee.cancel();
+                numScheduledTasks = 0;
+                delegatee = null;
+            }
+        }
+    }
+
+    /**
+     * Notifies this <code>Timer</code> that a task has been canceled.
+     */
+    private void taskCanceled() {
+        synchronized (this) {
+            if (--numScheduledTasks == 0) {
+                delegatee.cancel();
+                delegatee = null;
+            }
+        }
+    }
+
+    /**
+     * Extends the <code>TimerTask</code> with callback hooks to this
+     * <code>Timer</code> implementation.
+     */
+    public static abstract class Task extends TimerTask {
+
+        /**
+         * The <code>Timer</code> instance where this <code>Task</code> is
+         * scheduled on.
+         */
+        private Timer timer;
+
+        /**
+         * Sets the timer instance where this task is scheduled on.
+         * @param timer the timer instance.
+         */
+        private void setTimer(Timer timer) {
+            this.timer = timer;
+        }
+
+        /**
+         * @inheritDoc
+         */
+        public final boolean cancel() {
+            if (timer != null) {
+                timer.taskCanceled();
+                timer = null;
+            }
+            return super.cancel();
+        }
+    }
+}

Propchange: jackrabbit/trunk/jackrabbit/src/main/java/org/apache/jackrabbit/util/Timer.java
------------------------------------------------------------------------------
    svn:eol-style = native