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 ka...@apache.org on 2008/04/11 11:44:38 UTC

svn commit: r647091 - /db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/RAFContainer4.java

Author: kahatlen
Date: Fri Apr 11 02:44:26 2008
New Revision: 647091

URL: http://svn.apache.org/viewvc?rev=647091&view=rev
Log:
DERBY-3347: ERROR XSDB3: Container information cannot change once written

On JVMs that support the NIO API, multiple threads may perform I/O
operations concurrently on the same data file. As long as these
operations go through the page cache, only a single thread performs
I/O on a single page at any given time. The data files can also be
accessed by the container cache, which accesses space that it borrows
on the first page in the file. Since these accesses don't go through
the page cache, a mechanism is needed to prevent concurrent access
that page.

This patch makes reading and writing of the first page in a file
synchronize on the container object. Since access to the borrowed
space on the first page also is synchronized on the container,
concurrent I/O on the first page is prevented. (On JVMs that don't
support the NIO API, all page accesses synchronize on the container.)

Modified:
    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/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=647091&r1=647090&r2=647091&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 Apr 11 02:44:26 2008
@@ -167,6 +167,25 @@
     protected void readPage(long pageNumber, byte[] pageData)
          throws IOException, StandardException
     {
+        // If this is the first alloc page, there may be another thread
+        // accessing the container information in the borrowed space on the
+        // same page. In that case, we synchronize the entire method call, just
+        // like RAFContainer.readPage() does, in order to avoid conflicts. For
+        // all other pages it is safe to skip the synchronization, since
+        // concurrent threads will access different pages and therefore don't
+        // interfere with each other.
+        if (pageNumber == FIRST_ALLOC_PAGE_NUMBER) {
+            synchronized (this) {
+                readPage0(pageNumber, pageData);
+            }
+        } else {
+            readPage0(pageNumber, pageData);
+        }
+    }
+
+    private void readPage0(long pageNumber, byte[] pageData)
+         throws IOException, StandardException
+    {
         FileChannel ioChannel;
         synchronized (this) {
             ioChannel = ourChannel;
@@ -231,6 +250,25 @@
      *  @exception IOException IO error accessing page
      */
     protected void writePage(long pageNumber, byte[] pageData, boolean syncPage)
+         throws IOException, StandardException
+    {
+        // If this is the first alloc page, there may be another thread
+        // accessing the container information in the borrowed space on the
+        // same page. In that case, we synchronize the entire method call, just
+        // like RAFContainer.writePage() does, in order to avoid conflicts. For
+        // all other pages it is safe to skip the synchronization, since
+        // concurrent threads will access different pages and therefore don't
+        // interfere with each other.
+        if (pageNumber == FIRST_ALLOC_PAGE_NUMBER) {
+            synchronized (this) {
+                writePage0(pageNumber, pageData, syncPage);
+            }
+        } else {
+            writePage0(pageNumber, pageData, syncPage);
+        }
+    }
+
+    private void writePage0(long pageNumber, byte[] pageData, boolean syncPage)
          throws IOException, StandardException
     {
         FileChannel ioChannel;