Package org.jboss.ejb3.concurrency.impl

Source Code of org.jboss.ejb3.concurrency.impl.EJBReadWriteLock$WriteLock

/*
* JBoss, Home of Professional Open Source.
* Copyright 2009, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.ejb3.concurrency.impl;

import java.io.Serializable;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import javax.ejb.IllegalLoopbackException;

/**
* An implementation of {@link ReadWriteLock} which throws an {@link IllegalLoopbackException}
* when a thread holding a read lock tries to obtain a write lock.
*
* @author <a href="mailto:cdewolf@redhat.com">Carlo de Wolf</a>
* @version $Revision: $
*/
public class EJBReadWriteLock implements ReadWriteLock, Serializable
{
   private static final long serialVersionUID = 1L;

   /**
    * Keep track of the number of read locks held by this thread
    */
   private ThreadLocal<Integer> readLockCount = new ThreadLocal<Integer>();

   /**
    * We delegate all locking semantics to this {@link ReentrantReadWriteLock}
    */
   private ReentrantReadWriteLock delegate = new ReentrantReadWriteLock();

   /**
    * Read lock instance which will be handed out to clients
    * on a call to {@link #readLock()}
    */
   private Lock readLock = new ReadLock();

   /**
    * Write lock instance which will be handed out to clients
    * on a call to {@link #writeLock()}
    */
   private Lock writeLock = new WriteLock();

   /**
    *
    * A read lock which increments/decrements the count of
    * read locks held by the thread and delegates the locking
    * calls to the {@link #delegate}
    *
    * @author Jaikiran Pai
    * @version $Revision: $
    */
   public class ReadLock implements Lock, Serializable
   {
      private static final long serialVersionUID = 1L;

      /**
       * Delegate the call to the internal {@link ReentrantReadWriteLock} instance
       * and then increment the read lock count held by the thread
       */
      @Override
      public void lock()
      {
         delegate.readLock().lock();
         incReadLockCount();
      }

      /**
       * Delegate the call to the internal {@link ReentrantReadWriteLock} instance
       * and then increment the read lock count held by the thread
       */
      @Override
      public void lockInterruptibly() throws InterruptedException
      {
         delegate.readLock().lockInterruptibly();
         incReadLockCount();
      }

      /**
       * No implementation provided
       * @throws UnsupportedOperationException
       */
      @Override
      public Condition newCondition()
      {
         throw new UnsupportedOperationException();
      }

      /**
       * Delegate the call to the internal {@link ReentrantReadWriteLock} instance
       * and then on successful acquisition of lock, increment the read lock count held by the thread
       */
      @Override
      public boolean tryLock()
      {
         if (delegate.readLock().tryLock())
         {
            incReadLockCount();
            return true;
         }
         return false;
      }

      /**
       * Delegate the call to the internal {@link ReentrantReadWriteLock} instance
       * and then on successful acquisition of lock, increment the read lock count held by the thread
       */
      @Override
      public boolean tryLock(long time, TimeUnit unit) throws InterruptedException
      {
         if (delegate.readLock().tryLock(time, unit))
         {
            incReadLockCount();
            return true;
         }
         return false;
      }

      /**
       * Delegate the call to the internal {@link ReentrantReadWriteLock} instance
       * and then decrement the read lock count held by the thread
       */
      @Override
      public void unlock()
      {
         delegate.readLock().unlock();
         decReadLockCount();
      }

   }

   /**
    *
    * An implementation of lock which first checks the number of {@link ReadLock}
    * held by this thread. If the thread already holds a {@link ReadLock}, then
    * this implementation throws an {@link IllegalLoopbackException} when a lock
    * is requested
    *
    * @author Jaikiran Pai
    * @version $Revision: $
    */
   public class WriteLock implements Lock, Serializable
   {
      private static final long serialVersionUID = 1L;

      /**
       * Ensures that the current thread doesn't hold any read locks. If
       * the thread holds any read locks, this method throws a {@link IllegalLoopbackException}.
       * If no read locks are held, then this method delegates the call to the
       * internal delegate {@link ReentrantReadWriteLock}
       */
      @Override
      public void lock()
      {
         checkLoopback();
         delegate.writeLock().lock();
      }

      /**
       * Ensures that the current thread doesn't hold any read locks. If
       * the thread holds any read locks, this method throws a {@link IllegalLoopbackException}.
       * If no read locks are held, then this method delegates the call to the
       * internal delegate {@link ReentrantReadWriteLock}
       */
      @Override
      public void lockInterruptibly() throws InterruptedException
      {
         checkLoopback();
         delegate.writeLock().lockInterruptibly();
      }

      /**
       * Not implemented
       * @throws UnsupportedOperationException
       */
      @Override
      public Condition newCondition()
      {
         throw new UnsupportedOperationException();
      }

      /**
       * Ensures that the current thread doesn't hold any read locks. If
       * the thread holds any read locks, this method throws a {@link IllegalLoopbackException}.
       * If no read locks are held, then this method delegates the call to the
       * internal delegate {@link ReentrantReadWriteLock}
       */
      @Override
      public boolean tryLock()
      {
         checkLoopback();
         return delegate.writeLock().tryLock();
      }

      /**
       * Ensures that the current thread doesn't hold any read locks. If
       * the thread holds any read locks, this method throws a {@link IllegalLoopbackException}.
       * If no read locks are held, then this method delegates the call to the
       * internal delegate {@link ReentrantReadWriteLock}
       */
      @Override
      public boolean tryLock(long time, TimeUnit unit) throws InterruptedException
      {
         checkLoopback();
         return delegate.writeLock().tryLock(time, unit);
      }

      /**
       * This method delegates the call to the
       * internal delegate {@link ReentrantReadWriteLock}
       */
      @Override
      public void unlock()
      {
         delegate.writeLock().unlock();
      }
   }

   /**
    * Ensures that the current thread doesn't hold any read locks. If
    * the thread holds any read locks, this method throws a {@link IllegalLoopbackException}.
    *
    */
   private void checkLoopback()
   {
      Integer current = readLockCount.get();
      if (current != null)
      {
         assert current.intValue() > 0 : "readLockCount is set, but to 0";
         throw new IllegalLoopbackException("EJB 3.1 PFD2 4.8.5.1.1 upgrading from read to write lock is not allowed");
      }
   }

   /**
    * Decrements the read lock count held by the thread
    */
   private void decReadLockCount()
   {
      Integer current = readLockCount.get();
      int next;
      assert current != null : "can't decrease, readLockCount is not set";
      next = current.intValue() - 1;
      if (next == 0)
         readLockCount.remove();
      else
         readLockCount.set(new Integer(next));
   }

   /**
    * Increments the read lock count held by the thread
    */
   private void incReadLockCount()
   {
      Integer current = readLockCount.get();
      int next;
      if (current == null)
         next = 1;
      else
         next = current.intValue() + 1;
      readLockCount.set(new Integer(next));
   }

   /**
    * @see ReadWriteLock#readLock()
    */
   @Override
   public Lock readLock()
   {
      return readLock;
   }

   /**
    * @see ReadWriteLock#writeLock()
    */
   @Override
   public Lock writeLock()
   {
      return writeLock;
   }
}
TOP

Related Classes of org.jboss.ejb3.concurrency.impl.EJBReadWriteLock$WriteLock

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.