[jboss-cvs] jboss-seam/src/main/org/jboss/seam/core ...

Gavin King gavin.king at jboss.com
Thu Oct 12 22:24:30 EDT 2006


  User: gavin   
  Date: 06/10/12 22:24:30

  Modified:    src/main/org/jboss/seam/core   ConversationEntry.java
                        Manager.java
  Log:
  better thought-out locking model
  
  Revision  Changes    Path
  1.23      +15 -10    jboss-seam/src/main/org/jboss/seam/core/ConversationEntry.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: ConversationEntry.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/src/main/org/jboss/seam/core/ConversationEntry.java,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -b -r1.22 -r1.23
  --- ConversationEntry.java	13 Oct 2006 01:27:31 -0000	1.22
  +++ ConversationEntry.java	13 Oct 2006 02:24:30 -0000	1.23
  @@ -7,8 +7,8 @@
   import java.util.Collections;
   import java.util.Date;
   import java.util.List;
  -import java.util.concurrent.Semaphore;
   import java.util.concurrent.TimeUnit;
  +import java.util.concurrent.locks.ReentrantLock;
   
   /**
    * Metadata about an active conversation. Also used
  @@ -32,7 +32,7 @@
      
      private ConversationEntries parent;
      
  -   private Semaphore semaphore = new Semaphore(1,true);
  +   private ReentrantLock lock = new ReentrantLock(true);
   
      public ConversationEntry(String id, List<String> stack, ConversationEntries parent)
      {
  @@ -58,13 +58,13 @@
         this.description = description;
      }
   
  -   public long getLastRequestTime() {
  +   public synchronized long getLastRequestTime() {
         return lastRequestTime;
      }
   
  -   void touch() {
  +   synchronized void touch() {
         parent.setDirty();
  -      this.lastRequestTime = System.currentTimeMillis();
  +      lastRequestTime = System.currentTimeMillis();
         lastDatetime = new Date();
      }
   
  @@ -110,7 +110,7 @@
         return viewId;
      }
   
  -   public Date getLastDatetime() {
  +   public synchronized Date getLastDatetime() {
         return lastDatetime;
      }
   
  @@ -176,11 +176,16 @@
         this.id = id;
      }
   
  -   public boolean lock()
  +   public boolean lockNoWait() //not synchronized!
  +   {
  +      return lock.tryLock();
  +   }
  +
  +   public boolean lock() //not synchronized!
      {
         try
         {
  -         return semaphore.tryAcquire( Manager.instance().getConcurrentRequestTimeout(), TimeUnit.MILLISECONDS );
  +         return lock.tryLock( Manager.instance().getConcurrentRequestTimeout(), TimeUnit.MILLISECONDS );
         }
         catch (InterruptedException ie)
         {
  @@ -188,9 +193,9 @@
         }
      }
      
  -   public void unlock()
  +   public void unlock() //not synchronized!
      {
  -      semaphore.release();
  +      lock.unlock();
      }
      
   }
  \ No newline at end of file
  
  
  
  1.96      +32 -5     jboss-seam/src/main/org/jboss/seam/core/Manager.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: Manager.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss-seam/src/main/org/jboss/seam/core/Manager.java,v
  retrieving revision 1.95
  retrieving revision 1.96
  diff -u -b -r1.95 -r1.96
  --- Manager.java	13 Oct 2006 01:27:31 -0000	1.95
  +++ Manager.java	13 Oct 2006 02:24:30 -0000	1.96
  @@ -41,7 +41,7 @@
    *
    * @author Gavin King
    * @author <a href="mailto:theute at jboss.org">Thomas Heute</a>
  - * @version $Revision: 1.95 $
  + * @version $Revision: 1.96 $
    */
   @Scope(ScopeType.EVENT)
   @Name("org.jboss.seam.core.manager")
  @@ -249,16 +249,41 @@
         List<ConversationEntry> entries = new ArrayList<ConversationEntry>( ConversationEntries.instance().getConversationEntries() );
         for (ConversationEntry conversationEntry: entries)
         {
  +         boolean locked = conversationEntry.lockNoWait(); //we had better not wait for it, or we would be waiting for ALL other requests
  +         try
  +         {
            long delta = currentTime - conversationEntry.getLastRequestTime();
            if ( delta > conversationEntry.getTimeout() )
            {
  -            if ( conversationEntry.lock() ) //no need to release it...
  +               if ( locked )
  +               { 
  +                  if ( log.isDebugEnabled() )
               {
                  log.debug("conversation timeout for conversation: " + conversationEntry.getId());
  +                  }
  +               }
  +               else
  +               {
  +                  //if we could not acquire the lock, someone has left a garbage lock lying around
  +                  //the reason garbage locks can exist is that we don't require a servlet filter to
  +                  //exist - but if we do use SeamExceptionFilter, it will clean up garbage and this
  +                  //case should never occur
  +                  
  +                  //NOTE: this is slightly broken - in theory there is a window where a new request 
  +                  //      could have come in and got the lock just before us but called touch() just 
  +                  //      after we check the timeout - but in practice this would be extremely rare, 
  +                  //      and that request will get an IllegalMonitorStateException when it tries to 
  +                  //      unlock() the CE
  +                  log.info("destroying conversation with garbage lock: " + conversationEntry.getId());
  +               }
                  ContextAdaptor session = ContextAdaptor.getSession(externalContext, true);
                  destroyConversation( conversationEntry.getId(), session );
               }
            }
  +         finally
  +         {
  +            if (locked) conversationEntry.unlock();
  +         }
         }
      }
   
  @@ -527,6 +552,8 @@
         if ( ce!=null && ce.lock() )
         {
   
  +         touchConversationStack();
  +
            //we found an id and obtained the lock, so restore the long-running conversation
            log.debug("Restoring conversation with id: " + storedConversationId);
            setLongRunningConversation(true);
  
  
  



More information about the jboss-cvs-commits mailing list