db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d..@apache.org
Subject svn commit: r1200995 - in /db/derby/code/trunk/java/engine/org/apache/derby: iapi/util/InterruptStatus.java impl/io/DirFile4.java impl/store/raw/data/FileContainer.java impl/store/raw/data/RAFContainer.java impl/store/raw/data/RAFContainer4.java
Date Fri, 11 Nov 2011 17:52:16 GMT
Author: dag
Date: Fri Nov 11 17:52:16 2011
New Revision: 1200995

URL: http://svn.apache.org/viewvc?rev=1200995&view=rev
Log:
DERBY-5498 ClosedByInterruptException in AuthenticationTest

Patch d5498b plugs a hole in the handling of NIO channel closures due
to interrupt in DirFile4#getExclusiveFileLock.
 

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/util/InterruptStatus.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/io/DirFile4.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/FileContainer.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/RAFContainer.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/RAFContainer4.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/util/InterruptStatus.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/util/InterruptStatus.java?rev=1200995&r1=1200994&r2=1200995&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/util/InterruptStatus.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/util/InterruptStatus.java Fri Nov
11 17:52:16 2011
@@ -57,6 +57,13 @@ import org.apache.derby.iapi.sql.conn.La
 public class InterruptStatus {
 
     /**
+     * Constants used by code that retries file operations after seeing the
+     * NIO file channel closed due to interrupts.
+     */
+    public final static int MAX_INTERRUPT_RETRIES = 120;
+    public final static int INTERRUPT_RETRY_SLEEP = 500; // millis
+
+    /**
      * Use thread local variable to store interrupt status flag *only* if we
      * don't have lcc, e.g. during database creation, shutdown etc.
      */

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/io/DirFile4.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/io/DirFile4.java?rev=1200995&r1=1200994&r2=1200995&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/io/DirFile4.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/io/DirFile4.java Fri Nov 11 17:52:16
2011
@@ -31,12 +31,13 @@ import java.io.OutputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.RandomAccessFile;
+import java.nio.channels.AsynchronousCloseException;
+import java.nio.channels.ClosedChannelException;
 import java.nio.channels.FileChannel;
 import java.nio.channels.FileLock;
 import java.nio.channels.OverlappingFileLockException;
-import java.security.AccessControlException;
 import org.apache.derby.iapi.error.StandardException;
-import org.apache.derby.shared.common.reference.SQLState;
+import org.apache.derby.iapi.util.InterruptStatus;
 
 /**
  * This class implements the StorageFile interface using features of Java 1.4 not available
in earlier
@@ -154,24 +155,42 @@ class DirFile4 extends DirFile
 			//If we can acquire a reliable exclusive lock , try to get it.
 			if(validExclusiveLock)
 			{
-				lockFileOpen = new RandomAccessFile((File) this, "rw");
-                limitAccessToOwner(); // tamper-proof..
-				lockFileChannel = lockFileOpen.getChannel();
-				dbLock =lockFileChannel.tryLock();
-				if(dbLock == null)
-				{
-					lockFileChannel.close();
-					lockFileChannel=null;
-					lockFileOpen.close();
-					lockFileOpen = null;
-					status = EXCLUSIVE_FILE_LOCK_NOT_AVAILABLE;
-				}
-				else
-				{	
-					lockFileOpen.writeInt(EXCLUSIVE_FILE_LOCK);
-					lockFileChannel.force(true);
-					status = EXCLUSIVE_FILE_LOCK;
-				}
+                int retries = InterruptStatus.MAX_INTERRUPT_RETRIES;
+                while (true) {
+                    lockFileOpen = new RandomAccessFile((File) this, "rw");
+                    limitAccessToOwner(); // tamper-proof..
+                    lockFileChannel = lockFileOpen.getChannel();
+
+                    try {
+                        dbLock =lockFileChannel.tryLock();
+                        if(dbLock == null) {
+                            lockFileChannel.close();
+                            lockFileChannel=null;
+                            lockFileOpen.close();
+                            lockFileOpen = null;
+                            status = EXCLUSIVE_FILE_LOCK_NOT_AVAILABLE;
+                        } else {
+                            lockFileOpen.writeInt(EXCLUSIVE_FILE_LOCK);
+                            lockFileChannel.force(true);
+                            status = EXCLUSIVE_FILE_LOCK;
+                        }
+                    } catch (AsynchronousCloseException e) {
+                        // JDK bug 6979009: use AsynchronousCloseException
+                        // instead of the logically correct
+                        // ClosedByInterruptException
+
+                        InterruptStatus.setInterrupted();
+                        lockFileOpen.close();
+
+                        if (retries-- > 0) {
+                            continue;
+                        } else {
+                            throw e;
+                        }
+                    }
+
+                    break;
+                }
 			}
 			else
 			{

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/FileContainer.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/FileContainer.java?rev=1200995&r1=1200994&r2=1200995&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/FileContainer.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/FileContainer.java
Fri Nov 11 17:52:16 2011
@@ -1511,8 +1511,6 @@ abstract class FileContainer 
 		}
 	}
 
-    protected final static int INTERRUPT_RETRY_SLEEP = 500; // millis
-    protected final static int MAX_INTERRUPT_RETRIES = 120; // i.e. 60s
 
 	/**
 	  Create a new page in the container.
@@ -1587,7 +1585,7 @@ abstract class FileContainer 
 		boolean retry;
 		int numtries = 0;
 
-        int maxTries = MAX_INTERRUPT_RETRIES;
+        int maxTries = InterruptStatus.MAX_INTERRUPT_RETRIES;
 
         long startSearch = lastAllocatedPage;
 
@@ -1674,7 +1672,8 @@ abstract class FileContainer 
                             // we re-grab monitor on "this" (which recovery
                             // needs) and retry writeRAFHeader.
                             try {
-                                Thread.sleep(INTERRUPT_RETRY_SLEEP);
+                                Thread.sleep(
+                                    InterruptStatus.INTERRUPT_RETRY_SLEEP);
                             } catch (InterruptedException ee) {
                                 // This thread received an interrupt as
                                 // well, make a note.
@@ -2069,7 +2068,7 @@ abstract class FileContainer 
 	{
 		boolean retval = false;
         boolean done;
-        int maxTries = MAX_INTERRUPT_RETRIES;
+        int maxTries = InterruptStatus.MAX_INTERRUPT_RETRIES;
 
         do {
             done = true;
@@ -2095,7 +2094,7 @@ abstract class FileContainer 
                         // we re-grab monitor on "this" (which recovery
                         // needs) and retry writeRAFHeader.
                         try {
-                            Thread.sleep(INTERRUPT_RETRY_SLEEP);
+                            Thread.sleep(InterruptStatus.INTERRUPT_RETRY_SLEEP);
                         } catch (InterruptedException ee) {
                             // This thread received an interrupt as
                             // well, make a note.

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/RAFContainer.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/RAFContainer.java?rev=1200995&r1=1200994&r2=1200995&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/RAFContainer.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/RAFContainer.java
Fri Nov 11 17:52:16 2011
@@ -435,7 +435,7 @@ class RAFContainer extends FileContainer
         // release our monitor on "this" and to retry writeRAFHeader, so be
         // prepared to retry.
         boolean success = false;
-        int maxTries = MAX_INTERRUPT_RETRIES; // ca 60s = (120 * 0.5s)
+        int maxTries = InterruptStatus.MAX_INTERRUPT_RETRIES;
 
         while (!success) {
             success = true;
@@ -512,7 +512,8 @@ class RAFContainer extends FileContainer
                             // we re-grab monitor on "this" (which recovery
                             // needs) and retry writeRAFHeader.
                             try {
-                                Thread.sleep(INTERRUPT_RETRY_SLEEP);
+                                Thread.sleep(
+                                    InterruptStatus.INTERRUPT_RETRY_SLEEP);
                             } catch (InterruptedException ee) {
                                 // This thread received an interrupt as
                                 // well, make a note.

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/RAFContainer4.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/RAFContainer4.java?rev=1200995&r1=1200994&r2=1200995&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/RAFContainer4.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/RAFContainer4.java
Fri Nov 11 17:52:16 2011
@@ -324,7 +324,7 @@ class RAFContainer4 extends RAFContainer
             synchronized (channelCleanupMonitor) {
 
                 // Gain entry
-                int retries = MAX_INTERRUPT_RETRIES;
+                int retries = InterruptStatus.MAX_INTERRUPT_RETRIES;
 
                 while (restoreChannelInProgress) {
                     if (retries-- == 0) {
@@ -333,7 +333,8 @@ class RAFContainer4 extends RAFContainer
                     }
 
                     try {
-                        channelCleanupMonitor.wait(INTERRUPT_RETRY_SLEEP);
+                        channelCleanupMonitor.wait(
+                            InterruptStatus.INTERRUPT_RETRY_SLEEP);
                     } catch (InterruptedException e) {
                         InterruptStatus.setInterrupted();
                     }
@@ -346,7 +347,7 @@ class RAFContainer4 extends RAFContainer
 
 
         boolean success = false;
-        int retries = MAX_INTERRUPT_RETRIES;
+        int retries = InterruptStatus.MAX_INTERRUPT_RETRIES;
 
       try {
         while (!success) {
@@ -498,7 +499,7 @@ class RAFContainer4 extends RAFContainer
             synchronized (channelCleanupMonitor) {
 
                 // Gain entry
-                int retries = MAX_INTERRUPT_RETRIES;
+                int retries = InterruptStatus.MAX_INTERRUPT_RETRIES;
 
                 while (restoreChannelInProgress) {
                     if (retries-- == 0) {
@@ -507,7 +508,8 @@ class RAFContainer4 extends RAFContainer
                     }
 
                     try {
-                        channelCleanupMonitor.wait(INTERRUPT_RETRY_SLEEP);
+                        channelCleanupMonitor.wait(
+                            InterruptStatus.INTERRUPT_RETRY_SLEEP);
                     } catch (InterruptedException e) {
                         InterruptStatus.setInterrupted();
                     }
@@ -519,7 +521,7 @@ class RAFContainer4 extends RAFContainer
         }
 
         boolean success = false;
-        int retries = MAX_INTERRUPT_RETRIES;
+        int retries = InterruptStatus.MAX_INTERRUPT_RETRIES;
 
       try {
         while (!success) {
@@ -648,7 +650,8 @@ class RAFContainer4 extends RAFContainer
      * <p/>
      * If {@code stealthMode == false}, maximum wait time for the container to
      * become available again is determined by the product {@code
-     * FileContainer#MAX_INTERRUPT_RETRIES * FileContainer#INTERRUPT_RETRY_SLEEP}.
+     * InterruptStatus.MAX_INTERRUPT_RETRIES *
+     * InterruptStatus.INTERRUPT_RETRY_SLEEP}.
      * There is a chance this thread will not see any recovery occuring (yet),
      * in which case it waits for a bit and just returns, so the caller must
      * retry IO until success.
@@ -721,7 +724,7 @@ class RAFContainer4 extends RAFContainer
                             "already waited " + timesWaited + " times");
                     }
 
-                    if (timesWaited > MAX_INTERRUPT_RETRIES) {
+                    if (timesWaited > InterruptStatus.MAX_INTERRUPT_RETRIES) {
                         // Max, give up, probably way too long anyway,
                         // but doesn't hurt?
                         throw StandardException.newException(
@@ -729,7 +732,8 @@ class RAFContainer4 extends RAFContainer
                     }
 
                     try {
-                        channelCleanupMonitor.wait(INTERRUPT_RETRY_SLEEP);
+                        channelCleanupMonitor.wait(
+                            InterruptStatus.INTERRUPT_RETRY_SLEEP);
                     } catch (InterruptedException we) {
                         InterruptStatus.setInterrupted();
                     }
@@ -763,7 +767,7 @@ class RAFContainer4 extends RAFContainer
             // have raced past the interrupted thread, so let's wait a
             // bit before we attempt a new I/O.
             try {
-                Thread.sleep(INTERRUPT_RETRY_SLEEP);
+                Thread.sleep(InterruptStatus.INTERRUPT_RETRY_SLEEP);
             } catch (InterruptedException we) {
                 // This thread is getting hit, too..
                 InterruptStatus.setInterrupted();
@@ -849,7 +853,7 @@ class RAFContainer4 extends RAFContainer
         // Wait till other concurrent threads hit the wall
         // (ClosedChannelException) and are a ready waiting for us to clean up,
         // so we can set them loose when we're done.
-        int retries = MAX_INTERRUPT_RETRIES;
+        int retries = InterruptStatus.MAX_INTERRUPT_RETRIES;
 
         while (true) {
             synchronized (channelCleanupMonitor) {
@@ -870,7 +874,7 @@ class RAFContainer4 extends RAFContainer
             }
 
             try {
-                Thread.sleep(INTERRUPT_RETRY_SLEEP);
+                Thread.sleep(InterruptStatus.INTERRUPT_RETRY_SLEEP);
             } catch (InterruptedException te) {
                 InterruptStatus.setInterrupted();
             }



Mime
View raw message