]> source.dussan.org Git - vaadin-framework.git/commitdiff
Verify that lock is held when accessing state (#9515)
authorLeif Åstrand <leif@vaadin.com>
Sun, 9 Sep 2012 19:16:51 +0000 (22:16 +0300)
committerLeif Åstrand <leif@vaadin.com>
Sun, 9 Sep 2012 19:16:51 +0000 (22:16 +0300)
server/src/com/vaadin/server/AbstractClientConnector.java
server/src/com/vaadin/server/VaadinSession.java
server/src/com/vaadin/ui/ConnectorTracker.java
server/tests/src/com/vaadin/tests/data/converter/ConverterFactory.java
server/tests/src/com/vaadin/tests/server/component/abstractfield/AbstractFieldValueConversions.java
server/tests/src/com/vaadin/tests/server/component/abstractfield/RemoveListenersOnDetach.java

index 4c22a96782150bd110a5e6aca5e4c752777c0773..2fb468bd1cc8007be8be240906e5f1a519b2bedb 100644 (file)
@@ -146,6 +146,8 @@ public abstract class AbstractClientConnector implements ClientConnector {
     }
 
     protected SharedState getState() {
+        assert getSession() == null
+                || getSession().getLock().isHeldByCurrentThread() : VaadinSession.SESSION_LOCK_MESSAGE;
         if (null == sharedState) {
             sharedState = createState();
         }
index a91c011ddfce6653012cb771fa2065e70ac33a0a..03e64200080896eab85ce31e1eb3de60057c3de2 100644 (file)
@@ -28,7 +28,6 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
-import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.logging.Logger;
 
@@ -71,6 +70,8 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
      */
     public static final String UI_PARAMETER = "UI";
 
+    public static final String SESSION_LOCK_MESSAGE = "You are accessing UI state without proper synchronization!";
+
     private static final Method BOOTSTRAP_FRAGMENT_METHOD = ReflectTools
             .findMethod(BootstrapListener.class, "modifyBootstrapFragment",
                     BootstrapFragmentResponse.class);
@@ -78,7 +79,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
             .findMethod(BootstrapListener.class, "modifyBootstrapPage",
                     BootstrapPageResponse.class);
 
-    private final Lock lock = new ReentrantLock();
+    private final ReentrantLock lock = new ReentrantLock();
 
     /**
      * An event sent to {@link #start(SessionStartEvent)} when a new Application
@@ -206,6 +207,10 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
 
     private final Map<String, Object> attributes = new HashMap<String, Object>();
 
+    public VaadinSession() {
+        // TODO Auto-generated constructor stub
+    }
+
     /**
      * @see javax.servlet.http.HttpSessionBindingListener#valueBound(HttpSessionBindingEvent)
      */
@@ -1304,7 +1309,7 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
      * 
      * @return the lock that should be used for synchronization
      */
-    public Lock getLock() {
+    public ReentrantLock getLock() {
         return lock;
     }
 
index d454df98ee4e08b2579c2c37625fd73719fd06b9..dbada63a4770060e77f38d80d83fcdbe2d677cb1 100644 (file)
@@ -29,6 +29,7 @@ import com.vaadin.server.AbstractClientConnector;
 import com.vaadin.server.AbstractCommunicationManager;
 import com.vaadin.server.ClientConnector;
 import com.vaadin.server.GlobalResourceHandler;
+import com.vaadin.server.VaadinSession;
 
 /**
  * A class which takes care of book keeping of {@link ClientConnector}s for a
@@ -286,6 +287,8 @@ public class ConnectorTracker implements Serializable {
      *            The connector that should be marked clean.
      */
     public void markDirty(ClientConnector connector) {
+        assert uI.getSession() == null
+                || uI.getSession().getLock().isHeldByCurrentThread() : VaadinSession.SESSION_LOCK_MESSAGE;
         if (isWritingResponse()) {
             throw new IllegalStateException(
                     "A connector should not be marked as dirty while a response is being written.");
index b64514ea14687c4c7464a88f2dd9a7b17a10cfd1..bc5846acf002b92aa1b2303e3b878345fc498fa1 100644 (file)
@@ -69,6 +69,7 @@ public class ConverterFactory extends TestCase {
         final VaadinSession appWithCustomIntegerConverter = new VaadinSession();
         appWithCustomIntegerConverter
                 .setConverterFactory(new ConverterFactory42());
+        appWithCustomIntegerConverter.getLock().lock();
 
         TextField tf = new TextField("", "123") {
             @Override
@@ -97,6 +98,7 @@ public class ConverterFactory extends TestCase {
 
     public void testApplicationConverterFactoryForDifferentThanCurrentApplication() {
         final VaadinSession fieldAppWithCustomIntegerConverter = new VaadinSession();
+        fieldAppWithCustomIntegerConverter.getLock().lock();
         fieldAppWithCustomIntegerConverter
                 .setConverterFactory(new ConverterFactory42());
         VaadinSession.setCurrent(new VaadinSession());
index b48ad62bccb384fd6cf09a00c65d88f2ae3241a0..031e0c80bdb7a2e809ec098be4ee3e5e09f996ed 100644 (file)
@@ -187,6 +187,7 @@ public class AbstractFieldValueConversions extends TestCase {
 
     public void testNumberDoubleConverterChange() {
         final VaadinSession a = new VaadinSession();
+        a.getLock().lock();
         VaadinSession.setCurrent(a);
         TextField tf = new TextField() {
             @Override
index c9f579a88724355d5679a4940bf0ff0475cc42c4..f259e156ffa7ca6e464416f2309925fe75768841 100644 (file)
@@ -19,10 +19,11 @@ public class RemoveListenersOnDetach {
 
     AbstractField field = new AbstractField() {
         final private VaadinSession application = new VaadinSession() {
-
+            {
+                getLock().lock();
+            }
         };
         private UI uI = new UI() {
-
             @Override
             protected void init(WrappedRequest request) {