Author: peter_firmstone
Date: Sat Dec  7 23:26:45 2013
New Revision: 1548978

URL: http://svn.apache.org/r1548978
Log:
The existing implementation of ReadersWriter ensures exclusivity for writing 
threads,but makes no visibility guarantees for writes, as evidenced by test 
failures on Windows Server 2008 Jdk1.7.0_25:

Running 
com/sun/jini/test/spec/lookupservice/test_set00/MultipleEvntLeaseRenewals.td

=============================== CALLING RUN() ===============================

net.jini.core.lease.UnknownLeaseException: No event recorded for ID: 0
        at com.sun.jini.reggie.RegistrarImpl.checkEvent(RegistrarImpl.java:5471)
        at 
com.sun.jini.reggie.RegistrarImpl.renewEventLeaseInt(RegistrarImpl.java:5566)
        at 
com.sun.jini.reggie.RegistrarImpl.renewEventLeaseDo(RegistrarImpl.java:5549)
        at 
com.sun.jini.reggie.RegistrarImpl.renewEventLease(RegistrarImpl.java:3268)
        at 
com.sun.jini.reggie.TransientRegistrarImpl.renewEventLease(TransientRegistrarImpl.java:29)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at 
net.jini.jeri.BasicInvocationDispatcher.invoke(BasicInvocationDispatcher.java:1134)
        at 
net.jini.jeri.BasicInvocationDispatcher.dispatch(BasicInvocationDispatcher.java:610)
        at com.sun.jini.jeri.internal.runtime.Target$2.run(Target.java:493)
        at 
net.jini.export.ServerContext.doWithServerContext(ServerContext.java:108)
        at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:490)
        at com.sun.jini.jeri.internal.runtime.Target.access$000(Target.java:57)
        at com.sun.jini.jeri.internal.runtime.Target$1.run(Target.java:466)
        at 
com.sun.jini.start.AggregatePolicyProvider$AggregateSecurityContext$2.run(AggregatePolicyProvider.java:593)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:463)
        at com.sun.jini.jeri.internal.runtime.Target.dispatch(Target.java:428)
        at 
com.sun.jini.jeri.internal.runtime.DgcRequestDispatcher.dispatch(DgcRequestDispatcher.java:210)
        at 
net.jini.jeri.connection.ServerConnectionManager$Dispatcher.dispatch(ServerConnectionManager.java:147)
        at com.sun.jini.jeri.internal.mux.MuxServer$1$1.run(MuxServer.java:244)
        at 
com.sun.jini.start.AggregatePolicyProvider$AggregateSecurityContext$1.run(AggregatePolicyProvider.java:579)
        at java.security.AccessController.doPrivileged(Native Method)
        at com.sun.jini.jeri.internal.mux.MuxServer$1.run(MuxServer.java:241)
        at com.sun.jini.thread.ThreadPool$Task.run(ThreadPool.java:187)
        at com.sun.jini.thread.ThreadPool$Worker.run(ThreadPool.java:226)
        at java.lang.Thread.run(Thread.java:722)
        at 
com.sun.jini.jeri.internal.runtime.Util.__________EXCEPTION_RECEIVED_FROM_SERVER__________(Util.java:108)
        at 
com.sun.jini.jeri.internal.runtime.Util.exceptionReceivedFromServer(Util.java:101)
        at 
net.jini.jeri.BasicInvocationHandler.unmarshalThrow(BasicInvocationHandler.java:1303)
        at 
net.jini.jeri.BasicInvocationHandler.invokeRemoteMethodOnce(BasicInvocationHandler.java:832)
        at 
net.jini.jeri.BasicInvocationHandler.invokeRemoteMethod(BasicInvocationHandler.java:659)
        at 
net.jini.jeri.BasicInvocationHandler.invoke(BasicInvocationHandler.java:528)
        at com.sun.jini.reggie.$Proxy0.renewEventLease(Unknown Source)
        at com.sun.jini.reggie.EventLease.doRenew(EventLease.java:98)
        at com.sun.jini.lease.AbstractLease.renew(AbstractLease.java:83)
        at 
com.sun.jini.test.spec.lookupservice.QATestUtils.doRenewLease(QATestUtils.java:681)
        at 
com.sun.jini.test.spec.lookupservice.test_set00.MultipleEvntLeaseRenewals.run(MultipleEvntLeaseRenewals.java:193)
        at com.sun.jini.qa.harness.MasterTest.doTest(MasterTest.java:256)
        at com.sun.jini.qa.harness.MasterTest.main(MasterTest.java:144)

TIME: 11:05:11 AM

MasterTest.doTest INFO: 
============================ CALLING TEARDOWN() =============================

Removed:
    
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/thread/ReadersPriorityWriter.java
Modified:
    river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/fiddler/FiddlerImpl.java
    river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/MailboxImpl.java
    
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/PersistentStore.java
    
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/reggie/RegistrarImpl.java
    
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/start/AggregatePolicyProvider.java
    
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/thread/ReadersWriter.java
    
river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredClassProvider.java
    
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/net/RFC3986URLClassLoader.java

Modified: 
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/fiddler/FiddlerImpl.java
URL: 
http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/fiddler/FiddlerImpl.java?rev=1548978&r1=1548977&r2=1548978&view=diff
==============================================================================
--- 
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/fiddler/FiddlerImpl.java 
(original)
+++ 
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/fiddler/FiddlerImpl.java 
Sat Dec  7 23:26:45 2013
@@ -37,7 +37,6 @@ import com.sun.jini.start.LifeCycle;
 import org.apache.river.api.util.Commission;
 
 import com.sun.jini.thread.InterruptedStatusThread;
-import com.sun.jini.thread.ReadersPriorityWriter;
 import com.sun.jini.thread.ReadersWriter;
 import com.sun.jini.thread.ReadersWriter.ConcurrentLockException;
 import com.sun.jini.thread.ReadyState;
@@ -280,7 +279,7 @@ class FiddlerImpl implements ServerProxy
     private final SnapshotThread snapshotThread;
 
     /** Concurrent object to control read and write access */
-    private final ReadersWriter concurrentObj = new ReadersPriorityWriter();
+    private final ReadersWriter concurrentObj = new ReadersWriter();
     /** Object for synchronizing with the registration expire thread */
     private final Object leaseExpireThreadSyncObj = new Object();
     /** Object on which the snapshot-taking thread will synchronize */

Modified: 
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/MailboxImpl.java
URL: 
http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/MailboxImpl.java?rev=1548978&r1=1548977&r2=1548978&view=diff
==============================================================================
--- 
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/MailboxImpl.java 
(original)
+++ 
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/MailboxImpl.java 
Sat Dec  7 23:26:45 2013
@@ -39,7 +39,6 @@ import com.sun.jini.reliableLog.LogHandl
 import com.sun.jini.start.LifeCycle;
 import org.apache.river.api.util.Commission;
 import com.sun.jini.thread.InterruptedStatusThread;
-import com.sun.jini.thread.ReadersPriorityWriter;
 import com.sun.jini.thread.ReadersWriter;
 import com.sun.jini.thread.ReadersWriter.ConcurrentLockException;
 import com.sun.jini.thread.ReadyState;
@@ -274,7 +273,7 @@ class MailboxImpl implements MailboxBack
     /** The admin proxy of this server */
     private /*final*/ volatile MailboxAdminProxy mailboxAdminProxy;
     /** Concurrent object (lock) to control read and write access */
-    private final ReadersWriter concurrentObj = new ReadersPriorityWriter();
+    private final ReadersWriter concurrentObj = new ReadersWriter();
     /** Map from <code>Uuid</code> to <code>ServiceRegistration</code> */
     // HashMap is unsynchronized, but we are performing external
     // synchronization via the <code>concurrentObj</code> field. 

Modified: 
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/PersistentStore.java
URL: 
http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/PersistentStore.java?rev=1548978&r1=1548977&r2=1548978&view=diff
==============================================================================
--- 
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/PersistentStore.java 
(original)
+++ 
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/PersistentStore.java 
Sat Dec  7 23:26:45 2013
@@ -31,7 +31,6 @@ import com.sun.jini.norm.lookup.SubStore
 import com.sun.jini.reliableLog.LogHandler;
 import com.sun.jini.reliableLog.ReliableLog;
 import com.sun.jini.system.FileSystem;
-import com.sun.jini.thread.ReadersPriorityWriter;
 import com.sun.jini.thread.ReadersWriter;
 
 /**
@@ -58,7 +57,7 @@ class PersistentStore {
      * snapshot thread the writer since for us mutation is the
      * non-exclusive operation.
      */
-    final private ReadersWriter mutatorLock = new ReadersPriorityWriter();
+    final private ReadersWriter mutatorLock = new ReadersWriter();
 
     /**
      * Thread local that tracks if (and how many times) the current thread

Modified: 
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/reggie/RegistrarImpl.java
URL: 
http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/reggie/RegistrarImpl.java?rev=1548978&r1=1548977&r2=1548978&view=diff
==============================================================================
--- 
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/reggie/RegistrarImpl.java 
(original)
+++ 
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/reggie/RegistrarImpl.java 
Sat Dec  7 23:26:45 2013
@@ -35,7 +35,6 @@ import com.sun.jini.reliableLog.LogHandl
 import com.sun.jini.reliableLog.ReliableLog;
 import com.sun.jini.start.LifeCycle;
 import com.sun.jini.thread.InterruptedStatusThread;
-import com.sun.jini.thread.ReadersPriorityWriter;
 import com.sun.jini.thread.ReadersWriter;
 import com.sun.jini.thread.ReadersWriter.ConcurrentLockException;
 import com.sun.jini.thread.ReadyState;
@@ -312,7 +311,7 @@ class RegistrarImpl implements Registrar
     private final Thread snapshotter;
 
     /** Concurrent object to control read and write access */
-    private final ReadersWriter concurrentObj = new ReadersPriorityWriter();
+    private final ReadersWriter concurrentObj = new ReadersWriter();
     /** Object for synchronizing with the service expire thread */
     private final Object serviceNotifier = new Object();
     /** Object for synchronizing with the event expire thread */

Modified: 
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/start/AggregatePolicyProvider.java
URL: 
http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/start/AggregatePolicyProvider.java?rev=1548978&r1=1548977&r2=1548978&view=diff
==============================================================================
--- 
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/start/AggregatePolicyProvider.java
 (original)
+++ 
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/start/AggregatePolicyProvider.java
 Sat Dec  7 23:26:45 2013
@@ -110,7 +110,7 @@ public class AggregatePolicyProvider 
     private final ConcurrentMap<ClassLoader,Policy> 
subPolicyChildClassLoaderCache =
             RC.concurrentMap(
             new ConcurrentHashMap<Referrer<ClassLoader>,Referrer<Policy>>(),
-            Ref.WEAK_IDENTITY, Ref.STRONG, 1000L, 0L);
+            Ref.WEAK_IDENTITY, Ref.STRONG, 10000L, 0L);
     private final ReadWriteLock rwl = new ReentrantReadWriteLock();
     private final Lock lock = rwl.writeLock();
     private final Lock readLock = rwl.readLock(); // stop access to 
subPolicyChildClassLoaderCache while write in progress.

Modified: 
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/thread/ReadersWriter.java
URL: 
http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/thread/ReadersWriter.java?rev=1548978&r1=1548977&r2=1548978&view=diff
==============================================================================
--- 
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/thread/ReadersWriter.java 
(original)
+++ 
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/thread/ReadersWriter.java 
Sat Dec  7 23:26:45 2013
@@ -17,92 +17,102 @@
  */
 package com.sun.jini.thread;
 
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
 /**
  * An Object to control the concurrent state.  Allows multiple readers or
- * a single writer.  Waiting writers have priority over new readers.
- * Waiting priority writers have priority over waiting regular writers.
+ * a single writer.
+ * Waiting priority writers have priority over waiting regular writers and 
+ * waiting readers.
  * A single thread cannot hold a lock more than once.
  *
  * @author Sun Microsystems, Inc.
  *
  */
 public class ReadersWriter {
-    /** The number of active readers */
-    private int activeReaders = 0;
-    /** The number of waiting writers (both regular and priority) */
-    private int waitingWriters = 0;
-    /** The number of waiting priority writers */
-    private int waitingPriorityWriters = 0;
-    /** True if there is an active writer */
-    private boolean activeWriter = false;
-
-    public ReadersWriter() {}
+    private int waitingWriters;
+    private final AtomicInteger waitingPriorityWriters;
+    private final ReadWriteLock lock;
+    private final Lock readLock;
+    private final Lock writeLock;
+    private final Condition waitingPriorityWriter;
+    private final Condition waitingWriter;
+
+    public ReadersWriter() {
+        super();
+        lock = new ReentrantReadWriteLock();
+        readLock = lock.readLock();
+        writeLock = lock.writeLock();
+        waitingPriorityWriter = writeLock.newCondition();
+        waitingWriter = writeLock.newCondition();
+        waitingWriters = 0;
+        waitingPriorityWriters = new AtomicInteger();
+    }
 
     /** Obtain a read lock.  Multiple concurrent readers allowed. */
-    public synchronized void readLock() {
-       while (activeWriter || waitingWriters != 0) {
-           try {
-               wait();
-           } catch (InterruptedException e) {
-               throw new ConcurrentLockException(
-                                      "read lock interrupted in thread");
-           }
-       }
-       activeReaders++;
+    public void readLock() {
+       // Stop new readers from obtaining read lock if priority writer
+        // is waiting for current readers to finish.  Prevents writer lock 
+        // starvation.
+        while (waitingPriorityWriters.get() > 0){
+            try {
+                Thread.sleep(50L);
+            } catch (InterruptedException ex) {
+                // reestablish interrupted status.
+                Thread.currentThread().interrupt();
+            }
+        }
+        readLock.lock();
     }
 
     /** Release a read lock. */
-    public synchronized void readUnlock() {
-       activeReaders--;
-       if (activeReaders == 0)
-           notifyAll();
+    public void readUnlock() {
+       readLock.unlock();
     }
 
     /** Obtain a regular write lock.  Only a single writer allowed at once. */
-    public synchronized void writeLock() {
-       while (activeWriter ||
-              activeReaders != 0 ||
-              waitingPriorityWriters != 0)
-       {
-           try {
-               waitingWriters++;
-               try {
-                   wait();
-               } finally {
-                   waitingWriters--;
-               }
-           } catch (InterruptedException e) {
-               throw new ConcurrentLockException(
-                                     "write lock interrupted in thread");
-           }
-       }
-       activeWriter = true;
+    public void writeLock() {
+       writeLock.lock();
+        while (waitingPriorityWriters.get() > 0)
+        {
+            try {
+                waitingWriters++;
+                try {
+                    waitingPriorityWriter.signal();
+                    waitingWriter.await();
+                } finally {
+                    waitingWriters--;
+                }
+            } catch (InterruptedException e) {
+                throw new ConcurrentLockException(
+                                      "write lock interrupted in thread");
+            }
+        }
     }
 
     /** Obtain a priority write lock.  Only a single writer allowed at once. */
-    public synchronized void priorityWriteLock() {
-       while (activeWriter || activeReaders != 0) {
-           try {
-               waitingWriters++;
-               waitingPriorityWriters++;
-               try {
-                   wait();
-               } finally {
-                   waitingWriters--;
-                   waitingPriorityWriters--;
-               }
-           } catch (InterruptedException e) {
-               throw new ConcurrentLockException(
-                                     "write lock interrupted in thread");
-           }
-       }
-       activeWriter = true;
+    public void priorityWriteLock() {
+       waitingPriorityWriters.getAndIncrement();
+        try {
+            writeLock.lock();
+        } finally {
+            waitingPriorityWriters.getAndDecrement();
+        }
     }
 
     /** Release a (regular or priority) write lock. */
-    public synchronized void writeUnlock() {
-       activeWriter = false;
-       notifyAll();
+    public void writeUnlock() {
+       // should be in a locked state or an exception will be thrown.
+        try {
+            if (waitingPriorityWriters.get() > 0) 
waitingPriorityWriter.signal();
+            else if (waitingWriters > 0) waitingWriter.signal();
+        } finally {
+            writeLock.unlock();
+        }
     }
 
     /**

Modified: 
river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredClassProvider.java
URL: 
http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredClassProvider.java?rev=1548978&r1=1548977&r2=1548978&view=diff
==============================================================================
--- 
river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredClassProvider.java
 (original)
+++ 
river/jtsk/skunk/qa_refactor/trunk/src/net/jini/loader/pref/PreferredClassProvider.java
 Sat Dec  7 23:26:45 2013
@@ -299,7 +299,7 @@ public class PreferredClassProvider exte
     private static final Set<ClassLoader> localLoaders;
     static {
         Set<Referrer<ClassLoader>> internal = Collections.newSetFromMap(new 
ConcurrentHashMap<Referrer<ClassLoader>,Boolean>());
-        localLoaders = RC.set(internal, Ref.WEAK_IDENTITY, 100L);
+        localLoaders = RC.set(internal, Ref.WEAK_IDENTITY, 10000L);
        AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
            public ClassLoader run() {
                for (ClassLoader loader = ClassLoader.getSystemClassLoader();
@@ -393,7 +393,7 @@ public class PreferredClassProvider exte
        this.requireDlPerm = requireDlPerm;
         ConcurrentMap<Referrer<ClassLoader>,Referrer<PermissionCollection>> 
inter =
                 new 
ConcurrentHashMap<Referrer<ClassLoader>,Referrer<PermissionCollection>>();
-        classLoaderPerms = RC.concurrentMap(inter, Ref.WEAK_IDENTITY, 
Ref.STRONG, 200L, 200L);
+        classLoaderPerms = RC.concurrentMap(inter, Ref.WEAK_IDENTITY, 
Ref.STRONG, 5000L, 5000L);
        initialized = true;
     }
 

Modified: 
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/net/RFC3986URLClassLoader.java
URL: 
http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/net/RFC3986URLClassLoader.java?rev=1548978&r1=1548977&r2=1548978&view=diff
==============================================================================
--- 
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/net/RFC3986URLClassLoader.java
 (original)
+++ 
river/jtsk/skunk/qa_refactor/trunk/src/org/apache/river/api/net/RFC3986URLClassLoader.java
 Sat Dec  7 23:26:45 2013
@@ -1085,6 +1085,11 @@ public class RFC3986URLClassLoader exten
      * Returns an URL that will be checked if it contains the class or 
resource.
      * If the file component of the URL is not a directory, a Jar URL will be
      * created.
+     * 
+     * We need to modify this implementation to allow URLStreamHandlerFactory's
+     * to use custom caching, such as the per ClassLoader caching used by
+     * Apache Geronimo.  This would be very useful as it allows services
+     * to upgrade themselves by reloading and replacing their proxy's.
      *
      * @return java.net.URL a test URL
      */


Reply via email to