Fix race condition when stopDiscovery() is called during onServiceFound()/onServiceLost()

This commit is contained in:
Cameron Gutman
2023-07-25 18:46:31 -05:00
parent 67b2853ef0
commit 554fee037c
@@ -20,13 +20,13 @@ import java.util.concurrent.TimeUnit;
@TargetApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public class NsdManagerDiscoveryAgent extends MdnsDiscoveryAgent {
private static final String SERVICE_TYPE = "_nvstream._tcp";
private NsdManager nsdManager;
private final NsdManager nsdManager;
private boolean discoveryActive;
private boolean wantsDiscoveryActive;
private final HashMap<String, NsdManager.ServiceInfoCallback> serviceCallbacks = new HashMap<>();
private final ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
private NsdManager.DiscoveryListener discoveryListener = new NsdManager.DiscoveryListener() {
private final NsdManager.DiscoveryListener discoveryListener = new NsdManager.DiscoveryListener() {
@Override
public void onStartDiscoveryFailed(String serviceType, int errorCode) {
discoveryActive = false;
@@ -63,6 +63,13 @@ public class NsdManagerDiscoveryAgent extends MdnsDiscoveryAgent {
@Override
public void onServiceFound(NsdServiceInfo nsdServiceInfo) {
// Protect against racing stopDiscovery() call
synchronized (serviceCallbacks) {
// Bail if we've been stopped
if (!wantsDiscoveryActive) {
return;
}
LimeLog.info("NSD: Machine appeared: "+nsdServiceInfo.getServiceName());
NsdManager.ServiceInfoCallback serviceInfoCallback = new NsdManager.ServiceInfoCallback() {
@@ -90,9 +97,17 @@ public class NsdManagerDiscoveryAgent extends MdnsDiscoveryAgent {
nsdManager.registerServiceInfoCallback(nsdServiceInfo, executor, serviceInfoCallback);
serviceCallbacks.put(nsdServiceInfo.getServiceName(), serviceInfoCallback);
}
}
@Override
public void onServiceLost(NsdServiceInfo nsdServiceInfo) {
// Protect against racing stopDiscovery() call
synchronized (serviceCallbacks) {
// Bail if we've been stopped
if (!wantsDiscoveryActive) {
return;
}
LimeLog.info("NSD: Machine lost: " + nsdServiceInfo.getServiceName());
NsdManager.ServiceInfoCallback serviceInfoCallback = serviceCallbacks.remove(nsdServiceInfo.getServiceName());
@@ -100,6 +115,7 @@ public class NsdManagerDiscoveryAgent extends MdnsDiscoveryAgent {
nsdManager.unregisterServiceInfoCallback(serviceInfoCallback);
}
}
}
};
public NsdManagerDiscoveryAgent(Context context, MdnsDiscoveryListener listener) {
@@ -119,6 +135,8 @@ public class NsdManagerDiscoveryAgent extends MdnsDiscoveryAgent {
@Override
public void stopDiscovery() {
// Protect against racing ServiceInfoCallback and DiscoveryListener callbacks
synchronized (serviceCallbacks) {
wantsDiscoveryActive = false;
// Unregister the service discovery listener
@@ -132,6 +150,7 @@ public class NsdManagerDiscoveryAgent extends MdnsDiscoveryAgent {
}
serviceCallbacks.clear();
}
}
private static Inet4Address[] getV4Addrs(List<InetAddress> addrs) {
int matchCount = 0;