https://issues.apache.org/bugzilla/show_bug.cgi?id=46085
Summary: Session are incorrectly expired due to thread unsafe code Product: Tomcat 6 Version: 6.0.18 Platform: PC OS/Version: Linux Status: NEW Severity: major Priority: P2 Component: Catalina AssignedTo: dev@tomcat.apache.org ReportedBy: [EMAIL PROTECTED] We have identified a bug where sessions are expired even though they are still valid. The source of the problem is concurrent threads reading and writing thisAccessTime in "org.apache.catalina.session.StandardSession" in a way that is not thread safe. The good news is that we have a simple solution, for Tomcat 6. The fix is to mark the class level variables - thisAccessedTime and lastAccessedTime - as volatile. Detailed explanation of the bug: We found that StandardSession's isValid() function was making a call to expire() on the following block of code: if (maxInactiveInterval >= 0) { long timeNow = System.currentTimeMillis(); int timeIdle = (int) ((timeNow - thisAccessedTime) / 1000L); if (timeIdle >= maxInactiveInterval) { expire(true); } } Debugging showed that thisAccessedTime was in the past (1983!) and therefore timeIdle is large enough for expiry to happen. In another thread running in parallel, the access() function runs this line of code: this.thisAccessedTime = System.currentTimeMillis(); That single line of code might be atomic, i.e. is composed of multiple instructions, which means it is possible for another thread reading thisAccessedTime to read a value that is effectively corrupt. Marking thisAccessedTime as volatile ensures that writes are completely finished before reading is allowed. Note that the volatile solution only works for Java 1.5 or higher as the meaning of volatile changed then. That means it cannot be used for older Tomcat's if they have a similar problem. Another solution would have been to synchronize reads and writes to that variable. Reproducing the bug: This is quite hard within Tomcat as is very dependant on timings, the JVM's optimisations, and any changes to code may affect optimisations. We are only able to reproduce the bug on multiprocessor systems running an IBM JVM. Specifically, we are running: SLES 10.3 Linux on an Intel platform. Two or more Intel CPU's Tomcat 6.0.18 JVM package: java-1_5_0-ibm-1.5.0_sr8 ( https://svn.apache.org/viewcvs.cgi?view=rev&rev=8 )a-1.1 Initially, we thought that System.currentTimeMillis() was returning an incorrect value and created a test program which demo'd the problem to IBM. We were wrong but they did give us the volatile solution. See here: http://www.ibm.com/developerworks/forums/thread.jspa?threadID=230478 -- Configure bugmail: https://issues.apache.org/bugzilla/userprefs.cgi?tab=email ------- You are receiving this mail because: ------- You are the assignee for the bug. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]