diff options
author | Tatu Lund <tatu@vaadin.com> | 2021-08-09 13:22:58 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-09 13:22:58 +0300 |
commit | 308c6e46b48a3d48428d933e37b1ef5e4509e0ae (patch) | |
tree | e95e302bbfdeddacf277192587a1de6e7b2e52ca /server | |
parent | 0000c0ef34eaba6da9a10d6298cbf2963991b618 (diff) | |
download | vaadin-framework-7.7.27.tar.gz vaadin-framework-7.7.27.zip |
fix: Prevent deadlock in findOrCreateVaadinSession (#12353)7.7.27
Diffstat (limited to 'server')
-rw-r--r-- | server/src/main/java/com/vaadin/server/VaadinService.java | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/server/src/main/java/com/vaadin/server/VaadinService.java b/server/src/main/java/com/vaadin/server/VaadinService.java index bb9c2de803..f6e21f6776 100644 --- a/server/src/main/java/com/vaadin/server/VaadinService.java +++ b/server/src/main/java/com/vaadin/server/VaadinService.java @@ -604,14 +604,23 @@ public abstract class VaadinService implements Serializable { /** * Locks the given session for this service instance. Typically you want to * call {@link VaadinSession#lock()} instead of this method. - * + * <p> + * Note: The method and its signature has been changed to return lock + * instance in Vaadin 7.7.27. If you have overriden this method, you need + * to update your implementation. + * <p> + * Note: Overriding this method is not recommended, for custom lock storage + * strategy override {@link #getSessionLock(WrappedSession)} and + * {@link #setSessionLock(WrappedSession,Lock)} instead. + * * @param wrappedSession * The session to lock - * + * @return Lock instance + * * @throws IllegalStateException * if the session is invalidated before it can be locked */ - protected void lockSession(WrappedSession wrappedSession) { + protected Lock lockSession(WrappedSession wrappedSession) { Lock lock = getSessionLock(wrappedSession); if (lock == null) { /* @@ -641,21 +650,30 @@ public abstract class VaadinService implements Serializable { lock.unlock(); throw e; } + return lock; } /** * Releases the lock for the given session for this service instance. * Typically you want to call {@link VaadinSession#unlock()} instead of this * method. + * <p> + * Note: The method and its signature has been changed to get lock instance + * as parameter in Vaadin 7.7.27. If you have overriden this method, you need + * to update your implementation. + * <p> + * Note: Overriding this method is not recommended, for custom lock storage + * strategy override {@link #getSessionLock(WrappedSession)} and + * {@link #setSessionLock(WrappedSession,Lock)} instead. * * @param wrappedSession - * The session to unlock + * The session to unlock, used only with assert + * @param lock + * Lock instance to unlock */ - protected void unlockSession(WrappedSession wrappedSession) { - assert getSessionLock(wrappedSession) != null; - assert ((ReentrantLock) getSessionLock(wrappedSession)) - .isHeldByCurrentThread() : "Trying to unlock the session but it has not been locked by this thread"; - getSessionLock(wrappedSession).unlock(); + protected void unlockSession(WrappedSession wrappedSession, Lock lock) { + assert ((ReentrantLock) lock).isHeldByCurrentThread() : "Trying to unlock the session but it has not been locked by this thread"; + lock.unlock(); } private VaadinSession findOrCreateVaadinSession(VaadinRequest request) @@ -664,8 +682,9 @@ public abstract class VaadinService implements Serializable { WrappedSession wrappedSession = getWrappedSession(request, requestCanCreateSession); + final Lock lock; try { - lockSession(wrappedSession); + lock = lockSession(wrappedSession); } catch (IllegalStateException e) { throw new SessionExpiredException(); } @@ -674,7 +693,7 @@ public abstract class VaadinService implements Serializable { return doFindOrCreateVaadinSession(request, requestCanCreateSession); } finally { - unlockSession(wrappedSession); + unlockSession(wrappedSession, lock); } } |