Jetty

Deadlock in AbstractSessionManager

Details

  • Type: Bug Bug
  • Status: Resolved Resolved
  • Priority: Blocker Blocker
  • Resolution: Fixed
  • Affects Version/s: 6.1.18
  • Fix Version/s: 6.1.23
  • Component/s: Servlet
  • Labels:
    None
  • Environment:
    Jetty 6.1.18 + Liferay 5.2.2
  • Number of attachments :
    1

Description

Looks pretty textbook deadlook to me. I think the _sessionIdManager should be the outermost lock through which threads arrive to do their stuff. In this case however the removeSession releases _sessionIdManager too early.

Found one Java-level deadlock:
=============================
"17758642@qtp-24109300-249":
waiting to lock monitor 0x096d883c (object 0x5c17ce90, a org.mortbay.jetty.servlet.HashSessionIdManager),
which is held by "Timer-3"
"Timer-3":
waiting to lock monitor 0x0b997a1c (object 0x60d4c980, a java.util.HashMap),
which is held by "Timer-6"
"Timer-6":
waiting to lock monitor 0x096d883c (object 0x5c17ce90, a org.mortbay.jetty.servlet.HashSessionIdManager),
which is held by "Timer-3"

Java stack information for the threads listed above:
===================================================
"17758642@qtp-24109300-249":
at org.mortbay.jetty.servlet.HashSessionIdManager.newSessionId(HashSessionIdManager.java:219)

  • waiting to lock <0x5c17ce90> (a org.mortbay.jetty.servlet.HashSessionIdManager)
    at org.mortbay.jetty.servlet.AbstractSessionManager$Session.<init>(AbstractSessionManager.java:753)
    at org.mortbay.jetty.servlet.HashSessionManager$Session.<init>(HashSessionManager.java:511)
    at org.mortbay.jetty.servlet.HashSessionManager.newSession(HashSessionManager.java:345)
    at org.mortbay.jetty.servlet.AbstractSessionManager.newHttpSession(AbstractSessionManager.java:413)
    at org.mortbay.jetty.Request.getSession(Request.java:1158)
    at org.mortbay.jetty.Request.getSession(Request.java:1130)
    at com.liferay.portal.servlet.filters.virtualhost.VirtualHostFilter.doFilter(VirtualHostFilter.java:118)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1148)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:154)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:94)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1148)
    at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:738)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1148)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:387)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:417)
    at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
    at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:534)
    at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:864)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:390)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:212)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:520)
    "Timer-3":
    at com.liferay.portal.kernel.servlet.PortletSessionTracker._invalidate(PortletSessionTracker.java:90)
  • waiting to lock <0x60d4c980> (a java.util.HashMap)
    at com.liferay.portal.kernel.servlet.PortletSessionTracker.invalidate(PortletSessionTracker.java:59)
    at com.liferay.portal.kernel.servlet.PortletSessionTracker.valueUnbound(PortletSessionTracker.java:66)
    at org.mortbay.jetty.servlet.AbstractSessionManager$Session.unbindValue(AbstractSessionManager.java:1129)
    at org.mortbay.jetty.servlet.AbstractSessionManager$Session.removeAttribute(AbstractSessionManager.java:1023)
  • locked <0x6dfb98a8> (a org.mortbay.jetty.servlet.HashSessionManager$Session)
    at com.liferay.portal.servlet.PortalSessionListener.sessionDestroyed(PortalSessionListener.java:124)
    at org.mortbay.jetty.servlet.AbstractSessionManager.removeSession(AbstractSessionManager.java:665)
    at org.mortbay.jetty.servlet.AbstractSessionManager$Session.invalidate(AbstractSessionManager.java:938)
    at org.mortbay.jetty.servlet.HashSessionManager$Session.invalidate(HashSessionManager.java:536)
    at org.mortbay.jetty.servlet.HashSessionIdManager.invalidateAll(HashSessionIdManager.java:198)
  • locked <0x5c17ce90> (a org.mortbay.jetty.servlet.HashSessionIdManager)
    at org.mortbay.jetty.servlet.AbstractSessionManager.removeSession(AbstractSessionManager.java:657)
  • locked <0x5c17ce90> (a org.mortbay.jetty.servlet.HashSessionIdManager)
    at org.mortbay.jetty.servlet.AbstractSessionManager$Session.timeout(AbstractSessionManager.java:922)
    at org.mortbay.jetty.servlet.HashSessionManager.scavenge(HashSessionManager.java:283)
    at org.mortbay.jetty.servlet.HashSessionManager.access$000(HashSessionManager.java:44)
    at org.mortbay.jetty.servlet.HashSessionManager$2.run(HashSessionManager.java:217)
    at java.util.TimerThread.mainLoop(Timer.java:512)
    at java.util.TimerThread.run(Timer.java:462)
    "Timer-6":
    at org.mortbay.jetty.servlet.AbstractSessionManager.removeSession(AbstractSessionManager.java:638)
  • waiting to lock <0x5c17ce90> (a org.mortbay.jetty.servlet.HashSessionIdManager)
    at org.mortbay.jetty.servlet.AbstractSessionManager$Session.invalidate(AbstractSessionManager.java:938)
    at org.mortbay.jetty.servlet.HashSessionManager$Session.invalidate(HashSessionManager.java:536)
    at com.liferay.util.servlet.SharedSessionWrapper.invalidate(SharedSessionWrapper.java:138)
    at com.liferay.portal.kernel.servlet.PortletSessionTracker._invalidate(PortletSessionTracker.java:100)
  • locked <0x60d4c980> (a java.util.HashMap)
    at com.liferay.portal.kernel.servlet.PortletSessionTracker.invalidate(PortletSessionTracker.java:59)
    at com.liferay.portal.kernel.servlet.PortletSessionTracker.valueUnbound(PortletSessionTracker.java:66)
    at org.mortbay.jetty.servlet.AbstractSessionManager$Session.unbindValue(AbstractSessionManager.java:1129)
    at org.mortbay.jetty.servlet.AbstractSessionManager$Session.removeAttribute(AbstractSessionManager.java:1023)
  • locked <0x6ca72ad0> (a org.mortbay.jetty.servlet.HashSessionManager$Session)
    at com.liferay.portal.servlet.PortalSessionListener.sessionDestroyed(PortalSessionListener.java:124)
    at org.mortbay.jetty.servlet.AbstractSessionManager.removeSession(AbstractSessionManager.java:665)
    at org.mortbay.jetty.servlet.AbstractSessionManager$Session.timeout(AbstractSessionManager.java:922)
    at org.mortbay.jetty.servlet.HashSessionManager.scavenge(HashSessionManager.java:283)
    at org.mortbay.jetty.servlet.HashSessionManager.access$000(HashSessionManager.java:44)
    at org.mortbay.jetty.servlet.HashSessionManager$2.run(HashSessionManager.java:217)
    at java.util.TimerThread.mainLoop(Timer.java:512)
    at java.util.TimerThread.run(Timer.java:462)

Found 1 deadlock.

I've fixed this by extending the synchronized (_sessionIdManager) block to cover a bit more of the removeSession method.

/* ------------------------------------------------------------ */
/** Remove session from manager

  • @param session The session to remove
  • @param invalidate True if {@link HttpSessionListener#sessionDestroyed(HttpSessionEvent)} and
  • {@link SessionIdManager#invalidateAll(String)} should be called.
    */
    public void removeSession(Session session, boolean invalidate)
    {
    // Remove session from context and global maps
    synchronized (_sessionIdManager)
    {
    boolean removed = false;

synchronized (this)
{
//take this session out of the map of sessions for this context
if (getSession(session.getClusterId()) != null)

{ removed = true; removeSession(session.getClusterId()); }

}

if (removed)

{ // Remove session from all context and global id maps _sessionIdManager.removeSession(session); if (invalidate) _sessionIdManager.invalidateAll(session.getClusterId()); }

if (invalidate && _sessionListeners!=null)

{ HttpSessionEvent event=new HttpSessionEvent(session); for (int i=LazyList.size(_sessionListeners); i-->0;) ((HttpSessionListener)LazyList.get(_sessionListeners,i)).sessionDestroyed(event); }

}
if (!invalidate)

{ session.willPassivate(); }

}

Activity

Hide
Janne Kario added a comment -

Extends the syncronization block in AbstractSessionManager removeSession to cover some more stuff.

Show
Janne Kario added a comment - Extends the syncronization block in AbstractSessionManager removeSession to cover some more stuff.
Hide
Jan Bartel added a comment -

Janne,

We've improved the locking on the SessionIdManager.invalidateAll() and AbstractSessionManager.removeSession() methods to reduce the amount of time that locks are held.

Could you retest against jetty-6.1 trunk and confirm if that solves your issue?

thanks,
Jan

Show
Jan Bartel added a comment - Janne, We've improved the locking on the SessionIdManager.invalidateAll() and AbstractSessionManager.removeSession() methods to reduce the amount of time that locks are held. Could you retest against jetty-6.1 trunk and confirm if that solves your issue? thanks, Jan
Hide
Jan Bartel added a comment -

Janne,

I've pushed a jetty 6.1 snapshot. Could you test out the changes to the synchronization in your environment and report back the results?

thanks
Jan

Show
Jan Bartel added a comment - Janne, I've pushed a jetty 6.1 snapshot. Could you test out the changes to the synchronization in your environment and report back the results? thanks Jan
Hide
Janne Kario added a comment -

Unfortunately I'm unable to test this right now because were pushing for a production release. However once the production environment is running smoothly we will upgrade Jetty in our test environment and re-run the tests. I will be sometime during March.

The problem manifests in a situation where there are lotsa simultaneous new sessions created and at the same time lot of session invalidations.

Show
Janne Kario added a comment - Unfortunately I'm unable to test this right now because were pushing for a production release. However once the production environment is running smoothly we will upgrade Jetty in our test environment and re-run the tests. I will be sometime during March. The problem manifests in a situation where there are lotsa simultaneous new sessions created and at the same time lot of session invalidations.
Hide
Greg Wilkins added a comment -

I'm marking this as fixed for now. Please re-open if you still have the problem.

Show
Greg Wilkins added a comment - I'm marking this as fixed for now. Please re-open if you still have the problem.

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: