User: user57  
  Date: 01/07/10 15:45:41

  Modified:    src/main/org/jboss/ejb/plugins
                        EntityInstanceInterceptor.java
  Log:
   o just a re-intent (no code change)
  
  Revision  Changes    Path
  1.33      +280 -277  
jboss/src/main/org/jboss/ejb/plugins/EntityInstanceInterceptor.java
  
  Index: EntityInstanceInterceptor.java
  ===================================================================
  RCS file: 
/cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/EntityInstanceInterceptor.java,v
  retrieving revision 1.32
  retrieving revision 1.33
  diff -u -r1.32 -r1.33
  --- EntityInstanceInterceptor.java    2001/07/03 23:13:45     1.32
  +++ EntityInstanceInterceptor.java    2001/07/10 22:45:41     1.33
  @@ -1,9 +1,9 @@
   /*
  -* JBoss, the OpenSource EJB server
  -*
  -* Distributable under LGPL license.
  -* See terms of license at gnu.org.
  -*/
  + * JBoss, the OpenSource EJB server
  + *
  + * Distributable under LGPL license.
  + * See terms of license at gnu.org.
  + */
   package org.jboss.ejb.plugins;
   
   import java.lang.reflect.Method;
  @@ -39,317 +39,320 @@
   import org.jboss.util.Sync;
   
   /**
  -*
  -*     <p>The instance interceptors role is to acquire a context representing the 
target object from the 
  -*   cache.
  -*
  -*   <p>This particular container interceptor implements pessimistic locking on the 
transaction that 
  -*   is associated with the retrieved instance.  If there is a transaction 
associated with the 
  -*   target component and it is different from the transaction associated with the 
MethodInvocation
  -*   coming in then the policy is to wait for transactional commit. 
  -*   
  -*   <p>We also implement serialization of calls in here (this is a spec 
requirement).
  -*   This is a fine grained notify, notifyAll mechanism. We notify on ctx 
serialization locks and 
  -*   notifyAll on global transactional locks 
  -*   
  -*   <p><b>WARNING: critical code</b>, get approval from senior developers before 
changing.
  -*    
  -*
  -*   @see <related>
  -*   @author <a href="mailto:[EMAIL PROTECTED]";>Marc Fleury</a>
  -*   @version $Revision: 1.32 $
  -*
  -*   <p><b>Revisions:</b><br>
  -*   <p><b>2001/06/28: marcf</b>
  -*   <ol>
  -*   <li>Moved to new synchronization
  -*   <li>Pools are gone simple design
  -*   <li>two levels of syncrhonization with Tx and ctx
  -*   <li>remove busy wait from previous mechanisms
  -*   </ol>
  -*   
  -*/
  + * The instance interceptors role is to acquire a context representing
  + * the target object from the cache.
  + *
  + * <p>This particular container interceptor implements pessimistic locking
  + *    on the transaction that is associated with the retrieved instance.  If
  + *    there is a transaction associated with the target component and it is
  + *    different from the transaction associated with the MethodInvocation
  + *    coming in then the policy is to wait for transactional commit. 
  + *   
  + * <p>We also implement serialization of calls in here (this is a spec
  + *    requirement). This is a fine grained notify, notifyAll mechanism. We
  + *    notify on ctx serialization locks and notifyAll on global transactional
  + *    locks.
  + *   
  + * <p><b>WARNING: critical code</b>, get approval from senior developers
  + *    before changing.
  + *    
  + * @author <a href="mailto:[EMAIL PROTECTED]";>Marc Fleury</a>
  + * @version $Revision: 1.33 $
  + *
  + * <p><b>Revisions:</b><br>
  + * <p><b>2001/06/28: marcf</b>
  + * <ol>
  + *   <li>Moved to new synchronization
  + *   <li>Pools are gone simple design
  + *   <li>two levels of syncrhonization with Tx and ctx
  + *   <li>remove busy wait from previous mechanisms
  + * </ol>
  + */
   public class EntityInstanceInterceptor
  -extends AbstractInterceptor
  +   extends AbstractInterceptor
   {
  -     // Constants -----------------------------------------------------
  +   // Constants -----------------------------------------------------
        
  -     // Attributes ----------------------------------------------------
  -     protected EntityContainer container;
  +   // Attributes ----------------------------------------------------
  +
  +   protected EntityContainer container;
        
  -     // Static --------------------------------------------------------
  +   // Static --------------------------------------------------------
        
  -     // Constructors --------------------------------------------------
  +   // Constructors --------------------------------------------------
        
  -     // Public --------------------------------------------------------
  -     public void setContainer(Container container)
  -     {
  -             this.container = (EntityContainer)container;
  -     }
  +   // Public --------------------------------------------------------
  +   
  +   public void setContainer(Container container)
  +   {
  +      this.container = (EntityContainer)container;
  +   }
        
  -     public  Container getContainer()
  -     {
  -             return container;
  -     }
  +   public  Container getContainer()
  +   {
  +      return container;
  +   }
        
  -     // Interceptor implementation --------------------------------------
  -     public Object invokeHome(MethodInvocation mi)
  -     throws Exception
  -     {
  -             // Get context
  -             EnterpriseContext ctx = 
((EntityContainer)getContainer()).getInstancePool().get();
  -             
  -             // Pass it to the method invocation
  -             mi.setEnterpriseContext(ctx);
  -             
  -             // Give it the transaction
  -             ctx.setTransaction(mi.getTransaction());
  -             
  -             // This context is brand new. We can lock without more "fuss" 
  -             // The reason we need to lock it is that it will be put in cache 
before the end
  -             // of the call.  So another thread could access it before we are done.
  -             
  -             ctx.lock();
  -             
  -             try
  -             {
  -                     // Invoke through interceptors
  -                     return getNext().invokeHome(mi);
  -             } 
  -             finally
  -             {
  -                     //Other threads can be coming for this instance if it is in 
cache
  -                     synchronized(ctx) {
  -                             // Always unlock, no matter what
  -                             ctx.unlock();
  -                             // Wake everyone up in case of create with Tx 
contention
  -                             ctx.notifyAll();
  -                     }
  -                     //Do not send back to pools in any case, let the instance be 
GC'ed
  -             }
  -     }
  +   // Interceptor implementation --------------------------------------
  +   
  +   public Object invokeHome(MethodInvocation mi)
  +      throws Exception
  +   {
  +      // Get context
  +      EnterpriseContext ctx = 
((EntityContainer)getContainer()).getInstancePool().get();
  +             
  +      // Pass it to the method invocation
  +      mi.setEnterpriseContext(ctx);
  +             
  +      // Give it the transaction
  +      ctx.setTransaction(mi.getTransaction());
  +             
  +      // This context is brand new. We can lock without more "fuss" 
  +      // The reason we need to lock it is that it will be put in cache before the 
end
  +      // of the call.  So another thread could access it before we are done.
  +             
  +      ctx.lock();
  +             
  +      try
  +      {
  +         // Invoke through interceptors
  +         return getNext().invokeHome(mi);
  +      } 
  +      finally
  +      {
  +         //Other threads can be coming for this instance if it is in cache
  +         synchronized(ctx) {
  +            // Always unlock, no matter what
  +            ctx.unlock();
  +            // Wake everyone up in case of create with Tx contention
  +            ctx.notifyAll();
  +         }
  +         //Do not send back to pools in any case, let the instance be GC'ed
  +      }
  +   }
        
  -     public Object invoke(MethodInvocation mi)
  -     throws Exception
  -     {
  -             // It's all about the context
  -             EntityEnterpriseContext ctx = null;
  -             
  -             // And it must correspond to the key.
  -             CacheKey key = (CacheKey) mi.getId();
  -             
  -             while (ctx == null)
  -             {
  -                     ctx = (EntityEnterpriseContext) 
container.getInstanceCache().get(key);
  +   public Object invoke(MethodInvocation mi)
  +      throws Exception
  +   {
  +      // It's all about the context
  +      EntityEnterpriseContext ctx = null;
  +             
  +      // And it must correspond to the key.
  +      CacheKey key = (CacheKey) mi.getId();
  +             
  +      while (ctx == null)
  +      {
  +         ctx = (EntityEnterpriseContext) container.getInstanceCache().get(key);
                        
  -                     //Next test is independent of whether the context is locked or 
not, it is purely transactional
  -                     // Is the instance involved with another transaction? if so we 
implement pessimistic locking
  -                     synchronized(ctx.getTxLock()) 
  -                     {
  -                             Transaction tx = ctx.getTransaction();
  +         //Next test is independent of whether the context is locked or not, it is 
purely transactional
  +         // Is the instance involved with another transaction? if so we implement 
pessimistic locking
  +         synchronized(ctx.getTxLock()) 
  +         {
  +            Transaction tx = ctx.getTransaction();
                                
  -                             // Do we have a running transaction with the context?
  -                             if (tx != null &&
  -                                     // And are we trying to enter with another 
transaction?
  -                                     !tx.equals(mi.getTransaction()))
  -                             {
  -                                     // That's no good, only one transaction per 
context
  -                                     // Let's put the thread to sleep the 
transaction demarcation will wake them up
  -                                     Logger.debug("Transactional contention on 
context"+ctx.getId());
  +            // Do we have a running transaction with the context?
  +            if (tx != null &&
  +                // And are we trying to enter with another transaction?
  +                !tx.equals(mi.getTransaction()))
  +            {
  +               // That's no good, only one transaction per context
  +               // Let's put the thread to sleep the transaction demarcation will 
wake them up
  +               Logger.debug("Transactional contention on context"+ctx.getId());
                                        
  -                                     // Wait for it to finish, note that we use 
wait() and not wait(5000), why? 
  -                                     // cause we got cojones, if there a problem in 
this code we want a freeze not illusion
  -                                     // Threads finishing the transaction must 
notifyAll() on the ctx.txLock
  -                                     try {ctx.getTxLock().wait();}
  +               // Wait for it to finish, note that we use wait() and not 
wait(5000), why? 
  +               // cause we got cojones, if there a problem in this code we want a 
freeze not illusion
  +               // Threads finishing the transaction must notifyAll() on the 
ctx.txLock
  +               try {ctx.getTxLock().wait();}
                                        
  -                                     // We need to try again
  -                                     finally {ctx = null; continue;}
  -                             }
  +               // We need to try again
  +               finally {ctx = null; continue;}
  +            }
                                
  -                             /*
  -                             In future versions we can use copies of the instance 
per transaction
  -                             */
  -                     }
  +            /*
  +              In future versions we can use copies of the instance per transaction
  +            */
  +         }
                        
  -                     // The next test is the pure serialization from the EJB 
specification.  
  -                     synchronized(ctx) 
  -                     {
  -                             // synchronized is a time gap, when the thread enters 
here it can be after "sleep"
  -                             // we need to make sure that stuff is still kosher
  +         // The next test is the pure serialization from the EJB specification.  
  +         synchronized(ctx) 
  +         {
  +            // synchronized is a time gap, when the thread enters here it can be 
after "sleep"
  +            // we need to make sure that stuff is still kosher
                                
  -                             // Maybe my transaction already expired?
  -                             if (mi.getTransaction() != null && 
mi.getTransaction().getStatus() == Status.STATUS_MARKED_ROLLBACK)
  -                                     throw new RuntimeException("Transaction marked 
for rollback, possibly a timeout");
  +            // Maybe my transaction already expired?
  +            if (mi.getTransaction() != null && mi.getTransaction().getStatus() == 
Status.STATUS_MARKED_ROLLBACK)
  +               throw new RuntimeException("Transaction marked for rollback, 
possibly a timeout");
                                
  -                             // We do not use pools any longer so the only thing 
that can happen is that 
  -                             // a ctx has a null id (instance removed) (no more 
"wrong id" problem)
  -                             if (ctx.getId() == null) 
  -                             {
  -                                     // This will happen when the instance is 
removed from cache 
  -                                     // We need to go through the same mechs and 
get the new ctx
  -                                     ctx = null;
  -                                     continue;
  -                             }
  -                             // So the ctx is still valid and the transaction is 
still game and we own the context
  -                             // so no one can change ctx.  Make sure that all 
access to ctx is synchronized.
  +            // We do not use pools any longer so the only thing that can happen is 
that 
  +            // a ctx has a null id (instance removed) (no more "wrong id" problem)
  +            if (ctx.getId() == null) 
  +            {
  +               // This will happen when the instance is removed from cache 
  +               // We need to go through the same mechs and get the new ctx
  +               ctx = null;
  +               continue;
  +            }
  +            // So the ctx is still valid and the transaction is still game and we 
own the context
  +            // so no one can change ctx.  Make sure that all access to ctx is 
synchronized.
                                
  -                             // The ctx is still kosher go on with the real 
serialization
  +            // The ctx is still kosher go on with the real serialization
                                
  -                             //Is the context used already (with or without a 
transaction), is it locked?
  -                             if (ctx.isLocked()) 
  -                             {
  -                                     // It is locked but re-entrant calls permitted 
(reentrant home ones are ok as well)
  -                                     if (!isCallAllowed(mi)) 
  -                                     {
  -                                             // This instance is in use and you are 
not permitted to reenter
  -                                             // Go to sleep and wait for the lock 
to be released
  -                                             Logger.debug("Thread contention on 
context"+key);
  +            //Is the context used already (with or without a transaction), is it 
locked?
  +            if (ctx.isLocked()) 
  +            {
  +               // It is locked but re-entrant calls permitted (reentrant home ones 
are ok as well)
  +               if (!isCallAllowed(mi)) 
  +               {
  +                  // This instance is in use and you are not permitted to reenter
  +                  // Go to sleep and wait for the lock to be released
  +                  Logger.debug("Thread contention on context"+key);
                                                
  -                                             // we want to know about freezes so we 
wait(), let us know if this locks  
  -                                             // Threads finishing invocation will 
come here and notify() on the ctx
  -                                             try {ctx.wait();}
  -                                             catch (InterruptedException ignored) 
{}                                 
  -                                             // We need to try again
  -                                             finally {ctx = null; continue;}
  -                                     }
  -                                     else
  -                                     {
  -                                             //We are in a valid reentrant call so 
take the lock, take it!
  -                                             ctx.lock();
  -                                     }
  -                             }
  -                             // No one is using that context
  -                             else 
  -                             {
  +                  // we want to know about freezes so we wait(), let us know if 
this locks  
  +                  // Threads finishing invocation will come here and notify() on 
the ctx
  +                  try {ctx.wait();}
  +                  catch (InterruptedException ignored) {}                           
         
  +                  // We need to try again
  +                  finally {ctx = null; continue;}
  +               }
  +               else
  +               {
  +                  //We are in a valid reentrant call so take the lock, take it!
  +                  ctx.lock();
  +               }
  +            }
  +            // No one is using that context
  +            else 
  +            {
                                        
  -                                     // We are now using the context
  -                                     ctx.lock(); 
  -                             }
  +               // We are now using the context
  +               ctx.lock(); 
  +            }
                                
  -                             // The transaction is associated with the ctx while we 
own the lock 
  -                             ctx.setTransaction(mi.getTransaction());
  +            // The transaction is associated with the ctx while we own the lock 
  +            ctx.setTransaction(mi.getTransaction());
                        
  -                     }// end sychronized(ctx)
  +         }// end sychronized(ctx)
                
  -             }
  +      }
                
  -             // Set context on the method invocation
  -             mi.setEnterpriseContext(ctx);
  +      // Set context on the method invocation
  +      mi.setEnterpriseContext(ctx);
                
  -             boolean exceptionThrown = false;
  +      boolean exceptionThrown = false;
                
  -             try {
  +      try {
                        
  -                     // Go on, you won
  -                     return getNext().invoke(mi);
  +         // Go on, you won
  +         return getNext().invoke(mi);
                
  -             }
  -             catch (RemoteException e)
  -             {
  -                     exceptionThrown = true;
  -                     throw e;
  -             } catch (RuntimeException e)
  -             {
  -                     exceptionThrown = true;
  -                     throw e;
  -             } catch (Error e)
  -             {
  -                     exceptionThrown = true;
  -                     throw e;
  -             } 
  -             finally
  -             {
  -                     // ctx can be null if cache.get throws an Exception, for
  -                     // example when activating a bean.
  -                     if (ctx != null)
  -                     {
  +      }
  +      catch (RemoteException e)
  +      {
  +         exceptionThrown = true;
  +         throw e;
  +      } catch (RuntimeException e)
  +      {
  +         exceptionThrown = true;
  +         throw e;
  +      } catch (Error e)
  +      {
  +         exceptionThrown = true;
  +         throw e;
  +      } 
  +      finally
  +      {
  +         // ctx can be null if cache.get throws an Exception, for
  +         // example when activating a bean.
  +         if (ctx != null)
  +         {
                                
  -                             synchronized(ctx) 
  -                             {
  -                                     ctx.unlock();
  +            synchronized(ctx) 
  +            {
  +               ctx.unlock();
                                        
  -                                     Transaction tx = ctx.getTransaction();
  +               Transaction tx = ctx.getTransaction();
                                        
  -                                     // If an exception has been thrown, 
  -                                     if (exceptionThrown &&                         
         
  -                                             // if tx, the ctx has been registered 
in an InstanceSynchronization. 
  -                                             // that will remove the context, so we 
shouldn't.
  -                                        // if no synchronization then we need to do 
it by hand
  -                                             !ctx.isTxSynchronized()) 
  -                                     {
  -                                             // Discard instance
  -                                             // EJB 1.1 spec 12.3.1
  -                                             
container.getInstanceCache().remove(key);
  +               // If an exception has been thrown, 
  +               if (exceptionThrown &&                                        
  +                   // if tx, the ctx has been registered in an 
InstanceSynchronization. 
  +                   // that will remove the context, so we shouldn't.
  +                   // if no synchronization then we need to do it by hand
  +                   !ctx.isTxSynchronized()) 
  +               {
  +                  // Discard instance
  +                  // EJB 1.1 spec 12.3.1
  +                  container.getInstanceCache().remove(key);
                                                
  -                                             // A cache removal wakes everyone up
  -                                             ctx.notifyAll();
  -                                     }
  +                  // A cache removal wakes everyone up
  +                  ctx.notifyAll();
  +               }
                                        
  -                                     else if (ctx.getId() == null)
  -                                     {
  -                                             // The key from the MethodInvocation 
still identifies the right cachekey
  -                                             
container.getInstanceCache().remove(key);
  +               else if (ctx.getId() == null)
  +               {
  +                  // The key from the MethodInvocation still identifies the right 
cachekey
  +                  container.getInstanceCache().remove(key);
   
  -                                             // A cache removal wakes everyone up
  -                                             ctx.notifyAll();
  +                  // A cache removal wakes everyone up
  +                  ctx.notifyAll();
   
  -                                             // no more pool return
  -                                     }
  +                  // no more pool return
  +               }
                                        
  -                                     // We are done using the context so we wake up 
the next thread waiting for the ctx
  -                                     // marcf: I suspect we could use it only if 
lock = 0 (code it in the context.lock in fact)
  -                                     // this doesn't hurt here, meaning that even 
if we don't wait for 0 to come up 
  -                                     // we will wake up a thread that will go back 
to sleep and the next coming out of 
  -                                     // the body of code will wake the next one etc 
until we reach 0.  Reentrants are a pain
  -                                     // a minor though and I really suspect not 
checking for 0 is quite ok in all cases.
  -                                     ctx.notify();
  -                             }
  -                     }// synchronized ctx
  -             } // finally
  -     }
  +               // We are done using the context so we wake up the next thread 
waiting for the ctx
  +               // marcf: I suspect we could use it only if lock = 0 (code it in the 
context.lock in fact)
  +               // this doesn't hurt here, meaning that even if we don't wait for 0 
to come up 
  +               // we will wake up a thread that will go back to sleep and the next 
coming out of 
  +               // the body of code will wake the next one etc until we reach 0.  
Reentrants are a pain
  +               // a minor though and I really suspect not checking for 0 is quite 
ok in all cases.
  +               ctx.notify();
  +            }
  +         }// synchronized ctx
  +      } // finally
  +   }
        
  -     // Private --------------------------------------------------------
  +   // Private --------------------------------------------------------
        
  -     private static Method getEJBHome;
  -     private static Method getHandle;
  -     private static Method getPrimaryKey;
  -     private static Method isIdentical;
  -     private static Method remove;
  -     static
  -     {
  -             try
  -             {
  -                     Class[] noArg = new Class[0];
  -                     getEJBHome = EJBObject.class.getMethod("getEJBHome", noArg);
  -                     getHandle = EJBObject.class.getMethod("getHandle", noArg);
  -                     getPrimaryKey = EJBObject.class.getMethod("getPrimaryKey", 
noArg);
  -                     isIdentical = EJBObject.class.getMethod("isIdentical", new 
Class[] {EJBObject.class});
  -                     remove = EJBObject.class.getMethod("remove", noArg);
  -             }
  -             catch (Exception x) {x.printStackTrace();}
  -     }
  +   private static Method getEJBHome;
  +   private static Method getHandle;
  +   private static Method getPrimaryKey;
  +   private static Method isIdentical;
  +   private static Method remove;
  +   
  +   static
  +   {
  +      try
  +      {
  +         Class[] noArg = new Class[0];
  +         getEJBHome = EJBObject.class.getMethod("getEJBHome", noArg);
  +         getHandle = EJBObject.class.getMethod("getHandle", noArg);
  +         getPrimaryKey = EJBObject.class.getMethod("getPrimaryKey", noArg);
  +         isIdentical = EJBObject.class.getMethod("isIdentical", new Class[] 
{EJBObject.class});
  +         remove = EJBObject.class.getMethod("remove", noArg);
  +      }
  +      catch (Exception x) {x.printStackTrace();}
  +   }
        
  -     private boolean isCallAllowed(MethodInvocation mi)
  -     {
  -             boolean reentrant = 
((EntityMetaData)container.getBeanMetaData()).isReentrant();
  -             
  -             if (reentrant)
  -             {
  -                     return true;
  -             }
  -             else
  -             {
  -                     Method m = mi.getMethod();
  -                     if (m.equals(getEJBHome) ||
  -                             m.equals(getHandle) ||
  -                             m.equals(getPrimaryKey) ||
  -                             m.equals(isIdentical) ||
  -                             m.equals(remove))
  -                     {
  -                             return true;
  -                     }
  -             }
  +   private boolean isCallAllowed(MethodInvocation mi)
  +   {
  +      boolean reentrant = 
((EntityMetaData)container.getBeanMetaData()).isReentrant();
  +             
  +      if (reentrant)
  +      {
  +         return true;
  +      }
  +      else
  +      {
  +         Method m = mi.getMethod();
  +         if (m.equals(getEJBHome) ||
  +             m.equals(getHandle) ||
  +             m.equals(getPrimaryKey) ||
  +             m.equals(isIdentical) ||
  +             m.equals(remove))
  +         {
  +            return true;
  +         }
  +      }
                
  -             return false;
  -     }
  +      return false;
  +   }
   }
  
  
  

_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to