aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorTatu Lund <tatu@vaadin.com>2021-08-09 13:22:58 +0300
committerGitHub <noreply@github.com>2021-08-09 13:22:58 +0300
commit308c6e46b48a3d48428d933e37b1ef5e4509e0ae (patch)
treee95e302bbfdeddacf277192587a1de6e7b2e52ca /server
parent0000c0ef34eaba6da9a10d6298cbf2963991b618 (diff)
downloadvaadin-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.java41
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);
}
}