You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by mi...@apache.org on 2011/03/15 08:23:09 UTC

svn commit: r1081677 - /db/derby/code/trunk/java/engine/org/apache/derby/impl/services/daemon/IndexStatisticsDaemonImpl.java

Author: mikem
Date: Tue Mar 15 07:23:09 2011
New Revision: 1081677

URL: http://svn.apache.org/viewvc?rev=1081677&view=rev
Log:
DERBY-5108

Changes istat daemon shutdown to check during processing if a shutdown is
in progress and respond to the shutdown immediately.  Also changes the
module stop() to wait for worker threads to exit before returning.  Waiting
for work to stop allows the subsequent shutdown of the storage system to
properly close it's files during a clean shutdown request.  Without this
change the system sometimes left files open which the nightly tests uncovered
on windows machines while trying to delete those files.

This change is a slightly modified version of a patch proposed by Knut Anders Ha
tlen.

Previous to this change the AutomaticIndexStatisticsTest.testShutdownWhileScanni
ngThenDelete
test would fail on my machine consistently in SANE classes mode on a windows XP
laptop.  After this
I have only seen one failure in 50 runs.  Checking it in as it is definitely
an improvement and want to see if it fixes the errors in the nightly's across
a number of environments.


Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/services/daemon/IndexStatisticsDaemonImpl.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/services/daemon/IndexStatisticsDaemonImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/services/daemon/IndexStatisticsDaemonImpl.java?rev=1081677&r1=1081676&r2=1081677&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/services/daemon/IndexStatisticsDaemonImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/services/daemon/IndexStatisticsDaemonImpl.java Tue Mar 15 07:23:09 2011
@@ -424,12 +424,11 @@ public class IndexStatisticsDaemonImpl
         {
             if (conglomerateNumber[indexNumber] == -1)
                 continue;
+
             // Check if daemon has been disabled.
             if (asBackgroundTask) {
-                synchronized (queue) {
-                    if (daemonDisabled) {
-                        break;
-                    }
+                if (isShuttingDown()) {
+                    break;
                 }
             }
 
@@ -458,9 +457,25 @@ public class IndexStatisticsDaemonImpl
 
             try
             {
-                int rowsFetched = 0;
+                int     rowsFetched           = 0;
+                boolean giving_up_on_shutdown = false;
+
                 while ((rowsFetched = cmp.fetchRows(gsc)) > 0)
                 {
+                    // DERBY-5108
+                    // Check if daemon has been disabled, and if so stop
+                    // scan and exit asap.  On shutdown the system will
+                    // send interrupts, but the system currently will
+                    // recover from these during the scan and allow the
+                    // scan to finish. Checking here after each group
+                    // I/O that is processed as a convenient point.
+                    if (asBackgroundTask) {
+                        if (isShuttingDown()) {
+                            giving_up_on_shutdown = true;
+                            break;
+                        }
+                    }
+
                     for (int i = 0; i < rowsFetched; i++)
                     {
                         int whichPositionChanged = cmp.compareWithPrevKey(i);
@@ -469,7 +484,12 @@ public class IndexStatisticsDaemonImpl
                                 cardinality[j]++;
                         }
                     }
+
                 } // while
+
+                if (giving_up_on_shutdown)
+                    break;
+
                 gsc.setEstimatedRowCount(cmp.getRowCount());
             } // try
             finally
@@ -478,6 +498,7 @@ public class IndexStatisticsDaemonImpl
                 gsc = null;
             }
             scanTimes[sci++][2] = System.currentTimeMillis();
+
             // We have scanned the indexes, so let's give this a few attempts
             // before giving up.
             int retries = 0;
@@ -502,6 +523,7 @@ public class IndexStatisticsDaemonImpl
                 }
             }
         }
+
         log(asBackgroundTask, td, fmtScanTimes(scanTimes));
     }
 
@@ -863,6 +885,8 @@ public class IndexStatisticsDaemonImpl
      * first time the method is invoked.
      */
     public void stop() {
+        Thread threadToWaitFor = null;
+
         synchronized (queue) {
             if (!daemonDisabled) {
                 StringBuffer sb = new StringBuffer(100);
@@ -886,12 +910,26 @@ public class IndexStatisticsDaemonImpl
                     daemonLCC = null;
                 }
                 daemonDisabled = true;
+                threadToWaitFor = runningThread;
                 runningThread = null;
                 queue.clear();
             }
+
+        }
+
+        // Wait for the currently running thread, if there is one. Must do
+        // this outside of the synchronized block so that we don't deadlock
+        // with the thread.
+        if (threadToWaitFor != null) {
+            try {
+                threadToWaitFor.join();
+            } catch (InterruptedException ie) {
+                // Never mind. The thread will die eventually.
+            }
         }
     }
 
+
     /**
      * Handles fatal errors that will cause the daemon to be shut down.
      *