User: simone  
  Date: 00/12/12 01:42:58

  Modified:    src/main/org/jboss/ejb/plugins
                        EntityInstanceInterceptor.java
  Log:
  Improved synchronization with the passivation, see AbstractInstanceCache.
  Most of changes simply replace sync blocks with the use of a Semaphore object.
  
  Revision  Changes    Path
  1.25      +99 -113   
jboss/src/main/org/jboss/ejb/plugins/EntityInstanceInterceptor.java
  
  Index: EntityInstanceInterceptor.java
  ===================================================================
  RCS file: 
/products/cvs/ejboss/jboss/src/main/org/jboss/ejb/plugins/EntityInstanceInterceptor.java,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- EntityInstanceInterceptor.java    2000/12/07 15:44:23     1.24
  +++ EntityInstanceInterceptor.java    2000/12/12 09:42:58     1.25
  @@ -36,6 +36,7 @@
   import org.jboss.ejb.CacheKey;
   import org.jboss.metadata.EntityMetaData;
   import org.jboss.logging.Logger;
  +import org.jboss.util.Sync;
   
   /**
   *   This container acquires the given instance. 
  @@ -44,7 +45,7 @@
   *   @author Rickard �berg ([EMAIL PROTECTED])
   *   @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
   *   @author <a href="mailto:[EMAIL PROTECTED]">Sebastien Alborini</a>
  -*   @version $Revision: 1.24 $
  +*   @version $Revision: 1.25 $
   */
   public class EntityInstanceInterceptor
   extends AbstractInterceptor
  @@ -89,24 +90,12 @@
               // Always unlock, no matter what
               ctx.unlock();
               
  -            synchronized (ctx) {
  -                
  -                // Still free? Not free if create() was called successfully
  -                if (ctx.getId() == null)
  -                {
  -                    container.getInstancePool().free(ctx);
  -                
  -                    // the pool will notify all everyone
  -                } 
  -                else
  -                {
  -                    // DEBUG           Logger.debug("Entity was created; not 
returned to pool");
  -                    
  -                    //Let one waiter know
  -                    ctx.notify();
  -                    
  -                }
  -            }
  +            // Still free? Not free if create() was called successfully
  +            if (ctx.getId() == null)
  +            {
  +                container.getInstancePool().free(ctx);
  +                // the pool will notify all everyone
  +            } 
           }
       }
       
  @@ -114,11 +103,11 @@
       throws Exception
       {
           // The id store is a CacheKey in the case of Entity 
  -        CacheKey key = (CacheKey) mi.getId();
  +        CacheKey key = (CacheKey)mi.getId();
           
           // Get cache
  -        EnterpriseInstanceCache cache = 
(EnterpriseInstanceCache)container.getInstanceCache();
  -        Object mutex = cache.getLock(key);
  +        AbstractInstanceCache cache = 
(AbstractInstanceCache)container.getInstanceCache();
  +        Sync mutex = (Sync)cache.getLock(key);
           
           EnterpriseContext ctx = null;
           
  @@ -128,16 +117,14 @@
               {
                   if (mi.getTransaction() != null && mi.getTransaction().getStatus() 
== Status.STATUS_MARKED_ROLLBACK) 
                       throw new RuntimeException("Transaction marked for rollback, 
possibly a timeout");
  -                
  -                synchronized(this) 
  -                {
  -                    
  +  
  +                             try 
  +                             {
  +                             
  +                                     mutex.acquire();
  +                             
                       // Get context
                       ctx = cache.get(key);
  -                }
  -                
  -                synchronized(ctx) 
  -                {
                       
                       // Do we have a running transaction with the context
                       Transaction tx = ctx.getTransaction();
  @@ -148,15 +135,10 @@
                           // Let's put the thread to sleep a lock release will wake 
the thread
                           // Possible deadlock
                           Logger.debug("LOCKING-WAITING (TRANSACTION) for id 
"+ctx.getId()+" ctx.hash "+ctx.hashCode()+" tx:"+((tx == null) ? "null" : 
tx.toString()));
  -                        
  -                        try {
  -                            ctx.wait(5000);
  -                        } catch (InterruptedException ie) {}
  -                        
  +  
                           // Try your luck again
                           ctx = null;
                           continue;
  -                    
                       }
                       else 
                       {
  @@ -176,10 +158,6 @@
                                   // Possible deadlock
                                   Logger.debug("LOCKING-WAITING (CTX) for id 
"+ctx.getId()+" ctx.hash "+ctx.hashCode());
                                   
  -                                try{
  -                                    ctx.wait(5000);
  -                                } catch (InterruptedException ie) {}
  -                                
                                   // Try your luck again
                                   ctx = null;
                                   continue;
  @@ -194,6 +172,11 @@
                           }
                       }
                   }
  +                             catch (InterruptedException ignored) {}
  +                             finally 
  +                             {
  +                                     mutex.release();
  +                             }
               
               } while (ctx == null);
                   
  @@ -228,84 +211,87 @@
           } finally
           {
               //         Logger.debug("Release instance for "+id);
  -            if (ctx != null)
  -            {
  -                // unlock the context
  -                ctx.unlock();
  -                
  -                if (ctx.getId() == null)                             
  -                {
  -                    
  -                    // Work only if no transaction was encapsulating this remove()
  -                    if (ctx.getTransaction() == null) {
  -                        
  -                        // Remove from cache
  -                        cache.remove(key);
  -                        
  -                        // It has been removed -> send to the pool
  -                        container.getInstancePool().free(ctx);
  -                        
  -                        // The pool will notify everyone waiting on this
  -                        
  -                    }
  -                }
  +                     try 
  +                     {
  +                             mutex.acquire();
  +                             
  +                             // unlock the context
  +                             ctx.unlock();
                   
  -                else {
  -                 
  -                    // MF FIXME for speed reason I use notify
  -                    // however we would need to lock on the tx and ctx so we can 
  -                    // notify the right population, slightly more complicated...
  -                    
  -                    // notify the next thread waiting on ctx
  -                    synchronized (ctx) { ctx.notify();}
  -                }
  +                             if (ctx.getId() == null)                             
  +                             {
  +                                         
  +                                 // Work only if no transaction was encapsulating 
this remove()
  +                                     if (ctx.getTransaction() == null) 
  +                                     {
  +                                             // Here we arrive if the bean has been 
removed and no 
  +                                             // transaction was associated with the 
remove, or if 
  +                                             // the bean has been passivated
  +
  +                                             // Remove from cache
  +                                             cache.remove(key);
  +                                             
  +                                             // It has been removed -> send to the 
pool
  +                                             container.getInstancePool().free(ctx);
  +                                             
  +                                             // The pool will notify everyone 
waiting on this
  +                                 }
  +                             }
  +                             else 
  +                             {
  +                                     // Yeah, do nothing
  +                             }
               }
  +                     catch (InterruptedException ignored) {}
  +                     finally 
  +                     {
  +                             mutex.release();
  +                     }
           }
       }
   
  +     // 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;
  -        }
  -    }
  -    
  -    return false;
  -}
  +     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;
  +     }
   }
  
  
  

Reply via email to