You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by ge...@apache.org on 2003/08/10 22:55:15 UTC

cvs commit: incubator-geronimo/modules/core/src/java/org/apache/geronimo/lock ConcurrentInstanceLock.java InstanceLock.java LockContext.java LockCounter.java LockDomain.java LockInterceptor.java LockReentranceException.java NoTxLockContext.java TxLockContext.java WriterPreferredInstanceLock.java WriterPreferredInstanceLock2.java WriterPreferredInstanceLock3.java

geirm       2003/08/10 13:55:15

  Added:       modules/core/src/java/org/apache/geronimo/lock
                        ConcurrentInstanceLock.java InstanceLock.java
                        LockContext.java LockCounter.java LockDomain.java
                        LockInterceptor.java LockReentranceException.java
                        NoTxLockContext.java TxLockContext.java
                        WriterPreferredInstanceLock.java
                        WriterPreferredInstanceLock2.java
                        WriterPreferredInstanceLock3.java
  Log:
  initial import
  
  Revision  Changes    Path
  1.1                  incubator-geronimo/modules/core/src/java/org/apache/geronimo/lock/ConcurrentInstanceLock.java
  
  Index: ConcurrentInstanceLock.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Geronimo" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Geronimo", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * ====================================================================
   */
  package org.apache.geronimo.lock;
  
  import java.util.HashSet;
  
  import EDU.oswego.cs.dl.util.concurrent.ReadWriteLock;
  import EDU.oswego.cs.dl.util.concurrent.WriterPreferenceReadWriteLock;
  
  /**
   * Implementation based on the use of the util.concurrent package from Doug Lea.
   *
   *
   * @version $Revision: 1.1 $ $Date: 2003/08/10 20:55:14 $
   */
  public class ConcurrentInstanceLock implements InstanceLock {
      private final ReadWriteLock lock;
      private Object writer;
      private final HashSet readers = new HashSet();;
  
      public ConcurrentInstanceLock() {
          this.lock = new WriterPreferenceReadWriteLock();
      }
  
      public void sharedLock(Object context) throws InterruptedException {
          lock.readLock().acquire();
          synchronized (this) {
              readers.add(context);
          }
      }
  
      public void exclusiveLock(Object context) throws InterruptedException {
          lock.writeLock().acquire();
          synchronized (this) {
              writer = context;
          }
      }
  
      public synchronized void release(Object context) {
          if (writer == context) {
              writer = null;
              lock.writeLock().release();
          } else {
              readers.remove(context);
              lock.readLock().release();
          }
      }
  
      public synchronized int getSharedCount() {
          return readers.size();
      }
  }
  
  
  
  1.1                  incubator-geronimo/modules/core/src/java/org/apache/geronimo/lock/InstanceLock.java
  
  Index: InstanceLock.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Geronimo" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Geronimo", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * ====================================================================
   */
  package org.apache.geronimo.lock;
  
  /**
   * Interface providing a pessimistic lock mechanism to an instance of a
   * resource. Access is controlled by shared and exclusive locks; multiple
   * contexts can hold a shared lock at the same time, but only one may hold
   * an exclusive lock at any time. Lock allocation policy is determined by the
   * implementation and may or may not be fair.
   *
   *
   * @version $Revision: 1.1 $ $Date: 2003/08/10 20:55:14 $
   */
  public interface InstanceLock {
      /**
       * Provide context with shared access to this resource.
       * @param context the context requesting access
       * @throws java.lang.InterruptedException if the thread is interrupted before receiving the lock
       */
      public void sharedLock(Object context) throws InterruptedException;
  
      /**
       * Provide context with exclusive access to this resource.
       * @param context the context requesting access
       * @throws java.lang.InterruptedException if the thread is interrupted before receiving the lock
       */
      public void exclusiveLock(Object context) throws InterruptedException;
  
      /**
       * Notification from context that it no longer requires access to this resource
       * @param context the context relinguishing access
       */
      public void release(Object context);
  }
  
  
  
  1.1                  incubator-geronimo/modules/core/src/java/org/apache/geronimo/lock/LockContext.java
  
  Index: LockContext.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Geronimo" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Geronimo", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * ====================================================================
   */
  package org.apache.geronimo.lock;
  
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.Set;
  import javax.transaction.Synchronization;
  
  /**
   *
   *
   *
   * @version $Revision: 1.1 $ $Date: 2003/08/10 20:55:14 $
   */
  public abstract class LockContext implements Synchronization {
      protected final Set locks = new HashSet();
  
      public abstract void sharedLock(LockDomain domain, Object key) throws LockReentranceException, InterruptedException;
  
      public abstract void exclusiveLock(LockDomain domain, Object key) throws LockReentranceException, InterruptedException;
  
      public abstract void release(LockDomain domain, Object key);
  
      protected synchronized void sharedLock(InstanceLock lock) throws InterruptedException {
          lock.sharedLock(this);
          locks.add(lock);
      }
  
      protected synchronized void exclusiveLock(InstanceLock lock) throws InterruptedException {
          lock.exclusiveLock(this);
          locks.add(lock);
      }
  
      protected synchronized void releaseLock(InstanceLock lock) {
          lock.release(this);
          locks.remove(lock);
      }
  
      public void beforeCompletion() {
      }
  
      public void afterCompletion(int status) {
          synchronized (this) {
              for (Iterator i = locks.iterator(); i.hasNext();) {
                  InstanceLock lock = (InstanceLock) i.next();
                  lock.release(this);
              }
              locks.clear();
          }
      }
  }
  
  
  
  1.1                  incubator-geronimo/modules/core/src/java/org/apache/geronimo/lock/LockCounter.java
  
  Index: LockCounter.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Geronimo" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Geronimo", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * ====================================================================
   */
  package org.apache.geronimo.lock;
  
  /**
   *
   *
   *
   * @version $Revision: 1.1 $ $Date: 2003/08/10 20:55:14 $
   */
  public class LockCounter {
      private int counter = 0;
  
      public int inc() {
          return ++counter;
      }
  
      public int dec() {
          return --counter;
      }
  
      public int get() {
          return counter;
      }
  }
  
  
  
  1.1                  incubator-geronimo/modules/core/src/java/org/apache/geronimo/lock/LockDomain.java
  
  Index: LockDomain.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Geronimo" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Geronimo", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * ====================================================================
   */
  package org.apache.geronimo.lock;
  
  import java.lang.ref.ReferenceQueue;
  import java.lang.ref.WeakReference;
  import java.util.HashMap;
  import java.util.Map;
  
  
  /**
   *
   *
   *
   * @version $Revision: 1.1 $ $Date: 2003/08/10 20:55:14 $
   */
  public class LockDomain {
      private final String name;
      private final boolean reentrant;
      private final Class lockClass;
      private final ReferenceQueue queue = new ReferenceQueue();
      private final Map locks = new HashMap();
  
      public LockDomain(String name, boolean reentrant, Class lockClass) {
          this.name = name;
          this.reentrant = reentrant;
          this.lockClass = lockClass;
      }
  
      public boolean isReentrant() {
          return reentrant;
      }
  
      public InstanceLock getLock(Object key) {
          assert (key != null);
          InstanceLock lock;
          synchronized (locks) {
              processQueue();
              LockReference ref = (LockReference) locks.get(key);
              if (ref != null) {
                  lock = (InstanceLock) ref.get();
                  if (lock != null) {
                      return lock;
                  }
              }
  
              // lock not found create a new one
              try {
                  lock = (InstanceLock) lockClass.newInstance();
              } catch (InstantiationException e) {
                  throw new IllegalStateException();
              } catch (IllegalAccessException e) {
                  throw new IllegalStateException();
              }
              locks.put(key, new LockReference(key, lock));
          }
          return lock;
      }
  
      private void processQueue() {
          LockReference lockRef;
          while ((lockRef = (LockReference) queue.poll()) != null) {
              synchronized (locks) {
                  locks.remove(lockRef.key);
              }
          }
      }
  
      public String toString() {
          return "LockDomain[" + name + "]";
      }
  
      private class LockReference extends WeakReference {
          private final Object key;
  
          public LockReference(Object key, Object lock) {
              super(lock, queue);
              this.key = key;
          }
      }
  }
  
  
  
  1.1                  incubator-geronimo/modules/core/src/java/org/apache/geronimo/lock/LockInterceptor.java
  
  Index: LockInterceptor.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Geronimo" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Geronimo", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * ====================================================================
   */
  package org.apache.geronimo.lock;
  
  import java.rmi.RemoteException;
  import javax.ejb.EJBException;
  
  import org.apache.geronimo.common.AbstractInterceptor;
  import org.apache.geronimo.ejb.EJBInvocationUtil;
  import org.apache.geronimo.ejb.Entrancy;
  import org.apache.geronimo.common.Invocation;
  import org.apache.geronimo.common.InvocationResult;
  import org.apache.geronimo.common.InvocationType;
  import org.apache.geronimo.common.Container;
  import org.apache.geronimo.ejb.container.EJBPlugins;
  import org.apache.geronimo.ejb.context.ExecutionContext;
  
  /**
   *
   *
   * @version $Revision: 1.1 $ $Date: 2003/08/10 20:55:14 $
   */
  public final class LockInterceptor extends AbstractInterceptor {
      private LockDomain lockDomain;
  
      public void start() throws Exception {
          super.start();
          Container container = getContainer();
          lockDomain = EJBPlugins.getLockDomain(container);
      }
  
      public void stop() {
          lockDomain = null;
          super.stop();
      }
  
      public InvocationResult invoke(Invocation invocation) throws Exception {
          InvocationType type = InvocationType.getType(invocation);
          if (org.apache.geronimo.ejb.Entrancy.isNonEntrant(invocation)) {
              return getNext().invoke(invocation);
          }
  
          // lock the id of this object
          ExecutionContext context = ExecutionContext.getContext();
          LockContext lockContext = context.getLockContext();
          Object id = EJBInvocationUtil.getId(invocation);
          assert (id != null);
  
          try {
              lockContext.exclusiveLock(lockDomain, id);
          } catch (LockReentranceException e) {
              if (type.isLocalInvocation()) {
                  throw new EJBException("not reentrant", e); //@todo - proper subclass
              } else {
                  throw new RemoteException("not reentrant", e); //@todo - proper subclass
              }
          }
          return getNext().invoke(invocation);
      }
  }
  
  
  
  1.1                  incubator-geronimo/modules/core/src/java/org/apache/geronimo/lock/LockReentranceException.java
  
  Index: LockReentranceException.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Geronimo" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Geronimo", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * ====================================================================
   */
  package org.apache.geronimo.lock;
  
  /**
   *
   *
   *
   * @version $Revision: 1.1 $ $Date: 2003/08/10 20:55:14 $
   */
  public class LockReentranceException extends Exception {
  }
  
  
  
  1.1                  incubator-geronimo/modules/core/src/java/org/apache/geronimo/lock/NoTxLockContext.java
  
  Index: NoTxLockContext.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Geronimo" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Geronimo", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * ====================================================================
   */
  package org.apache.geronimo.lock;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  /**
   *
   *
   *
   * @version $Revision: 1.1 $ $Date: 2003/08/10 20:55:14 $
   */
  public class NoTxLockContext extends LockContext {
      private final static Log log = LogFactory.getLog(LockContext.class);
      private boolean isTrace = log.isTraceEnabled();
  
      public void sharedLock(LockDomain domain, Object key) throws LockReentranceException, InterruptedException {
          if (isTrace) {
              log.trace("NoTx Shared Lock domain=" + domain + ", id=" + key);
          }
          InstanceLock lock = domain.getLock(key);
          sharedLock(lock);
      }
  
      public void exclusiveLock(LockDomain domain, Object key) throws LockReentranceException, InterruptedException {
          if (isTrace) {
              log.trace("NoTx Exclusive Lock domain=" + domain + ", id=" + key);
          }
          InstanceLock lock = domain.getLock(key);
          exclusiveLock(lock);
      }
  
      public void release(LockDomain domain, Object key) {
          if (isTrace) {
              log.trace("NoTx Release Lock domain=" + domain + ", id=" + key);
          }
          InstanceLock lock = domain.getLock(key);
          releaseLock(lock);
      }
  }
  
  
  
  1.1                  incubator-geronimo/modules/core/src/java/org/apache/geronimo/lock/TxLockContext.java
  
  Index: TxLockContext.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Geronimo" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Geronimo", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * ====================================================================
   */
  package org.apache.geronimo.lock;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  /**
   *
   *
   *
   * @version $Revision: 1.1 $ $Date: 2003/08/10 20:55:14 $
   */
  public class TxLockContext extends LockContext {
      private final static Log log = LogFactory.getLog(LockContext.class);
      private boolean isTrace = log.isTraceEnabled();
  
      public void sharedLock(LockDomain domain, Object key) throws LockReentranceException, InterruptedException {
          if (isTrace) {
              log.trace("Tx Shared Lock domain=" + domain + ", id=" + key);
          }
          InstanceLock lock = domain.getLock(key);
          synchronized (this) {
              if (!locks.contains(lock)) {
                  sharedLock(lock);
              }
          }
      }
  
      public void exclusiveLock(LockDomain domain, Object key) throws LockReentranceException, InterruptedException {
          if (isTrace) {
              log.trace("Tx Exclusive Lock domain=" + domain + ", id=" + key);
          }
          InstanceLock lock = domain.getLock(key);
          synchronized (this) {
              if (!locks.contains(lock)) {
                  exclusiveLock(lock);
              }
          }
      }
  
      public void release(LockDomain domain, Object key) {
          if (isTrace) {
              log.trace("Tx Release Lock domain=" + domain + ", id=" + key);
          }
          InstanceLock lock = domain.getLock(key);
          synchronized (this) {
              releaseLock(lock);
          }
      }
  }
  
  
  
  1.1                  incubator-geronimo/modules/core/src/java/org/apache/geronimo/lock/WriterPreferredInstanceLock.java
  
  Index: WriterPreferredInstanceLock.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Geronimo" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Geronimo", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * ====================================================================
   */
  package org.apache.geronimo.lock;
  
  
  /**
   * Implementation of InstanceLock using a simple prefer-writer allocation
   * policy.
   * <ul>
   * <li>Contexts requesting exclusive locks will be scheduled before those requesting shared locks</li>
   * <li>A request for an exclusive lock causes requests for shared locks to block
   *     until all exclusive locks have been released.</li>
   * <li>When an exclusive lock is released, any other requests for exclusive locks
   *     will be scheduled before any requests for shared locks</li>
   * </ul>
   * If the workload makes many exclusive requests, this policy may result in
   * starvation of shared requests.
   *
   *
   * @version $Revision: 1.1 $ $Date: 2003/08/10 20:55:14 $
   */
  public class WriterPreferredInstanceLock implements InstanceLock {
      private Object exclActive;
      private int sharedCount = 0;
      private int exclWaiting = 0;
      private int sharedWaiting = 0;
      private final Object exclLock = new Object();
      private final Object sharedLock = new Object();
  
      public void sharedLock(Object context) throws InterruptedException {
          assert (context != null);
          synchronized (sharedLock) {
              synchronized (this) {
                  // we can get the lock immediately if no-one has or is waiting
                  // for an exclusive lock
                  if (exclActive == null && exclWaiting == 0) {
                      sharedCount++;
                      return;
                  }
  
                  // we will have to wait...
                  sharedWaiting++;
              }
              while (true) {
                  try {
                      sharedLock.wait();
                      synchronized (this) {
                          // can we get the lock now?
                          if (exclActive == null && exclWaiting == 0) {
                              sharedWaiting--;
                              sharedCount++;
                              return;
                          }
                      }
                  } catch (InterruptedException e) {
                      // we were interrupted whilst waiting for the lock
                      // no-one else really cares
                      synchronized (this) {
                          sharedWaiting--;
                      }
                      throw e;
                  }
              }
          }
      }
  
      public void exclusiveLock(Object context) throws InterruptedException {
          assert (context != null);
          synchronized (exclLock) {
              synchronized (this) {
                  // we can get the lock immediately if no-one has it and
                  // no-one has a shared lock
                  if (exclActive == null && sharedCount == 0) {
                      exclActive = context;
                      return;
                  }
  
                  // we will have to wait...
                  exclWaiting++;
              }
              while (true) {
                  try {
                      exclLock.wait();
                      synchronized (this) {
                          // can we get the lock now?
                          if (exclActive == null && sharedCount == 0) {
                              exclWaiting--;
                              exclActive = context;
                              return;
                          }
                      }
                  } catch (InterruptedException e) {
                      // we were interrupted whilst waiting for the lock
                      synchronized (this) {
                          exclWaiting--;
  
                          // was the fact that we were waiting stopping anyone
                          // else from getting it?
                          if (exclWaiting > 0) {
                              // trade-off - context switch vs. length of hold
                              // we choose to notify everyone on the assumption
                              // the first holder will release before the
                              // second gets scheduled
                              exclLock.notify();
                          } else if (sharedWaiting > 0) {
                              sharedLock.notifyAll();
                          }
                      }
                      throw e;
                  }
              }
          }
      }
  
      public void release(Object context) {
          assert (context != null);
          synchronized (exclLock) {
              synchronized (sharedLock) {
                  synchronized (this) {
                      if (exclActive == context) {
                          exclActive = null;
  
                          // is anyone waiting for me to release?
                          // give priority to those requesting exclusive access
                          if (exclWaiting > 0) {
                              exclLock.notify();
                          } else if (sharedWaiting > 0) {
                              sharedLock.notifyAll();
                          }
                      } else {
                          sharedCount--;
                          if (sharedCount == 0 && exclWaiting > 0) {
                              // I just released the last shared lock and someone is
                              // waiting for an exclusive, to its time to notify them
                              // again wake everyone - see above
                              exclLock.notify();
                          }
                      }
                  }
              }
          }
      }
  
      public synchronized int getSharedCount() {
          return sharedCount;
      }
  
      public synchronized int getSharedWaiting() {
          return sharedWaiting;
      }
  }
  
  
  
  1.1                  incubator-geronimo/modules/core/src/java/org/apache/geronimo/lock/WriterPreferredInstanceLock2.java
  
  Index: WriterPreferredInstanceLock2.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Geronimo" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Geronimo", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * ====================================================================
   */
  package org.apache.geronimo.lock;
  
  
  /**
   * Implementation of InstanceLock using a simple prefer-writer allocation
   * policy.
   * <ul>
   * <li>Contexts requesting exclusive locks will be scheduled before those requesting shared locks</li>
   * <li>A request for an exclusive lock causes requests for shared locks to block
   *     until all exclusive locks have been released.</li>
   * <li>When an exclusive lock is released, any other requests for exclusive locks
   *     will be scheduled before any requests for shared locks</li>
   * </ul>
   * If the workload makes many exclusive requests, this policy may result in
   * starvation of shared requests.
   *
   *
   * @version $Revision: 1.1 $ $Date: 2003/08/10 20:55:14 $
   */
  public class WriterPreferredInstanceLock2 implements InstanceLock {
      private Object exclActive;
      private int sharedCount = 0;
      private int exclWaiting = 0;
      private int sharedWaiting = 0;
      private final Object exclLock = new Object();
  
      public synchronized void sharedLock(Object context) throws InterruptedException {
          assert (context != null);
          // we can get the lock immediately if no-one has or is waiting
          // for an exclusive lock
          if (exclActive == null && exclWaiting == 0) {
              sharedCount++;
              return;
          }
  
          // we will have to wait...
          sharedWaiting++;
          while (true) {
              try {
                  wait();
                  // can we get the lock now?
                  if (exclActive == null && exclWaiting == 0) {
                      sharedWaiting--;
                      sharedCount++;
                      return;
                  }
              } catch (InterruptedException e) {
                  // we were interrupted whilst waiting for the lock
                  // no-one else really cares
                  sharedWaiting--;
                  throw e;
              }
          }
      }
  
      public synchronized void exclusiveLock(Object context) throws InterruptedException {
          assert (context != null);
          // we can get the lock immediately if no-one has it and
          // no-one has a shared lock
          if (exclActive == null && sharedCount == 0) {
              exclActive = context;
              return;
          }
  
          // we will have to wait...
          exclWaiting++;
          while (true) {
              try {
                  wait();
                  // can we get the lock now?
                  if (exclActive == null && sharedCount == 0) {
                      exclWaiting--;
                      exclActive = context;
                      return;
                  }
              } catch (InterruptedException e) {
                  // we were interrupted whilst waiting for the lock
                  exclWaiting--;
  
                  // was the fact that we were waiting stopping anyone
                  // else from getting it?
                  if (exclWaiting > 0) {
                      // trade-off - context switch vs. length of hold
                      // we choose to notify everyone on the assumption
                      // the first holder will release before the
                      // second gets scheduled
                      notifyAll();
                  } else if (sharedWaiting > 0) {
                      notifyAll();
                  }
                  throw e;
              }
          }
      }
  
  
      public synchronized void release(Object context) {
          assert (context != null);
          if (exclActive == context) {
              exclActive = null;
  
              // is anyone waiting for me to release?
              // give priority to those requesting exclusive access
              if (exclWaiting > 0) {
                  notifyAll();
              } else if (sharedWaiting > 0) {
                  notifyAll();
              }
          } else {
              sharedCount--;
              if (sharedCount == 0 && exclWaiting > 0) {
                  // I just released the last shared lock and someone is
                  // waiting for an exclusive, to its time to notify them
                  // again wake everyone - see above
                  notifyAll();
              }
          }
      }
  
      public synchronized int getSharedCount() {
          return sharedCount;
      }
  
      public synchronized int getSharedWaiting() {
          return sharedWaiting;
      }
  }
  
  
  
  1.1                  incubator-geronimo/modules/core/src/java/org/apache/geronimo/lock/WriterPreferredInstanceLock3.java
  
  Index: WriterPreferredInstanceLock3.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Geronimo" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Geronimo", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * ====================================================================
   */
  package org.apache.geronimo.lock;
  
  
  /**
   * Implementation of InstanceLock using a simple prefer-writer allocation
   * policy.
   * <ul>
   * <li>Contexts requesting exclusive locks will be scheduled before those requesting shared locks</li>
   * <li>A request for an exclusive lock causes requests for shared locks to block
   *     until all exclusive locks have been released.</li>
   * <li>When an exclusive lock is released, any other requests for exclusive locks
   *     will be scheduled before any requests for shared locks</li>
   * </ul>
   * If the workload makes many exclusive requests, this policy may result in
   * starvation of shared requests.
   *
   *
   * @version $Revision: 1.1 $ $Date: 2003/08/10 20:55:14 $
   */
  public class WriterPreferredInstanceLock3 implements InstanceLock {
      private Object exclActive;
      private int sharedCount = 0;
      private int exclWaiting = 0;
      private int sharedWaiting = 0;
      private final Object exclLock = new Object();
  
      public void sharedLock(Object context) throws InterruptedException {
          assert (context != null);
          synchronized (this) {
              // we can get the lock immediately if no-one has or is waiting
              // for an exclusive lock
              if (exclActive == null && exclWaiting == 0) {
                  sharedCount++;
                  return;
              }
  
              // we will have to wait...
              sharedWaiting++;
              while (true) {
                  try {
                      wait();
                      // can we get the lock now?
                      if (exclActive == null && exclWaiting == 0) {
                          sharedWaiting--;
                          sharedCount++;
                          return;
                      }
                  } catch (InterruptedException e) {
                      // we were interrupted whilst waiting for the lock
                      // no-one else really cares
                      sharedWaiting--;
                      throw e;
                  }
              }
          }
      }
  
      public void exclusiveLock(Object context) throws InterruptedException {
          assert (context != null);
          synchronized (exclLock) {
              synchronized (this) {
                  // we can get the lock immediately if no-one has it and
                  // no-one has a shared lock
                  if (exclActive == null && sharedCount == 0) {
                      exclActive = context;
                      return;
                  }
  
                  // we will have to wait...
                  exclWaiting++;
              }
              while (true) {
                  try {
                      exclLock.wait();
                      synchronized (this) {
                          // can we get the lock now?
                          if (exclActive == null && sharedCount == 0) {
                              exclWaiting--;
                              exclActive = context;
                              return;
                          }
                      }
                  } catch (InterruptedException e) {
                      // we were interrupted whilst waiting for the lock
                      synchronized (this) {
                          exclWaiting--;
  
                          // was the fact that we were waiting stopping anyone
                          // else from getting it?
                          if (exclWaiting > 0) {
                              // trade-off - context switch vs. length of hold
                              // we choose to notify everyone on the assumption
                              // the first holder will release before the
                              // second gets scheduled
                              exclLock.notify();
                          } else if (sharedWaiting > 0) {
                              notifyAll();
                          }
                      }
                      throw e;
                  }
              }
          }
      }
  
      public void release(Object context) {
          assert (context != null);
          synchronized (exclLock) {
              synchronized (this) {
                  if (exclActive == context) {
                      exclActive = null;
  
                      // is anyone waiting for me to release?
                      // give priority to those requesting exclusive access
                      if (exclWaiting > 0) {
                          exclLock.notify();
                      } else if (sharedWaiting > 0) {
                          notifyAll();
                      }
                  } else {
                      sharedCount--;
                      if (sharedCount == 0 && exclWaiting > 0) {
                          // I just released the last shared lock and someone is
                          // waiting for an exclusive, to its time to notify them
                          // again wake everyone - see above
                          exclLock.notify();
                      }
                  }
              }
          }
      }
  
      public synchronized int getSharedCount() {
          return sharedCount;
      }
  
      public synchronized int getSharedWaiting() {
          return sharedWaiting;
      }
  }