Author: hlship
Date: Mon Apr 24 16:11:48 2006
New Revision: 396714
URL: http://svn.apache.org/viewcvs?rev=396714&view=rev
Log:
Refactor annotations ReadLock and WriteLock into Synchronization.Read and
Synchronization.Write.
Added:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/Synchronized.java
Removed:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/ReadLock.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/WriteLock.java
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/InternalSynchronization.aj
tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/Synchronization.aj
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ClassTransformerImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/transform/ClassTransformation.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/CollectionFactory.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationAspectTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationTarget.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/util/CollectionFactoryTest.java
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/InternalSynchronization.aj
URL:
http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/InternalSynchronization.aj?rev=396714&r1=396713&r2=396714&view=diff
==============================================================================
---
tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/InternalSynchronization.aj
(original)
+++
tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/InternalSynchronization.aj
Mon Apr 24 16:11:48 2006
@@ -10,5 +10,5 @@
* the ReadLock or WriteLock annotations.
*/
pointcut targetClasses() :
- within(xxx.org.apache.tapestry.internal.aspects..*);
+ within(org.apache.tapestry.internal..*);
}
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/Synchronization.aj
URL:
http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/Synchronization.aj?rev=396714&r1=396713&r2=396714&view=diff
==============================================================================
---
tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/Synchronization.aj
(original)
+++
tapestry/tapestry5/tapestry-core/trunk/src/main/aspect/org/apache/tapestry/internal/aspects/Synchronization.aj
Mon Apr 24 16:11:48 2006
@@ -3,17 +3,17 @@
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
-import org.apache.tapestry.internal.annotations.ReadLock;
-import org.apache.tapestry.internal.annotations.WriteLock;
+import org.apache.tapestry.internal.annotations.Synchronized;
/**
* Manages multi-threaded access to methods of an object instance using a
- * [EMAIL PROTECTED] java.util.concurrent.locks.ReadWriteLock}, driven by the
[EMAIL PROTECTED] ReadLock} and
- * [EMAIL PROTECTED] WriteLock} annotations. Methods that have the ReadLock
annotation witll be advised to
- * obtain and release the read lock around their execution. Methods with the
WriteLock annotation
- * will obtain and release the write lock around their execution. Methods with
ReadLock that call a
- * WriteLock-ed method (within the same instance) will release the read lock
before invoking the
- * WriteLock-ed method.
+ * [EMAIL PROTECTED] java.util.concurrent.locks.ReentrantReadWriteLock},
driven by the
+ * [EMAIL PROTECTED] Synchronized.Read} and [EMAIL PROTECTED]
Synchronized.Write} annotations. Methods that have the
+ * Synchronized.Read annotation witll be advised to obtain and release the
read lock around their
+ * execution. Methods with the Synchronized.Write annotation will obtain and
release the write lock
+ * around their execution. Methods with Synchronized.Read that call a
Synchronized.Write-ed method
+ * (within the same instance) will release the read lock before invoking the
Synchronized.Write-ed
+ * method.
* <p>
* This aspect also enforces that the annotations are only applied to instance
(not static) methods,
* and that a method may be either read or write, but not both.
@@ -21,36 +21,46 @@
* TODO: read-into-write not yet implemented!
*
* @author Howard M. Lewis Ship
+ * @see org.apache.tapestry.internal.annotations.Synchronized
*/
public abstract aspect Synchronization extends AbstractClassTargetting
-perthis(readLockMethods() || writeLockMethods())
+perthis(annotatedClasses())
{
private final ReadWriteLock _lock = new ReentrantReadWriteLock();
+ pointcut annotatedClasses() :
+ targetClasses() && within(@Synchronized *);
+
+ declare error :
+ targetClasses() &&
+ execution(@(Synchronized.Read || Synchronized.Write) static * *(..)) :
+ "Synchronized.Read and Synchronized.Write annotations may only be
applied to instance methods.";
+
declare error :
targetClasses() &&
- execution(@(ReadLock || WriteLock) static * *(..)) :
- "ReadLock and WriteLock annotations may only be applied to
instance methods.";
+ execution(@(Synchronized.Read || Synchronized.Write) * *(..)) &&
+ within(!@(Synchronized) Object+) :
+ "The class must be annotated with Synchronized in order to use the
Synchronized.Read or Synchronized.Write annotations.";
declare error :
targetClasses() &&
- execution(@ReadLock @WriteLock * *(..)) :
- "A method may be annotated with ReadLock or with WriteLock but not
both.";
+ execution(@Synchronized.Read @Synchronized.Write * *(..)) :
+ "A method may be annotated with Synchronized.Read or with
Synchronized.Write but not both.";
- pointcut readLockMethods() :
- execution(@ReadLock * *(..)) && targetClasses();
+ pointcut readMethods() :
+ execution(@Synchronized.Read * *(..)) && annotatedClasses();
- pointcut writeLockMethods() :
- execution(@WriteLock * *(..)) && targetClasses();
+ pointcut writeMethods() :
+ execution(@Synchronized.Write * *(..)) && annotatedClasses();
/** Before read lock methods, acquire the read lock. */
- before() : readLockMethods()
+ before() : readMethods()
{
_lock.readLock().lock();
}
/** After read lock methods (including thrown exceptions), release the
read lock. */
- after() : readLockMethods()
+ after() : readMethods()
{
_lock.readLock().unlock();
}
@@ -61,13 +71,13 @@
* case.
*/
- before(): writeLockMethods()
+ before(): writeMethods()
{
_lock.writeLock().lock();
}
/** And release the write lock after the method completes (successfully,
or with an exception). */
- after() : writeLockMethods()
+ after() : writeMethods()
{
_lock.writeLock().unlock();
}
Added:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/Synchronized.java
URL:
http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/Synchronized.java?rev=396714&view=auto
==============================================================================
---
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/Synchronized.java
(added)
+++
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/annotations/Synchronized.java
Mon Apr 24 16:11:48 2006
@@ -0,0 +1,60 @@
+package org.apache.tapestry.internal.annotations;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * Marker interface for classes whose methods may be annotated with
Synchronized.Read or
+ * Synchronized.Write. It is the path of least AspectJ resistance to get
things working as they
+ * should.
+ *
+ * @author Howard M. Lewis Ship
+ */
[EMAIL PROTECTED](TYPE)
[EMAIL PROTECTED](RUNTIME)
[EMAIL PROTECTED]
[EMAIL PROTECTED]
+public @interface Synchronized {
+
+ /**
+ * Marker on methods that perform a read operation. A non-exclusive read
lock will be acquired
+ * before the method executes, and will be released after the method
completes (succesfully or
+ * otherwise).
+ * <p>
+ * This annotation may only be applied to methods within Synchronized
types. It may only be
+ * applied to instance, not static methods. It may not be used in
combination with the
+ * Synchronized.Write annotation.
+ */
+ @Target(METHOD)
+ @Retention(RUNTIME)
+ @Documented
+ public @interface Read {
+
+ }
+
+ /**
+ * Marker on methods that perform a write operation. An exclusive write
lock will be acquired
+ * before the method executes, and will be released after the method
completes (succesfully or
+ * otherwise).
+ * <p>
+ * This annotation may only be applied to methods within Synchronized
types. It may only be
+ * applied to instance, not static methods. It may not be used in
combination with the
+ * Synchronized.Write annotation.
+ * <p>
+ * TODO: To acquire the write lock, one must give up one's read lock (if
any). This is not
+ * supported yet, so invoking a Synchronized.Write method (even
indirectly) from a
+ * Synchronized.Read method will hang the thread.
+ */
+ @Target(METHOD)
+ @Retention(RUNTIME)
+ @Documented
+ public @interface Write {
+
+ }
+}
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ClassTransformerImpl.java
URL:
http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ClassTransformerImpl.java?rev=396714&r1=396713&r2=396714&view=diff
==============================================================================
---
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ClassTransformerImpl.java
(original)
+++
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ClassTransformerImpl.java
Mon Apr 24 16:11:48 2006
@@ -19,6 +19,7 @@
import javassist.CtClass;
import org.apache.tapestry.annotations.ComponentClass;
+import org.apache.tapestry.internal.annotations.Synchronized;
import org.apache.tapestry.internal.model.MutableComponentModelImpl;
import org.apache.tapestry.model.MutableComponentModel;
import org.apache.tapestry.transform.ClassTransformWorker;
@@ -30,6 +31,7 @@
*
* @author Howard M. Lewis Ship
*/
[EMAIL PROTECTED]
public class ClassTransformerImpl implements ClassTransformer
{
/** Map from class name to class transformation. */
@@ -37,6 +39,7 @@
private ClassTransformWorker _workers;
+ @Synchronized.Write
public void transformClass(CtClass ctClass)
{
String classname = ctClass.getName();
@@ -61,6 +64,7 @@
_nameToClassTransformation.put(classname, transformation);
}
+ @Synchronized.Read
public Instantiator createInstantiator(Class componentClass)
{
String className = componentClass.getName();
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImpl.java
URL:
http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImpl.java?rev=396714&r1=396713&r2=396714&view=diff
==============================================================================
---
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImpl.java
(original)
+++
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/transform/ComponentInstantiatorSourceImpl.java
Mon Apr 24 16:11:48 2006
@@ -114,6 +114,7 @@
}
}
+ // This is called from well within a synchronized block.
public void onLoad(ClassPool pool, String classname) throws
NotFoundException,
CannotCompileException
{
@@ -218,7 +219,8 @@
return input.substring(0, lastdot);
}
- public void addPackage(String packageName)
+ // synchronized may be overkill, but that's ok.
+ public synchronized void addPackage(String packageName)
{
Defense.notBlank(packageName, "packageName");
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/transform/ClassTransformation.java
URL:
http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/transform/ClassTransformation.java?rev=396714&r1=396713&r2=396714&view=diff
==============================================================================
---
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/transform/ClassTransformation.java
(original)
+++
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/transform/ClassTransformation.java
Mon Apr 24 16:11:48 2006
@@ -29,6 +29,10 @@
* transformed. A number of <em>workers</em> will operate upon the
ClassTransformation to effect
* the desired changes before the true class is loaded into memory.
* <p>
+ * Instances of this class are not designed to be thread safe, access to an
instance should be
+ * restricted to a single thread. In fact, the design of this type is to allow
stateless singletons
+ * in multiple threads to work on thread-specific data (within the
ClassTransformation). *
+ * <p>
* The majority of methods concern the <em>declared</em> members (field and
methods) of a specific
* class, rather than any fields or methods inherited from a base class.
*
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/CollectionFactory.java
URL:
http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/CollectionFactory.java?rev=396714&r1=396713&r2=396714&view=diff
==============================================================================
---
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/CollectionFactory.java
(original)
+++
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/util/CollectionFactory.java
Mon Apr 24 16:11:48 2006
@@ -22,6 +22,8 @@
import java.util.Map;
import java.util.Set;
+import org.apache.tapestry.internal.annotations.Utility;
+
/**
* Static factory methods to ease the creation of new collection types (when
using generics). Most
* of these method leverage the compiler's ability to match generic types by
return value. Typical
@@ -40,14 +42,9 @@
*
* @author Howard M. Lewis Ship
*/
[EMAIL PROTECTED]
public final class CollectionFactory
{
-
- /** Prevent instantiation. */
- private CollectionFactory()
- {
- }
-
/** Constructs and returns a generic [EMAIL PROTECTED] HashMap} instance.
*/
public static <K, V> Map<K, V> newMap()
{
@@ -61,10 +58,10 @@
}
/**
- * Constructs a new [EMAIL PROTECTED] java.util.HashMap} instance from an
existing Map instance.
+ * Constructs a new [EMAIL PROTECTED] java.util.HashMap} instance by
copying an existing Map instance.
*/
- public static <K, V> Map<K, V> copyMap(Map<K, V> map)
+ public static <K, V> Map<K, V> newMap(Map<K, V> map)
{
return new HashMap<K, V>(map);
}
@@ -75,7 +72,7 @@
return new ArrayList<T>();
}
- /** Easy way to convert a list of like-typed values into a list. */
+ /** Easy way to convert an array of like-typed values into a list. */
public static <T> List<T> newList(T... values)
{
return Arrays.asList(values);
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationAspectTest.java
URL:
http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationAspectTest.java?rev=396714&r1=396713&r2=396714&view=diff
==============================================================================
---
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationAspectTest.java
(original)
+++
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationAspectTest.java
Mon Apr 24 16:11:48 2006
@@ -23,10 +23,13 @@
private static final int THREAD_COUNT = 1000;
+ private static final int THREAD_BLOCK_SIZE = 50;
+
@Test
public void incrementCounter() throws Exception
{
List<Thread> threads = newList();
+ List<Thread> running = newList();
for (int i = 0; i < THREAD_COUNT; i++)
{
@@ -44,15 +47,28 @@
});
threads.add(t);
+
+ if (threads.size() >= THREAD_BLOCK_SIZE)
+ startThreads(threads, running);
}
- for (Thread t : threads)
- t.start();
+ startThreads(threads, running);
- for (Thread t : threads)
+ for (Thread t : running)
t.join();
assertEquals(_target.getCounter(), THREAD_COUNT);
+ }
+
+ private void startThreads(List<Thread> threads, List<Thread> running)
+ {
+ for (Thread t : threads)
+ {
+ t.start();
+ running.add(t);
+ }
+
+ threads.clear();
}
}
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationTarget.java
URL:
http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationTarget.java?rev=396714&r1=396713&r2=396714&view=diff
==============================================================================
---
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationTarget.java
(original)
+++
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/aspects/SynchronizationTarget.java
Mon Apr 24 16:11:48 2006
@@ -1,26 +1,23 @@
package org.apache.tapestry.internal.aspects;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-import org.apache.tapestry.internal.annotations.ReadLock;
-import org.apache.tapestry.internal.annotations.WriteLock;
+import org.apache.tapestry.internal.annotations.Synchronized;
/**
* Class used to test the [EMAIL PROTECTED] Synchorization} aspect.
*
* @author Howard M. Lewis Ship
*/
[EMAIL PROTECTED]
public class SynchronizationTarget
{
- private final ReadWriteLock _lock = new ReentrantReadWriteLock();
+ // private final ReadWriteLock _lock = new ReentrantReadWriteLock();
private int _counter;
- @ReadLock
+ @Synchronized.Read
public int getCounter()
{
- _lock.readLock().lock();
+ // _lock.readLock().lock();
try
{
@@ -28,14 +25,14 @@
}
finally
{
- _lock.readLock().unlock();
+ // _lock.readLock().unlock();
}
}
- @WriteLock
+ @Synchronized.Write
public void incrementCounter()
{
- _lock.writeLock().lock();
+ // _lock.writeLock().lock();
try
{
@@ -43,25 +40,25 @@
}
finally
{
- _lock.writeLock().unlock();
+ // _lock.writeLock().unlock();
}
}
- @WriteLock
+ @Synchronized.Write
public void setCounter(int newValue)
{
- _lock.writeLock().lock();
+ // _lock.writeLock().lock();
try
{
_counter = newValue;
}
finally
{
- _lock.writeLock().unlock();
+ // _lock.writeLock().unlock();
}
}
- @ReadLock
+ @Synchronized.Write
public void incrementCounterHard()
{
setCounter(getCounter() + 1);
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/util/CollectionFactoryTest.java
URL:
http://svn.apache.org/viewcvs/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/util/CollectionFactoryTest.java?rev=396714&r1=396713&r2=396714&view=diff
==============================================================================
---
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/util/CollectionFactoryTest.java
(original)
+++
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/util/CollectionFactoryTest.java
Mon Apr 24 16:11:48 2006
@@ -52,7 +52,7 @@
map.put("this", CollectionFactoryTest.class);
- Map<String, Class> copy = CollectionFactory.copyMap(map);
+ Map<String, Class> copy = CollectionFactory.newMap(map);
assertEquals(copy, map);
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]