001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.ejb.plugins.lock;
023:
024: import javax.transaction.Transaction;
025:
026: import org.jboss.ejb.BeanLock;
027: import org.jboss.ejb.Container;
028: import org.jboss.ejb.BeanLockExt;
029: import org.jboss.invocation.Invocation;
030: import org.jboss.logging.Logger;
031: import org.jboss.util.deadlock.Resource;
032:
033: /**
034: * Support for the BeanLock
035: *
036: * @author <a href="bill@burkecentral.com">Bill Burke</a>
037: * @author <a href="marc.fleury@jboss.org">Marc Fleury</a>
038: * @version $Revision: 57209 $
039: */
040: public abstract class BeanLockSupport implements Resource, BeanLockExt {
041: protected Container container = null;
042:
043: /**
044: * Number of threads that retrieved this lock from the manager
045: * (0 means removing)
046: */
047: protected int refs = 0;
048:
049: /** The Cachekey corresponding to this Bean */
050: protected Object id = null;
051:
052: /** Logger instance */
053: static Logger log = Logger.getLogger(BeanLock.class);
054:
055: /** Transaction holding lock on bean */
056: protected Transaction tx = null;
057:
058: protected Thread synched = null;
059: protected int synchedDepth = 0;
060:
061: protected int txTimeout;
062:
063: public void setId(Object id) {
064: this .id = id;
065: }
066:
067: public Object getId() {
068: return id;
069: }
070:
071: public void setTimeout(int timeout) {
072: txTimeout = timeout;
073: }
074:
075: public void setContainer(Container container) {
076: this .container = container;
077: }
078:
079: public Object getResourceHolder() {
080: return tx;
081: }
082:
083: /**
084: * A non-blocking method that checks if the calling thread will be able to acquire
085: * the sync lock based on the calling thread.
086: *
087: * @return true if the calling thread can obtain the sync lock in which
088: * case it will, false if another thread already has the lock.
089: */
090: public boolean attemptSync() {
091: boolean didSync = false;
092: synchronized (this ) {
093: Thread thread = Thread.currentThread();
094: if (synched == null || synched.equals(thread) == true) {
095: synched = thread;
096: ++synchedDepth;
097: didSync = true;
098: }
099: }
100: return didSync;
101: }
102:
103: /**
104: * A method that checks if the calling thread has the lock, and if it
105: * does not blocks until the lock is available. If there is no current owner
106: * of the lock, or the calling thread already owns the lock then the
107: * calling thread will immeadiately acquire the lock.
108: */
109: public void sync() {
110: synchronized (this ) {
111: Thread thread = Thread.currentThread();
112: while (synched != null && synched.equals(thread) == false) {
113: try {
114: this .wait();
115: } catch (InterruptedException ex) { /* ignore */
116: }
117: }
118: synched = thread;
119: ++synchedDepth;
120: }
121: }
122:
123: public void releaseSync() {
124: synchronized (this ) {
125: if (--synchedDepth == 0)
126: synched = null;
127: this .notify();
128: }
129: }
130:
131: public abstract void schedule(Invocation mi) throws Exception;
132:
133: /**
134: * The setTransaction associates a transaction with the lock.
135: * The current transaction is associated by the schedule call.
136: */
137: public void setTransaction(Transaction tx) {
138: this .tx = tx;
139: }
140:
141: public Transaction getTransaction() {
142: return tx;
143: }
144:
145: public abstract void endTransaction(Transaction tx);
146:
147: public abstract void wontSynchronize(Transaction tx);
148:
149: public abstract void endInvocation(Invocation mi);
150:
151: public void addRef() {
152: refs++;
153: }
154:
155: public void removeRef() {
156: refs--;
157: }
158:
159: public int getRefs() {
160: return refs;
161: }
162:
163: // Private --------------------------------------------------------
164:
165: }
|