1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 06:32:10 +02:00

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
This commit is contained in:
Jeff Johnston 2018-06-28 15:25:11 -04:00
parent 147335653f
commit 2bcd06f097
2 changed files with 203 additions and 132 deletions

View file

@ -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;
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) {
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
}
ICBuildConfigurationManager mgr = CCorePlugin
.getService(ICBuildConfigurationManager.class);
ICBuildConfigurationManager2 manager = (ICBuildConfigurationManager2) mgr;
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;
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);
}
}
// 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;
}
// 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);
}
}
}
};
checkConfigs.setUser(true);
checkConfigs.schedule();
}
}

View file

@ -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);
// call the recheckConfigs method in case any disabled targets are now
// ok
ICBuildConfigurationManager mgr = CCorePlugin
.getService(ICBuildConfigurationManager.class);
ICBuildConfigurationManager2 cbuildmanager = (ICBuildConfigurationManager2) mgr;
cbuildmanager.recheckConfigs();
}
@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) {
List<IDockerImage> images = connection.getImages();
for (IDockerImage image : images) {
if (!image.isDangling() && !image.isIntermediateImage()) {
final ContainerGCCToolChainProvider provider = this;
Map<String, String> properties = new HashMap<>();
Job checkConfigs = new Job("Check configs") { //$NON-NLS-1$
@Override
protected IStatus run(IProgressMonitor monitor) {
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(':', '_'));
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, 19), //$NON-NLS-1$
this, properties, null);
toolChainManager.addToolChain(toolChain);
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);
}
}
} catch (CoreException e1) {
// TODO Auto-generated catch block
DockerLaunchUIPlugin.log(e1);
}
}
return Status.OK_STATUS;
}
// 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);
}
}
};
checkConfigs.setUser(true);
checkConfigs.schedule();
}
}