boolean stopUsing() { int finalState = shouldExpire() ? STATE_EXPIRED : STATE_NONE; if (!sessionState.compareAndSet(STATE_IN_USE, finalState)) { throw new AssertionError("Unexpected state change; currently " + sessionState.get()); } if (finalState == STATE_NONE) return true; expirationTracker.closeAndRestartExpiredSessionAsync(this); return false; }
/** * Tries to use this session. When the session is in use, it will not expire. * @return true if the session can be used; false if it has already expired. */ public boolean tryUse(boolean ignoreExpiration) { while (true) { int oldValue = sessionState.get(); if (oldValue == STATE_IN_USE) throw new AssertionError(this + " is already in use"); if (oldValue == STATE_EXPIRED) return false; int finalState = (!ignoreExpiration && shouldExpire()) ? STATE_EXPIRED : STATE_IN_USE; if (sessionState.compareAndSet(STATE_NONE, finalState)) { if (finalState == STATE_IN_USE) return true; // Restart asynchronously, don't block the caller. expirationTracker.closeAndRestartExpiredSessionAsync(this); return false; } } }
/** * Tries to expire and restart the session. * @param isAsync Whether the restart should happen asynchronously. * @return True if the session was, or will be restarted. */ public boolean tryExpire(boolean isAsync) throws Exception { if (expirationNs == null) return true; if (!shouldExpire()) return false; // Try to expire the session if it's not in use; if in use, bail. while (true) { if (sessionState.get() != STATE_NONE) return true; // returnAfterUse will take care of this if (sessionState.compareAndSet(STATE_NONE, STATE_EXPIRED)) { if (isAsync) { expirationTracker.closeAndRestartExpiredSessionAsync(this); } else { expirationTracker.closeAndRestartExpiredSession(this); } return true; } } }