[Mulgara-svn] r1097 - branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver

ronald at mulgara.org ronald at mulgara.org
Fri Jul 18 13:51:22 UTC 2008


Author: ronald
Date: 2008-07-18 06:51:21 -0700 (Fri, 18 Jul 2008)
New Revision: 1097

Modified:
   branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/AdvDatabaseSessionUnitTest.java
   branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java
Log:
Only close the active transaction-factory on close().

This fixes bug that could cause close() release the write-lock even though
it's still in use. This could happen on internal transactions because the
external transaction-factory was being closed first, and because the factory
mutex is on a per-factory it would not block and wait for the mutex held by
an active operation using an internal transaction.

This problem could only happen if the application was closing a session while
it is still active, meaning if it was using the session in two threads
simultaneously, which is not allowed.


Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/AdvDatabaseSessionUnitTest.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/AdvDatabaseSessionUnitTest.java	2008-07-18 13:51:17 UTC (rev 1096)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/AdvDatabaseSessionUnitTest.java	2008-07-18 13:51:21 UTC (rev 1097)
@@ -1601,6 +1601,52 @@
     } catch (Exception e) {
       fail(e);
     }
+
+    // test close while operation active in auto-commit
+    try {
+      final Session session1 = database.newSession();
+      final URI delayTwoSecs = new URI("foo://mulgara/closeTest?active=l&hardWait=1000");
+      session1.createModel(delayTwoSecs, new URI(Mulgara.NAMESPACE + "MockModel"));
+
+      final boolean[] closing = new boolean[1];
+
+      try {
+        Thread t1 = new Thread("closeTest") {
+          public void run() {
+            try {
+              Answer answer = session1.query(createQuery(delayTwoSecs));
+              answer.close();
+              synchronized (closing) {
+                assertTrue("close didn't block", closing[0]);
+              }
+            } catch (Exception e) {
+              fail(e);
+            }
+          }
+        };
+        t1.start();
+        Thread.sleep(100L);     // give thread some time to start and block
+
+        assertTrue("query should still be active", t1.isAlive());
+
+        synchronized (closing) { closing[0] = true; }
+        session1.close();
+        synchronized (closing) { closing[0] = false; }
+
+        try {
+          t1.join(100L);
+        } catch (InterruptedException ie) {
+          logger.error("wait for thread-termination interrupted", ie);
+          fail(ie);
+        }
+        assertFalse("second session should've terminated", t1.isAlive());
+
+      } finally {
+        session1.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
   }
 
   //

Modified: branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java
===================================================================
--- branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java	2008-07-18 13:51:17 UTC (rev 1096)
+++ branches/mgr-121-lockrecovery/src/jar/resolver/java/org/mulgara/resolver/DatabaseSession.java	2008-07-18 13:51:21 UTC (rev 1097)
@@ -573,24 +573,17 @@
   public void close() throws QueryException {
     logger.debug("Closing session");
     try {
-      transactionFactory = null;
-      externalFactory.closingSession();
+      if (transactionFactory != null)
+        transactionFactory.closingSession();
     } catch (MulgaraTransactionException em) {
       logger.error("Error force-closing session", em);
       throw new QueryException("Error force-closing session.", em);
     } finally {
       try {
-        internalFactory.closingSession();
+        transactionManager.closingSession(this);
       } catch (MulgaraTransactionException em2) {
         logger.error("Error force-closing session", em2);
         throw new QueryException("Error force-closing session.", em2);
-      } finally {
-        try {
-          transactionManager.closingSession(this);
-        } catch (MulgaraTransactionException em2) {
-          logger.error("Error force-closing session", em2);
-          throw new QueryException("Error force-closing session.", em2);
-        }
       }
     }
   }




More information about the Mulgara-svn mailing list