Browse Source

Make access() throw if another session is already locked (#11757)

Change-Id: Ic8571b0d078c3ff64e8b9914e55c51766ae49024
tags/7.1.0
Leif Åstrand 11 years ago
parent
commit
79e9ddc524

+ 19
- 0
server/src/com/vaadin/server/VaadinService.java View File

@@ -1540,6 +1540,25 @@ public abstract class VaadinService implements Serializable {
return false;
}

/**
* Checks that another {@link VaadinSession} instance is not locked. This is
* internally used by {@link VaadinSession#access(Runnable)} and
* {@link UI#access(Runnable)} to help avoid causing deadlocks.
*
* @since 7.1
* @param session
* the session that is being locked
* @throws IllegalStateException
* if the current thread holds the lock for another session
*/
public static void verifyNoOtherSessionLocked(VaadinSession session) {
VaadinSession otherSession = VaadinSession.getCurrent();
if (otherSession != null && otherSession != session) {
throw new IllegalStateException(
"Can't access session while another session is locked by the same thread. This restriction is intended to help avoid deadlocks.");
}
}

/**
* Verifies that the given CSRF token (aka double submit cookie) is valid
* for the given session. This is used to protect against Cross Site Request

+ 12
- 0
server/src/com/vaadin/server/VaadinSession.java View File

@@ -1075,15 +1075,27 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
* as the session is automatically locked by the framework during request
* handling.
* </p>
* <p>
* Note that calling this method while another session is locked by the
* current thread will cause an exception. This is to prevent deadlock
* situations when two threads have locked one session each and are both
* waiting for the lock for the other session.
* </p>
*
* @param runnable
* the runnable which accesses the session
*
* @throws IllegalStateException
* if the current thread holds the lock for another session
*
*
* @see #lock()
* @see #getCurrent()
* @see UI#access(Runnable)
*/
public void access(Runnable runnable) {
VaadinService.verifyNoOtherSessionLocked(this);

Map<Class<?>, CurrentInstance> old = null;
lock();
try {

+ 10
- 0
server/src/com/vaadin/ui/UI.java View File

@@ -1103,12 +1103,20 @@ public abstract class UI extends AbstractSingleComponentContainer implements
* RPC handlers for components inside this UI do not need this method as the
* session is automatically locked by the framework during request handling.
* </p>
* <p>
* Note that calling this method while another session is locked by the
* current thread will cause an exception. This is to prevent deadlock
* situations when two threads have locked one session each and are both
* waiting for the lock for the other session.
* </p>
*
* @param runnable
* the runnable which accesses the UI
* @throws UIDetachedException
* if the UI is not attached to a session (and locking can
* therefore not be done)
* @throws IllegalStateException
* if the current thread holds the lock for another session
*
* @see #getCurrent()
* @see VaadinSession#access(Runnable)
@@ -1123,6 +1131,8 @@ public abstract class UI extends AbstractSingleComponentContainer implements
throw new UIDetachedException();
}

VaadinService.verifyNoOtherSessionLocked(session);

session.lock();
try {
if (getSession() == null) {

Loading…
Cancel
Save