Wait for connection stop before allowing a pending start to proceed

This commit is contained in:
Cameron Gutman 2017-11-05 13:46:56 -08:00
parent ba5c026bff
commit e5d9da447c

View File

@ -4,6 +4,7 @@ import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.concurrent.Semaphore;
import javax.crypto.KeyGenerator; import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
@ -27,6 +28,7 @@ public class NvConnection {
private LimelightCryptoProvider cryptoProvider; private LimelightCryptoProvider cryptoProvider;
private String uniqueId; private String uniqueId;
private ConnectionContext context; private ConnectionContext context;
private static Semaphore connectionAllowed = new Semaphore(1);
public NvConnection(String host, String uniqueId, StreamConfiguration config, LimelightCryptoProvider cryptoProvider) public NvConnection(String host, String uniqueId, StreamConfiguration config, LimelightCryptoProvider cryptoProvider)
{ {
@ -70,6 +72,9 @@ public class NvConnection {
MoonBridge.stopConnection(); MoonBridge.stopConnection();
MoonBridge.cleanupBridge(); MoonBridge.cleanupBridge();
} }
// Now a pending connection can be processed
connectionAllowed.release();
} }
private boolean startApp() throws XmlPullParserException, IOException private boolean startApp() throws XmlPullParserException, IOException
@ -237,11 +242,21 @@ public class NvConnection {
ByteBuffer ib = ByteBuffer.allocate(16); ByteBuffer ib = ByteBuffer.allocate(16);
ib.putInt(context.riKeyId); ib.putInt(context.riKeyId);
// Acquire the connection semaphore to ensure we only have one
// connection going at once.
try {
connectionAllowed.acquire();
} catch (InterruptedException e) {
context.connListener.displayMessage(e.getMessage());
context.connListener.stageFailed(appName, 0);
return;
}
// Moonlight-core is not thread-safe with respect to connection start and stop, so // Moonlight-core is not thread-safe with respect to connection start and stop, so
// we must not invoke that functionality in parallel. // we must not invoke that functionality in parallel.
synchronized (MoonBridge.class) { synchronized (MoonBridge.class) {
MoonBridge.setupBridge(videoDecoderRenderer, audioRenderer, connectionListener); MoonBridge.setupBridge(videoDecoderRenderer, audioRenderer, connectionListener);
MoonBridge.startConnection(context.serverAddress, int ret = MoonBridge.startConnection(context.serverAddress,
context.serverAppVersion, context.serverGfeVersion, context.serverAppVersion, context.serverGfeVersion,
context.negotiatedWidth, context.negotiatedHeight, context.negotiatedWidth, context.negotiatedHeight,
context.negotiatedFps, context.streamConfig.getBitrate(), context.negotiatedFps, context.streamConfig.getBitrate(),
@ -251,6 +266,12 @@ public class NvConnection {
context.streamConfig.getHevcBitratePercentageMultiplier(), context.streamConfig.getHevcBitratePercentageMultiplier(),
context.riKey.getEncoded(), ib.array(), context.riKey.getEncoded(), ib.array(),
context.videoCapabilities); context.videoCapabilities);
if (ret != 0) {
// LiStartConnection() failed, so the caller is not expected
// to stop the connection themselves. We need to release their
// semaphore count for them.
connectionAllowed.release();
}
} }
} }
}).start(); }).start();