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;
023:
024: import org.jboss.ejb.BeanLock;
025: import org.jboss.invocation.Invocation;
026:
027: /**
028: * The lock interceptors role is to schedule thread wanting to invoke method on a target bean
029: *
030: * <p>The policies for implementing scheduling (pessimistic locking etc) is implemented by pluggable
031: * locks
032: *
033: * <p>We also implement serialization of calls in here (this is a spec
034: * requirement). This is a fine grained notify, notifyAll mechanism. We
035: * notify on ctx serialization locks and notifyAll on global transactional
036: * locks.
037: *
038: * <p><b>WARNING: critical code</b>, get approval from senior developers
039: * before changing.
040: *
041: * @author <a href="mailto:marc.fleury@jboss.org">Marc Fleury</a>
042: * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
043: * @version $Revision: 57209 $
044: *
045: * <p><b>Revisions:</b><br>
046: * <p><b>2001/07/30: marcf</b>
047: * <ol>
048: * <li>Initial revision
049: * <li>Factorization of the lock out of the context in cache
050: * <li>The new locking is implement as "scheduling" in the lock which allows for pluggable locks
051: * </ol>
052: * <p><b>2001/08/07: billb</b>
053: * <ol>
054: * <li>Removed while loop and moved it to SimplePessimisticEJBLock where it belongs.
055: * </ol>
056: */
057: public class EntityLockInterceptor extends AbstractInterceptor {
058: // Constants -----------------------------------------------------
059:
060: // Attributes ----------------------------------------------------
061:
062: // Static --------------------------------------------------------
063:
064: // Constructors --------------------------------------------------
065:
066: // Public --------------------------------------------------------
067:
068: // Interceptor implementation --------------------------------------
069:
070: public Object invokeHome(Invocation mi) throws Exception {
071: // Invoke through interceptors
072: return getNext().invokeHome(mi);
073:
074: }
075:
076: public Object invoke(Invocation mi) throws Exception {
077:
078: // The key.
079: Object key = mi.getId();
080:
081: // The lock.
082: BeanLock lock;
083:
084: boolean threadIsScheduled = false;
085: boolean trace = log.isTraceEnabled();
086:
087: if (trace)
088: log.trace("Begin invoke, key=" + key);
089:
090: lock = container.getLockManager().getLock(key);
091: try {
092:
093: lock.schedule(mi);
094:
095: try {
096:
097: return getNext().invoke(mi);
098: }
099:
100: finally {
101:
102: // we are done with the method, decrease the count, if it reaches 0 it will wake up
103: // the next thread
104: lock.sync();
105: lock.endInvocation(mi);
106: lock.releaseSync();
107: }
108: } finally {
109:
110: // We are done with the lock in general
111: container.getLockManager().removeLockRef(key);
112:
113: if (trace)
114: log.trace("End invoke, key=" + key);
115: }
116: }
117: }
|