Fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=473558
Change-Id: I97587098ffe5917e3b4f8a6310af81aa13e9ec1b
diff --git a/providers/bundles/org.eclipse.ecf.provider.jmdns/META-INF/MANIFEST.MF b/providers/bundles/org.eclipse.ecf.provider.jmdns/META-INF/MANIFEST.MF
index 0a2653b..0b303bd 100644
--- a/providers/bundles/org.eclipse.ecf.provider.jmdns/META-INF/MANIFEST.MF
+++ b/providers/bundles/org.eclipse.ecf.provider.jmdns/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.ecf.provider.jmdns;singleton:=true
-Bundle-Version: 4.3.0.qualifier
+Bundle-Version: 4.3.100.qualifier
Bundle-Activator: org.eclipse.ecf.internal.provider.jmdns.JMDNSPlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin
diff --git a/providers/bundles/org.eclipse.ecf.provider.jmdns/src/org/eclipse/ecf/provider/jmdns/container/JMDNSDiscoveryContainer.java b/providers/bundles/org.eclipse.ecf.provider.jmdns/src/org/eclipse/ecf/provider/jmdns/container/JMDNSDiscoveryContainer.java
index 2923877..80f06a0 100644
--- a/providers/bundles/org.eclipse.ecf.provider.jmdns/src/org/eclipse/ecf/provider/jmdns/container/JMDNSDiscoveryContainer.java
+++ b/providers/bundles/org.eclipse.ecf.provider.jmdns/src/org/eclipse/ecf/provider/jmdns/container/JMDNSDiscoveryContainer.java
@@ -51,7 +51,6 @@
*/
final Map services = Collections.synchronizedMap(new HashMap());
- boolean disposed = false;
final Object lock = new Object();
SimpleFIFOQueue queue = null;
@@ -75,64 +74,62 @@
}
/* (non-Javadoc)
- * @see org.eclipse.ecf.discovery.AbstractDiscoveryContainerAdapter#dispose()
- */
- public void dispose() {
- synchronized (lock) {
- super.dispose();
- disposed = true;
- }
- }
-
- /* (non-Javadoc)
* @see org.eclipse.ecf.core.IContainer#connect(org.eclipse.ecf.core.identity.ID, org.eclipse.ecf.core.security.IConnectContext)
*/
public void connect(final ID targetID1, final IConnectContext joinContext) throws ContainerConnectException {
synchronized (lock) {
- if (disposed)
- throw new ContainerConnectException("Container has been disposed"); //$NON-NLS-1$
if (this.targetID != null)
throw new ContainerConnectException("Already connected"); //$NON-NLS-1$
this.targetID = (targetID1 == null) ? getConfig().getID() : targetID1;
fireContainerEvent(new ContainerConnectingEvent(this.getID(), this.targetID, joinContext));
- initializeQueue();
+ // initialize queue and JMDNS discovery thread
+ queue = new SimpleFIFOQueue();
+ notificationThread = new Thread(new Runnable() {
+ public void run() {
+ while (!queue.isStopped()) {
+ if (Thread.currentThread().isInterrupted())
+ break;
+ final Runnable runnable = (Runnable) queue.dequeue();
+ if (Thread.currentThread().isInterrupted() || runnable == null)
+ break;
+ try {
+ runnable.run();
+ } catch (final Throwable t) {
+ JMDNSPlugin plugin = JMDNSPlugin.getDefault();
+ if (plugin != null)
+ plugin.logException("JMDNS.handleNotificationThreadException", t); //$NON-NLS-1$
+ }
+ }
+ }
+ }, "JMDNS Discovery Thread"); //$NON-NLS-1$
+ notificationThread.start();
+ // Create JmDNS and add type listener
try {
this.jmdns = JmDNS.create();
jmdns.addServiceTypeListener(this);
} catch (final IOException e) {
Trace.catching(JMDNSPlugin.PLUGIN_ID, JMDNSDebugOptions.EXCEPTIONS_CATCHING, this.getClass(), "connect", e); //$NON-NLS-1$
- if (this.jmdns != null) {
- jmdns.close();
- jmdns = null;
- }
+ doCleanup();
throw new ContainerConnectException("Cannot create JmDNS instance", e); //$NON-NLS-1$
}
fireContainerEvent(new ContainerConnectedEvent(this.getID(), this.targetID));
}
}
- private void initializeQueue() {
- queue = new SimpleFIFOQueue();
- notificationThread = new Thread(new Runnable() {
- public void run() {
- while (!disposed || queue.isStopped()) {
- if (Thread.currentThread().isInterrupted())
- break;
- final Runnable runnable = (Runnable) queue.dequeue();
- if (Thread.currentThread().isInterrupted() || runnable == null)
- break;
- try {
- runnable.run();
- } catch (final Throwable t) {
- JMDNSPlugin plugin = JMDNSPlugin.getDefault();
- if (plugin != null) {
- plugin.logException("handleRuntimeException", t); //$NON-NLS-1$
- }
- }
- }
- }
- }, "JMDNS Discovery Thread"); //$NON-NLS-1$
- notificationThread.start();
+ private void doCleanup() {
+ if (queue != null)
+ queue.close();
+ if (notificationThread != null) {
+ notificationThread.interrupt();
+ notificationThread = null;
+ }
+ this.targetID = null;
+ serviceTypes.clear();
+ // @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=385395
+ if (jmdns != null) {
+ jmdns.close();
+ jmdns = null;
+ }
}
/* (non-Javadoc)
@@ -140,21 +137,11 @@
*/
public void disconnect() {
synchronized (lock) {
- if (getConnectedID() == null || disposed) {
- return;
- }
final ID connectedID = getConnectedID();
+ if (connectedID == null)
+ return;
fireContainerEvent(new ContainerDisconnectingEvent(this.getID(), connectedID));
- queue.close();
- notificationThread.interrupt();
- notificationThread = null;
- this.targetID = null;
- serviceTypes.clear();
- // @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=385395
- if (jmdns != null) {
- jmdns.close();
- jmdns = null;
- }
+ doCleanup();
fireContainerEvent(new ContainerDisconnectedEvent(this.getID(), connectedID));
}
}
@@ -168,6 +155,8 @@
Assert.isNotNull(service);
synchronized (lock) {
try {
+ if (jmdns == null)
+ return null;
// ECF discovery API defines identity to be the service type and the URI (location)
// see https://bugs.eclipse.org/266723
final ServiceInfo[] serviceInfos = jmdns.list(service.getServiceTypeID().getInternal());
@@ -215,7 +204,7 @@
for (final Iterator itr = serviceTypes.iterator(); itr.hasNext();) {
final IServiceTypeID serviceType = (IServiceTypeID) itr.next();
if (Arrays.equals(serviceType.getServices(), type.getServices()) && Arrays.equals(serviceType.getProtocols(), type.getProtocols()) && Arrays.equals(serviceType.getScopes(), type.getScopes())) {
- final ServiceInfo[] infos = jmdns.list(type.getInternal());
+ final ServiceInfo[] infos = (jmdns == null) ? new ServiceInfo[0] : jmdns.list(type.getInternal());
for (int i = 0; i < infos.length; i++) {
try {
if (infos[i] != null) {
@@ -229,7 +218,7 @@
}
}
}
- return (IServiceInfo[]) serviceInfos.toArray(new IServiceInfo[] {});
+ return (IServiceInfo[]) serviceInfos.toArray(new IServiceInfo[serviceInfos.size()]);
}
}
@@ -238,7 +227,7 @@
*/
public IServiceTypeID[] getServiceTypes() {
synchronized (lock) {
- return (IServiceTypeID[]) serviceTypes.toArray(new IServiceTypeID[] {});
+ return (IServiceTypeID[]) serviceTypes.toArray(new IServiceTypeID[serviceTypes.size()]);
}
}
@@ -249,10 +238,13 @@
Assert.isNotNull(serviceInfo);
final ServiceInfo svcInfo = createServiceInfoFromIServiceInfo(serviceInfo);
checkServiceInfo(svcInfo);
- try {
- jmdns.registerService(svcInfo);
- } catch (final IOException e) {
- throw new ECFRuntimeException("Exception registering service", e); //$NON-NLS-1$
+ synchronized (lock) {
+ try {
+ if (jmdns != null)
+ jmdns.registerService(svcInfo);
+ } catch (final IOException e) {
+ throw new ECFRuntimeException("Exception registering service", e); //$NON-NLS-1$
+ }
}
}
@@ -262,14 +254,20 @@
public void unregisterService(final IServiceInfo serviceInfo) {
Assert.isNotNull(serviceInfo);
final ServiceInfo si = createServiceInfoFromIServiceInfo(serviceInfo);
- jmdns.unregisterService(si);
+ synchronized (lock) {
+ if (jmdns != null)
+ jmdns.unregisterService(si);
+ }
}
/* (non-Javadoc)
* @see org.eclipse.ecf.discovery.AbstractDiscoveryContainerAdapter#unregisterAllServices()
*/
public void unregisterAllServices() {
- jmdns.unregisterAllServices();
+ synchronized (lock) {
+ if (jmdns != null)
+ jmdns.unregisterAllServices();
+ }
}
/* (non-Javadoc)
@@ -311,9 +309,8 @@
final String serviceName = arg0.getName();
IServiceInfo aServiceInfo = null;
synchronized (lock) {
- if (getConnectedID() == null || disposed) {
+ if (getConnectedID() == null)
return;
- }
// explicitly get the service to determine the naming authority (part of the service properties)
try {
@@ -339,9 +336,8 @@
Trace.trace(JMDNSPlugin.PLUGIN_ID, "serviceRemoved(" + arg0.getName() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
runInThread(new Runnable() {
public void run() {
- if (getConnectedID() == null || disposed) {
+ if (getConnectedID() == null)
return;
- }
final String serviceType = arg0.getType();
final String serviceName = arg0.getName();
IServiceInfo aServiceInfo = (IServiceInfo) services.remove(serviceType + serviceName);