You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by pe...@apache.org on 2013/12/08 00:26:46 UTC
svn commit: r1548978 - in /river/jtsk/skunk/qa_refactor/trunk/src:
com/sun/jini/fiddler/ com/sun/jini/mercury/ com/sun/jini/norm/
com/sun/jini/reggie/ com/sun/jini/start/ com/sun/jini/thread/
net/jini/loader/pref/ org/apache/river/api/net/
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
*/