/**
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.react.testing;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import com.facebook.react.bridge.NotThreadSafeBridgeIdleDebugListener;
/**
* Utility class that uses {@link NotThreadSafeBridgeIdleDebugListener} interface to allow callers
* to wait for the bridge to be idle.
*/
public class ReactBridgeIdleSignaler implements NotThreadSafeBridgeIdleDebugListener {
// Starts at 1 since bridge starts idle. The logic here is that the semaphore is only acquirable
// if the bridge is idle.
private final Semaphore mBridgeIdleSemaphore = new Semaphore(1);
private volatile boolean mIsBridgeIdle = true;
@Override
public void onTransitionToBridgeIdle() {
mIsBridgeIdle = true;
mBridgeIdleSemaphore.release();
}
@Override
public void onTransitionToBridgeBusy() {
mIsBridgeIdle = false;
try {
if (!mBridgeIdleSemaphore.tryAcquire(15000, TimeUnit.MILLISECONDS)) {
throw new RuntimeException(
"Timed out waiting to acquire the test idle listener semaphore. Deadlock?");
}
} catch (InterruptedException e) {
throw new RuntimeException("Got interrupted", e);
}
}
public boolean isBridgeIdle() {
return mIsBridgeIdle;
}
public boolean waitForIdle(long millis) {
try {
if (mBridgeIdleSemaphore.tryAcquire(millis, TimeUnit.MILLISECONDS)) {
mBridgeIdleSemaphore.release();
return true;
}
return false;
} catch (InterruptedException e) {
throw new RuntimeException("Got interrupted", e);
}
}
}