/*
* JBoss, Home of Professional Open Source.
* Copyright 2008, 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.ejb.plugins.lock;
import javax.transaction.Transaction;
import org.jboss.ejb.BeanLock;
import org.jboss.ejb.Container;
import org.jboss.ejb.BeanLockExt;
import org.jboss.invocation.Invocation;
import org.jboss.logging.Logger;
import org.jboss.util.deadlock.Resource;
/**
* Support for the BeanLock
*
* @author <a href="bill@burkecentral.com">Bill Burke</a>
* @author <a href="marc.fleury@jboss.org">Marc Fleury</a>
* @version $Revision: 81030 $
*/
public abstract class BeanLockSupport implements Resource, BeanLockExt
{
protected Container container = null;
/**
* Number of threads that retrieved this lock from the manager
* (0 means removing)
*/
protected int refs = 0;
/** The Cachekey corresponding to this Bean */
protected Object id = null;
/** Logger instance */
static Logger log = Logger.getLogger(BeanLock.class);
/** Transaction holding lock on bean */
protected Transaction tx = null;
protected Thread synched = null;
protected int synchedDepth = 0;
protected int txTimeout;
public void setId(Object id) { this.id = id;}
public Object getId() { return id;}
public void setTimeout(int timeout) {txTimeout = timeout;}
public void setContainer(Container container) { this.container = container; }
public Object getResourceHolder() { return tx; }
/**
* A non-blocking method that checks if the calling thread will be able to acquire
* the sync lock based on the calling thread.
*
* @return true if the calling thread can obtain the sync lock in which
* case it will, false if another thread already has the lock.
*/
public boolean attemptSync()
{
boolean didSync = false;
synchronized(this)
{
Thread thread = Thread.currentThread();
if(synched == null || synched.equals(thread) == true)
{
synched = thread;
++ synchedDepth;
didSync = true;
}
}
return didSync;
}
/**
* A method that checks if the calling thread has the lock, and if it
* does not blocks until the lock is available. If there is no current owner
* of the lock, or the calling thread already owns the lock then the
* calling thread will immeadiately acquire the lock.
*/
public void sync()
{
synchronized(this)
{
Thread thread = Thread.currentThread();
while(synched != null && synched.equals(thread) == false)
{
try
{
this.wait();
}
catch (InterruptedException ex) { /* ignore */ }
}
synched = thread;
++synchedDepth;
}
}
public void releaseSync()
{
synchronized(this)
{
if (--synchedDepth == 0)
synched = null;
this.notify();
}
}
public abstract void schedule(Invocation mi) throws Exception;
/**
* The setTransaction associates a transaction with the lock.
* The current transaction is associated by the schedule call.
*/
public void setTransaction(Transaction tx){this.tx = tx;}
public Transaction getTransaction(){return tx;}
public abstract void endTransaction(Transaction tx);
public abstract void wontSynchronize(Transaction tx);
public abstract void endInvocation(Invocation mi);
public void addRef() { refs++;}
public void removeRef() { refs--;}
public int getRefs() { return refs;}
// Private --------------------------------------------------------
}