diff options
author | Jeff Johnston | 2018-06-28 19:25:11 +0000 |
---|---|---|
committer | Jeff Johnston | 2018-07-03 19:22:58 +0000 |
commit | 2bcd06f097d1cc846baf8164705ff349843b8080 (patch) | |
tree | 5a34c23f4d2126a5885253f49421637a304fa658 | |
parent | 147335653fbcf669e5d324e5a31a1e3c4ad11b2e (diff) | |
download | org.eclipse.cdt-2bcd06f097d1cc846baf8164705ff349843b8080.tar.gz org.eclipse.cdt-2bcd06f097d1cc846baf8164705ff349843b8080.tar.xz org.eclipse.cdt-2bcd06f097d1cc846baf8164705ff349843b8080.zip |
Bug 536317 - Deadlock at start with launchbar and docker tooling enabled
- fix ContainerTargetTypeProvider changeEvent() to start a Job and
return immediately so it will not cause a DockerConnection
to be held in multi-threading
- move the DockerConnectionManager addConnectionListener call
to end of init() method so the fetching of images won't cause
a notification event to occur
- at end of init(), call CBuildConfigurationManager.recheckConfigs()
to make sure any disabled configuration due to a missing
IDockerConnection is now put in the configs master list and
removed from the noconfigs list
- make similar changes to ContainerGCCToolChainProvider
Change-Id: Idc120d613b99ec365522f5e7bf5da82d1b362425
2 files changed, 206 insertions, 135 deletions
diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerTargetTypeProvider.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerTargetTypeProvider.java index f529d427a35..297359f6762 100644 --- a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerTargetTypeProvider.java +++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/docker/launcher/ContainerTargetTypeProvider.java @@ -21,7 +21,11 @@ import org.eclipse.cdt.core.build.ICBuildConfigurationManager; import org.eclipse.cdt.core.build.ICBuildConfigurationManager2; import org.eclipse.cdt.debug.core.CDebugCorePlugin; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.launchbar.core.ILaunchBarManager; import org.eclipse.launchbar.core.target.ILaunchTarget; import org.eclipse.launchbar.core.target.ILaunchTargetManager; @@ -60,7 +64,6 @@ public class ContainerTargetTypeProvider } IDockerConnection[] connections = DockerConnectionManager.getInstance() .getConnections(); - DockerConnectionManager.getInstance().addConnectionManagerListener(this); Map<String, IDockerConnection> establishedConnectionMap = new HashMap<>(); Set<String> imageNames = new HashSet<>(); for (IDockerConnection connection : connections) { @@ -74,7 +77,9 @@ public class ContainerTargetTypeProvider for (IDockerImage image : images) { if (!image.isDangling() && !image.isIntermediateImage()) { String imageName = "[" //$NON-NLS-1$ - + image.repoTags().get(0).replace(':', '_') + "]"; //$NON-NLS-1$ + + image.repoTags().get(0).replace(':', '_') + // .replace('/', '_') + + "]"; //$NON-NLS-1$ if (imageNames.contains(imageName)) { imageName += "[" + connection.getName() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ } @@ -102,13 +107,29 @@ public class ContainerTargetTypeProvider // remove any launch targets for closed/disabled connections ILaunchTarget[] targets = targetManager.getLaunchTargetsOfType(TYPE_ID); for (ILaunchTarget target : targets) { - String uri = target.getAttribute( - IContainerLaunchTarget.ATTR_CONNECTION_URI, ""); //$NON-NLS-1$ - if (!establishedConnectionMap.containsKey(uri)) { - targetManager.removeLaunchTarget(target); + try { + String uri = target.getAttribute( + IContainerLaunchTarget.ATTR_CONNECTION_URI, ""); //$NON-NLS-1$ + if (!establishedConnectionMap.containsKey(uri)) { + targetManager.removeLaunchTarget(target); + } + } catch (IllegalStateException e) { + // ignore } } + // add a Docker Connection listener to handle enablement/disablement of + // Connections + DockerConnectionManager.getInstance() + .addConnectionManagerListener(this); + + // call the recheckConfigs method in case any disabled targets are now + // ok + ICBuildConfigurationManager mgr = CCorePlugin + .getService(ICBuildConfigurationManager.class); + ICBuildConfigurationManager2 manager = (ICBuildConfigurationManager2) mgr; + manager.recheckConfigs(); + try { launchbarManager.setActiveLaunchTarget(defaultTarget); } catch (CoreException e) { @@ -124,85 +145,105 @@ public class ContainerTargetTypeProvider } @Override - public synchronized void changeEvent(IDockerConnection connection, - int type) { - ICBuildConfigurationManager mgr = CCorePlugin - .getService(ICBuildConfigurationManager.class); - ICBuildConfigurationManager2 manager = (ICBuildConfigurationManager2) mgr; - - if (type == IDockerConnectionManagerListener.ADD_EVENT - || type == IDockerConnectionManagerListener.ENABLE_EVENT) { - ILaunchBarManager launchbarManager = CDebugCorePlugin - .getService(ILaunchBarManager.class); - ILaunchTarget defaultTarget = null; - try { - defaultTarget = launchbarManager.getActiveLaunchTarget(); - } catch (CoreException e) { - // ignore - } - - List<IDockerImage> images = connection.getImages(); - for (IDockerImage image : images) { - if (!image.isDangling() && !image.isIntermediateImage()) { - - String imageName = "[" //$NON-NLS-1$ - + image.repoTags().get(0).replace(':', '_') + "]"; //$NON-NLS-1$ - String imageName2 = imageName + "[" //$NON-NLS-1$ - + connection.getName() + "]"; //$NON-NLS-1$ - ILaunchTarget target = targetManager - .getLaunchTarget(TYPE_ID, imageName2); - if (target != null) { - continue; + public synchronized void changeEvent(final IDockerConnection connection, + final int type) { + Job checkConfigs = new Job("Check configs") { //$NON-NLS-1$ + @Override + protected IStatus run(IProgressMonitor monitor) { + + ICBuildConfigurationManager mgr = CCorePlugin + .getService(ICBuildConfigurationManager.class); + ICBuildConfigurationManager2 manager = (ICBuildConfigurationManager2) mgr; + + if (type == IDockerConnectionManagerListener.ADD_EVENT + || type == IDockerConnectionManagerListener.ENABLE_EVENT) { + ILaunchBarManager launchbarManager = CDebugCorePlugin + .getService(ILaunchBarManager.class); + ILaunchTarget defaultTarget = null; + try { + defaultTarget = launchbarManager + .getActiveLaunchTarget(); + } catch (CoreException e) { + // ignore } - target = targetManager.getLaunchTarget(TYPE_ID, imageName); - if (target != null) { - if (target.getAttribute( - IContainerLaunchTarget.ATTR_CONNECTION_URI, "") - .equals(connection.getUri())) { - continue; + + List<IDockerImage> images = connection.getImages(); + for (IDockerImage image : images) { + if (!image.isDangling() + && !image.isIntermediateImage()) { + + String imageName = "[" //$NON-NLS-1$ + + image.repoTags().get(0).replace(':', '_') + // .replace('/', '_') + + "]"; //$NON-NLS-1$ + String imageName2 = imageName + "[" //$NON-NLS-1$ + + connection.getName() + "]"; //$NON-NLS-1$ + ILaunchTarget target = targetManager + .getLaunchTarget(TYPE_ID, imageName2); + if (target != null) { + continue; + } + target = targetManager.getLaunchTarget(TYPE_ID, + imageName); + if (target != null) { + if (target.getAttribute( + IContainerLaunchTarget.ATTR_CONNECTION_URI, + "").equals(connection.getUri())) { + continue; + } + imageName = imageName2; + } + target = targetManager.addLaunchTarget(TYPE_ID, + imageName); + ILaunchTargetWorkingCopy wc = target + .getWorkingCopy(); + wc.setAttribute(ILaunchTarget.ATTR_OS, + CONTAINER_LINUX); + wc.setAttribute(ILaunchTarget.ATTR_ARCH, + Platform.getOSArch()); + wc.setAttribute( + IContainerLaunchTarget.ATTR_CONNECTION_URI, + connection.getUri()); + wc.setAttribute( + IContainerLaunchTarget.ATTR_IMAGE_ID, + image.repoTags().get(0)); + + wc.save(); } - imageName = imageName2; } - target = targetManager.addLaunchTarget(TYPE_ID, imageName); - ILaunchTargetWorkingCopy wc = target.getWorkingCopy(); - wc.setAttribute(ILaunchTarget.ATTR_OS, CONTAINER_LINUX); - wc.setAttribute(ILaunchTarget.ATTR_ARCH, - Platform.getOSArch()); - wc.setAttribute(IContainerLaunchTarget.ATTR_CONNECTION_URI, - connection.getUri()); - wc.setAttribute(IContainerLaunchTarget.ATTR_IMAGE_ID, - image.repoTags().get(0)); - - wc.save(); - } - } - // reset the default target back again - if (defaultTarget != null) { - try { - launchbarManager.setActiveLaunchTarget(defaultTarget); - } catch (CoreException e) { - DockerLaunchUIPlugin.log(e); - } + // reset the default target back again + if (defaultTarget != null) { + try { + launchbarManager + .setActiveLaunchTarget(defaultTarget); + } catch (CoreException e) { + DockerLaunchUIPlugin.log(e); + } - } + } - // Re-evaluate config list in case a build config was marked - // invalid and is now enabled - manager.recheckConfigs(); - } else if (type == IDockerConnectionManagerListener.REMOVE_EVENT - || type == IDockerConnectionManagerListener.DISABLE_EVENT) { - String connectionURI = connection.getUri(); - ILaunchTarget[] targets = targetManager - .getLaunchTargetsOfType(TYPE_ID); - for (ILaunchTarget target : targets) { - String uri = target.getAttribute( - IContainerLaunchTarget.ATTR_CONNECTION_URI, ""); //$NON-NLS-1$ - if (connectionURI.equals(uri)) { - targetManager.removeLaunchTarget(target); + // Re-evaluate config list in case a build config was marked + // invalid and is now enabled + manager.recheckConfigs(); + } else if (type == IDockerConnectionManagerListener.REMOVE_EVENT + || type == IDockerConnectionManagerListener.DISABLE_EVENT) { + String connectionURI = connection.getUri(); + ILaunchTarget[] targets = targetManager + .getLaunchTargetsOfType(TYPE_ID); + for (ILaunchTarget target : targets) { + String uri = target.getAttribute( + IContainerLaunchTarget.ATTR_CONNECTION_URI, ""); //$NON-NLS-1$ + if (connectionURI.equals(uri)) { + targetManager.removeLaunchTarget(target); + } + } } + return Status.OK_STATUS; } - } + }; + checkConfigs.setUser(true); + checkConfigs.schedule(); } } diff --git a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/ContainerGCCToolChainProvider.java b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/ContainerGCCToolChainProvider.java index 3134e07bacf..defb52a92a8 100644 --- a/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/ContainerGCCToolChainProvider.java +++ b/launch/org.eclipse.cdt.docker.launcher/src/org/eclipse/cdt/internal/docker/launcher/ui/launchbar/ContainerGCCToolChainProvider.java @@ -25,7 +25,11 @@ import org.eclipse.cdt.docker.launcher.ContainerTargetTypeProvider; import org.eclipse.cdt.docker.launcher.DockerLaunchUIPlugin; import org.eclipse.cdt.docker.launcher.IContainerLaunchTarget; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.launchbar.core.target.ILaunchTarget; import org.eclipse.linuxtools.docker.core.DockerConnectionManager; import org.eclipse.linuxtools.docker.core.IDockerConnection; @@ -58,8 +62,6 @@ public class ContainerGCCToolChainProvider this.toolChainManager = manager; IDockerConnection[] connections = DockerConnectionManager.getInstance() .getConnections(); - DockerConnectionManager.getInstance() - .addConnectionManagerListener(this); Map<String, IDockerConnection> connectionMap = new HashMap<>(); for (IDockerConnection connection : connections) { connectionMap.put(connection.getUri(), connection); @@ -80,6 +82,7 @@ public class ContainerGCCToolChainProvider // following can be used for naming build configurations properties.put(CONTAINER_LINUX_CONFIG_ID, image.repoTags().get(0).replace(':', '_')); + // .replace('/', '_')); ContainerGCCToolChain toolChain = new ContainerGCCToolChain( "gcc-img-" + image.id().substring(0, 19), //$NON-NLS-1$ @@ -90,73 +93,100 @@ public class ContainerGCCToolChainProvider } } - } + // add a Docker Connection listener to handle enablement/disablement of + // Connections + DockerConnectionManager.getInstance() + .addConnectionManagerListener(this); - @Override - public synchronized void changeEvent(IDockerConnection connection, - int type) { + // call the recheckConfigs method in case any disabled targets are now + // ok ICBuildConfigurationManager mgr = CCorePlugin .getService(ICBuildConfigurationManager.class); - ICBuildConfigurationManager2 manager = (ICBuildConfigurationManager2) mgr; - - if (type == IDockerConnectionManagerListener.ADD_EVENT - || type == IDockerConnectionManagerListener.ENABLE_EVENT) { - List<IDockerImage> images = connection.getImages(); - for (IDockerImage image : images) { - if (!image.isDangling() && !image.isIntermediateImage()) { - - Map<String, String> properties = new HashMap<>(); + ICBuildConfigurationManager2 cbuildmanager = (ICBuildConfigurationManager2) mgr; + cbuildmanager.recheckConfigs(); - properties.put(ILaunchTarget.ATTR_OS, - ContainerTargetTypeProvider.CONTAINER_LINUX); - properties.put(ILaunchTarget.ATTR_ARCH, - Platform.getOSArch()); - properties.put(IContainerLaunchTarget.ATTR_CONNECTION_URI, - connection.getUri()); - properties.put(IContainerLaunchTarget.ATTR_IMAGE_ID, - image.repoTags().get(0)); - // following can be used for naming build configurations - properties.put(CONTAINER_LINUX_CONFIG_ID, - image.repoTags().get(0).replace(':', '_')); + } + @Override + public synchronized void changeEvent(IDockerConnection connection, + int type) { - Collection<IToolChain> toolChains; - try { - toolChains = toolChainManager - .getToolChainsMatching(properties); - if (toolChains.isEmpty()) { - ContainerGCCToolChain toolChain = new ContainerGCCToolChain( - "gcc-img-" + image.id().substring(0, 19), //$NON-NLS-1$ - this, properties, null); - toolChainManager.addToolChain(toolChain); + final ContainerGCCToolChainProvider provider = this; + + Job checkConfigs = new Job("Check configs") { //$NON-NLS-1$ + @Override + protected IStatus run(IProgressMonitor monitor) { + + ICBuildConfigurationManager mgr = CCorePlugin + .getService(ICBuildConfigurationManager.class); + ICBuildConfigurationManager2 manager = (ICBuildConfigurationManager2) mgr; + + if (type == IDockerConnectionManagerListener.ADD_EVENT + || type == IDockerConnectionManagerListener.ENABLE_EVENT) { + List<IDockerImage> images = connection.getImages(); + for (IDockerImage image : images) { + if (!image.isDangling() + && !image.isIntermediateImage()) { + + Map<String, String> properties = new HashMap<>(); + + properties.put(ILaunchTarget.ATTR_OS, + ContainerTargetTypeProvider.CONTAINER_LINUX); + properties.put(ILaunchTarget.ATTR_ARCH, + Platform.getOSArch()); + properties.put( + IContainerLaunchTarget.ATTR_CONNECTION_URI, + connection.getUri()); + properties.put(IContainerLaunchTarget.ATTR_IMAGE_ID, + image.repoTags().get(0)); + // following can be used for naming build + // configurations + properties.put(CONTAINER_LINUX_CONFIG_ID, + image.repoTags().get(0).replace(':', '_')); + // .replace('/', '_')); + + + Collection<IToolChain> toolChains; + try { + toolChains = toolChainManager + .getToolChainsMatching(properties); + if (toolChains.isEmpty()) { + ContainerGCCToolChain toolChain = new ContainerGCCToolChain( + "gcc-img-" + image.id().substring(0, //$NON-NLS-1$ + 19), provider, properties, null); + toolChainManager.addToolChain(toolChain); + } + } catch (CoreException e) { + DockerLaunchUIPlugin.log(e); + } } - } catch (CoreException e) { - DockerLaunchUIPlugin.log(e); } - } - } - // Re-evaluate config list in case a build config was marked - // invalid and is now enabled - manager.recheckConfigs(); - } else if (type == IDockerConnectionManagerListener.REMOVE_EVENT - || type == IDockerConnectionManagerListener.DISABLE_EVENT) { - try { - String connectionURI = connection.getUri(); - Collection<IToolChain> toolChains = toolChainManager - .getAllToolChains(); - for (IToolChain toolChain : toolChains) { - String uri = toolChain.getProperty( - IContainerLaunchTarget.ATTR_CONNECTION_URI); - if (connectionURI.equals(uri)) { - toolChainManager.removeToolChain(toolChain); + // Re-evaluate config list in case a build config was marked + // invalid and is now enabled + manager.recheckConfigs(); + } else if (type == IDockerConnectionManagerListener.REMOVE_EVENT + || type == IDockerConnectionManagerListener.DISABLE_EVENT) { + try { + String connectionURI = connection.getUri(); + Collection<IToolChain> toolChains = toolChainManager + .getAllToolChains(); + for (IToolChain toolChain : toolChains) { + String uri = toolChain.getProperty( + IContainerLaunchTarget.ATTR_CONNECTION_URI); + if (connectionURI.equals(uri)) { + toolChainManager.removeToolChain(toolChain); + } + } + } catch (CoreException e1) { + // TODO Auto-generated catch block + DockerLaunchUIPlugin.log(e1); } } - } catch (CoreException e1) { - // TODO Auto-generated catch block - DockerLaunchUIPlugin.log(e1); + return Status.OK_STATUS; } - } - + }; + checkConfigs.setUser(true); + checkConfigs.schedule(); } } |