/** * Acquire the lock so that the scene can be acted upon. * * <p>This returns null if the lock was just acquired, otherwise it returns {@link * Result.Status#SUCCESS} if the lock already belonged to that thread, or another instance (see * {@link Result#getStatus()}) if an error occurred. * * @param timeout the time to wait if another rendering is happening. * @return null if the lock was just acquire or another result depending on the state. * @throws IllegalStateException if the current context is different than the one owned by the * scene. */ private Result acquireLock(long timeout) { ReentrantLock lock = Bridge.getLock(); if (!lock.isHeldByCurrentThread()) { try { boolean acquired = lock.tryLock(timeout, TimeUnit.MILLISECONDS); if (!acquired) { return ERROR_TIMEOUT.createResult(); } } catch (InterruptedException e) { return ERROR_LOCK_INTERRUPTED.createResult(); } } else { // This thread holds the lock already. Checks that this wasn't for a different context. // If this is called by init, mContext will be null and so should sCurrentContext // anyway if (mContext != sCurrentContext) { throw new IllegalStateException( "Acquiring different scenes from same thread without releases"); } return SUCCESS.createResult(); } return null; }
/** * Checks that the lock is owned by the current thread and that the current context is the one * from this scene. * * @throws IllegalStateException if the current context is different than the one owned by the * scene, or if {@link #acquire(long)} was not called. */ protected void checkLock() { ReentrantLock lock = Bridge.getLock(); if (!lock.isHeldByCurrentThread()) { throw new IllegalStateException("scene must be acquired first. see #acquire(long)"); } if (sCurrentContext != mContext) { throw new IllegalStateException("Thread acquired a scene but is rendering a different one"); } }
/** Cleans up the scene after an action. */ public void release() { ReentrantLock lock = Bridge.getLock(); // with the use of finally blocks, it is possible to find ourself calling this // without a successful call to prepareScene. This test makes sure that unlock() will // not throw IllegalMonitorStateException. if (lock.isHeldByCurrentThread()) { tearDown(); lock.unlock(); } }