WICKET-5508 Memory model improvements for Session fields

Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/c78379f4
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/c78379f4
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/c78379f4

Branch: refs/heads/sandbox/component-queueing-2
Commit: c78379f4ba3fdd58c574a610db3e85e616860d10
Parents: 87df7f4
Author: Martin Tzvetanov Grigorov <[email protected]>
Authored: Tue Feb 18 10:13:20 2014 +0200
Committer: Martin Tzvetanov Grigorov <[email protected]>
Committed: Tue Feb 18 10:13:20 2014 +0200

----------------------------------------------------------------------
 .../main/java/org/apache/wicket/Session.java    | 86 +++++++++++++-------
 1 file changed, 55 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/wicket/blob/c78379f4/wicket-core/src/main/java/org/apache/wicket/Session.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/Session.java 
b/wicket-core/src/main/java/org/apache/wicket/Session.java
index 37de3f3..147351b 100644
--- a/wicket-core/src/main/java/org/apache/wicket/Session.java
+++ b/wicket-core/src/main/java/org/apache/wicket/Session.java
@@ -23,6 +23,8 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.wicket.application.IClassResolver;
 import org.apache.wicket.authorization.IAuthorizationStrategy;
@@ -40,6 +42,7 @@ import org.apache.wicket.session.ISessionStore;
 import org.apache.wicket.util.IProvider;
 import org.apache.wicket.util.LazyInitializer;
 import org.apache.wicket.util.io.IClusterable;
+import org.apache.wicket.util.lang.Args;
 import org.apache.wicket.util.lang.Objects;
 import org.apache.wicket.util.time.Duration;
 import org.slf4j.Logger;
@@ -114,10 +117,10 @@ public abstract class Session implements IClusterable, 
IEventSink
        public static final String SESSION_ATTRIBUTE_NAME = "session";
 
        /** a sequence used for whenever something session-specific needs a 
unique value */
-       private int sequence = 1;
+       private final AtomicInteger sequence = new AtomicInteger(1);
 
        /** a sequence used for generating page IDs */
-       private int pageId = 0;
+       private final AtomicInteger pageId = new AtomicInteger(0);
 
        /** synchronize page's access by session */
        private final IProvider<PageAccessSynchronizer> pageAccessSynchronizer;
@@ -174,7 +177,7 @@ public abstract class Session implements IClusterable, 
IEventSink
        protected ClientInfo clientInfo;
 
        /** True if session state has been changed */
-       private transient boolean dirty = false;
+       private transient volatile boolean dirty = false;
 
        /** feedback messages */
        private final FeedbackMessages feedbackMessages = new 
FeedbackMessages();
@@ -183,13 +186,13 @@ public abstract class Session implements IClusterable, 
IEventSink
        private String id = null;
 
        /** The locale to use when loading resources for this session. */
-       private Locale locale;
+       private final AtomicReference<Locale> locale;
 
        /** Application level meta data. */
        private MetaDataEntry<?>[] metaData;
 
        /** True, if session has been invalidated */
-       private transient boolean sessionInvalidated = false;
+       private transient volatile boolean sessionInvalidated = false;
 
        /**
         * Temporary instance of the session store. Should be set on each 
request as it is not supposed
@@ -198,7 +201,7 @@ public abstract class Session implements IClusterable, 
IEventSink
        private transient ISessionStore sessionStore;
 
        /** Any special "skin" style to use when loading resources. */
-       private String style;
+       private final AtomicReference<String> style = new AtomicReference<>();
 
        /**
         * Holds attributes for sessions that are still temporary/ not bound to 
a session store. Only
@@ -219,12 +222,13 @@ public abstract class Session implements IClusterable, 
IEventSink
         */
        public Session(Request request)
        {
-               locale = request.getLocale();
+               Locale locale = request.getLocale();
                if (locale == null)
                {
                        throw new IllegalStateException(
                                "Request#getLocale() cannot return null, 
request has to have a locale set on it");
                }
+               this.locale = new AtomicReference<>(locale);
 
                pageAccessSynchronizer = new PageAccessSynchronizerProvider();
        }
@@ -402,7 +406,7 @@ public abstract class Session implements IClusterable, 
IEventSink
         */
        public Locale getLocale()
        {
-               return locale;
+               return locale.get();
        }
 
        /**
@@ -443,7 +447,7 @@ public abstract class Session implements IClusterable, 
IEventSink
         */
        public final String getStyle()
        {
-               return style;
+               return style.get();
        }
 
        /**
@@ -565,15 +569,13 @@ public abstract class Session implements IClusterable, 
IEventSink
         */
        public Session setLocale(final Locale locale)
        {
-               if (locale == null)
-               {
-                       throw new IllegalArgumentException("Argument 'locale' 
must not be null");
-               }
-               if (!Objects.equal(this.locale, locale))
+               Args.notNull(locale, "locale");
+
+               if (!Objects.equal(getLocale(), locale))
                {
+                       this.locale.set(locale);
                        dirty();
                }
-               this.locale = locale;
                return this;
        }
 
@@ -605,8 +607,11 @@ public abstract class Session implements IClusterable, 
IEventSink
         */
        public final Session setStyle(final String style)
        {
-               this.style = style;
-               dirty();
+               if (!Objects.equal(getStyle(), style))
+               {
+                       this.style.set(style);
+                       dirty();
+               }
                return this;
        }
 
@@ -682,11 +687,36 @@ public abstract class Session implements IClusterable, 
IEventSink
        }
 
        /**
-        * Marks session state as dirty so that it will be flushed at the end 
of the request.
+        * Marks session state as dirty so that it will be (re)stored in the 
ISessionStore
+        * at the end of the request.
+        * <strong>Note</strong>: binds the session if it is temporary
         */
        public final void dirty()
        {
-               dirty = true;
+               dirty(true);
+       }
+
+       /**
+        * Marks session state as dirty so that it will be re-stored in the 
ISessionStore
+        * at the end of the request.
+        *
+        * @param forced
+        *          A flag indicating whether the session should be marked as 
dirty even
+        *          when it is temporary. If {@code true} the Session will be 
bound.
+        */
+       public final void dirty(boolean forced)
+       {
+               if (isTemporary())
+               {
+                       if (forced)
+                       {
+                               dirty = true;
+                       }
+               }
+               else
+               {
+                       dirty = true;
+               }
        }
 
        /**
@@ -839,26 +869,20 @@ public abstract class Session implements IClusterable, 
IEventSink
         * 
         * @return session-unique value
         */
-       public synchronized int nextSequenceValue()
+       public int nextSequenceValue()
        {
-               if (isTemporary() == false)
-               {
-                       dirty();
-               }
-               return sequence++;
+               dirty(false);
+               return sequence.getAndIncrement();
        }
 
        /**
         * 
         * @return the next page id
         */
-       public synchronized int nextPageId()
+       public int nextPageId()
        {
-               if (isTemporary() == false)
-               {
-                       dirty();
-               }
-               return pageId++;
+               dirty(false);
+               return pageId.getAndIncrement();
        }
 
        /**

Reply via email to