sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1429706 - in /sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis: internal/util/ util/resources/
Date Mon, 07 Jan 2013 08:42:49 GMT
Author: desruisseaux
Date: Mon Jan  7 08:42:48 2013
New Revision: 1429706

URL: http://svn.apache.org/viewvc?rev=1429706&view=rev
Log:
Centralize the shutdown logic in a new Shutdown class, to be registered to the JVM in a future
version.

Added:
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/Shutdown.java
  (with props)
Modified:
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/DaemonThread.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/DelayedExecutor.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/OSGiActivator.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/Supervisor.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/SupervisorMBean.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/Threads.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/DaemonThread.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/DaemonThread.java?rev=1429706&r1=1429705&r2=1429706&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/DaemonThread.java
(original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/DaemonThread.java
Mon Jan  7 08:42:48 2013
@@ -99,6 +99,18 @@ abstract class DaemonThread extends Thre
     public abstract void run();
 
     /**
+     * Returns {@code true} if this thread seems to be blocked for a time long enough for
suspecting
+     * a problem. The default implementation always returns {@code false}. Subclasses are
encouraged
+     * to provide some problem detection mechanism here if they can. For example if the head
of a
+     * queue seems to be never removed, then maybe the process consuming that queue is blocked.
+     *
+     * @return {@code true} if this thread seems to be stalled.
+     */
+    protected boolean isStalled() {
+        return false;
+    }
+
+    /**
      * Returns {@code true} if this daemon thread shall terminate.
      * This happen at shutdown time.
      *
@@ -137,26 +149,24 @@ abstract class DaemonThread extends Thre
     }
 
     /**
-     * Returns the names of dead threads, or {@code null} if none. The returned list should
-     * always be null. A non-empty list would be a symptom for a severe problem, probably
+     * Returns the list of stalled or dead threads, or {@code null} if none. The returned
list
+     * should always be null. A non-empty list would be a symptom for a severe problem, probably
      * requiring an application reboot.
      *
      * <p><strong>This method is for internal use by Apache SIS only.</strong>
      * Users should never invoke this method explicitely.</p>
      *
      * @param  thread The first thread in the chain of threads to verify.
-     * @return The name of dead threads, or {@code null} if none.
-     *
-     * @see Threads#listDeadThreads()
+     * @return The list of stalled or dead threads, or {@code null} if none.
      */
-    static List<String> listDeadThreads(DaemonThread thread) {
-        List<String> list = null;
+    static List<Thread> listStalledThreads(DaemonThread thread) {
+        List<Thread> list = null;
         while (thread != null) {
-            if (!thread.isAlive()) {
+            if (!thread.isAlive() || thread.isStalled()) {
                 if (list == null) {
                     list = new ArrayList<>();
                 }
-                list.add(thread.getName());
+                list.add(thread);
             }
             thread = thread.previous;
         }

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/DelayedExecutor.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/DelayedExecutor.java?rev=1429706&r1=1429705&r2=1429706&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/DelayedExecutor.java
(original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/DelayedExecutor.java
Mon Jan  7 08:42:48 2013
@@ -16,6 +16,7 @@
  */
 package org.apache.sis.internal.util;
 
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.DelayQueue;
 import java.util.concurrent.BlockingQueue;
 import org.apache.sis.util.logging.Logging;
@@ -182,4 +183,28 @@ public final class DelayedExecutor exten
         }
         // Do not log anything at this point, since the loggers may be shutdown now.
     }
+
+    /**
+     * Returns {@code true} if this thread seems to be stalled. This method checks the head
+     * of the queue. If the delay for that head has expired and the head is not removed in
+     * the next 5 seconds, then we will presume that the thread is stalled or dead.
+     */
+    @Override
+    protected boolean isStalled() {
+        final DelayedRunnable waiting = QUEUE.peek();
+        if (waiting != null && waiting.getDelay(TimeUnit.NANOSECONDS) <= 0) try
{
+            for (int i=0; i<50; i++) {
+                if (!isAlive()) break;
+                Thread.sleep(100);
+                if (QUEUE.peek() != waiting) {
+                    return false;
+                }
+            }
+            return true;
+        } catch (InterruptedException e) {
+            // Someone doesn't want to let us wait. Since we didn't had the time to
+            // determine if the thread is stalled, conservatively return 'false'.
+        }
+        return false;
+    }
 }

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/OSGiActivator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/OSGiActivator.java?rev=1429706&r1=1429705&r2=1429706&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/OSGiActivator.java
(original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/OSGiActivator.java
Mon Jan  7 08:42:48 2013
@@ -51,15 +51,10 @@ public final class OSGiActivator impleme
      * This method shutdowns the {@code sis-utility} threads.
      *
      * @param  context The execution context of the bundle being stopped.
-     * @throws InterruptedException If an other thread invoked {@link #interrupt()} while
-     *         we were waiting for the {@code sis-utility} threads to die.
      * @throws JMException If an error occurred during unregistration of the supervisor MBean.
      */
     @Override
-    public void stop(final BundleContext context) throws InterruptedException, JMException
{
-        Threads.shutdown(4000);
-        if (Supervisor.ENABLED) {
-            Supervisor.unregister();
-        }
+    public void stop(final BundleContext context) throws JMException {
+        Shutdown.stop(getClass());
     }
 }

Added: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/Shutdown.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/Shutdown.java?rev=1429706&view=auto
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/Shutdown.java
(added)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/Shutdown.java
Mon Jan  7 08:42:48 2013
@@ -0,0 +1,77 @@
+/*
+ * 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.sis.internal.util;
+
+import javax.management.JMException;
+import org.apache.sis.util.logging.Logging;
+
+
+/**
+ * A central place where to manage SIS shutdown process.
+ * For now this class is not yet registered as a shutdown hock,
+ * but it will be in a future version.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.3
+ * @version 0.3
+ * @module
+ */
+public final class Shutdown {
+    /**
+     * Do not allow instantiation of this class.
+     */
+    private Shutdown() {
+    }
+
+    /**
+     * Shutdowns the {@code sis-utility} threads and unregister the supervisor MBean.
+     *
+     * @param  caller The class invoking this method, to be used only for logging purpose,
+     *         or {@code null} if the logging system is not available anymore (i.e. the JVM
+     *         itself is shutting down).
+     * @throws JMException If an error occurred during unregistration of the supervisor MBean.
+     */
+    public static void stop(final Class<?> caller) throws JMException {
+        /*
+         * Unregister the MBean before to stop the threads, in order to avoid false alerts
+         * in the superviror 'warnings()' method. Failure to unregister the MBean is worth
+         * to report, but we will do that only after we completed the other shutdown steps.
+         */
+        JMException exception = null;
+        if (Supervisor.ENABLED) try {
+            Supervisor.unregister();
+        } catch (JMException deferred) {
+            exception = deferred;
+        }
+        /*
+         * Following is usually fast, but may potentially take a little while.
+         * If an other thread invoked Thread.interrupt() while we were waiting
+         * for the threads to terminate, maybe not all threads have terminated
+         * but continue the shutdown process anyway.
+         */
+        try {
+            Threads.shutdown(System.nanoTime() + 4000);
+        } catch (InterruptedException e) {
+            if (caller != null) {
+                Logging.unexpectedException(caller, "stop", e);
+            }
+        }
+        if (exception != null) {
+            throw exception;
+        }
+    }
+}

Propchange: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/Shutdown.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/Shutdown.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/Supervisor.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/Supervisor.java?rev=1429706&r1=1429705&r2=1429706&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/Supervisor.java
(original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/Supervisor.java
Mon Jan  7 08:42:48 2013
@@ -199,13 +199,21 @@ public final class Supervisor extends St
      * {@inheritDoc}
      */
     @Override
-    public List<String> warnings() {
-        final List<String> warnings = Threads.listDeadThreads();
-        if (warnings != null) {
-            final Errors resources = Errors.getResources(locale);
-            for (int i=warnings.size(); --i>=0;) {
-                warnings.set(i, resources.getString(Errors.Keys.DeadThread_1, warnings.get(i)));
-            }
+    public String[] warnings() {
+        final DaemonThread lastCreatedDaemon;
+        synchronized (Threads.class) {
+            lastCreatedDaemon = Threads.lastCreatedDaemon;
+        }
+        final List<Thread> threads = DaemonThread.listStalledThreads(lastCreatedDaemon);
+        if (threads == null) {
+            return null;
+        }
+        final String[] warnings = new String[threads.size()];
+        final Errors resources = Errors.getResources(locale);
+        for (int i=0; i<warnings.length; i++) {
+            final Thread thread = threads.get(i);
+            warnings[i] = resources.getString(thread.isAlive() ?
+                    Errors.Keys.StalledThread_1 : Errors.Keys.DeadThread_1, thread.getName());
         }
         return warnings;
     }

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/SupervisorMBean.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/SupervisorMBean.java?rev=1429706&r1=1429705&r2=1429706&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/SupervisorMBean.java
(original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/SupervisorMBean.java
Mon Jan  7 08:42:48 2013
@@ -16,7 +16,6 @@
  */
 package org.apache.sis.internal.util;
 
-import java.util.List;
 import org.apache.sis.util.collection.TreeTable;
 
 
@@ -46,5 +45,5 @@ public interface SupervisorMBean {
      *
      * @return A description of a problems in the library, or {@code null} if none.
      */
-    List<String> warnings();
+    String[] warnings();
 }

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/Threads.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/Threads.java?rev=1429706&r1=1429705&r2=1429706&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/Threads.java
(original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/internal/util/Threads.java
Mon Jan  7 08:42:48 2013
@@ -16,7 +16,6 @@
  */
 package org.apache.sis.internal.util;
 
-import java.util.List;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.ExecutorService;
 import org.apache.sis.util.Static;
@@ -131,15 +130,4 @@ final class Threads extends Static {
         }
         DaemonThread.killAll(lastCreatedDaemon, stopWaitingAt);
     }
-
-    /**
-     * Returns the names of dead threads, or {@code null} if none. The returned list should
-     * always be null. A non-empty list would be a symptom for a severe problem, probably
-     * requiring an application reboot.
-     *
-     * @return The name of dead threads, or {@code null} if none.
-     */
-    static synchronized List<String> listDeadThreads() {
-        return DaemonThread.listDeadThreads(lastCreatedDaemon);
-    }
 }

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1429706&r1=1429705&r2=1429706&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
(original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
Mon Jan  7 08:42:48 2013
@@ -309,6 +309,11 @@ public final class Errors extends Indexe
         public static final int RequireDecimalSeparator = 33;
 
         /**
+         * Thread “{0}” seems stalled.
+         */
+        public static final int StalledThread_1 = 63;
+
+        /**
          * Unexpected change in ‘{0}’.
          */
         public static final int UnexpectedChange_1 = 56;

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1429706&r1=1429705&r2=1429706&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
(original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
Mon Jan  7 08:42:48 2013
@@ -74,6 +74,7 @@ NullArgument_1                  = Argume
 OddArrayLength_1                = Array length is {0}, while we expected an even length.
 RecursiveCreateCallForKey_1     = Recursive call while creating an object for the \u201c{0}\u201d
key.
 RequireDecimalSeparator         = A decimal separator is required.
+StalledThread_1                 = Thread \u201c{0}\u201d seems stalled.
 UnexpectedChange_1              = Unexpected change in \u2018{0}\u2019.
 UnexpectedEndOfString_1         = More characters were expected at the end of \u201c{0}\u201d.
 UnmodifiableAffineTransform     = This affine transform is unmodifiable.

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1429706&r1=1429705&r2=1429706&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
(original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
Mon Jan  7 08:42:48 2013
@@ -63,6 +63,7 @@ NullArgument_1                  = L\u201
 OddArrayLength_1                = La longueur du tableau est {0}, alors qu\u2019on attendait
une longueur paire.
 RecursiveCreateCallForKey_1     = Appel r\u00e9cursif lors de la cr\u00e9ation d\u2019un
objet pour la cl\u00e9 \u201c{0}\u201d.
 RequireDecimalSeparator         = Un s\u00e9parateur d\u00e9cimal est requis.
+StalledThread_1                 = La t\u00e2che \u201c{0}\u201d semble bloqu\u00e9e.
 UnexpectedChange_1              = Changement inattendu dans \u2018{0}\u2019.
 UnexpectedEndOfString_1         = D\u2019autres caract\u00e8res \u00e9taient attendus \u00e0
la fin du texte \u201c{0}\u201d.
 UnmodifiableAffineTransform     = Cette transformation affine n\u2019est pas modifiable.



Mime
View raw message