You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by im...@apache.org on 2007/07/05 15:03:39 UTC

svn commit: r553490 - in /myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation: Conversation.java ConversationContext.java ConversationManager.java jsf/filter/OrchestraServletFilter.java

Author: imario
Date: Thu Jul  5 06:03:38 2007
New Revision: 553490

URL: http://svn.apache.org/viewvc?view=rev&rev=553490
Log:
try to avoid deadlock

Modified:
    myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/Conversation.java
    myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationContext.java
    myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationManager.java
    myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/jsf/filter/OrchestraServletFilter.java

Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/Conversation.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/Conversation.java?view=diff&rev=553490&r1=553489&r2=553490
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/Conversation.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/Conversation.java Thu Jul  5 06:03:38 2007
@@ -108,13 +108,13 @@
 	{
 		checkValid();
 
-		synchronized(this)
+		synchronized(conversationContext)
 		{
 			removeAttribute(name);
 
 			if (log.isDebugEnabled())
 			{
-				log.debug("put bean to conversation:" + name + "(bean=" + name + ")");
+				log.debug("put bean to conversation:" + name + "(bean=" + bean + ")");
 			}
 
 			beans.put(name, bean);
@@ -225,7 +225,7 @@
 			log.debug("destroy conversation:" + name);
 		}
 
-		synchronized(this)
+		synchronized(conversationContext)
 		{
 			String[] beanNames = (String[]) beans.keySet().toArray(new String[beans.size()]);
 			for (int i = 0; i< beanNames.length; i++)
@@ -244,7 +244,7 @@
 	 */
 	public boolean hasAttribute(String name)
 	{
-		synchronized(this)
+		synchronized(conversationContext)
 		{
 			return beans.containsKey(name);
 		}
@@ -255,7 +255,7 @@
 	 */
 	public Object getAttribute(String name)
 	{
-		synchronized(this)
+		synchronized(conversationContext)
 		{
 			return beans.get(name);
 		}
@@ -270,7 +270,7 @@
 	 */
 	public Object removeAttribute(String name)
 	{
-		synchronized(this)
+		synchronized(conversationContext)
 		{
 			Object bean = beans.remove(name);
 			if (bean instanceof ConversationBindingListener)

Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationContext.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationContext.java?view=diff&rev=553490&r1=553489&r2=553490
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationContext.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationContext.java Thu Jul  5 06:03:38 2007
@@ -42,6 +42,8 @@
 	private final long id;
 	private final ConversationManager manager;
 
+	private final Map attributes = new TreeMap();
+
 	private final Map conversations = new TreeMap();
 
 	private long lastAccess;
@@ -228,6 +230,57 @@
 					conversation.invalidate();
 				}
 			}
+		}
+	}
+
+	/**
+	 * add an attribute to the conversationContext
+	 */
+	public void setAttribute(String name, Object attribute)
+	{
+		synchronized(this)
+		{
+			removeAttribute(name);
+
+			if (log.isDebugEnabled())
+			{
+				log.debug("put bean to conversationContext:" + name + "(attribute=" + attribute + ")");
+			}
+
+			attributes.put(name, attribute);
+		}
+	}
+
+	/**
+	 * check if this conversationContext holds a specific attribute
+	 */
+	public boolean hasAttribute(String name)
+	{
+		synchronized(this)
+		{
+			return attributes.containsKey(name);
+		}
+	}
+
+	/**
+	 * get a specific attribute
+	 */
+	public Object getAttribute(String name)
+	{
+		synchronized(this)
+		{
+			return attributes.get(name);
+		}
+	}
+
+	/**
+	 * <p>remove an attribute from the conversationContext.</p>
+	 */
+	public Object removeAttribute(String name)
+	{
+		synchronized(this)
+		{
+			return attributes.remove(name);
 		}
 	}
 }

Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationManager.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationManager.java?view=diff&rev=553490&r1=553489&r2=553490
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationManager.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/ConversationManager.java Thu Jul  5 06:03:38 2007
@@ -102,7 +102,7 @@
 
 	/**
 	 * Get the conversation manager.
-	 * @param create false if you just would like to get one if it has been created already   
+	 * @param create false if you just would like to get one if it has been created already
 	 */
 	public static ConversationManager getInstance(boolean create)
 	{
@@ -371,26 +371,35 @@
 
 	protected void checkTimeouts()
 	{
+		Map.Entry[] contexts;
 		synchronized (this)
 		{
-			long timeToLive = 30 * 60 * 1000;
-			long checkTime = System.currentTimeMillis();
+			contexts = new Map.Entry[conversationContexts.size()];
+			conversationContexts.entrySet().toArray(contexts);
+		}
 
-			Iterator iterContexts = conversationContexts.values().iterator();
-			while (iterContexts.hasNext())
-			{
-				ConversationContext conversationContext = (ConversationContext) iterContexts.next();
-				conversationContext.checkConversationTimeout();
+		long timeToLive = 30 * 60 * 1000;
+		long checkTime = System.currentTimeMillis();
+
+		for (int i = 0; i<contexts.length; i++)
+		{
+			Map.Entry context = contexts[i];
 
-				if (conversationContext.getLastAccess() + timeToLive < checkTime)
+			Long conversationContextId = (Long) context.getKey();
+			ConversationContext conversationContext = (ConversationContext) context.getValue();
+			conversationContext.checkConversationTimeout();
+
+			if (conversationContext.getLastAccess() + timeToLive < checkTime)
+			{
+				if (log.isDebugEnabled())
 				{
-					if (log.isDebugEnabled())
-					{
-						log.debug("end conversation context due to timeout: " + conversationContext.getId());
-					}
+					log.debug("end conversation context due to timeout: " + conversationContext.getId());
+				}
 
-					conversationContext.clear();
-					iterContexts.remove();
+				conversationContext.clear();
+				synchronized (this)
+				{
+					conversationContexts.remove(conversationContextId);
 				}
 			}
 		}

Modified: myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/jsf/filter/OrchestraServletFilter.java
URL: http://svn.apache.org/viewvc/myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/jsf/filter/OrchestraServletFilter.java?view=diff&rev=553490&r1=553489&r2=553490
==============================================================================
--- myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/jsf/filter/OrchestraServletFilter.java (original)
+++ myfaces/orchestra/trunk/core/src/main/java/org/apache/myfaces/orchestra/conversation/jsf/filter/OrchestraServletFilter.java Thu Jul  5 06:03:38 2007
@@ -43,6 +43,7 @@
 	 * Default: true
 	 */
 	public final static String SERIALIZE_REQUESTS = "serializeRequests"; // NON-NLS
+	private final static String CONTEXT_MUTEXT_OBJECT = OrchestraServletFilter.class.getName() + ".SER_MUTEX";
 
 	private static ThreadLocal httpServletRequest = new ThreadLocal();
 	private static ThreadLocal httpServletResponse = new ThreadLocal();
@@ -71,18 +72,30 @@
 				httpServletResponse.set(servletResponse);
 			}
 
-			ConversationContext conversationContext = null;
+			Object mutex = null;
 			if (serializeRequests)
 			{
 				ConversationManager manager = ConversationManager.getInstance(false);
 				if (manager != null)
 				{
-					conversationContext = manager.getCurrentConversationContext();
+					ConversationContext conversationContext = manager.getCurrentConversationContext();
+					if (conversationContext != null)
+					{
+						synchronized(conversationContext)
+						{
+							mutex = conversationContext.getAttribute(CONTEXT_MUTEXT_OBJECT);
+							if (mutex == null)
+							{
+								mutex = new Object();
+								conversationContext.setAttribute(CONTEXT_MUTEXT_OBJECT, mutex);
+							}
+						}
+					}
 				}
 			}
-			if (serializeRequests && conversationContext != null)
+			if (serializeRequests && mutex != null)
 			{
-				synchronized(conversationContext)
+				synchronized(mutex)
 				{
 					filterChain.doFilter(servletRequest, servletResponse);
 				}